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