diff options
author | metamuffin <metamuffin@disroot.org> | 2022-10-26 23:54:33 +0200 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2022-10-26 23:54:33 +0200 |
commit | 2a83c8bdbdd5a67b6068420520e83524f4a6f6bd (patch) | |
tree | 8638903b93eb929ca74e5027a1816820ff0bc346 /client-web/source/sw/worker.ts | |
parent | d0162d41438c7ee3d9bc5321f73ed33defc443a3 (diff) | |
download | keks-meet-2a83c8bdbdd5a67b6068420520e83524f4a6f6bd.tar keks-meet-2a83c8bdbdd5a67b6068420520e83524f4a6f6bd.tar.bz2 keks-meet-2a83c8bdbdd5a67b6068420520e83524f4a6f6bd.tar.zst |
some code for streamed downloads
Diffstat (limited to 'client-web/source/sw/worker.ts')
-rw-r--r-- | client-web/source/sw/worker.ts | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/client-web/source/sw/worker.ts b/client-web/source/sw/worker.ts new file mode 100644 index 0000000..25f6bab --- /dev/null +++ b/client-web/source/sw/worker.ts @@ -0,0 +1,86 @@ +/* + This file is part of keks-meet (https://codeberg.org/metamuffin/keks-meet) + which is licensed under the GNU Affero General Public License (version 3); see /COPYING. + Copyright (C) 2022 metamuffin <metamuffin@disroot.org> +*/ +/// <reference no-default-lib="true"/> + +/// <reference lib="esnext" /> +/// <reference lib="webworker" /> +declare const self: ServiceWorkerGlobalScope; export { }; + +console.log("hello from the keks-meet service worker"); +console.log(self.origin) + +// let cache: Cache; + +self.addEventListener("install", event => { + console.log("install"); + self.skipWaiting() + event.waitUntil(caches.delete("v1")) +}) +self.addEventListener("activate", _event => { + console.log("activate"); + self.clients.claim() + // event.waitUntil((async () => { + // cache = await caches.open("v1") + // cache.addAll([ + // "/assets/bundle.js", + // "/assets/sw.js", + // ]) + // })()) +}) +self.addEventListener("unload", () => { + console.log("unload") +}) + +const streams = new Map<string, { readable: ReadableStream, size: number }>() + +self.addEventListener("message", ev => { + console.log(ev); + const { path, size } = ev.data, port = ev.ports[0] + const readable = port_to_readable(port) + streams.set(path, { readable, size }) +}) + +function port_to_readable(port: MessagePort): ReadableStream { + return new ReadableStream({ + start(controller) { + console.log("ReadableStream started"); + port.addEventListener("message", event => { + console.log(event.data); + if (event.data === "end") { controller.close() } + else if (event.data === "abort") controller.error("aborted") + else controller.enqueue(event.data) + }) + }, + cancel() { console.log("ReadableStream cancelled"); port.postMessage({ abort: true }) }, + }) +} + +self.addEventListener("fetch", event => { + const { request } = event; + if (!request.url.startsWith(self.origin)) return + const path = request.url.substring(self.origin.length) + console.log(request.method, path); + + const stream = streams.get(path) + if (stream) { + streams.delete(path) + console.log(`-> stream response`); + return event.respondWith( + new Response( + stream.readable, + { + headers: new Headers({ + "Content-Type": "application/octet-stream; charset=utf-8", // TODO transmit and set accordingly + "Content-Security-Policy": "default-src 'none'", + "Content-Length": `${stream.size}`, + }) + } + ) + ) + } + + event.respondWith(fetch(request)) +}) |