fix(persist): flush pending save on navigate-away and quit

Edits are saved on an 800ms debounce, so leaving a book within that
window lost the latest changes. Flush a dirty book before openBook /
closeBook swap state (covers All books, open-another, Cmd+N), and add a
window close-request handler that saves before destroying on quit.

Claude-Session: https://claude.ai/code/session_01RzTWrLiy4zGuw2hZSQGamk
This commit is contained in:
pj committed 2026-06-22 13:16:33 -04:00
1 parent 0bc3e36ee6
commit 14eb3c4427
3 files changed
+29 -3

No files matched your search

+11 -2
View File
@@ -13,6 +13,7 @@ import {
normalizeBook,
} from "../model/book";
import { loadActiveChapter, saveActiveChapter } from "../editor/positions";
import { saveBook } from "../library";
export const COVER_ID = "__cover__";
@@ -41,7 +42,11 @@ interface BookState {
markSaved: () => void;
}
export const useBook = create<BookState>((set) => ({
function flushOutgoing(book: Book | null, dirty: boolean): void {
if (book && dirty) saveBook(book).catch(() => {});
}
export const useBook = create<BookState>((set, get) => ({
book: null,
activeChapterId: "",
dirty: false,
@@ -50,13 +55,17 @@ export const useBook = create<BookState>((set) => ({
setExporting: (label) => set({ exporting: label }),
setNotice: (message) => set({ notice: message }),
openBook: (book) => {
flushOutgoing(get().book, get().dirty);
const normalized = normalizeBook(book);
const saved = loadActiveChapter(normalized.id);
const valid = saved === COVER_ID || normalized.chapters.some((c) => c.id === saved);
const activeChapterId = valid ? (saved as string) : normalized.chapters[0]?.id ?? "";
set({ book: normalized, activeChapterId, dirty: false });
},
closeBook: () => set({ book: null, activeChapterId: "", dirty: false }),
closeBook: () => {
flushOutgoing(get().book, get().dirty);
set({ book: null, activeChapterId: "", dirty: false });
},
setActiveChapter: (id) => set({ activeChapterId: id }),
setChapterContent: (id, content) =>
set((s) =>