diff --git a/packages/example/src/routes/promise.tsx b/packages/example/src/routes/promise.tsx index 9577aca..58c1452 100644 --- a/packages/example/src/routes/promise.tsx +++ b/packages/example/src/routes/promise.tsx @@ -15,9 +15,8 @@ const Result = Schema.Tuple(Schema.String) type Result = typeof Result.Type function RouteComponent() { - const promise = R.usePromiseScoped(Effect.addFinalizer(() => Console.log("Cleanup")).pipe( - Effect.andThen(HttpClient.HttpClient), - Effect.flatMap(client => client.get("https://www.uuidtools.com/api/generate/v4")), + const promise = R.usePromise(Effect.addFinalizer(() => Console.log("Cleanup")).pipe( + Effect.andThen(HttpClient.get("https://www.uuidtools.com/api/generate/v4")), HttpClient.withTracerPropagation(false), Effect.flatMap(res => res.json), Effect.flatMap(Schema.decodeUnknown(Result)), diff --git a/packages/reffuse/src/Reffuse.ts b/packages/reffuse/src/Reffuse.ts index 08700cb..50ee1a3 100644 --- a/packages/reffuse/src/Reffuse.ts +++ b/packages/reffuse/src/Reffuse.ts @@ -284,19 +284,6 @@ export class Reffuse { } usePromise( - effect: Effect.Effect, - deps?: React.DependencyList, - options?: { readonly signal?: AbortSignal } & RenderOptions, - ): Promise { - const runPromise = this.useRunPromise() - - return React.useMemo(() => runPromise(effect, options), [ - ...options?.doNotReExecuteOnRuntimeOrContextChange ? [] : [runPromise], - ...(deps ?? []), - ]) - } - - usePromiseScoped( effect: Effect.Effect, deps?: React.DependencyList, options?: { readonly signal?: AbortSignal } & Runtime.RunForkOptions & RenderOptions & ScopeOptions, @@ -310,27 +297,29 @@ export class Reffuse { const { promise, resolve, reject } = Promise.withResolvers() setValue(promise) - const scope = runSync(Scope.make(options?.finalizerExecutionStrategy)) + const scope = runSync(options?.scope + ? Scope.fork(options.scope, options?.finalizerExecutionStrategy ?? ExecutionStrategy.sequential) + : Scope.make(options?.finalizerExecutionStrategy) + ) - const fiber = effect.pipe( + const cleanup = () => { runFork(Scope.close(scope, Exit.void)) } + if (options?.signal) + options.signal.addEventListener("abort", cleanup) + + effect.pipe( Effect.provideService(Scope.Scope, scope), Effect.match({ onSuccess: resolve, onFailure: reject, }), - - // TODO: use scope from RunForkOptions? effect => runFork(effect, { ...options, scope }), ) return () => { - // Fiber.interrupt(fiber).pipe( - // Effect.andThen(Scope.close(scope, Exit.void)), - // // \/ TODO: should interrupted promises reject? - // // Effect.andThen(Effect.sync(() => { reject() })), - // runFork, - // ) - runFork(Scope.close(scope, Exit.void)) + if (options?.signal) + options.signal.removeEventListener("abort", cleanup) + + cleanup() } }, [ ...options?.doNotReExecuteOnRuntimeOrContextChange ? [] : [runSync, runFork], @@ -340,41 +329,6 @@ export class Reffuse { return value } - // usePromiseScoped( - // effect: Effect.Effect, - // deps?: React.DependencyList, - // options?: { readonly signal?: AbortSignal } & RenderOptions & ScopeOptions, - // ): Promise { - // const runSync = this.useRunSync() - // const runPromise = this.useRunPromise() - - // const [value, setValue] = React.useState(new Promise(() => {})) - - // React.useEffect(() => { - // const controller = new AbortController() - // const signal = AbortSignal.any([ - // controller.signal, - // ...options?.signal ? [options.signal] : [], - // ]) - - // const scope = runSync(Scope.make(options?.finalizerExecutionStrategy)) - // setValue(runPromise(Effect.provideService(effect, Scope.Scope, scope), { - // ...options, - // signal, - // })) - - // return () => { - // controller.abort() - // runSync(Scope.close(scope, Exit.void)) - // } - // }, [ - // ...options?.doNotReExecuteOnRuntimeOrContextChange ? [] : [runSync, runPromise], - // ...(deps ?? []), - // ]) - - // return value - // } - useRef(value: A): SubscriptionRef.SubscriptionRef { return this.useMemo(