diff --git a/packages/example/src/routes/tests.tsx b/packages/example/src/routes/tests.tsx index 729f1e0..1dee1f5 100644 --- a/packages/example/src/routes/tests.tsx +++ b/packages/example/src/routes/tests.tsx @@ -1,6 +1,6 @@ import { R } from "@/reffuse" import { createFileRoute } from "@tanstack/react-router" -import { Console, Effect } from "effect" +import { Effect } from "effect" export const Route = createFileRoute("/tests")({ @@ -8,9 +8,12 @@ export const Route = createFileRoute("/tests")({ }) function RouteComponent() { - R.useMemo(Effect.addFinalizer(() => Console.log("Cleanup!")).pipe( - Effect.map(() => "test") - )) + // R.useMemo(Effect.addFinalizer(() => Console.log("Cleanup!")).pipe( + // Effect.map(() => "test") + // )) + + const value = R.useSuspense(Effect.succeed("test")) + console.log(value) return
Hello "/tests"!
} diff --git a/packages/reffuse/src/Reffuse.ts b/packages/reffuse/src/Reffuse.ts index f6b7fac..e30a56d 100644 --- a/packages/reffuse/src/Reffuse.ts +++ b/packages/reffuse/src/Reffuse.ts @@ -55,6 +55,19 @@ export class Reffuse { ), [runtime, context]) } + useRunCallback() { + const runtime = ReffuseRuntime.useRuntime() + const context = this.useContext() + + return React.useCallback(( + effect: Effect.Effect, + options?: Runtime.RunCallbackOptions, + ): Runtime.Cancel => effect.pipe( + Effect.provide(context), + effect => Runtime.runCallback(runtime)(effect, options), + ), [runtime, context]) + } + /** * ⚠️ Scope closing on cleanup is currently broken when using React strict mode! ⚠️ @@ -213,18 +226,44 @@ export class Reffuse { ]) } + // useSuspense( + // effect: Effect.Effect, + // deps?: React.DependencyList, + // options?: { readonly signal?: AbortSignal } & RenderOptions, + // ): A { + // const runPromise = this.useRunPromise() + + // const promise = React.useMemo(() => runPromise(effect, options), [ + // ...options?.doNotReExecuteOnRuntimeOrContextChange ? [] : [runPromise], + // ...(deps ?? []), + // ]) + // return React.use(promise) + // } + useSuspense( effect: Effect.Effect, deps?: React.DependencyList, - options?: { readonly signal?: AbortSignal } & RenderOptions, + options?: RenderOptions, ): A { - const runPromise = this.useRunPromise() + const runSync = this.useRunPromise() + const runCallback = this.useRunCallback() - const promise = React.useMemo(() => runPromise(effect, options), [ - ...options?.doNotReExecuteOnRuntimeOrContextChange ? [] : [runPromise], - ...(deps ?? []), - ]) - return React.use(promise) + const promiseRef = React.useRef(Promise.withResolvers().promise) + + React.useEffect(() => { + const { promise, resolve, reject } = Promise.withResolvers() + promiseRef.current = promise + + runCallback(effect, { + onExit: Exit.mapBoth({ + onSuccess: resolve, + onFailure: reject, + }) + }) + }, deps) + + console.log(promiseRef.current) + return React.use(promiseRef.current) } /**