(webSocket)
| 51 | |
| 52 | class WebSocketTransport { |
| 53 | constructor(webSocket) { |
| 54 | this._ws = webSocket; |
| 55 | this._sendQueue = []; |
| 56 | this._receiveQueue = []; |
| 57 | this._receiveResolver = undefined; |
| 58 | this._receiveRejecter = undefined; |
| 59 | this._error = undefined; |
| 60 | this._opened = webSocket.readyState === WebSocket.OPEN; |
| 61 | |
| 62 | if (!this._opened) { |
| 63 | webSocket.addEventListener("open", () => { |
| 64 | try { |
| 65 | for (const m of this._sendQueue) webSocket.send(m); |
| 66 | } catch (err) { |
| 67 | this._receivedError(err); |
| 68 | } |
| 69 | this._sendQueue = undefined; |
| 70 | this._opened = true; |
| 71 | }); |
| 72 | } else { |
| 73 | this._sendQueue = undefined; |
| 74 | } |
| 75 | |
| 76 | webSocket.addEventListener("message", (event) => { |
| 77 | if (this._error) return; |
| 78 | const data = typeof event.data === "string" ? event.data : event.data?.toString("utf8"); |
| 79 | if (typeof data !== "string") { |
| 80 | this._receivedError(new TypeError("non-string ws message")); |
| 81 | return; |
| 82 | } |
| 83 | if (this._receiveResolver) { |
| 84 | const r = this._receiveResolver; |
| 85 | this._receiveResolver = undefined; |
| 86 | this._receiveRejecter = undefined; |
| 87 | r(data); |
| 88 | } else { |
| 89 | this._receiveQueue.push(data); |
| 90 | } |
| 91 | }); |
| 92 | |
| 93 | webSocket.addEventListener("close", (event) => { |
| 94 | this._receivedError(new Error(`Peer closed WebSocket: ${event.code} ${event.reason}`)); |
| 95 | }); |
| 96 | webSocket.addEventListener("error", () => { |
| 97 | this._receivedError(new Error("WebSocket connection failed.")); |
| 98 | }); |
| 99 | } |
| 100 | |
| 101 | async send(message) { |
| 102 | if (this._sendQueue !== undefined) this._sendQueue.push(message); |
nothing calls this directly
no test coverage detected