Add web/templates/pwa/service-worker.js

This commit is contained in:
Joshua Laymon 2025-08-24 02:02:22 +00:00
parent 6b7f0b7a3b
commit b495ef824d

View File

@ -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 dont 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
});