From 2b78d4dc4942d7e6faf58c7ccf49ee24592feeda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Sun, 29 Jun 2025 19:35:43 +0200 Subject: [PATCH] Cleanup --- .../effect-components/src/ReactComponent.ts | 117 ++++++++++-------- .../src/routes/effect-component-tests.tsx | 2 +- 2 files changed, 65 insertions(+), 54 deletions(-) diff --git a/packages/effect-components/src/ReactComponent.ts b/packages/effect-components/src/ReactComponent.ts index 6960543..d02102a 100644 --- a/packages/effect-components/src/ReactComponent.ts +++ b/packages/effect-components/src/ReactComponent.ts @@ -1,4 +1,4 @@ -import { Context, Effect, ExecutionStrategy, Exit, Ref, Runtime, Scope, Tracer } from "effect" +import { Context, Effect, Runtime, Tracer } from "effect" import * as React from "react" import * as ReactHook from "./ReactHook.js" @@ -14,67 +14,78 @@ export const useFC: { ( self: ReactComponent, options?: ReactHook.ScopeOptions, - ): Effect.Effect, never, Exclude> + ): Effect.Effect, never, R> } = Effect.fnUntraced(function* useFC( - self: ReactComponent, - options?: ReactHook.ScopeOptions, + self: ReactComponent ) { - const runtime = yield* Effect.runtime>() + const runtime = yield* Effect.runtime() - return React.useCallback((props: P) => { - const [isInitialRun, initialScope] = React.useMemo(() => Runtime.runSync(runtime)( - Effect.all([Ref.make(true), makeScope(options)]) - ), []) - const [scope, setScope] = React.useState(initialScope) - - React.useEffect(() => Runtime.runSync(runtime)( - Effect.if(isInitialRun, { - onTrue: () => Effect.as( - Ref.set(isInitialRun, false), - () => closeScope(scope, runtime, options), - ), - - onFalse: () => makeScope(options).pipe( - Effect.tap(scope => Effect.sync(() => setScope(scope))), - Effect.map(scope => () => closeScope(scope, runtime, options)), - ), - }) - ), []) - - return Runtime.runSync(runtime)( - Effect.provideService(self(props), Scope.Scope, scope) - ) - }, Array.from( + return React.useCallback((props: P) => Runtime.runSync(runtime)(self(props)), Array.from( Context.omit(...nonReactiveTags)(runtime.context).unsafeMap.values() )) }) -const makeScope = (options?: ReactHook.ScopeOptions) => Scope.make(options?.finalizerExecutionStrategy ?? ExecutionStrategy.sequential) -const closeScope = ( - scope: Scope.CloseableScope, - runtime: Runtime.Runtime, - options?: ReactHook.ScopeOptions, -) => { - switch (options?.finalizerExecutionMode ?? "sync") { - case "sync": - Runtime.runSync(runtime)(Scope.close(scope, Exit.void)) - break - case "fork": - Runtime.runFork(runtime)(Scope.close(scope, Exit.void)) - break - } -} - export const use: { ( self: ReactComponent, fn: (Component: React.FC

) => React.ReactNode, - options?: ReactHook.ScopeOptions, - ): Effect.Effect> -} = Effect.fnUntraced(function* use( - self: ReactComponent, - fn: (Component: React.FC

) => React.ReactNode, - options?: ReactHook.ScopeOptions, -) { - return fn(yield* useFC(self, options)) + ): Effect.Effect +} = Effect.fnUntraced(function* use(self, fn) { + return fn(yield* useFC(self)) }) + + +// export const useFC: { +// ( +// self: ReactComponent, +// options?: ReactHook.ScopeOptions, +// ): Effect.Effect, never, Exclude> +// } = Effect.fnUntraced(function* useFC( +// self: ReactComponent, +// options?: ReactHook.ScopeOptions, +// ) { +// const runtime = yield* Effect.runtime>() + +// return React.useCallback((props: P) => { +// const [isInitialRun, initialScope] = React.useMemo(() => Runtime.runSync(runtime)( +// Effect.all([Ref.make(true), makeScope(options)]) +// ), []) +// const [scope, setScope] = React.useState(initialScope) + +// React.useEffect(() => Runtime.runSync(runtime)( +// Effect.if(isInitialRun, { +// onTrue: () => Effect.as( +// Ref.set(isInitialRun, false), +// () => closeScope(scope, runtime, options), +// ), + +// onFalse: () => makeScope(options).pipe( +// Effect.tap(scope => Effect.sync(() => setScope(scope))), +// Effect.map(scope => () => closeScope(scope, runtime, options)), +// ), +// }) +// ), []) + +// return Runtime.runSync(runtime)( +// Effect.provideService(self(props), Scope.Scope, scope) +// ) +// }, Array.from( +// Context.omit(...nonReactiveTags)(runtime.context).unsafeMap.values() +// )) +// }) + +// const makeScope = (options?: ReactHook.ScopeOptions) => Scope.make(options?.finalizerExecutionStrategy ?? ExecutionStrategy.sequential) +// const closeScope = ( +// scope: Scope.CloseableScope, +// runtime: Runtime.Runtime, +// options?: ReactHook.ScopeOptions, +// ) => { +// switch (options?.finalizerExecutionMode ?? "sync") { +// case "sync": +// Runtime.runSync(runtime)(Scope.close(scope, Exit.void)) +// break +// case "fork": +// Runtime.runFork(runtime)(Scope.close(scope, Exit.void)) +// break +// } +// } diff --git a/packages/example/src/routes/effect-component-tests.tsx b/packages/example/src/routes/effect-component-tests.tsx index 5d6ad78..1a09eb9 100644 --- a/packages/example/src/routes/effect-component-tests.tsx +++ b/packages/example/src/routes/effect-component-tests.tsx @@ -27,7 +27,7 @@ class TestService extends Effect.Service()("TestService", { const MyTestComponent = Effect.fn(function* MyTestComponent(props?: { readonly value?: string }) { const [state, setState] = React.useState("value") - // yield* ReactHook.useMemo(() => Effect.andThen( + // yield* ReactHook.useEffect(() => Effect.andThen( // Effect.addFinalizer(() => Console.log("MyTestComponent umounted")), // Console.log("MyTestComponent mounted"), // ), [])