// ============================================================ // SERVICE WORKER — Cache the React shell + manifest. // Network-first for API (medical data must always be fresh). // Hashed Vite assets are NOT precached — they change every build, // the browser HTTP cache plus immutable Cache-Control handles them. // ============================================================ var CACHE_NAME = 'pedscribe-v13'; var SHELL_ASSETS = [ '/', '/manifest.json', ]; // Install: precache shell. Errors swallowed so a missing single // asset doesn't break SW install entirely. self.addEventListener('install', function(event) { event.waitUntil( caches.open(CACHE_NAME).then(function(cache) { return Promise.allSettled(SHELL_ASSETS.map(function(url) { return cache.add(url).catch(function() {}); })); }).then(function() { return self.skipWaiting(); }) ); }); // Activate: clear old caches (deletes pedscribe-v12 and earlier). self.addEventListener('activate', function(event) { event.waitUntil( caches.keys().then(function(names) { return Promise.all( names.filter(function(name) { return name !== CACHE_NAME; }) .map(function(name) { return caches.delete(name); }) ); }).then(function() { return self.clients.claim(); }) ); }); self.addEventListener('fetch', function(event) { if (event.request.method !== 'GET') return; var url = new URL(event.request.url); // Same-origin only; skip cross-origin (CDN, fonts, etc.) if (url.origin !== self.location.origin) return; // API: network only — never cache medical data. if (url.pathname.startsWith('/api/')) return; // Hashed Vite assets: serve from network, fall back to cache if offline. if (url.pathname.startsWith('/app/assets/')) { event.respondWith( fetch(event.request).catch(function() { return caches.match(event.request); }) ); return; } // SPA shell + everything else: cache-first with network update. event.respondWith( caches.match(event.request).then(function(cached) { var fetchPromise = fetch(event.request).then(function(resp) { if (resp && resp.status === 200) { var copy = resp.clone(); caches.open(CACHE_NAME).then(function(cache) { cache.put(event.request, copy); }); } return resp; }).catch(function() { return cached; }); return cached || fetchPromise; }) ); });