import { Effect, ManagedRuntime } from 'effect'; export type EffectRuntime = Pick< ManagedRuntime.ManagedRuntime, 'runPromise' | 'runSync' > & Partial, 'contextEffect'>>; export type EffectRunner = { runPromise: (effect: Effect.Effect) => Promise; runSync: (effect: Effect.Effect) => A; provide: (effect: Effect.Effect) => Effect.Effect; }; export const makeEffectRunner = ( runtime: EffectRuntime | undefined, ): EffectRunner => { if (runtime) { const contextEffect = runtime.contextEffect; return { runPromise: (effect) => runtime.runPromise(effect), runSync: (effect) => runtime.runSync(effect), // Without a context the effect hops through a promise and cannot be // interrupted; a ManagedRuntime keeps it in-fiber. provide: (effect) => contextEffect ? (contextEffect.pipe( Effect.flatMap((context) => Effect.provide(effect, context)), ) as Effect.Effect) : (Effect.promise(() => runtime.runPromise(effect)) as Effect.Effect< never, never >), }; } return { runPromise: (effect) => Effect.runPromise(effect as Effect.Effect), runSync: (effect) => Effect.runSync(effect as Effect.Effect), provide: (effect) => effect, } as EffectRunner; };