// Service Worker – Network-first für HTML, kein Cache für Assets // Stellt sicher dass nach einem Deploy immer der neue Stand geladen wird const CACHE_NAME = 'dickendock-v2'; self.addEventListener('install', () => { self.skipWaiting(); // sofort aktivieren, nicht auf Tab-Schließen warten }); self.addEventListener('activate', e => { // Alle alten Caches löschen e.waitUntil( caches.keys() .then(keys => Promise.all(keys.map(k => caches.delete(k)))) .then(() => self.clients.claim()) // alle offenen Tabs übernehmen ); }); self.addEventListener('fetch', e => { const url = new URL(e.request.url); // API-Requests immer direkt ans Netzwerk, nie cachen if (url.pathname.startsWith('/api/')) { e.respondWith(fetch(e.request)); return; } // index.html und Navigation: Network-first, kein Cache // Damit nach einem Deploy immer die neue Version geladen wird if (e.request.mode === 'navigate' || url.pathname === '/' || url.pathname === '/index.html') { e.respondWith( fetch(e.request, { cache: 'no-store' }) .catch(() => caches.match('/index.html')) // Fallback wenn offline ); return; } // JS/CSS/Assets: Network-first mit Cache-Fallback // Vite baut mit Content-Hash im Dateinamen → neue Version = neue URL e.respondWith( fetch(e.request) .then(response => { // Erfolgreiche Antwort kurz cachen als Offline-Fallback if (response.ok) { const clone = response.clone(); caches.open(CACHE_NAME).then(cache => cache.put(e.request, clone)); } return response; }) .catch(() => caches.match(e.request)) ); }); // Auf Update-Nachricht vom Frontend reagieren self.addEventListener('message', e => { if (e.data === 'SKIP_WAITING') self.skipWaiting(); });