markSaved cleared dirty unconditionally, so an edit made while a save
was in flight had its dirty flag wiped and its follow-up save dropped.
Only clear dirty when the book reference is unchanged since the save
started (immutable updates give a fresh reference per edit).
Claude-Session: https://claude.ai/code/session_01RzTWrLiy4zGuw2hZSQGamk
Key the editor by chapter id so each chapter gets a fresh TipTap
instance with its own history. Previously a single instance was reused
across chapters, so the content swap entered the undo stack and Ctrl+Z
after switching restored the prior chapter's doc into the current one,
which autosave then persisted.
With remount, save the cursor/scroll position on unmount (from a ref,
not the editor, which is destroyed by then) and load it on mount,
replacing the in-place chapter-switch bookkeeping.
Claude-Session: https://claude.ai/code/session_01RzTWrLiy4zGuw2hZSQGamk
Positions were kept in an in-memory Map, so they were lost on quit and
the cursor jumped to the top on reopen. Store them in localStorage
(keyed by book + chapter, like theme/width) and restore on app open,
not just on in-session chapter switches. Also save the current chapter
continuously (debounced on selection + scroll) so closing the app
records where you left off, and re-apply scroll after fonts load.