diff --git a/packages/example/src/routes/tests.tsx b/packages/example/src/routes/tests.tsx index 51ce6a5..8d077ce 100644 --- a/packages/example/src/routes/tests.tsx +++ b/packages/example/src/routes/tests.tsx @@ -2,7 +2,7 @@ import { R } from "@/reffuse" import { Button, Flex, Text } from "@radix-ui/themes" import { createFileRoute } from "@tanstack/react-router" import { GetRandomValues, makeUuid4 } from "@typed/id" -import { Console, Effect, Option, Scope } from "effect" +import { Console, Effect, Option } from "effect" import { useEffect, useState } from "react" @@ -24,13 +24,13 @@ function RouteComponent() { const uuidStream = R.useStreamFromReactiveValues([uuid]) const uuidStreamLatestValue = R.useSubscribeStream(uuidStream) - const scope = R.useScope([uuid]) + const [, scopeLayer] = R.useScope([uuid]) useEffect(() => Effect.addFinalizer(() => Console.log("Scope cleanup!")).pipe( Effect.andThen(Console.log("Scope changed")), - Effect.provideService(Scope.Scope, scope), + Effect.provide(scopeLayer), runSync, - ), [scope, runSync]) + ), [scopeLayer, runSync]) return ( diff --git a/packages/reffuse/src/ReffuseNamespace.ts b/packages/reffuse/src/ReffuseNamespace.ts index 4070cc5..ddf3e01 100644 --- a/packages/reffuse/src/ReffuseNamespace.ts +++ b/packages/reffuse/src/ReffuseNamespace.ts @@ -1,4 +1,4 @@ -import { type Context, Effect, ExecutionStrategy, Exit, type Fiber, type Layer, Match, Option, pipe, Pipeable, PubSub, Ref, Runtime, Scope, Stream, SubscriptionRef } from "effect" +import { type Context, Effect, ExecutionStrategy, Exit, type Fiber, Layer, Match, Option, pipe, Pipeable, PubSub, Ref, Runtime, Scope, Stream, SubscriptionRef } from "effect" import * as React from "react" import * as ReffuseContext from "./ReffuseContext.js" import * as ReffuseRuntime from "./ReffuseRuntime.js" @@ -98,7 +98,7 @@ export abstract class ReffuseNamespace { this: ReffuseNamespace, deps: React.DependencyList = [], options?: UseScopeOptions, - ): Scope.Scope { + ): readonly [scope: Scope.Scope, layer: Layer.Layer] { const runSync = this.useRunSync() const runFork = this.useRunFork() @@ -115,10 +115,9 @@ export abstract class ReffuseNamespace { ) ) - const [isInitialRun, initialScope] = React.useMemo(() => runSync(Effect.all([ - Ref.make(true), - makeScope, - ])), [makeScope]) + const [isInitialRun, initialScope] = React.useMemo(() => runSync( + Effect.all([Ref.make(true), makeScope]) + ), [makeScope]) const [scope, setScope] = React.useState(initialScope) @@ -142,7 +141,7 @@ export abstract class ReffuseNamespace { ...deps, ]) - return scope + return React.useMemo(() => [scope, Layer.succeed(Scope.Scope, scope)] as const, [scope]) } /** @@ -490,7 +489,7 @@ export abstract class ReffuseNamespace { this: ReffuseNamespace, values: A, ): Stream.Stream { - const scope = this.useScope([], { finalizerExecutionMode: "fork" }) + const [, scopeLayer] = this.useScope([], { finalizerExecutionMode: "fork" }) const { latest, pubsub, stream } = this.useMemo(() => Effect.Do.pipe( Effect.bind("latest", () => Ref.make(values)), @@ -502,8 +501,8 @@ export abstract class ReffuseNamespace { )), Stream.unwrapScoped, )), - Effect.provideService(Scope.Scope, scope), - ), [scope], { doNotReExecuteOnRuntimeOrContextChange: true }) + Effect.provide(scopeLayer), + ), [scopeLayer], { doNotReExecuteOnRuntimeOrContextChange: true }) this.useEffect(() => Ref.set(latest, values).pipe( Effect.andThen(PubSub.publish(pubsub, values)),