Skip to content

feat: domain flow #64

@mathcovax

Description

@mathcovax

Créer le domain flow. Ce domain utilise les génératrices pour faire des earlyReturn et autre opération.

gros intéré : faire remonté une data au block du dessus sans intérompre le code.

idée de fonctions:

  • breafIf: permet de stoper l'exécution si une condition n'est pas réspecter
  • defer: donne une call back qui s'execute a la fin
  • createWithDisposer: permet de créer une donner qui a une fonction associer pour traiter cellci une fois sont utilisation passé
  • monade write.

poc:

import { justExec } from "./justExec";
import { type AnyFunction } from "./types";

class ExitFlow<
	GenericValue extends unknown = unknown,
> {
	public constructor(
		public value: GenericValue,
	) {}
}

function breakIf<
	GenericValue extends unknown,
	GenericPredicate extends GenericValue,
>(
	value: GenericValue,
	thePredicate: (value: GenericValue) => value is GenericPredicate
): Generator<
	ExitFlow<
		Extract<GenericValue, GenericPredicate>
	>,
	Exclude<GenericValue, GenericPredicate>
>;
function breakIf<
	GenericValue extends unknown,
>(
	value: GenericValue,
	thePredicate: (value: GenericValue) => boolean
): Generator<
	ExitFlow<GenericValue>,
	GenericValue
>;
function *breakIf(value: unknown, thePredicate: AnyFunction): any {
	if (thePredicate(value) === true) {
		yield new ExitFlow(value);
	} else {
		return value;
	}
}

export interface FlowParams {
	breakIf: typeof breakIf;
}

type ComputeResult<
	GenericOutput extends (
		| AsyncGenerator
		| Generator
	),
> = (
	GenericOutput extends AsyncGenerator<infer InferredElement, infer InferredReturn>
		? Promise<InferredElement | InferredReturn>
		: GenericOutput extends Generator<infer InferredElement, infer InferredReturn>
			? InferredElement | InferredReturn
			: never
) extends infer InferredResult
	? InferredResult extends ExitFlow
		? InferredResult["value"]
		: InferredResult
	: never;

export function flow<
	GenericOutput extends(
		| AsyncGenerator
		| Generator
	),
>(
	theFunction: (params: FlowParams) => GenericOutput,
): ComputeResult<GenericOutput> {
	let result: undefined | IteratorResult<unknown> = undefined;

	const generator = theFunction({
		breakIf,
	});

	if (Symbol.asyncIterator in generator) {
		return justExec(async() => {
			do {
				result = await generator.next();
				if (result.value instanceof ExitFlow) {
					return result.value.value;
				}
			} while (result.done !== true);

			return result.value;
		}) as never;
	}

	do {
		result = generator.next();
		if (result.value instanceof ExitFlow) {
			return result.value.value;
		}
	} while (result.done !== true);

	return result.value;
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions