This commit is contained in:
@@ -35,6 +35,7 @@
|
|||||||
"@effect/platform-browser": "^0.52.1",
|
"@effect/platform-browser": "^0.52.1",
|
||||||
"@radix-ui/themes": "^3.1.6",
|
"@radix-ui/themes": "^3.1.6",
|
||||||
"@typed/id": "^0.17.1",
|
"@typed/id": "^0.17.1",
|
||||||
|
"@typed/lazy-ref": "^0.3.3",
|
||||||
"lucide-react": "^0.471.1",
|
"lucide-react": "^0.471.1",
|
||||||
"mobx": "^6.13.5"
|
"mobx": "^6.13.5"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { R } from "@/reffuse"
|
import { R } from "@/reffuse"
|
||||||
import { createFileRoute } from "@tanstack/react-router"
|
import { createFileRoute } from "@tanstack/react-router"
|
||||||
|
import { GetRandomValues, makeUuid4 } from "@typed/id"
|
||||||
import { Console, Effect } from "effect"
|
import { Console, Effect } from "effect"
|
||||||
|
|
||||||
|
|
||||||
@@ -12,13 +13,11 @@ function RouteComponent() {
|
|||||||
// Effect.map(() => "test")
|
// Effect.map(() => "test")
|
||||||
// ))
|
// ))
|
||||||
|
|
||||||
R.useSuspenseScoped(Effect.addFinalizer(() => Console.log("cleanup")).pipe(
|
const value = R.useMemoScoped(Effect.addFinalizer(() => Console.log("cleanup")).pipe(
|
||||||
Effect.andThen(Effect.promise(() => new Promise<string>(resolve => {
|
Effect.andThen(makeUuid4),
|
||||||
setTimeout(() => { resolve("test") }, 0)
|
Effect.provide(GetRandomValues.CryptoRandom),
|
||||||
}))),
|
|
||||||
|
|
||||||
Effect.tap(Console.log),
|
|
||||||
), [])
|
), [])
|
||||||
|
console.log(value)
|
||||||
|
|
||||||
return <div>Hello "/tests"!</div>
|
return <div>Hello "/tests"!</div>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -99,13 +99,39 @@ export class Reffuse<R> {
|
|||||||
): A {
|
): A {
|
||||||
const runSync = this.useRunSync()
|
const runSync = this.useRunSync()
|
||||||
|
|
||||||
const initialValue = React.useMemo(() => runSync(Effect.scoped(effect)), [])
|
// 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.provideService(Scope.Scope, scope),
|
||||||
|
Effect.map(value => [scope, value] as const),
|
||||||
|
)),
|
||||||
|
|
||||||
|
runSync,
|
||||||
|
), [])
|
||||||
|
|
||||||
|
// Keep track of the state of the initial scope
|
||||||
|
const initialScopeClosed = React.useRef(false)
|
||||||
|
|
||||||
const [value, setValue] = React.useState(initialValue)
|
const [value, setValue] = React.useState(initialValue)
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
const scope = runSync(Scope.make(options?.finalizerExecutionStrategy))
|
const closeInitialScope = Scope.close(initialScope, Exit.void).pipe(
|
||||||
setValue(runSync(Effect.provideService(effect, Scope.Scope, scope)))
|
Effect.andThen(Effect.sync(() => { initialScopeClosed.current = true })),
|
||||||
|
Effect.when(() => !initialScopeClosed.current),
|
||||||
|
)
|
||||||
|
|
||||||
|
const [scope, value] = closeInitialScope.pipe(
|
||||||
|
Effect.andThen(Scope.make(options?.finalizerExecutionStrategy).pipe(
|
||||||
|
Effect.flatMap(scope => effect.pipe(
|
||||||
|
Effect.provideService(Scope.Scope, scope),
|
||||||
|
Effect.map(value => [scope, value] as const),
|
||||||
|
))
|
||||||
|
)),
|
||||||
|
|
||||||
|
runSync,
|
||||||
|
)
|
||||||
|
|
||||||
|
setValue(value)
|
||||||
return () => { runSync(Scope.close(scope, Exit.void)) }
|
return () => { runSync(Scope.close(scope, Exit.void)) }
|
||||||
}, [
|
}, [
|
||||||
...options?.doNotReExecuteOnRuntimeOrContextChange ? [] : [runSync],
|
...options?.doNotReExecuteOnRuntimeOrContextChange ? [] : [runSync],
|
||||||
|
|||||||
Reference in New Issue
Block a user