import type { InitializedObservable } from '@noshiro/syncflow'; import { useCallback } from 'react'; import { useObservableReducer } from './use-observable-reducer'; type Action = Readonly< { type: 'set'; nextState: S } | { type: 'update'; updateFn: (a: S) => S } >; const reducer = (state: S, action: Action): S => { switch (action.type) { case 'set': return action.nextState; case 'update': return action.updateFn(state); } }; export const useObservableState = ( initialState: S ): Readonly<{ state$: InitializedObservable; setState: (v: S) => S; updateState: (updateFn: (prev: S) => S) => S; resetState: () => S; }> => { const [state$, dispatch] = useObservableReducer>( reducer, initialState ); const updateState = useCallback( (updateFn: (prev: S) => S): S => dispatch({ type: 'update', updateFn }), [] ); const setState = useCallback( (nextState: S): S => dispatch({ type: 'set', nextState }), [] ); const resetState = useCallback( (): S => dispatch({ type: 'set', nextState: initialState }), [] ); return { state$, setState, updateState, resetState }; };