const APP_SHELL_CACHE = 'privatechat-app-shell-v1'; const APP_SHELL_FILES = [ '/', '/index.html', '/manifest.webmanifest', '/favicon.ico', '/apple-touch-icon.png', '/pwa-192x192.png', '/pwa-512x512.png', '/maskable-192x192.png', '/maskable-512x512.png', ]; self.addEventListener('install', (event) => { event.waitUntil( caches.open(APP_SHELL_CACHE).then((cache) => cache.addAll(APP_SHELL_FILES)), ); self.skipWaiting(); }); self.addEventListener('activate', (event) => { event.waitUntil( caches.keys().then((cacheNames) => Promise.all( cacheNames .filter((cacheName) => cacheName !== APP_SHELL_CACHE) .map((cacheName) => caches.delete(cacheName)), )), ); self.clients.claim(); }); self.addEventListener('fetch', (event) => { const { request } = event; if (request.method !== 'GET') { return; } const url = new URL(request.url); if (url.origin !== self.location.origin || url.pathname.startsWith('/api/') || url.pathname === '/ws') { return; } if (request.mode === 'navigate') { event.respondWith( fetch(request) .then((response) => { const responseCopy = response.clone(); void caches.open(APP_SHELL_CACHE).then((cache) => cache.put('/index.html', responseCopy)); return response; }) .catch(async () => { const cache = await caches.open(APP_SHELL_CACHE); return cache.match('/index.html') || Response.error(); }), ); return; } event.respondWith( caches.match(request).then((cachedResponse) => { const networkFetch = fetch(request) .then((response) => { if (response.ok) { const responseCopy = response.clone(); void caches.open(APP_SHELL_CACHE).then((cache) => cache.put(request, responseCopy)); } return response; }) .catch(() => cachedResponse || Response.error()); return cachedResponse || networkFetch; }), ); });