diff --git a/frontend/public/sw.js b/frontend/public/sw.js index 5a3179e..e976c34 100644 --- a/frontend/public/sw.js +++ b/frontend/public/sw.js @@ -1,4 +1,4 @@ -const CACHE_NAME = 'agency-cache-v3'; +const CACHE_NAME = 'agency-cache-v4'; const ASSETS = [ '/', '/index.html', @@ -7,11 +7,28 @@ const ASSETS = [ '/icon-512.png' ]; +// Force immediate update to the latest SW self.addEventListener('install', (event) => { event.waitUntil( caches.open(CACHE_NAME).then((cache) => { return cache.addAll(ASSETS); - }) + }).then(() => self.skipWaiting()) + ); +}); + +// Clean up old caches and take control of all clients immediately +self.addEventListener('activate', (event) => { + event.waitUntil( + caches.keys().then((cacheNames) => { + return Promise.all( + cacheNames.map((cacheName) => { + if (cacheName !== CACHE_NAME) { + console.log('Deleting old cache:', cacheName); + return caches.delete(cacheName); + } + }) + ); + }).then(() => self.clients.claim()) ); }); @@ -20,16 +37,27 @@ self.addEventListener('fetch', (event) => { if (!event.request.url.startsWith('http')) return; event.respondWith( - caches.match(event.request).then((response) => { - // Return cached response if found, otherwise fetch from network - return response || fetch(event.request).catch(error => { + caches.match(event.request).then((cachedResponse) => { + if (cachedResponse) { + return cachedResponse; + } + + return fetch(event.request).catch((error) => { // If network fetch fails and it's a navigation request, return index.html if (event.request.mode === 'navigate') { return caches.match('/index.html'); } - // For assets, let the browser handle the failure normally - console.error('Fetch failed:', event.request.url, error); - throw error; + + // For assets, return a failure response instead of throwing. + // Re-throwing (or returning a rejected promise) causes the browser to show + // the "unexpected error" interception UI. + console.warn('Fetch failed for:', event.request.url, error); + + return new Response('Network error occurred', { + status: 503, + statusText: 'Service Unavailable', + headers: new Headers({ 'Content-Type': 'text/plain' }) + }); }); }) );