/// /// /// /// import { build, files, version } from '$service-worker'; const sw = self as unknown as ServiceWorkerGlobalScope; const APP_CACHE = `kochwas-app-${version}`; const IMAGE_CACHE = `kochwas-images-v1`; const APP_ASSETS = [...build, ...files]; sw.addEventListener('install', (event) => { event.waitUntil( caches.open(APP_CACHE).then((cache) => cache.addAll(APP_ASSETS)) ); // Activate new worker without waiting for old clients to close. void sw.skipWaiting(); }); sw.addEventListener('activate', (event) => { event.waitUntil( (async () => { const keys = await caches.keys(); await Promise.all( keys .filter((k) => k.startsWith('kochwas-app-') && k !== APP_CACHE) .map((k) => caches.delete(k)) ); await sw.clients.claim(); })() ); }); sw.addEventListener('fetch', (event) => { const req = event.request; if (req.method !== 'GET') return; const url = new URL(req.url); if (url.origin !== location.origin) return; // Images served from /images/* — cache-first with background update if (url.pathname.startsWith('/images/')) { event.respondWith( (async () => { const cache = await caches.open(IMAGE_CACHE); const cached = await cache.match(req); const network = fetch(req) .then((res) => { if (res.ok) void cache.put(req, res.clone()); return res; }) .catch(() => undefined); return cached ?? (await network) ?? new Response('Offline', { status: 503 }); })() ); return; } // App shell assets (build/* and static files) — cache-first if (APP_ASSETS.includes(url.pathname)) { event.respondWith( (async () => { const cache = await caches.open(APP_CACHE); const cached = await cache.match(req); return cached ?? fetch(req); })() ); return; } // API and HTML pages — network-first, fall back to cache for HTML if (req.destination === 'document') { event.respondWith( (async () => { try { const res = await fetch(req); const cache = await caches.open(APP_CACHE); if (res.ok) void cache.put(req, res.clone()); return res; } catch { const cached = await caches.match(req); return cached ?? new Response('Offline', { status: 503 }); } })() ); } });