0.2.1 #26
@@ -95,6 +95,53 @@ const ResultPrototype = Object.freeze({
|
|||||||
} as const satisfies Result.Prototype)
|
} as const satisfies Result.Prototype)
|
||||||
|
|
||||||
|
|
||||||
|
export const isResult = (u: unknown): u is Result<unknown, unknown, unknown> => 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<unknown> => isResult(u) && u._tag === "Running"
|
||||||
|
export const isSuccess = (u: unknown): u is Success<unknown> => isResult(u) && u._tag === "Success"
|
||||||
|
export const isFailure = (u: unknown): u is Failure<unknown, unknown> => isResult(u) && u._tag === "Failure"
|
||||||
|
export const isRefreshing = (u: unknown): u is Refreshing<unknown> => isResult(u) && Predicate.hasProperty(u, "refreshing") && u.refreshing
|
||||||
|
|
||||||
|
export const initial = (): Initial => Object.setPrototypeOf({ _tag: "Initial" }, ResultPrototype)
|
||||||
|
export const running = <P = never>(progress?: P): Running<P> => Object.setPrototypeOf({ _tag: "Running", progress }, ResultPrototype)
|
||||||
|
export const succeed = <A>(value: A): Success<A> => Object.setPrototypeOf({ _tag: "Success", value }, ResultPrototype)
|
||||||
|
|
||||||
|
export const fail = <E, A = never>(
|
||||||
|
cause: Cause.Cause<E>,
|
||||||
|
previousSuccess?: Success<A>,
|
||||||
|
): Failure<A, E> => Object.setPrototypeOf({
|
||||||
|
_tag: "Failure",
|
||||||
|
cause,
|
||||||
|
previousSuccess: Option.fromNullable(previousSuccess),
|
||||||
|
}, ResultPrototype)
|
||||||
|
export const refreshing = <R extends Success<any> | Failure<any, any>, P = never>(
|
||||||
|
result: R,
|
||||||
|
progress?: P,
|
||||||
|
): Omit<R, keyof Refreshing<Result.Progress<R>>> & Refreshing<P> => Object.setPrototypeOf(
|
||||||
|
Object.assign({}, result, { progress }),
|
||||||
|
Object.getPrototypeOf(result),
|
||||||
|
)
|
||||||
|
|
||||||
|
export const fromExit = <A, E>(
|
||||||
|
exit: Exit.Exit<A, E>
|
||||||
|
): Success<A> | Failure<A, E> => exit._tag === "Success"
|
||||||
|
? succeed(exit.value)
|
||||||
|
: fail(exit.cause)
|
||||||
|
|
||||||
|
export const toExit = <A, E, P>(
|
||||||
|
self: Result<A, E, P>
|
||||||
|
): Exit.Exit<A, E | Cause.NoSuchElementException> => {
|
||||||
|
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<P = never> {
|
export interface Progress<P = never> {
|
||||||
readonly update: <E, R>(
|
readonly update: <E, R>(
|
||||||
f: (previous: P) => Effect.Effect<P, E, R>
|
f: (previous: P) => Effect.Effect<P, E, R>
|
||||||
@@ -126,70 +173,37 @@ export const makeProgressLayer = <A, E, P = never>(
|
|||||||
Effect.tap(({ next }) => Ref.set(ref, next)),
|
Effect.tap(({ next }) => Ref.set(ref, next)),
|
||||||
Effect.tap(({ next }) => Queue.offer(queue, next)),
|
Effect.tap(({ next }) => Queue.offer(queue, next)),
|
||||||
Effect.asVoid,
|
Effect.asVoid,
|
||||||
)
|
),
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
|
||||||
export const isResult = (u: unknown): u is Result<unknown, unknown, unknown> => Predicate.hasProperty(u, ResultTypeId)
|
export namespace forkEffectScoped {
|
||||||
export const isInitial = (u: unknown): u is Initial => isResult(u) && u._tag === "Initial"
|
export type ContextInput<R, P> = (R extends Progress<infer X>
|
||||||
export const isRunning = (u: unknown): u is Running<unknown> => isResult(u) && u._tag === "Running"
|
? [X] extends [P]
|
||||||
export const isSuccess = (u: unknown): u is Success<unknown> => isResult(u) && u._tag === "Success"
|
? R
|
||||||
export const isFailure = (u: unknown): u is Failure<unknown, unknown> => isResult(u) && u._tag === "Failure"
|
: never
|
||||||
export const isRefreshing = (u: unknown): u is Refreshing<unknown> => isResult(u) && Predicate.hasProperty(u, "refreshing") && u.refreshing
|
: R
|
||||||
|
|
||||||
export const initial = (): Initial => Object.setPrototypeOf({ _tag: "Initial" }, ResultPrototype)
|
|
||||||
export const running = <P = never>(progress?: P): Running<P> => Object.setPrototypeOf({ _tag: "Running", progress }, ResultPrototype)
|
|
||||||
export const succeed = <A>(value: A): Success<A> => Object.setPrototypeOf({ _tag: "Success", value }, ResultPrototype)
|
|
||||||
export const fail = <E, A = never>(
|
|
||||||
cause: Cause.Cause<E>,
|
|
||||||
previousSuccess?: Success<A>,
|
|
||||||
): Failure<A, E> => Object.setPrototypeOf({
|
|
||||||
_tag: "Failure",
|
|
||||||
cause,
|
|
||||||
previousSuccess: Option.fromNullable(previousSuccess),
|
|
||||||
}, ResultPrototype)
|
|
||||||
export const refreshing = <R extends Success<any> | Failure<any, any>, P = never>(
|
|
||||||
result: R,
|
|
||||||
progress?: P,
|
|
||||||
): Omit<R, keyof Refreshing<Result.Progress<R>>> & Refreshing<P> => Object.setPrototypeOf(
|
|
||||||
Object.assign({}, result, { progress }),
|
|
||||||
Object.getPrototypeOf(result),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
export interface Options<P = never> {
|
||||||
export const fromExit = <A, E>(
|
readonly initialProgress?: P
|
||||||
exit: Exit.Exit<A, E>
|
|
||||||
): Success<A> | Failure<A, E> => exit._tag === "Success"
|
|
||||||
? succeed(exit.value)
|
|
||||||
: fail(exit.cause)
|
|
||||||
|
|
||||||
export const toExit = <A, E, P>(
|
|
||||||
self: Result<A, E, P>
|
|
||||||
): Exit.Exit<A, E | Cause.NoSuchElementException> => {
|
|
||||||
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 const forkEffectScoped = <A, E, R, P = never>(
|
export const forkEffectScoped = <A, E, R, P = never>(
|
||||||
effect: Effect.Effect<A, E, R>,
|
effect: Effect.Effect<A, E, forkEffectScoped.ContextInput<R, NoInfer<P>>>,
|
||||||
initialProgress?: P,
|
options?: forkEffectScoped.Options<P>,
|
||||||
): Effect.Effect<
|
): Effect.Effect<
|
||||||
Queue.Dequeue<Result<A, E, P>>,
|
Queue.Dequeue<Result<A, E, P>>,
|
||||||
never,
|
never,
|
||||||
Scope.Scope | Exclude<R, Progress<P>>
|
Scope.Scope | Exclude<R, Progress<any>>
|
||||||
> => Effect.Do.pipe(
|
> => Effect.Do.pipe(
|
||||||
Effect.bind("queue", () => Queue.unbounded<Result<A, E, P>>()),
|
Effect.bind("queue", () => Queue.unbounded<Result<A, E, P>>()),
|
||||||
Effect.bind("ref", () => Ref.make<Result<A, E, P>>(initial())),
|
Effect.bind("ref", () => Ref.make<Result<A, E, P>>(initial())),
|
||||||
Effect.tap(({ queue, ref }) => Effect.andThen(ref, v => Queue.offer(queue, v))),
|
Effect.tap(({ queue, ref }) => Effect.andThen(ref, v => Queue.offer(queue, v))),
|
||||||
Effect.tap(({ queue, ref }) => Effect.forkScoped(
|
Effect.tap(({ queue, ref }) => Effect.forkScoped(
|
||||||
Effect.addFinalizer(() => Queue.shutdown(queue)).pipe(
|
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 => Ref.set(ref, v)),
|
||||||
Effect.tap(v => Queue.offer(queue, v)),
|
Effect.tap(v => Queue.offer(queue, v)),
|
||||||
)),
|
)),
|
||||||
@@ -205,3 +219,11 @@ export const forkEffectScoped = <A, E, R, P = never>(
|
|||||||
)),
|
)),
|
||||||
Effect.map(({ queue }) => queue),
|
Effect.map(({ queue }) => queue),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
const t = forkEffectScoped(
|
||||||
|
Effect.gen(function*() {
|
||||||
|
yield* Progress()
|
||||||
|
}),
|
||||||
|
{ initialProgress: "juif" }
|
||||||
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user