0.1.13 #18

Merged
Thilawyn merged 359 commits from next into master 2025-06-18 00:12:19 +02:00
Showing only changes of commit 0a4bb2856d - Show all commits

View File

@@ -23,28 +23,26 @@ export type R<T> = T extends ReffuseContext<infer R> ? R : never
export type ReactProvider<R> = React.FC<{ export type ReactProvider<R> = React.FC<{
readonly layer: Layer.Layer<R, unknown> readonly layer: Layer.Layer<R, unknown, Scope.Scope>
readonly children?: React.ReactNode readonly children?: React.ReactNode
}> }>
const makeProvider = <R>(Context: React.Context<Context.Context<R>>): ReactProvider<R> => { const makeProvider = <R>(Context: React.Context<Context.Context<R>>): ReactProvider<R> => {
return function ReffuseContextReactProvider(props) { return function ReffuseContextReactProvider(props) {
const runtime = ReffuseRuntime.useRuntime() const runtime = ReffuseRuntime.useRuntime()
const runSync = React.useMemo(() => Runtime.runSync(runtime), [runtime])
const makeScopeAndContext = React.useMemo(() => Effect.Do.pipe( const makeContext = React.useCallback((scope: Scope.CloseableScope) => Effect.context<R>().pipe(
Effect.bind("scope", () => Scope.make()), Effect.provide(props.layer),
Effect.bind("context", ({ scope }) => Effect.context<R>().pipe( Effect.provideService(Scope.Scope, scope),
Effect.provide(props.layer),
Effect.provideService(Scope.Scope, scope),
)),
Effect.map(({ scope, context }) => [scope, context] as const),
), [props.layer]) ), [props.layer])
const [isInitialRun, initialScope, initialValue] = React.useMemo(() => Effect.Do.pipe( const [isInitialRun, initialScope, initialValue] = React.useMemo(() => Effect.Do.pipe(
Effect.bind("isInitialRun", () => Ref.make(true)), Effect.bind("isInitialRun", () => Ref.make(true)),
Effect.bind("scopeAndContext", () => makeScopeAndContext), Effect.bind("scope", () => Scope.make()),
Effect.map(({ isInitialRun, scopeAndContext }) => [isInitialRun, ...scopeAndContext] as const), Effect.bind("context", ({ scope }) => makeContext(scope)),
Runtime.runSync(runtime), Effect.map(({ isInitialRun, scope, context }) => [isInitialRun, scope, context] as const),
runSync,
), []) ), [])
const [value, setValue] = React.useState(initialValue) const [value, setValue] = React.useState(initialValue)
@@ -54,13 +52,19 @@ const makeProvider = <R>(Context: React.Context<Context.Context<R>>): ReactProvi
onTrue: () => Ref.set(isInitialRun, false), onTrue: () => Ref.set(isInitialRun, false),
onFalse: () => Effect.Do.pipe( onFalse: () => Effect.Do.pipe(
Effect.tap(Scope.close(initialScope, Exit.void)), Effect.tap(Scope.close(initialScope, Exit.void)),
Effect.bind("scopeAndContext", () => makeScopeAndContext), Effect.bind("scope", () => Scope.make()),
Effect.tap(({ scopeAndContext }) => Effect.sync(() => setValue())) Effect.bind("context", ({ scope }) => makeContext(scope)),
Effect.tap(({ context }) =>
Effect.sync(() => setValue(context))
),
Effect.map(({ scope }) =>
() => runSync(Scope.close(scope, Exit.void))
),
), ),
}), }),
Runtime.runSync(runtime), runSync,
), [makeScopeAndContext, runtime]) ), [makeContext, runSync])
return React.createElement(Context, { ...props, value }) return React.createElement(Context, { ...props, value })
} }