// Minimal service worker: cache the app shell so site is quickly available and installable. const CACHE_NAME = 'phone-webcam-v1'; const FILES_TO_CACHE = [ '/', '/manifest.json', '/static/index.html', '/static/index.html', // duplicated intentionally harmless '/static/icon-192.png' ]; self.addEventListener('install', (evt) => { evt.waitUntil( caches.open(CACHE_NAME).then(cache => cache.addAll(FILES_TO_CACHE)) ); self.skipWaiting(); }); self.addEventListener('activate', (evt) => { evt.waitUntil( caches.keys().then(keys => Promise.all( keys.map(k => { if (k !== CACHE_NAME) return caches.delete(k); }) )) ); self.clients.claim(); }); self.addEventListener('fetch', (evt) => { // network-first for /offer (dynamic), cache-first for app shell assets const url = new URL(evt.request.url); if (url.pathname === '/offer') { // passthrough to network evt.respondWith(fetch(evt.request)); return; } evt.respondWith( caches.match(evt.request).then(cached => cached || fetch(evt.request).then(resp => { // optionally cache dynamic responses here return resp; }).catch(() => { // fallback could be a blank response for image or offline page return caches.match('/'); })) ); });