From fef12705eca39dfcdb82368f2b9a439218fcde82 Mon Sep 17 00:00:00 2001 From: Daniel Date: Sun, 3 Mar 2024 20:34:38 +0100 Subject: [PATCH] Add ServiceWorker --- package-lock.json | 15 +++++++++++++ package.json | 1 + src/App.ts | 2 ++ src/ServiceWorker.ts | 47 +++++++++++++++++++++++++++++++++++++++ src/ServiceWorkerComms.ts | 17 ++++++++++++++ tsconfig.json | 9 ++++++++ 6 files changed, 91 insertions(+) create mode 100644 src/ServiceWorker.ts create mode 100644 src/ServiceWorkerComms.ts create mode 100644 tsconfig.json diff --git a/package-lock.json b/package-lock.json index 70b8a2a..529fd56 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,6 +7,7 @@ "name": "nitro-play", "license": "GPL-3.0-or-later", "devDependencies": { + "@parcel/service-worker": "^2.12.0", "nitro-fs": "^1.1.0", "parcel": "^2.12.0" } @@ -1257,6 +1258,20 @@ "url": "https://opencollective.com/parcel" } }, + "node_modules/@parcel/service-worker": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/@parcel/service-worker/-/service-worker-2.12.0.tgz", + "integrity": "sha512-ySRbSQhsEZZTfjOEPoYsP+tKSolf9qBj1CE1MYI5Uxac4RUsT4Mdk/GryASmxu7H/r1ktW6EmePIlf3nrUKUug==", + "dev": true, + "engines": { + "node": ">= 12.0.0", + "parcel": "^2.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, "node_modules/@parcel/source-map": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/@parcel/source-map/-/source-map-2.1.1.tgz", diff --git a/package.json b/package.json index 866ee8b..40feb07 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "author": "", "license": "GPL-3.0-or-later", "devDependencies": { + "@parcel/service-worker": "^2.12.0", "nitro-fs": "^1.1.0", "parcel": "^2.12.0" } diff --git a/src/App.ts b/src/App.ts index 030dd2c..04fd8c6 100644 --- a/src/App.ts +++ b/src/App.ts @@ -1,3 +1,4 @@ +import * as ServiceWorkerComms from "./ServiceWorkerComms"; import * as AudioWorkerComms from "./AudioWorkerComms"; import * as ControlPanel from "./ControlPanel"; import * as AudioPlayer from "./AudioPlayer"; @@ -57,6 +58,7 @@ function stop() { StateManager.discardStates(Infinity); } +ServiceWorkerComms.init(); AudioWorkerComms.init(); Renderer.init(); ControlPanel.init(load, start, stop); diff --git a/src/ServiceWorker.ts b/src/ServiceWorker.ts new file mode 100644 index 0000000..ca33ca6 --- /dev/null +++ b/src/ServiceWorker.ts @@ -0,0 +1,47 @@ +import { version, manifest } from "@parcel/service-worker"; + +declare const self: ServiceWorkerGlobalScope; + +async function install() { + const cache = await caches.open(version); + await cache.addAll(manifest); + await cache.add("/"); +} + +self.addEventListener("install", (e: ExtendableEvent) => { + e.waitUntil(install()); + self.skipWaiting(); +}); + +async function activate() { + const keys = await caches.keys(); + await Promise.all( + keys.map(key => key !== version && caches.delete(key)) + ); +} + +self.addEventListener("activate", (e: ExtendableEvent) => { + e.waitUntil(activate()); + e.waitUntil(self.clients.claim()); +}); + +self.addEventListener("fetch", (e: FetchEvent) => { + if (e.request.method !== "GET") return; + + async function getResponse() { + const cache = await caches.open(version); + + // Parcel adds stupid timestamps to the end of the URLs (at least for debug builds) + // and I can't figure out how to disable them, + // so I'm just going to strip them off here + const realUrl = e.request.url.replace(/\?.*$/, ""); + const cachedResponse = await cache.match(realUrl); + if (cachedResponse) { + return cachedResponse; + } + + return fetch(e.request); + } + + e.respondWith(getResponse()); +}); diff --git a/src/ServiceWorkerComms.ts b/src/ServiceWorkerComms.ts new file mode 100644 index 0000000..eb56a6b --- /dev/null +++ b/src/ServiceWorkerComms.ts @@ -0,0 +1,17 @@ +export async function init() { + if (!("serviceWorker" in navigator)) { + console.error("Service workers are not supported in this browser."); + } + + try { + await navigator.serviceWorker.register( + new URL("ServiceWorker.ts", import.meta.url), + { + scope: "/", + type: "module" + } + ); + } catch (e) { + console.error("Service worker registration failed:", e); + } +} \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..c1561ac --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "lib": ["ES2015", "WebWorker"], + }, + "include": [ + "src/AudioWorker.ts", + "src/ServiceWorker.ts", + ] +} \ No newline at end of file