From 00f8b192af2e3375488feb4d9b077ce3597a918b Mon Sep 17 00:00:00 2001 From: Made Baruna Date: Thu, 21 Jul 2022 20:09:18 +0700 Subject: [PATCH] Add service worker --- src/routes/__layout.svelte | 25 ++++++++++++- src/service-worker.js | 72 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 src/service-worker.js diff --git a/src/routes/__layout.svelte b/src/routes/__layout.svelte index c01d21e8..da2ad850 100644 --- a/src/routes/__layout.svelte +++ b/src/routes/__layout.svelte @@ -30,9 +30,14 @@ startClient(); - page.subscribe(() => { + let broadcastChannel; + page.subscribe((p) => { try { window.reloadAdSlots(); + broadcastChannel.postMessage({ + type: 'fetch-doc', + path: p.url.pathname, + }); } catch (error) {} }); @@ -46,6 +51,24 @@ }); window.localforage = localforage; await checkLocalSave(); + + if ('serviceWorker' in navigator) { + broadcastChannel = new BroadcastChannel('paimonmoe-sw'); + broadcastChannel.addEventListener('message', (event) => { + if (event.data.type === 'update') window.location.reload(); + }); + + navigator.serviceWorker.register('/service-worker.js').then( + function () { + console.log('service worker registration succeeded'); + }, + function (error) { + console.log('service worker registration failed:', error); + }, + ); + } else { + console.log('service workers are not supported'); + } }); $: segment = $page.url.pathname.substring(1).split('/')[0]; diff --git a/src/service-worker.js b/src/service-worker.js new file mode 100644 index 00000000..31d8f316 --- /dev/null +++ b/src/service-worker.js @@ -0,0 +1,72 @@ +import { version } from '$service-worker'; + +const CACHE = `cache${version}`; +const channel = new BroadcastChannel('paimonmoe-sw'); + +self.addEventListener('install', (event) => { + event.waitUntil(self.skipWaiting()); +}); + +async function fetchAddCache(url) { + try { + const cache = await caches.open(CACHE); + const cachedRes = await cache.match(url); + + if (cachedRes) return; + + const res = await fetch(url); + cache.put(url, res.clone()); + } catch (err) { + console.error(err); + } +} + +self.addEventListener('activate', (event) => { + event.waitUntil( + caches.keys().then(async (keys) => { + let needUpdate = false; + // delete old caches + for (const key of keys) { + if (key !== CACHE) { + await caches.delete(key); + needUpdate = true; + } + } + + self.clients.claim(); + console.log('SW NEED UPDATE', needUpdate); + if (needUpdate) { + channel.postMessage({ + type: 'update', + version, + }); + } + + fetchAddCache('/'); + channel.addEventListener('message', (event) => { + if (event.data.type === 'fetch-doc') { + fetchAddCache(event.data.path); + } + }); + }), + ); +}); + +self.addEventListener('fetch', async (event) => { + if (!event.request.url.startsWith(self.location.origin) || event.request.method !== 'GET') return; + + event.respondWith( + (async () => { + const cache = await caches.open(CACHE); + const cachedRes = await cache.match(event.request); + + if (cachedRes) { + return cachedRes; + } + + const res = await fetch(event.request); + cache.put(event.request, res.clone()); + return res; + })(), + ); +});