Add web/templates/pwa/service-worker.js
This commit is contained in:
@@ -0,0 +1,76 @@
|
|||||||
|
// Service Worker — Illustrations DB
|
||||||
|
const VERSION = 'v1.0.0';
|
||||||
|
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
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user