From 44de864713c1c5fef4058436d50aa63e14eaf5eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Tue, 25 Feb 2025 14:48:58 +0100 Subject: [PATCH] API update --- packages/example/src/routes/lazyref.tsx | 2 +- packages/example/src/routes/promise.tsx | 2 +- packages/example/src/routes/tests.tsx | 2 +- packages/example/src/routes/time.tsx | 4 +- packages/example/src/todos/views/VNewTodo.tsx | 2 +- packages/example/src/todos/views/VTodos.tsx | 4 +- packages/extension-lazyref/src/index.ts | 2 +- packages/reffuse/src/ReffuseHelpers.ts | 68 +++++++++---------- 8 files changed, 42 insertions(+), 44 deletions(-) diff --git a/packages/example/src/routes/lazyref.tsx b/packages/example/src/routes/lazyref.tsx index 586f25c..32d8187 100644 --- a/packages/example/src/routes/lazyref.tsx +++ b/packages/example/src/routes/lazyref.tsx @@ -10,7 +10,7 @@ export const Route = createFileRoute("/lazyref")({ }) function RouteComponent() { - const promise = R.usePromise(LazyRef.of(0)) + const promise = R.usePromise(() => LazyRef.of(0)) return ( Loading...}> diff --git a/packages/example/src/routes/promise.tsx b/packages/example/src/routes/promise.tsx index 58c1452..09af62a 100644 --- a/packages/example/src/routes/promise.tsx +++ b/packages/example/src/routes/promise.tsx @@ -15,7 +15,7 @@ const Result = Schema.Tuple(Schema.String) type Result = typeof Result.Type function RouteComponent() { - const promise = R.usePromise(Effect.addFinalizer(() => Console.log("Cleanup")).pipe( + 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), diff --git a/packages/example/src/routes/tests.tsx b/packages/example/src/routes/tests.tsx index 82b6919..ab6e89a 100644 --- a/packages/example/src/routes/tests.tsx +++ b/packages/example/src/routes/tests.tsx @@ -14,7 +14,7 @@ function RouteComponent() { // ), []) // console.log(value) - R.useFork(Effect.addFinalizer(() => Console.log("cleanup")).pipe( + R.useFork(() => Effect.addFinalizer(() => Console.log("cleanup")).pipe( Effect.andThen(Console.log("ouient")), Effect.delay("1 second"), )) diff --git a/packages/example/src/routes/time.tsx b/packages/example/src/routes/time.tsx index 7332f6b..f99f979 100644 --- a/packages/example/src/routes/time.tsx +++ b/packages/example/src/routes/time.tsx @@ -15,9 +15,9 @@ export const Route = createFileRoute("/time")({ function Time() { - const timeRef = R.useMemo(DateTime.now.pipe(Effect.flatMap(SubscriptionRef.make))) + const timeRef = R.useMemo(() => DateTime.now.pipe(Effect.flatMap(SubscriptionRef.make))) - R.useFork(Effect.addFinalizer(() => Console.log("Cleanup")).pipe( + R.useFork(() => Effect.addFinalizer(() => Console.log("Cleanup")).pipe( Effect.andThen(Stream.runForEach(timeEverySecond, v => Ref.set(timeRef, v))) ), [timeRef]) diff --git a/packages/example/src/todos/views/VNewTodo.tsx b/packages/example/src/todos/views/VNewTodo.tsx index ccb4346..2328006 100644 --- a/packages/example/src/todos/views/VNewTodo.tsx +++ b/packages/example/src/todos/views/VNewTodo.tsx @@ -18,7 +18,7 @@ export function VNewTodo() { const runSync = R.useRunSync() - const todoRef = R.useMemo(createEmptyTodo.pipe(Effect.flatMap(SubscriptionRef.make))) + const todoRef = R.useMemo(() => createEmptyTodo.pipe(Effect.flatMap(SubscriptionRef.make))) const [todo, setTodo] = R.useRefState(todoRef) diff --git a/packages/example/src/todos/views/VTodos.tsx b/packages/example/src/todos/views/VTodos.tsx index c747afa..83485b0 100644 --- a/packages/example/src/todos/views/VTodos.tsx +++ b/packages/example/src/todos/views/VTodos.tsx @@ -9,13 +9,13 @@ import { VTodo } from "./VTodo" export function VTodos() { // Sync changes to the todos with the local storage - R.useFork(TodosState.TodosState.pipe( + R.useFork(() => TodosState.TodosState.pipe( Effect.flatMap(state => Stream.runForEach(state.todos.changes, () => state.saveToLocalStorage) ) )) - const todosRef = R.useMemo(TodosState.TodosState.pipe(Effect.map(state => state.todos))) + const todosRef = R.useMemo(() => TodosState.TodosState.pipe(Effect.map(state => state.todos))) const [todos] = R.useRefState(todosRef) diff --git a/packages/extension-lazyref/src/index.ts b/packages/extension-lazyref/src/index.ts index 42728c5..e5fbb02 100644 --- a/packages/extension-lazyref/src/index.ts +++ b/packages/extension-lazyref/src/index.ts @@ -14,7 +14,7 @@ export const LazyRefExtension = ReffuseExtension.make(() => ({ const initialState = React.useMemo(() => runSync(ref), []) const [reactStateValue, setReactStateValue] = React.useState(initialState) - this.useFork(Stream.runForEach(ref.changes, v => Effect.sync(() => + this.useFork(() => Stream.runForEach(ref.changes, v => Effect.sync(() => setReactStateValue(v) )), [ref]) diff --git a/packages/reffuse/src/ReffuseHelpers.ts b/packages/reffuse/src/ReffuseHelpers.ts index 1605791..08a8ebc 100644 --- a/packages/reffuse/src/ReffuseHelpers.ts +++ b/packages/reffuse/src/ReffuseHelpers.ts @@ -24,52 +24,50 @@ export abstract class ReffuseHelpers { } - useRunSync(this: ReffuseHelpers) { + useRunSync(this: ReffuseHelpers): (effect: Effect.Effect) => A { const runtime = ReffuseRuntime.useRuntime() const context = this.useContext() - return React.useCallback(( - effect: Effect.Effect - ): A => effect.pipe( + return React.useCallback(effect => effect.pipe( Effect.provide(context), Runtime.runSync(runtime), ), [runtime, context]) } - useRunPromise(this: ReffuseHelpers) { + useRunPromise(this: ReffuseHelpers): ( + effect: Effect.Effect, + options?: { readonly signal?: AbortSignal }, + ) => Promise { const runtime = ReffuseRuntime.useRuntime() const context = this.useContext() - return React.useCallback(( - effect: Effect.Effect, - options?: { readonly signal?: AbortSignal }, - ): Promise => effect.pipe( + return React.useCallback((effect, options) => effect.pipe( Effect.provide(context), effect => Runtime.runPromise(runtime)(effect, options), ), [runtime, context]) } - useRunFork(this: ReffuseHelpers) { + useRunFork(this: ReffuseHelpers): ( + effect: Effect.Effect, + options?: Runtime.RunForkOptions, + ) => Fiber.RuntimeFiber { const runtime = ReffuseRuntime.useRuntime() const context = this.useContext() - return React.useCallback(( - effect: Effect.Effect, - options?: Runtime.RunForkOptions, - ): Fiber.RuntimeFiber => effect.pipe( + return React.useCallback((effect, options) => effect.pipe( Effect.provide(context), effect => Runtime.runFork(runtime)(effect, options), ), [runtime, context]) } - useRunCallback(this: ReffuseHelpers) { + useRunCallback(this: ReffuseHelpers): ( + effect: Effect.Effect, + options?: Runtime.RunCallbackOptions, + ) => Runtime.Cancel { const runtime = ReffuseRuntime.useRuntime() const context = this.useContext() - return React.useCallback(( - effect: Effect.Effect, - options?: Runtime.RunCallbackOptions, - ): Runtime.Cancel => effect.pipe( + return React.useCallback((effect, options) => effect.pipe( Effect.provide(context), effect => Runtime.runCallback(runtime)(effect, options), ), [runtime, context]) @@ -87,13 +85,13 @@ export abstract class ReffuseHelpers { */ useMemo( this: ReffuseHelpers, - effect: Effect.Effect, + effect: () => Effect.Effect, deps?: React.DependencyList, options?: RenderOptions, ): A { const runSync = this.useRunSync() - return React.useMemo(() => runSync(effect), [ + return React.useMemo(() => runSync(effect()), [ ...options?.doNotReExecuteOnRuntimeOrContextChange ? [] : [runSync], ...(deps ?? []), ]) @@ -101,7 +99,7 @@ export abstract class ReffuseHelpers { useMemoScoped( this: ReffuseHelpers, - effect: Effect.Effect, + effect: () => Effect.Effect, deps?: React.DependencyList, options?: RenderOptions & ScopeOptions, ): A { @@ -109,7 +107,7 @@ export abstract class ReffuseHelpers { // Calculate an initial version of the value so that it can be accessed during the first render const [initialScope, initialValue] = React.useMemo(() => Scope.make(options?.finalizerExecutionStrategy).pipe( - Effect.flatMap(scope => effect.pipe( + Effect.flatMap(scope => effect().pipe( Effect.provideService(Scope.Scope, scope), Effect.map(value => [scope, value] as const), )), @@ -130,7 +128,7 @@ export abstract class ReffuseHelpers { const [scope, value] = closeInitialScopeIfNeeded.pipe( Effect.andThen(Scope.make(options?.finalizerExecutionStrategy).pipe( - Effect.flatMap(scope => effect.pipe( + Effect.flatMap(scope => effect().pipe( Effect.provideService(Scope.Scope, scope), Effect.map(value => [scope, value] as const), )) @@ -177,15 +175,15 @@ export abstract class ReffuseHelpers { */ useEffect( this: ReffuseHelpers, - effect: Effect.Effect, + effect: () => Effect.Effect, deps?: React.DependencyList, options?: RenderOptions & ScopeOptions, ): void { const runSync = this.useRunSync() - return React.useEffect(() => { + React.useEffect(() => { const scope = Scope.make(options?.finalizerExecutionStrategy).pipe( - Effect.tap(scope => Effect.provideService(effect, Scope.Scope, scope)), + Effect.tap(scope => Effect.provideService(effect(), Scope.Scope, scope)), runSync, ) @@ -225,7 +223,7 @@ export abstract class ReffuseHelpers { */ useLayoutEffect( this: ReffuseHelpers, - effect: Effect.Effect, + effect: () => Effect.Effect, deps?: React.DependencyList, options?: RenderOptions & ScopeOptions, ): void { @@ -233,7 +231,7 @@ export abstract class ReffuseHelpers { return React.useLayoutEffect(() => { const scope = Scope.make(options?.finalizerExecutionStrategy).pipe( - Effect.tap(scope => Effect.provideService(effect, Scope.Scope, scope)), + Effect.tap(scope => Effect.provideService(effect(), Scope.Scope, scope)), runSync, ) @@ -273,7 +271,7 @@ export abstract class ReffuseHelpers { */ useFork( this: ReffuseHelpers, - effect: Effect.Effect, + effect: () => Effect.Effect, deps?: React.DependencyList, options?: Runtime.RunForkOptions & RenderOptions & ScopeOptions, ): void { @@ -285,7 +283,7 @@ export abstract class ReffuseHelpers { ? Scope.fork(options.scope, options?.finalizerExecutionStrategy ?? ExecutionStrategy.sequential) : Scope.make(options?.finalizerExecutionStrategy) ) - runFork(Effect.provideService(effect, Scope.Scope, scope), { ...options, scope }) + runFork(Effect.provideService(effect(), Scope.Scope, scope), { ...options, scope }) return () => { runFork(Scope.close(scope, Exit.void)) } }, [ @@ -296,7 +294,7 @@ export abstract class ReffuseHelpers { usePromise( this: ReffuseHelpers, - effect: Effect.Effect, + effect: () => Effect.Effect, deps?: React.DependencyList, options?: { readonly signal?: AbortSignal } & Runtime.RunForkOptions & RenderOptions & ScopeOptions, ): Promise { @@ -318,7 +316,7 @@ export abstract class ReffuseHelpers { if (options?.signal) options.signal.addEventListener("abort", cleanup) - effect.pipe( + effect().pipe( Effect.provideService(Scope.Scope, scope), Effect.match({ onSuccess: resolve, @@ -347,7 +345,7 @@ export abstract class ReffuseHelpers { value: A, ): SubscriptionRef.SubscriptionRef { return this.useMemo( - SubscriptionRef.make(value), + () => SubscriptionRef.make(value), [], { doNotReExecuteOnRuntimeOrContextChange: true }, // Do not recreate the ref when the context changes ) @@ -369,7 +367,7 @@ export abstract class ReffuseHelpers { const initialState = React.useMemo(() => runSync(ref), []) const [reactStateValue, setReactStateValue] = React.useState(initialState) - this.useFork(Stream.runForEach(ref.changes, v => Effect.sync(() => + this.useFork(() => Stream.runForEach(ref.changes, v => Effect.sync(() => setReactStateValue(v) )), [ref])