Document search library, server search cache and versioned static caching

This commit is contained in:
Claude
2026-10-02 02:15:36 +00:00
parent ee248d2303
commit 883c9e7ba0

View File

@@ -57,12 +57,24 @@ JSON shapes mirror the Tauri Rust bridge exactly — don't change one side alone
- Now-playing tiles are `[svg.ti][span.tl]`; change state text with `setTile(btn, label)`, never `textContent`.
## Saved searches + caching notes
- `SearchLibrary` (app.js, localStorage `ytpSearchLibrary`, ≤150 queries × 50 results incl. thumbnail URLs) keeps
every search. The search box's recent list and its "Clear this list" only touch `ytpRecentSearches`; results are
deleted ONLY in Settings → Saved searches (select + delete, or clear all). Thumbnails are warmed into the SW
`ytplayer-thumbs` cache (`THUMB_CACHE_MAX` 2500). Browse view: `{type:'savedSearches'}`.
- `/api/search`: 10 min fresh cache, then stale-while-revalidate up to 6 h (answers instantly, refreshes in the
background); identical concurrent searches share one fetch (`fetchSearch`). `/fonts` and `/icons` are cached 30 days.
- `SearchLibrary` (app.js) keeps every search: metadata index in localStorage `ytpSearchIndex` (sync, ~250 KB),
result lists in IndexedDB `ytpSearchLibrary` (≤1000 queries × 100 results incl. thumbnail URLs; `get()` is async).
A saved copy is trusted 15 days (`FRESH_MS`): a fresh one is shown with NO network call, an older one is shown then
refreshed. The "Update search" button (`#searchMeta`) calls `API.search(q,{refresh:true})` → `/api/search?refresh=1`
which skips every server cache. The search box's recent list and its "Clear this list" only touch
`ytpRecentSearches`; results are deleted ONLY in Settings → Saved searches. Thumbnails are warmed into the SW
`ytplayer-thumbs` cache (`THUMB_CACHE_MAX` 25000, trimmed every 100th put — `cache.keys()` is costly at that size).
Browse view: `{type:'savedSearches'}`. Web Workers were NOT added: IndexedDB/fetch are already async off-thread I/O and
postMessage would clone the same data; DOM rendering can't move to a worker.
- Server `/api/search` (`server/search-cache.js`, tables `search_cache` + `video_meta`): memory (200, 10 min fresh) →
libsql (up to 200 YouTube cards per query via `innertube.searchDeep` continuation paging; ≤250,000 queries AND
`SEARCH_CACHE_MAX_BYTES` 2 GiB, LRU) → YouTube. Stale copies are served for 15 days while refreshing in the background.
Every card seen is also stored in `video_meta` (≤500k); `GET /api/search/local?q=` matches known videos by title/channel
(all words) + uploads in ms, and the app paints them while the real search loads. yt-dlp fallback still returns 25.
- Static files: index.html is stamped with `?v=<BUILD_TAG>` on local css/js (`indexHtml()`); a request whose `v` equals the
running build is `immutable, max-age=1y`, anything else `no-cache`. The SW `cacheFirst` matches `?v=` URLs with
`ignoreSearch` against the plain-URL precache. A new build = new URLs, so old ones simply get evicted.
`/fonts` and `/icons` are cached 30 days.
## Server media cache (`server/media-cache.js`)
- Every played (`/api/streams`, LOW priority, ≤ `MEDIA_AUTO_MAX_SECONDS`, default 3 h) or saved