1const CACHE_VERSION = "huduma-shell-v2"; 2const SAFE_SHELL = [ 3 "/offline.html", 4 "/manifest.json", 5 "/logo192.png", 6 "/logo512.png", 7 "/favicon.ico", 8]; 9 10self.addEventListener("install", (event) => { 11 event.waitUntil( 12 caches.open(CACHE_VERSION).then((cache) => cache.addAll(SAFE_SHELL)), 13 ); 14 self.skipWaiting(); 15}); 16 17self.addEventListener("activate", (event) => { 18 event.waitUntil( 19 caches 20 .keys() 21 .then((keys) => 22 Promise.all( 23 keys.filter((key) => key !== CACHE_VERSION).map((key) => caches.delete(key)), 24 ), 25 ) 26 .then(() => self.clients.claim()), 27 ); 28}); 29 30self.addEventListener("fetch", (event) => { 31 const request = event.request; 32 if (request.method !== "GET") return; 33 const url = new URL(request.url); 34 if (url.origin !== self.location.origin) return; 35 36 // Pages and all live Firebase/API data stay network-first. This prevents an 37 // installed device from showing stale exam access, answers, or results. 38 if (request.mode === "navigate") { 39 event.respondWith( 40 fetch(request).catch(() => caches.match("/offline.html")), 41 ); 42 return; 43 } 44 45 // Only immutable build assets and public branding are cached locally. 46 if ( 47 url.pathname.startsWith("/static/") || 48 SAFE_SHELL.includes(url.pathname) 49 ) { 50 event.respondWith( 51 caches.match(request).then( 52 (cached) => 53 cached || 54 fetch(request).then((response) => { 55 if (response.ok) { 56 const copy = response.clone(); 57 caches.open(CACHE_VERSION).then((cache) => cache.put(request, copy)); 58 } 59 return response; 60 }), 61 ), 62 ); 63 } 64});
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.