Integration: Form Autosave
Relevant source files
The following files were used as context for generating this wiki page:
Integration of @b2m9/keyfold into form autosave systems allows for efficient, partial updates of complex state trees from single authoritative sources. By utilizing identity-keyed list reconciliation, the system ensures that user inputs in nested forms are preserved and merged correctly without corrupting list order or losing unmentioned fields.
Sources: README.md:14-25, AGENTS.md:54-57
Architecture and Data Flow
The autosave integration relies on a "last-delta-wins" approach where partial payloads (deltas) are immutably folded into a central state tree. This is particularly useful for UI reconciliation where only changed fields are transmitted to or from a server.
The flow typically involves a user interface generating a Delta<T>, which is then processed by a merger created via createMerger. This merger applies the changes to the current base state to produce a next state reference.
The diagram shows the cyclic flow of data from a form interface through the reconciliation process to update the application state.
Sources: README.md:21-25, src/merge.ts:14-22
Components of the Autosave System
| Component | Description |
|---|---|
| Merger | A reusable function created via createMerger that encapsulates path policies (keyBy, replace). |
| Delta | A recursive partial update of the state tree, allowing undefined for unmentioned fields and DELETE for removals. |
| Identity Key | A unique string or number used to match items in lists during reconciliation. |
| Tombstone | An object { id, $delete: true } used to signal the removal of a keyed item from a list. |
Sources: src/types.ts:24-34, src/reconcile.ts:133-151, README.md:110-120
Reconciliation Logic
In form autosave scenarios, handling lists (e.g., a list of addresses or line items) is critical. Keyfold reconciles these by identity rather than index, preventing data corruption when items are reordered or partially updated.
Keyed List Matching
When a delta contains a list, the merger uses the keyBy policy to identify the unique field (e.g., "id") for each item. Items present in both the base and delta are merged; items only in the delta are appended; and items marked with $delete: true are removed.
The sequence diagram illustrates how different items in a delta list are handled based on their presence in the base state and the use of operators.
Sources: src/reconcile.ts:23-57, test/reconcile.test.ts:46-60
Configuration for Autosave
For a robust autosave implementation, specific merger options are typically configured to handle the nuances of web-based form data.
Handling Deletes over JSON
Since standard JSON does not support symbols, the wireDeletes option is used to interpret a specific string token (DELETE_TOKEN) as a field deletion command.
const merge = createMerger<State>({
wireDeletes: true,
keyBy: { "profile.tags": "id" }
});
// JSON-safe delta for autosave
const delta = {
profile: {
nickname: "@@keyfold/delete", // Interpreted as field delete
tags: [{ id: "tag-1", $delete: true }] // JSON-native item delete
}
};
Sources: src/sentinels.ts:5, test/wire.test.ts:20-35, README.md:126-135
Structural Sharing and Performance
The integration is optimized for performance by ensuring that branches of the state tree not mentioned in the delta are preserved by reference. In an autosave context, this means that even a large state tree can be updated efficiently because the cost scales with the size of the delta, not the full state.
Sources: src/merge.ts:98-101, AGENTS.md:58-59, README.md:155-160
Implementation Constraints
- Immutability: The original base state is never mutated; a new object is returned if changes occur.
- Idempotency: Re-applying the same delta to the result of a previous merge returns the same object reference.
- Safety: Internal properties like
__proto__are ignored during the fold to prevent prototype pollution from untrusted form inputs.
Sources: src/objects.ts:5-15, test/merge.test.ts:96-105, AGENTS.md:31-33
Conclusion
Integrating Form Autosave via Keyfold provides a predictable, type-safe, and efficient way to synchronize partial form updates with a complex application state. By focusing on identity-keyed reconciliation, it solves the common pitfalls of array synchronization in standard merge implementations.