(
effected: E extends Effected<infer F extends Effect, unknown> ?
[ExtractUnhandled<F>] extends [never] ?
E
: UnhandledEffect<ExtractUnhandled<F>>
: never,
)
| 2552 | * @throws {Error} If an asynchronous effect is encountered. |
| 2553 | */ |
| 2554 | export function runSync<E extends Effected<Effect, unknown>>( |
| 2555 | effected: E extends Effected<infer F extends Effect, unknown> ? |
| 2556 | [ExtractUnhandled<F>] extends [never] ? |
| 2557 | E |
| 2558 | : UnhandledEffect<ExtractUnhandled<F>> |
| 2559 | : never, |
| 2560 | ): E extends Effected<infer F, infer R> ? ExtractDefaultTerminateType<F> | R : never { |
| 2561 | const iterator = (effected as Iterable<any>)[Symbol.iterator](); |
| 2562 | const context = { |
| 2563 | interceptIterator: null as typeof iterator | null, |
| 2564 | terminated: false as false | "with-value" | "without-value", |
| 2565 | terminatedValue: undefined as unknown, |
| 2566 | }; |
| 2567 | |
| 2568 | let { done, value } = (context.interceptIterator || iterator).next(); |
| 2569 | while (!done) { |
| 2570 | if (context.terminated) return context.terminatedValue as never; |
| 2571 | |
| 2572 | if (!value) |
| 2573 | throw new Error( |
| 2574 | `Invalid effected program: an effected program should yield only effects (received ${stringify(value)})`, |
| 2575 | ); |
| 2576 | if (value instanceof Effect) { |
| 2577 | while (value instanceof Effect && typeof (value as any).defaultHandler === "function") { |
| 2578 | value = handleEffect(context, effect.name, value, (value as any).defaultHandler).value; |
| 2579 | // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition |
| 2580 | if (context.terminated) return context.terminatedValue as never; |
| 2581 | } |
| 2582 | if (value instanceof Effect) |
| 2583 | throw new UnhandledEffectError(value, `Unhandled effect: ${stringifyEffect(value)}`); |
| 2584 | } |
| 2585 | if (value._effectSync) { |
| 2586 | ({ done, value } = (context.interceptIterator || iterator).next( |
| 2587 | ...("value" in value ? [value.value] : []), |
| 2588 | )); |
| 2589 | continue; |
| 2590 | } |
| 2591 | if (value._effectAsync) |
| 2592 | throw new Error( |
| 2593 | "Cannot run an asynchronous effected program with `runSync`, use `runAsync` instead", |
| 2594 | ); |
| 2595 | |
| 2596 | throw new Error( |
| 2597 | `Invalid effected program: an effected program should yield only effects (received ${stringify(value)})`, |
| 2598 | ); |
| 2599 | } |
| 2600 | return value; |
| 2601 | } |
| 2602 | |
| 2603 | /** |
| 2604 | * Run a (possibly) asynchronous effected program and return its result as a {@link Promise}. |
no test coverage detected