This release is a breaking rewrite of the entire public API. The two creators from 0.1.0 are gone and every spread and option name changed with them — existing code will not compile until migrated. The mapping:
| 0.1.0 | 1.0.0 |
|---|---|
createValidation(remote) + createEnhancedForm(remote, { validation, ... }) |
enhancedForm(remote, { ... }) — one object, validation always wired in |
{...valid.formHandler} on the <form> |
{...form.handlers} |
{...valid.fields.x.handlers} on inputs |
{...form.fields.x.validate} |
valid.fields.x.issues / .pending / .addIssues / .addValidator |
same names, now on form.fields.x |
resetOnSuccess: false |
preventResetOnSuccess: true |
enhanced.reset() (state only) |
form.resetState() — form.reset() now also resets the form element |
valid.updateIssues() / valid.validateAll() in enhance callbacks |
delete them — the lifecycle wiring is internal now |
Changed
- BREAKING: Merged
createValidationandcreateEnhancedForminto a singleenhancedFormexport — one object, one field proxy, one form-level spread. Thevalidationoption is gone: validation is always wired into the submission lifecycle, so the manualupdateIssues()/validateAll()calls previously required in enhance handlers (and the silent miswiring whenvalidationwasn't passed) no longer exist.updateIssues()is now internal;validateAll(),clearAllIssues(),allIssues,allKnownIssues, andformIssuesremain on the merged object. - BREAKING: The field spread
fields.some.path.handlersis nowfields.some.path.validate, and the form-level spreadformHandleris nowhandlers. - BREAKING: Replaced
resetOnSuccess(defaulttrue) with the opt-inpreventResetOnSuccess(defaultfalse), so keeping values after a successful save is something you opt into rather than out of.resetOnSuccess: falsebecomespreventResetOnSuccess: true. - BREAKING:
reset()now resets the form element as well as the submission state. For the old behavior (state only), useresetState().
Added
- Added draft persistence. Spread
form.fields.some.path.persistonto an input and its value is saved to web storage as the user types (debounced, flushed onchange) and restored when the input mounts — so a reload no longer loses what was typed. Restored fields are marked dirty. Drafts are discarded on successful submission, on form reset, on expiry, or via the newdiscardPersisted(). Thepersistcreation option overrides defaults:key(defaults to the remote form's action id, which is stable across reloads/builds and self-invalidates when the remote function moves),storage('local'default, or'session'), andmaxAgeMs(default: no expiry). File inputs are skipped. - Added
autoSubmit: boolean | { debounceMs?: number }(default 600ms) — the form submits itself viarequestSubmit()once input settles, for save-button-less forms. Preflight validation, the submit-attempt issue display, and enhance callbacks all run as they would for a button press. Built in: data identical to the last submission is never re-submitted, a debounce firing mid-submission waits and re-submits only if the data changed since, and achangeevent (text blur, select/checkbox pick) submits immediately. Auto-submitting forms never reset after success, sopreventResetOnSuccessis not accepted alongsideautoSubmit(type error). - Added
reset()(resets the form element and the submission state — the reset event also clears validation state and discards the persisted draft) alongsideresetState(), which is the old state-only reset.
Changed (internal)
- Added a runtime test suite (vitest + jsdom,
bun run test): the submission state machine (success/issues/error flows, delayed/timeout timers, superseded-submission races, cancel, reset behaviors), auto-submit (debounce, dirty check, in-flight coalescing, change flush, teardown), draft persistence (restore/expiry/discard, debounced writes, storage selection, attachment identity), and the validation core (issue layers, field validators, dirty-gated debounced validation). CI's test job now runs it after the type checks.
Fixed
- Added a
defaultcondition to the packageexportsso non-Svelte-aware tooling (vitest, plain Node) can resolve the package. - Raised the
sveltepeer dependency to^5.29.0— the package importssvelte/attachments, which was introduced in that release. - Calling
updates()with no arguments inonSubmitis now correctly forwarded to kit'ssubmit().updates(), which suppresses the defaultinvalidateAll. Previously, a zero-argument call was indistinguishable from not callingupdates()at all. - A debounced draft write pending when the draft is discarded (e.g. by a successful submission) no longer fires afterwards and resurrects the stale draft.
- Resetting the form now cancels a pending auto-submit debounce and any queued auto-submit — previously the debounce could fire after the reset and submit the freshly-emptied form.
- A queued auto-submit is no longer dropped when an
onSubmitcallback throws, andresetState()clears the queued flag instead of stranding it. - The auto-submit change detector now snapshots the form when the submit event fires (the moment kit captures its
FormData) instead of when the enhance callback runs, so input arriving during an async preflight can no longer be recorded as submitted without actually being sent.