From c91b5c2392da5c983f4f5b0c574f6bed1d6c9bd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fe=CC=81lix=20Pe=CC=81ault?= Date: Thu, 6 Oct 2022 19:23:20 +0200 Subject: [PATCH] Add service worker --- src/service-workers.ts | 114 +++++++++++++++++++++++++++++++++++++++++ tsconfig.json | 4 +- 2 files changed, 116 insertions(+), 2 deletions(-) create mode 100644 src/service-workers.ts diff --git a/src/service-workers.ts b/src/service-workers.ts new file mode 100644 index 0000000..a42ee98 --- /dev/null +++ b/src/service-workers.ts @@ -0,0 +1,114 @@ +import { build, files, version } from '$service-worker' + +const ASSETS = 'assets' + version + +// `build` is an array of all the files generated by the bundler, `files` is an +// array of everything in the `static` directory (except exlucdes defined in svelte.config.js) +const cached = build.concat(files); + +// if you use typescript: +(self as unknown as ServiceWorkerGlobalScope).addEventListener('install', event => { + // self.addEventListener( + event.waitUntil( + caches + .open(ASSETS) + .then(cache => cache.addAll(cached)) + .then(() => { + // if you use typescript: + (self as unknown as ServiceWorkerGlobalScope).skipWaiting(); + // self.skipWaiting(); + }) + ); + } +); + +// self.addEventListener( +// if you use typescript: +(self as unknown as ServiceWorkerGlobalScope).addEventListener('activate', event => { + event.waitUntil( + caches.keys().then(async keys => { + // delete old caches + keys.map(async key => { + if (key !== ASSETS) { + await caches.delete(key) + } + }); + + // if you use typescript: + (self as unknown as ServiceWorkerGlobalScope).clients.claim() + // self.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) { +// if you use typescript: +async function fetchAndCache(request: Request) { + const cache = await caches.open(`offline${version}`) + + try { + const response = await fetch(request) + + if (response.status === 200) { + cache.put(request, response.clone()) + } + + return response + } catch (err) { + const response = await cache.match(request) + + if (response) { + return response + } + + throw err + } +} + +// self.addEventListener('fetch', event => { +// if you use typescript: +(self as unknown as ServiceWorkerGlobalScope).addEventListener('fetch', event => { + if (event.request.method !== 'GET' || event.request.headers.has('range')) { + return + } + + const url = new URL(event.request.url) + + if ( + // don't try to handle e.g. data: URIs + !url.protocol.startsWith('http') || + // ignore dev server requests + (url.hostname === self.location.hostname && + url.port !== self.location.port) || + // ignore /_app/version.json + url.pathname === '/_app/version.json' + ) { + return + } + + // always serve static files and bundler-generated assets from cache + const isStaticAsset = url.host === self.location.host && cached.indexOf(url.pathname) > -1 + + if (event.request.cache === 'only-if-cached' && !isStaticAsset) { + return + } + + // for everything else, try the network first, falling back to cache if the + // user is offline. (If the pages never change, you might prefer a cache-first + // approach to a network-first one.) + 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) + })() + ) + } +) \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index fa5bf6c..00a17bf 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,7 +1,7 @@ { "extends": "./.svelte-kit/tsconfig.json", "compilerOptions": { - "allowSyntheticDefaultImports": true + "allowSyntheticDefaultImports": true, + "lib": ["WebWorker"], }, - "exclude": ["./src/modules/globe/**/*"], } \ No newline at end of file