[Reader][Perf] EPUB page prefetch/LRU + fix dead ngsw api-books cache group #650

Closed
opened 2026-07-17 13:52:16 +00:00 by spikerj · 2 comments
Owner

First slice of the reader offline/caching workstream (WS-1).

Prefetch + LRU (new epub-page-cache.service.ts): a read-through in-memory LRU (24 pages) with in-flight de-duplication in front of getEpubPage, plus prefetchAround(±5) after each load so page turns are usually instant. Wired into epub-reader.loadPage. (This is the online perf layer; the IndexedDB offline store is a separate follow-up.)

ngsw fix: the api-books dataGroup pointed at https://api.spikersoft.com/Book* — a path that never exists (real API is /api/...), so it cached nothing. Replaced with:

  • api-book-metadata/api/book/* (freshness 7d). ngsw's * = [^/]* (single segment), so this matches only the bare metadata GET — not /api/book/{id}/file (auth'd PDF) or /epub-page.
  • api-epub-pages/api/book/*/epub-page* (freshness, 2s timeout).
  • api-epub-resources/api/book/*/epub-resource* (performance 30d).

Critically, /api/book/{id}/file and all /api/reader/* (progress, bookmarks, social) match no dataGroup, so auth'd/dynamic data is never SW-cached.

Note: ngsw config isn't unit-testable — the caching scope should be spot-checked against a built SW (confirm /file and /api/reader/* aren't in any cache).

Remaining WS-1 (follow-up PRs): IndexedDB offline book store + download service (quota preflight/rollback/progress), offline reader fallback + blob-URL resource rewriting, download-button UI + profile offline-books section, auth.guard offline entry.

PR: spikersoft-angular feat/reader-offline-ngsw-prefetch.

First slice of the reader offline/caching workstream (WS-1). **Prefetch + LRU** (new `epub-page-cache.service.ts`): a read-through in-memory LRU (24 pages) with in-flight de-duplication in front of `getEpubPage`, plus `prefetchAround(±5)` after each load so page turns are usually instant. Wired into `epub-reader.loadPage`. (This is the online perf layer; the IndexedDB offline store is a separate follow-up.) **ngsw fix**: the `api-books` dataGroup pointed at `https://api.spikersoft.com/Book*` — a path that never exists (real API is `/api/...`), so it cached nothing. Replaced with: - `api-book-metadata` — `/api/book/*` (freshness 7d). ngsw's `*` = `[^/]*` (single segment), so this matches only the bare metadata GET — **not** `/api/book/{id}/file` (auth'd PDF) or `/epub-page`. - `api-epub-pages` — `/api/book/*/epub-page*` (freshness, 2s timeout). - `api-epub-resources` — `/api/book/*/epub-resource*` (performance 30d). Critically, `/api/book/{id}/file` and all `/api/reader/*` (progress, bookmarks, social) match **no** dataGroup, so auth'd/dynamic data is never SW-cached. Note: ngsw config isn't unit-testable — the caching scope should be spot-checked against a built SW (confirm `/file` and `/api/reader/*` aren't in any cache). **Remaining WS-1 (follow-up PRs):** IndexedDB offline book store + download service (quota preflight/rollback/progress), offline reader fallback + blob-URL resource rewriting, download-button UI + profile offline-books section, `auth.guard` offline entry. PR: spikersoft-angular `feat/reader-offline-ngsw-prefetch`.
Author
Owner

Resolved in spikersoft-angular PR #223 (merged to master). EpubPageCacheService (LRU + prefetch±5 + in-flight dedupe) wired into epub-reader.loadPage; ngsw api-books (dead /Book*) replaced with api-book-metadata/api-epub-pages/api-epub-resources — auth'd /file and /api/reader/* match no dataGroup. Closing.

Resolved in spikersoft-angular PR #223 (merged to `master`). EpubPageCacheService (LRU + prefetch±5 + in-flight dedupe) wired into `epub-reader.loadPage`; ngsw `api-books` (dead `/Book*`) replaced with `api-book-metadata`/`api-epub-pages`/`api-epub-resources` — auth'd `/file` and `/api/reader/*` match no dataGroup. Closing.
Author
Owner

Resolved in spikersoft-backend PR #360 (merged to master). The two empty catches are gone — Keycloak update failures now propagate to UserController, which logs and returns BadRequest (restoring the designed, already-tested behavior). The two handler tests that pinned the swallow were corrected to assert propagation. S2486 finding closes as FIXED on the next scan. Closing.

Resolved in spikersoft-backend PR #360 (merged to master). The two empty catches are gone — Keycloak update failures now propagate to UserController, which logs and returns BadRequest (restoring the designed, already-tested behavior). The two handler tests that pinned the swallow were corrected to assert propagation. S2486 finding closes as FIXED on the next scan. Closing.
Sign in to join this conversation.