import { Effect, Equivalence, Ref, Stream, type SubscriptionRef } from "effect" import * as React from "react" import * as SetStateAction from "../SetStateAction.js" import { useCallbackSync } from "./useCallbackSync.js" import { useFork } from "./useFork.js" import { useOnce } from "./useOnce.js" export const useRefState: { ( ref: SubscriptionRef.SubscriptionRef ): Effect.Effect>]> } = Effect.fnUntraced(function* (ref: SubscriptionRef.SubscriptionRef) { const [reactStateValue, setReactStateValue] = React.useState(yield* useOnce(() => ref)) yield* useFork(() => Stream.runForEach( Stream.changesWith(ref.changes, Equivalence.strict()), v => Effect.sync(() => setReactStateValue(v)), ), [ref]) const setValue = yield* useCallbackSync((setStateAction: React.SetStateAction) => Effect.andThen( Ref.updateAndGet(ref, prevState => SetStateAction.value(setStateAction, prevState)), v => setReactStateValue(v), ), [ref]) return [reactStateValue, setValue] })