1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/* Jaro PWA — cache-first shell, network-first data */
const CACHE = 'jaro-v1';
const SHELL = ['./', './index.html', './manifest.json', './icon.svg'];
self.addEventListener('install', e => {
e.waitUntil(caches.open(CACHE).then(c => c.addAll(SHELL)).then(() => self.skipWaiting()));
});
self.addEventListener('activate', e => {
e.waitUntil(caches.keys().then(ks => Promise.all(ks.filter(k => k !== CACHE).map(k => caches.delete(k)))).then(() => self.clients.claim()));
});
self.addEventListener('fetch', e => {
const url = new URL(e.request.url);
if (url.pathname.endsWith('cf-ips.json')) { // data: network first, cache fallback
e.respondWith(fetch(e.request).then(r => {
const copy = r.clone();
caches.open(CACHE).then(c => c.put(e.request, copy));
return r;
}).catch(() => caches.match(e.request)));
return;
}
e.respondWith(caches.match(e.request).then(hit => hit || fetch(e.request)));
});