/// /// /// /// import { build, files, version } from '$service-worker'; const sw = self as unknown as ServiceWorkerGlobalScope; const APP_SHELL = `jwe-shell-${version}`; // immuable, recréé à chaque build const PHOTOS = 'jwe-photos'; // stale-while-revalidate const ASSETS = [...build, ...files]; sw.addEventListener('install', (event) => { event.waitUntil(caches.open(APP_SHELL).then((cache) => cache.addAll(ASSETS))); }); sw.addEventListener('activate', (event) => { event.waitUntil( caches.keys().then((keys) => Promise.all( keys .filter((key) => key !== APP_SHELL && key !== PHOTOS) .map((key) => caches.delete(key)) ) ) ); }); function isPhoto(url: URL): boolean { return ( url.hostname === 'upload.wikimedia.org' || (url.hostname === 'commons.wikimedia.org' && url.pathname.startsWith('/wiki/Special:FilePath')) ); } sw.addEventListener('fetch', (event) => { const url = new URL(event.request.url); if (event.request.method !== 'GET') return; // App shell : cache d'abord if (ASSETS.includes(url.pathname)) { event.respondWith(caches.match(event.request).then((r) => r ?? fetch(event.request))); return; } // Photos Wikimedia : stale-while-revalidate if (isPhoto(url)) { event.respondWith( caches.open(PHOTOS).then(async (cache) => { const cached = await cache.match(event.request); const frais = fetch(event.request) .then((res) => { if (res.ok) void cache.put(event.request, res.clone()); return res; }) .catch(() => cached as Response); return cached ?? frais; }) ); return; } });