const CACHE_NAME = 'financial-static-v1'; const STATIC_ASSETS = [ '/offline.html', '/assets/vendor/bootstrap.min.css', '/assets/vendor/bootstrap.bundle.min.js', '/assets/vendor/chart.umd.js', '/assets/app.css', '/assets/pwa.js', '/favicon.png?v=2', '/manifest.webmanifest' ]; self.addEventListener('install', event => { event.waitUntil( caches.open(CACHE_NAME) .then(cache => cache.addAll(STATIC_ASSETS)) .catch(() => undefined) ); self.skipWaiting(); }); self.addEventListener('activate', event => { event.waitUntil( caches.keys().then(keys => Promise.all( keys.filter(key => key !== CACHE_NAME).map(key => caches.delete(key)) )) ); self.clients.claim(); }); self.addEventListener('fetch', event => { const request = event.request; if (request.method !== 'GET') { return; } const url = new URL(request.url); if (url.origin !== location.origin) { return; } if (url.pathname.startsWith('/api/')) { return; } if (url.pathname.startsWith('/assets/vendor/') || url.pathname === '/assets/app.css' || url.pathname === '/assets/pwa.js' || url.pathname === '/manifest.webmanifest' || url.pathname === '/favicon.png') { event.respondWith( caches.match(request).then(cached => cached || fetch(request)) ); return; } if (request.mode === 'navigate') { event.respondWith( fetch(request).catch(() => caches.match('/offline.html')) ); } });