76 lines
2.1 KiB
JavaScript
76 lines
2.1 KiB
JavaScript
// Service Worker — Illustrations DB
|
||
const VERSION = 'v1.0.2';
|
||
const STATIC_CACHE = `static-${VERSION}`;
|
||
const PAGES_CACHE = `pages-${VERSION}`;
|
||
const OFFLINE_URL = '/offline/';
|
||
|
||
const STATIC_ASSETS = [
|
||
'/', // optional: remove if you don’t want to cache /
|
||
'/static/pwa/icon-192.png',
|
||
'/static/pwa/icon-512.png'
|
||
];
|
||
|
||
self.addEventListener('install', (event) => {
|
||
event.waitUntil(
|
||
caches.open(STATIC_CACHE).then((cache) => cache.addAll(STATIC_ASSETS))
|
||
.then(() => self.skipWaiting())
|
||
);
|
||
});
|
||
|
||
self.addEventListener('activate', (event) => {
|
||
event.waitUntil(
|
||
caches.keys().then((keys) =>
|
||
Promise.all(
|
||
keys.filter(k => ![STATIC_CACHE, PAGES_CACHE].includes(k))
|
||
.map(k => caches.delete(k))
|
||
)
|
||
).then(() => self.clients.claim())
|
||
);
|
||
});
|
||
|
||
function isNavigation(req) {
|
||
return req.mode === 'navigate' ||
|
||
(req.method === 'GET' && req.headers.get('accept')?.includes('text/html'));
|
||
}
|
||
|
||
self.addEventListener('fetch', (event) => {
|
||
const req = event.request;
|
||
if (req.method !== 'GET') return;
|
||
|
||
// HTML pages: stale-while-revalidate w/ offline fallback
|
||
if (isNavigation(req)) {
|
||
event.respondWith((async () => {
|
||
try {
|
||
const network = await fetch(req);
|
||
const cache = await caches.open(PAGES_CACHE);
|
||
cache.put(req, network.clone());
|
||
return network;
|
||
} catch {
|
||
const cache = await caches.open(PAGES_CACHE);
|
||
const cached = await cache.match(req);
|
||
return cached || caches.match(OFFLINE_URL);
|
||
}
|
||
})());
|
||
return;
|
||
}
|
||
|
||
// Static files under /static: cache-first
|
||
const url = new URL(req.url);
|
||
if (url.pathname.startsWith('/static/')) {
|
||
event.respondWith((async () => {
|
||
const cache = await caches.open(STATIC_CACHE);
|
||
const cached = await cache.match(req);
|
||
if (cached) return cached;
|
||
try {
|
||
const network = await fetch(req);
|
||
cache.put(req, network.clone());
|
||
return network;
|
||
} catch {
|
||
return cached; // best effort
|
||
}
|
||
})());
|
||
return;
|
||
}
|
||
|
||
// Default: pass-through
|
||
}); |