58 lines
1.8 KiB
JavaScript
58 lines
1.8 KiB
JavaScript
// Service Worker – stellt sicher dass nach einem Deploy immer der neue Stand geladen wird
|
||
// index.html und API: immer vom Netzwerk (no-store)
|
||
// Assets (JS/CSS mit Hash): Network-first mit Cache-Fallback für Offline
|
||
|
||
const CACHE_NAME = 'dickendock-v2';
|
||
|
||
self.addEventListener('install', () => {
|
||
self.skipWaiting(); // sofort aktivieren ohne auf Tab-Schließen zu warten
|
||
});
|
||
|
||
self.addEventListener('activate', e => {
|
||
e.waitUntil(
|
||
caches.keys()
|
||
.then(keys => Promise.all(keys.map(k => caches.delete(k))))
|
||
.then(() => self.clients.claim()) // alle offenen Tabs sofort übernehmen
|
||
);
|
||
});
|
||
|
||
self.addEventListener('fetch', e => {
|
||
const url = new URL(e.request.url);
|
||
|
||
// API-Requests: nie cachen
|
||
if (url.pathname.startsWith('/api/')) {
|
||
e.respondWith(fetch(e.request));
|
||
return;
|
||
}
|
||
|
||
// HTML-Navigation (index.html, /, /*, alle Routen): immer frisch vom Server
|
||
// Das ist der Kern: verhindert dass eine alte index.html aus dem HTTP-Cache kommt
|
||
if (e.request.mode === 'navigate') {
|
||
e.respondWith(
|
||
fetch(e.request, {
|
||
cache: 'no-store', // Browser-HTTP-Cache umgehen
|
||
headers: { 'Cache-Control': 'no-cache' }
|
||
}).catch(() => caches.match('/index.html')) // nur bei echtem Offline-Fall: Cache-Fallback
|
||
);
|
||
return;
|
||
}
|
||
|
||
// Statische Assets (Vite baut mit Content-Hash im Dateinamen):
|
||
// Network-first, bei Fehler Cache-Fallback (für Offline-Nutzung)
|
||
e.respondWith(
|
||
fetch(e.request)
|
||
.then(response => {
|
||
if (response.ok) {
|
||
const clone = response.clone();
|
||
caches.open(CACHE_NAME).then(c => c.put(e.request, clone));
|
||
}
|
||
return response;
|
||
})
|
||
.catch(() => caches.match(e.request))
|
||
);
|
||
});
|
||
|
||
self.addEventListener('message', e => {
|
||
if (e.data === 'SKIP_WAITING') self.skipWaiting();
|
||
});
|