From abec64ef97cba2c2517bb2e0508e4ec55c7492e6 Mon Sep 17 00:00:00 2001 From: velzie Date: Sat, 7 Sep 2024 16:29:32 -0400 Subject: [PATCH] greatly simplify createwebsocket --- package.json | 1 - src/client.ts | 10 +-- src/websocket.ts | 204 +++++++++++++++-------------------------------- 3 files changed, 69 insertions(+), 146 deletions(-) diff --git a/package.json b/package.json index bd3bb9f..b87c969 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,6 @@ } }, "devDependencies": { - "@rollup/plugin-terser": "^0.4.4", "@rollup/plugin-inject": "^5.0.5", "@rollup/plugin-replace": "^5.0.5", "rollup": "^4.9.6", diff --git a/src/client.ts b/src/client.ts index 2468ed4..53d95a2 100644 --- a/src/client.ts +++ b/src/client.ts @@ -121,10 +121,9 @@ export class BareClient { createWebSocket( remote: string | URL, protocols: string | string[] | undefined = [], - webSocketImpl?: WebSocketImpl, + __deprecated_donotuse_websocket?: any, requestHeaders?: BareHeaders, - arrayBufferImpl?: ArrayBuffer, - ): WebSocket { + ): BareWebSocket { try { remote = new URL(remote); } catch (err) { @@ -148,7 +147,6 @@ export class BareClient { `Failed to construct 'WebSocket': The subprotocol '${proto}' is invalid.` ); - arrayBufferImpl = arrayBufferImpl || (webSocketImpl || WebSocket).constructor.constructor("return ArrayBuffer")().prototype; requestHeaders = requestHeaders || {}; requestHeaders['Host'] = (new URL(remote)).host; // requestHeaders['Origin'] = origin; @@ -158,9 +156,9 @@ export class BareClient { // requestHeaders['User-Agent'] = navigator.userAgent; requestHeaders['Connection'] = 'Upgrade'; - const socket = new BareWebSocket(remote, protocols, this.worker, requestHeaders, arrayBufferImpl) + const socket = new BareWebSocket(remote, protocols, this.worker, requestHeaders); - return socket as unknown as WebSocket; + return socket; } async fetch( diff --git a/src/websocket.ts b/src/websocket.ts index b0a7d13..b290f68 100644 --- a/src/websocket.ts +++ b/src/websocket.ts @@ -3,150 +3,76 @@ import { WebSocketFields } from "./snapshot"; import { BareHeaders } from "./baretypes"; export class BareWebSocket extends EventTarget { - url: string; - protocols: string | string[] | undefined = []; - readyState: number = WebSocketFields.CONNECTING; - binaryType = "blob"; + url: string; - //legacy event handlers - onopen = null; - onerror = null; - onmessage = null; - onclose = null; - - channel: MessageChannel; - constructor( - remote: string | URL, - protocols: string | string[] | undefined = [], - worker: WorkerConnection, - requestHeaders?: BareHeaders, - arrayBufferImpl?: ArrayBuffer, - ) { - super(); - this.url = remote.toString(); - this.protocols = protocols; - - const onopen = (protocol: string) => { - this.readyState = WebSocketFields.OPEN; - this.protocols = protocol; + channel: MessageChannel; + constructor( + remote: string | URL, + public protocols: string | string[] | undefined = [], + worker: WorkerConnection, + requestHeaders?: BareHeaders, + ) { + super(); + this.url = remote.toString(); + this.protocols = protocols; - (this as any).meta = { - headers: { - "sec-websocket-protocol": protocol, - } - }; - const event = new Event("open") - this.dispatchEvent(event); - if (this.onopen) { - this.onopen(event); - } - }; - - const onmessage = async (payload) => { - if (typeof payload === "string") { - } else if ("byteLength" in payload) { - if (this.binaryType === "blob") { - payload = new Blob([payload]); - } else { - Object.setPrototypeOf(payload, arrayBufferImpl); - } - } else if ("arrayBuffer" in payload) { - if (this.binaryType === "arraybuffer") { - payload = await payload.arrayBuffer() - Object.setPrototypeOf(payload, arrayBufferImpl); - } - } + const onopen = (protocol: string) => { + this.protocols = protocol; - const event = new MessageEvent("message", {data: payload }); - this.dispatchEvent(event); - if (this.onmessage) { - this.onmessage(event); - } - }; - - const onclose = (code: number, reason: string) => { - this.readyState = WebSocketFields.CLOSED; - const event = new CloseEvent("close", { code, reason }) - this.dispatchEvent(event); - if (this.onclose) { - this.onclose(event); - } - }; - - const onerror = () => { - this.readyState = WebSocketFields.CLOSED; - const event = new Event("error"); - this.dispatchEvent(event); - if (this.onerror) { - this.onerror(event); - }; - }; - - this.channel = new MessageChannel(); - - this.channel.port1.onmessage = event => { - if (event.data.type === "open") { - onopen(event.data.args[0]); - } else if (event.data.type === "message") { - onmessage(event.data.args[0]); - } else if (event.data.type === "close") { - onclose(event.data.args[0], event.data.args[1]); - } else if (event.data.type === "error") { - onerror(/* event.data.args[0] */); - } - } - - worker.sendMessage({ - type: "websocket", - websocket: { - url: remote.toString(), - origin: origin, - //@ts-expect-error - protocols: protocols, - requestHeaders: requestHeaders, - channel: this.channel.port2, - }, - }, [this.channel.port2]) - } - - send(...args) { - if (this.readyState === WebSocketFields.CONNECTING) { - throw new DOMException( - "Failed to execute 'send' on 'WebSocket': Still in CONNECTING state." - ); - } + const event = new Event("open") + this.dispatchEvent(event); + }; - let data = args[0]; - if (data.buffer) data = data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength); + const onmessage = async (payload) => { + const event = new MessageEvent("message", { data: payload }); + this.dispatchEvent(event); + }; - this.channel.port1.postMessage({ type: "data", data: data }, data instanceof ArrayBuffer ? [data] : []); - } - - close(code, reason) { - this.readyState = WebSocketFields.CLOSING; - this.channel.port1.postMessage({ type: "close", closeCode: code, closeReason: reason }); - } - - get bufferedAmount() { - return 0; - } - get protocol() { - if (Array.isArray(this.protocols)) { - return this.protocols[0] || ""; - } else { - return this.protocols || ""; + const onclose = (code: number, reason: string) => { + const event = new CloseEvent("close", { code, reason }) + this.dispatchEvent(event); + }; + + const onerror = () => { + const event = new Event("error"); + this.dispatchEvent(event); + }; + + this.channel = new MessageChannel(); + + this.channel.port1.onmessage = event => { + if (event.data.type === "open") { + onopen(event.data.args[0]); + } else if (event.data.type === "message") { + onmessage(event.data.args[0]); + } else if (event.data.type === "close") { + onclose(event.data.args[0], event.data.args[1]); + } else if (event.data.type === "error") { + onerror(/* event.data.args[0] */); } } - get extensions() { - return ""; - } + + worker.sendMessage({ + type: "websocket", + websocket: { + url: remote.toString(), + origin: origin, + //@ts-expect-error + protocols: protocols, + requestHeaders: requestHeaders, + channel: this.channel.port2, + }, + }, [this.channel.port2]) + } + + send(...args) { + let data = args[0]; + if (data.buffer) data = data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength); + + this.channel.port1.postMessage({ type: "data", data: data }, data instanceof ArrayBuffer ? [data] : []); + } + + close(code, reason) { + this.channel.port1.postMessage({ type: "close", closeCode: code, closeReason: reason }); + } } -//@ts-expect-error have to do this -BareWebSocket.prototype.CONNECTING = WebSocketFields.CONNECTING; -//@ts-expect-error have to do this -BareWebSocket.prototype.OPEN = WebSocketFields.OPEN; -//@ts-expect-error have to do this -BareWebSocket.prototype.CLOSING = WebSocketFields.CLOSING; -//@ts-expect-error have to do this -BareWebSocket.prototype.CLOSED = WebSocketFields.CLOSED; -