Created
June 27, 2021 21:01
-
-
Save 100lvlmaster/8e966302b2e03404203e965424cb2bca to your computer and use it in GitHub Desktop.
service-worker.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// <reference lib="webworker" /> | |
import { build, files, timestamp } from '$service-worker'; | |
const worker = (self as unknown) as ServiceWorkerGlobalScope; | |
const FILES = `cache${timestamp}`; | |
// `build` is an array of all the files generated by the bundler, | |
// `files` is an array of everything in the `static` directory | |
const to_cache = build.concat(files); | |
const staticAssets = new Set(to_cache); | |
worker.addEventListener('install', (event) => { | |
event.waitUntil( | |
caches | |
.open(FILES) | |
.then((cache) => cache.addAll(to_cache)) | |
.then(() => { | |
worker.skipWaiting(); | |
}) | |
); | |
}); | |
worker.addEventListener('activate', (event) => { | |
event.waitUntil( | |
caches.keys().then(async (keys) => { | |
// delete old caches | |
for (const key of keys) { | |
if (key !== FILES) await caches.delete(key); | |
} | |
worker.clients.claim(); | |
}) | |
); | |
}); | |
/** | |
* Fetch the asset from the network and store it in the cache. | |
* Fall back to the cache if the user is offline. | |
*/ | |
async function fetchAndCache(request: Request) { | |
const cache = await caches.open(`offline${timestamp}`); | |
try { | |
const response = await fetch(request); | |
cache.put(request, response.clone()); | |
return response; | |
} catch (err) { | |
const response = await cache.match(request); | |
if (response) return response; | |
throw err; | |
} | |
} | |
worker.addEventListener('fetch', (event) => { | |
if (event.request.method !== 'GET' || event.request.headers.has('range')) return; | |
const url = new URL(event.request.url); | |
// don't try to handle e.g. data: URIs | |
const isHttp = url.protocol.startsWith('http'); | |
const isDevServerRequest = | |
url.hostname === self.location.hostname && url.port !== self.location.port; | |
const isStaticAsset = url.host === self.location.host && staticAssets.has(url.pathname); | |
const skipBecauseUncached = event.request.cache === 'only-if-cached' && !isStaticAsset; | |
if (isHttp && !isDevServerRequest && !skipBecauseUncached) { | |
event.respondWith( | |
(async () => { | |
// always serve static files and bundler-generated assets from cache. | |
// if your application has other URLs with data that will never change, | |
// set this variable to true for them and they will only be fetched once. | |
const cachedAsset = isStaticAsset && (await caches.match(event.request)); | |
return cachedAsset || fetchAndCache(event.request); | |
})() | |
); | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Note
timestamp
replaced withversion
in 1.0.0-next.294 (changelog). I've noted this on the Mlocik97 example as well.