feat(offline)!: deploy-proof PWA cache + universal recipe loads
CI / update (push) Successful in 1m10s

Service worker:
- Strip version suffix from CACHE_PAGES and CACHE_IMAGES so cached pages
  and recipe thumbs survive SW updates. Each deploy used to wipe both,
  forcing a re-sync before the user could open the app offline. Build
  and static caches stay version-suffixed (entries are hash-fingerprinted).
- Install precaches the offline shells: /, /rezepte, /recipes, both
  offline-shell pages, /glaube, /faith, /fitness — best-effort with
  Promise.allSettled so a single 5xx can't fail SW install.
- Bulk thumbnail precache now skips URLs already in CACHE_IMAGES.
  Recipe thumb URLs embed a content hash, so a cache hit guarantees
  identical bytes; subsequent syncs after small recipe edits no longer
  redownload every image.
- Activate cleanup deletes only stale versioned build/static entries
  and obsolete versioned pages/images caches.

Universal load migration:
- [recipeLang]/+layout.server.ts removed; logic in universal +layout.ts.
  Session fetched from /auth/session, nulled when offline.
- [recipeLang]/+page.server.ts and season/[month]/+page.server.ts
  removed; merged into universal +page.ts. Drops the __data.json
  round-trip entirely for these routes — IndexedDB fallback now runs
  even when the SW page cache is empty (fresh install, hash mismatch,
  etc.) instead of getting blocked by a 503 from the data handler.

Other:
- /static/rezepte/thumb URLs in sync.ts and the SW thumb fallback now
  use the absolute https://bocken.org origin. Dev/preview servers don't
  host /static/rezepte and were 404ing on themselves; production keys
  resolve to the same string so existing caches stay valid.
- Root +layout.svelte invalidateAll() now bails when !navigator.onLine.
  Resume-while-offline used to refetch every load() and surface the
  error page instead of the still-viewable cached content.

Bump 1.64.2 -> 1.65.2.
This commit is contained in:
2026-05-04 21:25:39 +02:00
parent 1bceabe967
commit 065c435d8b
10 changed files with 177 additions and 154 deletions
+4 -3
View File
@@ -278,13 +278,14 @@ async function precacheThumbnails(
const registration = await navigator.serviceWorker.ready;
if (!registration.active) return;
// Collect all thumbnail URLs using mediapath (includes hash for cache busting)
// Collect all thumbnail URLs using mediapath (includes hash for cache busting).
// Absolute origin so dev/preview servers — which don't host /static/rezepte —
// fetch directly from production instead of 404ing on themselves.
const thumbnailUrls: string[] = [];
for (const recipe of recipes) {
if (recipe.images && recipe.images.length > 0) {
const mediapath = recipe.images[0].mediapath;
// Thumbnail path format: /static/rezepte/thumb/{mediapath}
thumbnailUrls.push(`/static/rezepte/thumb/${mediapath}`);
thumbnailUrls.push(`https://bocken.org/static/rezepte/thumb/${mediapath}`);
}
}