import { Draft } from "immer"; /** * Context provided to the action factory function. * Gives actions access to read and write state. */ export interface ActionContext { /** Get the current state. Always returns the latest value, even mid-async-action. */ getState(): S; /** Replace the state entirely. Triggers a React re-render. */ setState(state: S): void; /** Update state using an immer recipe — mutate the draft freely. Triggers a React re-render. */ update(recipe: (draft: Draft) => void): void; } /** * Maps each action function to a queued version that returns a Promise. * Async actions preserve their return type. Sync actions get wrapped in Promise. */ export type QueuedActions = { [K in keyof A]: A[K] extends (...args: infer P) => Promise ? (...args: P) => Promise : A[K] extends (...args: infer P) => infer R ? (...args: P) => Promise : never; }; /** * A typesafe React hook for local state management with: * - Immer-powered immutable updates * - Async action support * - Serialized (one-at-a-time) action execution via a FIFO queue * - Fully typesafe actions — no action constants needed * * Actions are defined as plain functions in a factory closure. The factory * receives an {@link ActionContext} for reading and writing state. * * @param initialState - initial state value, or a lazy initializer function * @param actionFactory - function that receives an ActionContext and returns * a record of action functions * @returns a tuple of `[state, actions]` where actions are queued wrappers * of the originals * * @example * ```ts * const [state, actions] = useStateMachine( * { count: 0, loading: false }, * (ctx) => ({ * increment() { * ctx.update(draft => { draft.count++ }) * }, * async loadData(url: string) { * ctx.update(draft => { draft.loading = true }) * const data = await fetch(url).then(r => r.json()) * ctx.update(draft => { * draft.count = data.count * draft.loading = false * }) * return data * } * }) * ) * ``` */ export declare function useStateMachine any>>(initialState: S | (() => S), actionFactory: (ctx: ActionContext) => A): [S, QueuedActions];