@naeemo/capnp 0.5.2 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,8 +1,35 @@
1
1
  import { C as QuestionTable, S as ImportTable, _ as QueuedCallManager, a as serializeGetSchemaParams, b as AnswerTable, c as serializeSchemaRequest, d as parseSchemaNodes, f as SchemaFormat, g as PipelineResolutionTracker, h as PipelineOpTracker, i as deserializeSchemaResponse, l as serializeSchemaResponse, m as PIPELINE_CLIENT_SYMBOL, n as SCHEMA_MESSAGE_TYPES, o as serializeGetSchemaResults, p as SchemaNodeType, r as deserializeSchemaRequest, s as serializeListSchemasResults, t as RpcConnection, u as createSchemaRegistry, v as createPipelineClient, x as ExportTable, y as isPipelineClient } from "./rpc-connection-C3-uEtpd.js";
2
2
  import { createRequire } from "node:module";
3
- import * as net from "node:net";
3
+ import * as net$1 from "node:net";
4
+ import { createConnection } from "node:net";
5
+ import { EventEmitter } from "node:events";
4
6
 
5
7
  //#region \0rolldown/runtime.js
8
+ var __create = Object.create;
9
+ var __defProp = Object.defineProperty;
10
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
11
+ var __getOwnPropNames = Object.getOwnPropertyNames;
12
+ var __getProtoOf = Object.getPrototypeOf;
13
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
14
+ var __commonJSMin = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
15
+ var __copyProps = (to, from, except, desc) => {
16
+ if (from && typeof from === "object" || typeof from === "function") {
17
+ for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
18
+ key = keys[i];
19
+ if (!__hasOwnProp.call(to, key) && key !== except) {
20
+ __defProp(to, key, {
21
+ get: ((k) => from[k]).bind(null, key),
22
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
23
+ });
24
+ }
25
+ }
26
+ }
27
+ return to;
28
+ };
29
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
30
+ value: mod,
31
+ enumerable: true
32
+ }) : target, mod));
6
33
  var __require = /* @__PURE__ */ createRequire(import.meta.url);
7
34
 
8
35
  //#endregion
@@ -334,6 +361,25 @@ var StructBuilder = class StructBuilder {
334
361
  segment.setWord(ptrOffset, ptr);
335
362
  }
336
363
  /**
364
+ * 设置数据字段(Uint8Array)
365
+ * @param pointerIndex - 指针索引
366
+ * @param value - Uint8Array 数据
367
+ */
368
+ setData(pointerIndex, value) {
369
+ const ptrOffset = this.wordOffset + this.dataWords + pointerIndex;
370
+ const segment = this.message.getSegment();
371
+ if (value.length === 0) {
372
+ const ptr = encodeListPointer(0, ElementSize.BYTE, 0);
373
+ segment.setWord(ptrOffset, ptr);
374
+ return;
375
+ }
376
+ const wordCount = Math.ceil(value.length / WORD_SIZE);
377
+ const listOffset = segment.allocate(wordCount);
378
+ new Uint8Array(segment.dataView.buffer, listOffset * WORD_SIZE, value.length).set(value);
379
+ const ptr = encodeListPointer(listOffset - ptrOffset - 1, ElementSize.BYTE, value.length);
380
+ segment.setWord(ptrOffset, ptr);
381
+ }
382
+ /**
337
383
  * 初始化嵌套结构
338
384
  */
339
385
  initStruct(pointerIndex, dataWords, pointerCount) {
@@ -769,6 +815,25 @@ var StructReader = class StructReader {
769
815
  return new TextDecoder().decode(bytes);
770
816
  }
771
817
  /**
818
+ * 获取数据字段
819
+ * Data is stored as List(UInt8) without NUL terminator
820
+ * @param pointerIndex - The index of the pointer in the pointer section
821
+ * @returns Uint8Array of the data content, or undefined if null pointer
822
+ */
823
+ getData(pointerIndex) {
824
+ const ptrOffset = this.wordOffset + this.dataWords + pointerIndex;
825
+ const resolved = this.message.resolvePointer(this.segmentIndex, ptrOffset);
826
+ if (!resolved) return void 0;
827
+ const { segmentIndex, wordOffset, pointer } = resolved;
828
+ if (pointer.tag !== PointerTag.LIST) return void 0;
829
+ const listPtr = pointer;
830
+ const segment = this.message.getSegment(segmentIndex);
831
+ const byteLength = listPtr.elementCount;
832
+ if (byteLength === 0) return new Uint8Array(0);
833
+ const bytes = new Uint8Array(segment.dataView.buffer, wordOffset * WORD_SIZE, byteLength);
834
+ return new Uint8Array(bytes);
835
+ }
836
+ /**
772
837
  * 获取嵌套结构
773
838
  */
774
839
  getStruct(pointerIndex, _dataWords, _pointerCount) {
@@ -1794,7 +1859,7 @@ var TcpTransport = class TcpTransport {
1794
1859
  this.socket?.destroy();
1795
1860
  reject(/* @__PURE__ */ new Error("Connection timeout"));
1796
1861
  }, this.options.connectTimeoutMs ?? 1e4);
1797
- this.socket = new net.Socket();
1862
+ this.socket = new net$1.Socket();
1798
1863
  this.socket.on("connect", () => {
1799
1864
  clearTimeout(timeout);
1800
1865
  this._connected = true;
@@ -1951,7 +2016,7 @@ var EzRpcTransport = class EzRpcTransport {
1951
2016
  this.socket?.destroy();
1952
2017
  reject(/* @__PURE__ */ new Error(`Connection timeout: failed to connect to ${this.host}:${this.port}`));
1953
2018
  }, this.options.connectTimeoutMs ?? 1e4);
1954
- this.socket = new net.Socket();
2019
+ this.socket = new net$1.Socket();
1955
2020
  this.socket.on("connect", () => {
1956
2021
  clearTimeout(timeout);
1957
2022
  this._connected = true;
@@ -6192,5 +6257,3756 @@ var SchemaCapabilityClient = class {
6192
6257
  };
6193
6258
 
6194
6259
  //#endregion
6195
- export { AnswerTable, BaseCapabilityClient, BulkTransfer, BulkTransferManager, ConnectionManager, DEFAULT_BULK_CONFIG, DEFAULT_ESCROW_CONFIG, DEFAULT_FLOW_CONTROL, DEFAULT_JOIN_OPTIONS, DEFAULT_JOIN_SECURITY_POLICY, DEFAULT_REALTIME_CONFIG, DEFAULT_STREAMING_CAPABILITIES, DropPolicy, ElementSize, ExportTable, EzRpcTransport, ImportTable, Level3Handlers, Level4Handlers, ListBuilder, ListReader, MemoryPool, MessageBuilder, MessageReader, MultiSegmentMessageBuilder, OptimizedRpcMessageBuilder, PIPELINE_CLIENT_SYMBOL, PipelineOpTracker, PipelineResolutionTracker, PointerTag, QuestionTable, QueuedCallManager, RealtimeStream, RealtimeStreamManager, RestoreHandler, RpcConnection, SCHEMA_MESSAGE_TYPES, SchemaCapabilityClient, SchemaCapabilityServer, SchemaFormat, Segment, Stream, StreamManager, StreamPriority, StreamType, StreamingRpcConnection, StructBuilder, StructReader, SturdyRefManager, TcpTransport, UnionBuilder, UnionReader, WORD_SIZE, WebSocketTransport, configureGlobalMemoryPool, createBulkTransferManager, createDynamicReader, createDynamicReaderByTypeId, createDynamicReaderFromStruct, createDynamicWriter, createDynamicWriterByTypeId, createNestedDynamicWriter, createPipelineClient, createProvisionId, createRealtimeStreamManager, createRecipientId, createSchemaRegistry, createStream, createStreamManager, createStreamingConnection, createSturdyRef, createThirdPartyCapId, createUnionBuilder, createUnionReader, createZeroCopyView, decodePointer, deserializeRpcMessage, deserializeSchemaRequest, deserializeSchemaResponse, deserializeSturdyRef, dumpDynamicReader, encodeListPointer, encodeStructPointer, fastCopy, generateProvisionId, generateVatId, getGlobalMemoryPool, isPipelineClient, isSameBuffer, isStream, isSturdyRefValid, parseSchemaNodes, serializeDynamic, serializeDynamicByTypeId, serializeGetSchemaParams, serializeGetSchemaResults, serializeListSchemasResults, serializeRpcMessage, serializeSchemaRequest, serializeSchemaResponse, serializeSturdyRef, supportsStreaming };
6260
+ //#region node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/constants.js
6261
+ var require_constants = /* @__PURE__ */ __commonJSMin(((exports, module) => {
6262
+ const BINARY_TYPES = [
6263
+ "nodebuffer",
6264
+ "arraybuffer",
6265
+ "fragments"
6266
+ ];
6267
+ const hasBlob = typeof Blob !== "undefined";
6268
+ if (hasBlob) BINARY_TYPES.push("blob");
6269
+ module.exports = {
6270
+ BINARY_TYPES,
6271
+ CLOSE_TIMEOUT: 3e4,
6272
+ EMPTY_BUFFER: Buffer.alloc(0),
6273
+ GUID: "258EAFA5-E914-47DA-95CA-C5AB0DC85B11",
6274
+ hasBlob,
6275
+ kForOnEventAttribute: Symbol("kIsForOnEventAttribute"),
6276
+ kListener: Symbol("kListener"),
6277
+ kStatusCode: Symbol("status-code"),
6278
+ kWebSocket: Symbol("websocket"),
6279
+ NOOP: () => {}
6280
+ };
6281
+ }));
6282
+
6283
+ //#endregion
6284
+ //#region node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/buffer-util.js
6285
+ var require_buffer_util = /* @__PURE__ */ __commonJSMin(((exports, module) => {
6286
+ const { EMPTY_BUFFER } = require_constants();
6287
+ const FastBuffer = Buffer[Symbol.species];
6288
+ /**
6289
+ * Merges an array of buffers into a new buffer.
6290
+ *
6291
+ * @param {Buffer[]} list The array of buffers to concat
6292
+ * @param {Number} totalLength The total length of buffers in the list
6293
+ * @return {Buffer} The resulting buffer
6294
+ * @public
6295
+ */
6296
+ function concat(list, totalLength) {
6297
+ if (list.length === 0) return EMPTY_BUFFER;
6298
+ if (list.length === 1) return list[0];
6299
+ const target = Buffer.allocUnsafe(totalLength);
6300
+ let offset = 0;
6301
+ for (let i = 0; i < list.length; i++) {
6302
+ const buf = list[i];
6303
+ target.set(buf, offset);
6304
+ offset += buf.length;
6305
+ }
6306
+ if (offset < totalLength) return new FastBuffer(target.buffer, target.byteOffset, offset);
6307
+ return target;
6308
+ }
6309
+ /**
6310
+ * Masks a buffer using the given mask.
6311
+ *
6312
+ * @param {Buffer} source The buffer to mask
6313
+ * @param {Buffer} mask The mask to use
6314
+ * @param {Buffer} output The buffer where to store the result
6315
+ * @param {Number} offset The offset at which to start writing
6316
+ * @param {Number} length The number of bytes to mask.
6317
+ * @public
6318
+ */
6319
+ function _mask(source, mask, output, offset, length) {
6320
+ for (let i = 0; i < length; i++) output[offset + i] = source[i] ^ mask[i & 3];
6321
+ }
6322
+ /**
6323
+ * Unmasks a buffer using the given mask.
6324
+ *
6325
+ * @param {Buffer} buffer The buffer to unmask
6326
+ * @param {Buffer} mask The mask to use
6327
+ * @public
6328
+ */
6329
+ function _unmask(buffer, mask) {
6330
+ for (let i = 0; i < buffer.length; i++) buffer[i] ^= mask[i & 3];
6331
+ }
6332
+ /**
6333
+ * Converts a buffer to an `ArrayBuffer`.
6334
+ *
6335
+ * @param {Buffer} buf The buffer to convert
6336
+ * @return {ArrayBuffer} Converted buffer
6337
+ * @public
6338
+ */
6339
+ function toArrayBuffer(buf) {
6340
+ if (buf.length === buf.buffer.byteLength) return buf.buffer;
6341
+ return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.length);
6342
+ }
6343
+ /**
6344
+ * Converts `data` to a `Buffer`.
6345
+ *
6346
+ * @param {*} data The data to convert
6347
+ * @return {Buffer} The buffer
6348
+ * @throws {TypeError}
6349
+ * @public
6350
+ */
6351
+ function toBuffer(data) {
6352
+ toBuffer.readOnly = true;
6353
+ if (Buffer.isBuffer(data)) return data;
6354
+ let buf;
6355
+ if (data instanceof ArrayBuffer) buf = new FastBuffer(data);
6356
+ else if (ArrayBuffer.isView(data)) buf = new FastBuffer(data.buffer, data.byteOffset, data.byteLength);
6357
+ else {
6358
+ buf = Buffer.from(data);
6359
+ toBuffer.readOnly = false;
6360
+ }
6361
+ return buf;
6362
+ }
6363
+ module.exports = {
6364
+ concat,
6365
+ mask: _mask,
6366
+ toArrayBuffer,
6367
+ toBuffer,
6368
+ unmask: _unmask
6369
+ };
6370
+ /* istanbul ignore else */
6371
+ if (!process.env.WS_NO_BUFFER_UTIL) try {
6372
+ const bufferUtil = __require("bufferutil");
6373
+ module.exports.mask = function(source, mask, output, offset, length) {
6374
+ if (length < 48) _mask(source, mask, output, offset, length);
6375
+ else bufferUtil.mask(source, mask, output, offset, length);
6376
+ };
6377
+ module.exports.unmask = function(buffer, mask) {
6378
+ if (buffer.length < 32) _unmask(buffer, mask);
6379
+ else bufferUtil.unmask(buffer, mask);
6380
+ };
6381
+ } catch (e) {}
6382
+ }));
6383
+
6384
+ //#endregion
6385
+ //#region node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/limiter.js
6386
+ var require_limiter = /* @__PURE__ */ __commonJSMin(((exports, module) => {
6387
+ const kDone = Symbol("kDone");
6388
+ const kRun = Symbol("kRun");
6389
+ /**
6390
+ * A very simple job queue with adjustable concurrency. Adapted from
6391
+ * https://github.com/STRML/async-limiter
6392
+ */
6393
+ var Limiter = class {
6394
+ /**
6395
+ * Creates a new `Limiter`.
6396
+ *
6397
+ * @param {Number} [concurrency=Infinity] The maximum number of jobs allowed
6398
+ * to run concurrently
6399
+ */
6400
+ constructor(concurrency) {
6401
+ this[kDone] = () => {
6402
+ this.pending--;
6403
+ this[kRun]();
6404
+ };
6405
+ this.concurrency = concurrency || Infinity;
6406
+ this.jobs = [];
6407
+ this.pending = 0;
6408
+ }
6409
+ /**
6410
+ * Adds a job to the queue.
6411
+ *
6412
+ * @param {Function} job The job to run
6413
+ * @public
6414
+ */
6415
+ add(job) {
6416
+ this.jobs.push(job);
6417
+ this[kRun]();
6418
+ }
6419
+ /**
6420
+ * Removes a job from the queue and runs it if possible.
6421
+ *
6422
+ * @private
6423
+ */
6424
+ [kRun]() {
6425
+ if (this.pending === this.concurrency) return;
6426
+ if (this.jobs.length) {
6427
+ const job = this.jobs.shift();
6428
+ this.pending++;
6429
+ job(this[kDone]);
6430
+ }
6431
+ }
6432
+ };
6433
+ module.exports = Limiter;
6434
+ }));
6435
+
6436
+ //#endregion
6437
+ //#region node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/permessage-deflate.js
6438
+ var require_permessage_deflate = /* @__PURE__ */ __commonJSMin(((exports, module) => {
6439
+ const zlib = __require("zlib");
6440
+ const bufferUtil = require_buffer_util();
6441
+ const Limiter = require_limiter();
6442
+ const { kStatusCode } = require_constants();
6443
+ const FastBuffer = Buffer[Symbol.species];
6444
+ const TRAILER = Buffer.from([
6445
+ 0,
6446
+ 0,
6447
+ 255,
6448
+ 255
6449
+ ]);
6450
+ const kPerMessageDeflate = Symbol("permessage-deflate");
6451
+ const kTotalLength = Symbol("total-length");
6452
+ const kCallback = Symbol("callback");
6453
+ const kBuffers = Symbol("buffers");
6454
+ const kError = Symbol("error");
6455
+ let zlibLimiter;
6456
+ /**
6457
+ * permessage-deflate implementation.
6458
+ */
6459
+ var PerMessageDeflate = class {
6460
+ /**
6461
+ * Creates a PerMessageDeflate instance.
6462
+ *
6463
+ * @param {Object} [options] Configuration options
6464
+ * @param {(Boolean|Number)} [options.clientMaxWindowBits] Advertise support
6465
+ * for, or request, a custom client window size
6466
+ * @param {Boolean} [options.clientNoContextTakeover=false] Advertise/
6467
+ * acknowledge disabling of client context takeover
6468
+ * @param {Number} [options.concurrencyLimit=10] The number of concurrent
6469
+ * calls to zlib
6470
+ * @param {(Boolean|Number)} [options.serverMaxWindowBits] Request/confirm the
6471
+ * use of a custom server window size
6472
+ * @param {Boolean} [options.serverNoContextTakeover=false] Request/accept
6473
+ * disabling of server context takeover
6474
+ * @param {Number} [options.threshold=1024] Size (in bytes) below which
6475
+ * messages should not be compressed if context takeover is disabled
6476
+ * @param {Object} [options.zlibDeflateOptions] Options to pass to zlib on
6477
+ * deflate
6478
+ * @param {Object} [options.zlibInflateOptions] Options to pass to zlib on
6479
+ * inflate
6480
+ * @param {Boolean} [isServer=false] Create the instance in either server or
6481
+ * client mode
6482
+ * @param {Number} [maxPayload=0] The maximum allowed message length
6483
+ */
6484
+ constructor(options, isServer, maxPayload) {
6485
+ this._maxPayload = maxPayload | 0;
6486
+ this._options = options || {};
6487
+ this._threshold = this._options.threshold !== void 0 ? this._options.threshold : 1024;
6488
+ this._isServer = !!isServer;
6489
+ this._deflate = null;
6490
+ this._inflate = null;
6491
+ this.params = null;
6492
+ if (!zlibLimiter) zlibLimiter = new Limiter(this._options.concurrencyLimit !== void 0 ? this._options.concurrencyLimit : 10);
6493
+ }
6494
+ /**
6495
+ * @type {String}
6496
+ */
6497
+ static get extensionName() {
6498
+ return "permessage-deflate";
6499
+ }
6500
+ /**
6501
+ * Create an extension negotiation offer.
6502
+ *
6503
+ * @return {Object} Extension parameters
6504
+ * @public
6505
+ */
6506
+ offer() {
6507
+ const params = {};
6508
+ if (this._options.serverNoContextTakeover) params.server_no_context_takeover = true;
6509
+ if (this._options.clientNoContextTakeover) params.client_no_context_takeover = true;
6510
+ if (this._options.serverMaxWindowBits) params.server_max_window_bits = this._options.serverMaxWindowBits;
6511
+ if (this._options.clientMaxWindowBits) params.client_max_window_bits = this._options.clientMaxWindowBits;
6512
+ else if (this._options.clientMaxWindowBits == null) params.client_max_window_bits = true;
6513
+ return params;
6514
+ }
6515
+ /**
6516
+ * Accept an extension negotiation offer/response.
6517
+ *
6518
+ * @param {Array} configurations The extension negotiation offers/reponse
6519
+ * @return {Object} Accepted configuration
6520
+ * @public
6521
+ */
6522
+ accept(configurations) {
6523
+ configurations = this.normalizeParams(configurations);
6524
+ this.params = this._isServer ? this.acceptAsServer(configurations) : this.acceptAsClient(configurations);
6525
+ return this.params;
6526
+ }
6527
+ /**
6528
+ * Releases all resources used by the extension.
6529
+ *
6530
+ * @public
6531
+ */
6532
+ cleanup() {
6533
+ if (this._inflate) {
6534
+ this._inflate.close();
6535
+ this._inflate = null;
6536
+ }
6537
+ if (this._deflate) {
6538
+ const callback = this._deflate[kCallback];
6539
+ this._deflate.close();
6540
+ this._deflate = null;
6541
+ if (callback) callback(/* @__PURE__ */ new Error("The deflate stream was closed while data was being processed"));
6542
+ }
6543
+ }
6544
+ /**
6545
+ * Accept an extension negotiation offer.
6546
+ *
6547
+ * @param {Array} offers The extension negotiation offers
6548
+ * @return {Object} Accepted configuration
6549
+ * @private
6550
+ */
6551
+ acceptAsServer(offers) {
6552
+ const opts = this._options;
6553
+ const accepted = offers.find((params) => {
6554
+ if (opts.serverNoContextTakeover === false && params.server_no_context_takeover || params.server_max_window_bits && (opts.serverMaxWindowBits === false || typeof opts.serverMaxWindowBits === "number" && opts.serverMaxWindowBits > params.server_max_window_bits) || typeof opts.clientMaxWindowBits === "number" && !params.client_max_window_bits) return false;
6555
+ return true;
6556
+ });
6557
+ if (!accepted) throw new Error("None of the extension offers can be accepted");
6558
+ if (opts.serverNoContextTakeover) accepted.server_no_context_takeover = true;
6559
+ if (opts.clientNoContextTakeover) accepted.client_no_context_takeover = true;
6560
+ if (typeof opts.serverMaxWindowBits === "number") accepted.server_max_window_bits = opts.serverMaxWindowBits;
6561
+ if (typeof opts.clientMaxWindowBits === "number") accepted.client_max_window_bits = opts.clientMaxWindowBits;
6562
+ else if (accepted.client_max_window_bits === true || opts.clientMaxWindowBits === false) delete accepted.client_max_window_bits;
6563
+ return accepted;
6564
+ }
6565
+ /**
6566
+ * Accept the extension negotiation response.
6567
+ *
6568
+ * @param {Array} response The extension negotiation response
6569
+ * @return {Object} Accepted configuration
6570
+ * @private
6571
+ */
6572
+ acceptAsClient(response) {
6573
+ const params = response[0];
6574
+ if (this._options.clientNoContextTakeover === false && params.client_no_context_takeover) throw new Error("Unexpected parameter \"client_no_context_takeover\"");
6575
+ if (!params.client_max_window_bits) {
6576
+ if (typeof this._options.clientMaxWindowBits === "number") params.client_max_window_bits = this._options.clientMaxWindowBits;
6577
+ } else if (this._options.clientMaxWindowBits === false || typeof this._options.clientMaxWindowBits === "number" && params.client_max_window_bits > this._options.clientMaxWindowBits) throw new Error("Unexpected or invalid parameter \"client_max_window_bits\"");
6578
+ return params;
6579
+ }
6580
+ /**
6581
+ * Normalize parameters.
6582
+ *
6583
+ * @param {Array} configurations The extension negotiation offers/reponse
6584
+ * @return {Array} The offers/response with normalized parameters
6585
+ * @private
6586
+ */
6587
+ normalizeParams(configurations) {
6588
+ configurations.forEach((params) => {
6589
+ Object.keys(params).forEach((key) => {
6590
+ let value = params[key];
6591
+ if (value.length > 1) throw new Error(`Parameter "${key}" must have only a single value`);
6592
+ value = value[0];
6593
+ if (key === "client_max_window_bits") {
6594
+ if (value !== true) {
6595
+ const num = +value;
6596
+ if (!Number.isInteger(num) || num < 8 || num > 15) throw new TypeError(`Invalid value for parameter "${key}": ${value}`);
6597
+ value = num;
6598
+ } else if (!this._isServer) throw new TypeError(`Invalid value for parameter "${key}": ${value}`);
6599
+ } else if (key === "server_max_window_bits") {
6600
+ const num = +value;
6601
+ if (!Number.isInteger(num) || num < 8 || num > 15) throw new TypeError(`Invalid value for parameter "${key}": ${value}`);
6602
+ value = num;
6603
+ } else if (key === "client_no_context_takeover" || key === "server_no_context_takeover") {
6604
+ if (value !== true) throw new TypeError(`Invalid value for parameter "${key}": ${value}`);
6605
+ } else throw new Error(`Unknown parameter "${key}"`);
6606
+ params[key] = value;
6607
+ });
6608
+ });
6609
+ return configurations;
6610
+ }
6611
+ /**
6612
+ * Decompress data. Concurrency limited.
6613
+ *
6614
+ * @param {Buffer} data Compressed data
6615
+ * @param {Boolean} fin Specifies whether or not this is the last fragment
6616
+ * @param {Function} callback Callback
6617
+ * @public
6618
+ */
6619
+ decompress(data, fin, callback) {
6620
+ zlibLimiter.add((done) => {
6621
+ this._decompress(data, fin, (err, result) => {
6622
+ done();
6623
+ callback(err, result);
6624
+ });
6625
+ });
6626
+ }
6627
+ /**
6628
+ * Compress data. Concurrency limited.
6629
+ *
6630
+ * @param {(Buffer|String)} data Data to compress
6631
+ * @param {Boolean} fin Specifies whether or not this is the last fragment
6632
+ * @param {Function} callback Callback
6633
+ * @public
6634
+ */
6635
+ compress(data, fin, callback) {
6636
+ zlibLimiter.add((done) => {
6637
+ this._compress(data, fin, (err, result) => {
6638
+ done();
6639
+ callback(err, result);
6640
+ });
6641
+ });
6642
+ }
6643
+ /**
6644
+ * Decompress data.
6645
+ *
6646
+ * @param {Buffer} data Compressed data
6647
+ * @param {Boolean} fin Specifies whether or not this is the last fragment
6648
+ * @param {Function} callback Callback
6649
+ * @private
6650
+ */
6651
+ _decompress(data, fin, callback) {
6652
+ const endpoint = this._isServer ? "client" : "server";
6653
+ if (!this._inflate) {
6654
+ const key = `${endpoint}_max_window_bits`;
6655
+ const windowBits = typeof this.params[key] !== "number" ? zlib.Z_DEFAULT_WINDOWBITS : this.params[key];
6656
+ this._inflate = zlib.createInflateRaw({
6657
+ ...this._options.zlibInflateOptions,
6658
+ windowBits
6659
+ });
6660
+ this._inflate[kPerMessageDeflate] = this;
6661
+ this._inflate[kTotalLength] = 0;
6662
+ this._inflate[kBuffers] = [];
6663
+ this._inflate.on("error", inflateOnError);
6664
+ this._inflate.on("data", inflateOnData);
6665
+ }
6666
+ this._inflate[kCallback] = callback;
6667
+ this._inflate.write(data);
6668
+ if (fin) this._inflate.write(TRAILER);
6669
+ this._inflate.flush(() => {
6670
+ const err = this._inflate[kError];
6671
+ if (err) {
6672
+ this._inflate.close();
6673
+ this._inflate = null;
6674
+ callback(err);
6675
+ return;
6676
+ }
6677
+ const data = bufferUtil.concat(this._inflate[kBuffers], this._inflate[kTotalLength]);
6678
+ if (this._inflate._readableState.endEmitted) {
6679
+ this._inflate.close();
6680
+ this._inflate = null;
6681
+ } else {
6682
+ this._inflate[kTotalLength] = 0;
6683
+ this._inflate[kBuffers] = [];
6684
+ if (fin && this.params[`${endpoint}_no_context_takeover`]) this._inflate.reset();
6685
+ }
6686
+ callback(null, data);
6687
+ });
6688
+ }
6689
+ /**
6690
+ * Compress data.
6691
+ *
6692
+ * @param {(Buffer|String)} data Data to compress
6693
+ * @param {Boolean} fin Specifies whether or not this is the last fragment
6694
+ * @param {Function} callback Callback
6695
+ * @private
6696
+ */
6697
+ _compress(data, fin, callback) {
6698
+ const endpoint = this._isServer ? "server" : "client";
6699
+ if (!this._deflate) {
6700
+ const key = `${endpoint}_max_window_bits`;
6701
+ const windowBits = typeof this.params[key] !== "number" ? zlib.Z_DEFAULT_WINDOWBITS : this.params[key];
6702
+ this._deflate = zlib.createDeflateRaw({
6703
+ ...this._options.zlibDeflateOptions,
6704
+ windowBits
6705
+ });
6706
+ this._deflate[kTotalLength] = 0;
6707
+ this._deflate[kBuffers] = [];
6708
+ this._deflate.on("data", deflateOnData);
6709
+ }
6710
+ this._deflate[kCallback] = callback;
6711
+ this._deflate.write(data);
6712
+ this._deflate.flush(zlib.Z_SYNC_FLUSH, () => {
6713
+ if (!this._deflate) return;
6714
+ let data = bufferUtil.concat(this._deflate[kBuffers], this._deflate[kTotalLength]);
6715
+ if (fin) data = new FastBuffer(data.buffer, data.byteOffset, data.length - 4);
6716
+ this._deflate[kCallback] = null;
6717
+ this._deflate[kTotalLength] = 0;
6718
+ this._deflate[kBuffers] = [];
6719
+ if (fin && this.params[`${endpoint}_no_context_takeover`]) this._deflate.reset();
6720
+ callback(null, data);
6721
+ });
6722
+ }
6723
+ };
6724
+ module.exports = PerMessageDeflate;
6725
+ /**
6726
+ * The listener of the `zlib.DeflateRaw` stream `'data'` event.
6727
+ *
6728
+ * @param {Buffer} chunk A chunk of data
6729
+ * @private
6730
+ */
6731
+ function deflateOnData(chunk) {
6732
+ this[kBuffers].push(chunk);
6733
+ this[kTotalLength] += chunk.length;
6734
+ }
6735
+ /**
6736
+ * The listener of the `zlib.InflateRaw` stream `'data'` event.
6737
+ *
6738
+ * @param {Buffer} chunk A chunk of data
6739
+ * @private
6740
+ */
6741
+ function inflateOnData(chunk) {
6742
+ this[kTotalLength] += chunk.length;
6743
+ if (this[kPerMessageDeflate]._maxPayload < 1 || this[kTotalLength] <= this[kPerMessageDeflate]._maxPayload) {
6744
+ this[kBuffers].push(chunk);
6745
+ return;
6746
+ }
6747
+ this[kError] = /* @__PURE__ */ new RangeError("Max payload size exceeded");
6748
+ this[kError].code = "WS_ERR_UNSUPPORTED_MESSAGE_LENGTH";
6749
+ this[kError][kStatusCode] = 1009;
6750
+ this.removeListener("data", inflateOnData);
6751
+ this.reset();
6752
+ }
6753
+ /**
6754
+ * The listener of the `zlib.InflateRaw` stream `'error'` event.
6755
+ *
6756
+ * @param {Error} err The emitted error
6757
+ * @private
6758
+ */
6759
+ function inflateOnError(err) {
6760
+ this[kPerMessageDeflate]._inflate = null;
6761
+ if (this[kError]) {
6762
+ this[kCallback](this[kError]);
6763
+ return;
6764
+ }
6765
+ err[kStatusCode] = 1007;
6766
+ this[kCallback](err);
6767
+ }
6768
+ }));
6769
+
6770
+ //#endregion
6771
+ //#region node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/validation.js
6772
+ var require_validation = /* @__PURE__ */ __commonJSMin(((exports, module) => {
6773
+ const { isUtf8 } = __require("buffer");
6774
+ const { hasBlob } = require_constants();
6775
+ const tokenChars = [
6776
+ 0,
6777
+ 0,
6778
+ 0,
6779
+ 0,
6780
+ 0,
6781
+ 0,
6782
+ 0,
6783
+ 0,
6784
+ 0,
6785
+ 0,
6786
+ 0,
6787
+ 0,
6788
+ 0,
6789
+ 0,
6790
+ 0,
6791
+ 0,
6792
+ 0,
6793
+ 0,
6794
+ 0,
6795
+ 0,
6796
+ 0,
6797
+ 0,
6798
+ 0,
6799
+ 0,
6800
+ 0,
6801
+ 0,
6802
+ 0,
6803
+ 0,
6804
+ 0,
6805
+ 0,
6806
+ 0,
6807
+ 0,
6808
+ 0,
6809
+ 1,
6810
+ 0,
6811
+ 1,
6812
+ 1,
6813
+ 1,
6814
+ 1,
6815
+ 1,
6816
+ 0,
6817
+ 0,
6818
+ 1,
6819
+ 1,
6820
+ 0,
6821
+ 1,
6822
+ 1,
6823
+ 0,
6824
+ 1,
6825
+ 1,
6826
+ 1,
6827
+ 1,
6828
+ 1,
6829
+ 1,
6830
+ 1,
6831
+ 1,
6832
+ 1,
6833
+ 1,
6834
+ 0,
6835
+ 0,
6836
+ 0,
6837
+ 0,
6838
+ 0,
6839
+ 0,
6840
+ 0,
6841
+ 1,
6842
+ 1,
6843
+ 1,
6844
+ 1,
6845
+ 1,
6846
+ 1,
6847
+ 1,
6848
+ 1,
6849
+ 1,
6850
+ 1,
6851
+ 1,
6852
+ 1,
6853
+ 1,
6854
+ 1,
6855
+ 1,
6856
+ 1,
6857
+ 1,
6858
+ 1,
6859
+ 1,
6860
+ 1,
6861
+ 1,
6862
+ 1,
6863
+ 1,
6864
+ 1,
6865
+ 1,
6866
+ 1,
6867
+ 0,
6868
+ 0,
6869
+ 0,
6870
+ 1,
6871
+ 1,
6872
+ 1,
6873
+ 1,
6874
+ 1,
6875
+ 1,
6876
+ 1,
6877
+ 1,
6878
+ 1,
6879
+ 1,
6880
+ 1,
6881
+ 1,
6882
+ 1,
6883
+ 1,
6884
+ 1,
6885
+ 1,
6886
+ 1,
6887
+ 1,
6888
+ 1,
6889
+ 1,
6890
+ 1,
6891
+ 1,
6892
+ 1,
6893
+ 1,
6894
+ 1,
6895
+ 1,
6896
+ 1,
6897
+ 1,
6898
+ 1,
6899
+ 0,
6900
+ 1,
6901
+ 0,
6902
+ 1,
6903
+ 0
6904
+ ];
6905
+ /**
6906
+ * Checks if a status code is allowed in a close frame.
6907
+ *
6908
+ * @param {Number} code The status code
6909
+ * @return {Boolean} `true` if the status code is valid, else `false`
6910
+ * @public
6911
+ */
6912
+ function isValidStatusCode(code) {
6913
+ return code >= 1e3 && code <= 1014 && code !== 1004 && code !== 1005 && code !== 1006 || code >= 3e3 && code <= 4999;
6914
+ }
6915
+ /**
6916
+ * Checks if a given buffer contains only correct UTF-8.
6917
+ * Ported from https://www.cl.cam.ac.uk/%7Emgk25/ucs/utf8_check.c by
6918
+ * Markus Kuhn.
6919
+ *
6920
+ * @param {Buffer} buf The buffer to check
6921
+ * @return {Boolean} `true` if `buf` contains only correct UTF-8, else `false`
6922
+ * @public
6923
+ */
6924
+ function _isValidUTF8(buf) {
6925
+ const len = buf.length;
6926
+ let i = 0;
6927
+ while (i < len) if ((buf[i] & 128) === 0) i++;
6928
+ else if ((buf[i] & 224) === 192) {
6929
+ if (i + 1 === len || (buf[i + 1] & 192) !== 128 || (buf[i] & 254) === 192) return false;
6930
+ i += 2;
6931
+ } else if ((buf[i] & 240) === 224) {
6932
+ if (i + 2 >= len || (buf[i + 1] & 192) !== 128 || (buf[i + 2] & 192) !== 128 || buf[i] === 224 && (buf[i + 1] & 224) === 128 || buf[i] === 237 && (buf[i + 1] & 224) === 160) return false;
6933
+ i += 3;
6934
+ } else if ((buf[i] & 248) === 240) {
6935
+ if (i + 3 >= len || (buf[i + 1] & 192) !== 128 || (buf[i + 2] & 192) !== 128 || (buf[i + 3] & 192) !== 128 || buf[i] === 240 && (buf[i + 1] & 240) === 128 || buf[i] === 244 && buf[i + 1] > 143 || buf[i] > 244) return false;
6936
+ i += 4;
6937
+ } else return false;
6938
+ return true;
6939
+ }
6940
+ /**
6941
+ * Determines whether a value is a `Blob`.
6942
+ *
6943
+ * @param {*} value The value to be tested
6944
+ * @return {Boolean} `true` if `value` is a `Blob`, else `false`
6945
+ * @private
6946
+ */
6947
+ function isBlob(value) {
6948
+ return hasBlob && typeof value === "object" && typeof value.arrayBuffer === "function" && typeof value.type === "string" && typeof value.stream === "function" && (value[Symbol.toStringTag] === "Blob" || value[Symbol.toStringTag] === "File");
6949
+ }
6950
+ module.exports = {
6951
+ isBlob,
6952
+ isValidStatusCode,
6953
+ isValidUTF8: _isValidUTF8,
6954
+ tokenChars
6955
+ };
6956
+ if (isUtf8) module.exports.isValidUTF8 = function(buf) {
6957
+ return buf.length < 24 ? _isValidUTF8(buf) : isUtf8(buf);
6958
+ };
6959
+ else if (!process.env.WS_NO_UTF_8_VALIDATE) try {
6960
+ const isValidUTF8 = __require("utf-8-validate");
6961
+ module.exports.isValidUTF8 = function(buf) {
6962
+ return buf.length < 32 ? _isValidUTF8(buf) : isValidUTF8(buf);
6963
+ };
6964
+ } catch (e) {}
6965
+ }));
6966
+
6967
+ //#endregion
6968
+ //#region node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/receiver.js
6969
+ var require_receiver = /* @__PURE__ */ __commonJSMin(((exports, module) => {
6970
+ const { Writable } = __require("stream");
6971
+ const PerMessageDeflate = require_permessage_deflate();
6972
+ const { BINARY_TYPES, EMPTY_BUFFER, kStatusCode, kWebSocket } = require_constants();
6973
+ const { concat, toArrayBuffer, unmask } = require_buffer_util();
6974
+ const { isValidStatusCode, isValidUTF8 } = require_validation();
6975
+ const FastBuffer = Buffer[Symbol.species];
6976
+ const GET_INFO = 0;
6977
+ const GET_PAYLOAD_LENGTH_16 = 1;
6978
+ const GET_PAYLOAD_LENGTH_64 = 2;
6979
+ const GET_MASK = 3;
6980
+ const GET_DATA = 4;
6981
+ const INFLATING = 5;
6982
+ const DEFER_EVENT = 6;
6983
+ /**
6984
+ * HyBi Receiver implementation.
6985
+ *
6986
+ * @extends Writable
6987
+ */
6988
+ var Receiver = class extends Writable {
6989
+ /**
6990
+ * Creates a Receiver instance.
6991
+ *
6992
+ * @param {Object} [options] Options object
6993
+ * @param {Boolean} [options.allowSynchronousEvents=true] Specifies whether
6994
+ * any of the `'message'`, `'ping'`, and `'pong'` events can be emitted
6995
+ * multiple times in the same tick
6996
+ * @param {String} [options.binaryType=nodebuffer] The type for binary data
6997
+ * @param {Object} [options.extensions] An object containing the negotiated
6998
+ * extensions
6999
+ * @param {Boolean} [options.isServer=false] Specifies whether to operate in
7000
+ * client or server mode
7001
+ * @param {Number} [options.maxPayload=0] The maximum allowed message length
7002
+ * @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or
7003
+ * not to skip UTF-8 validation for text and close messages
7004
+ */
7005
+ constructor(options = {}) {
7006
+ super();
7007
+ this._allowSynchronousEvents = options.allowSynchronousEvents !== void 0 ? options.allowSynchronousEvents : true;
7008
+ this._binaryType = options.binaryType || BINARY_TYPES[0];
7009
+ this._extensions = options.extensions || {};
7010
+ this._isServer = !!options.isServer;
7011
+ this._maxPayload = options.maxPayload | 0;
7012
+ this._skipUTF8Validation = !!options.skipUTF8Validation;
7013
+ this[kWebSocket] = void 0;
7014
+ this._bufferedBytes = 0;
7015
+ this._buffers = [];
7016
+ this._compressed = false;
7017
+ this._payloadLength = 0;
7018
+ this._mask = void 0;
7019
+ this._fragmented = 0;
7020
+ this._masked = false;
7021
+ this._fin = false;
7022
+ this._opcode = 0;
7023
+ this._totalPayloadLength = 0;
7024
+ this._messageLength = 0;
7025
+ this._fragments = [];
7026
+ this._errored = false;
7027
+ this._loop = false;
7028
+ this._state = GET_INFO;
7029
+ }
7030
+ /**
7031
+ * Implements `Writable.prototype._write()`.
7032
+ *
7033
+ * @param {Buffer} chunk The chunk of data to write
7034
+ * @param {String} encoding The character encoding of `chunk`
7035
+ * @param {Function} cb Callback
7036
+ * @private
7037
+ */
7038
+ _write(chunk, encoding, cb) {
7039
+ if (this._opcode === 8 && this._state == GET_INFO) return cb();
7040
+ this._bufferedBytes += chunk.length;
7041
+ this._buffers.push(chunk);
7042
+ this.startLoop(cb);
7043
+ }
7044
+ /**
7045
+ * Consumes `n` bytes from the buffered data.
7046
+ *
7047
+ * @param {Number} n The number of bytes to consume
7048
+ * @return {Buffer} The consumed bytes
7049
+ * @private
7050
+ */
7051
+ consume(n) {
7052
+ this._bufferedBytes -= n;
7053
+ if (n === this._buffers[0].length) return this._buffers.shift();
7054
+ if (n < this._buffers[0].length) {
7055
+ const buf = this._buffers[0];
7056
+ this._buffers[0] = new FastBuffer(buf.buffer, buf.byteOffset + n, buf.length - n);
7057
+ return new FastBuffer(buf.buffer, buf.byteOffset, n);
7058
+ }
7059
+ const dst = Buffer.allocUnsafe(n);
7060
+ do {
7061
+ const buf = this._buffers[0];
7062
+ const offset = dst.length - n;
7063
+ if (n >= buf.length) dst.set(this._buffers.shift(), offset);
7064
+ else {
7065
+ dst.set(new Uint8Array(buf.buffer, buf.byteOffset, n), offset);
7066
+ this._buffers[0] = new FastBuffer(buf.buffer, buf.byteOffset + n, buf.length - n);
7067
+ }
7068
+ n -= buf.length;
7069
+ } while (n > 0);
7070
+ return dst;
7071
+ }
7072
+ /**
7073
+ * Starts the parsing loop.
7074
+ *
7075
+ * @param {Function} cb Callback
7076
+ * @private
7077
+ */
7078
+ startLoop(cb) {
7079
+ this._loop = true;
7080
+ do
7081
+ switch (this._state) {
7082
+ case GET_INFO:
7083
+ this.getInfo(cb);
7084
+ break;
7085
+ case GET_PAYLOAD_LENGTH_16:
7086
+ this.getPayloadLength16(cb);
7087
+ break;
7088
+ case GET_PAYLOAD_LENGTH_64:
7089
+ this.getPayloadLength64(cb);
7090
+ break;
7091
+ case GET_MASK:
7092
+ this.getMask();
7093
+ break;
7094
+ case GET_DATA:
7095
+ this.getData(cb);
7096
+ break;
7097
+ case INFLATING:
7098
+ case DEFER_EVENT:
7099
+ this._loop = false;
7100
+ return;
7101
+ }
7102
+ while (this._loop);
7103
+ if (!this._errored) cb();
7104
+ }
7105
+ /**
7106
+ * Reads the first two bytes of a frame.
7107
+ *
7108
+ * @param {Function} cb Callback
7109
+ * @private
7110
+ */
7111
+ getInfo(cb) {
7112
+ if (this._bufferedBytes < 2) {
7113
+ this._loop = false;
7114
+ return;
7115
+ }
7116
+ const buf = this.consume(2);
7117
+ if ((buf[0] & 48) !== 0) {
7118
+ cb(this.createError(RangeError, "RSV2 and RSV3 must be clear", true, 1002, "WS_ERR_UNEXPECTED_RSV_2_3"));
7119
+ return;
7120
+ }
7121
+ const compressed = (buf[0] & 64) === 64;
7122
+ if (compressed && !this._extensions[PerMessageDeflate.extensionName]) {
7123
+ cb(this.createError(RangeError, "RSV1 must be clear", true, 1002, "WS_ERR_UNEXPECTED_RSV_1"));
7124
+ return;
7125
+ }
7126
+ this._fin = (buf[0] & 128) === 128;
7127
+ this._opcode = buf[0] & 15;
7128
+ this._payloadLength = buf[1] & 127;
7129
+ if (this._opcode === 0) {
7130
+ if (compressed) {
7131
+ cb(this.createError(RangeError, "RSV1 must be clear", true, 1002, "WS_ERR_UNEXPECTED_RSV_1"));
7132
+ return;
7133
+ }
7134
+ if (!this._fragmented) {
7135
+ cb(this.createError(RangeError, "invalid opcode 0", true, 1002, "WS_ERR_INVALID_OPCODE"));
7136
+ return;
7137
+ }
7138
+ this._opcode = this._fragmented;
7139
+ } else if (this._opcode === 1 || this._opcode === 2) {
7140
+ if (this._fragmented) {
7141
+ cb(this.createError(RangeError, `invalid opcode ${this._opcode}`, true, 1002, "WS_ERR_INVALID_OPCODE"));
7142
+ return;
7143
+ }
7144
+ this._compressed = compressed;
7145
+ } else if (this._opcode > 7 && this._opcode < 11) {
7146
+ if (!this._fin) {
7147
+ cb(this.createError(RangeError, "FIN must be set", true, 1002, "WS_ERR_EXPECTED_FIN"));
7148
+ return;
7149
+ }
7150
+ if (compressed) {
7151
+ cb(this.createError(RangeError, "RSV1 must be clear", true, 1002, "WS_ERR_UNEXPECTED_RSV_1"));
7152
+ return;
7153
+ }
7154
+ if (this._payloadLength > 125 || this._opcode === 8 && this._payloadLength === 1) {
7155
+ cb(this.createError(RangeError, `invalid payload length ${this._payloadLength}`, true, 1002, "WS_ERR_INVALID_CONTROL_PAYLOAD_LENGTH"));
7156
+ return;
7157
+ }
7158
+ } else {
7159
+ cb(this.createError(RangeError, `invalid opcode ${this._opcode}`, true, 1002, "WS_ERR_INVALID_OPCODE"));
7160
+ return;
7161
+ }
7162
+ if (!this._fin && !this._fragmented) this._fragmented = this._opcode;
7163
+ this._masked = (buf[1] & 128) === 128;
7164
+ if (this._isServer) {
7165
+ if (!this._masked) {
7166
+ cb(this.createError(RangeError, "MASK must be set", true, 1002, "WS_ERR_EXPECTED_MASK"));
7167
+ return;
7168
+ }
7169
+ } else if (this._masked) {
7170
+ cb(this.createError(RangeError, "MASK must be clear", true, 1002, "WS_ERR_UNEXPECTED_MASK"));
7171
+ return;
7172
+ }
7173
+ if (this._payloadLength === 126) this._state = GET_PAYLOAD_LENGTH_16;
7174
+ else if (this._payloadLength === 127) this._state = GET_PAYLOAD_LENGTH_64;
7175
+ else this.haveLength(cb);
7176
+ }
7177
+ /**
7178
+ * Gets extended payload length (7+16).
7179
+ *
7180
+ * @param {Function} cb Callback
7181
+ * @private
7182
+ */
7183
+ getPayloadLength16(cb) {
7184
+ if (this._bufferedBytes < 2) {
7185
+ this._loop = false;
7186
+ return;
7187
+ }
7188
+ this._payloadLength = this.consume(2).readUInt16BE(0);
7189
+ this.haveLength(cb);
7190
+ }
7191
+ /**
7192
+ * Gets extended payload length (7+64).
7193
+ *
7194
+ * @param {Function} cb Callback
7195
+ * @private
7196
+ */
7197
+ getPayloadLength64(cb) {
7198
+ if (this._bufferedBytes < 8) {
7199
+ this._loop = false;
7200
+ return;
7201
+ }
7202
+ const buf = this.consume(8);
7203
+ const num = buf.readUInt32BE(0);
7204
+ if (num > Math.pow(2, 21) - 1) {
7205
+ cb(this.createError(RangeError, "Unsupported WebSocket frame: payload length > 2^53 - 1", false, 1009, "WS_ERR_UNSUPPORTED_DATA_PAYLOAD_LENGTH"));
7206
+ return;
7207
+ }
7208
+ this._payloadLength = num * Math.pow(2, 32) + buf.readUInt32BE(4);
7209
+ this.haveLength(cb);
7210
+ }
7211
+ /**
7212
+ * Payload length has been read.
7213
+ *
7214
+ * @param {Function} cb Callback
7215
+ * @private
7216
+ */
7217
+ haveLength(cb) {
7218
+ if (this._payloadLength && this._opcode < 8) {
7219
+ this._totalPayloadLength += this._payloadLength;
7220
+ if (this._totalPayloadLength > this._maxPayload && this._maxPayload > 0) {
7221
+ cb(this.createError(RangeError, "Max payload size exceeded", false, 1009, "WS_ERR_UNSUPPORTED_MESSAGE_LENGTH"));
7222
+ return;
7223
+ }
7224
+ }
7225
+ if (this._masked) this._state = GET_MASK;
7226
+ else this._state = GET_DATA;
7227
+ }
7228
+ /**
7229
+ * Reads mask bytes.
7230
+ *
7231
+ * @private
7232
+ */
7233
+ getMask() {
7234
+ if (this._bufferedBytes < 4) {
7235
+ this._loop = false;
7236
+ return;
7237
+ }
7238
+ this._mask = this.consume(4);
7239
+ this._state = GET_DATA;
7240
+ }
7241
+ /**
7242
+ * Reads data bytes.
7243
+ *
7244
+ * @param {Function} cb Callback
7245
+ * @private
7246
+ */
7247
+ getData(cb) {
7248
+ let data = EMPTY_BUFFER;
7249
+ if (this._payloadLength) {
7250
+ if (this._bufferedBytes < this._payloadLength) {
7251
+ this._loop = false;
7252
+ return;
7253
+ }
7254
+ data = this.consume(this._payloadLength);
7255
+ if (this._masked && (this._mask[0] | this._mask[1] | this._mask[2] | this._mask[3]) !== 0) unmask(data, this._mask);
7256
+ }
7257
+ if (this._opcode > 7) {
7258
+ this.controlMessage(data, cb);
7259
+ return;
7260
+ }
7261
+ if (this._compressed) {
7262
+ this._state = INFLATING;
7263
+ this.decompress(data, cb);
7264
+ return;
7265
+ }
7266
+ if (data.length) {
7267
+ this._messageLength = this._totalPayloadLength;
7268
+ this._fragments.push(data);
7269
+ }
7270
+ this.dataMessage(cb);
7271
+ }
7272
+ /**
7273
+ * Decompresses data.
7274
+ *
7275
+ * @param {Buffer} data Compressed data
7276
+ * @param {Function} cb Callback
7277
+ * @private
7278
+ */
7279
+ decompress(data, cb) {
7280
+ this._extensions[PerMessageDeflate.extensionName].decompress(data, this._fin, (err, buf) => {
7281
+ if (err) return cb(err);
7282
+ if (buf.length) {
7283
+ this._messageLength += buf.length;
7284
+ if (this._messageLength > this._maxPayload && this._maxPayload > 0) {
7285
+ cb(this.createError(RangeError, "Max payload size exceeded", false, 1009, "WS_ERR_UNSUPPORTED_MESSAGE_LENGTH"));
7286
+ return;
7287
+ }
7288
+ this._fragments.push(buf);
7289
+ }
7290
+ this.dataMessage(cb);
7291
+ if (this._state === GET_INFO) this.startLoop(cb);
7292
+ });
7293
+ }
7294
+ /**
7295
+ * Handles a data message.
7296
+ *
7297
+ * @param {Function} cb Callback
7298
+ * @private
7299
+ */
7300
+ dataMessage(cb) {
7301
+ if (!this._fin) {
7302
+ this._state = GET_INFO;
7303
+ return;
7304
+ }
7305
+ const messageLength = this._messageLength;
7306
+ const fragments = this._fragments;
7307
+ this._totalPayloadLength = 0;
7308
+ this._messageLength = 0;
7309
+ this._fragmented = 0;
7310
+ this._fragments = [];
7311
+ if (this._opcode === 2) {
7312
+ let data;
7313
+ if (this._binaryType === "nodebuffer") data = concat(fragments, messageLength);
7314
+ else if (this._binaryType === "arraybuffer") data = toArrayBuffer(concat(fragments, messageLength));
7315
+ else if (this._binaryType === "blob") data = new Blob(fragments);
7316
+ else data = fragments;
7317
+ if (this._allowSynchronousEvents) {
7318
+ this.emit("message", data, true);
7319
+ this._state = GET_INFO;
7320
+ } else {
7321
+ this._state = DEFER_EVENT;
7322
+ setImmediate(() => {
7323
+ this.emit("message", data, true);
7324
+ this._state = GET_INFO;
7325
+ this.startLoop(cb);
7326
+ });
7327
+ }
7328
+ } else {
7329
+ const buf = concat(fragments, messageLength);
7330
+ if (!this._skipUTF8Validation && !isValidUTF8(buf)) {
7331
+ cb(this.createError(Error, "invalid UTF-8 sequence", true, 1007, "WS_ERR_INVALID_UTF8"));
7332
+ return;
7333
+ }
7334
+ if (this._state === INFLATING || this._allowSynchronousEvents) {
7335
+ this.emit("message", buf, false);
7336
+ this._state = GET_INFO;
7337
+ } else {
7338
+ this._state = DEFER_EVENT;
7339
+ setImmediate(() => {
7340
+ this.emit("message", buf, false);
7341
+ this._state = GET_INFO;
7342
+ this.startLoop(cb);
7343
+ });
7344
+ }
7345
+ }
7346
+ }
7347
+ /**
7348
+ * Handles a control message.
7349
+ *
7350
+ * @param {Buffer} data Data to handle
7351
+ * @return {(Error|RangeError|undefined)} A possible error
7352
+ * @private
7353
+ */
7354
+ controlMessage(data, cb) {
7355
+ if (this._opcode === 8) {
7356
+ if (data.length === 0) {
7357
+ this._loop = false;
7358
+ this.emit("conclude", 1005, EMPTY_BUFFER);
7359
+ this.end();
7360
+ } else {
7361
+ const code = data.readUInt16BE(0);
7362
+ if (!isValidStatusCode(code)) {
7363
+ cb(this.createError(RangeError, `invalid status code ${code}`, true, 1002, "WS_ERR_INVALID_CLOSE_CODE"));
7364
+ return;
7365
+ }
7366
+ const buf = new FastBuffer(data.buffer, data.byteOffset + 2, data.length - 2);
7367
+ if (!this._skipUTF8Validation && !isValidUTF8(buf)) {
7368
+ cb(this.createError(Error, "invalid UTF-8 sequence", true, 1007, "WS_ERR_INVALID_UTF8"));
7369
+ return;
7370
+ }
7371
+ this._loop = false;
7372
+ this.emit("conclude", code, buf);
7373
+ this.end();
7374
+ }
7375
+ this._state = GET_INFO;
7376
+ return;
7377
+ }
7378
+ if (this._allowSynchronousEvents) {
7379
+ this.emit(this._opcode === 9 ? "ping" : "pong", data);
7380
+ this._state = GET_INFO;
7381
+ } else {
7382
+ this._state = DEFER_EVENT;
7383
+ setImmediate(() => {
7384
+ this.emit(this._opcode === 9 ? "ping" : "pong", data);
7385
+ this._state = GET_INFO;
7386
+ this.startLoop(cb);
7387
+ });
7388
+ }
7389
+ }
7390
+ /**
7391
+ * Builds an error object.
7392
+ *
7393
+ * @param {function(new:Error|RangeError)} ErrorCtor The error constructor
7394
+ * @param {String} message The error message
7395
+ * @param {Boolean} prefix Specifies whether or not to add a default prefix to
7396
+ * `message`
7397
+ * @param {Number} statusCode The status code
7398
+ * @param {String} errorCode The exposed error code
7399
+ * @return {(Error|RangeError)} The error
7400
+ * @private
7401
+ */
7402
+ createError(ErrorCtor, message, prefix, statusCode, errorCode) {
7403
+ this._loop = false;
7404
+ this._errored = true;
7405
+ const err = new ErrorCtor(prefix ? `Invalid WebSocket frame: ${message}` : message);
7406
+ Error.captureStackTrace(err, this.createError);
7407
+ err.code = errorCode;
7408
+ err[kStatusCode] = statusCode;
7409
+ return err;
7410
+ }
7411
+ };
7412
+ module.exports = Receiver;
7413
+ }));
7414
+
7415
+ //#endregion
7416
+ //#region node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/sender.js
7417
+ var require_sender = /* @__PURE__ */ __commonJSMin(((exports, module) => {
7418
+ const { Duplex: Duplex$3 } = __require("stream");
7419
+ const { randomFillSync } = __require("crypto");
7420
+ const PerMessageDeflate = require_permessage_deflate();
7421
+ const { EMPTY_BUFFER, kWebSocket, NOOP } = require_constants();
7422
+ const { isBlob, isValidStatusCode } = require_validation();
7423
+ const { mask: applyMask, toBuffer } = require_buffer_util();
7424
+ const kByteLength = Symbol("kByteLength");
7425
+ const maskBuffer = Buffer.alloc(4);
7426
+ const RANDOM_POOL_SIZE = 8 * 1024;
7427
+ let randomPool;
7428
+ let randomPoolPointer = RANDOM_POOL_SIZE;
7429
+ const DEFAULT = 0;
7430
+ const DEFLATING = 1;
7431
+ const GET_BLOB_DATA = 2;
7432
+ /**
7433
+ * HyBi Sender implementation.
7434
+ */
7435
+ var Sender = class Sender {
7436
+ /**
7437
+ * Creates a Sender instance.
7438
+ *
7439
+ * @param {Duplex} socket The connection socket
7440
+ * @param {Object} [extensions] An object containing the negotiated extensions
7441
+ * @param {Function} [generateMask] The function used to generate the masking
7442
+ * key
7443
+ */
7444
+ constructor(socket, extensions, generateMask) {
7445
+ this._extensions = extensions || {};
7446
+ if (generateMask) {
7447
+ this._generateMask = generateMask;
7448
+ this._maskBuffer = Buffer.alloc(4);
7449
+ }
7450
+ this._socket = socket;
7451
+ this._firstFragment = true;
7452
+ this._compress = false;
7453
+ this._bufferedBytes = 0;
7454
+ this._queue = [];
7455
+ this._state = DEFAULT;
7456
+ this.onerror = NOOP;
7457
+ this[kWebSocket] = void 0;
7458
+ }
7459
+ /**
7460
+ * Frames a piece of data according to the HyBi WebSocket protocol.
7461
+ *
7462
+ * @param {(Buffer|String)} data The data to frame
7463
+ * @param {Object} options Options object
7464
+ * @param {Boolean} [options.fin=false] Specifies whether or not to set the
7465
+ * FIN bit
7466
+ * @param {Function} [options.generateMask] The function used to generate the
7467
+ * masking key
7468
+ * @param {Boolean} [options.mask=false] Specifies whether or not to mask
7469
+ * `data`
7470
+ * @param {Buffer} [options.maskBuffer] The buffer used to store the masking
7471
+ * key
7472
+ * @param {Number} options.opcode The opcode
7473
+ * @param {Boolean} [options.readOnly=false] Specifies whether `data` can be
7474
+ * modified
7475
+ * @param {Boolean} [options.rsv1=false] Specifies whether or not to set the
7476
+ * RSV1 bit
7477
+ * @return {(Buffer|String)[]} The framed data
7478
+ * @public
7479
+ */
7480
+ static frame(data, options) {
7481
+ let mask;
7482
+ let merge = false;
7483
+ let offset = 2;
7484
+ let skipMasking = false;
7485
+ if (options.mask) {
7486
+ mask = options.maskBuffer || maskBuffer;
7487
+ if (options.generateMask) options.generateMask(mask);
7488
+ else {
7489
+ if (randomPoolPointer === RANDOM_POOL_SIZE) {
7490
+ /* istanbul ignore else */
7491
+ if (randomPool === void 0) randomPool = Buffer.alloc(RANDOM_POOL_SIZE);
7492
+ randomFillSync(randomPool, 0, RANDOM_POOL_SIZE);
7493
+ randomPoolPointer = 0;
7494
+ }
7495
+ mask[0] = randomPool[randomPoolPointer++];
7496
+ mask[1] = randomPool[randomPoolPointer++];
7497
+ mask[2] = randomPool[randomPoolPointer++];
7498
+ mask[3] = randomPool[randomPoolPointer++];
7499
+ }
7500
+ skipMasking = (mask[0] | mask[1] | mask[2] | mask[3]) === 0;
7501
+ offset = 6;
7502
+ }
7503
+ let dataLength;
7504
+ if (typeof data === "string") if ((!options.mask || skipMasking) && options[kByteLength] !== void 0) dataLength = options[kByteLength];
7505
+ else {
7506
+ data = Buffer.from(data);
7507
+ dataLength = data.length;
7508
+ }
7509
+ else {
7510
+ dataLength = data.length;
7511
+ merge = options.mask && options.readOnly && !skipMasking;
7512
+ }
7513
+ let payloadLength = dataLength;
7514
+ if (dataLength >= 65536) {
7515
+ offset += 8;
7516
+ payloadLength = 127;
7517
+ } else if (dataLength > 125) {
7518
+ offset += 2;
7519
+ payloadLength = 126;
7520
+ }
7521
+ const target = Buffer.allocUnsafe(merge ? dataLength + offset : offset);
7522
+ target[0] = options.fin ? options.opcode | 128 : options.opcode;
7523
+ if (options.rsv1) target[0] |= 64;
7524
+ target[1] = payloadLength;
7525
+ if (payloadLength === 126) target.writeUInt16BE(dataLength, 2);
7526
+ else if (payloadLength === 127) {
7527
+ target[2] = target[3] = 0;
7528
+ target.writeUIntBE(dataLength, 4, 6);
7529
+ }
7530
+ if (!options.mask) return [target, data];
7531
+ target[1] |= 128;
7532
+ target[offset - 4] = mask[0];
7533
+ target[offset - 3] = mask[1];
7534
+ target[offset - 2] = mask[2];
7535
+ target[offset - 1] = mask[3];
7536
+ if (skipMasking) return [target, data];
7537
+ if (merge) {
7538
+ applyMask(data, mask, target, offset, dataLength);
7539
+ return [target];
7540
+ }
7541
+ applyMask(data, mask, data, 0, dataLength);
7542
+ return [target, data];
7543
+ }
7544
+ /**
7545
+ * Sends a close message to the other peer.
7546
+ *
7547
+ * @param {Number} [code] The status code component of the body
7548
+ * @param {(String|Buffer)} [data] The message component of the body
7549
+ * @param {Boolean} [mask=false] Specifies whether or not to mask the message
7550
+ * @param {Function} [cb] Callback
7551
+ * @public
7552
+ */
7553
+ close(code, data, mask, cb) {
7554
+ let buf;
7555
+ if (code === void 0) buf = EMPTY_BUFFER;
7556
+ else if (typeof code !== "number" || !isValidStatusCode(code)) throw new TypeError("First argument must be a valid error code number");
7557
+ else if (data === void 0 || !data.length) {
7558
+ buf = Buffer.allocUnsafe(2);
7559
+ buf.writeUInt16BE(code, 0);
7560
+ } else {
7561
+ const length = Buffer.byteLength(data);
7562
+ if (length > 123) throw new RangeError("The message must not be greater than 123 bytes");
7563
+ buf = Buffer.allocUnsafe(2 + length);
7564
+ buf.writeUInt16BE(code, 0);
7565
+ if (typeof data === "string") buf.write(data, 2);
7566
+ else buf.set(data, 2);
7567
+ }
7568
+ const options = {
7569
+ [kByteLength]: buf.length,
7570
+ fin: true,
7571
+ generateMask: this._generateMask,
7572
+ mask,
7573
+ maskBuffer: this._maskBuffer,
7574
+ opcode: 8,
7575
+ readOnly: false,
7576
+ rsv1: false
7577
+ };
7578
+ if (this._state !== DEFAULT) this.enqueue([
7579
+ this.dispatch,
7580
+ buf,
7581
+ false,
7582
+ options,
7583
+ cb
7584
+ ]);
7585
+ else this.sendFrame(Sender.frame(buf, options), cb);
7586
+ }
7587
+ /**
7588
+ * Sends a ping message to the other peer.
7589
+ *
7590
+ * @param {*} data The message to send
7591
+ * @param {Boolean} [mask=false] Specifies whether or not to mask `data`
7592
+ * @param {Function} [cb] Callback
7593
+ * @public
7594
+ */
7595
+ ping(data, mask, cb) {
7596
+ let byteLength;
7597
+ let readOnly;
7598
+ if (typeof data === "string") {
7599
+ byteLength = Buffer.byteLength(data);
7600
+ readOnly = false;
7601
+ } else if (isBlob(data)) {
7602
+ byteLength = data.size;
7603
+ readOnly = false;
7604
+ } else {
7605
+ data = toBuffer(data);
7606
+ byteLength = data.length;
7607
+ readOnly = toBuffer.readOnly;
7608
+ }
7609
+ if (byteLength > 125) throw new RangeError("The data size must not be greater than 125 bytes");
7610
+ const options = {
7611
+ [kByteLength]: byteLength,
7612
+ fin: true,
7613
+ generateMask: this._generateMask,
7614
+ mask,
7615
+ maskBuffer: this._maskBuffer,
7616
+ opcode: 9,
7617
+ readOnly,
7618
+ rsv1: false
7619
+ };
7620
+ if (isBlob(data)) if (this._state !== DEFAULT) this.enqueue([
7621
+ this.getBlobData,
7622
+ data,
7623
+ false,
7624
+ options,
7625
+ cb
7626
+ ]);
7627
+ else this.getBlobData(data, false, options, cb);
7628
+ else if (this._state !== DEFAULT) this.enqueue([
7629
+ this.dispatch,
7630
+ data,
7631
+ false,
7632
+ options,
7633
+ cb
7634
+ ]);
7635
+ else this.sendFrame(Sender.frame(data, options), cb);
7636
+ }
7637
+ /**
7638
+ * Sends a pong message to the other peer.
7639
+ *
7640
+ * @param {*} data The message to send
7641
+ * @param {Boolean} [mask=false] Specifies whether or not to mask `data`
7642
+ * @param {Function} [cb] Callback
7643
+ * @public
7644
+ */
7645
+ pong(data, mask, cb) {
7646
+ let byteLength;
7647
+ let readOnly;
7648
+ if (typeof data === "string") {
7649
+ byteLength = Buffer.byteLength(data);
7650
+ readOnly = false;
7651
+ } else if (isBlob(data)) {
7652
+ byteLength = data.size;
7653
+ readOnly = false;
7654
+ } else {
7655
+ data = toBuffer(data);
7656
+ byteLength = data.length;
7657
+ readOnly = toBuffer.readOnly;
7658
+ }
7659
+ if (byteLength > 125) throw new RangeError("The data size must not be greater than 125 bytes");
7660
+ const options = {
7661
+ [kByteLength]: byteLength,
7662
+ fin: true,
7663
+ generateMask: this._generateMask,
7664
+ mask,
7665
+ maskBuffer: this._maskBuffer,
7666
+ opcode: 10,
7667
+ readOnly,
7668
+ rsv1: false
7669
+ };
7670
+ if (isBlob(data)) if (this._state !== DEFAULT) this.enqueue([
7671
+ this.getBlobData,
7672
+ data,
7673
+ false,
7674
+ options,
7675
+ cb
7676
+ ]);
7677
+ else this.getBlobData(data, false, options, cb);
7678
+ else if (this._state !== DEFAULT) this.enqueue([
7679
+ this.dispatch,
7680
+ data,
7681
+ false,
7682
+ options,
7683
+ cb
7684
+ ]);
7685
+ else this.sendFrame(Sender.frame(data, options), cb);
7686
+ }
7687
+ /**
7688
+ * Sends a data message to the other peer.
7689
+ *
7690
+ * @param {*} data The message to send
7691
+ * @param {Object} options Options object
7692
+ * @param {Boolean} [options.binary=false] Specifies whether `data` is binary
7693
+ * or text
7694
+ * @param {Boolean} [options.compress=false] Specifies whether or not to
7695
+ * compress `data`
7696
+ * @param {Boolean} [options.fin=false] Specifies whether the fragment is the
7697
+ * last one
7698
+ * @param {Boolean} [options.mask=false] Specifies whether or not to mask
7699
+ * `data`
7700
+ * @param {Function} [cb] Callback
7701
+ * @public
7702
+ */
7703
+ send(data, options, cb) {
7704
+ const perMessageDeflate = this._extensions[PerMessageDeflate.extensionName];
7705
+ let opcode = options.binary ? 2 : 1;
7706
+ let rsv1 = options.compress;
7707
+ let byteLength;
7708
+ let readOnly;
7709
+ if (typeof data === "string") {
7710
+ byteLength = Buffer.byteLength(data);
7711
+ readOnly = false;
7712
+ } else if (isBlob(data)) {
7713
+ byteLength = data.size;
7714
+ readOnly = false;
7715
+ } else {
7716
+ data = toBuffer(data);
7717
+ byteLength = data.length;
7718
+ readOnly = toBuffer.readOnly;
7719
+ }
7720
+ if (this._firstFragment) {
7721
+ this._firstFragment = false;
7722
+ if (rsv1 && perMessageDeflate && perMessageDeflate.params[perMessageDeflate._isServer ? "server_no_context_takeover" : "client_no_context_takeover"]) rsv1 = byteLength >= perMessageDeflate._threshold;
7723
+ this._compress = rsv1;
7724
+ } else {
7725
+ rsv1 = false;
7726
+ opcode = 0;
7727
+ }
7728
+ if (options.fin) this._firstFragment = true;
7729
+ const opts = {
7730
+ [kByteLength]: byteLength,
7731
+ fin: options.fin,
7732
+ generateMask: this._generateMask,
7733
+ mask: options.mask,
7734
+ maskBuffer: this._maskBuffer,
7735
+ opcode,
7736
+ readOnly,
7737
+ rsv1
7738
+ };
7739
+ if (isBlob(data)) if (this._state !== DEFAULT) this.enqueue([
7740
+ this.getBlobData,
7741
+ data,
7742
+ this._compress,
7743
+ opts,
7744
+ cb
7745
+ ]);
7746
+ else this.getBlobData(data, this._compress, opts, cb);
7747
+ else if (this._state !== DEFAULT) this.enqueue([
7748
+ this.dispatch,
7749
+ data,
7750
+ this._compress,
7751
+ opts,
7752
+ cb
7753
+ ]);
7754
+ else this.dispatch(data, this._compress, opts, cb);
7755
+ }
7756
+ /**
7757
+ * Gets the contents of a blob as binary data.
7758
+ *
7759
+ * @param {Blob} blob The blob
7760
+ * @param {Boolean} [compress=false] Specifies whether or not to compress
7761
+ * the data
7762
+ * @param {Object} options Options object
7763
+ * @param {Boolean} [options.fin=false] Specifies whether or not to set the
7764
+ * FIN bit
7765
+ * @param {Function} [options.generateMask] The function used to generate the
7766
+ * masking key
7767
+ * @param {Boolean} [options.mask=false] Specifies whether or not to mask
7768
+ * `data`
7769
+ * @param {Buffer} [options.maskBuffer] The buffer used to store the masking
7770
+ * key
7771
+ * @param {Number} options.opcode The opcode
7772
+ * @param {Boolean} [options.readOnly=false] Specifies whether `data` can be
7773
+ * modified
7774
+ * @param {Boolean} [options.rsv1=false] Specifies whether or not to set the
7775
+ * RSV1 bit
7776
+ * @param {Function} [cb] Callback
7777
+ * @private
7778
+ */
7779
+ getBlobData(blob, compress, options, cb) {
7780
+ this._bufferedBytes += options[kByteLength];
7781
+ this._state = GET_BLOB_DATA;
7782
+ blob.arrayBuffer().then((arrayBuffer) => {
7783
+ if (this._socket.destroyed) {
7784
+ const err = /* @__PURE__ */ new Error("The socket was closed while the blob was being read");
7785
+ process.nextTick(callCallbacks, this, err, cb);
7786
+ return;
7787
+ }
7788
+ this._bufferedBytes -= options[kByteLength];
7789
+ const data = toBuffer(arrayBuffer);
7790
+ if (!compress) {
7791
+ this._state = DEFAULT;
7792
+ this.sendFrame(Sender.frame(data, options), cb);
7793
+ this.dequeue();
7794
+ } else this.dispatch(data, compress, options, cb);
7795
+ }).catch((err) => {
7796
+ process.nextTick(onError, this, err, cb);
7797
+ });
7798
+ }
7799
+ /**
7800
+ * Dispatches a message.
7801
+ *
7802
+ * @param {(Buffer|String)} data The message to send
7803
+ * @param {Boolean} [compress=false] Specifies whether or not to compress
7804
+ * `data`
7805
+ * @param {Object} options Options object
7806
+ * @param {Boolean} [options.fin=false] Specifies whether or not to set the
7807
+ * FIN bit
7808
+ * @param {Function} [options.generateMask] The function used to generate the
7809
+ * masking key
7810
+ * @param {Boolean} [options.mask=false] Specifies whether or not to mask
7811
+ * `data`
7812
+ * @param {Buffer} [options.maskBuffer] The buffer used to store the masking
7813
+ * key
7814
+ * @param {Number} options.opcode The opcode
7815
+ * @param {Boolean} [options.readOnly=false] Specifies whether `data` can be
7816
+ * modified
7817
+ * @param {Boolean} [options.rsv1=false] Specifies whether or not to set the
7818
+ * RSV1 bit
7819
+ * @param {Function} [cb] Callback
7820
+ * @private
7821
+ */
7822
+ dispatch(data, compress, options, cb) {
7823
+ if (!compress) {
7824
+ this.sendFrame(Sender.frame(data, options), cb);
7825
+ return;
7826
+ }
7827
+ const perMessageDeflate = this._extensions[PerMessageDeflate.extensionName];
7828
+ this._bufferedBytes += options[kByteLength];
7829
+ this._state = DEFLATING;
7830
+ perMessageDeflate.compress(data, options.fin, (_, buf) => {
7831
+ if (this._socket.destroyed) {
7832
+ callCallbacks(this, /* @__PURE__ */ new Error("The socket was closed while data was being compressed"), cb);
7833
+ return;
7834
+ }
7835
+ this._bufferedBytes -= options[kByteLength];
7836
+ this._state = DEFAULT;
7837
+ options.readOnly = false;
7838
+ this.sendFrame(Sender.frame(buf, options), cb);
7839
+ this.dequeue();
7840
+ });
7841
+ }
7842
+ /**
7843
+ * Executes queued send operations.
7844
+ *
7845
+ * @private
7846
+ */
7847
+ dequeue() {
7848
+ while (this._state === DEFAULT && this._queue.length) {
7849
+ const params = this._queue.shift();
7850
+ this._bufferedBytes -= params[3][kByteLength];
7851
+ Reflect.apply(params[0], this, params.slice(1));
7852
+ }
7853
+ }
7854
+ /**
7855
+ * Enqueues a send operation.
7856
+ *
7857
+ * @param {Array} params Send operation parameters.
7858
+ * @private
7859
+ */
7860
+ enqueue(params) {
7861
+ this._bufferedBytes += params[3][kByteLength];
7862
+ this._queue.push(params);
7863
+ }
7864
+ /**
7865
+ * Sends a frame.
7866
+ *
7867
+ * @param {(Buffer | String)[]} list The frame to send
7868
+ * @param {Function} [cb] Callback
7869
+ * @private
7870
+ */
7871
+ sendFrame(list, cb) {
7872
+ if (list.length === 2) {
7873
+ this._socket.cork();
7874
+ this._socket.write(list[0]);
7875
+ this._socket.write(list[1], cb);
7876
+ this._socket.uncork();
7877
+ } else this._socket.write(list[0], cb);
7878
+ }
7879
+ };
7880
+ module.exports = Sender;
7881
+ /**
7882
+ * Calls queued callbacks with an error.
7883
+ *
7884
+ * @param {Sender} sender The `Sender` instance
7885
+ * @param {Error} err The error to call the callbacks with
7886
+ * @param {Function} [cb] The first callback
7887
+ * @private
7888
+ */
7889
+ function callCallbacks(sender, err, cb) {
7890
+ if (typeof cb === "function") cb(err);
7891
+ for (let i = 0; i < sender._queue.length; i++) {
7892
+ const params = sender._queue[i];
7893
+ const callback = params[params.length - 1];
7894
+ if (typeof callback === "function") callback(err);
7895
+ }
7896
+ }
7897
+ /**
7898
+ * Handles a `Sender` error.
7899
+ *
7900
+ * @param {Sender} sender The `Sender` instance
7901
+ * @param {Error} err The error
7902
+ * @param {Function} [cb] The first pending callback
7903
+ * @private
7904
+ */
7905
+ function onError(sender, err, cb) {
7906
+ callCallbacks(sender, err, cb);
7907
+ sender.onerror(err);
7908
+ }
7909
+ }));
7910
+
7911
+ //#endregion
7912
+ //#region node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/event-target.js
7913
+ var require_event_target = /* @__PURE__ */ __commonJSMin(((exports, module) => {
7914
+ const { kForOnEventAttribute, kListener } = require_constants();
7915
+ const kCode = Symbol("kCode");
7916
+ const kData = Symbol("kData");
7917
+ const kError = Symbol("kError");
7918
+ const kMessage = Symbol("kMessage");
7919
+ const kReason = Symbol("kReason");
7920
+ const kTarget = Symbol("kTarget");
7921
+ const kType = Symbol("kType");
7922
+ const kWasClean = Symbol("kWasClean");
7923
+ /**
7924
+ * Class representing an event.
7925
+ */
7926
+ var Event = class {
7927
+ /**
7928
+ * Create a new `Event`.
7929
+ *
7930
+ * @param {String} type The name of the event
7931
+ * @throws {TypeError} If the `type` argument is not specified
7932
+ */
7933
+ constructor(type) {
7934
+ this[kTarget] = null;
7935
+ this[kType] = type;
7936
+ }
7937
+ /**
7938
+ * @type {*}
7939
+ */
7940
+ get target() {
7941
+ return this[kTarget];
7942
+ }
7943
+ /**
7944
+ * @type {String}
7945
+ */
7946
+ get type() {
7947
+ return this[kType];
7948
+ }
7949
+ };
7950
+ Object.defineProperty(Event.prototype, "target", { enumerable: true });
7951
+ Object.defineProperty(Event.prototype, "type", { enumerable: true });
7952
+ /**
7953
+ * Class representing a close event.
7954
+ *
7955
+ * @extends Event
7956
+ */
7957
+ var CloseEvent = class extends Event {
7958
+ /**
7959
+ * Create a new `CloseEvent`.
7960
+ *
7961
+ * @param {String} type The name of the event
7962
+ * @param {Object} [options] A dictionary object that allows for setting
7963
+ * attributes via object members of the same name
7964
+ * @param {Number} [options.code=0] The status code explaining why the
7965
+ * connection was closed
7966
+ * @param {String} [options.reason=''] A human-readable string explaining why
7967
+ * the connection was closed
7968
+ * @param {Boolean} [options.wasClean=false] Indicates whether or not the
7969
+ * connection was cleanly closed
7970
+ */
7971
+ constructor(type, options = {}) {
7972
+ super(type);
7973
+ this[kCode] = options.code === void 0 ? 0 : options.code;
7974
+ this[kReason] = options.reason === void 0 ? "" : options.reason;
7975
+ this[kWasClean] = options.wasClean === void 0 ? false : options.wasClean;
7976
+ }
7977
+ /**
7978
+ * @type {Number}
7979
+ */
7980
+ get code() {
7981
+ return this[kCode];
7982
+ }
7983
+ /**
7984
+ * @type {String}
7985
+ */
7986
+ get reason() {
7987
+ return this[kReason];
7988
+ }
7989
+ /**
7990
+ * @type {Boolean}
7991
+ */
7992
+ get wasClean() {
7993
+ return this[kWasClean];
7994
+ }
7995
+ };
7996
+ Object.defineProperty(CloseEvent.prototype, "code", { enumerable: true });
7997
+ Object.defineProperty(CloseEvent.prototype, "reason", { enumerable: true });
7998
+ Object.defineProperty(CloseEvent.prototype, "wasClean", { enumerable: true });
7999
+ /**
8000
+ * Class representing an error event.
8001
+ *
8002
+ * @extends Event
8003
+ */
8004
+ var ErrorEvent = class extends Event {
8005
+ /**
8006
+ * Create a new `ErrorEvent`.
8007
+ *
8008
+ * @param {String} type The name of the event
8009
+ * @param {Object} [options] A dictionary object that allows for setting
8010
+ * attributes via object members of the same name
8011
+ * @param {*} [options.error=null] The error that generated this event
8012
+ * @param {String} [options.message=''] The error message
8013
+ */
8014
+ constructor(type, options = {}) {
8015
+ super(type);
8016
+ this[kError] = options.error === void 0 ? null : options.error;
8017
+ this[kMessage] = options.message === void 0 ? "" : options.message;
8018
+ }
8019
+ /**
8020
+ * @type {*}
8021
+ */
8022
+ get error() {
8023
+ return this[kError];
8024
+ }
8025
+ /**
8026
+ * @type {String}
8027
+ */
8028
+ get message() {
8029
+ return this[kMessage];
8030
+ }
8031
+ };
8032
+ Object.defineProperty(ErrorEvent.prototype, "error", { enumerable: true });
8033
+ Object.defineProperty(ErrorEvent.prototype, "message", { enumerable: true });
8034
+ /**
8035
+ * Class representing a message event.
8036
+ *
8037
+ * @extends Event
8038
+ */
8039
+ var MessageEvent = class extends Event {
8040
+ /**
8041
+ * Create a new `MessageEvent`.
8042
+ *
8043
+ * @param {String} type The name of the event
8044
+ * @param {Object} [options] A dictionary object that allows for setting
8045
+ * attributes via object members of the same name
8046
+ * @param {*} [options.data=null] The message content
8047
+ */
8048
+ constructor(type, options = {}) {
8049
+ super(type);
8050
+ this[kData] = options.data === void 0 ? null : options.data;
8051
+ }
8052
+ /**
8053
+ * @type {*}
8054
+ */
8055
+ get data() {
8056
+ return this[kData];
8057
+ }
8058
+ };
8059
+ Object.defineProperty(MessageEvent.prototype, "data", { enumerable: true });
8060
+ /**
8061
+ * This provides methods for emulating the `EventTarget` interface. It's not
8062
+ * meant to be used directly.
8063
+ *
8064
+ * @mixin
8065
+ */
8066
+ const EventTarget = {
8067
+ addEventListener(type, handler, options = {}) {
8068
+ for (const listener of this.listeners(type)) if (!options[kForOnEventAttribute] && listener[kListener] === handler && !listener[kForOnEventAttribute]) return;
8069
+ let wrapper;
8070
+ if (type === "message") wrapper = function onMessage(data, isBinary) {
8071
+ const event = new MessageEvent("message", { data: isBinary ? data : data.toString() });
8072
+ event[kTarget] = this;
8073
+ callListener(handler, this, event);
8074
+ };
8075
+ else if (type === "close") wrapper = function onClose(code, message) {
8076
+ const event = new CloseEvent("close", {
8077
+ code,
8078
+ reason: message.toString(),
8079
+ wasClean: this._closeFrameReceived && this._closeFrameSent
8080
+ });
8081
+ event[kTarget] = this;
8082
+ callListener(handler, this, event);
8083
+ };
8084
+ else if (type === "error") wrapper = function onError(error) {
8085
+ const event = new ErrorEvent("error", {
8086
+ error,
8087
+ message: error.message
8088
+ });
8089
+ event[kTarget] = this;
8090
+ callListener(handler, this, event);
8091
+ };
8092
+ else if (type === "open") wrapper = function onOpen() {
8093
+ const event = new Event("open");
8094
+ event[kTarget] = this;
8095
+ callListener(handler, this, event);
8096
+ };
8097
+ else return;
8098
+ wrapper[kForOnEventAttribute] = !!options[kForOnEventAttribute];
8099
+ wrapper[kListener] = handler;
8100
+ if (options.once) this.once(type, wrapper);
8101
+ else this.on(type, wrapper);
8102
+ },
8103
+ removeEventListener(type, handler) {
8104
+ for (const listener of this.listeners(type)) if (listener[kListener] === handler && !listener[kForOnEventAttribute]) {
8105
+ this.removeListener(type, listener);
8106
+ break;
8107
+ }
8108
+ }
8109
+ };
8110
+ module.exports = {
8111
+ CloseEvent,
8112
+ ErrorEvent,
8113
+ Event,
8114
+ EventTarget,
8115
+ MessageEvent
8116
+ };
8117
+ /**
8118
+ * Call an event listener
8119
+ *
8120
+ * @param {(Function|Object)} listener The listener to call
8121
+ * @param {*} thisArg The value to use as `this`` when calling the listener
8122
+ * @param {Event} event The event to pass to the listener
8123
+ * @private
8124
+ */
8125
+ function callListener(listener, thisArg, event) {
8126
+ if (typeof listener === "object" && listener.handleEvent) listener.handleEvent.call(listener, event);
8127
+ else listener.call(thisArg, event);
8128
+ }
8129
+ }));
8130
+
8131
+ //#endregion
8132
+ //#region node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/extension.js
8133
+ var require_extension = /* @__PURE__ */ __commonJSMin(((exports, module) => {
8134
+ const { tokenChars } = require_validation();
8135
+ /**
8136
+ * Adds an offer to the map of extension offers or a parameter to the map of
8137
+ * parameters.
8138
+ *
8139
+ * @param {Object} dest The map of extension offers or parameters
8140
+ * @param {String} name The extension or parameter name
8141
+ * @param {(Object|Boolean|String)} elem The extension parameters or the
8142
+ * parameter value
8143
+ * @private
8144
+ */
8145
+ function push(dest, name, elem) {
8146
+ if (dest[name] === void 0) dest[name] = [elem];
8147
+ else dest[name].push(elem);
8148
+ }
8149
+ /**
8150
+ * Parses the `Sec-WebSocket-Extensions` header into an object.
8151
+ *
8152
+ * @param {String} header The field value of the header
8153
+ * @return {Object} The parsed object
8154
+ * @public
8155
+ */
8156
+ function parse(header) {
8157
+ const offers = Object.create(null);
8158
+ let params = Object.create(null);
8159
+ let mustUnescape = false;
8160
+ let isEscaping = false;
8161
+ let inQuotes = false;
8162
+ let extensionName;
8163
+ let paramName;
8164
+ let start = -1;
8165
+ let code = -1;
8166
+ let end = -1;
8167
+ let i = 0;
8168
+ for (; i < header.length; i++) {
8169
+ code = header.charCodeAt(i);
8170
+ if (extensionName === void 0) if (end === -1 && tokenChars[code] === 1) {
8171
+ if (start === -1) start = i;
8172
+ } else if (i !== 0 && (code === 32 || code === 9)) {
8173
+ if (end === -1 && start !== -1) end = i;
8174
+ } else if (code === 59 || code === 44) {
8175
+ if (start === -1) throw new SyntaxError(`Unexpected character at index ${i}`);
8176
+ if (end === -1) end = i;
8177
+ const name = header.slice(start, end);
8178
+ if (code === 44) {
8179
+ push(offers, name, params);
8180
+ params = Object.create(null);
8181
+ } else extensionName = name;
8182
+ start = end = -1;
8183
+ } else throw new SyntaxError(`Unexpected character at index ${i}`);
8184
+ else if (paramName === void 0) if (end === -1 && tokenChars[code] === 1) {
8185
+ if (start === -1) start = i;
8186
+ } else if (code === 32 || code === 9) {
8187
+ if (end === -1 && start !== -1) end = i;
8188
+ } else if (code === 59 || code === 44) {
8189
+ if (start === -1) throw new SyntaxError(`Unexpected character at index ${i}`);
8190
+ if (end === -1) end = i;
8191
+ push(params, header.slice(start, end), true);
8192
+ if (code === 44) {
8193
+ push(offers, extensionName, params);
8194
+ params = Object.create(null);
8195
+ extensionName = void 0;
8196
+ }
8197
+ start = end = -1;
8198
+ } else if (code === 61 && start !== -1 && end === -1) {
8199
+ paramName = header.slice(start, i);
8200
+ start = end = -1;
8201
+ } else throw new SyntaxError(`Unexpected character at index ${i}`);
8202
+ else if (isEscaping) {
8203
+ if (tokenChars[code] !== 1) throw new SyntaxError(`Unexpected character at index ${i}`);
8204
+ if (start === -1) start = i;
8205
+ else if (!mustUnescape) mustUnescape = true;
8206
+ isEscaping = false;
8207
+ } else if (inQuotes) if (tokenChars[code] === 1) {
8208
+ if (start === -1) start = i;
8209
+ } else if (code === 34 && start !== -1) {
8210
+ inQuotes = false;
8211
+ end = i;
8212
+ } else if (code === 92) isEscaping = true;
8213
+ else throw new SyntaxError(`Unexpected character at index ${i}`);
8214
+ else if (code === 34 && header.charCodeAt(i - 1) === 61) inQuotes = true;
8215
+ else if (end === -1 && tokenChars[code] === 1) {
8216
+ if (start === -1) start = i;
8217
+ } else if (start !== -1 && (code === 32 || code === 9)) {
8218
+ if (end === -1) end = i;
8219
+ } else if (code === 59 || code === 44) {
8220
+ if (start === -1) throw new SyntaxError(`Unexpected character at index ${i}`);
8221
+ if (end === -1) end = i;
8222
+ let value = header.slice(start, end);
8223
+ if (mustUnescape) {
8224
+ value = value.replace(/\\/g, "");
8225
+ mustUnescape = false;
8226
+ }
8227
+ push(params, paramName, value);
8228
+ if (code === 44) {
8229
+ push(offers, extensionName, params);
8230
+ params = Object.create(null);
8231
+ extensionName = void 0;
8232
+ }
8233
+ paramName = void 0;
8234
+ start = end = -1;
8235
+ } else throw new SyntaxError(`Unexpected character at index ${i}`);
8236
+ }
8237
+ if (start === -1 || inQuotes || code === 32 || code === 9) throw new SyntaxError("Unexpected end of input");
8238
+ if (end === -1) end = i;
8239
+ const token = header.slice(start, end);
8240
+ if (extensionName === void 0) push(offers, token, params);
8241
+ else {
8242
+ if (paramName === void 0) push(params, token, true);
8243
+ else if (mustUnescape) push(params, paramName, token.replace(/\\/g, ""));
8244
+ else push(params, paramName, token);
8245
+ push(offers, extensionName, params);
8246
+ }
8247
+ return offers;
8248
+ }
8249
+ /**
8250
+ * Builds the `Sec-WebSocket-Extensions` header field value.
8251
+ *
8252
+ * @param {Object} extensions The map of extensions and parameters to format
8253
+ * @return {String} A string representing the given object
8254
+ * @public
8255
+ */
8256
+ function format(extensions) {
8257
+ return Object.keys(extensions).map((extension) => {
8258
+ let configurations = extensions[extension];
8259
+ if (!Array.isArray(configurations)) configurations = [configurations];
8260
+ return configurations.map((params) => {
8261
+ return [extension].concat(Object.keys(params).map((k) => {
8262
+ let values = params[k];
8263
+ if (!Array.isArray(values)) values = [values];
8264
+ return values.map((v) => v === true ? k : `${k}=${v}`).join("; ");
8265
+ })).join("; ");
8266
+ }).join(", ");
8267
+ }).join(", ");
8268
+ }
8269
+ module.exports = {
8270
+ format,
8271
+ parse
8272
+ };
8273
+ }));
8274
+
8275
+ //#endregion
8276
+ //#region node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/websocket.js
8277
+ var require_websocket = /* @__PURE__ */ __commonJSMin(((exports, module) => {
8278
+ const EventEmitter$2 = __require("events");
8279
+ const https = __require("https");
8280
+ const http$1 = __require("http");
8281
+ const net = __require("net");
8282
+ const tls = __require("tls");
8283
+ const { randomBytes, createHash: createHash$1 } = __require("crypto");
8284
+ const { Duplex: Duplex$2, Readable } = __require("stream");
8285
+ const { URL } = __require("url");
8286
+ const PerMessageDeflate = require_permessage_deflate();
8287
+ const Receiver = require_receiver();
8288
+ const Sender = require_sender();
8289
+ const { isBlob } = require_validation();
8290
+ const { BINARY_TYPES, CLOSE_TIMEOUT, EMPTY_BUFFER, GUID, kForOnEventAttribute, kListener, kStatusCode, kWebSocket, NOOP } = require_constants();
8291
+ const { EventTarget: { addEventListener, removeEventListener } } = require_event_target();
8292
+ const { format, parse } = require_extension();
8293
+ const { toBuffer } = require_buffer_util();
8294
+ const kAborted = Symbol("kAborted");
8295
+ const protocolVersions = [8, 13];
8296
+ const readyStates = [
8297
+ "CONNECTING",
8298
+ "OPEN",
8299
+ "CLOSING",
8300
+ "CLOSED"
8301
+ ];
8302
+ const subprotocolRegex = /^[!#$%&'*+\-.0-9A-Z^_`|a-z~]+$/;
8303
+ /**
8304
+ * Class representing a WebSocket.
8305
+ *
8306
+ * @extends EventEmitter
8307
+ */
8308
+ var WebSocket = class WebSocket extends EventEmitter$2 {
8309
+ /**
8310
+ * Create a new `WebSocket`.
8311
+ *
8312
+ * @param {(String|URL)} address The URL to which to connect
8313
+ * @param {(String|String[])} [protocols] The subprotocols
8314
+ * @param {Object} [options] Connection options
8315
+ */
8316
+ constructor(address, protocols, options) {
8317
+ super();
8318
+ this._binaryType = BINARY_TYPES[0];
8319
+ this._closeCode = 1006;
8320
+ this._closeFrameReceived = false;
8321
+ this._closeFrameSent = false;
8322
+ this._closeMessage = EMPTY_BUFFER;
8323
+ this._closeTimer = null;
8324
+ this._errorEmitted = false;
8325
+ this._extensions = {};
8326
+ this._paused = false;
8327
+ this._protocol = "";
8328
+ this._readyState = WebSocket.CONNECTING;
8329
+ this._receiver = null;
8330
+ this._sender = null;
8331
+ this._socket = null;
8332
+ if (address !== null) {
8333
+ this._bufferedAmount = 0;
8334
+ this._isServer = false;
8335
+ this._redirects = 0;
8336
+ if (protocols === void 0) protocols = [];
8337
+ else if (!Array.isArray(protocols)) if (typeof protocols === "object" && protocols !== null) {
8338
+ options = protocols;
8339
+ protocols = [];
8340
+ } else protocols = [protocols];
8341
+ initAsClient(this, address, protocols, options);
8342
+ } else {
8343
+ this._autoPong = options.autoPong;
8344
+ this._closeTimeout = options.closeTimeout;
8345
+ this._isServer = true;
8346
+ }
8347
+ }
8348
+ /**
8349
+ * For historical reasons, the custom "nodebuffer" type is used by the default
8350
+ * instead of "blob".
8351
+ *
8352
+ * @type {String}
8353
+ */
8354
+ get binaryType() {
8355
+ return this._binaryType;
8356
+ }
8357
+ set binaryType(type) {
8358
+ if (!BINARY_TYPES.includes(type)) return;
8359
+ this._binaryType = type;
8360
+ if (this._receiver) this._receiver._binaryType = type;
8361
+ }
8362
+ /**
8363
+ * @type {Number}
8364
+ */
8365
+ get bufferedAmount() {
8366
+ if (!this._socket) return this._bufferedAmount;
8367
+ return this._socket._writableState.length + this._sender._bufferedBytes;
8368
+ }
8369
+ /**
8370
+ * @type {String}
8371
+ */
8372
+ get extensions() {
8373
+ return Object.keys(this._extensions).join();
8374
+ }
8375
+ /**
8376
+ * @type {Boolean}
8377
+ */
8378
+ get isPaused() {
8379
+ return this._paused;
8380
+ }
8381
+ /**
8382
+ * @type {Function}
8383
+ */
8384
+ /* istanbul ignore next */
8385
+ get onclose() {
8386
+ return null;
8387
+ }
8388
+ /**
8389
+ * @type {Function}
8390
+ */
8391
+ /* istanbul ignore next */
8392
+ get onerror() {
8393
+ return null;
8394
+ }
8395
+ /**
8396
+ * @type {Function}
8397
+ */
8398
+ /* istanbul ignore next */
8399
+ get onopen() {
8400
+ return null;
8401
+ }
8402
+ /**
8403
+ * @type {Function}
8404
+ */
8405
+ /* istanbul ignore next */
8406
+ get onmessage() {
8407
+ return null;
8408
+ }
8409
+ /**
8410
+ * @type {String}
8411
+ */
8412
+ get protocol() {
8413
+ return this._protocol;
8414
+ }
8415
+ /**
8416
+ * @type {Number}
8417
+ */
8418
+ get readyState() {
8419
+ return this._readyState;
8420
+ }
8421
+ /**
8422
+ * @type {String}
8423
+ */
8424
+ get url() {
8425
+ return this._url;
8426
+ }
8427
+ /**
8428
+ * Set up the socket and the internal resources.
8429
+ *
8430
+ * @param {Duplex} socket The network socket between the server and client
8431
+ * @param {Buffer} head The first packet of the upgraded stream
8432
+ * @param {Object} options Options object
8433
+ * @param {Boolean} [options.allowSynchronousEvents=false] Specifies whether
8434
+ * any of the `'message'`, `'ping'`, and `'pong'` events can be emitted
8435
+ * multiple times in the same tick
8436
+ * @param {Function} [options.generateMask] The function used to generate the
8437
+ * masking key
8438
+ * @param {Number} [options.maxPayload=0] The maximum allowed message size
8439
+ * @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or
8440
+ * not to skip UTF-8 validation for text and close messages
8441
+ * @private
8442
+ */
8443
+ setSocket(socket, head, options) {
8444
+ const receiver = new Receiver({
8445
+ allowSynchronousEvents: options.allowSynchronousEvents,
8446
+ binaryType: this.binaryType,
8447
+ extensions: this._extensions,
8448
+ isServer: this._isServer,
8449
+ maxPayload: options.maxPayload,
8450
+ skipUTF8Validation: options.skipUTF8Validation
8451
+ });
8452
+ const sender = new Sender(socket, this._extensions, options.generateMask);
8453
+ this._receiver = receiver;
8454
+ this._sender = sender;
8455
+ this._socket = socket;
8456
+ receiver[kWebSocket] = this;
8457
+ sender[kWebSocket] = this;
8458
+ socket[kWebSocket] = this;
8459
+ receiver.on("conclude", receiverOnConclude);
8460
+ receiver.on("drain", receiverOnDrain);
8461
+ receiver.on("error", receiverOnError);
8462
+ receiver.on("message", receiverOnMessage);
8463
+ receiver.on("ping", receiverOnPing);
8464
+ receiver.on("pong", receiverOnPong);
8465
+ sender.onerror = senderOnError;
8466
+ if (socket.setTimeout) socket.setTimeout(0);
8467
+ if (socket.setNoDelay) socket.setNoDelay();
8468
+ if (head.length > 0) socket.unshift(head);
8469
+ socket.on("close", socketOnClose);
8470
+ socket.on("data", socketOnData);
8471
+ socket.on("end", socketOnEnd);
8472
+ socket.on("error", socketOnError);
8473
+ this._readyState = WebSocket.OPEN;
8474
+ this.emit("open");
8475
+ }
8476
+ /**
8477
+ * Emit the `'close'` event.
8478
+ *
8479
+ * @private
8480
+ */
8481
+ emitClose() {
8482
+ if (!this._socket) {
8483
+ this._readyState = WebSocket.CLOSED;
8484
+ this.emit("close", this._closeCode, this._closeMessage);
8485
+ return;
8486
+ }
8487
+ if (this._extensions[PerMessageDeflate.extensionName]) this._extensions[PerMessageDeflate.extensionName].cleanup();
8488
+ this._receiver.removeAllListeners();
8489
+ this._readyState = WebSocket.CLOSED;
8490
+ this.emit("close", this._closeCode, this._closeMessage);
8491
+ }
8492
+ /**
8493
+ * Start a closing handshake.
8494
+ *
8495
+ * +----------+ +-----------+ +----------+
8496
+ * - - -|ws.close()|-->|close frame|-->|ws.close()|- - -
8497
+ * | +----------+ +-----------+ +----------+ |
8498
+ * +----------+ +-----------+ |
8499
+ * CLOSING |ws.close()|<--|close frame|<--+-----+ CLOSING
8500
+ * +----------+ +-----------+ |
8501
+ * | | | +---+ |
8502
+ * +------------------------+-->|fin| - - - -
8503
+ * | +---+ | +---+
8504
+ * - - - - -|fin|<---------------------+
8505
+ * +---+
8506
+ *
8507
+ * @param {Number} [code] Status code explaining why the connection is closing
8508
+ * @param {(String|Buffer)} [data] The reason why the connection is
8509
+ * closing
8510
+ * @public
8511
+ */
8512
+ close(code, data) {
8513
+ if (this.readyState === WebSocket.CLOSED) return;
8514
+ if (this.readyState === WebSocket.CONNECTING) {
8515
+ abortHandshake(this, this._req, "WebSocket was closed before the connection was established");
8516
+ return;
8517
+ }
8518
+ if (this.readyState === WebSocket.CLOSING) {
8519
+ if (this._closeFrameSent && (this._closeFrameReceived || this._receiver._writableState.errorEmitted)) this._socket.end();
8520
+ return;
8521
+ }
8522
+ this._readyState = WebSocket.CLOSING;
8523
+ this._sender.close(code, data, !this._isServer, (err) => {
8524
+ if (err) return;
8525
+ this._closeFrameSent = true;
8526
+ if (this._closeFrameReceived || this._receiver._writableState.errorEmitted) this._socket.end();
8527
+ });
8528
+ setCloseTimer(this);
8529
+ }
8530
+ /**
8531
+ * Pause the socket.
8532
+ *
8533
+ * @public
8534
+ */
8535
+ pause() {
8536
+ if (this.readyState === WebSocket.CONNECTING || this.readyState === WebSocket.CLOSED) return;
8537
+ this._paused = true;
8538
+ this._socket.pause();
8539
+ }
8540
+ /**
8541
+ * Send a ping.
8542
+ *
8543
+ * @param {*} [data] The data to send
8544
+ * @param {Boolean} [mask] Indicates whether or not to mask `data`
8545
+ * @param {Function} [cb] Callback which is executed when the ping is sent
8546
+ * @public
8547
+ */
8548
+ ping(data, mask, cb) {
8549
+ if (this.readyState === WebSocket.CONNECTING) throw new Error("WebSocket is not open: readyState 0 (CONNECTING)");
8550
+ if (typeof data === "function") {
8551
+ cb = data;
8552
+ data = mask = void 0;
8553
+ } else if (typeof mask === "function") {
8554
+ cb = mask;
8555
+ mask = void 0;
8556
+ }
8557
+ if (typeof data === "number") data = data.toString();
8558
+ if (this.readyState !== WebSocket.OPEN) {
8559
+ sendAfterClose(this, data, cb);
8560
+ return;
8561
+ }
8562
+ if (mask === void 0) mask = !this._isServer;
8563
+ this._sender.ping(data || EMPTY_BUFFER, mask, cb);
8564
+ }
8565
+ /**
8566
+ * Send a pong.
8567
+ *
8568
+ * @param {*} [data] The data to send
8569
+ * @param {Boolean} [mask] Indicates whether or not to mask `data`
8570
+ * @param {Function} [cb] Callback which is executed when the pong is sent
8571
+ * @public
8572
+ */
8573
+ pong(data, mask, cb) {
8574
+ if (this.readyState === WebSocket.CONNECTING) throw new Error("WebSocket is not open: readyState 0 (CONNECTING)");
8575
+ if (typeof data === "function") {
8576
+ cb = data;
8577
+ data = mask = void 0;
8578
+ } else if (typeof mask === "function") {
8579
+ cb = mask;
8580
+ mask = void 0;
8581
+ }
8582
+ if (typeof data === "number") data = data.toString();
8583
+ if (this.readyState !== WebSocket.OPEN) {
8584
+ sendAfterClose(this, data, cb);
8585
+ return;
8586
+ }
8587
+ if (mask === void 0) mask = !this._isServer;
8588
+ this._sender.pong(data || EMPTY_BUFFER, mask, cb);
8589
+ }
8590
+ /**
8591
+ * Resume the socket.
8592
+ *
8593
+ * @public
8594
+ */
8595
+ resume() {
8596
+ if (this.readyState === WebSocket.CONNECTING || this.readyState === WebSocket.CLOSED) return;
8597
+ this._paused = false;
8598
+ if (!this._receiver._writableState.needDrain) this._socket.resume();
8599
+ }
8600
+ /**
8601
+ * Send a data message.
8602
+ *
8603
+ * @param {*} data The message to send
8604
+ * @param {Object} [options] Options object
8605
+ * @param {Boolean} [options.binary] Specifies whether `data` is binary or
8606
+ * text
8607
+ * @param {Boolean} [options.compress] Specifies whether or not to compress
8608
+ * `data`
8609
+ * @param {Boolean} [options.fin=true] Specifies whether the fragment is the
8610
+ * last one
8611
+ * @param {Boolean} [options.mask] Specifies whether or not to mask `data`
8612
+ * @param {Function} [cb] Callback which is executed when data is written out
8613
+ * @public
8614
+ */
8615
+ send(data, options, cb) {
8616
+ if (this.readyState === WebSocket.CONNECTING) throw new Error("WebSocket is not open: readyState 0 (CONNECTING)");
8617
+ if (typeof options === "function") {
8618
+ cb = options;
8619
+ options = {};
8620
+ }
8621
+ if (typeof data === "number") data = data.toString();
8622
+ if (this.readyState !== WebSocket.OPEN) {
8623
+ sendAfterClose(this, data, cb);
8624
+ return;
8625
+ }
8626
+ const opts = {
8627
+ binary: typeof data !== "string",
8628
+ mask: !this._isServer,
8629
+ compress: true,
8630
+ fin: true,
8631
+ ...options
8632
+ };
8633
+ if (!this._extensions[PerMessageDeflate.extensionName]) opts.compress = false;
8634
+ this._sender.send(data || EMPTY_BUFFER, opts, cb);
8635
+ }
8636
+ /**
8637
+ * Forcibly close the connection.
8638
+ *
8639
+ * @public
8640
+ */
8641
+ terminate() {
8642
+ if (this.readyState === WebSocket.CLOSED) return;
8643
+ if (this.readyState === WebSocket.CONNECTING) {
8644
+ abortHandshake(this, this._req, "WebSocket was closed before the connection was established");
8645
+ return;
8646
+ }
8647
+ if (this._socket) {
8648
+ this._readyState = WebSocket.CLOSING;
8649
+ this._socket.destroy();
8650
+ }
8651
+ }
8652
+ };
8653
+ /**
8654
+ * @constant {Number} CONNECTING
8655
+ * @memberof WebSocket
8656
+ */
8657
+ Object.defineProperty(WebSocket, "CONNECTING", {
8658
+ enumerable: true,
8659
+ value: readyStates.indexOf("CONNECTING")
8660
+ });
8661
+ /**
8662
+ * @constant {Number} CONNECTING
8663
+ * @memberof WebSocket.prototype
8664
+ */
8665
+ Object.defineProperty(WebSocket.prototype, "CONNECTING", {
8666
+ enumerable: true,
8667
+ value: readyStates.indexOf("CONNECTING")
8668
+ });
8669
+ /**
8670
+ * @constant {Number} OPEN
8671
+ * @memberof WebSocket
8672
+ */
8673
+ Object.defineProperty(WebSocket, "OPEN", {
8674
+ enumerable: true,
8675
+ value: readyStates.indexOf("OPEN")
8676
+ });
8677
+ /**
8678
+ * @constant {Number} OPEN
8679
+ * @memberof WebSocket.prototype
8680
+ */
8681
+ Object.defineProperty(WebSocket.prototype, "OPEN", {
8682
+ enumerable: true,
8683
+ value: readyStates.indexOf("OPEN")
8684
+ });
8685
+ /**
8686
+ * @constant {Number} CLOSING
8687
+ * @memberof WebSocket
8688
+ */
8689
+ Object.defineProperty(WebSocket, "CLOSING", {
8690
+ enumerable: true,
8691
+ value: readyStates.indexOf("CLOSING")
8692
+ });
8693
+ /**
8694
+ * @constant {Number} CLOSING
8695
+ * @memberof WebSocket.prototype
8696
+ */
8697
+ Object.defineProperty(WebSocket.prototype, "CLOSING", {
8698
+ enumerable: true,
8699
+ value: readyStates.indexOf("CLOSING")
8700
+ });
8701
+ /**
8702
+ * @constant {Number} CLOSED
8703
+ * @memberof WebSocket
8704
+ */
8705
+ Object.defineProperty(WebSocket, "CLOSED", {
8706
+ enumerable: true,
8707
+ value: readyStates.indexOf("CLOSED")
8708
+ });
8709
+ /**
8710
+ * @constant {Number} CLOSED
8711
+ * @memberof WebSocket.prototype
8712
+ */
8713
+ Object.defineProperty(WebSocket.prototype, "CLOSED", {
8714
+ enumerable: true,
8715
+ value: readyStates.indexOf("CLOSED")
8716
+ });
8717
+ [
8718
+ "binaryType",
8719
+ "bufferedAmount",
8720
+ "extensions",
8721
+ "isPaused",
8722
+ "protocol",
8723
+ "readyState",
8724
+ "url"
8725
+ ].forEach((property) => {
8726
+ Object.defineProperty(WebSocket.prototype, property, { enumerable: true });
8727
+ });
8728
+ [
8729
+ "open",
8730
+ "error",
8731
+ "close",
8732
+ "message"
8733
+ ].forEach((method) => {
8734
+ Object.defineProperty(WebSocket.prototype, `on${method}`, {
8735
+ enumerable: true,
8736
+ get() {
8737
+ for (const listener of this.listeners(method)) if (listener[kForOnEventAttribute]) return listener[kListener];
8738
+ return null;
8739
+ },
8740
+ set(handler) {
8741
+ for (const listener of this.listeners(method)) if (listener[kForOnEventAttribute]) {
8742
+ this.removeListener(method, listener);
8743
+ break;
8744
+ }
8745
+ if (typeof handler !== "function") return;
8746
+ this.addEventListener(method, handler, { [kForOnEventAttribute]: true });
8747
+ }
8748
+ });
8749
+ });
8750
+ WebSocket.prototype.addEventListener = addEventListener;
8751
+ WebSocket.prototype.removeEventListener = removeEventListener;
8752
+ module.exports = WebSocket;
8753
+ /**
8754
+ * Initialize a WebSocket client.
8755
+ *
8756
+ * @param {WebSocket} websocket The client to initialize
8757
+ * @param {(String|URL)} address The URL to which to connect
8758
+ * @param {Array} protocols The subprotocols
8759
+ * @param {Object} [options] Connection options
8760
+ * @param {Boolean} [options.allowSynchronousEvents=true] Specifies whether any
8761
+ * of the `'message'`, `'ping'`, and `'pong'` events can be emitted multiple
8762
+ * times in the same tick
8763
+ * @param {Boolean} [options.autoPong=true] Specifies whether or not to
8764
+ * automatically send a pong in response to a ping
8765
+ * @param {Number} [options.closeTimeout=30000] Duration in milliseconds to wait
8766
+ * for the closing handshake to finish after `websocket.close()` is called
8767
+ * @param {Function} [options.finishRequest] A function which can be used to
8768
+ * customize the headers of each http request before it is sent
8769
+ * @param {Boolean} [options.followRedirects=false] Whether or not to follow
8770
+ * redirects
8771
+ * @param {Function} [options.generateMask] The function used to generate the
8772
+ * masking key
8773
+ * @param {Number} [options.handshakeTimeout] Timeout in milliseconds for the
8774
+ * handshake request
8775
+ * @param {Number} [options.maxPayload=104857600] The maximum allowed message
8776
+ * size
8777
+ * @param {Number} [options.maxRedirects=10] The maximum number of redirects
8778
+ * allowed
8779
+ * @param {String} [options.origin] Value of the `Origin` or
8780
+ * `Sec-WebSocket-Origin` header
8781
+ * @param {(Boolean|Object)} [options.perMessageDeflate=true] Enable/disable
8782
+ * permessage-deflate
8783
+ * @param {Number} [options.protocolVersion=13] Value of the
8784
+ * `Sec-WebSocket-Version` header
8785
+ * @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or
8786
+ * not to skip UTF-8 validation for text and close messages
8787
+ * @private
8788
+ */
8789
+ function initAsClient(websocket, address, protocols, options) {
8790
+ const opts = {
8791
+ allowSynchronousEvents: true,
8792
+ autoPong: true,
8793
+ closeTimeout: CLOSE_TIMEOUT,
8794
+ protocolVersion: protocolVersions[1],
8795
+ maxPayload: 100 * 1024 * 1024,
8796
+ skipUTF8Validation: false,
8797
+ perMessageDeflate: true,
8798
+ followRedirects: false,
8799
+ maxRedirects: 10,
8800
+ ...options,
8801
+ socketPath: void 0,
8802
+ hostname: void 0,
8803
+ protocol: void 0,
8804
+ timeout: void 0,
8805
+ method: "GET",
8806
+ host: void 0,
8807
+ path: void 0,
8808
+ port: void 0
8809
+ };
8810
+ websocket._autoPong = opts.autoPong;
8811
+ websocket._closeTimeout = opts.closeTimeout;
8812
+ if (!protocolVersions.includes(opts.protocolVersion)) throw new RangeError(`Unsupported protocol version: ${opts.protocolVersion} (supported versions: ${protocolVersions.join(", ")})`);
8813
+ let parsedUrl;
8814
+ if (address instanceof URL) parsedUrl = address;
8815
+ else try {
8816
+ parsedUrl = new URL(address);
8817
+ } catch (e) {
8818
+ throw new SyntaxError(`Invalid URL: ${address}`);
8819
+ }
8820
+ if (parsedUrl.protocol === "http:") parsedUrl.protocol = "ws:";
8821
+ else if (parsedUrl.protocol === "https:") parsedUrl.protocol = "wss:";
8822
+ websocket._url = parsedUrl.href;
8823
+ const isSecure = parsedUrl.protocol === "wss:";
8824
+ const isIpcUrl = parsedUrl.protocol === "ws+unix:";
8825
+ let invalidUrlMessage;
8826
+ if (parsedUrl.protocol !== "ws:" && !isSecure && !isIpcUrl) invalidUrlMessage = "The URL's protocol must be one of \"ws:\", \"wss:\", \"http:\", \"https:\", or \"ws+unix:\"";
8827
+ else if (isIpcUrl && !parsedUrl.pathname) invalidUrlMessage = "The URL's pathname is empty";
8828
+ else if (parsedUrl.hash) invalidUrlMessage = "The URL contains a fragment identifier";
8829
+ if (invalidUrlMessage) {
8830
+ const err = new SyntaxError(invalidUrlMessage);
8831
+ if (websocket._redirects === 0) throw err;
8832
+ else {
8833
+ emitErrorAndClose(websocket, err);
8834
+ return;
8835
+ }
8836
+ }
8837
+ const defaultPort = isSecure ? 443 : 80;
8838
+ const key = randomBytes(16).toString("base64");
8839
+ const request = isSecure ? https.request : http$1.request;
8840
+ const protocolSet = /* @__PURE__ */ new Set();
8841
+ let perMessageDeflate;
8842
+ opts.createConnection = opts.createConnection || (isSecure ? tlsConnect : netConnect);
8843
+ opts.defaultPort = opts.defaultPort || defaultPort;
8844
+ opts.port = parsedUrl.port || defaultPort;
8845
+ opts.host = parsedUrl.hostname.startsWith("[") ? parsedUrl.hostname.slice(1, -1) : parsedUrl.hostname;
8846
+ opts.headers = {
8847
+ ...opts.headers,
8848
+ "Sec-WebSocket-Version": opts.protocolVersion,
8849
+ "Sec-WebSocket-Key": key,
8850
+ Connection: "Upgrade",
8851
+ Upgrade: "websocket"
8852
+ };
8853
+ opts.path = parsedUrl.pathname + parsedUrl.search;
8854
+ opts.timeout = opts.handshakeTimeout;
8855
+ if (opts.perMessageDeflate) {
8856
+ perMessageDeflate = new PerMessageDeflate(opts.perMessageDeflate !== true ? opts.perMessageDeflate : {}, false, opts.maxPayload);
8857
+ opts.headers["Sec-WebSocket-Extensions"] = format({ [PerMessageDeflate.extensionName]: perMessageDeflate.offer() });
8858
+ }
8859
+ if (protocols.length) {
8860
+ for (const protocol of protocols) {
8861
+ if (typeof protocol !== "string" || !subprotocolRegex.test(protocol) || protocolSet.has(protocol)) throw new SyntaxError("An invalid or duplicated subprotocol was specified");
8862
+ protocolSet.add(protocol);
8863
+ }
8864
+ opts.headers["Sec-WebSocket-Protocol"] = protocols.join(",");
8865
+ }
8866
+ if (opts.origin) if (opts.protocolVersion < 13) opts.headers["Sec-WebSocket-Origin"] = opts.origin;
8867
+ else opts.headers.Origin = opts.origin;
8868
+ if (parsedUrl.username || parsedUrl.password) opts.auth = `${parsedUrl.username}:${parsedUrl.password}`;
8869
+ if (isIpcUrl) {
8870
+ const parts = opts.path.split(":");
8871
+ opts.socketPath = parts[0];
8872
+ opts.path = parts[1];
8873
+ }
8874
+ let req;
8875
+ if (opts.followRedirects) {
8876
+ if (websocket._redirects === 0) {
8877
+ websocket._originalIpc = isIpcUrl;
8878
+ websocket._originalSecure = isSecure;
8879
+ websocket._originalHostOrSocketPath = isIpcUrl ? opts.socketPath : parsedUrl.host;
8880
+ const headers = options && options.headers;
8881
+ options = {
8882
+ ...options,
8883
+ headers: {}
8884
+ };
8885
+ if (headers) for (const [key, value] of Object.entries(headers)) options.headers[key.toLowerCase()] = value;
8886
+ } else if (websocket.listenerCount("redirect") === 0) {
8887
+ const isSameHost = isIpcUrl ? websocket._originalIpc ? opts.socketPath === websocket._originalHostOrSocketPath : false : websocket._originalIpc ? false : parsedUrl.host === websocket._originalHostOrSocketPath;
8888
+ if (!isSameHost || websocket._originalSecure && !isSecure) {
8889
+ delete opts.headers.authorization;
8890
+ delete opts.headers.cookie;
8891
+ if (!isSameHost) delete opts.headers.host;
8892
+ opts.auth = void 0;
8893
+ }
8894
+ }
8895
+ if (opts.auth && !options.headers.authorization) options.headers.authorization = "Basic " + Buffer.from(opts.auth).toString("base64");
8896
+ req = websocket._req = request(opts);
8897
+ if (websocket._redirects) websocket.emit("redirect", websocket.url, req);
8898
+ } else req = websocket._req = request(opts);
8899
+ if (opts.timeout) req.on("timeout", () => {
8900
+ abortHandshake(websocket, req, "Opening handshake has timed out");
8901
+ });
8902
+ req.on("error", (err) => {
8903
+ if (req === null || req[kAborted]) return;
8904
+ req = websocket._req = null;
8905
+ emitErrorAndClose(websocket, err);
8906
+ });
8907
+ req.on("response", (res) => {
8908
+ const location = res.headers.location;
8909
+ const statusCode = res.statusCode;
8910
+ if (location && opts.followRedirects && statusCode >= 300 && statusCode < 400) {
8911
+ if (++websocket._redirects > opts.maxRedirects) {
8912
+ abortHandshake(websocket, req, "Maximum redirects exceeded");
8913
+ return;
8914
+ }
8915
+ req.abort();
8916
+ let addr;
8917
+ try {
8918
+ addr = new URL(location, address);
8919
+ } catch (e) {
8920
+ emitErrorAndClose(websocket, /* @__PURE__ */ new SyntaxError(`Invalid URL: ${location}`));
8921
+ return;
8922
+ }
8923
+ initAsClient(websocket, addr, protocols, options);
8924
+ } else if (!websocket.emit("unexpected-response", req, res)) abortHandshake(websocket, req, `Unexpected server response: ${res.statusCode}`);
8925
+ });
8926
+ req.on("upgrade", (res, socket, head) => {
8927
+ websocket.emit("upgrade", res);
8928
+ if (websocket.readyState !== WebSocket.CONNECTING) return;
8929
+ req = websocket._req = null;
8930
+ const upgrade = res.headers.upgrade;
8931
+ if (upgrade === void 0 || upgrade.toLowerCase() !== "websocket") {
8932
+ abortHandshake(websocket, socket, "Invalid Upgrade header");
8933
+ return;
8934
+ }
8935
+ const digest = createHash$1("sha1").update(key + GUID).digest("base64");
8936
+ if (res.headers["sec-websocket-accept"] !== digest) {
8937
+ abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Accept header");
8938
+ return;
8939
+ }
8940
+ const serverProt = res.headers["sec-websocket-protocol"];
8941
+ let protError;
8942
+ if (serverProt !== void 0) {
8943
+ if (!protocolSet.size) protError = "Server sent a subprotocol but none was requested";
8944
+ else if (!protocolSet.has(serverProt)) protError = "Server sent an invalid subprotocol";
8945
+ } else if (protocolSet.size) protError = "Server sent no subprotocol";
8946
+ if (protError) {
8947
+ abortHandshake(websocket, socket, protError);
8948
+ return;
8949
+ }
8950
+ if (serverProt) websocket._protocol = serverProt;
8951
+ const secWebSocketExtensions = res.headers["sec-websocket-extensions"];
8952
+ if (secWebSocketExtensions !== void 0) {
8953
+ if (!perMessageDeflate) {
8954
+ abortHandshake(websocket, socket, "Server sent a Sec-WebSocket-Extensions header but no extension was requested");
8955
+ return;
8956
+ }
8957
+ let extensions;
8958
+ try {
8959
+ extensions = parse(secWebSocketExtensions);
8960
+ } catch (err) {
8961
+ abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Extensions header");
8962
+ return;
8963
+ }
8964
+ const extensionNames = Object.keys(extensions);
8965
+ if (extensionNames.length !== 1 || extensionNames[0] !== PerMessageDeflate.extensionName) {
8966
+ abortHandshake(websocket, socket, "Server indicated an extension that was not requested");
8967
+ return;
8968
+ }
8969
+ try {
8970
+ perMessageDeflate.accept(extensions[PerMessageDeflate.extensionName]);
8971
+ } catch (err) {
8972
+ abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Extensions header");
8973
+ return;
8974
+ }
8975
+ websocket._extensions[PerMessageDeflate.extensionName] = perMessageDeflate;
8976
+ }
8977
+ websocket.setSocket(socket, head, {
8978
+ allowSynchronousEvents: opts.allowSynchronousEvents,
8979
+ generateMask: opts.generateMask,
8980
+ maxPayload: opts.maxPayload,
8981
+ skipUTF8Validation: opts.skipUTF8Validation
8982
+ });
8983
+ });
8984
+ if (opts.finishRequest) opts.finishRequest(req, websocket);
8985
+ else req.end();
8986
+ }
8987
+ /**
8988
+ * Emit the `'error'` and `'close'` events.
8989
+ *
8990
+ * @param {WebSocket} websocket The WebSocket instance
8991
+ * @param {Error} The error to emit
8992
+ * @private
8993
+ */
8994
+ function emitErrorAndClose(websocket, err) {
8995
+ websocket._readyState = WebSocket.CLOSING;
8996
+ websocket._errorEmitted = true;
8997
+ websocket.emit("error", err);
8998
+ websocket.emitClose();
8999
+ }
9000
+ /**
9001
+ * Create a `net.Socket` and initiate a connection.
9002
+ *
9003
+ * @param {Object} options Connection options
9004
+ * @return {net.Socket} The newly created socket used to start the connection
9005
+ * @private
9006
+ */
9007
+ function netConnect(options) {
9008
+ options.path = options.socketPath;
9009
+ return net.connect(options);
9010
+ }
9011
+ /**
9012
+ * Create a `tls.TLSSocket` and initiate a connection.
9013
+ *
9014
+ * @param {Object} options Connection options
9015
+ * @return {tls.TLSSocket} The newly created socket used to start the connection
9016
+ * @private
9017
+ */
9018
+ function tlsConnect(options) {
9019
+ options.path = void 0;
9020
+ if (!options.servername && options.servername !== "") options.servername = net.isIP(options.host) ? "" : options.host;
9021
+ return tls.connect(options);
9022
+ }
9023
+ /**
9024
+ * Abort the handshake and emit an error.
9025
+ *
9026
+ * @param {WebSocket} websocket The WebSocket instance
9027
+ * @param {(http.ClientRequest|net.Socket|tls.Socket)} stream The request to
9028
+ * abort or the socket to destroy
9029
+ * @param {String} message The error message
9030
+ * @private
9031
+ */
9032
+ function abortHandshake(websocket, stream, message) {
9033
+ websocket._readyState = WebSocket.CLOSING;
9034
+ const err = new Error(message);
9035
+ Error.captureStackTrace(err, abortHandshake);
9036
+ if (stream.setHeader) {
9037
+ stream[kAborted] = true;
9038
+ stream.abort();
9039
+ if (stream.socket && !stream.socket.destroyed) stream.socket.destroy();
9040
+ process.nextTick(emitErrorAndClose, websocket, err);
9041
+ } else {
9042
+ stream.destroy(err);
9043
+ stream.once("error", websocket.emit.bind(websocket, "error"));
9044
+ stream.once("close", websocket.emitClose.bind(websocket));
9045
+ }
9046
+ }
9047
+ /**
9048
+ * Handle cases where the `ping()`, `pong()`, or `send()` methods are called
9049
+ * when the `readyState` attribute is `CLOSING` or `CLOSED`.
9050
+ *
9051
+ * @param {WebSocket} websocket The WebSocket instance
9052
+ * @param {*} [data] The data to send
9053
+ * @param {Function} [cb] Callback
9054
+ * @private
9055
+ */
9056
+ function sendAfterClose(websocket, data, cb) {
9057
+ if (data) {
9058
+ const length = isBlob(data) ? data.size : toBuffer(data).length;
9059
+ if (websocket._socket) websocket._sender._bufferedBytes += length;
9060
+ else websocket._bufferedAmount += length;
9061
+ }
9062
+ if (cb) {
9063
+ const err = /* @__PURE__ */ new Error(`WebSocket is not open: readyState ${websocket.readyState} (${readyStates[websocket.readyState]})`);
9064
+ process.nextTick(cb, err);
9065
+ }
9066
+ }
9067
+ /**
9068
+ * The listener of the `Receiver` `'conclude'` event.
9069
+ *
9070
+ * @param {Number} code The status code
9071
+ * @param {Buffer} reason The reason for closing
9072
+ * @private
9073
+ */
9074
+ function receiverOnConclude(code, reason) {
9075
+ const websocket = this[kWebSocket];
9076
+ websocket._closeFrameReceived = true;
9077
+ websocket._closeMessage = reason;
9078
+ websocket._closeCode = code;
9079
+ if (websocket._socket[kWebSocket] === void 0) return;
9080
+ websocket._socket.removeListener("data", socketOnData);
9081
+ process.nextTick(resume, websocket._socket);
9082
+ if (code === 1005) websocket.close();
9083
+ else websocket.close(code, reason);
9084
+ }
9085
+ /**
9086
+ * The listener of the `Receiver` `'drain'` event.
9087
+ *
9088
+ * @private
9089
+ */
9090
+ function receiverOnDrain() {
9091
+ const websocket = this[kWebSocket];
9092
+ if (!websocket.isPaused) websocket._socket.resume();
9093
+ }
9094
+ /**
9095
+ * The listener of the `Receiver` `'error'` event.
9096
+ *
9097
+ * @param {(RangeError|Error)} err The emitted error
9098
+ * @private
9099
+ */
9100
+ function receiverOnError(err) {
9101
+ const websocket = this[kWebSocket];
9102
+ if (websocket._socket[kWebSocket] !== void 0) {
9103
+ websocket._socket.removeListener("data", socketOnData);
9104
+ process.nextTick(resume, websocket._socket);
9105
+ websocket.close(err[kStatusCode]);
9106
+ }
9107
+ if (!websocket._errorEmitted) {
9108
+ websocket._errorEmitted = true;
9109
+ websocket.emit("error", err);
9110
+ }
9111
+ }
9112
+ /**
9113
+ * The listener of the `Receiver` `'finish'` event.
9114
+ *
9115
+ * @private
9116
+ */
9117
+ function receiverOnFinish() {
9118
+ this[kWebSocket].emitClose();
9119
+ }
9120
+ /**
9121
+ * The listener of the `Receiver` `'message'` event.
9122
+ *
9123
+ * @param {Buffer|ArrayBuffer|Buffer[])} data The message
9124
+ * @param {Boolean} isBinary Specifies whether the message is binary or not
9125
+ * @private
9126
+ */
9127
+ function receiverOnMessage(data, isBinary) {
9128
+ this[kWebSocket].emit("message", data, isBinary);
9129
+ }
9130
+ /**
9131
+ * The listener of the `Receiver` `'ping'` event.
9132
+ *
9133
+ * @param {Buffer} data The data included in the ping frame
9134
+ * @private
9135
+ */
9136
+ function receiverOnPing(data) {
9137
+ const websocket = this[kWebSocket];
9138
+ if (websocket._autoPong) websocket.pong(data, !this._isServer, NOOP);
9139
+ websocket.emit("ping", data);
9140
+ }
9141
+ /**
9142
+ * The listener of the `Receiver` `'pong'` event.
9143
+ *
9144
+ * @param {Buffer} data The data included in the pong frame
9145
+ * @private
9146
+ */
9147
+ function receiverOnPong(data) {
9148
+ this[kWebSocket].emit("pong", data);
9149
+ }
9150
+ /**
9151
+ * Resume a readable stream
9152
+ *
9153
+ * @param {Readable} stream The readable stream
9154
+ * @private
9155
+ */
9156
+ function resume(stream) {
9157
+ stream.resume();
9158
+ }
9159
+ /**
9160
+ * The `Sender` error event handler.
9161
+ *
9162
+ * @param {Error} The error
9163
+ * @private
9164
+ */
9165
+ function senderOnError(err) {
9166
+ const websocket = this[kWebSocket];
9167
+ if (websocket.readyState === WebSocket.CLOSED) return;
9168
+ if (websocket.readyState === WebSocket.OPEN) {
9169
+ websocket._readyState = WebSocket.CLOSING;
9170
+ setCloseTimer(websocket);
9171
+ }
9172
+ this._socket.end();
9173
+ if (!websocket._errorEmitted) {
9174
+ websocket._errorEmitted = true;
9175
+ websocket.emit("error", err);
9176
+ }
9177
+ }
9178
+ /**
9179
+ * Set a timer to destroy the underlying raw socket of a WebSocket.
9180
+ *
9181
+ * @param {WebSocket} websocket The WebSocket instance
9182
+ * @private
9183
+ */
9184
+ function setCloseTimer(websocket) {
9185
+ websocket._closeTimer = setTimeout(websocket._socket.destroy.bind(websocket._socket), websocket._closeTimeout);
9186
+ }
9187
+ /**
9188
+ * The listener of the socket `'close'` event.
9189
+ *
9190
+ * @private
9191
+ */
9192
+ function socketOnClose() {
9193
+ const websocket = this[kWebSocket];
9194
+ this.removeListener("close", socketOnClose);
9195
+ this.removeListener("data", socketOnData);
9196
+ this.removeListener("end", socketOnEnd);
9197
+ websocket._readyState = WebSocket.CLOSING;
9198
+ if (!this._readableState.endEmitted && !websocket._closeFrameReceived && !websocket._receiver._writableState.errorEmitted && this._readableState.length !== 0) {
9199
+ const chunk = this.read(this._readableState.length);
9200
+ websocket._receiver.write(chunk);
9201
+ }
9202
+ websocket._receiver.end();
9203
+ this[kWebSocket] = void 0;
9204
+ clearTimeout(websocket._closeTimer);
9205
+ if (websocket._receiver._writableState.finished || websocket._receiver._writableState.errorEmitted) websocket.emitClose();
9206
+ else {
9207
+ websocket._receiver.on("error", receiverOnFinish);
9208
+ websocket._receiver.on("finish", receiverOnFinish);
9209
+ }
9210
+ }
9211
+ /**
9212
+ * The listener of the socket `'data'` event.
9213
+ *
9214
+ * @param {Buffer} chunk A chunk of data
9215
+ * @private
9216
+ */
9217
+ function socketOnData(chunk) {
9218
+ if (!this[kWebSocket]._receiver.write(chunk)) this.pause();
9219
+ }
9220
+ /**
9221
+ * The listener of the socket `'end'` event.
9222
+ *
9223
+ * @private
9224
+ */
9225
+ function socketOnEnd() {
9226
+ const websocket = this[kWebSocket];
9227
+ websocket._readyState = WebSocket.CLOSING;
9228
+ websocket._receiver.end();
9229
+ this.end();
9230
+ }
9231
+ /**
9232
+ * The listener of the socket `'error'` event.
9233
+ *
9234
+ * @private
9235
+ */
9236
+ function socketOnError() {
9237
+ const websocket = this[kWebSocket];
9238
+ this.removeListener("error", socketOnError);
9239
+ this.on("error", NOOP);
9240
+ if (websocket) {
9241
+ websocket._readyState = WebSocket.CLOSING;
9242
+ this.destroy();
9243
+ }
9244
+ }
9245
+ }));
9246
+
9247
+ //#endregion
9248
+ //#region node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/stream.js
9249
+ var require_stream = /* @__PURE__ */ __commonJSMin(((exports, module) => {
9250
+ require_websocket();
9251
+ const { Duplex: Duplex$1 } = __require("stream");
9252
+ /**
9253
+ * Emits the `'close'` event on a stream.
9254
+ *
9255
+ * @param {Duplex} stream The stream.
9256
+ * @private
9257
+ */
9258
+ function emitClose(stream) {
9259
+ stream.emit("close");
9260
+ }
9261
+ /**
9262
+ * The listener of the `'end'` event.
9263
+ *
9264
+ * @private
9265
+ */
9266
+ function duplexOnEnd() {
9267
+ if (!this.destroyed && this._writableState.finished) this.destroy();
9268
+ }
9269
+ /**
9270
+ * The listener of the `'error'` event.
9271
+ *
9272
+ * @param {Error} err The error
9273
+ * @private
9274
+ */
9275
+ function duplexOnError(err) {
9276
+ this.removeListener("error", duplexOnError);
9277
+ this.destroy();
9278
+ if (this.listenerCount("error") === 0) this.emit("error", err);
9279
+ }
9280
+ /**
9281
+ * Wraps a `WebSocket` in a duplex stream.
9282
+ *
9283
+ * @param {WebSocket} ws The `WebSocket` to wrap
9284
+ * @param {Object} [options] The options for the `Duplex` constructor
9285
+ * @return {Duplex} The duplex stream
9286
+ * @public
9287
+ */
9288
+ function createWebSocketStream(ws, options) {
9289
+ let terminateOnDestroy = true;
9290
+ const duplex = new Duplex$1({
9291
+ ...options,
9292
+ autoDestroy: false,
9293
+ emitClose: false,
9294
+ objectMode: false,
9295
+ writableObjectMode: false
9296
+ });
9297
+ ws.on("message", function message(msg, isBinary) {
9298
+ const data = !isBinary && duplex._readableState.objectMode ? msg.toString() : msg;
9299
+ if (!duplex.push(data)) ws.pause();
9300
+ });
9301
+ ws.once("error", function error(err) {
9302
+ if (duplex.destroyed) return;
9303
+ terminateOnDestroy = false;
9304
+ duplex.destroy(err);
9305
+ });
9306
+ ws.once("close", function close() {
9307
+ if (duplex.destroyed) return;
9308
+ duplex.push(null);
9309
+ });
9310
+ duplex._destroy = function(err, callback) {
9311
+ if (ws.readyState === ws.CLOSED) {
9312
+ callback(err);
9313
+ process.nextTick(emitClose, duplex);
9314
+ return;
9315
+ }
9316
+ let called = false;
9317
+ ws.once("error", function error(err) {
9318
+ called = true;
9319
+ callback(err);
9320
+ });
9321
+ ws.once("close", function close() {
9322
+ if (!called) callback(err);
9323
+ process.nextTick(emitClose, duplex);
9324
+ });
9325
+ if (terminateOnDestroy) ws.terminate();
9326
+ };
9327
+ duplex._final = function(callback) {
9328
+ if (ws.readyState === ws.CONNECTING) {
9329
+ ws.once("open", function open() {
9330
+ duplex._final(callback);
9331
+ });
9332
+ return;
9333
+ }
9334
+ if (ws._socket === null) return;
9335
+ if (ws._socket._writableState.finished) {
9336
+ callback();
9337
+ if (duplex._readableState.endEmitted) duplex.destroy();
9338
+ } else {
9339
+ ws._socket.once("finish", function finish() {
9340
+ callback();
9341
+ });
9342
+ ws.close();
9343
+ }
9344
+ };
9345
+ duplex._read = function() {
9346
+ if (ws.isPaused) ws.resume();
9347
+ };
9348
+ duplex._write = function(chunk, encoding, callback) {
9349
+ if (ws.readyState === ws.CONNECTING) {
9350
+ ws.once("open", function open() {
9351
+ duplex._write(chunk, encoding, callback);
9352
+ });
9353
+ return;
9354
+ }
9355
+ ws.send(chunk, callback);
9356
+ };
9357
+ duplex.on("end", duplexOnEnd);
9358
+ duplex.on("error", duplexOnError);
9359
+ return duplex;
9360
+ }
9361
+ module.exports = createWebSocketStream;
9362
+ }));
9363
+
9364
+ //#endregion
9365
+ //#region node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/subprotocol.js
9366
+ var require_subprotocol = /* @__PURE__ */ __commonJSMin(((exports, module) => {
9367
+ const { tokenChars } = require_validation();
9368
+ /**
9369
+ * Parses the `Sec-WebSocket-Protocol` header into a set of subprotocol names.
9370
+ *
9371
+ * @param {String} header The field value of the header
9372
+ * @return {Set} The subprotocol names
9373
+ * @public
9374
+ */
9375
+ function parse(header) {
9376
+ const protocols = /* @__PURE__ */ new Set();
9377
+ let start = -1;
9378
+ let end = -1;
9379
+ let i = 0;
9380
+ for (; i < header.length; i++) {
9381
+ const code = header.charCodeAt(i);
9382
+ if (end === -1 && tokenChars[code] === 1) {
9383
+ if (start === -1) start = i;
9384
+ } else if (i !== 0 && (code === 32 || code === 9)) {
9385
+ if (end === -1 && start !== -1) end = i;
9386
+ } else if (code === 44) {
9387
+ if (start === -1) throw new SyntaxError(`Unexpected character at index ${i}`);
9388
+ if (end === -1) end = i;
9389
+ const protocol = header.slice(start, end);
9390
+ if (protocols.has(protocol)) throw new SyntaxError(`The "${protocol}" subprotocol is duplicated`);
9391
+ protocols.add(protocol);
9392
+ start = end = -1;
9393
+ } else throw new SyntaxError(`Unexpected character at index ${i}`);
9394
+ }
9395
+ if (start === -1 || end !== -1) throw new SyntaxError("Unexpected end of input");
9396
+ const protocol = header.slice(start, i);
9397
+ if (protocols.has(protocol)) throw new SyntaxError(`The "${protocol}" subprotocol is duplicated`);
9398
+ protocols.add(protocol);
9399
+ return protocols;
9400
+ }
9401
+ module.exports = { parse };
9402
+ }));
9403
+
9404
+ //#endregion
9405
+ //#region node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/websocket-server.js
9406
+ var require_websocket_server = /* @__PURE__ */ __commonJSMin(((exports, module) => {
9407
+ const EventEmitter$1 = __require("events");
9408
+ const http = __require("http");
9409
+ const { Duplex } = __require("stream");
9410
+ const { createHash } = __require("crypto");
9411
+ const extension = require_extension();
9412
+ const PerMessageDeflate = require_permessage_deflate();
9413
+ const subprotocol = require_subprotocol();
9414
+ const WebSocket = require_websocket();
9415
+ const { CLOSE_TIMEOUT, GUID, kWebSocket } = require_constants();
9416
+ const keyRegex = /^[+/0-9A-Za-z]{22}==$/;
9417
+ const RUNNING = 0;
9418
+ const CLOSING = 1;
9419
+ const CLOSED = 2;
9420
+ /**
9421
+ * Class representing a WebSocket server.
9422
+ *
9423
+ * @extends EventEmitter
9424
+ */
9425
+ var WebSocketServer = class extends EventEmitter$1 {
9426
+ /**
9427
+ * Create a `WebSocketServer` instance.
9428
+ *
9429
+ * @param {Object} options Configuration options
9430
+ * @param {Boolean} [options.allowSynchronousEvents=true] Specifies whether
9431
+ * any of the `'message'`, `'ping'`, and `'pong'` events can be emitted
9432
+ * multiple times in the same tick
9433
+ * @param {Boolean} [options.autoPong=true] Specifies whether or not to
9434
+ * automatically send a pong in response to a ping
9435
+ * @param {Number} [options.backlog=511] The maximum length of the queue of
9436
+ * pending connections
9437
+ * @param {Boolean} [options.clientTracking=true] Specifies whether or not to
9438
+ * track clients
9439
+ * @param {Number} [options.closeTimeout=30000] Duration in milliseconds to
9440
+ * wait for the closing handshake to finish after `websocket.close()` is
9441
+ * called
9442
+ * @param {Function} [options.handleProtocols] A hook to handle protocols
9443
+ * @param {String} [options.host] The hostname where to bind the server
9444
+ * @param {Number} [options.maxPayload=104857600] The maximum allowed message
9445
+ * size
9446
+ * @param {Boolean} [options.noServer=false] Enable no server mode
9447
+ * @param {String} [options.path] Accept only connections matching this path
9448
+ * @param {(Boolean|Object)} [options.perMessageDeflate=false] Enable/disable
9449
+ * permessage-deflate
9450
+ * @param {Number} [options.port] The port where to bind the server
9451
+ * @param {(http.Server|https.Server)} [options.server] A pre-created HTTP/S
9452
+ * server to use
9453
+ * @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or
9454
+ * not to skip UTF-8 validation for text and close messages
9455
+ * @param {Function} [options.verifyClient] A hook to reject connections
9456
+ * @param {Function} [options.WebSocket=WebSocket] Specifies the `WebSocket`
9457
+ * class to use. It must be the `WebSocket` class or class that extends it
9458
+ * @param {Function} [callback] A listener for the `listening` event
9459
+ */
9460
+ constructor(options, callback) {
9461
+ super();
9462
+ options = {
9463
+ allowSynchronousEvents: true,
9464
+ autoPong: true,
9465
+ maxPayload: 100 * 1024 * 1024,
9466
+ skipUTF8Validation: false,
9467
+ perMessageDeflate: false,
9468
+ handleProtocols: null,
9469
+ clientTracking: true,
9470
+ closeTimeout: CLOSE_TIMEOUT,
9471
+ verifyClient: null,
9472
+ noServer: false,
9473
+ backlog: null,
9474
+ server: null,
9475
+ host: null,
9476
+ path: null,
9477
+ port: null,
9478
+ WebSocket,
9479
+ ...options
9480
+ };
9481
+ if (options.port == null && !options.server && !options.noServer || options.port != null && (options.server || options.noServer) || options.server && options.noServer) throw new TypeError("One and only one of the \"port\", \"server\", or \"noServer\" options must be specified");
9482
+ if (options.port != null) {
9483
+ this._server = http.createServer((req, res) => {
9484
+ const body = http.STATUS_CODES[426];
9485
+ res.writeHead(426, {
9486
+ "Content-Length": body.length,
9487
+ "Content-Type": "text/plain"
9488
+ });
9489
+ res.end(body);
9490
+ });
9491
+ this._server.listen(options.port, options.host, options.backlog, callback);
9492
+ } else if (options.server) this._server = options.server;
9493
+ if (this._server) {
9494
+ const emitConnection = this.emit.bind(this, "connection");
9495
+ this._removeListeners = addListeners(this._server, {
9496
+ listening: this.emit.bind(this, "listening"),
9497
+ error: this.emit.bind(this, "error"),
9498
+ upgrade: (req, socket, head) => {
9499
+ this.handleUpgrade(req, socket, head, emitConnection);
9500
+ }
9501
+ });
9502
+ }
9503
+ if (options.perMessageDeflate === true) options.perMessageDeflate = {};
9504
+ if (options.clientTracking) {
9505
+ this.clients = /* @__PURE__ */ new Set();
9506
+ this._shouldEmitClose = false;
9507
+ }
9508
+ this.options = options;
9509
+ this._state = RUNNING;
9510
+ }
9511
+ /**
9512
+ * Returns the bound address, the address family name, and port of the server
9513
+ * as reported by the operating system if listening on an IP socket.
9514
+ * If the server is listening on a pipe or UNIX domain socket, the name is
9515
+ * returned as a string.
9516
+ *
9517
+ * @return {(Object|String|null)} The address of the server
9518
+ * @public
9519
+ */
9520
+ address() {
9521
+ if (this.options.noServer) throw new Error("The server is operating in \"noServer\" mode");
9522
+ if (!this._server) return null;
9523
+ return this._server.address();
9524
+ }
9525
+ /**
9526
+ * Stop the server from accepting new connections and emit the `'close'` event
9527
+ * when all existing connections are closed.
9528
+ *
9529
+ * @param {Function} [cb] A one-time listener for the `'close'` event
9530
+ * @public
9531
+ */
9532
+ close(cb) {
9533
+ if (this._state === CLOSED) {
9534
+ if (cb) this.once("close", () => {
9535
+ cb(/* @__PURE__ */ new Error("The server is not running"));
9536
+ });
9537
+ process.nextTick(emitClose, this);
9538
+ return;
9539
+ }
9540
+ if (cb) this.once("close", cb);
9541
+ if (this._state === CLOSING) return;
9542
+ this._state = CLOSING;
9543
+ if (this.options.noServer || this.options.server) {
9544
+ if (this._server) {
9545
+ this._removeListeners();
9546
+ this._removeListeners = this._server = null;
9547
+ }
9548
+ if (this.clients) if (!this.clients.size) process.nextTick(emitClose, this);
9549
+ else this._shouldEmitClose = true;
9550
+ else process.nextTick(emitClose, this);
9551
+ } else {
9552
+ const server = this._server;
9553
+ this._removeListeners();
9554
+ this._removeListeners = this._server = null;
9555
+ server.close(() => {
9556
+ emitClose(this);
9557
+ });
9558
+ }
9559
+ }
9560
+ /**
9561
+ * See if a given request should be handled by this server instance.
9562
+ *
9563
+ * @param {http.IncomingMessage} req Request object to inspect
9564
+ * @return {Boolean} `true` if the request is valid, else `false`
9565
+ * @public
9566
+ */
9567
+ shouldHandle(req) {
9568
+ if (this.options.path) {
9569
+ const index = req.url.indexOf("?");
9570
+ if ((index !== -1 ? req.url.slice(0, index) : req.url) !== this.options.path) return false;
9571
+ }
9572
+ return true;
9573
+ }
9574
+ /**
9575
+ * Handle a HTTP Upgrade request.
9576
+ *
9577
+ * @param {http.IncomingMessage} req The request object
9578
+ * @param {Duplex} socket The network socket between the server and client
9579
+ * @param {Buffer} head The first packet of the upgraded stream
9580
+ * @param {Function} cb Callback
9581
+ * @public
9582
+ */
9583
+ handleUpgrade(req, socket, head, cb) {
9584
+ socket.on("error", socketOnError);
9585
+ const key = req.headers["sec-websocket-key"];
9586
+ const upgrade = req.headers.upgrade;
9587
+ const version = +req.headers["sec-websocket-version"];
9588
+ if (req.method !== "GET") {
9589
+ abortHandshakeOrEmitwsClientError(this, req, socket, 405, "Invalid HTTP method");
9590
+ return;
9591
+ }
9592
+ if (upgrade === void 0 || upgrade.toLowerCase() !== "websocket") {
9593
+ abortHandshakeOrEmitwsClientError(this, req, socket, 400, "Invalid Upgrade header");
9594
+ return;
9595
+ }
9596
+ if (key === void 0 || !keyRegex.test(key)) {
9597
+ abortHandshakeOrEmitwsClientError(this, req, socket, 400, "Missing or invalid Sec-WebSocket-Key header");
9598
+ return;
9599
+ }
9600
+ if (version !== 13 && version !== 8) {
9601
+ abortHandshakeOrEmitwsClientError(this, req, socket, 400, "Missing or invalid Sec-WebSocket-Version header", { "Sec-WebSocket-Version": "13, 8" });
9602
+ return;
9603
+ }
9604
+ if (!this.shouldHandle(req)) {
9605
+ abortHandshake(socket, 400);
9606
+ return;
9607
+ }
9608
+ const secWebSocketProtocol = req.headers["sec-websocket-protocol"];
9609
+ let protocols = /* @__PURE__ */ new Set();
9610
+ if (secWebSocketProtocol !== void 0) try {
9611
+ protocols = subprotocol.parse(secWebSocketProtocol);
9612
+ } catch (err) {
9613
+ abortHandshakeOrEmitwsClientError(this, req, socket, 400, "Invalid Sec-WebSocket-Protocol header");
9614
+ return;
9615
+ }
9616
+ const secWebSocketExtensions = req.headers["sec-websocket-extensions"];
9617
+ const extensions = {};
9618
+ if (this.options.perMessageDeflate && secWebSocketExtensions !== void 0) {
9619
+ const perMessageDeflate = new PerMessageDeflate(this.options.perMessageDeflate, true, this.options.maxPayload);
9620
+ try {
9621
+ const offers = extension.parse(secWebSocketExtensions);
9622
+ if (offers[PerMessageDeflate.extensionName]) {
9623
+ perMessageDeflate.accept(offers[PerMessageDeflate.extensionName]);
9624
+ extensions[PerMessageDeflate.extensionName] = perMessageDeflate;
9625
+ }
9626
+ } catch (err) {
9627
+ abortHandshakeOrEmitwsClientError(this, req, socket, 400, "Invalid or unacceptable Sec-WebSocket-Extensions header");
9628
+ return;
9629
+ }
9630
+ }
9631
+ if (this.options.verifyClient) {
9632
+ const info = {
9633
+ origin: req.headers[`${version === 8 ? "sec-websocket-origin" : "origin"}`],
9634
+ secure: !!(req.socket.authorized || req.socket.encrypted),
9635
+ req
9636
+ };
9637
+ if (this.options.verifyClient.length === 2) {
9638
+ this.options.verifyClient(info, (verified, code, message, headers) => {
9639
+ if (!verified) return abortHandshake(socket, code || 401, message, headers);
9640
+ this.completeUpgrade(extensions, key, protocols, req, socket, head, cb);
9641
+ });
9642
+ return;
9643
+ }
9644
+ if (!this.options.verifyClient(info)) return abortHandshake(socket, 401);
9645
+ }
9646
+ this.completeUpgrade(extensions, key, protocols, req, socket, head, cb);
9647
+ }
9648
+ /**
9649
+ * Upgrade the connection to WebSocket.
9650
+ *
9651
+ * @param {Object} extensions The accepted extensions
9652
+ * @param {String} key The value of the `Sec-WebSocket-Key` header
9653
+ * @param {Set} protocols The subprotocols
9654
+ * @param {http.IncomingMessage} req The request object
9655
+ * @param {Duplex} socket The network socket between the server and client
9656
+ * @param {Buffer} head The first packet of the upgraded stream
9657
+ * @param {Function} cb Callback
9658
+ * @throws {Error} If called more than once with the same socket
9659
+ * @private
9660
+ */
9661
+ completeUpgrade(extensions, key, protocols, req, socket, head, cb) {
9662
+ if (!socket.readable || !socket.writable) return socket.destroy();
9663
+ if (socket[kWebSocket]) throw new Error("server.handleUpgrade() was called more than once with the same socket, possibly due to a misconfiguration");
9664
+ if (this._state > RUNNING) return abortHandshake(socket, 503);
9665
+ const headers = [
9666
+ "HTTP/1.1 101 Switching Protocols",
9667
+ "Upgrade: websocket",
9668
+ "Connection: Upgrade",
9669
+ `Sec-WebSocket-Accept: ${createHash("sha1").update(key + GUID).digest("base64")}`
9670
+ ];
9671
+ const ws = new this.options.WebSocket(null, void 0, this.options);
9672
+ if (protocols.size) {
9673
+ const protocol = this.options.handleProtocols ? this.options.handleProtocols(protocols, req) : protocols.values().next().value;
9674
+ if (protocol) {
9675
+ headers.push(`Sec-WebSocket-Protocol: ${protocol}`);
9676
+ ws._protocol = protocol;
9677
+ }
9678
+ }
9679
+ if (extensions[PerMessageDeflate.extensionName]) {
9680
+ const params = extensions[PerMessageDeflate.extensionName].params;
9681
+ const value = extension.format({ [PerMessageDeflate.extensionName]: [params] });
9682
+ headers.push(`Sec-WebSocket-Extensions: ${value}`);
9683
+ ws._extensions = extensions;
9684
+ }
9685
+ this.emit("headers", headers, req);
9686
+ socket.write(headers.concat("\r\n").join("\r\n"));
9687
+ socket.removeListener("error", socketOnError);
9688
+ ws.setSocket(socket, head, {
9689
+ allowSynchronousEvents: this.options.allowSynchronousEvents,
9690
+ maxPayload: this.options.maxPayload,
9691
+ skipUTF8Validation: this.options.skipUTF8Validation
9692
+ });
9693
+ if (this.clients) {
9694
+ this.clients.add(ws);
9695
+ ws.on("close", () => {
9696
+ this.clients.delete(ws);
9697
+ if (this._shouldEmitClose && !this.clients.size) process.nextTick(emitClose, this);
9698
+ });
9699
+ }
9700
+ cb(ws, req);
9701
+ }
9702
+ };
9703
+ module.exports = WebSocketServer;
9704
+ /**
9705
+ * Add event listeners on an `EventEmitter` using a map of <event, listener>
9706
+ * pairs.
9707
+ *
9708
+ * @param {EventEmitter} server The event emitter
9709
+ * @param {Object.<String, Function>} map The listeners to add
9710
+ * @return {Function} A function that will remove the added listeners when
9711
+ * called
9712
+ * @private
9713
+ */
9714
+ function addListeners(server, map) {
9715
+ for (const event of Object.keys(map)) server.on(event, map[event]);
9716
+ return function removeListeners() {
9717
+ for (const event of Object.keys(map)) server.removeListener(event, map[event]);
9718
+ };
9719
+ }
9720
+ /**
9721
+ * Emit a `'close'` event on an `EventEmitter`.
9722
+ *
9723
+ * @param {EventEmitter} server The event emitter
9724
+ * @private
9725
+ */
9726
+ function emitClose(server) {
9727
+ server._state = CLOSED;
9728
+ server.emit("close");
9729
+ }
9730
+ /**
9731
+ * Handle socket errors.
9732
+ *
9733
+ * @private
9734
+ */
9735
+ function socketOnError() {
9736
+ this.destroy();
9737
+ }
9738
+ /**
9739
+ * Close the connection when preconditions are not fulfilled.
9740
+ *
9741
+ * @param {Duplex} socket The socket of the upgrade request
9742
+ * @param {Number} code The HTTP response status code
9743
+ * @param {String} [message] The HTTP response body
9744
+ * @param {Object} [headers] Additional HTTP response headers
9745
+ * @private
9746
+ */
9747
+ function abortHandshake(socket, code, message, headers) {
9748
+ message = message || http.STATUS_CODES[code];
9749
+ headers = {
9750
+ Connection: "close",
9751
+ "Content-Type": "text/html",
9752
+ "Content-Length": Buffer.byteLength(message),
9753
+ ...headers
9754
+ };
9755
+ socket.once("finish", socket.destroy);
9756
+ socket.end(`HTTP/1.1 ${code} ${http.STATUS_CODES[code]}\r\n` + Object.keys(headers).map((h) => `${h}: ${headers[h]}`).join("\r\n") + "\r\n\r\n" + message);
9757
+ }
9758
+ /**
9759
+ * Emit a `'wsClientError'` event on a `WebSocketServer` if there is at least
9760
+ * one listener for it, otherwise call `abortHandshake()`.
9761
+ *
9762
+ * @param {WebSocketServer} server The WebSocket server
9763
+ * @param {http.IncomingMessage} req The request object
9764
+ * @param {Duplex} socket The socket of the upgrade request
9765
+ * @param {Number} code The HTTP response status code
9766
+ * @param {String} message The HTTP response body
9767
+ * @param {Object} [headers] The HTTP response headers
9768
+ * @private
9769
+ */
9770
+ function abortHandshakeOrEmitwsClientError(server, req, socket, code, message, headers) {
9771
+ if (server.listenerCount("wsClientError")) {
9772
+ const err = new Error(message);
9773
+ Error.captureStackTrace(err, abortHandshakeOrEmitwsClientError);
9774
+ server.emit("wsClientError", err, socket, req);
9775
+ } else abortHandshake(socket, code, message, headers);
9776
+ }
9777
+ }));
9778
+
9779
+ //#endregion
9780
+ //#region node_modules/.pnpm/ws@8.19.0/node_modules/ws/wrapper.mjs
9781
+ var import_stream = /* @__PURE__ */ __toESM(require_stream(), 1);
9782
+ var import_receiver = /* @__PURE__ */ __toESM(require_receiver(), 1);
9783
+ var import_sender = /* @__PURE__ */ __toESM(require_sender(), 1);
9784
+ var import_websocket = /* @__PURE__ */ __toESM(require_websocket(), 1);
9785
+ var import_websocket_server = /* @__PURE__ */ __toESM(require_websocket_server(), 1);
9786
+
9787
+ //#endregion
9788
+ //#region src/proxy/websocket-proxy.ts
9789
+ /**
9790
+ * WebSocket-to-TCP Proxy for Cap'n Proto
9791
+ *
9792
+ * Allows browsers to connect to native Cap'n Proto services (C++, etc.)
9793
+ * via WebSocket. Handles the protocol bridging between WebSocket (browser)
9794
+ * and raw TCP (Cap'n Proto services).
9795
+ */
9796
+ var ProxyConnection = class extends EventEmitter {
9797
+ ws;
9798
+ tcpSocket = null;
9799
+ stats;
9800
+ options;
9801
+ closed = false;
9802
+ constructor(ws, options) {
9803
+ super();
9804
+ this.ws = ws;
9805
+ this.options = options;
9806
+ this.stats = {
9807
+ wsMessagesIn: 0,
9808
+ wsMessagesOut: 0,
9809
+ tcpBytesIn: 0,
9810
+ tcpBytesOut: 0,
9811
+ connectedAt: /* @__PURE__ */ new Date()
9812
+ };
9813
+ this.setupWebSocket();
9814
+ }
9815
+ setupWebSocket() {
9816
+ this.ws.on("message", (data) => {
9817
+ this.handleWebSocketMessage(data);
9818
+ });
9819
+ this.ws.on("close", () => {
9820
+ this.log("WebSocket closed");
9821
+ this.close();
9822
+ });
9823
+ this.ws.on("error", (err) => {
9824
+ this.log("WebSocket error:", err);
9825
+ this.emit("error", err);
9826
+ this.close();
9827
+ });
9828
+ this.connectToTarget();
9829
+ }
9830
+ connectToTarget() {
9831
+ const timeout = this.options.connectionTimeout ?? 3e4;
9832
+ this.tcpSocket = createConnection({
9833
+ host: this.options.targetHost,
9834
+ port: this.options.targetPort,
9835
+ timeout
9836
+ });
9837
+ this.tcpSocket.on("connect", () => {
9838
+ this.log("Connected to target TCP service");
9839
+ this.emit("connected");
9840
+ });
9841
+ this.tcpSocket.on("data", (data) => {
9842
+ this.handleTcpData(data);
9843
+ });
9844
+ this.tcpSocket.on("close", () => {
9845
+ this.log("TCP connection closed");
9846
+ this.close();
9847
+ });
9848
+ this.tcpSocket.on("error", (err) => {
9849
+ this.log("TCP error:", err);
9850
+ this.emit("error", err);
9851
+ this.close();
9852
+ });
9853
+ this.tcpSocket.on("timeout", () => {
9854
+ this.log("TCP connection timeout");
9855
+ this.close();
9856
+ });
9857
+ }
9858
+ handleWebSocketMessage(data) {
9859
+ if (this.closed) return;
9860
+ const buffer = Buffer.isBuffer(data) ? data : Array.isArray(data) ? Buffer.concat(data) : Buffer.from(data);
9861
+ const maxSize = this.options.maxMessageSize ?? 16 * 1024 * 1024;
9862
+ if (buffer.length > maxSize) {
9863
+ this.log(`Message too large: ${buffer.length} bytes`);
9864
+ this.close();
9865
+ return;
9866
+ }
9867
+ this.stats.wsMessagesIn++;
9868
+ this.stats.tcpBytesOut += buffer.length;
9869
+ if (this.tcpSocket?.writable) {
9870
+ this.tcpSocket.write(buffer);
9871
+ this.log(`Forwarded ${buffer.length} bytes to TCP`);
9872
+ }
9873
+ }
9874
+ handleTcpData(data) {
9875
+ if (this.closed) return;
9876
+ this.stats.tcpBytesIn += data.length;
9877
+ this.stats.wsMessagesOut++;
9878
+ if (this.ws.readyState === import_websocket.default.OPEN) {
9879
+ this.ws.send(data);
9880
+ this.log(`Forwarded ${data.length} bytes to WebSocket`);
9881
+ }
9882
+ }
9883
+ log(...args) {
9884
+ if (this.options.debug) console.log("[ProxyConnection]", ...args);
9885
+ }
9886
+ getStats() {
9887
+ return { ...this.stats };
9888
+ }
9889
+ close() {
9890
+ if (this.closed) return;
9891
+ this.closed = true;
9892
+ this.ws.close();
9893
+ this.tcpSocket?.destroy();
9894
+ this.emit("closed");
9895
+ }
9896
+ };
9897
+ var CapnpWebSocketProxy = class extends EventEmitter {
9898
+ wss;
9899
+ connections = /* @__PURE__ */ new Map();
9900
+ options;
9901
+ constructor(options) {
9902
+ super();
9903
+ this.options = options;
9904
+ this.wss = new import_websocket_server.default({ port: options.wsPort });
9905
+ this.setupServer();
9906
+ }
9907
+ setupServer() {
9908
+ this.wss.on("connection", (ws, req) => {
9909
+ const clientIp = req.socket.remoteAddress;
9910
+ this.log(`New WebSocket connection from ${clientIp}`);
9911
+ const connection = new ProxyConnection(ws, this.options);
9912
+ this.connections.set(ws, connection);
9913
+ connection.on("connected", () => {
9914
+ this.emit("connection", connection);
9915
+ });
9916
+ connection.on("error", (err) => {
9917
+ this.emit("error", err, connection);
9918
+ });
9919
+ connection.on("closed", () => {
9920
+ this.connections.delete(ws);
9921
+ this.emit("disconnection", connection);
9922
+ });
9923
+ });
9924
+ this.wss.on("error", (err) => {
9925
+ this.emit("error", err);
9926
+ });
9927
+ }
9928
+ log(...args) {
9929
+ if (this.options.debug) console.log("[CapnpWebSocketProxy]", ...args);
9930
+ }
9931
+ getConnectionCount() {
9932
+ return this.connections.size;
9933
+ }
9934
+ getAllStats() {
9935
+ return Array.from(this.connections.values()).map((c) => c.getStats());
9936
+ }
9937
+ close() {
9938
+ return new Promise((resolve) => {
9939
+ for (const connection of this.connections.values()) connection.close();
9940
+ this.connections.clear();
9941
+ this.wss.close(() => {
9942
+ this.emit("closed");
9943
+ resolve();
9944
+ });
9945
+ });
9946
+ }
9947
+ };
9948
+ if (import.meta.url === `file://${process.argv[1]}`) {
9949
+ const args = process.argv.slice(2);
9950
+ let wsPort = 8080;
9951
+ let targetHost = "localhost";
9952
+ let targetPort = 8081;
9953
+ let debug = false;
9954
+ for (let i = 0; i < args.length; i++) switch (args[i]) {
9955
+ case "--ws-port":
9956
+ case "-p":
9957
+ wsPort = Number.parseInt(args[++i], 10);
9958
+ break;
9959
+ case "--target":
9960
+ case "-t": {
9961
+ const [host, port] = args[++i].split(":");
9962
+ targetHost = host;
9963
+ targetPort = Number.parseInt(port, 10);
9964
+ break;
9965
+ }
9966
+ case "--debug":
9967
+ case "-d":
9968
+ debug = true;
9969
+ break;
9970
+ case "--help":
9971
+ case "-h":
9972
+ console.log(`
9973
+ Cap'n Proto WebSocket-to-TCP Proxy
9974
+
9975
+ Usage: npx @naeemo/capnp proxy [options]
9976
+
9977
+ Options:
9978
+ -p, --ws-port <port> WebSocket server port (default: 8080)
9979
+ -t, --target <host:port> Target TCP service (default: localhost:8081)
9980
+ -d, --debug Enable debug logging
9981
+ -h, --help Show this help
9982
+
9983
+ Example:
9984
+ npx @naeemo/capnp proxy -p 9000 -t 192.168.1.100:7000
9985
+ `);
9986
+ process.exit(0);
9987
+ }
9988
+ const proxy = new CapnpWebSocketProxy({
9989
+ wsPort,
9990
+ targetHost,
9991
+ targetPort,
9992
+ debug
9993
+ });
9994
+ console.log("WebSocket-to-TCP Proxy started");
9995
+ console.log(` WebSocket: ws://localhost:${wsPort}`);
9996
+ console.log(` Target: ${targetHost}:${targetPort}`);
9997
+ proxy.on("connection", () => {
9998
+ console.log(`Active connections: ${proxy.getConnectionCount()}`);
9999
+ });
10000
+ proxy.on("disconnection", () => {
10001
+ console.log(`Active connections: ${proxy.getConnectionCount()}`);
10002
+ });
10003
+ process.on("SIGINT", async () => {
10004
+ console.log("\nShutting down...");
10005
+ await proxy.close();
10006
+ process.exit(0);
10007
+ });
10008
+ }
10009
+
10010
+ //#endregion
10011
+ export { AnswerTable, BaseCapabilityClient, BulkTransfer, BulkTransferManager, CapnpWebSocketProxy, ConnectionManager, DEFAULT_BULK_CONFIG, DEFAULT_ESCROW_CONFIG, DEFAULT_FLOW_CONTROL, DEFAULT_JOIN_OPTIONS, DEFAULT_JOIN_SECURITY_POLICY, DEFAULT_REALTIME_CONFIG, DEFAULT_STREAMING_CAPABILITIES, DropPolicy, ElementSize, ExportTable, EzRpcTransport, ImportTable, Level3Handlers, Level4Handlers, ListBuilder, ListReader, MemoryPool, MessageBuilder, MessageReader, MultiSegmentMessageBuilder, OptimizedRpcMessageBuilder, PIPELINE_CLIENT_SYMBOL, PipelineOpTracker, PipelineResolutionTracker, PointerTag, QuestionTable, QueuedCallManager, RealtimeStream, RealtimeStreamManager, RestoreHandler, RpcConnection, SCHEMA_MESSAGE_TYPES, SchemaCapabilityClient, SchemaCapabilityServer, SchemaFormat, Segment, Stream, StreamManager, StreamPriority, StreamType, StreamingRpcConnection, StructBuilder, StructReader, SturdyRefManager, TcpTransport, UnionBuilder, UnionReader, WORD_SIZE, WebSocketTransport, configureGlobalMemoryPool, createBulkTransferManager, createDynamicReader, createDynamicReaderByTypeId, createDynamicReaderFromStruct, createDynamicWriter, createDynamicWriterByTypeId, createNestedDynamicWriter, createPipelineClient, createProvisionId, createRealtimeStreamManager, createRecipientId, createSchemaRegistry, createStream, createStreamManager, createStreamingConnection, createSturdyRef, createThirdPartyCapId, createUnionBuilder, createUnionReader, createZeroCopyView, decodePointer, deserializeRpcMessage, deserializeSchemaRequest, deserializeSchemaResponse, deserializeSturdyRef, dumpDynamicReader, encodeListPointer, encodeStructPointer, fastCopy, generateProvisionId, generateVatId, getGlobalMemoryPool, isPipelineClient, isSameBuffer, isStream, isSturdyRefValid, parseSchemaNodes, serializeDynamic, serializeDynamicByTypeId, serializeGetSchemaParams, serializeGetSchemaResults, serializeListSchemasResults, serializeRpcMessage, serializeSchemaRequest, serializeSchemaResponse, serializeSturdyRef, supportsStreaming };
6196
10012
  //# sourceMappingURL=index.js.map