Files
readest/apps/readest-app
Huang Xin fa120081a1 fix(library): never let a routine save shrink library.json (cold-start "Open with" wipe) (#4627)
Opening a book via Android "Open with" on a cold start could clear the
entire library. `openTransient` built an ephemeral entry on top of the
not-yet-loaded (empty) store; the library page's `length > 0` cached-skip
then skipped loading the real library from disk; and a later
`saveLibraryBooks` persisted the empty/partial set — overwriting both
library.json and its .bak. Introduced by #4407 (transient "Open with"),
made reliably reproducible by #4527 (reliable cold-start delivery) — so
released v0.11.4, which lacks #4527, does not reproduce it.

Two layers of defense:

- saveLibraryBooks now merges with the on-disk library (union by hash,
  incoming wins), so a routine save is monotonic: it can add or modify
  rows (including `deletedAt` tombstones) but can never drop a book.
  Deliberate, authoritative rewrites (restore, tombstone GC, account
  reset) opt in via the new `{ replace: true }`. This layer alone makes
  the wipe impossible.
- openTransient loads the real library from disk before importing a
  transient book — also fixing the cold-start hash-match miss that
  re-imported already-imported books — and the library page's load-skip
  now gates on the store's `libraryLoaded` flag instead of `length > 0`.

Tests cover the merge floor (no-drop / no-wipe-on-empty / tombstone
preserved / incoming-wins) and both `{ replace: true }` paths.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 07:04:00 +02:00
..