/** * @jorvel/runtime — server actions (the MUTATION primitive) * * Symmetric counterpart to the READ-side loader (`defineLoader` / * `useLoaderData` in `@jorvel/ssr`): * - `defineLoader` (in `@jorvel/ssr`) — typed read, SSR + hydration ready. * - `defineAction` (here) — typed mutation ("server action"). * Pairs with `useAction` for pending/error/result state, * and binds directly to a `
` via `useFormAction`. * * An action is a plain async function you can call anywhere; the React hooks add * the pending/error/data state machine expected of React 19 form actions. */ import React from 'react'; export interface ActionContext { request?: Request; signal?: AbortSignal; } export type Action = (input: Input, ctx?: ActionContext) => Promise | Output; /** Identity wrapper that pins an action's input/output types for inference. */ export declare function defineAction(fn: Action): Action; export interface ActionState { /** Last successful result, or null before the first success. */ data: Output | null; /** Error from the last failed run, or null. */ error: unknown; /** True while a submission is in flight. */ pending: boolean; /** Run the action. Resolves to the result or throws on failure. */ submit: (input: Input) => Promise; /** Clear data/error/pending back to the initial state. */ reset: () => void; } /** * Drive a {@link defineAction} action with React state. Concurrent submissions * are serialized to "last wins": only the most recent `submit` updates state, * so a slow earlier request can't clobber a newer result. */ export declare function useAction(action: Action): ActionState; export interface FormActionState extends Omit, 'submit'> { /** Attach to `` — calls preventDefault + submits FormData. */ onSubmit: (event: React.FormEvent) => void; /** Submit a FormData payload imperatively. */ submit: (input: FormData) => Promise; } export interface CsrfConfig { /** Token value to echo back (from `issueCsrfToken` in @jorvel/security). */ token: string; /** Hidden field name. Default `_csrf` — match `csrfFieldName()`. */ field?: string; } /** * Progressive-enhancement helper: binds a `FormData` action to a ``. * Without JS the form posts natively (wire the same action server-side); with * JS this intercepts submit, runs the action, and exposes pending/error/data. */ export declare function useFormAction(action: Action): FormActionState; export interface FormProps extends Omit, 'onSubmit' | 'action' | 'children'> { /** The mutation to run on submit. Receives the form's FormData. */ action: Action; /** Inject a hidden CSRF field. Pair with `issueCsrfToken` / `verifyCsrf`. */ csrf?: CsrfConfig; /** Native POST target — used as the no-JS fallback. */ formAction?: string; /** Static children, or a render fn given the live form-action state. */ children?: React.ReactNode | ((state: FormActionState) => React.ReactNode); } /** * Progressive-enhancement form bound to a {@link defineAction}. Renders a real * `` (native POST without JS when `formAction` is set), intercepts submit * with JS, and injects a hidden CSRF field when `csrf` is provided. Pass a * render-fn child to read `{ pending, error, data, reset }`. */ export declare function Form({ action, csrf, formAction, children, ...formProps }: FormProps): React.ReactElement; //# sourceMappingURL=actions.d.ts.map