Skip to content

[Feature]: Progressive-enhancement form actions + optimistic updates #140

Description

@JosunLP

Pre-flight checklist

  • I searched existing issues and did not find a duplicate request.
  • I explained the problem or use case, not just the desired API.

Problem or use case
bQuery forms submit via JS (onSubmit) only — there is no progressive-enhancement model where a form posts to a server action and works even before/without client JS, and no optimistic-update primitive for instant feedback. React 19 added function action/formAction props on <form>/<input>/<button> with useActionState, useFormStatus, and useOptimistic; SvelteKit ships server form actions. bQuery, despite having both a forms module and a server module, does not connect them this way, which is a concrete gap for resilient apps.

Proposed solution
Add a form-action model that binds a form to a server action (via the server module / file-based route actions in #149), submits as a normal POST when JS is unavailable, and progressively enhances to a fetch-based submit with pending state when JS is present. Add an optimistic-update primitive so the UI can reflect the expected result immediately and reconcile on response. Must compose with the existing validation pipeline and with sessions/CSRF from #132.

Possible API or UX shape

import { formAction, useFormStatus, optimistic } from "@bquery/bquery/forms";

// binds to a server action; falls back to native POST without JS
const submit = formAction("/todos", { method: "POST" });

const { pending } = useFormStatus(submit);
const list = optimistic(todos, (cur, draft) => [...cur, draft]); // instant feedback

Alternatives considered
Keeping JS-only submit and documenting manual fetch patterns — leaves bQuery without the resilience and ergonomics React 19/SvelteKit now treat as standard. Building optimistic updates only in store — possible, but form submission is where users expect it, so the primitive should be reachable from forms.

Relevant area
forms

Additional context
Depends on server session/CSRF (#132) and pairs with file-based route actions (#149). This is one of the headline React-19-parity features.

Metadata

Metadata

Assignees

No one assigned

    Labels

    formsChanges to the forms module

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions