0.1.8 #11

Merged
Thilawyn merged 233 commits from next into master 2025-04-21 02:08:14 +02:00
Showing only changes of commit 6b74b9a3b2 - Show all commits

View File

@@ -108,41 +108,38 @@ export abstract class ReffuseHelpers<R> {
): A { ): A {
const runSync = this.useRunSync() const runSync = this.useRunSync()
// Calculate an initial version of the value so that it can be accessed during the first render const [isInitialRun, initialScope, initialValue] = React.useMemo(() => Effect.Do.pipe(
const [initialScope, initialValue] = React.useMemo(() => Scope.make(options?.finalizerExecutionStrategy).pipe( Effect.bind("isInitialRun", () => Ref.make(true)),
Effect.flatMap(scope => effect().pipe( Effect.bind("scope", () => Scope.make(options?.finalizerExecutionStrategy)),
Effect.provideService(Scope.Scope, scope), Effect.bind("value", ({ scope }) => Effect.provideService(effect(), Scope.Scope, scope)),
Effect.map(value => [scope, value] as const), Effect.map(({ isInitialRun, scope, value }) => [isInitialRun, scope, value] as const),
)),
runSync, 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(() => isInitialRun.pipe(
const closeInitialScopeIfNeeded = Scope.close(initialScope, Exit.void).pipe( Effect.if({
Effect.andThen(Effect.sync(() => { initialScopeClosed.current = true })), onTrue: () => Ref.set(isInitialRun, false).pipe(
Effect.when(() => !initialScopeClosed.current), Effect.map(() =>
) () => runSync(Scope.close(initialScope, Exit.void))
)
),
const [scope, value] = closeInitialScopeIfNeeded.pipe( onFalse: () => Effect.Do.pipe(
Effect.andThen(Scope.make(options?.finalizerExecutionStrategy).pipe( Effect.bind("scope", () => Scope.make(options?.finalizerExecutionStrategy)),
Effect.flatMap(scope => effect().pipe( Effect.bind("value", ({ scope }) => Effect.provideService(effect(), Scope.Scope, scope)),
Effect.provideService(Scope.Scope, scope), Effect.tap(({ value }) =>
Effect.map(value => [scope, value] as const), Effect.sync(() => setValue(value))
)) ),
)), Effect.map(({ scope }) =>
() => runSync(Scope.close(scope, Exit.void))
),
),
}),
runSync, runSync,
) ), [
setValue(value)
return () => { runSync(Scope.close(scope, Exit.void)) }
}, [
...options?.doNotReExecuteOnRuntimeOrContextChange ? [] : [runSync], ...options?.doNotReExecuteOnRuntimeOrContextChange ? [] : [runSync],
...deps, ...deps,
]) ])