From 581bab027cae8003c5d2998c2a25ecaed03dea2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Fri, 23 Jan 2026 01:20:11 +0100 Subject: [PATCH] Fix useScope --- packages/effect-fc/src/Component.ts | 57 ++++++++++++++--------------- 1 file changed, 27 insertions(+), 30 deletions(-) diff --git a/packages/effect-fc/src/Component.ts b/packages/effect-fc/src/Component.ts index 284f09d..3cd4b2d 100644 --- a/packages/effect-fc/src/Component.ts +++ b/packages/effect-fc/src/Component.ts @@ -522,43 +522,40 @@ export const useScope = Effect.fnUntraced(function*( const runtimeRef = React.useRef>(null!) runtimeRef.current = yield* Effect.runtime() - const scopeMap = yield* ScopeMap as unknown as Effect.Effect - - const [key, scope] = React.useMemo(() => Runtime.runSync(runtimeRef.current)(Effect.andThen( - Effect.all([Effect.succeed({}), scopeMap.ref]), - ([key, map]) => Effect.andThen( - Option.match(HashMap.get(map, key), { - onSome: entry => Effect.succeed(entry.scope), - onNone: () => Effect.tap( - Scope.make(options?.finalizerExecutionStrategy ?? defaultOptions.finalizerExecutionStrategy), - scope => Ref.update(scopeMap.ref, HashMap.set(key, { - scope, - closeFiber: Option.none(), - })), - ), - }), - scope => [key, scope] as const, + const { key, scope } = React.useMemo(() => Runtime.runSync(runtimeRef.current)(Effect.Do.pipe( + Effect.bind("scopeMapRef", () => Effect.map( + ScopeMap as unknown as Effect.Effect, + scopeMap => scopeMap.ref, + )), + Effect.let("key", () => ({})), + Effect.bind("scope", () => Scope.make(options?.finalizerExecutionStrategy ?? defaultOptions.finalizerExecutionStrategy)), + Effect.tap(({ scopeMapRef, key, scope }) => + Ref.update(scopeMapRef, HashMap.set(key, { + scope, + closeFiber: Option.none(), + })) ), // biome-ignore lint/correctness/useExhaustiveDependencies: use of React.DependencyList )), deps) // biome-ignore lint/correctness/useExhaustiveDependencies: only reactive on "key" - React.useEffect(() => Runtime.runSync(runtimeRef.current)(scopeMap.ref.pipe( - Effect.andThen(HashMap.get(key)), - Effect.tap(entry => Option.match(entry.closeFiber, { - onSome: fiber => Effect.andThen( - Ref.update(scopeMap.ref, HashMap.set(key, { ...entry, closeFiber: Option.none() })), - Fiber.interruptFork(fiber), - ), - onNone: () => Effect.void, - })), - Effect.map(({ scope }) => + React.useEffect(() => Runtime.runSync(runtimeRef.current)((ScopeMap as unknown as Effect.Effect).pipe( + Effect.map(scopeMap => scopeMap.ref), + Effect.tap(ref => ref.pipe( + Effect.andThen(HashMap.get(key)), + Effect.andThen(entry => Option.match(entry.closeFiber, { + onSome: Fiber.interruptFork, + onNone: () => Effect.void, + })), + )), + Effect.map(ref => () => Runtime.runSync(runtimeRef.current)(Effect.andThen( - Effect.forkDaemon(Effect.sleep(options?.finalizerExecutionDebounce ?? defaultOptions.finalizerExecutionDebounce).pipe( + Effect.sleep(options?.finalizerExecutionDebounce ?? defaultOptions.finalizerExecutionDebounce).pipe( Effect.andThen(Scope.close(scope, Exit.void)), - Effect.andThen(Ref.update(scopeMap.ref, HashMap.remove(key))), - )), - fiber => Ref.update(scopeMap.ref, HashMap.set(key, { + Effect.onExit(() => Ref.update(ref, HashMap.remove(key))), + Effect.forkDaemon, + ), + fiber => Ref.update(ref, HashMap.set(key, { scope, closeFiber: Option.some(fiber), })),