/* * UdyamLinc service worker — app-shell precache + stale-while-revalidate. * * Scope of the offline promise (deck feature 7): the enterprise PWA must open, * render and accept ledger entries with zero connectivity. Ledger writes are * queued in localStorage by the app itself (see lib/ledgerStore.ts); this worker * only guarantees the shell and its assets are reachable. */ const CACHE = 'udyamlinc-v1' const SHELL = ['/', '/app', '/index.html', '/manifest.webmanifest', '/udyamlinc-tile.svg'] self.addEventListener('install', (event) => { event.waitUntil(caches.open(CACHE).then((c) => c.addAll(SHELL)).then(() => self.skipWaiting())) }) self.addEventListener('activate', (event) => { event.waitUntil( caches .keys() .then((keys) => Promise.all(keys.filter((k) => k !== CACHE).map((k) => caches.delete(k)))) .then(() => self.clients.claim()), ) }) self.addEventListener('fetch', (event) => { const req = event.request if (req.method !== 'GET') return const url = new URL(req.url) // API calls are never served stale — the app falls back to its local store instead. if (url.pathname.includes('/api/')) return // Navigations: network first, fall back to the cached shell when offline. if (req.mode === 'navigate') { event.respondWith(fetch(req).catch(() => caches.match('/index.html'))) return } // Assets: cache first, refresh in the background. event.respondWith( caches.match(req).then((hit) => { const network = fetch(req) .then((res) => { if (res.ok) { const copy = res.clone() caches.open(CACHE).then((c) => c.put(req, copy)) } return res }) .catch(() => hit) return hit || network }), ) })