Autosave Plugin
Autosave is an opt-in plugin for draft-style persistence with UX-oriented runtime state.
It debounces snapshot writes, can hydrate the initial snapshot from storage, and exposes save status through the machine API. It is built on the same snapshot persistence behavior as Journey persistence, but it does not require consumers to register the persistence plugin separately.
Install And Use
import { createJourneyMachine } from "@rxova/journey-core";
import { createAutosavePlugin } from "@rxova/journey-core/autosave";
const machine = createJourneyMachine(journey, {
plugins: [
createAutosavePlugin({
key: "journey.checkout.draft",
debounceMs: 500,
allowList: ["profile", "shipping", "billing"],
blockList: ["billing.cardNumber"]
})
]
});
What You Get
The plugin augments the machine with:
type JourneyAutosaveMachineExtension = {
getAutosaveState: () => JourneyAutosaveState;
flushAutosave: () => Promise<void>;
clearAutosave: () => void;
};
getAutosaveState() returns:
type JourneyAutosaveState = {
status: "idle" | "pending" | "saved" | "error";
lastSavedAt?: number;
pendingReason?: "context" | "navigation" | "reset" | "start" | "transition" | "async";
error?: unknown;
};
Options
key: unique storage keystorage: custom storage adapterdebounceMs: delay before writes are committedhydrate: whether to hydrate the initial snapshot from storagesaveOn: snapshot-change reasons that should trigger autosaveallowList: persist only matching context pathsblockList: remove matching context paths before storageclearOnReset: remove storage entry on reset instead of writing the initial snapshotserialize/deserialize: custom codecsmigrate(value, persistedVersion): migrate older payloadsonSaved(details): callback after a successful autosave commitonError(error): storage or serialization error handler
Runtime Behavior
Autosave schedules writes from committed snapshot changes.
asyncsnapshot changes are ignoredresetclears storage whenclearOnResetis enabledflushAutosave()forces the pending write immediatelyclearAutosave()removes the stored draft and resets autosave state
When hydrate is enabled, the plugin restores the last saved draft into the initial machine snapshot before normal runtime work begins.
Relationship To Persistence
Autosave is not a wrapper around createPersistencePlugin(...) at the public API level.
Use persistence when you want straightforward durable snapshots with minimal behavior.
Use autosave when you want:
- debounced draft saving
- save status for UI
- explicit flush/clear controls
- the same filtering and migration model as persistence
Example
const machine = createJourneyMachine(journey, {
plugins: [
createAutosavePlugin({
key: "journey.checkout.draft",
debounceMs: 300,
saveOn: ["context", "transition", "navigation"],
onSaved: ({ timestamp }) => {
console.log("draft saved", timestamp);
}
})
]
});
await machine.start();
await machine.updateContext((context) => ({ ...context, email: "user@example.com" }));
const autosave = machine.getAutosaveState();
// { status: "pending" }
await machine.flushAutosave();