aboutsummaryrefslogtreecommitdiffstats
path: root/node_modules/undici/lib/web/websocket/sender.js
diff options
context:
space:
mode:
authorpack <pack@packgekko.xyz>2026-08-09 10:37:07 +0000
committerpack <pack@packgekko.xyz>2026-08-09 10:37:07 +0000
commit55a4f1fc869e41aca748c63d3018f0448b1606e0 (patch)
treed132d1d01772b6d53faee3e63c534dea5706b78a /node_modules/undici/lib/web/websocket/sender.js
downloadcrud-55a4f1fc869e41aca748c63d3018f0448b1606e0.tar.gz
first commit
Diffstat (limited to 'node_modules/undici/lib/web/websocket/sender.js')
-rw-r--r--node_modules/undici/lib/web/websocket/sender.js104
1 files changed, 104 insertions, 0 deletions
diff --git a/node_modules/undici/lib/web/websocket/sender.js b/node_modules/undici/lib/web/websocket/sender.js
new file mode 100644
index 0000000..1b1468d
--- /dev/null
+++ b/node_modules/undici/lib/web/websocket/sender.js
@@ -0,0 +1,104 @@
+'use strict'
+
+const { WebsocketFrameSend } = require('./frame')
+const { opcodes, sendHints } = require('./constants')
+const FixedQueue = require('../../dispatcher/fixed-queue')
+
+/** @type {typeof Uint8Array} */
+const FastBuffer = Buffer[Symbol.species]
+
+/**
+ * @typedef {object} SendQueueNode
+ * @property {Promise<void> | null} promise
+ * @property {((...args: any[]) => any)} callback
+ * @property {Buffer | null} frame
+ */
+
+class SendQueue {
+ /**
+ * @type {FixedQueue}
+ */
+ #queue = new FixedQueue()
+
+ /**
+ * @type {boolean}
+ */
+ #running = false
+
+ /** @type {import('node:net').Socket} */
+ #socket
+
+ constructor (socket) {
+ this.#socket = socket
+ }
+
+ add (item, cb, hint) {
+ if (hint !== sendHints.blob) {
+ const frame = createFrame(item, hint)
+ if (!this.#running) {
+ // fast-path
+ this.#socket.write(frame, cb)
+ } else {
+ /** @type {SendQueueNode} */
+ const node = {
+ promise: null,
+ callback: cb,
+ frame
+ }
+ this.#queue.push(node)
+ }
+ return
+ }
+
+ /** @type {SendQueueNode} */
+ const node = {
+ promise: item.arrayBuffer().then((ab) => {
+ node.promise = null
+ node.frame = createFrame(ab, hint)
+ }),
+ callback: cb,
+ frame: null
+ }
+
+ this.#queue.push(node)
+
+ if (!this.#running) {
+ this.#run()
+ }
+ }
+
+ async #run () {
+ this.#running = true
+ const queue = this.#queue
+ while (!queue.isEmpty()) {
+ const node = queue.shift()
+ // wait pending promise
+ if (node.promise !== null) {
+ await node.promise
+ }
+ // write
+ this.#socket.write(node.frame, node.callback)
+ // cleanup
+ node.callback = node.frame = null
+ }
+ this.#running = false
+ }
+}
+
+function createFrame (data, hint) {
+ return new WebsocketFrameSend(toBuffer(data, hint)).createFrame(hint === sendHints.string ? opcodes.TEXT : opcodes.BINARY)
+}
+
+function toBuffer (data, hint) {
+ switch (hint) {
+ case sendHints.string:
+ return Buffer.from(data)
+ case sendHints.arrayBuffer:
+ case sendHints.blob:
+ return new FastBuffer(data)
+ case sendHints.typedArray:
+ return new FastBuffer(data.buffer, data.byteOffset, data.byteLength)
+ }
+}
+
+module.exports = { SendQueue }