diff options
Diffstat (limited to 'ext/websocket/01_websocket.js')
-rw-r--r-- | ext/websocket/01_websocket.js | 74 |
1 files changed, 46 insertions, 28 deletions
diff --git a/ext/websocket/01_websocket.js b/ext/websocket/01_websocket.js index f7bd820c0..e4774f815 100644 --- a/ext/websocket/01_websocket.js +++ b/ext/websocket/01_websocket.js @@ -18,20 +18,20 @@ ArrayPrototypeJoin, ArrayPrototypeMap, ArrayPrototypeSome, - DataView, ErrorPrototypeToString, ObjectDefineProperties, ObjectPrototypeIsPrototypeOf, PromisePrototypeThen, RegExpPrototypeTest, Set, - String, StringPrototypeEndsWith, StringPrototypeToLowerCase, Symbol, SymbolIterator, PromisePrototypeCatch, + queueMicrotask, SymbolFor, + Uint8Array, } = window.__bootstrap.primordials; webidl.converters["sequence<DOMString> or DOMString"] = (V, opts) => { @@ -290,40 +290,58 @@ throw new DOMException("readyState not OPEN", "InvalidStateError"); } + if (typeof data === "string") { + // try to send in one go! + const d = core.byteLength(data); + const sent = ops.op_ws_try_send_string(this[_rid], data); + this[_bufferedAmount] += d; + if (!sent) { + PromisePrototypeThen( + core.opAsync("op_ws_send_string", this[_rid], data), + () => { + this[_bufferedAmount] -= d; + }, + ); + } else { + // Spec expects data to be start flushing on next tick but oh well... + // we already sent it so we can just decrement the bufferedAmount + // on the next tick. + queueMicrotask(() => { + this[_bufferedAmount] -= d; + }); + } + return; + } + const sendTypedArray = (ta) => { + // try to send in one go! + const sent = ops.op_ws_try_send_binary(this[_rid], ta); this[_bufferedAmount] += ta.byteLength; - PromisePrototypeThen( - core.opAsync("op_ws_send", this[_rid], { - kind: "binary", - value: ta, - }), - () => { + if (!sent) { + PromisePrototypeThen( + core.opAsync("op_ws_send_binary", this[_rid], ta), + () => { + this[_bufferedAmount] -= ta.byteLength; + }, + ); + } else { + // Spec expects data to be start flushing on next tick but oh well... + // we already sent it so we can just decrement the bufferedAmount + // on the next tick. + queueMicrotask(() => { this[_bufferedAmount] -= ta.byteLength; - }, - ); + }); + } }; - if (ObjectPrototypeIsPrototypeOf(BlobPrototype, data)) { - PromisePrototypeThen( - data.slice().arrayBuffer(), - (ab) => sendTypedArray(new DataView(ab)), - ); + if (ObjectPrototypeIsPrototypeOf(ArrayBufferPrototype, data)) { + sendTypedArray(new Uint8Array(data)); } else if (ArrayBufferIsView(data)) { sendTypedArray(data); - } else if (ObjectPrototypeIsPrototypeOf(ArrayBufferPrototype, data)) { - sendTypedArray(new DataView(data)); - } else { - const string = String(data); - const d = core.encode(string); - this[_bufferedAmount] += d.byteLength; + } else if (ObjectPrototypeIsPrototypeOf(BlobPrototype, data)) { PromisePrototypeThen( - core.opAsync("op_ws_send", this[_rid], { - kind: "text", - value: string, - }), - () => { - this[_bufferedAmount] -= d.byteLength; - }, + data.slice().arrayBuffer(), + (ab) => sendTypedArray(new Uint8Array(ab)), ); } } |