Troubleshooting: Draft restore
"A refresh trashes everything"#
The canvas autosaves every change to localStorage (debounced 500 ms) and restores on boot. If you refresh and your work is gone:
1. Verify autosave is writing#
In your browser's DevTools → Application → Local Storage, look for entries:
scaiflow_draft_<flow_id>— the per-flow draft envelope (JSON withsaved_at+flow).scaiflow_draft_latest— a pointer to the most-recently-saved draft id.
If these are missing entirely, autosave isn't running. Probable causes:
- Incognito with no localStorage — some browsers' incognito modes disable localStorage; the autosave silently degrades.
- Quota exceeded — very large flows can hit per-origin quota; autosave catches the QuotaExceededError and skips.
- localStorage disabled by extension/policy — same fail-silent behavior.
If the entries ARE there, autosave is working — the restore step is the issue.
2. Verify restore on boot#
On a fresh page load, the canvas reads scaiflow_draft_latest to find the most-recent draft id, then loads that draft. If _latest doesn't exist (first-ever load) or points at a flow id whose scaiflow_draft_<id> entry was cleared, restore doesn't run.
When restoring works: the canvas appears with your last state, undo history is cleared (no point undoing back to the empty default), and autosave continues.
3. "I saved the flow but the restore loaded an old version"#
Saved flows get their drafts cleared on successful Save (flowsListStore.saveCurrent calls clearDraft(content.id)). After Save, refreshing should load the freshly-saved server-side version, not a stale draft.
If you're getting a stale draft instead: the Save might have succeeded but the clearDraft step didn't (clearDraft is in a try/catch that silently ignores quota/disabled-storage errors). Manually clear the localStorage entry for that flow id and refresh.
4. "My currentId is gone but the content is back"#
flowsListStore.state.currentId (which saved-flow row you're editing) is now persisted to localStorage under scaiflow_current_flow as {id, version}. If the content restores but the canvas thinks it's unsaved (Save button reads "Save new" instead of "Save"), the pointer was missing or cleared.
This wasn't always persisted — older sessions may have orphaned drafts whose _latest pointer survives but the _current_flow entry was never set. To recover: manually save the restored flow under the right name; the new save will create a fresh row.
What the autosave actually tracks#
Solid's createStore is fine-grained reactive — it tracks property reads. The autosave effect uses JSON.stringify(state.flow) inside the effect, which walks every property recursively. That makes the tracker pick up every mutation — node moves, label edits, edge creates, kind config tweaks — not just top-level replaces.
If you're testing whether autosave fires on a particular action: open DevTools → Application → Local Storage → watch the scaiflow_draft_<id> entry's saved_at field. It should bump 500 ms after every edit.
Multi-tab safety#
Each flow id gets its own localStorage key. Editing flow A in tab 1 and flow B in tab 2 doesn't clobber either.
But: the _latest pointer is single-valued. If you have two tabs editing two different flows, whichever tab autosaved most recently is what a third-tab refresh restores. Save explicitly to your backend if you care which one comes back.
"I want a clean slate"#
To wipe all canvas autosave state:
1 2 3 4 5 6 | |
Or click New in the toolbar — that explicitly clears the current flow's draft.