import { Effect, Equivalence, Ref, Stream, SubscriptionRef } from "effect" import * as React from "react" import * as Component from "./Component.js" import * as SetStateAction from "./SetStateAction.js" export declare namespace useSubscriptionRefState { export interface Options { readonly equivalence?: Equivalence.Equivalence } } export const useSubscriptionRefState = Effect.fnUntraced(function* ( ref: SubscriptionRef.SubscriptionRef, options?: useSubscriptionRefState.Options>, ): Effect.fn.Return>]> { const [reactStateValue, setReactStateValue] = React.useState(yield* Component.useOnMount(() => ref)) yield* Component.useReactEffect(() => Effect.forkScoped( Stream.runForEach( Stream.changesWith(ref.changes, options?.equivalence ?? Equivalence.strict()), v => Effect.sync(() => setReactStateValue(v)), ) ), [ref]) const setValue = yield* Component.useCallbackSync( (setStateAction: React.SetStateAction) => Effect.andThen( Ref.updateAndGet(ref, prevState => SetStateAction.value(setStateAction, prevState)), v => setReactStateValue(v), ), [ref], ) return [reactStateValue, setValue] }) export declare namespace useSubscriptionRefFromState { export interface Options { readonly equivalence?: Equivalence.Equivalence } } export const useSubscriptionRefFromState = Effect.fnUntraced(function* ( [value, setValue]: readonly [A, React.Dispatch>], options?: useSubscriptionRefFromState.Options>, ): Effect.fn.Return> { const ref = yield* Component.useOnChange(() => Effect.tap( SubscriptionRef.make(value), ref => Effect.forkScoped( Stream.runForEach( Stream.changesWith(ref.changes, options?.equivalence ?? Equivalence.strict()), v => Effect.sync(() => setValue(v)), ) ), ), [setValue]) yield* Component.useReactEffect(() => Ref.set(ref, value), [value]) return ref }) export * from "effect/SubscriptionRef"