Service worker caching strategy
CI / ci (pull_request) Successful in 1m34s
CI / ci (push) Successful in 1m33s

Precache the shell, JS, CSS and self-hosted fonts in
mealquest-precache-v1. Route every other request through the pure
src/sw/routes.ts decision: NetworkFirst (3 s timeout) for plans,
shopping, dinners and home; CacheFirst with expiration for /media/* and
font files; NetworkOnly for /auth/*, settings, jobs and every non-GET.
App navigations fall back to the precached index.html offline. On
activate, delete only stale caches named mealquest-*.

Maestro task: 8fa0d0bd-4a52-4f09-ba68-41bdbdfda63b

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-04 16:20:19 -04:00
co-authored by Claude Opus 5.5
parent dd58865323
commit fe124f0d52
5 changed files with 288 additions and 8 deletions
+19
View File
@@ -95,6 +95,25 @@ describe('production build', () => {
}
})
it('precaches the shell, JS, CSS and every self-hosted font', async () => {
const sw = await (await get('/sw.js')).text()
const urls = [...sw.matchAll(/"url":"([^"]+)"/g)].map((match) => match[1])
// index.html keeps its URL across builds, so it carries a content
// revision; the other assets have content hashes in their names.
expect(sw).toMatch(/\{"revision":"[0-9a-f]{32}","url":"index\.html"\}/)
expect(urls.some((url) => url?.endsWith('.js'))).toBe(true)
expect(urls.some((url) => url?.endsWith('.css'))).toBe(true)
for (const font of [
'BagelFatOne-LatinExt',
'BagelFatOne-Latin',
'Figtree-Regular',
'Figtree-SemiBold',
'Figtree-Bold',
]) {
expect(urls.some((url) => url?.startsWith(`assets/${font}`) && url.endsWith('.woff2'))).toBe(true)
}
})
it('links the manifest, theme colour and apple-touch-icon from index.html', async () => {
const html = await (await get('/')).text()
expect(html.match(/<link rel="manifest" href="\/manifest\.webmanifest">/g)).toHaveLength(1)