{"id":1143,"date":"2018-06-20T07:39:41","date_gmt":"2018-06-20T06:39:41","guid":{"rendered":"https:\/\/solidt.eu\/site\/?p=1143"},"modified":"2023-06-22T12:58:42","modified_gmt":"2023-06-22T11:58:42","slug":"javascript-service-worker","status":"publish","type":"post","link":"https:\/\/solidt.eu\/site\/javascript-service-worker\/","title":{"rendered":"Javascript: service worker"},"content":{"rendered":"\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/* eslint-disable no-restricted-globals *\/\nconst worker = self;\nconst uniqueName = new Date().toISOString();\nconst preloadCache = 'preloadCache-' + uniqueName;\nconst cacheJsonPath = '\/assets\/cache.json';\n\nconst getRandom = () => String(Math.random()).slice(2);\nconst getRandomQuery = () => \"?version=\" + getRandom();\n\nconst getLatestCacheJson = async () => {\n    const response = await fetch(cacheJsonPath + getRandomQuery());\n    return response.json();\n};\n\nconst getCacheJsonFromCache = async () => {\n    const cache = await caches.open(preloadCache);\n    const response = await cache.match(cacheJsonPath);\n    if (!response) return null;\n    return response.json();\n};\n\nworker.addEventListener('message', event => {\n    if (event.data &amp;&amp; event.data.action !== \"check-for-updates\") return;\n    console.log(\"service-worker: check-for-updates\");\n    checkForUpdates();\n});\n\nasync function checkForUpdates() {\n    const [oldJson, newJson] = await Promise.all([getCacheJsonFromCache(), getLatestCacheJson()]);\n    if (oldJson &amp;&amp; oldJson.id !== newJson.id) {\n        console.log('old version', oldJson.id, 'new version', newJson.id, \"updating...\");\n        await addUrlsToTheCache(newJson);\n    }\n}\n\nfunction sendUpdatedMessageToClients() {\n    worker.clients.matchAll().then(clients => {\n        clients.forEach(client => client.postMessage({ \"serviceWorkerUpdated\": true }));\n    });\n}\n\nworker.addEventListener('activate', event => {\n    console.log('service-worker', 'activate');\n    event.waitUntil(checkForUpdates());\n});\n\nworker.addEventListener('install', event => {\n    console.log('service-worker', 'install');\n    event.waitUntil(\n        getLatestCacheJson()\n            .then(addUrlsToTheCache)\n            .then(() => {\n                console.log('service-worker', 'install: complete');\n            })\n    );\n});\n\nlet installing = false;\n\nasync function addUrlsToTheCache(cacheJsonContent) {\n    installing = true;\n    const urlsToCache = cacheJsonContent.preload;\n    urlsToCache.push(cacheJsonPath);\n    const names = await caches.keys();\n    const hadPreviousCache = names.length > 0;\n    await Promise.all(names.map(name => caches.delete(name)));\n    const cache = await caches.open(preloadCache);\n    await addAllToCache(cache, urlsToCache);\n    await worker.skipWaiting();\n    console.log('service-worker', 'install: added caches');\n    installing = false;\n\n    if (hadPreviousCache) {\n        sendUpdatedMessageToClients();\n    }\n}\n\nasync function addAllToCache(cache, urls) {\n    await Promise.all(urls.map(async url => {\n        const response = await fetch(url + getRandomQuery());\n        if (!response.ok) {\n            throw new TypeError('bad response status');\n        }\n        return cache.put(url, response);\n    }));\n}\n\nworker.addEventListener('fetch', event => {\n    const url = event.request.url;\n    if (!installing &amp;&amp; url.startsWith(worker.location.origin)) {\n        event.respondWith(\n            caches.match(event.request, {\n                ignoreSearch: true,\n                ignoreVary: true\n            }).then(cachedResponse => {\n                if (cachedResponse) {\n                    return cachedResponse;\n                }\n                return fetch(event.request);\n            })\n        );\n    }\n});<\/pre>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">if ('serviceWorker' in navigator) {\n    const serviceWorker = navigator.serviceWorker;\n    serviceWorker.getRegistrations().then(registrations => {\n        for (const registration of registrations) {\n            if (registration.active) {\n                registration.active.postMessage({ action: \"check-for-updates\" });\n            }\n        }\n    });\n    serviceWorker.register('\/serviceWorker.js', { scope: '\/' });\n    serviceWorker.addEventListener('message', e => {\n        if (e.data &amp;&amp; e.data.serviceWorkerUpdated) {\n            window.alert('Updating app to the latest version');\n            window.location.reload(true);\n        }\n    });\n}\n<\/pre>\n\n\n\n<p>empty \/assets\/cache.json (generated by script)<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"json\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">{\n    \"id\": \"\",\n    \"preload\": []\n}<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>empty \/assets\/cache.json (generated by script)<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"inline_featured_image":false,"footnotes":""},"categories":[5,4],"tags":[],"class_list":["post-1143","post","type-post","status-publish","format-standard","hentry","category-javascript","category-programming"],"_links":{"self":[{"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/posts\/1143","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/comments?post=1143"}],"version-history":[{"count":16,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/posts\/1143\/revisions"}],"predecessor-version":[{"id":7884,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/posts\/1143\/revisions\/7884"}],"wp:attachment":[{"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/media?parent=1143"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/categories?post=1143"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/tags?post=1143"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}