diff --git a/packages/extension-lazyref/package.json b/packages/extension-lazyref/package.json index 5991388..f126cdd 100644 --- a/packages/extension-lazyref/package.json +++ b/packages/extension-lazyref/package.json @@ -1,6 +1,6 @@ { "name": "@reffuse/extension-lazyref", - "version": "0.1.2", + "version": "0.1.3", "type": "module", "files": [ "./README.md", @@ -37,6 +37,6 @@ "@types/react": "^19.0.0", "effect": "^3.13.0", "react": "^19.0.0", - "reffuse": "^0.1.6" + "reffuse": "^0.1.7" } } diff --git a/packages/extension-lazyref/src/index.ts b/packages/extension-lazyref/src/index.ts index 42b76ec..7a51a86 100644 --- a/packages/extension-lazyref/src/index.ts +++ b/packages/extension-lazyref/src/index.ts @@ -1,16 +1,43 @@ import * as LazyRef from "@typed/lazy-ref" -import { Effect, Stream } from "effect" +import { Effect, pipe, Stream } from "effect" import * as React from "react" import { ReffuseExtension, type ReffuseNamespace, SetStateAction } from "reffuse" export const LazyRefExtension = ReffuseExtension.make(() => ({ + useSubscribeLazyRefs< + const Refs extends readonly LazyRef.LazyRef[], + R, + >( + this: ReffuseNamespace.ReffuseNamespace, + ...refs: Refs + ): [...{ [K in keyof Refs]: Effect.Effect.Success }] { + const [reactStateValue, setReactStateValue] = React.useState(this.useMemo( + () => Effect.all(refs as readonly LazyRef.LazyRef[]), + [], + { doNotReExecuteOnRuntimeOrContextChange: true }, + ) as [...{ [K in keyof Refs]: Effect.Effect.Success }]) + + this.useFork(() => pipe( + refs.map(ref => Stream.changesWith(ref.changes, (x, y) => x === y)), + streams => Stream.zipLatestAll(...streams), + Stream.runForEach(v => + Effect.sync(() => setReactStateValue(v as [...{ [K in keyof Refs]: Effect.Effect.Success }])) + ), + ), refs) + + return reactStateValue + }, + useLazyRefState( this: ReffuseNamespace.ReffuseNamespace, ref: LazyRef.LazyRef, ): [A, React.Dispatch>] { - const initialState = this.useMemo(() => ref, [], { doNotReExecuteOnRuntimeOrContextChange: true }) - const [reactStateValue, setReactStateValue] = React.useState(initialState) + const [reactStateValue, setReactStateValue] = React.useState(this.useMemo( + () => ref, + [], + { doNotReExecuteOnRuntimeOrContextChange: true }, + )) this.useFork(() => Stream.runForEach( Stream.changesWith(ref.changes, (x, y) => x === y), diff --git a/packages/reffuse/package.json b/packages/reffuse/package.json index cd66e15..5e189c2 100644 --- a/packages/reffuse/package.json +++ b/packages/reffuse/package.json @@ -1,6 +1,6 @@ { "name": "reffuse", - "version": "0.1.6", + "version": "0.1.7", "type": "module", "files": [ "./README.md", diff --git a/packages/reffuse/src/ReffuseNamespace.ts b/packages/reffuse/src/ReffuseNamespace.ts index 4ed41b7..a6d56e3 100644 --- a/packages/reffuse/src/ReffuseNamespace.ts +++ b/packages/reffuse/src/ReffuseNamespace.ts @@ -419,8 +419,11 @@ export abstract class ReffuseNamespace { this: ReffuseNamespace, ref: SubscriptionRef.SubscriptionRef, ): [A, React.Dispatch>] { - const initialState = this.useMemo(() => ref, [], { doNotReExecuteOnRuntimeOrContextChange: true }) - const [reactStateValue, setReactStateValue] = React.useState(initialState) + const [reactStateValue, setReactStateValue] = React.useState(this.useMemo( + () => ref, + [], + { doNotReExecuteOnRuntimeOrContextChange: true }, + )) this.useFork(() => Stream.runForEach( Stream.changesWith(ref.changes, (x, y) => x === y),