1/* unbywyd.com â minimal service worker 2 * Strategy: 3 * - HTML / navigation requests: network-first, fallback to cache, then offline.html 4 * - Static assets (images, css, js, fonts, manifest, video): cache-first with background revalidate 5 * - All other GET: network-first, fallback to cache 6 * Bumping CACHE_VERSION invalidates all old caches on the next visit. 7 */ 8 9const CACHE_VERSION = 'v2'; 10const STATIC_CACHE = `unbywyd-static-${CACHE_VERSION}`; 11const RUNTIME_CACHE = `unbywyd-runtime-${CACHE_VERSION}`; 12const OFFLINE_URL = '/offline.html'; 13 14const PRECACHE_URLS = [ 15 '/', 16 '/index.html', 17 '/offline.html', 18 '/manifest.webmanifest', 19 '/icon-192.png', 20 '/icon-512.png' 21]; 22 23self.addEventListener('install', (event) => { 24 event.waitUntil( 25 caches.open(STATIC_CACHE).then((cache) => cache.addAll(PRECACHE_URLS)) 26 .then(() => self.skipWaiting()) 27 ); 28}); 29 30self.addEventListener('activate', (event) => { 31 event.waitUntil( 32 caches.keys().then((keys) => Promise.all( 33 keys.filter((k) => k !== STATIC_CACHE && k !== RUNTIME_CACHE).map((k) => caches.delete(k)) 34 )).then(() => self.clients.claim()) 35 ); 36}); 37 38function isStaticAsset(url) { 39 return /\.(?:png|jpg|jpeg|webp|svg|gif|ico|css|js|woff2?|ttf|otf|mp4|webm|json|webmanifest)$/i.test(url.pathname); 40} 41 42self.addEventListener('fetch', (event) => { 43 const req = event.request; 44 if (req.method !== 'GET') return; 45 46 const url = new URL(req.url); 47 const sameOrigin = url.origin === self.location.origin; 48 49 // navigation / HTML â network first, fallback to cache, then offline page 50 if (req.mode === 'navigate' || (req.headers.get('accept') || '').includes('text/html')) { 51 event.respondWith( 52 fetch(req).then((res) => { 53 const copy = res.clone(); 54 caches.open(RUNTIME_CACHE).then((c) => c.put(req, copy)).catch(() => {}); 55 return res; 56 }).catch(() => caches.match(req).then((cached) => cached || caches.match(OFFLINE_URL))) 57 ); 58 return; 59 } 60 61 // static assets â cache first, revalidate in background (stale-while-revalidate) 62 if (isStaticAsset(url) || !sameOrigin) { 63 event.respondWith( 64 caches.match(req).then((cached) => { 65 const fetchPromise = fetch(req).then((res) => { 66 if (res && res.status === 200 && (sameOrigin || res.type === 'cors' || res.type === 'opaque')) { 67 const copy = res.clone(); 68 caches.open(RUNTIME_CACHE).then((c) => c.put(req, copy)).catch(() => {}); 69 } 70 return res; 71 }).catch(() => cached); 72 return cached || fetchPromise; 73 }) 74 ); 75 return; 76 } 77 78 // default: network first 79 event.respondWith( 80 fetch(req).then((res) => { 81 const copy = res.clone(); 82 caches.open(RUNTIME_CACHE).then((c) => c.put(req, copy)).catch(() => {}); 83 return res; 84 }).catch(() => caches.match(req)) 85 ); 86}); 87 88// allow page to trigger immediate activation after a fresh deploy 89self.addEventListener('message', (event) => { 90 if (event.data === 'SKIP_WAITING') self.skipWaiting(); 91});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.