Last active
November 16, 2023 10:53
-
-
Save Mlocik97/cf0f4c39e46d45404fda8808a25244c8 to your computer and use it in GitHub Desktop.
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
import { build, files, version } from '$service-worker'; | |
// https://github.com/microsoft/TypeScript/issues/11781 - this is needed for TS and ESLint | |
/// env serviceworker | |
const globalThis = /** @type {unknown} */ (self); | |
/// <reference no-default-lib="true"/> | |
/// <reference lib="es2020" /> | |
/// <reference lib="WebWorker" /> | |
const sw = /** @type {ServiceWorkerGlobalScope & typeof globalThis} */ (globalThis); | |
const ASSETS = `cache${version}`; | |
// `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); | |
/** @param {ExtendableEvent} event */ | |
function install_listener(event) { | |
event.waitUntil( | |
caches | |
.open(ASSETS) | |
.then((cache) => cache.addAll(to_cache)) | |
.then(() => { | |
sw.skipWaiting(); | |
}) | |
); | |
} | |
/** @param {ExtendableEvent} event */ | |
function activate_listener(event) { | |
event.waitUntil( | |
caches.keys().then(async (keys) => { | |
// delete old caches | |
for (const key of keys) { | |
if (key !== ASSETS) | |
await caches.delete(key); | |
} | |
sw.clients.claim(); | |
}) | |
); | |
} | |
/** | |
* Fetch the asset from the network and store it in the cache. | |
* Fall back to the cache if the user is offline. | |
* @param {RequestInfo} request | |
*/ | |
async function fetchAndCache(request) { | |
const cache = await caches.open(`offline${version}`); | |
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; | |
} | |
} | |
/** @param {FetchEvent} event */ | |
function fetch_listener(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 === sw.location.hostname && url.port !== sw.location.port; | |
const isStaticAsset = url.host === sw.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)); | |
// for pages, you might want to serve a build `service-worker-index.html` file. | |
// It's not right for every app, but if it's right for yours then uncomment this section | |
/* | |
if (!cachedAsset && url.origin === sw.origin && routes.find(route => route.pattern.test(url.pathname))) { | |
return caches.match('/service-worker-index.html'); | |
} | |
*/ | |
return cachedAsset || fetchAndCache(event.request); | |
})() | |
); | |
} | |
} | |
// prettier-ignore | |
sw.addEventListener('install' , install_listener); | |
// prettier-ignore | |
sw.addEventListener('activate', activate_listener); | |
// prettier-ignore | |
sw.addEventListener('fetch' , fetch_listener); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment