diff --git a/packages/effect-fc/src/Result.ts b/packages/effect-fc/src/Result.ts index b4e9eba..40c6bef 100644 --- a/packages/effect-fc/src/Result.ts +++ b/packages/effect-fc/src/Result.ts @@ -177,6 +177,46 @@ export const makeProgressLayer = ( })) +export namespace forkEffect { + export type InputContext = R extends Progress ? [X] extends [P] ? R : never : R + export type OutputContext = Scope.Scope | Exclude | Progress> + + export interface Options

{ + readonly initialProgress?: P + } +} + +export const forkEffect = ( + effect: Effect.Effect>>, + options?: forkEffect.Options

, +): Effect.Effect< + Queue.Dequeue>, + never, + forkEffect.OutputContext +> => Effect.Do.pipe( + Effect.bind("scope", () => Scope.Scope), + Effect.bind("queue", () => Queue.unbounded>()), + Effect.bind("ref", () => Ref.make>(initial())), + Effect.tap(({ queue, ref }) => Effect.andThen(ref, v => Queue.offer(queue, v))), + Effect.tap(({ scope, queue, ref }) => Effect.forkScoped( + Effect.addFinalizer(() => Queue.shutdown(queue)).pipe( + Effect.andThen(Effect.succeed(running(options?.initialProgress)).pipe( + Effect.tap(v => Ref.set(ref, v)), + Effect.tap(v => Queue.offer(queue, v)), + )), + Effect.andThen(Effect.provideService(effect, Scope.Scope, scope)), + Effect.exit, + Effect.andThen(exit => Effect.succeed(fromExit(exit)).pipe( + Effect.tap(v => Ref.set(ref, v)), + Effect.tap(v => Queue.offer(queue, v)), + )), + Effect.scoped, + Effect.provide(makeProgressLayer(queue, ref)), + ) + )), + Effect.map(({ queue }) => queue), +) as Effect.Effect>, never, Scope.Scope> + export namespace forkEffectScoped { export type InputContext = (R extends Progress ? [X] extends [P]