{"version":3,"file":"hooks-RMagaUHm.mjs","names":[],"sources":["../src/hooks-utils.ts","../src/hooks-shared.ts","../src/hooks.ts"],"sourcesContent":["import * as React from \"react\";\nimport type { HookActionStatus, HookCallbacks, HookShorthandStatus } from \"./hooks.types\";\nimport type { NormalizeActionResult, SafeActionResult } from \"./index.types\";\nimport { FrameworkErrorHandler } from \"./next/errors\";\nimport type { InferInputOrDefault, StandardSchemaV1 } from \"./standard-schema\";\n\nexport const getActionStatus = <ServerError, Schema extends StandardSchemaV1 | undefined, ShapedErrors, Data>({\n\tisIdle,\n\tisExecuting,\n\tresult,\n\thasNavigated,\n\thasThrownError,\n}: {\n\tisIdle: boolean;\n\tisExecuting: boolean;\n\thasNavigated: boolean;\n\thasThrownError: boolean;\n\tresult: SafeActionResult<ServerError, Schema, ShapedErrors, Data>;\n}): HookActionStatus => {\n\tif (isIdle) {\n\t\treturn \"idle\";\n\t} else if (isExecuting) {\n\t\treturn \"executing\";\n\t} else if (\n\t\thasThrownError ||\n\t\ttypeof result.validationErrors !== \"undefined\" ||\n\t\ttypeof result.serverError !== \"undefined\"\n\t) {\n\t\treturn \"hasErrored\";\n\t} else if (hasNavigated) {\n\t\treturn \"hasNavigated\";\n\t} else {\n\t\treturn \"hasSucceeded\";\n\t}\n};\n\nexport const getActionShorthandStatusObject = ({\n\tstatus,\n\tisTransitioning,\n}: {\n\tstatus: HookActionStatus;\n\tisTransitioning: boolean;\n}): HookShorthandStatus => {\n\treturn {\n\t\tisIdle: status === \"idle\",\n\t\tisExecuting: status === \"executing\",\n\t\tisTransitioning,\n\t\tisPending: status === \"executing\" || isTransitioning,\n\t\thasSucceeded: status === \"hasSucceeded\",\n\t\thasErrored: status === \"hasErrored\",\n\t\thasNavigated: status === \"hasNavigated\",\n\t};\n};\n\n/**\n * Converts a callback to a ref to avoid triggering re-renders when passed as a\n * prop or avoid re-executing effects when passed as a dependency\n */\nfunction useCallbackRef<T extends (arg: any) => any>(callback: T | undefined): T {\n\tconst callbackRef = React.useRef(callback);\n\tReact.useEffect(() => {\n\t\tcallbackRef.current = callback;\n\t});\n\treturn React.useMemo(() => ((arg) => callbackRef.current?.(arg) as T) as T, []);\n}\n\nexport const useActionCallbacks = <ServerError, Schema extends StandardSchemaV1 | undefined, ShapedErrors, Data>({\n\tresult,\n\tinput,\n\tstatus,\n\tcb,\n\tthrowOnNavigation,\n\tnavigationError,\n\tthrownError,\n}: {\n\tresult: SafeActionResult<ServerError, Schema, ShapedErrors, Data>;\n\tinput: InferInputOrDefault<Schema, undefined>;\n\tstatus: HookActionStatus;\n\tcb?: HookCallbacks<ServerError, Schema, ShapedErrors, Data>;\n\tthrowOnNavigation: boolean;\n\tnavigationError: Error | null;\n\tthrownError: Error | null;\n}) => {\n\tconst onExecute = useCallbackRef(cb?.onExecute);\n\tconst onSuccess = useCallbackRef(cb?.onSuccess);\n\tconst onError = useCallbackRef(cb?.onError);\n\tconst onSettled = useCallbackRef(cb?.onSettled);\n\tconst onNavigation = useCallbackRef(cb?.onNavigation);\n\n\t// Execute hook callbacks as non-visual side effects.\n\tReact.useEffect(() => {\n\t\tconst executeCallbacks = async () => {\n\t\t\tswitch (status) {\n\t\t\t\tcase \"executing\":\n\t\t\t\t\tawait Promise.resolve(onExecute?.({ input })).then(() => {});\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"hasSucceeded\":\n\t\t\t\t\tif (navigationError || thrownError) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tawait Promise.all([\n\t\t\t\t\t\tPromise.resolve(onSuccess?.({ data: result.data!, input })),\n\t\t\t\t\t\t// Cast rationale: `onSettled`'s public type uses\n\t\t\t\t\t\t// `NormalizeActionResult` so void actions surface `data: undefined`,\n\t\t\t\t\t\t// but internally `result` is the raw `SafeActionResult<..., Data>`.\n\t\t\t\t\t\t// The two are structurally equivalent for every concrete `Data` the\n\t\t\t\t\t\t// runtime produces — see the comment in `useActionBase`.\n\t\t\t\t\t\tPromise.resolve(\n\t\t\t\t\t\t\tonSettled?.({\n\t\t\t\t\t\t\t\tresult: result as unknown as NormalizeActionResult<\n\t\t\t\t\t\t\t\t\tSafeActionResult<ServerError, Schema, ShapedErrors, Data>\n\t\t\t\t\t\t\t\t>,\n\t\t\t\t\t\t\t\tinput,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t),\n\t\t\t\t\t]);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"hasErrored\":\n\t\t\t\t\tawait Promise.all([\n\t\t\t\t\t\tPromise.resolve(\n\t\t\t\t\t\t\tonError?.({\n\t\t\t\t\t\t\t\terror: { ...result, ...(thrownError ? { thrownError } : {}) },\n\t\t\t\t\t\t\t\tinput,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t),\n\t\t\t\t\t\tPromise.resolve(\n\t\t\t\t\t\t\tonSettled?.({\n\t\t\t\t\t\t\t\tresult: result as unknown as NormalizeActionResult<\n\t\t\t\t\t\t\t\t\tSafeActionResult<ServerError, Schema, ShapedErrors, Data>\n\t\t\t\t\t\t\t\t>,\n\t\t\t\t\t\t\t\tinput,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t),\n\t\t\t\t\t]);\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// Navigation flow.\n\t\t\t// Skip navigation callbacks when throwOnNavigation is true: the render-phase throw\n\t\t\t// is the primary guard, but this explicit check prevents race conditions and protects\n\t\t\t// against edge cases in concurrent mode or JavaScript usage without TypeScript.\n\t\t\tif (throwOnNavigation || !navigationError) return;\n\t\t\tconst navigationKind = FrameworkErrorHandler.getNavigationKind(navigationError);\n\n\t\t\tif (navigationKind === \"redirect\" || status === \"hasNavigated\") {\n\t\t\t\tconst actualNavigationKind = FrameworkErrorHandler.getNavigationKind(navigationError);\n\t\t\t\tawait Promise.all([\n\t\t\t\t\tPromise.resolve(\n\t\t\t\t\t\tonNavigation?.({\n\t\t\t\t\t\t\tinput,\n\t\t\t\t\t\t\tnavigationKind: actualNavigationKind,\n\t\t\t\t\t\t})\n\t\t\t\t\t),\n\t\t\t\t\tPromise.resolve(\n\t\t\t\t\t\tonSettled?.({\n\t\t\t\t\t\t\tresult: result as unknown as NormalizeActionResult<\n\t\t\t\t\t\t\t\tSafeActionResult<ServerError, Schema, ShapedErrors, Data>\n\t\t\t\t\t\t\t>,\n\t\t\t\t\t\t\tinput,\n\t\t\t\t\t\t\tnavigationKind: actualNavigationKind,\n\t\t\t\t\t\t})\n\t\t\t\t\t),\n\t\t\t\t]);\n\t\t\t}\n\t\t};\n\n\t\texecuteCallbacks().catch(console.error);\n\t}, [\n\t\tinput,\n\t\tstatus,\n\t\tresult,\n\t\tthrowOnNavigation,\n\t\tnavigationError,\n\t\tthrownError,\n\t\tonExecute,\n\t\tonSuccess,\n\t\tonSettled,\n\t\tonError,\n\t\tonNavigation,\n\t]);\n};\n","\"use client\";\n\nimport * as React from \"react\";\nimport { getActionShorthandStatusObject, getActionStatus, useActionCallbacks } from \"./hooks-utils\";\nimport type {\n\tHookActionStatus,\n\tHookBaseOptions,\n\tHookCallbacks,\n\tSingleInputActionFn,\n\tHookShorthandStatus,\n} from \"./hooks.types\";\nimport type { NormalizeActionResult, SafeActionResult } from \"./index.types\";\nimport { FrameworkErrorHandler } from \"./next/errors\";\nimport type { InferInputOrDefault, StandardSchemaV1 } from \"./standard-schema\";\n\n/**\n * Shared base hook for `useAction` and `useOptimisticAction`.\n * Extracts common state management, execution logic, and callback wiring.\n *\n * @param onTransitionStart Optional callback invoked inside `startTransition` before the action runs.\n *   Used by `useOptimisticAction` to call `setOptimisticValue`.\n */\nexport function useActionBase<ServerError, Schema extends StandardSchemaV1 | undefined, ShapedErrors, Data>(\n\tsafeActionFn: SingleInputActionFn<ServerError, Schema, ShapedErrors, Data>,\n\topts: HookBaseOptions<ServerError, Schema, ShapedErrors, Data> | undefined,\n\tonTransitionStart?: (input: InferInputOrDefault<Schema, undefined>) => void\n): {\n\tisTransitioning: boolean;\n\t// Exposed as `NormalizeActionResult<...>` so that void-returning actions\n\t// surface `data: undefined` rather than `data: void | undefined`. The\n\t// internal `useState` still holds the raw `SafeActionResult` union — the\n\t// type-only narrowing happens once at this boundary via a cast.\n\tresult: NormalizeActionResult<SafeActionResult<ServerError, Schema, ShapedErrors, Data>>;\n\tclientInput: InferInputOrDefault<Schema, void> | undefined;\n\tstatus: HookActionStatus;\n\texecute: (input: InferInputOrDefault<Schema, void>) => void;\n\texecuteAsync: (\n\t\tinput: InferInputOrDefault<Schema, void>\n\t) => Promise<NormalizeActionResult<SafeActionResult<ServerError, Schema, ShapedErrors, Data>>>;\n\treset: () => void;\n\tshorthandStatus: HookShorthandStatus;\n} {\n\tconst [isTransitioning, startTransition] = React.useTransition();\n\tconst [result, setResult] = React.useState<SafeActionResult<ServerError, Schema, ShapedErrors, Data>>({});\n\tconst [clientInput, setClientInput] = React.useState<InferInputOrDefault<Schema, void>>();\n\tconst [isExecuting, setIsExecuting] = React.useState(false);\n\tconst [navigationError, setNavigationError] = React.useState<Error | null>(null);\n\tconst [thrownError, setThrownError] = React.useState<Error | null>(null);\n\tconst [isIdle, setIsIdle] = React.useState(true);\n\n\t// Request ordering: only the latest request's response updates UI state.\n\t// This prevents stale responses from overwriting fresh state on rapid calls.\n\tconst requestIdRef = React.useRef(0);\n\n\t// Stable ref for the transition start callback to avoid destabilizing execute/executeAsync.\n\tconst onTransitionStartRef = React.useRef(onTransitionStart);\n\tonTransitionStartRef.current = onTransitionStart;\n\n\tconst status = getActionStatus<ServerError, Schema, ShapedErrors, Data>({\n\t\tisExecuting,\n\t\tresult,\n\t\tisIdle,\n\t\thasNavigated: navigationError !== null,\n\t\thasThrownError: thrownError !== null,\n\t});\n\n\tconst execute = React.useCallback(\n\t\t(input: InferInputOrDefault<Schema, void>) => {\n\t\t\tconst thisRequestId = ++requestIdRef.current;\n\n\t\t\t// Set state synchronously before starting the transition.\n\t\t\tsetIsIdle(false);\n\t\t\tsetNavigationError(null);\n\t\t\tsetThrownError(null);\n\t\t\tsetClientInput(input);\n\t\t\tsetIsExecuting(true);\n\n\t\t\tstartTransition(() => {\n\t\t\t\tonTransitionStartRef.current?.(input as InferInputOrDefault<Schema, undefined>);\n\n\t\t\t\tsafeActionFn(input as InferInputOrDefault<Schema, undefined>)\n\t\t\t\t\t.then((res) => {\n\t\t\t\t\t\tif (thisRequestId !== requestIdRef.current) return;\n\t\t\t\t\t\tsetResult(res ?? {});\n\t\t\t\t\t})\n\t\t\t\t\t.catch((e) => {\n\t\t\t\t\t\tif (thisRequestId === requestIdRef.current) {\n\t\t\t\t\t\t\tsetResult({});\n\n\t\t\t\t\t\t\tif (FrameworkErrorHandler.isNavigationError(e)) {\n\t\t\t\t\t\t\t\tsetNavigationError(e);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tsetThrownError(e as Error);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Only re-throw non-navigation errors for React error boundary handling.\n\t\t\t\t\t\t// Navigation errors are handled via render-phase throw (throwOnNavigation).\n\t\t\t\t\t\tif (!FrameworkErrorHandler.isNavigationError(e)) {\n\t\t\t\t\t\t\tthrow e;\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t\t.finally(() => {\n\t\t\t\t\t\tif (thisRequestId !== requestIdRef.current) return;\n\t\t\t\t\t\tsetIsExecuting(false);\n\t\t\t\t\t});\n\t\t\t});\n\t\t},\n\t\t[safeActionFn]\n\t);\n\n\tconst executeAsync = React.useCallback(\n\t\t(input: InferInputOrDefault<Schema, void>) => {\n\t\t\treturn new Promise<Awaited<ReturnType<typeof safeActionFn>>>((resolve, reject) => {\n\t\t\t\tconst thisRequestId = ++requestIdRef.current;\n\n\t\t\t\tsetIsIdle(false);\n\t\t\t\tsetNavigationError(null);\n\t\t\t\tsetThrownError(null);\n\t\t\t\tsetClientInput(input);\n\t\t\t\tsetIsExecuting(true);\n\n\t\t\t\tstartTransition(() => {\n\t\t\t\t\tonTransitionStartRef.current?.(input as InferInputOrDefault<Schema, undefined>);\n\n\t\t\t\t\tsafeActionFn(input as InferInputOrDefault<Schema, undefined>)\n\t\t\t\t\t\t.then((res) => {\n\t\t\t\t\t\t\tif (thisRequestId === requestIdRef.current) {\n\t\t\t\t\t\t\t\tsetResult(res ?? {});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t// Always resolve so the caller's await settles.\n\t\t\t\t\t\t\tresolve(res);\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.catch((e) => {\n\t\t\t\t\t\t\tif (thisRequestId === requestIdRef.current) {\n\t\t\t\t\t\t\t\tsetResult({});\n\n\t\t\t\t\t\t\t\tif (FrameworkErrorHandler.isNavigationError(e)) {\n\t\t\t\t\t\t\t\t\tsetNavigationError(e);\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tsetThrownError(e as Error);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Always reject so the caller's await settles.\n\t\t\t\t\t\t\treject(e);\n\n\t\t\t\t\t\t\t// Only re-throw non-navigation errors for React error boundary handling.\n\t\t\t\t\t\t\t// Navigation errors are handled via render-phase throw (throwOnNavigation).\n\t\t\t\t\t\t\tif (!FrameworkErrorHandler.isNavigationError(e)) {\n\t\t\t\t\t\t\t\tthrow e;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.finally(() => {\n\t\t\t\t\t\t\tif (thisRequestId !== requestIdRef.current) return;\n\t\t\t\t\t\t\tsetIsExecuting(false);\n\t\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t});\n\t\t},\n\t\t[safeActionFn]\n\t);\n\n\tconst reset = React.useCallback(() => {\n\t\tsetIsIdle(true);\n\t\tsetNavigationError(null);\n\t\tsetThrownError(null);\n\t\tsetClientInput(undefined);\n\t\tsetResult({});\n\t}, []);\n\n\tuseActionCallbacks({\n\t\tresult: result ?? {},\n\t\tinput: clientInput as InferInputOrDefault<Schema, undefined>,\n\t\tstatus,\n\t\tthrowOnNavigation: opts?.throwOnNavigation === true,\n\t\tnavigationError,\n\t\tthrownError,\n\t\t// Cast: HookBaseOptions is a discriminated union that always includes callback properties at runtime.\n\t\t// When throwOnNavigation is true, onNavigation/onSettled are omitted from the type but absent at runtime too.\n\t\tcb: opts as HookCallbacks<ServerError, Schema, ShapedErrors, Data> | undefined,\n\t});\n\n\t// When throwOnNavigation is explicitly enabled, throw navigation errors during React's render\n\t// phase so they reach the nearest error boundary. In Next.js, this is HTTPAccessFallbackBoundary,\n\t// which shows 404/403/401 pages.\n\tif (opts?.throwOnNavigation === true && navigationError !== null) {\n\t\tthrow navigationError;\n\t}\n\n\treturn {\n\t\tisTransitioning,\n\t\t// `result` and `executeAsync` are structurally compatible with\n\t\t// `NormalizeActionResult<SafeActionResult<...>>` for every concrete `Data`\n\t\t// the runtime ever produces — `NormalizeActionResult` only drops the\n\t\t// `{ data: void }` branch, which the action builder never emits (see\n\t\t// `buildResultAndRunCallbacks` in `action-builder.ts`). TypeScript can't\n\t\t// verify this while `Data` is still a free generic, so the cast is\n\t\t// isolated here and not repeated across every consumer hook.\n\t\tresult: result as unknown as NormalizeActionResult<SafeActionResult<ServerError, Schema, ShapedErrors, Data>>,\n\t\tclientInput,\n\t\tstatus,\n\t\texecute,\n\t\texecuteAsync: executeAsync as unknown as (\n\t\t\tinput: InferInputOrDefault<Schema, void>\n\t\t) => Promise<NormalizeActionResult<SafeActionResult<ServerError, Schema, ShapedErrors, Data>>>,\n\t\treset,\n\t\tshorthandStatus: getActionShorthandStatusObject({ status, isTransitioning }),\n\t};\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport { useActionBase } from \"./hooks-shared\";\nimport { getActionShorthandStatusObject, getActionStatus, useActionCallbacks } from \"./hooks-utils\";\nimport type {\n\tHookBaseOptions,\n\tHookCallbacks,\n\tHookIdleResult,\n\tSingleInputActionFn,\n\tSingleInputStateActionFn,\n\tUseActionHookReturn,\n\tUseOptimisticActionHookReturn,\n\tUseStateActionHookReturn,\n} from \"./hooks.types\";\nimport type { NormalizeActionResult, SafeActionResult } from \"./index.types\";\nimport { FrameworkErrorHandler } from \"./next/errors\";\nimport type { InferInputOrDefault, StandardSchemaV1 } from \"./standard-schema\";\n\n// HOOKS\n\n/**\n * Use the action from a Client Component via hook.\n * @param safeActionFn The action function\n * @param opts Optional configuration and callbacks\n *\n * {@link https://next-safe-action.dev/docs/execute-actions/hooks/useaction See docs for more information}\n */\nexport const useAction = <ServerError, Schema extends StandardSchemaV1 | undefined, ShapedErrors, Data>(\n\tsafeActionFn: SingleInputActionFn<ServerError, Schema, ShapedErrors, Data>,\n\topts?: HookBaseOptions<ServerError, Schema, ShapedErrors, Data>\n): UseActionHookReturn<ServerError, Schema, ShapedErrors, Data> => {\n\tconst { result, clientInput, status, execute, executeAsync, reset, shorthandStatus } = useActionBase(\n\t\tsafeActionFn,\n\t\topts\n\t);\n\n\t// Cast rationale: the return object's runtime values are guaranteed consistent\n\t// by `getActionStatus` + `getActionShorthandStatusObject`, but TypeScript can't\n\t// verify that the widened types (e.g. `status: HookActionStatus`) satisfy a\n\t// specific branch of the discriminated union. The cast is safe and isolated here.\n\treturn {\n\t\texecute,\n\t\texecuteAsync,\n\t\tinput: clientInput as InferInputOrDefault<Schema, undefined>,\n\t\tresult,\n\t\treset,\n\t\tstatus,\n\t\t...shorthandStatus,\n\t} as UseActionHookReturn<ServerError, Schema, ShapedErrors, Data>;\n};\n\n/**\n * Use the action from a Client Component via hook, with optimistic data update.\n * @param safeActionFn The action function\n * @param utils Required `currentData` and `updateFn` and optional callbacks\n *\n * {@link https://next-safe-action.dev/docs/execute-actions/hooks/useoptimisticaction See docs for more information}\n */\nexport const useOptimisticAction = <\n\tServerError,\n\tSchema extends StandardSchemaV1 | undefined,\n\tShapedErrors,\n\tData,\n\tState,\n>(\n\tsafeActionFn: SingleInputActionFn<ServerError, Schema, ShapedErrors, Data>,\n\tutils: {\n\t\tcurrentState: State;\n\t\tupdateFn: (state: State, input: InferInputOrDefault<Schema, void>) => State;\n\t} & HookBaseOptions<ServerError, Schema, ShapedErrors, Data>\n): UseOptimisticActionHookReturn<ServerError, Schema, ShapedErrors, Data, State> => {\n\tconst [optimisticState, setOptimisticValue] = React.useOptimistic<State, InferInputOrDefault<Schema, undefined>>(\n\t\tutils.currentState,\n\t\tutils.updateFn\n\t);\n\n\t// Extract hook options from utils, excluding the useOptimisticAction-specific properties.\n\tconst { currentState: _, updateFn: __, ...hookOpts } = utils;\n\n\tconst { result, clientInput, status, execute, executeAsync, reset, shorthandStatus } = useActionBase(\n\t\tsafeActionFn,\n\t\thookOpts as HookBaseOptions<ServerError, Schema, ShapedErrors, Data>,\n\t\tsetOptimisticValue\n\t);\n\n\t// Cast rationale: same as `useAction` — runtime consistency guaranteed by\n\t// `getActionStatus` + `getActionShorthandStatusObject`. The double assertion\n\t// is needed because TypeScript can't verify overlap between the widened object\n\t// and the distributed intersection-over-union (`UseActionHookReturn & { optimisticState }`).\n\treturn {\n\t\texecute,\n\t\texecuteAsync,\n\t\tinput: clientInput as InferInputOrDefault<Schema, undefined>,\n\t\tresult,\n\t\toptimisticState,\n\t\treset,\n\t\tstatus,\n\t\t...shorthandStatus,\n\t} as unknown as UseOptimisticActionHookReturn<ServerError, Schema, ShapedErrors, Data, State>;\n};\n\n/**\n * Use the stateful action from a Client Component via hook. Used for actions defined with\n * [`stateAction`](https://next-safe-action.dev/docs/define-actions/instance-methods#action--stateaction).\n *\n * Provides full lifecycle control: callbacks, status tracking, navigation error handling,\n * `executeAsync`, `reset`, and `formAction` for `<form action={formAction}>` integration.\n *\n * Requires React 19+ (Next.js 15+). On older versions, a runtime error is thrown with guidance.\n *\n * @param safeActionFn The stateful action function created with `.stateAction()`.\n * @param opts Optional configuration: `initResult` for initial state, plus all hook options and callbacks.\n *\n * {@link https://next-safe-action.dev/docs/execute-actions/hooks/usestateaction See docs for more information}\n */\nexport const useStateAction = <\n\tServerError,\n\tSchema extends StandardSchemaV1 | undefined,\n\tShapedErrors,\n\tData,\n\tInitR extends SafeActionResult<ServerError, Schema, ShapedErrors, Data> = HookIdleResult,\n>(\n\tsafeActionFn: SingleInputStateActionFn<ServerError, Schema, ShapedErrors, Data>,\n\topts?: {\n\t\tinitResult?: InitR;\n\t} & HookBaseOptions<ServerError, Schema, ShapedErrors, Data>\n): UseStateActionHookReturn<ServerError, Schema, ShapedErrors, Data, InitR> => {\n\tif (typeof React.useActionState !== \"function\") {\n\t\tthrow new Error(\n\t\t\t\"useStateAction requires React 19+ (Next.js 15+). \" +\n\t\t\t\t\"For older versions, use React's useActionState directly with your safe action.\"\n\t\t);\n\t}\n\n\tconst initResult = opts?.initResult;\n\n\t// ─── Refs ────────────────────────────────────────────────────────────\n\n\tconst asyncResolverRef = React.useRef<{\n\t\tresolve: (value: unknown) => void;\n\t\treject: (reason: unknown) => void;\n\t} | null>(null);\n\tconst prevResultOverrideRef = React.useRef<SafeActionResult<ServerError, Schema, ShapedErrors, Data> | null>(null);\n\n\t// ─── State ────────────────────────────────────────────────────────────\n\n\tconst [navigationError, setNavigationError] = React.useState<Error | null>(null);\n\tconst [thrownError, setThrownError] = React.useState<Error | null>(null);\n\tconst [isIdle, setIsIdle] = React.useState(true);\n\tconst [isReset, setIsReset] = React.useState(false);\n\tconst [clientInput, setClientInput] = React.useState<InferInputOrDefault<Schema, void>>();\n\tconst [isTransitioning, startTransition] = React.useTransition();\n\n\t// ─── Wrapper function ─────────────────────────────────────────────────\n\t// All state updates inside the wrapper are batched into the transition by React,\n\t// so they commit atomically with the result. This prevents the double-fire issue\n\t// that would occur if state were synced via a separate effect.\n\n\tconst wrappedAction = React.useCallback(\n\t\tasync (\n\t\t\tprevResult: SafeActionResult<ServerError, Schema, ShapedErrors, Data>,\n\t\t\tinput: InferInputOrDefault<Schema, undefined>\n\t\t): Promise<SafeActionResult<ServerError, Schema, ShapedErrors, Data>> => {\n\t\t\tsetIsIdle(false);\n\t\t\tsetIsReset(false);\n\t\t\tsetClientInput(input as InferInputOrDefault<Schema, void>);\n\t\t\tsetNavigationError(null);\n\t\t\tsetThrownError(null);\n\n\t\t\tconst effectivePrevResult = prevResultOverrideRef.current ?? prevResult;\n\t\t\tprevResultOverrideRef.current = null;\n\n\t\t\ttry {\n\t\t\t\tconst result = await safeActionFn(effectivePrevResult, input);\n\t\t\t\tasyncResolverRef.current?.resolve(result);\n\t\t\t\treturn result;\n\t\t\t} catch (e) {\n\t\t\t\tif (FrameworkErrorHandler.isNavigationError(e)) {\n\t\t\t\t\tsetNavigationError(e);\n\t\t\t\t\tasyncResolverRef.current?.reject(e);\n\t\t\t\t\treturn {};\n\t\t\t\t}\n\n\t\t\t\tsetThrownError(e as Error);\n\t\t\t\tasyncResolverRef.current?.reject(e);\n\t\t\t\tthrow e;\n\t\t\t} finally {\n\t\t\t\tasyncResolverRef.current = null;\n\t\t\t}\n\t\t},\n\t\t[safeActionFn]\n\t);\n\n\t// ─── Core useActionState ──────────────────────────────────────────────\n\n\tconst [rawResult, dispatcher, isExecuting] = React.useActionState(wrappedAction, initResult ?? {});\n\n\t// ─── execute ──────────────────────────────────────────────────────────\n\n\tconst execute = React.useCallback(\n\t\t(input: InferInputOrDefault<Schema, void>) => {\n\t\t\tsetIsIdle(false);\n\t\t\tsetIsReset(false);\n\t\t\tsetNavigationError(null);\n\t\t\tsetThrownError(null);\n\t\t\tsetClientInput(input);\n\n\t\t\tstartTransition(() => {\n\t\t\t\tdispatcher(input as InferInputOrDefault<Schema, undefined>);\n\t\t\t});\n\t\t},\n\t\t[dispatcher]\n\t);\n\n\t// ─── executeAsync ─────────────────────────────────────────────────────\n\n\tconst executeAsync = React.useCallback(\n\t\t(input: InferInputOrDefault<Schema, void>) => {\n\t\t\treturn new Promise<SafeActionResult<ServerError, Schema, ShapedErrors, Data>>((resolve, reject) => {\n\t\t\t\tasyncResolverRef.current = {\n\t\t\t\t\tresolve: resolve as (value: unknown) => void,\n\t\t\t\t\treject,\n\t\t\t\t};\n\t\t\t\texecute(input);\n\t\t\t});\n\t\t},\n\t\t[execute]\n\t);\n\n\t// ─── reset ────────────────────────────────────────────────────────────\n\n\tconst reset = React.useCallback(() => {\n\t\tsetIsIdle(true);\n\t\tsetIsReset(true);\n\t\tsetNavigationError(null);\n\t\tsetThrownError(null);\n\t\tsetClientInput(undefined);\n\t\tprevResultOverrideRef.current = initResult ?? {};\n\t}, [initResult]);\n\n\t// ─── Status ───────────────────────────────────────────────────────────\n\n\t// On reset, the visible `result` is restored to `initResult` (or `{}` when not provided) so\n\t// the idle branch's runtime value matches its declared type in both phases: at mount and\n\t// after reset. This is also the intuitive contract for `reset` — return to the initial state.\n\tconst result = isReset\n\t\t? ((initResult ?? {}) as SafeActionResult<ServerError, Schema, ShapedErrors, Data>)\n\t\t: (rawResult ?? {});\n\n\tconst status = getActionStatus<ServerError, Schema, ShapedErrors, Data>({\n\t\tisExecuting,\n\t\tresult,\n\t\tisIdle: isIdle && !isExecuting,\n\t\thasNavigated: navigationError !== null,\n\t\thasThrownError: thrownError !== null,\n\t});\n\n\t// ─── Callbacks ────────────────────────────────────────────────────────\n\n\tuseActionCallbacks({\n\t\tresult,\n\t\tinput: clientInput as InferInputOrDefault<Schema, undefined>,\n\t\tstatus,\n\t\tcb: opts as HookCallbacks<ServerError, Schema, ShapedErrors, Data> | undefined,\n\t\tthrowOnNavigation: opts?.throwOnNavigation === true,\n\t\tnavigationError,\n\t\tthrownError,\n\t});\n\n\tif (opts?.throwOnNavigation === true && navigationError !== null) {\n\t\tthrow navigationError;\n\t}\n\n\t// ─── Return ───────────────────────────────────────────────────────────\n\n\t// Cast rationale: same as `useAction` — runtime consistency guaranteed by\n\t// `getActionStatus` + `getActionShorthandStatusObject`. The double assertion\n\t// through `unknown` is needed because TypeScript can't verify overlap between\n\t// the widened object and the distributed intersection-over-union.\n\treturn {\n\t\texecute,\n\t\texecuteAsync: executeAsync as unknown as (\n\t\t\tinput: InferInputOrDefault<Schema, void>\n\t\t) => Promise<NormalizeActionResult<SafeActionResult<ServerError, Schema, ShapedErrors, Data>>>,\n\t\tformAction: dispatcher as (input: InferInputOrDefault<Schema, void>) => void,\n\t\tinput: clientInput as InferInputOrDefault<Schema, undefined>,\n\t\tresult: result as unknown as NormalizeActionResult<SafeActionResult<ServerError, Schema, ShapedErrors, Data>>,\n\t\treset,\n\t\tstatus,\n\t\t...getActionShorthandStatusObject({ status, isTransitioning }),\n\t} as unknown as UseStateActionHookReturn<ServerError, Schema, ShapedErrors, Data, InitR>;\n};\n\nexport type * from \"./hooks.types\";\n"],"mappings":"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"}