diff --git a/packages/effect-fc/src/Result.ts b/packages/effect-fc/src/Result.ts index 649dd66..2ea70fa 100644 --- a/packages/effect-fc/src/Result.ts +++ b/packages/effect-fc/src/Result.ts @@ -95,6 +95,53 @@ const ResultPrototype = Object.freeze({ } as const satisfies Result.Prototype) +export const isResult = (u: unknown): u is Result => Predicate.hasProperty(u, ResultTypeId) +export const isInitial = (u: unknown): u is Initial => isResult(u) && u._tag === "Initial" +export const isRunning = (u: unknown): u is Running => isResult(u) && u._tag === "Running" +export const isSuccess = (u: unknown): u is Success => isResult(u) && u._tag === "Success" +export const isFailure = (u: unknown): u is Failure => isResult(u) && u._tag === "Failure" +export const isRefreshing = (u: unknown): u is Refreshing => isResult(u) && Predicate.hasProperty(u, "refreshing") && u.refreshing + +export const initial = (): Initial => Object.setPrototypeOf({ _tag: "Initial" }, ResultPrototype) +export const running =

(progress?: P): Running

=> Object.setPrototypeOf({ _tag: "Running", progress }, ResultPrototype) +export const succeed = (value: A): Success => Object.setPrototypeOf({ _tag: "Success", value }, ResultPrototype) + +export const fail = ( + cause: Cause.Cause, + previousSuccess?: Success, +): Failure => Object.setPrototypeOf({ + _tag: "Failure", + cause, + previousSuccess: Option.fromNullable(previousSuccess), +}, ResultPrototype) +export const refreshing = | Failure, P = never>( + result: R, + progress?: P, +): Omit>> & Refreshing

=> Object.setPrototypeOf( + Object.assign({}, result, { progress }), + Object.getPrototypeOf(result), +) + +export const fromExit = ( + exit: Exit.Exit +): Success | Failure => exit._tag === "Success" + ? succeed(exit.value) + : fail(exit.cause) + +export const toExit = ( + self: Result +): Exit.Exit => { + switch (self._tag) { + case "Success": + return Exit.succeed(self.value) + case "Failure": + return Exit.failCause(self.cause) + default: + return Exit.fail(new Cause.NoSuchElementException()) + } +} + + export interface Progress

{ readonly update: ( f: (previous: P) => Effect.Effect @@ -126,70 +173,37 @@ export const makeProgressLayer = ( Effect.tap(({ next }) => Ref.set(ref, next)), Effect.tap(({ next }) => Queue.offer(queue, next)), Effect.asVoid, - ) + ), })) -export const isResult = (u: unknown): u is Result => Predicate.hasProperty(u, ResultTypeId) -export const isInitial = (u: unknown): u is Initial => isResult(u) && u._tag === "Initial" -export const isRunning = (u: unknown): u is Running => isResult(u) && u._tag === "Running" -export const isSuccess = (u: unknown): u is Success => isResult(u) && u._tag === "Success" -export const isFailure = (u: unknown): u is Failure => isResult(u) && u._tag === "Failure" -export const isRefreshing = (u: unknown): u is Refreshing => isResult(u) && Predicate.hasProperty(u, "refreshing") && u.refreshing +export namespace forkEffectScoped { + export type ContextInput = (R extends Progress + ? [X] extends [P] + ? R + : never + : R + ) -export const initial = (): Initial => Object.setPrototypeOf({ _tag: "Initial" }, ResultPrototype) -export const running =

(progress?: P): Running

=> Object.setPrototypeOf({ _tag: "Running", progress }, ResultPrototype) -export const succeed = (value: A): Success => Object.setPrototypeOf({ _tag: "Success", value }, ResultPrototype) -export const fail = ( - cause: Cause.Cause, - previousSuccess?: Success, -): Failure => Object.setPrototypeOf({ - _tag: "Failure", - cause, - previousSuccess: Option.fromNullable(previousSuccess), -}, ResultPrototype) -export const refreshing = | Failure, P = never>( - result: R, - progress?: P, -): Omit>> & Refreshing

=> Object.setPrototypeOf( - Object.assign({}, result, { progress }), - Object.getPrototypeOf(result), -) - - -export const fromExit = ( - exit: Exit.Exit -): Success | Failure => exit._tag === "Success" - ? succeed(exit.value) - : fail(exit.cause) - -export const toExit = ( - self: Result -): Exit.Exit => { - switch (self._tag) { - case "Success": - return Exit.succeed(self.value) - case "Failure": - return Exit.failCause(self.cause) - default: - return Exit.fail(new Cause.NoSuchElementException()) + export interface Options

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

, ): Effect.Effect< Queue.Dequeue>, never, - Scope.Scope | Exclude> + Scope.Scope | Exclude> > => Effect.Do.pipe( 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(({ queue, ref }) => Effect.forkScoped( Effect.addFinalizer(() => Queue.shutdown(queue)).pipe( - Effect.andThen(Effect.succeed(running(initialProgress)).pipe( + Effect.andThen(Effect.succeed(running(options?.initialProgress)).pipe( Effect.tap(v => Ref.set(ref, v)), Effect.tap(v => Queue.offer(queue, v)), )), @@ -205,3 +219,11 @@ export const forkEffectScoped = ( )), Effect.map(({ queue }) => queue), ) + + +const t = forkEffectScoped( + Effect.gen(function*() { + yield* Progress() + }), + { initialProgress: "juif" } +)