diff --git a/src/connection.ts b/src/connection.ts index b6190c6..17785b5 100644 --- a/src/connection.ts +++ b/src/connection.ts @@ -46,6 +46,23 @@ type BroadcastMessage = { path?: string, } +function createPort(path: string, channel: BroadcastChannel): MessagePort { + const worker = new SharedWorker(path, "bare-mux-worker"); + navigator.serviceWorker.addEventListener("message", event => { + if (event.data.type === "getPort" && event.data.port) { + console.debug("bare-mux: recieved request for port from sw"); + event.data.port.postMessage(worker.port, [worker.port]); + } + }); + channel.onmessage = (event: MessageEvent) => { + if (event.data.type === "getPath") { + console.debug("bare-mux: recieved request for worker path from broadcast channel"); + channel.postMessage({ type: "path", path: path }); + } + }; + return worker.port; +} + export class WorkerConnection { channel: BroadcastChannel; port: MessagePort | Promise; @@ -62,34 +79,14 @@ export class WorkerConnection { } else if (workerPath && SharedWorker) { // running in a window, was passed a workerPath // create the SharedWorker and help other bare-mux clients get the workerPath - navigator.serviceWorker.addEventListener("message", event => { - if (event.data.type === "getPort" && event.data.port) { - const worker = new SharedWorker(workerPath, "bare-mux-worker"); - event.data.port.postMessage(worker.port, [worker.port]); - } - }); - - this.channel.onmessage = (event: MessageEvent) => { - if (event.data.type === "getPath") { - this.channel.postMessage({ type: "path", path: workerPath }); - } - } - - const worker = new SharedWorker(workerPath, "bare-mux-worker"); - this.port = worker.port; + this.port = createPort(workerPath, this.channel); } else if (SharedWorker) { // running in a window, was not passed a workerPath // ask other bare-mux clients for the workerPath this.port = new Promise(resolve => { this.channel.onmessage = (event: MessageEvent) => { if (event.data.type === "path") { - const worker = new SharedWorker(event.data.path, "bare-mux-worker"); - this.channel.onmessage = (event: MessageEvent) => { - if (event.data.type === "getPath") { - this.channel.postMessage({ type: "path", path: event.data.path }); - } - } - resolve(worker.port); + resolve(createPort(event.data.path, this.channel)); } } this.channel.postMessage({ type: "getPath" }); diff --git a/src/worker.ts b/src/worker.ts index 577d605..501b8be 100644 --- a/src/worker.ts +++ b/src/worker.ts @@ -3,6 +3,13 @@ import { WorkerMessage, WorkerResponse } from "./connection" let currentTransport: BareTransport | null = null; +function noClients(): Error { + // @ts-expect-error mdn error constructor: new Error(message, options) + return new Error("there are no bare clients", { + cause: "No BareTransport was set. Try creating a BareMuxConnection and calling setTransport() or setManualTransport() on it before using BareClient." + }); +} + function handleConnection(port: MessagePort) { port.onmessage = async (event: MessageEvent) => { const port = event.data.port; @@ -10,7 +17,7 @@ function handleConnection(port: MessagePort) { if (message.type === "set") { try { - const AsyncFunction = (async function () {}).constructor; + const AsyncFunction = (async function() { }).constructor; // @ts-expect-error const func = new AsyncFunction(message.client); @@ -18,12 +25,12 @@ function handleConnection(port: MessagePort) { console.log("set transport to ", currentTransport); port.postMessage({ type: "set" }); - } catch(err) { + } catch (err) { port.postMessage({ type: "error", error: err }); } } else if (message.type === "fetch") { try { - if (!currentTransport) throw new Error("No BareTransport was set. Try creating a BareMuxConnection and calling set() on it."); + if (!currentTransport) throw noClients(); if (!currentTransport.ready) await currentTransport.init(); const resp = await currentTransport.request( @@ -44,7 +51,7 @@ function handleConnection(port: MessagePort) { } } else if (message.type === "websocket") { try { - if (!currentTransport) throw new Error("No BareTransport was set. Try creating a BareMuxConnection and calling set() on it."); + if (!currentTransport) throw noClients(); if (!currentTransport.ready) await currentTransport.init(); const onopen = (protocol: string) => {