diff --git a/src/connection.ts b/src/connection.ts index 2c4b8af..5befe9c 100644 --- a/src/connection.ts +++ b/src/connection.ts @@ -2,6 +2,8 @@ import { BareHeaders, TransferrableResponse } from "./baretypes"; type SWClient = { postMessage: typeof MessagePort.prototype.postMessage }; +const realPostMessage = MessagePort.prototype.postMessage; + export type WorkerMessage = { type: "fetch" | "websocket" | "set" | "get" | "ping", fetch?: { @@ -67,7 +69,7 @@ async function searchForPort(): Promise { function tryGetPort(client: SWClient): Promise { let channel = new MessageChannel(); return new Promise(resolve => { - client.postMessage({ type: "getPort", port: channel.port2 }, [channel.port2]); + realPostMessage.call(client, { type: "getPort", port: channel.port2 }, [channel.port2]); channel.port1.onmessage = event => { resolve(event.data) } @@ -84,7 +86,7 @@ function testPort(port: MessagePort): Promise { }; setTimeout(reject, 1500); }); - port.postMessage({ message: { type: "ping" }, port: pingChannel.port2 }, [pingChannel.port2]); + realPostMessage.call(port, { message: { type: "ping" }, port: pingChannel.port2 }, [pingChannel.port2]); return pingPromise; } @@ -96,7 +98,7 @@ function createPort(path: string, registerHandlers: boolean): MessagePort { if (event.data.type === "getPort" && event.data.port) { console.debug("bare-mux: recieved request for port from sw"); const newWorker = new SharedWorker(path, "bare-mux-worker"); - event.data.port.postMessage(newWorker.port, [newWorker.port]); + realPostMessage.call(event.data.port, newWorker.port, [newWorker.port]); } }); } @@ -110,7 +112,7 @@ export function browserSupportsTransferringStreams(): boolean { const stream = new ReadableStream(); let res: boolean; try { - chan.port1.postMessage(stream, [stream]); + realPostMessage.call(chan.port1, stream, [stream]); res = true; } catch (err) { res = false; @@ -192,7 +194,7 @@ export class WorkerConnection { } } }); - this.port.postMessage({ message: message, port: channel.port2 }, toTransfer); + realPostMessage.call(this.port, { message: message, port: channel.port2 }, toTransfer); return await promise; } diff --git a/src/index.ts b/src/index.ts index ca2466f..3d3de30 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,6 +3,7 @@ export * from './client'; export * from './connection'; export { BareClient as default } from './client'; export { WebSocketFields } from "./snapshot"; +export { BareWebSocket } from "./websocket"; export type * from './baretypes'; export type * from './client'; diff --git a/src/websocket.ts b/src/websocket.ts index b290f68..54593dd 100644 --- a/src/websocket.ts +++ b/src/websocket.ts @@ -4,6 +4,7 @@ import { BareHeaders } from "./baretypes"; export class BareWebSocket extends EventTarget { url: string; + readyState: number = WebSocketFields.CONNECTING; channel: MessageChannel; constructor( @@ -18,6 +19,7 @@ export class BareWebSocket extends EventTarget { const onopen = (protocol: string) => { this.protocols = protocol; + this.readyState = WebSocketFields.OPEN; const event = new Event("open") this.dispatchEvent(event); @@ -29,11 +31,13 @@ export class BareWebSocket extends EventTarget { }; const onclose = (code: number, reason: string) => { + this.readyState = WebSocketFields.CLOSED; const event = new CloseEvent("close", { code, reason }) this.dispatchEvent(event); }; const onerror = () => { + this.readyState = WebSocketFields.CLOSED; const event = new Event("error"); this.dispatchEvent(event); }; @@ -66,6 +70,12 @@ export class BareWebSocket extends EventTarget { } send(...args) { + if (this.readyState === WebSocketFields.CONNECTING) { + throw new DOMException( + "Failed to execute 'send' on 'WebSocket': Still in CONNECTING state." + ); + } + let data = args[0]; if (data.buffer) data = data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength);