Split out from PR #424 review (CodeRabbit, src/core/undo-history.ts:258) as a tracked follow-up. Pre-existing on main — not introduced by the web-edit PR — and affects both desktop and web, so it's out of scope for #424 and deserves its own change.
Problem
ModificationTracker.serialize() persists only { timeline, checkpointIndex }:
// src/core/undo-history.ts
serialize(): Uint8Array {
const payload = { timeline: this.timeline, checkpointIndex: this.checkpointIndex };
...
}
But stepBack() (undo) and rollbackToCheckpoint() move entries into futureStack (the redo stack), which is not serialized. Hot-exit restore opens the last saved DB bytes and replays only getUncommittedEntries() (timeline.slice(checkpointIndex)).
Consequence
Repro:
- Make an edit, save (checkpoint advances past the edit).
- Undo that saved edit (entry moves to
futureStack; document is now dirty).
- Hot-exit (close VS Code with the dirty doc), then reopen from the backup.
Expected: the database reflects the undone state (edit removed).
Actual: restore opens the saved bytes (which still contain the edit) and replays no forward entries, so the undone state is lost — and the redo stack is gone entirely.
Possible approaches (design decision — not prescribing)
- Persist
futureStack + futureStackSizes and reconstruct the cursor on restore, then replay the net state (requires representing the undo, e.g. applying inverse ops or re-deriving live state).
- Snapshot the live DB bytes for the hot-exit backup instead of replaying forward entries from the saved image (exact, simpler to reason about, larger backups).
CodeRabbit tagged this a "Heavy lift"; flagging for a dedicated PR with its own tests (desktop + web hot-exit round-trips covering undo-of-saved-edit).
Refs: PR #424 review thread on src/core/undo-history.ts.
Split out from PR #424 review (CodeRabbit,
src/core/undo-history.ts:258) as a tracked follow-up. Pre-existing onmain— not introduced by the web-edit PR — and affects both desktop and web, so it's out of scope for #424 and deserves its own change.Problem
ModificationTracker.serialize()persists only{ timeline, checkpointIndex }:But
stepBack()(undo) androllbackToCheckpoint()move entries intofutureStack(the redo stack), which is not serialized. Hot-exit restore opens the last saved DB bytes and replays onlygetUncommittedEntries()(timeline.slice(checkpointIndex)).Consequence
Repro:
futureStack; document is now dirty).Expected: the database reflects the undone state (edit removed).
Actual: restore opens the saved bytes (which still contain the edit) and replays no forward entries, so the undone state is lost — and the redo stack is gone entirely.
Possible approaches (design decision — not prescribing)
futureStack+futureStackSizesand reconstruct the cursor on restore, then replay the net state (requires representing the undo, e.g. applying inverse ops or re-deriving live state).CodeRabbit tagged this a "Heavy lift"; flagging for a dedicated PR with its own tests (desktop + web hot-exit round-trips covering undo-of-saved-edit).
Refs: PR #424 review thread on
src/core/undo-history.ts.