import { useCallback } from 'react'; import type { Selector } from '@wener/reaction'; import { maybeFunction, type MaybeFunction } from '@wener/utils'; import type { Draft } from 'mutative'; import { useStore, type StoreApi } from 'zustand'; import { useShallow } from 'zustand/react/shallow'; import type { HasComponentsState } from './ComponentsState'; import type { SetState } from './types'; type DraftUpdater = (update: Partial | ((state: Draft) => void)) => void; type DraftStore = Omit, 'setState'> & { setState: DraftUpdater; }; type UseViewComponentState = (name: string, selector?: Selector) => [R, SetState]; export function createViewComponentStateHook>( store: MaybeFunction, ): UseViewComponentState { return (name: string, selector?: Selector) => { const currentStore = maybeFunction(store); const state = useStore( currentStore, useShallow((s) => (selector ? selector((s.components[name] || {}) as T) : s.components[name] || {})), ) as R; return [ state, useCallback( (action) => { currentStore.setState((s) => { const prevState = (s.components[name] || {}) as any; const nextState = typeof action === 'function' ? (action(prevState) ?? prevState) : action; s.components[name] = nextState; }); }, [currentStore, name], ), ]; }; }