import { scopedAssetPath } from './app-url.ts' export function serviceWorkerScript(scope: string) { const root = scope.endsWith('/') ? scope : `${scope}/` const shell = [ scopedAssetPath(root, 'manifest.webmanifest'), scopedAssetPath(root, 'favicon.png'), scopedAssetPath(root, 'apple-touch-icon.png'), scopedAssetPath(root, 'pwa-192.png'), scopedAssetPath(root, 'icon.svg'), ] return `const SCOPE = ${JSON.stringify(root)}; const VERSION = 'lineage-v9'; const SHELL = ${JSON.stringify(shell)}; self.addEventListener('install', (event) => { event.waitUntil( caches.open(VERSION).then((cache) => Promise.all(SHELL.map((url) => cache.add(url).catch(() => undefined))), ).then(() => { if (!self.registration.active) return self.skipWaiting(); }), ); }); self.addEventListener('activate', (event) => { event.waitUntil( caches.keys().then((keys) => Promise.all(keys.filter((key) => key !== VERSION).map((key) => caches.delete(key))), ).then(() => self.clients.claim()), ); }); self.addEventListener('message', (event) => { if (event.data === 'SKIP_WAITING') self.skipWaiting(); }); async function staleWhileRevalidate(request, cacheFirst) { const cache = await caches.open(VERSION); const cached = await cache.match(request); const network = fetch(request).then((response) => { if (response.ok) cache.put(request, response.clone()); return response; }); if (cacheFirst && cached) { network.catch(() => undefined); return cached; } try { return await network; } catch (error) { if (cached) return cached; throw error; } } self.addEventListener('fetch', (event) => { const request = event.request; if (request.method !== 'GET') return; const url = new URL(request.url); const isApi = url.pathname.includes('/api/'); const isDocument = request.mode === 'navigate' || url.pathname === SCOPE || url.pathname === SCOPE.slice(0, -1); if (isApi || isDocument) { const cacheFirst = isDocument || request.cache === 'default' || request.cache === 'force-cache'; event.respondWith(staleWhileRevalidate(request, cacheFirst)); return; } event.respondWith( caches.match(request).then((cached) => cached || fetch(request).then((response) => { const copy = response.clone(); caches.open(VERSION).then((cache) => cache.put(request, copy)); return response; })), ); }); ` }