| 42 | |
| 43 | // @effect-diagnostics-next-line missingEffectServiceDependency:off |
| 44 | export class WithToast extends Context.Service<WithToast>()("WithToast", { |
| 45 | make: Effect.gen(function*() { |
| 46 | const toast = yield* Toast |
| 47 | return <A, E, Args extends readonly unknown[], R, WaiR = never, SucR = never, ErrR = never>( |
| 48 | options: ToastOptions<A, E, Args, WaiR, SucR, ErrR> |
| 49 | ) => |
| 50 | Effect.fnUntraced(function*(self: Effect.Effect<A, E, R>, ...args: Args) { |
| 51 | const baseTimeout = options.timeout ?? 3_000 |
| 52 | |
| 53 | const stableToastId = typeof options.stableToastId === "function" |
| 54 | ? options.stableToastId(...args) |
| 55 | : options.stableToastId |
| 56 | |
| 57 | const requestId: string = yield* Effect.currentSpan.pipe( |
| 58 | Effect.map((span) => span.traceId), |
| 59 | Effect.orElseSucceed(() => S.StringId.make()) |
| 60 | ) |
| 61 | const groupId = options.groupId |
| 62 | const meta = { ...(groupId !== undefined ? { groupId } : {}), requestId } |
| 63 | |
| 64 | const t = yield* wrapEffect(options.onWaiting)(...args) |
| 65 | const toastId: ToastId | undefined = t === null |
| 66 | ? stableToastId |
| 67 | : stableToastId ?? `wait-${Math.random().toString(36).slice(2)}` |
| 68 | |
| 69 | const waitingFiber = t === null ? undefined : yield* Effect.forkChild( |
| 70 | Effect.sleep("1 seconds").pipe( |
| 71 | Effect.andThen(toast.info(t, { id: toastId!, timeout: Infinity, ...meta })) |
| 72 | ) |
| 73 | ) |
| 74 | const interruptWaiting = waitingFiber ? Fiber.interrupt(waitingFiber) : Effect.void |
| 75 | |
| 76 | return yield* self.pipe( |
| 77 | Effect.tap(Effect.fnUntraced(function*(a) { |
| 78 | yield* interruptWaiting |
| 79 | const t = yield* wrapEffect(options.onSuccess)(a, ...args) |
| 80 | if (t === null) { |
| 81 | return |
| 82 | } |
| 83 | yield* toast.success( |
| 84 | t, |
| 85 | toastId !== undefined |
| 86 | ? { id: toastId, timeout: baseTimeout, ...meta } |
| 87 | : { timeout: baseTimeout, ...meta } |
| 88 | ) |
| 89 | })), |
| 90 | Effect.tapCause(Effect.fnUntraced(function*(cause) { |
| 91 | yield* interruptWaiting |
| 92 | yield* Effect.logDebug( |
| 93 | "WithToast - caught error cause: " + Cause.squash(cause), |
| 94 | Cause.hasInterruptsOnly(cause), |
| 95 | cause |
| 96 | ) |
| 97 | |
| 98 | if (Cause.hasInterruptsOnly(cause)) { |
| 99 | if (toastId) yield* toast.dismiss(toastId) |
| 100 | return |
| 101 | } |
nothing calls this directly
no test coverage detected
searching dependent graphs…