diff options
| author | Christophe Besson <cbesson@gmail.com> | 2026-08-16 20:57:52 +0200 |
|---|---|---|
| committer | Christophe Besson <cbesson@gmail.com> | 2026-08-16 20:57:52 +0200 |
| commit | 5dea19d9950518887be7eb14696f600ee023dbbd (patch) | |
| tree | 024b5f946f737713b175f33b27426f9d9a74cb5a /CLAUDE.md | |
| parent | 373f83236816aaff536dfa2f9589801acac44012 (diff) | |
| download | meshbay-5dea19d9950518887be7eb14696f600ee023dbbd.tar.gz | |
fix(hub): serve the SPA under a fingerprint of what it is
`Cache-Control: no-cache` requires a browser to revalidate, but it only binds
one that asks. A browser that cached app.js before that header existed applies
heuristic freshness instead — a fraction of the file's age, which for a file
dated weeks ago is days — and never asks. It then runs an old player against a
new node.
That cost most of a session. A phone kept a player without the read-ahead bound
and filled the browser's buffer ceiling at 106 MB, the exact symptom the bound
had been written to remove, for an hour after the bounded player went live. A
fix that is written, tested, deployed and served, and still not what runs, is
indistinguishable from a fix that does not work.
The whole module graph now lives under `/a/<content-hash>/`. A path prefix
rather than a query string, because relative imports inherit it: `app.js`
reaching for `./i18n.js` gets the build it was written against, and never a
mixture of two — which does not render a stale page, it fails to link. The URL
changes with the content, so those may be cached hard.
`sw.js` stays at the root. Its scope is its own path, and under the prefix it
would no longer control the pages whose downloads it exists to intercept.
Diffstat (limited to 'CLAUDE.md')
0 files changed, 0 insertions, 0 deletions