Show the update banner only when the running build differs from the server and make Refresh UI land the new shell on flaky links
This commit is contained in:
32
CLAUDE.md
32
CLAUDE.md
@@ -95,12 +95,32 @@ Local DB file: `server/data/ytplayer.db` (gitignored). `BUILD_TAG` is computed f
|
||||
"Update available keeps showing" bug.
|
||||
- `BUILD_TAG` hashes **every** file under `./public` recursively. Don't reduce it
|
||||
to a file subset; a change to an unlisted shell file would stop busting caches.
|
||||
- The update banner only shows when a waiting SW exists **and the page already
|
||||
has a controller** — a first install (fresh visit, or after Settings → Force
|
||||
refresh unregisters) passes through `waiting` transiently and must not banner.
|
||||
- "Refresh UI" (`frontend/sw-update.js`): if no worker is waiting yet (banner came
|
||||
from the `/api/version` poll), it calls `reg.update()`, waits for `installed`,
|
||||
posts SKIP_WAITING, waits for `controllerchange`, then reloads once.
|
||||
- **The banner has ONE rule** (`maybeShowUpdateBanner` in app.js): show it only
|
||||
when the build this page runs differs from `/api/version`. The server stamps
|
||||
the running build into index.html (`<meta name="ytp-build">`, at request
|
||||
time like sw.js's BUILD_TAG); the SW caches that index.html with the rest of the
|
||||
shell, so the meta always describes the code in the tab. The poll, a waiting
|
||||
worker and the SW_UPDATE_AVAILABLE broadcast are only *prompts to re-check*.
|
||||
This loop was "fixed" three times by chasing individual triggers — don't add
|
||||
a trigger that calls `showUpdateBanner()` directly.
|
||||
- **Refresh UI** (`frontend/sw-update.js`): `refreshShellInPlace()` re-downloads
|
||||
every file the shell caches hold — cache-busted (`?__ytpfresh=`) so even an
|
||||
OLD worker's cache-first handler can't answer from its cache, 3 tries per file,
|
||||
all-or-nothing — and writes them into every versioned shell cache; then it
|
||||
activates a waiting worker (SKIP_WAITING) if any and reloads once. A failed
|
||||
download shows an error toast and re-offers later; it never reloads into the
|
||||
old shell. `checkUpdateOutcome()` verifies after the reload (sessionStorage,
|
||||
max 3 attempts) instead of looping.
|
||||
- **Why it kept looping on prod:** the VPS→homelab link is slow and drops
|
||||
requests. The SW install (`cache.addAll`, all-or-nothing) failed, Refresh UI
|
||||
reloaded into the old cached shell, and the partial `ytplayer-<tag>` cache
|
||||
left by the failed install later made activate broadcast "update available"
|
||||
to pages that were already current. sw.js now precaches with
|
||||
`cache: 'reload'`, retries each file, and deletes its partial cache on failure.
|
||||
- Reproduce with the throttling/stalling proxy approach: WebKit (Playwright on
|
||||
the Windows side) or Chrome over CDP against a scratch copy of the server,
|
||||
stalling every Nth shell request after "deploying" v2. A fast local link never
|
||||
shows the bug.
|
||||
|
||||
## Cache layout & offline thumbnails
|
||||
- Three cache families, and the split matters on activate: the **versioned shell
|
||||
|
||||
Reference in New Issue
Block a user