use real postmessage

This commit is contained in:
velzie 2024-09-19 20:11:08 -04:00
parent abec64ef97
commit 07f29a322e
No known key found for this signature in database
GPG key ID: 048413F95F0DDE1F
3 changed files with 18 additions and 5 deletions

View file

@ -2,6 +2,8 @@ import { BareHeaders, TransferrableResponse } from "./baretypes";
type SWClient = { postMessage: typeof MessagePort.prototype.postMessage }; type SWClient = { postMessage: typeof MessagePort.prototype.postMessage };
const realPostMessage = MessagePort.prototype.postMessage;
export type WorkerMessage = { export type WorkerMessage = {
type: "fetch" | "websocket" | "set" | "get" | "ping", type: "fetch" | "websocket" | "set" | "get" | "ping",
fetch?: { fetch?: {
@ -67,7 +69,7 @@ async function searchForPort(): Promise<MessagePort> {
function tryGetPort(client: SWClient): Promise<MessagePort> { function tryGetPort(client: SWClient): Promise<MessagePort> {
let channel = new MessageChannel(); let channel = new MessageChannel();
return new Promise(resolve => { 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 => { channel.port1.onmessage = event => {
resolve(event.data) resolve(event.data)
} }
@ -84,7 +86,7 @@ function testPort(port: MessagePort): Promise<void> {
}; };
setTimeout(reject, 1500); setTimeout(reject, 1500);
}); });
port.postMessage(<WorkerRequest>{ message: { type: "ping" }, port: pingChannel.port2 }, [pingChannel.port2]); realPostMessage.call(port, <WorkerRequest>{ message: { type: "ping" }, port: pingChannel.port2 }, [pingChannel.port2]);
return pingPromise; return pingPromise;
} }
@ -96,7 +98,7 @@ function createPort(path: string, registerHandlers: boolean): MessagePort {
if (event.data.type === "getPort" && event.data.port) { if (event.data.type === "getPort" && event.data.port) {
console.debug("bare-mux: recieved request for port from sw"); console.debug("bare-mux: recieved request for port from sw");
const newWorker = new SharedWorker(path, "bare-mux-worker"); 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(); const stream = new ReadableStream();
let res: boolean; let res: boolean;
try { try {
chan.port1.postMessage(stream, [stream]); realPostMessage.call(chan.port1, stream, [stream]);
res = true; res = true;
} catch (err) { } catch (err) {
res = false; res = false;
@ -192,7 +194,7 @@ export class WorkerConnection {
} }
} }
}); });
this.port.postMessage(<WorkerRequest>{ message: message, port: channel.port2 }, toTransfer); realPostMessage.call(this.port, <WorkerRequest>{ message: message, port: channel.port2 }, toTransfer);
return await promise; return await promise;
} }

View file

@ -3,6 +3,7 @@ export * from './client';
export * from './connection'; export * from './connection';
export { BareClient as default } from './client'; export { BareClient as default } from './client';
export { WebSocketFields } from "./snapshot"; export { WebSocketFields } from "./snapshot";
export { BareWebSocket } from "./websocket";
export type * from './baretypes'; export type * from './baretypes';
export type * from './client'; export type * from './client';

View file

@ -4,6 +4,7 @@ import { BareHeaders } from "./baretypes";
export class BareWebSocket extends EventTarget { export class BareWebSocket extends EventTarget {
url: string; url: string;
readyState: number = WebSocketFields.CONNECTING;
channel: MessageChannel; channel: MessageChannel;
constructor( constructor(
@ -18,6 +19,7 @@ export class BareWebSocket extends EventTarget {
const onopen = (protocol: string) => { const onopen = (protocol: string) => {
this.protocols = protocol; this.protocols = protocol;
this.readyState = WebSocketFields.OPEN;
const event = new Event("open") const event = new Event("open")
this.dispatchEvent(event); this.dispatchEvent(event);
@ -29,11 +31,13 @@ export class BareWebSocket extends EventTarget {
}; };
const onclose = (code: number, reason: string) => { const onclose = (code: number, reason: string) => {
this.readyState = WebSocketFields.CLOSED;
const event = new CloseEvent("close", { code, reason }) const event = new CloseEvent("close", { code, reason })
this.dispatchEvent(event); this.dispatchEvent(event);
}; };
const onerror = () => { const onerror = () => {
this.readyState = WebSocketFields.CLOSED;
const event = new Event("error"); const event = new Event("error");
this.dispatchEvent(event); this.dispatchEvent(event);
}; };
@ -66,6 +70,12 @@ export class BareWebSocket extends EventTarget {
} }
send(...args) { send(...args) {
if (this.readyState === WebSocketFields.CONNECTING) {
throw new DOMException(
"Failed to execute 'send' on 'WebSocket': Still in CONNECTING state."
);
}
let data = args[0]; let data = args[0];
if (data.buffer) data = data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength); if (data.buffer) data = data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength);