diff options
Diffstat (limited to 'serviceWorker.js')
| -rw-r--r-- | serviceWorker.js | 61 |
1 files changed, 45 insertions, 16 deletions
diff --git a/serviceWorker.js b/serviceWorker.js index ba9ca7a..ce8ed7e 100644 --- a/serviceWorker.js +++ b/serviceWorker.js @@ -23,30 +23,59 @@ self.addEventListener('activate', e => { e.waitUntil(self.clients.claim()) }) +const checkChange = (r1, r2) => { + const h1 = r1.headers + const h2 = r2.headers + if (h1.get('etag') && h2.get('etag')) return h1.get('etag') !== h2.get('etag') + if (h1.get('last-modified') && h2.get('last-modified')) return h1.get('last-modified') !== h2.get('last-modified') + return h1.get('content-length') !== h2.get('content-length') +} + self.addEventListener('fetch', e => { const url = new URL(e.request.url) const isTarget = ASSETS.includes(url.pathname) || url.pathname.startsWith('/fonts/') if (!isTarget) return - e.respondWith( - caches.open(CACHE_NAME).then(async cache => { - const cachedResponse = await cache.match(e.request) + e.respondWith((async () => { + const cache = await caches.open(CACHE_NAME) + const cachedResponse = await cache.match(e.request) + + const networkFetch = fetch(e.request, { cache: 'no-cache' }).then(async networkResponse => { + if (!networkResponse.ok) return networkResponse + + const freshCopy = networkResponse.clone() + let changed = false - if (cachedResponse) console.log(`cache ${url.pathname}`) - else console.log(`fetch ${url.pathname}`) + if (cachedResponse) { + changed = checkChange(cachedResponse, networkResponse) + } else { + console.log(`fetch ${url.pathname}`) + } - const networkFetch = fetch(e.request).then(networkResponse => { - if (networkResponse.ok) { - console.log(`updating ${url.pathname}`) - cache.put(e.request, networkResponse.clone()) - } - return networkResponse - }).catch(err => { - console.error(`failed ${url.pathname}:`, err) - }) + await cache.put(e.request, freshCopy) - return cachedResponse || networkFetch + if (changed) { + console.log(`content changed, signaling refresh: ${url.pathname}`) + const clients = await self.clients.matchAll() + clients.forEach(client => { + client.postMessage({ + type: 'REFRESH', + url: url.pathname + }) + }) + } + return networkResponse + }).catch(err => { + console.error(`failed ${url.pathname}:`, err) }) - ) + + if (cachedResponse) { + console.log(`cache ${url.pathname}`) + e.waitUntil(networkFetch) + return cachedResponse + } + + return networkFetch + })()) })
\ No newline at end of file |
