/* eslint-disable no-restricted-globals */ const worker = self; const uniqueName = new Date().toISOString(); const preloadCache = 'preloadCache-' + uniqueName; const cacheJsonPath = '/assets/cache.json'; const getRandom = () => String(Math.random()).slice(2); const getRandomQuery = () => "?version=" + getRandom(); const getLatestCacheJson = async () => { const response = await fetch(cacheJsonPath + getRandomQuery()); return response.json(); }; const getCacheJsonFromCache = async () => { const cache = await caches.open(preloadCache); const response = await cache.match(cacheJsonPath); if (!response) return null; return response.json(); }; worker.addEventListener('message', event => { if (event.data && event.data.action !== "check-for-updates") return; console.log("service-worker: check-for-updates"); checkForUpdates(); }); async function checkForUpdates() { const [oldJson, newJson] = await Promise.all([getCacheJsonFromCache(), getLatestCacheJson()]); if (oldJson && oldJson.id !== newJson.id) { console.log('old version', oldJson.id, 'new version', newJson.id, "updating..."); await addUrlsToTheCache(newJson); } } function sendUpdatedMessageToClients() { worker.clients.matchAll().then(clients => { clients.forEach(client => client.postMessage({ "serviceWorkerUpdated": true })); }); } worker.addEventListener('activate', event => { console.log('service-worker', 'activate'); event.waitUntil(checkForUpdates()); }); worker.addEventListener('install', event => { console.log('service-worker', 'install'); event.waitUntil( getLatestCacheJson() .then(addUrlsToTheCache) .then(() => { console.log('service-worker', 'install: complete'); }) ); }); let installing = false; async function addUrlsToTheCache(cacheJsonContent) { installing = true; const urlsToCache = cacheJsonContent.preload; urlsToCache.push(cacheJsonPath); const names = await caches.keys(); const hadPreviousCache = names.length > 0; await Promise.all(names.map(name => caches.delete(name))); const cache = await caches.open(preloadCache); await addAllToCache(cache, urlsToCache); await worker.skipWaiting(); console.log('service-worker', 'install: added caches'); installing = false; if (hadPreviousCache) { sendUpdatedMessageToClients(); } } async function addAllToCache(cache, urls) { await Promise.all(urls.map(async url => { const response = await fetch(url + getRandomQuery()); if (!response.ok) { throw new TypeError('bad response status'); } return cache.put(url, response); })); } worker.addEventListener('fetch', event => { const url = event.request.url; if (!installing && url.startsWith(worker.location.origin)) { event.respondWith( caches.match(event.request, { ignoreSearch: true, ignoreVary: true }).then(cachedResponse => { if (cachedResponse) { return cachedResponse; } return fetch(event.request); }) ); } });
if ('serviceWorker' in navigator) { const serviceWorker = navigator.serviceWorker; serviceWorker.getRegistrations().then(registrations => { for (const registration of registrations) { if (registration.active) { registration.active.postMessage({ action: "check-for-updates" }); } } }); serviceWorker.register('/serviceWorker.js', { scope: '/' }); serviceWorker.addEventListener('message', e => { if (e.data && e.data.serviceWorkerUpdated) { window.alert('Updating app to the latest version'); window.location.reload(true); } }); }
empty /assets/cache.json (generated by script)
{ "id": "", "preload": [] }
114300cookie-checkJavascript: service worker