MCPcopy Create free account
hub / github.com/Snowflyt/tinyeffect / runAsync

Function runAsync

src/effected.ts:2610–2701  ·  view source on GitHub ↗
(
  effected: E extends Effected<infer F extends Effect, unknown> ?
    [ExtractUnhandled<F>] extends [never] ?
      E
    : UnhandledEffect<ExtractUnhandled<F>>
  : never,
)

Source from the content-addressed store, hash-verified

2608 * @throws {UnhandledEffectError} If an unhandled effect is encountered.
2609 */
2610export function runAsync<E extends Effected<Effect, unknown>>(
2611 effected: E extends Effected<infer F extends Effect, unknown> ?
2612 [ExtractUnhandled<F>] extends [never] ?
2613 E
2614 : UnhandledEffect<ExtractUnhandled<F>>
2615 : never,
2616): Promise<E extends Effected<infer F, infer R> ? ExtractDefaultTerminateType<F> | R : never> {
2617 const iterator = (effected as Iterable<any>)[Symbol.iterator]();
2618 const context = {
2619 interceptIterator: null as typeof iterator | null,
2620 terminated: false as false | "with-value" | "without-value",
2621 terminatedValue: undefined as unknown,
2622 };
2623
2624 return new Promise((resolve, reject) => {
2625 const iterate = (...args: [] | [unknown]) => {
2626 if (context.terminated) return context.terminatedValue;
2627
2628 let done: boolean | undefined;
2629 let value: any;
2630 try {
2631 ({ done, value } = (context.interceptIterator || iterator).next(...args));
2632 } catch (e) {
2633 // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors
2634 reject(e);
2635 return;
2636 }
2637
2638 // We use a while loop to avoid stack overflow when there are many synchronous effects
2639 while (!done) {
2640 if (!value) {
2641 reject(
2642 new Error(
2643 `Invalid effected program: an effected program should yield only effects (received ${stringify(value)})`,
2644 ),
2645 );
2646 return;
2647 }
2648 if (value instanceof Effect) {
2649 while (value instanceof Effect && typeof (value as any).defaultHandler === "function") {
2650 value = handleEffect(context, effect.name, value, (value as any).defaultHandler).value;
2651 // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
2652 if (context.terminated) return context.terminatedValue;
2653 }
2654 if (value instanceof Effect) {
2655 reject(new UnhandledEffectError(value, `Unhandled effect: ${stringifyEffect(value)}`));
2656 return;
2657 }
2658 }
2659 if (value._effectSync) {
2660 try {
2661 ({ done, value } = (context.interceptIterator || iterator).next(
2662 ...("value" in value ? [value.value] : []),
2663 ));
2664 } catch (e) {
2665 // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors
2666 reject(e);
2667 return;

Callers 2

effected.spec.tsFile · 0.90
constructorMethod · 0.85

Calls 1

iterateFunction · 0.70

Tested by

no test coverage detected