diff --git a/packages/example/src/routes/tests.tsx b/packages/example/src/routes/tests.tsx index 64bac4d..578578d 100644 --- a/packages/example/src/routes/tests.tsx +++ b/packages/example/src/routes/tests.tsx @@ -3,6 +3,8 @@ import { Button, Flex, Text } from "@radix-ui/themes" import { createFileRoute } from "@tanstack/react-router" import { GetRandomValues, makeUuid4 } from "@typed/id" import { Console, Effect, Ref } from "effect" +import { useMemo } from "react" +import { SubscriptionSubRef } from "reffuse" export const Route = createFileRoute("/tests")({ @@ -10,6 +12,13 @@ export const Route = createFileRoute("/tests")({ }) function RouteComponent() { + const deepRef = R.useRef({ value: "poulet" }) + const deepValueRef = useMemo(() => SubscriptionSubRef.make( + deepRef, + b => b.value, + (b, a) => ({ ...b, value: a }), + ), [deepRef]) + // const value = R.useMemoScoped(Effect.addFinalizer(() => Console.log("cleanup")).pipe( // Effect.andThen(makeUuid4), // Effect.provide(GetRandomValues.CryptoRandom), @@ -32,7 +41,8 @@ function RouteComponent() { const generateUuid = R.useCallbackSync(() => makeUuid4.pipe( Effect.provide(GetRandomValues.CryptoRandom), - Effect.flatMap(v => Ref.set(uuidRef, v)), + Effect.tap(v => Ref.set(uuidRef, v)), + Effect.tap(v => Ref.set(deepValueRef, v)), ), []) @@ -42,6 +52,10 @@ function RouteComponent() { {(uuid, anotherRef) => {uuid} / {anotherRef}} + + {(deep, deepValue) => {JSON.stringify(deep)} / {deepValue}} + + diff --git a/packages/reffuse/src/SubscriptionSubRef.ts b/packages/reffuse/src/SubscriptionSubRef.ts index 60e08ac..13a2e44 100644 --- a/packages/reffuse/src/SubscriptionSubRef.ts +++ b/packages/reffuse/src/SubscriptionSubRef.ts @@ -27,7 +27,7 @@ class SubscriptionSubRefImpl extends Effectable.Class imp constructor( readonly ref: SubscriptionRef.SubscriptionRef, readonly select: (value: B) => A, - readonly setter: (value: A) => B, + readonly setter: (value: B, subValue: A) => B, ) { super() this.get = Ref.get(this.ref).pipe(Effect.map(this.select)) @@ -52,11 +52,11 @@ class SubscriptionSubRefImpl extends Effectable.Class imp } modifyEffect(f: (a: A) => Effect.Effect): Effect.Effect { - return this.get.pipe( - Effect.flatMap(f), - Effect.flatMap(([b, a]) => Ref.set(this.ref, this.setter(a)).pipe( - Effect.as(b) - )), + return Effect.Do.pipe( + Effect.bind("b", () => Ref.get(this.ref)), + Effect.bind("ca", ({ b }) => f(this.select(b))), + Effect.tap(({ b, ca: [, a] }) => Ref.set(this.ref, this.setter(b, a))), + Effect.map(({ ca: [c] }) => c), ) } } @@ -65,5 +65,5 @@ class SubscriptionSubRefImpl extends Effectable.Class imp export const make = ( ref: SubscriptionRef.SubscriptionRef, select: (value: B) => A, - setter: (value: A) => B, + setter: (value: B, subValue: A) => B, ): SubscriptionSubRef => new SubscriptionSubRefImpl(ref, select, setter)