go-chat-sdk 1.0.0 → 1.0.2

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.mjs CHANGED
@@ -1,3 +1,28 @@
1
+ import { createRequire } from "node:module";
2
+ //#region \0rolldown/runtime.js
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod), cb = null), mod.exports);
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
12
+ key = keys[i];
13
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
14
+ get: ((k) => from[k]).bind(null, key),
15
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
16
+ });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
21
+ value: mod,
22
+ enumerable: true
23
+ }) : target, mod));
24
+ var __require = /* @__PURE__ */ createRequire(import.meta.url);
25
+ //#endregion
1
26
  //#region types.ts
2
27
  let ChatType = /* @__PURE__ */ function(ChatType) {
3
28
  ChatType["Single"] = "single";
@@ -108,8 +133,7 @@ var APIClient = class {
108
133
  */
109
134
  async getHistoryMessages(params) {
110
135
  const queryParams = new URLSearchParams();
111
- queryParams.append("receiver_id", params.receiver_id);
112
- queryParams.append("chat_type", params.chat_type);
136
+ queryParams.append("room_id", params.room_id);
113
137
  if (params.before_server_time !== void 0) queryParams.append("before_server_time", params.before_server_time.toString());
114
138
  if (params.page_size !== void 0) queryParams.append("page_size", params.page_size.toString());
115
139
  const messages = await this.request("GET", `/api/v1/messages/history?${queryParams.toString()}`);
@@ -238,95 +262,3611 @@ function createStateChange(state, previousState) {
238
262
  };
239
263
  }
240
264
  //#endregion
241
- //#region websocket.ts
242
- /**
243
- * WebSocket 连接管理器
244
- */
245
- var WebSocketManager = class {
246
- constructor(options, emitter) {
247
- this.ws = null;
248
- this.currentState = "disconnected";
249
- this.reconnectAttempts = 0;
250
- this.reconnectTimer = null;
251
- this.heartbeatTimer = null;
252
- this.messageQueue = [];
253
- this.token = null;
254
- this.intentionalClose = false;
255
- this.options = {
256
- baseURL: options.baseURL,
257
- gatewayURL: options.gatewayURL,
258
- reconnectInterval: options.reconnectInterval ?? 3e3,
259
- maxReconnectAttempts: options.maxReconnectAttempts ?? 10,
260
- heartbeatInterval: options.heartbeatInterval ?? 3e4,
261
- messageBufferSize: options.messageBufferSize ?? 100
265
+ //#region node_modules/.pnpm/ws@8.20.0/node_modules/ws/lib/constants.js
266
+ var require_constants = /* @__PURE__ */ __commonJSMin(((exports, module) => {
267
+ const BINARY_TYPES = [
268
+ "nodebuffer",
269
+ "arraybuffer",
270
+ "fragments"
271
+ ];
272
+ const hasBlob = typeof Blob !== "undefined";
273
+ if (hasBlob) BINARY_TYPES.push("blob");
274
+ module.exports = {
275
+ BINARY_TYPES,
276
+ CLOSE_TIMEOUT: 3e4,
277
+ EMPTY_BUFFER: Buffer.alloc(0),
278
+ GUID: "258EAFA5-E914-47DA-95CA-C5AB0DC85B11",
279
+ hasBlob,
280
+ kForOnEventAttribute: Symbol("kIsForOnEventAttribute"),
281
+ kListener: Symbol("kListener"),
282
+ kStatusCode: Symbol("status-code"),
283
+ kWebSocket: Symbol("websocket"),
284
+ NOOP: () => {}
285
+ };
286
+ }));
287
+ //#endregion
288
+ //#region node_modules/.pnpm/ws@8.20.0/node_modules/ws/lib/buffer-util.js
289
+ var require_buffer_util = /* @__PURE__ */ __commonJSMin(((exports, module) => {
290
+ const { EMPTY_BUFFER } = require_constants();
291
+ const FastBuffer = Buffer[Symbol.species];
292
+ /**
293
+ * Merges an array of buffers into a new buffer.
294
+ *
295
+ * @param {Buffer[]} list The array of buffers to concat
296
+ * @param {Number} totalLength The total length of buffers in the list
297
+ * @return {Buffer} The resulting buffer
298
+ * @public
299
+ */
300
+ function concat(list, totalLength) {
301
+ if (list.length === 0) return EMPTY_BUFFER;
302
+ if (list.length === 1) return list[0];
303
+ const target = Buffer.allocUnsafe(totalLength);
304
+ let offset = 0;
305
+ for (let i = 0; i < list.length; i++) {
306
+ const buf = list[i];
307
+ target.set(buf, offset);
308
+ offset += buf.length;
309
+ }
310
+ if (offset < totalLength) return new FastBuffer(target.buffer, target.byteOffset, offset);
311
+ return target;
312
+ }
313
+ /**
314
+ * Masks a buffer using the given mask.
315
+ *
316
+ * @param {Buffer} source The buffer to mask
317
+ * @param {Buffer} mask The mask to use
318
+ * @param {Buffer} output The buffer where to store the result
319
+ * @param {Number} offset The offset at which to start writing
320
+ * @param {Number} length The number of bytes to mask.
321
+ * @public
322
+ */
323
+ function _mask(source, mask, output, offset, length) {
324
+ for (let i = 0; i < length; i++) output[offset + i] = source[i] ^ mask[i & 3];
325
+ }
326
+ /**
327
+ * Unmasks a buffer using the given mask.
328
+ *
329
+ * @param {Buffer} buffer The buffer to unmask
330
+ * @param {Buffer} mask The mask to use
331
+ * @public
332
+ */
333
+ function _unmask(buffer, mask) {
334
+ for (let i = 0; i < buffer.length; i++) buffer[i] ^= mask[i & 3];
335
+ }
336
+ /**
337
+ * Converts a buffer to an `ArrayBuffer`.
338
+ *
339
+ * @param {Buffer} buf The buffer to convert
340
+ * @return {ArrayBuffer} Converted buffer
341
+ * @public
342
+ */
343
+ function toArrayBuffer(buf) {
344
+ if (buf.length === buf.buffer.byteLength) return buf.buffer;
345
+ return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.length);
346
+ }
347
+ /**
348
+ * Converts `data` to a `Buffer`.
349
+ *
350
+ * @param {*} data The data to convert
351
+ * @return {Buffer} The buffer
352
+ * @throws {TypeError}
353
+ * @public
354
+ */
355
+ function toBuffer(data) {
356
+ toBuffer.readOnly = true;
357
+ if (Buffer.isBuffer(data)) return data;
358
+ let buf;
359
+ if (data instanceof ArrayBuffer) buf = new FastBuffer(data);
360
+ else if (ArrayBuffer.isView(data)) buf = new FastBuffer(data.buffer, data.byteOffset, data.byteLength);
361
+ else {
362
+ buf = Buffer.from(data);
363
+ toBuffer.readOnly = false;
364
+ }
365
+ return buf;
366
+ }
367
+ module.exports = {
368
+ concat,
369
+ mask: _mask,
370
+ toArrayBuffer,
371
+ toBuffer,
372
+ unmask: _unmask
373
+ };
374
+ /* istanbul ignore else */
375
+ if (!process.env.WS_NO_BUFFER_UTIL) try {
376
+ const bufferUtil = __require("bufferutil");
377
+ module.exports.mask = function(source, mask, output, offset, length) {
378
+ if (length < 48) _mask(source, mask, output, offset, length);
379
+ else bufferUtil.mask(source, mask, output, offset, length);
262
380
  };
263
- this.emitter = emitter;
381
+ module.exports.unmask = function(buffer, mask) {
382
+ if (buffer.length < 32) _unmask(buffer, mask);
383
+ else bufferUtil.unmask(buffer, mask);
384
+ };
385
+ } catch (e) {}
386
+ }));
387
+ //#endregion
388
+ //#region node_modules/.pnpm/ws@8.20.0/node_modules/ws/lib/limiter.js
389
+ var require_limiter = /* @__PURE__ */ __commonJSMin(((exports, module) => {
390
+ const kDone = Symbol("kDone");
391
+ const kRun = Symbol("kRun");
392
+ /**
393
+ * A very simple job queue with adjustable concurrency. Adapted from
394
+ * https://github.com/STRML/async-limiter
395
+ */
396
+ var Limiter = class {
397
+ /**
398
+ * Creates a new `Limiter`.
399
+ *
400
+ * @param {Number} [concurrency=Infinity] The maximum number of jobs allowed
401
+ * to run concurrently
402
+ */
403
+ constructor(concurrency) {
404
+ this[kDone] = () => {
405
+ this.pending--;
406
+ this[kRun]();
407
+ };
408
+ this.concurrency = concurrency || Infinity;
409
+ this.jobs = [];
410
+ this.pending = 0;
411
+ }
412
+ /**
413
+ * Adds a job to the queue.
414
+ *
415
+ * @param {Function} job The job to run
416
+ * @public
417
+ */
418
+ add(job) {
419
+ this.jobs.push(job);
420
+ this[kRun]();
421
+ }
422
+ /**
423
+ * Removes a job from the queue and runs it if possible.
424
+ *
425
+ * @private
426
+ */
427
+ [kRun]() {
428
+ if (this.pending === this.concurrency) return;
429
+ if (this.jobs.length) {
430
+ const job = this.jobs.shift();
431
+ this.pending++;
432
+ job(this[kDone]);
433
+ }
434
+ }
435
+ };
436
+ module.exports = Limiter;
437
+ }));
438
+ //#endregion
439
+ //#region node_modules/.pnpm/ws@8.20.0/node_modules/ws/lib/permessage-deflate.js
440
+ var require_permessage_deflate = /* @__PURE__ */ __commonJSMin(((exports, module) => {
441
+ const zlib = __require("zlib");
442
+ const bufferUtil = require_buffer_util();
443
+ const Limiter = require_limiter();
444
+ const { kStatusCode } = require_constants();
445
+ const FastBuffer = Buffer[Symbol.species];
446
+ const TRAILER = Buffer.from([
447
+ 0,
448
+ 0,
449
+ 255,
450
+ 255
451
+ ]);
452
+ const kPerMessageDeflate = Symbol("permessage-deflate");
453
+ const kTotalLength = Symbol("total-length");
454
+ const kCallback = Symbol("callback");
455
+ const kBuffers = Symbol("buffers");
456
+ const kError = Symbol("error");
457
+ let zlibLimiter;
458
+ /**
459
+ * permessage-deflate implementation.
460
+ */
461
+ var PerMessageDeflate = class {
462
+ /**
463
+ * Creates a PerMessageDeflate instance.
464
+ *
465
+ * @param {Object} [options] Configuration options
466
+ * @param {(Boolean|Number)} [options.clientMaxWindowBits] Advertise support
467
+ * for, or request, a custom client window size
468
+ * @param {Boolean} [options.clientNoContextTakeover=false] Advertise/
469
+ * acknowledge disabling of client context takeover
470
+ * @param {Number} [options.concurrencyLimit=10] The number of concurrent
471
+ * calls to zlib
472
+ * @param {Boolean} [options.isServer=false] Create the instance in either
473
+ * server or client mode
474
+ * @param {Number} [options.maxPayload=0] The maximum allowed message length
475
+ * @param {(Boolean|Number)} [options.serverMaxWindowBits] Request/confirm the
476
+ * use of a custom server window size
477
+ * @param {Boolean} [options.serverNoContextTakeover=false] Request/accept
478
+ * disabling of server context takeover
479
+ * @param {Number} [options.threshold=1024] Size (in bytes) below which
480
+ * messages should not be compressed if context takeover is disabled
481
+ * @param {Object} [options.zlibDeflateOptions] Options to pass to zlib on
482
+ * deflate
483
+ * @param {Object} [options.zlibInflateOptions] Options to pass to zlib on
484
+ * inflate
485
+ */
486
+ constructor(options) {
487
+ this._options = options || {};
488
+ this._threshold = this._options.threshold !== void 0 ? this._options.threshold : 1024;
489
+ this._maxPayload = this._options.maxPayload | 0;
490
+ this._isServer = !!this._options.isServer;
491
+ this._deflate = null;
492
+ this._inflate = null;
493
+ this.params = null;
494
+ if (!zlibLimiter) zlibLimiter = new Limiter(this._options.concurrencyLimit !== void 0 ? this._options.concurrencyLimit : 10);
495
+ }
496
+ /**
497
+ * @type {String}
498
+ */
499
+ static get extensionName() {
500
+ return "permessage-deflate";
501
+ }
502
+ /**
503
+ * Create an extension negotiation offer.
504
+ *
505
+ * @return {Object} Extension parameters
506
+ * @public
507
+ */
508
+ offer() {
509
+ const params = {};
510
+ if (this._options.serverNoContextTakeover) params.server_no_context_takeover = true;
511
+ if (this._options.clientNoContextTakeover) params.client_no_context_takeover = true;
512
+ if (this._options.serverMaxWindowBits) params.server_max_window_bits = this._options.serverMaxWindowBits;
513
+ if (this._options.clientMaxWindowBits) params.client_max_window_bits = this._options.clientMaxWindowBits;
514
+ else if (this._options.clientMaxWindowBits == null) params.client_max_window_bits = true;
515
+ return params;
516
+ }
517
+ /**
518
+ * Accept an extension negotiation offer/response.
519
+ *
520
+ * @param {Array} configurations The extension negotiation offers/reponse
521
+ * @return {Object} Accepted configuration
522
+ * @public
523
+ */
524
+ accept(configurations) {
525
+ configurations = this.normalizeParams(configurations);
526
+ this.params = this._isServer ? this.acceptAsServer(configurations) : this.acceptAsClient(configurations);
527
+ return this.params;
528
+ }
529
+ /**
530
+ * Releases all resources used by the extension.
531
+ *
532
+ * @public
533
+ */
534
+ cleanup() {
535
+ if (this._inflate) {
536
+ this._inflate.close();
537
+ this._inflate = null;
538
+ }
539
+ if (this._deflate) {
540
+ const callback = this._deflate[kCallback];
541
+ this._deflate.close();
542
+ this._deflate = null;
543
+ if (callback) callback(/* @__PURE__ */ new Error("The deflate stream was closed while data was being processed"));
544
+ }
545
+ }
546
+ /**
547
+ * Accept an extension negotiation offer.
548
+ *
549
+ * @param {Array} offers The extension negotiation offers
550
+ * @return {Object} Accepted configuration
551
+ * @private
552
+ */
553
+ acceptAsServer(offers) {
554
+ const opts = this._options;
555
+ const accepted = offers.find((params) => {
556
+ 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;
557
+ return true;
558
+ });
559
+ if (!accepted) throw new Error("None of the extension offers can be accepted");
560
+ if (opts.serverNoContextTakeover) accepted.server_no_context_takeover = true;
561
+ if (opts.clientNoContextTakeover) accepted.client_no_context_takeover = true;
562
+ if (typeof opts.serverMaxWindowBits === "number") accepted.server_max_window_bits = opts.serverMaxWindowBits;
563
+ if (typeof opts.clientMaxWindowBits === "number") accepted.client_max_window_bits = opts.clientMaxWindowBits;
564
+ else if (accepted.client_max_window_bits === true || opts.clientMaxWindowBits === false) delete accepted.client_max_window_bits;
565
+ return accepted;
566
+ }
567
+ /**
568
+ * Accept the extension negotiation response.
569
+ *
570
+ * @param {Array} response The extension negotiation response
571
+ * @return {Object} Accepted configuration
572
+ * @private
573
+ */
574
+ acceptAsClient(response) {
575
+ const params = response[0];
576
+ if (this._options.clientNoContextTakeover === false && params.client_no_context_takeover) throw new Error("Unexpected parameter \"client_no_context_takeover\"");
577
+ if (!params.client_max_window_bits) {
578
+ if (typeof this._options.clientMaxWindowBits === "number") params.client_max_window_bits = this._options.clientMaxWindowBits;
579
+ } 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\"");
580
+ return params;
581
+ }
582
+ /**
583
+ * Normalize parameters.
584
+ *
585
+ * @param {Array} configurations The extension negotiation offers/reponse
586
+ * @return {Array} The offers/response with normalized parameters
587
+ * @private
588
+ */
589
+ normalizeParams(configurations) {
590
+ configurations.forEach((params) => {
591
+ Object.keys(params).forEach((key) => {
592
+ let value = params[key];
593
+ if (value.length > 1) throw new Error(`Parameter "${key}" must have only a single value`);
594
+ value = value[0];
595
+ if (key === "client_max_window_bits") {
596
+ if (value !== true) {
597
+ const num = +value;
598
+ if (!Number.isInteger(num) || num < 8 || num > 15) throw new TypeError(`Invalid value for parameter "${key}": ${value}`);
599
+ value = num;
600
+ } else if (!this._isServer) throw new TypeError(`Invalid value for parameter "${key}": ${value}`);
601
+ } else if (key === "server_max_window_bits") {
602
+ const num = +value;
603
+ if (!Number.isInteger(num) || num < 8 || num > 15) throw new TypeError(`Invalid value for parameter "${key}": ${value}`);
604
+ value = num;
605
+ } else if (key === "client_no_context_takeover" || key === "server_no_context_takeover") {
606
+ if (value !== true) throw new TypeError(`Invalid value for parameter "${key}": ${value}`);
607
+ } else throw new Error(`Unknown parameter "${key}"`);
608
+ params[key] = value;
609
+ });
610
+ });
611
+ return configurations;
612
+ }
613
+ /**
614
+ * Decompress data. Concurrency limited.
615
+ *
616
+ * @param {Buffer} data Compressed data
617
+ * @param {Boolean} fin Specifies whether or not this is the last fragment
618
+ * @param {Function} callback Callback
619
+ * @public
620
+ */
621
+ decompress(data, fin, callback) {
622
+ zlibLimiter.add((done) => {
623
+ this._decompress(data, fin, (err, result) => {
624
+ done();
625
+ callback(err, result);
626
+ });
627
+ });
628
+ }
629
+ /**
630
+ * Compress data. Concurrency limited.
631
+ *
632
+ * @param {(Buffer|String)} data Data to compress
633
+ * @param {Boolean} fin Specifies whether or not this is the last fragment
634
+ * @param {Function} callback Callback
635
+ * @public
636
+ */
637
+ compress(data, fin, callback) {
638
+ zlibLimiter.add((done) => {
639
+ this._compress(data, fin, (err, result) => {
640
+ done();
641
+ callback(err, result);
642
+ });
643
+ });
644
+ }
645
+ /**
646
+ * Decompress data.
647
+ *
648
+ * @param {Buffer} data Compressed data
649
+ * @param {Boolean} fin Specifies whether or not this is the last fragment
650
+ * @param {Function} callback Callback
651
+ * @private
652
+ */
653
+ _decompress(data, fin, callback) {
654
+ const endpoint = this._isServer ? "client" : "server";
655
+ if (!this._inflate) {
656
+ const key = `${endpoint}_max_window_bits`;
657
+ const windowBits = typeof this.params[key] !== "number" ? zlib.Z_DEFAULT_WINDOWBITS : this.params[key];
658
+ this._inflate = zlib.createInflateRaw({
659
+ ...this._options.zlibInflateOptions,
660
+ windowBits
661
+ });
662
+ this._inflate[kPerMessageDeflate] = this;
663
+ this._inflate[kTotalLength] = 0;
664
+ this._inflate[kBuffers] = [];
665
+ this._inflate.on("error", inflateOnError);
666
+ this._inflate.on("data", inflateOnData);
667
+ }
668
+ this._inflate[kCallback] = callback;
669
+ this._inflate.write(data);
670
+ if (fin) this._inflate.write(TRAILER);
671
+ this._inflate.flush(() => {
672
+ const err = this._inflate[kError];
673
+ if (err) {
674
+ this._inflate.close();
675
+ this._inflate = null;
676
+ callback(err);
677
+ return;
678
+ }
679
+ const data = bufferUtil.concat(this._inflate[kBuffers], this._inflate[kTotalLength]);
680
+ if (this._inflate._readableState.endEmitted) {
681
+ this._inflate.close();
682
+ this._inflate = null;
683
+ } else {
684
+ this._inflate[kTotalLength] = 0;
685
+ this._inflate[kBuffers] = [];
686
+ if (fin && this.params[`${endpoint}_no_context_takeover`]) this._inflate.reset();
687
+ }
688
+ callback(null, data);
689
+ });
690
+ }
691
+ /**
692
+ * Compress data.
693
+ *
694
+ * @param {(Buffer|String)} data Data to compress
695
+ * @param {Boolean} fin Specifies whether or not this is the last fragment
696
+ * @param {Function} callback Callback
697
+ * @private
698
+ */
699
+ _compress(data, fin, callback) {
700
+ const endpoint = this._isServer ? "server" : "client";
701
+ if (!this._deflate) {
702
+ const key = `${endpoint}_max_window_bits`;
703
+ const windowBits = typeof this.params[key] !== "number" ? zlib.Z_DEFAULT_WINDOWBITS : this.params[key];
704
+ this._deflate = zlib.createDeflateRaw({
705
+ ...this._options.zlibDeflateOptions,
706
+ windowBits
707
+ });
708
+ this._deflate[kTotalLength] = 0;
709
+ this._deflate[kBuffers] = [];
710
+ this._deflate.on("data", deflateOnData);
711
+ }
712
+ this._deflate[kCallback] = callback;
713
+ this._deflate.write(data);
714
+ this._deflate.flush(zlib.Z_SYNC_FLUSH, () => {
715
+ if (!this._deflate) return;
716
+ let data = bufferUtil.concat(this._deflate[kBuffers], this._deflate[kTotalLength]);
717
+ if (fin) data = new FastBuffer(data.buffer, data.byteOffset, data.length - 4);
718
+ this._deflate[kCallback] = null;
719
+ this._deflate[kTotalLength] = 0;
720
+ this._deflate[kBuffers] = [];
721
+ if (fin && this.params[`${endpoint}_no_context_takeover`]) this._deflate.reset();
722
+ callback(null, data);
723
+ });
724
+ }
725
+ };
726
+ module.exports = PerMessageDeflate;
727
+ /**
728
+ * The listener of the `zlib.DeflateRaw` stream `'data'` event.
729
+ *
730
+ * @param {Buffer} chunk A chunk of data
731
+ * @private
732
+ */
733
+ function deflateOnData(chunk) {
734
+ this[kBuffers].push(chunk);
735
+ this[kTotalLength] += chunk.length;
264
736
  }
265
737
  /**
266
- * 设置认证 Token
738
+ * The listener of the `zlib.InflateRaw` stream `'data'` event.
739
+ *
740
+ * @param {Buffer} chunk A chunk of data
741
+ * @private
267
742
  */
268
- setToken(token) {
269
- this.token = token;
743
+ function inflateOnData(chunk) {
744
+ this[kTotalLength] += chunk.length;
745
+ if (this[kPerMessageDeflate]._maxPayload < 1 || this[kTotalLength] <= this[kPerMessageDeflate]._maxPayload) {
746
+ this[kBuffers].push(chunk);
747
+ return;
748
+ }
749
+ this[kError] = /* @__PURE__ */ new RangeError("Max payload size exceeded");
750
+ this[kError].code = "WS_ERR_UNSUPPORTED_MESSAGE_LENGTH";
751
+ this[kError][kStatusCode] = 1009;
752
+ this.removeListener("data", inflateOnData);
753
+ this.reset();
270
754
  }
271
755
  /**
272
- * 清除认证 Token
756
+ * The listener of the `zlib.InflateRaw` stream `'error'` event.
757
+ *
758
+ * @param {Error} err The emitted error
759
+ * @private
273
760
  */
274
- clearToken() {
275
- this.token = null;
761
+ function inflateOnError(err) {
762
+ this[kPerMessageDeflate]._inflate = null;
763
+ if (this[kError]) {
764
+ this[kCallback](this[kError]);
765
+ return;
766
+ }
767
+ err[kStatusCode] = 1007;
768
+ this[kCallback](err);
276
769
  }
770
+ }));
771
+ //#endregion
772
+ //#region node_modules/.pnpm/ws@8.20.0/node_modules/ws/lib/validation.js
773
+ var require_validation = /* @__PURE__ */ __commonJSMin(((exports, module) => {
774
+ const { isUtf8 } = __require("buffer");
775
+ const { hasBlob } = require_constants();
776
+ const tokenChars = [
777
+ 0,
778
+ 0,
779
+ 0,
780
+ 0,
781
+ 0,
782
+ 0,
783
+ 0,
784
+ 0,
785
+ 0,
786
+ 0,
787
+ 0,
788
+ 0,
789
+ 0,
790
+ 0,
791
+ 0,
792
+ 0,
793
+ 0,
794
+ 0,
795
+ 0,
796
+ 0,
797
+ 0,
798
+ 0,
799
+ 0,
800
+ 0,
801
+ 0,
802
+ 0,
803
+ 0,
804
+ 0,
805
+ 0,
806
+ 0,
807
+ 0,
808
+ 0,
809
+ 0,
810
+ 1,
811
+ 0,
812
+ 1,
813
+ 1,
814
+ 1,
815
+ 1,
816
+ 1,
817
+ 0,
818
+ 0,
819
+ 1,
820
+ 1,
821
+ 0,
822
+ 1,
823
+ 1,
824
+ 0,
825
+ 1,
826
+ 1,
827
+ 1,
828
+ 1,
829
+ 1,
830
+ 1,
831
+ 1,
832
+ 1,
833
+ 1,
834
+ 1,
835
+ 0,
836
+ 0,
837
+ 0,
838
+ 0,
839
+ 0,
840
+ 0,
841
+ 0,
842
+ 1,
843
+ 1,
844
+ 1,
845
+ 1,
846
+ 1,
847
+ 1,
848
+ 1,
849
+ 1,
850
+ 1,
851
+ 1,
852
+ 1,
853
+ 1,
854
+ 1,
855
+ 1,
856
+ 1,
857
+ 1,
858
+ 1,
859
+ 1,
860
+ 1,
861
+ 1,
862
+ 1,
863
+ 1,
864
+ 1,
865
+ 1,
866
+ 1,
867
+ 1,
868
+ 0,
869
+ 0,
870
+ 0,
871
+ 1,
872
+ 1,
873
+ 1,
874
+ 1,
875
+ 1,
876
+ 1,
877
+ 1,
878
+ 1,
879
+ 1,
880
+ 1,
881
+ 1,
882
+ 1,
883
+ 1,
884
+ 1,
885
+ 1,
886
+ 1,
887
+ 1,
888
+ 1,
889
+ 1,
890
+ 1,
891
+ 1,
892
+ 1,
893
+ 1,
894
+ 1,
895
+ 1,
896
+ 1,
897
+ 1,
898
+ 1,
899
+ 1,
900
+ 0,
901
+ 1,
902
+ 0,
903
+ 1,
904
+ 0
905
+ ];
277
906
  /**
278
- * 获取当前连接状态
907
+ * Checks if a status code is allowed in a close frame.
908
+ *
909
+ * @param {Number} code The status code
910
+ * @return {Boolean} `true` if the status code is valid, else `false`
911
+ * @public
279
912
  */
280
- getState() {
281
- return this.currentState;
913
+ function isValidStatusCode(code) {
914
+ return code >= 1e3 && code <= 1014 && code !== 1004 && code !== 1005 && code !== 1006 || code >= 3e3 && code <= 4999;
282
915
  }
283
916
  /**
284
- * 是否已连接
917
+ * Checks if a given buffer contains only correct UTF-8.
918
+ * Ported from https://www.cl.cam.ac.uk/%7Emgk25/ucs/utf8_check.c by
919
+ * Markus Kuhn.
920
+ *
921
+ * @param {Buffer} buf The buffer to check
922
+ * @return {Boolean} `true` if `buf` contains only correct UTF-8, else `false`
923
+ * @public
285
924
  */
286
- isConnected() {
287
- return this.currentState === "connected" && this.ws?.readyState === WebSocket.OPEN;
925
+ function _isValidUTF8(buf) {
926
+ const len = buf.length;
927
+ let i = 0;
928
+ while (i < len) if ((buf[i] & 128) === 0) i++;
929
+ else if ((buf[i] & 224) === 192) {
930
+ if (i + 1 === len || (buf[i + 1] & 192) !== 128 || (buf[i] & 254) === 192) return false;
931
+ i += 2;
932
+ } else if ((buf[i] & 240) === 224) {
933
+ 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;
934
+ i += 3;
935
+ } else if ((buf[i] & 248) === 240) {
936
+ 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;
937
+ i += 4;
938
+ } else return false;
939
+ return true;
288
940
  }
289
941
  /**
290
- * 更新连接状态并触发事件
942
+ * Determines whether a value is a `Blob`.
943
+ *
944
+ * @param {*} value The value to be tested
945
+ * @return {Boolean} `true` if `value` is a `Blob`, else `false`
946
+ * @private
291
947
  */
292
- setState(newState) {
293
- const previousState = this.currentState;
294
- this.currentState = newState;
295
- this.emitter.emit("connection:state:change", createStateChange(newState, previousState));
948
+ function isBlob(value) {
949
+ 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");
296
950
  }
951
+ module.exports = {
952
+ isBlob,
953
+ isValidStatusCode,
954
+ isValidUTF8: _isValidUTF8,
955
+ tokenChars
956
+ };
957
+ if (isUtf8) module.exports.isValidUTF8 = function(buf) {
958
+ return buf.length < 24 ? _isValidUTF8(buf) : isUtf8(buf);
959
+ };
960
+ else if (!process.env.WS_NO_UTF_8_VALIDATE) try {
961
+ const isValidUTF8 = __require("utf-8-validate");
962
+ module.exports.isValidUTF8 = function(buf) {
963
+ return buf.length < 32 ? _isValidUTF8(buf) : isValidUTF8(buf);
964
+ };
965
+ } catch (e) {}
966
+ }));
967
+ //#endregion
968
+ //#region node_modules/.pnpm/ws@8.20.0/node_modules/ws/lib/receiver.js
969
+ var require_receiver = /* @__PURE__ */ __commonJSMin(((exports, module) => {
970
+ const { Writable } = __require("stream");
971
+ const PerMessageDeflate = require_permessage_deflate();
972
+ const { BINARY_TYPES, EMPTY_BUFFER, kStatusCode, kWebSocket } = require_constants();
973
+ const { concat, toArrayBuffer, unmask } = require_buffer_util();
974
+ const { isValidStatusCode, isValidUTF8 } = require_validation();
975
+ const FastBuffer = Buffer[Symbol.species];
976
+ const GET_INFO = 0;
977
+ const GET_PAYLOAD_LENGTH_16 = 1;
978
+ const GET_PAYLOAD_LENGTH_64 = 2;
979
+ const GET_MASK = 3;
980
+ const GET_DATA = 4;
981
+ const INFLATING = 5;
982
+ const DEFER_EVENT = 6;
297
983
  /**
298
- * 连接到 WebSocket 网关
984
+ * HyBi Receiver implementation.
985
+ *
986
+ * @extends Writable
299
987
  */
300
- async connect() {
301
- if (this.isConnected()) return;
302
- if (!this.token) throw new Error("Token is required before connecting to WebSocket");
303
- this.intentionalClose = false;
304
- this.setState("connecting");
305
- try {
306
- const wsUrl = new URL(this.options.gatewayURL);
307
- wsUrl.searchParams.append("token", this.token);
308
- this.ws = new WebSocket(wsUrl.toString());
309
- await this.setupWebSocketHandlers();
310
- } catch (error) {
311
- this.setState("error");
312
- this.emitter.emit("error", createError("WS_CONNECT_FAILED", "Failed to connect to WebSocket", error instanceof Error ? error : void 0));
313
- this.scheduleReconnect();
314
- throw error;
988
+ var Receiver = class extends Writable {
989
+ /**
990
+ * Creates a Receiver instance.
991
+ *
992
+ * @param {Object} [options] Options object
993
+ * @param {Boolean} [options.allowSynchronousEvents=true] Specifies whether
994
+ * any of the `'message'`, `'ping'`, and `'pong'` events can be emitted
995
+ * multiple times in the same tick
996
+ * @param {String} [options.binaryType=nodebuffer] The type for binary data
997
+ * @param {Object} [options.extensions] An object containing the negotiated
998
+ * extensions
999
+ * @param {Boolean} [options.isServer=false] Specifies whether to operate in
1000
+ * client or server mode
1001
+ * @param {Number} [options.maxPayload=0] The maximum allowed message length
1002
+ * @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or
1003
+ * not to skip UTF-8 validation for text and close messages
1004
+ */
1005
+ constructor(options = {}) {
1006
+ super();
1007
+ this._allowSynchronousEvents = options.allowSynchronousEvents !== void 0 ? options.allowSynchronousEvents : true;
1008
+ this._binaryType = options.binaryType || BINARY_TYPES[0];
1009
+ this._extensions = options.extensions || {};
1010
+ this._isServer = !!options.isServer;
1011
+ this._maxPayload = options.maxPayload | 0;
1012
+ this._skipUTF8Validation = !!options.skipUTF8Validation;
1013
+ this[kWebSocket] = void 0;
1014
+ this._bufferedBytes = 0;
1015
+ this._buffers = [];
1016
+ this._compressed = false;
1017
+ this._payloadLength = 0;
1018
+ this._mask = void 0;
1019
+ this._fragmented = 0;
1020
+ this._masked = false;
1021
+ this._fin = false;
1022
+ this._opcode = 0;
1023
+ this._totalPayloadLength = 0;
1024
+ this._messageLength = 0;
1025
+ this._fragments = [];
1026
+ this._errored = false;
1027
+ this._loop = false;
1028
+ this._state = GET_INFO;
1029
+ }
1030
+ /**
1031
+ * Implements `Writable.prototype._write()`.
1032
+ *
1033
+ * @param {Buffer} chunk The chunk of data to write
1034
+ * @param {String} encoding The character encoding of `chunk`
1035
+ * @param {Function} cb Callback
1036
+ * @private
1037
+ */
1038
+ _write(chunk, encoding, cb) {
1039
+ if (this._opcode === 8 && this._state == GET_INFO) return cb();
1040
+ this._bufferedBytes += chunk.length;
1041
+ this._buffers.push(chunk);
1042
+ this.startLoop(cb);
1043
+ }
1044
+ /**
1045
+ * Consumes `n` bytes from the buffered data.
1046
+ *
1047
+ * @param {Number} n The number of bytes to consume
1048
+ * @return {Buffer} The consumed bytes
1049
+ * @private
1050
+ */
1051
+ consume(n) {
1052
+ this._bufferedBytes -= n;
1053
+ if (n === this._buffers[0].length) return this._buffers.shift();
1054
+ if (n < this._buffers[0].length) {
1055
+ const buf = this._buffers[0];
1056
+ this._buffers[0] = new FastBuffer(buf.buffer, buf.byteOffset + n, buf.length - n);
1057
+ return new FastBuffer(buf.buffer, buf.byteOffset, n);
1058
+ }
1059
+ const dst = Buffer.allocUnsafe(n);
1060
+ do {
1061
+ const buf = this._buffers[0];
1062
+ const offset = dst.length - n;
1063
+ if (n >= buf.length) dst.set(this._buffers.shift(), offset);
1064
+ else {
1065
+ dst.set(new Uint8Array(buf.buffer, buf.byteOffset, n), offset);
1066
+ this._buffers[0] = new FastBuffer(buf.buffer, buf.byteOffset + n, buf.length - n);
1067
+ }
1068
+ n -= buf.length;
1069
+ } while (n > 0);
1070
+ return dst;
1071
+ }
1072
+ /**
1073
+ * Starts the parsing loop.
1074
+ *
1075
+ * @param {Function} cb Callback
1076
+ * @private
1077
+ */
1078
+ startLoop(cb) {
1079
+ this._loop = true;
1080
+ do
1081
+ switch (this._state) {
1082
+ case GET_INFO:
1083
+ this.getInfo(cb);
1084
+ break;
1085
+ case GET_PAYLOAD_LENGTH_16:
1086
+ this.getPayloadLength16(cb);
1087
+ break;
1088
+ case GET_PAYLOAD_LENGTH_64:
1089
+ this.getPayloadLength64(cb);
1090
+ break;
1091
+ case GET_MASK:
1092
+ this.getMask();
1093
+ break;
1094
+ case GET_DATA:
1095
+ this.getData(cb);
1096
+ break;
1097
+ case INFLATING:
1098
+ case DEFER_EVENT:
1099
+ this._loop = false;
1100
+ return;
1101
+ }
1102
+ while (this._loop);
1103
+ if (!this._errored) cb();
1104
+ }
1105
+ /**
1106
+ * Reads the first two bytes of a frame.
1107
+ *
1108
+ * @param {Function} cb Callback
1109
+ * @private
1110
+ */
1111
+ getInfo(cb) {
1112
+ if (this._bufferedBytes < 2) {
1113
+ this._loop = false;
1114
+ return;
1115
+ }
1116
+ const buf = this.consume(2);
1117
+ if ((buf[0] & 48) !== 0) {
1118
+ cb(this.createError(RangeError, "RSV2 and RSV3 must be clear", true, 1002, "WS_ERR_UNEXPECTED_RSV_2_3"));
1119
+ return;
1120
+ }
1121
+ const compressed = (buf[0] & 64) === 64;
1122
+ if (compressed && !this._extensions[PerMessageDeflate.extensionName]) {
1123
+ cb(this.createError(RangeError, "RSV1 must be clear", true, 1002, "WS_ERR_UNEXPECTED_RSV_1"));
1124
+ return;
1125
+ }
1126
+ this._fin = (buf[0] & 128) === 128;
1127
+ this._opcode = buf[0] & 15;
1128
+ this._payloadLength = buf[1] & 127;
1129
+ if (this._opcode === 0) {
1130
+ if (compressed) {
1131
+ cb(this.createError(RangeError, "RSV1 must be clear", true, 1002, "WS_ERR_UNEXPECTED_RSV_1"));
1132
+ return;
1133
+ }
1134
+ if (!this._fragmented) {
1135
+ cb(this.createError(RangeError, "invalid opcode 0", true, 1002, "WS_ERR_INVALID_OPCODE"));
1136
+ return;
1137
+ }
1138
+ this._opcode = this._fragmented;
1139
+ } else if (this._opcode === 1 || this._opcode === 2) {
1140
+ if (this._fragmented) {
1141
+ cb(this.createError(RangeError, `invalid opcode ${this._opcode}`, true, 1002, "WS_ERR_INVALID_OPCODE"));
1142
+ return;
1143
+ }
1144
+ this._compressed = compressed;
1145
+ } else if (this._opcode > 7 && this._opcode < 11) {
1146
+ if (!this._fin) {
1147
+ cb(this.createError(RangeError, "FIN must be set", true, 1002, "WS_ERR_EXPECTED_FIN"));
1148
+ return;
1149
+ }
1150
+ if (compressed) {
1151
+ cb(this.createError(RangeError, "RSV1 must be clear", true, 1002, "WS_ERR_UNEXPECTED_RSV_1"));
1152
+ return;
1153
+ }
1154
+ if (this._payloadLength > 125 || this._opcode === 8 && this._payloadLength === 1) {
1155
+ cb(this.createError(RangeError, `invalid payload length ${this._payloadLength}`, true, 1002, "WS_ERR_INVALID_CONTROL_PAYLOAD_LENGTH"));
1156
+ return;
1157
+ }
1158
+ } else {
1159
+ cb(this.createError(RangeError, `invalid opcode ${this._opcode}`, true, 1002, "WS_ERR_INVALID_OPCODE"));
1160
+ return;
1161
+ }
1162
+ if (!this._fin && !this._fragmented) this._fragmented = this._opcode;
1163
+ this._masked = (buf[1] & 128) === 128;
1164
+ if (this._isServer) {
1165
+ if (!this._masked) {
1166
+ cb(this.createError(RangeError, "MASK must be set", true, 1002, "WS_ERR_EXPECTED_MASK"));
1167
+ return;
1168
+ }
1169
+ } else if (this._masked) {
1170
+ cb(this.createError(RangeError, "MASK must be clear", true, 1002, "WS_ERR_UNEXPECTED_MASK"));
1171
+ return;
1172
+ }
1173
+ if (this._payloadLength === 126) this._state = GET_PAYLOAD_LENGTH_16;
1174
+ else if (this._payloadLength === 127) this._state = GET_PAYLOAD_LENGTH_64;
1175
+ else this.haveLength(cb);
1176
+ }
1177
+ /**
1178
+ * Gets extended payload length (7+16).
1179
+ *
1180
+ * @param {Function} cb Callback
1181
+ * @private
1182
+ */
1183
+ getPayloadLength16(cb) {
1184
+ if (this._bufferedBytes < 2) {
1185
+ this._loop = false;
1186
+ return;
1187
+ }
1188
+ this._payloadLength = this.consume(2).readUInt16BE(0);
1189
+ this.haveLength(cb);
1190
+ }
1191
+ /**
1192
+ * Gets extended payload length (7+64).
1193
+ *
1194
+ * @param {Function} cb Callback
1195
+ * @private
1196
+ */
1197
+ getPayloadLength64(cb) {
1198
+ if (this._bufferedBytes < 8) {
1199
+ this._loop = false;
1200
+ return;
1201
+ }
1202
+ const buf = this.consume(8);
1203
+ const num = buf.readUInt32BE(0);
1204
+ if (num > Math.pow(2, 21) - 1) {
1205
+ cb(this.createError(RangeError, "Unsupported WebSocket frame: payload length > 2^53 - 1", false, 1009, "WS_ERR_UNSUPPORTED_DATA_PAYLOAD_LENGTH"));
1206
+ return;
1207
+ }
1208
+ this._payloadLength = num * Math.pow(2, 32) + buf.readUInt32BE(4);
1209
+ this.haveLength(cb);
1210
+ }
1211
+ /**
1212
+ * Payload length has been read.
1213
+ *
1214
+ * @param {Function} cb Callback
1215
+ * @private
1216
+ */
1217
+ haveLength(cb) {
1218
+ if (this._payloadLength && this._opcode < 8) {
1219
+ this._totalPayloadLength += this._payloadLength;
1220
+ if (this._totalPayloadLength > this._maxPayload && this._maxPayload > 0) {
1221
+ cb(this.createError(RangeError, "Max payload size exceeded", false, 1009, "WS_ERR_UNSUPPORTED_MESSAGE_LENGTH"));
1222
+ return;
1223
+ }
1224
+ }
1225
+ if (this._masked) this._state = GET_MASK;
1226
+ else this._state = GET_DATA;
1227
+ }
1228
+ /**
1229
+ * Reads mask bytes.
1230
+ *
1231
+ * @private
1232
+ */
1233
+ getMask() {
1234
+ if (this._bufferedBytes < 4) {
1235
+ this._loop = false;
1236
+ return;
1237
+ }
1238
+ this._mask = this.consume(4);
1239
+ this._state = GET_DATA;
1240
+ }
1241
+ /**
1242
+ * Reads data bytes.
1243
+ *
1244
+ * @param {Function} cb Callback
1245
+ * @private
1246
+ */
1247
+ getData(cb) {
1248
+ let data = EMPTY_BUFFER;
1249
+ if (this._payloadLength) {
1250
+ if (this._bufferedBytes < this._payloadLength) {
1251
+ this._loop = false;
1252
+ return;
1253
+ }
1254
+ data = this.consume(this._payloadLength);
1255
+ if (this._masked && (this._mask[0] | this._mask[1] | this._mask[2] | this._mask[3]) !== 0) unmask(data, this._mask);
1256
+ }
1257
+ if (this._opcode > 7) {
1258
+ this.controlMessage(data, cb);
1259
+ return;
1260
+ }
1261
+ if (this._compressed) {
1262
+ this._state = INFLATING;
1263
+ this.decompress(data, cb);
1264
+ return;
1265
+ }
1266
+ if (data.length) {
1267
+ this._messageLength = this._totalPayloadLength;
1268
+ this._fragments.push(data);
1269
+ }
1270
+ this.dataMessage(cb);
1271
+ }
1272
+ /**
1273
+ * Decompresses data.
1274
+ *
1275
+ * @param {Buffer} data Compressed data
1276
+ * @param {Function} cb Callback
1277
+ * @private
1278
+ */
1279
+ decompress(data, cb) {
1280
+ this._extensions[PerMessageDeflate.extensionName].decompress(data, this._fin, (err, buf) => {
1281
+ if (err) return cb(err);
1282
+ if (buf.length) {
1283
+ this._messageLength += buf.length;
1284
+ if (this._messageLength > this._maxPayload && this._maxPayload > 0) {
1285
+ cb(this.createError(RangeError, "Max payload size exceeded", false, 1009, "WS_ERR_UNSUPPORTED_MESSAGE_LENGTH"));
1286
+ return;
1287
+ }
1288
+ this._fragments.push(buf);
1289
+ }
1290
+ this.dataMessage(cb);
1291
+ if (this._state === GET_INFO) this.startLoop(cb);
1292
+ });
1293
+ }
1294
+ /**
1295
+ * Handles a data message.
1296
+ *
1297
+ * @param {Function} cb Callback
1298
+ * @private
1299
+ */
1300
+ dataMessage(cb) {
1301
+ if (!this._fin) {
1302
+ this._state = GET_INFO;
1303
+ return;
1304
+ }
1305
+ const messageLength = this._messageLength;
1306
+ const fragments = this._fragments;
1307
+ this._totalPayloadLength = 0;
1308
+ this._messageLength = 0;
1309
+ this._fragmented = 0;
1310
+ this._fragments = [];
1311
+ if (this._opcode === 2) {
1312
+ let data;
1313
+ if (this._binaryType === "nodebuffer") data = concat(fragments, messageLength);
1314
+ else if (this._binaryType === "arraybuffer") data = toArrayBuffer(concat(fragments, messageLength));
1315
+ else if (this._binaryType === "blob") data = new Blob(fragments);
1316
+ else data = fragments;
1317
+ if (this._allowSynchronousEvents) {
1318
+ this.emit("message", data, true);
1319
+ this._state = GET_INFO;
1320
+ } else {
1321
+ this._state = DEFER_EVENT;
1322
+ setImmediate(() => {
1323
+ this.emit("message", data, true);
1324
+ this._state = GET_INFO;
1325
+ this.startLoop(cb);
1326
+ });
1327
+ }
1328
+ } else {
1329
+ const buf = concat(fragments, messageLength);
1330
+ if (!this._skipUTF8Validation && !isValidUTF8(buf)) {
1331
+ cb(this.createError(Error, "invalid UTF-8 sequence", true, 1007, "WS_ERR_INVALID_UTF8"));
1332
+ return;
1333
+ }
1334
+ if (this._state === INFLATING || this._allowSynchronousEvents) {
1335
+ this.emit("message", buf, false);
1336
+ this._state = GET_INFO;
1337
+ } else {
1338
+ this._state = DEFER_EVENT;
1339
+ setImmediate(() => {
1340
+ this.emit("message", buf, false);
1341
+ this._state = GET_INFO;
1342
+ this.startLoop(cb);
1343
+ });
1344
+ }
1345
+ }
1346
+ }
1347
+ /**
1348
+ * Handles a control message.
1349
+ *
1350
+ * @param {Buffer} data Data to handle
1351
+ * @return {(Error|RangeError|undefined)} A possible error
1352
+ * @private
1353
+ */
1354
+ controlMessage(data, cb) {
1355
+ if (this._opcode === 8) {
1356
+ if (data.length === 0) {
1357
+ this._loop = false;
1358
+ this.emit("conclude", 1005, EMPTY_BUFFER);
1359
+ this.end();
1360
+ } else {
1361
+ const code = data.readUInt16BE(0);
1362
+ if (!isValidStatusCode(code)) {
1363
+ cb(this.createError(RangeError, `invalid status code ${code}`, true, 1002, "WS_ERR_INVALID_CLOSE_CODE"));
1364
+ return;
1365
+ }
1366
+ const buf = new FastBuffer(data.buffer, data.byteOffset + 2, data.length - 2);
1367
+ if (!this._skipUTF8Validation && !isValidUTF8(buf)) {
1368
+ cb(this.createError(Error, "invalid UTF-8 sequence", true, 1007, "WS_ERR_INVALID_UTF8"));
1369
+ return;
1370
+ }
1371
+ this._loop = false;
1372
+ this.emit("conclude", code, buf);
1373
+ this.end();
1374
+ }
1375
+ this._state = GET_INFO;
1376
+ return;
1377
+ }
1378
+ if (this._allowSynchronousEvents) {
1379
+ this.emit(this._opcode === 9 ? "ping" : "pong", data);
1380
+ this._state = GET_INFO;
1381
+ } else {
1382
+ this._state = DEFER_EVENT;
1383
+ setImmediate(() => {
1384
+ this.emit(this._opcode === 9 ? "ping" : "pong", data);
1385
+ this._state = GET_INFO;
1386
+ this.startLoop(cb);
1387
+ });
1388
+ }
1389
+ }
1390
+ /**
1391
+ * Builds an error object.
1392
+ *
1393
+ * @param {function(new:Error|RangeError)} ErrorCtor The error constructor
1394
+ * @param {String} message The error message
1395
+ * @param {Boolean} prefix Specifies whether or not to add a default prefix to
1396
+ * `message`
1397
+ * @param {Number} statusCode The status code
1398
+ * @param {String} errorCode The exposed error code
1399
+ * @return {(Error|RangeError)} The error
1400
+ * @private
1401
+ */
1402
+ createError(ErrorCtor, message, prefix, statusCode, errorCode) {
1403
+ this._loop = false;
1404
+ this._errored = true;
1405
+ const err = new ErrorCtor(prefix ? `Invalid WebSocket frame: ${message}` : message);
1406
+ Error.captureStackTrace(err, this.createError);
1407
+ err.code = errorCode;
1408
+ err[kStatusCode] = statusCode;
1409
+ return err;
1410
+ }
1411
+ };
1412
+ module.exports = Receiver;
1413
+ }));
1414
+ //#endregion
1415
+ //#region node_modules/.pnpm/ws@8.20.0/node_modules/ws/lib/sender.js
1416
+ var require_sender = /* @__PURE__ */ __commonJSMin(((exports, module) => {
1417
+ const { Duplex: Duplex$3 } = __require("stream");
1418
+ const { randomFillSync } = __require("crypto");
1419
+ const PerMessageDeflate = require_permessage_deflate();
1420
+ const { EMPTY_BUFFER, kWebSocket, NOOP } = require_constants();
1421
+ const { isBlob, isValidStatusCode } = require_validation();
1422
+ const { mask: applyMask, toBuffer } = require_buffer_util();
1423
+ const kByteLength = Symbol("kByteLength");
1424
+ const maskBuffer = Buffer.alloc(4);
1425
+ const RANDOM_POOL_SIZE = 8 * 1024;
1426
+ let randomPool;
1427
+ let randomPoolPointer = RANDOM_POOL_SIZE;
1428
+ const DEFAULT = 0;
1429
+ const DEFLATING = 1;
1430
+ const GET_BLOB_DATA = 2;
1431
+ module.exports = class Sender {
1432
+ /**
1433
+ * Creates a Sender instance.
1434
+ *
1435
+ * @param {Duplex} socket The connection socket
1436
+ * @param {Object} [extensions] An object containing the negotiated extensions
1437
+ * @param {Function} [generateMask] The function used to generate the masking
1438
+ * key
1439
+ */
1440
+ constructor(socket, extensions, generateMask) {
1441
+ this._extensions = extensions || {};
1442
+ if (generateMask) {
1443
+ this._generateMask = generateMask;
1444
+ this._maskBuffer = Buffer.alloc(4);
1445
+ }
1446
+ this._socket = socket;
1447
+ this._firstFragment = true;
1448
+ this._compress = false;
1449
+ this._bufferedBytes = 0;
1450
+ this._queue = [];
1451
+ this._state = DEFAULT;
1452
+ this.onerror = NOOP;
1453
+ this[kWebSocket] = void 0;
1454
+ }
1455
+ /**
1456
+ * Frames a piece of data according to the HyBi WebSocket protocol.
1457
+ *
1458
+ * @param {(Buffer|String)} data The data to frame
1459
+ * @param {Object} options Options object
1460
+ * @param {Boolean} [options.fin=false] Specifies whether or not to set the
1461
+ * FIN bit
1462
+ * @param {Function} [options.generateMask] The function used to generate the
1463
+ * masking key
1464
+ * @param {Boolean} [options.mask=false] Specifies whether or not to mask
1465
+ * `data`
1466
+ * @param {Buffer} [options.maskBuffer] The buffer used to store the masking
1467
+ * key
1468
+ * @param {Number} options.opcode The opcode
1469
+ * @param {Boolean} [options.readOnly=false] Specifies whether `data` can be
1470
+ * modified
1471
+ * @param {Boolean} [options.rsv1=false] Specifies whether or not to set the
1472
+ * RSV1 bit
1473
+ * @return {(Buffer|String)[]} The framed data
1474
+ * @public
1475
+ */
1476
+ static frame(data, options) {
1477
+ let mask;
1478
+ let merge = false;
1479
+ let offset = 2;
1480
+ let skipMasking = false;
1481
+ if (options.mask) {
1482
+ mask = options.maskBuffer || maskBuffer;
1483
+ if (options.generateMask) options.generateMask(mask);
1484
+ else {
1485
+ if (randomPoolPointer === RANDOM_POOL_SIZE) {
1486
+ /* istanbul ignore else */
1487
+ if (randomPool === void 0) randomPool = Buffer.alloc(RANDOM_POOL_SIZE);
1488
+ randomFillSync(randomPool, 0, RANDOM_POOL_SIZE);
1489
+ randomPoolPointer = 0;
1490
+ }
1491
+ mask[0] = randomPool[randomPoolPointer++];
1492
+ mask[1] = randomPool[randomPoolPointer++];
1493
+ mask[2] = randomPool[randomPoolPointer++];
1494
+ mask[3] = randomPool[randomPoolPointer++];
1495
+ }
1496
+ skipMasking = (mask[0] | mask[1] | mask[2] | mask[3]) === 0;
1497
+ offset = 6;
1498
+ }
1499
+ let dataLength;
1500
+ if (typeof data === "string") if ((!options.mask || skipMasking) && options[kByteLength] !== void 0) dataLength = options[kByteLength];
1501
+ else {
1502
+ data = Buffer.from(data);
1503
+ dataLength = data.length;
1504
+ }
1505
+ else {
1506
+ dataLength = data.length;
1507
+ merge = options.mask && options.readOnly && !skipMasking;
1508
+ }
1509
+ let payloadLength = dataLength;
1510
+ if (dataLength >= 65536) {
1511
+ offset += 8;
1512
+ payloadLength = 127;
1513
+ } else if (dataLength > 125) {
1514
+ offset += 2;
1515
+ payloadLength = 126;
1516
+ }
1517
+ const target = Buffer.allocUnsafe(merge ? dataLength + offset : offset);
1518
+ target[0] = options.fin ? options.opcode | 128 : options.opcode;
1519
+ if (options.rsv1) target[0] |= 64;
1520
+ target[1] = payloadLength;
1521
+ if (payloadLength === 126) target.writeUInt16BE(dataLength, 2);
1522
+ else if (payloadLength === 127) {
1523
+ target[2] = target[3] = 0;
1524
+ target.writeUIntBE(dataLength, 4, 6);
1525
+ }
1526
+ if (!options.mask) return [target, data];
1527
+ target[1] |= 128;
1528
+ target[offset - 4] = mask[0];
1529
+ target[offset - 3] = mask[1];
1530
+ target[offset - 2] = mask[2];
1531
+ target[offset - 1] = mask[3];
1532
+ if (skipMasking) return [target, data];
1533
+ if (merge) {
1534
+ applyMask(data, mask, target, offset, dataLength);
1535
+ return [target];
1536
+ }
1537
+ applyMask(data, mask, data, 0, dataLength);
1538
+ return [target, data];
1539
+ }
1540
+ /**
1541
+ * Sends a close message to the other peer.
1542
+ *
1543
+ * @param {Number} [code] The status code component of the body
1544
+ * @param {(String|Buffer)} [data] The message component of the body
1545
+ * @param {Boolean} [mask=false] Specifies whether or not to mask the message
1546
+ * @param {Function} [cb] Callback
1547
+ * @public
1548
+ */
1549
+ close(code, data, mask, cb) {
1550
+ let buf;
1551
+ if (code === void 0) buf = EMPTY_BUFFER;
1552
+ else if (typeof code !== "number" || !isValidStatusCode(code)) throw new TypeError("First argument must be a valid error code number");
1553
+ else if (data === void 0 || !data.length) {
1554
+ buf = Buffer.allocUnsafe(2);
1555
+ buf.writeUInt16BE(code, 0);
1556
+ } else {
1557
+ const length = Buffer.byteLength(data);
1558
+ if (length > 123) throw new RangeError("The message must not be greater than 123 bytes");
1559
+ buf = Buffer.allocUnsafe(2 + length);
1560
+ buf.writeUInt16BE(code, 0);
1561
+ if (typeof data === "string") buf.write(data, 2);
1562
+ else buf.set(data, 2);
1563
+ }
1564
+ const options = {
1565
+ [kByteLength]: buf.length,
1566
+ fin: true,
1567
+ generateMask: this._generateMask,
1568
+ mask,
1569
+ maskBuffer: this._maskBuffer,
1570
+ opcode: 8,
1571
+ readOnly: false,
1572
+ rsv1: false
1573
+ };
1574
+ if (this._state !== DEFAULT) this.enqueue([
1575
+ this.dispatch,
1576
+ buf,
1577
+ false,
1578
+ options,
1579
+ cb
1580
+ ]);
1581
+ else this.sendFrame(Sender.frame(buf, options), cb);
1582
+ }
1583
+ /**
1584
+ * Sends a ping message to the other peer.
1585
+ *
1586
+ * @param {*} data The message to send
1587
+ * @param {Boolean} [mask=false] Specifies whether or not to mask `data`
1588
+ * @param {Function} [cb] Callback
1589
+ * @public
1590
+ */
1591
+ ping(data, mask, cb) {
1592
+ let byteLength;
1593
+ let readOnly;
1594
+ if (typeof data === "string") {
1595
+ byteLength = Buffer.byteLength(data);
1596
+ readOnly = false;
1597
+ } else if (isBlob(data)) {
1598
+ byteLength = data.size;
1599
+ readOnly = false;
1600
+ } else {
1601
+ data = toBuffer(data);
1602
+ byteLength = data.length;
1603
+ readOnly = toBuffer.readOnly;
1604
+ }
1605
+ if (byteLength > 125) throw new RangeError("The data size must not be greater than 125 bytes");
1606
+ const options = {
1607
+ [kByteLength]: byteLength,
1608
+ fin: true,
1609
+ generateMask: this._generateMask,
1610
+ mask,
1611
+ maskBuffer: this._maskBuffer,
1612
+ opcode: 9,
1613
+ readOnly,
1614
+ rsv1: false
1615
+ };
1616
+ if (isBlob(data)) if (this._state !== DEFAULT) this.enqueue([
1617
+ this.getBlobData,
1618
+ data,
1619
+ false,
1620
+ options,
1621
+ cb
1622
+ ]);
1623
+ else this.getBlobData(data, false, options, cb);
1624
+ else if (this._state !== DEFAULT) this.enqueue([
1625
+ this.dispatch,
1626
+ data,
1627
+ false,
1628
+ options,
1629
+ cb
1630
+ ]);
1631
+ else this.sendFrame(Sender.frame(data, options), cb);
1632
+ }
1633
+ /**
1634
+ * Sends a pong message to the other peer.
1635
+ *
1636
+ * @param {*} data The message to send
1637
+ * @param {Boolean} [mask=false] Specifies whether or not to mask `data`
1638
+ * @param {Function} [cb] Callback
1639
+ * @public
1640
+ */
1641
+ pong(data, mask, cb) {
1642
+ let byteLength;
1643
+ let readOnly;
1644
+ if (typeof data === "string") {
1645
+ byteLength = Buffer.byteLength(data);
1646
+ readOnly = false;
1647
+ } else if (isBlob(data)) {
1648
+ byteLength = data.size;
1649
+ readOnly = false;
1650
+ } else {
1651
+ data = toBuffer(data);
1652
+ byteLength = data.length;
1653
+ readOnly = toBuffer.readOnly;
1654
+ }
1655
+ if (byteLength > 125) throw new RangeError("The data size must not be greater than 125 bytes");
1656
+ const options = {
1657
+ [kByteLength]: byteLength,
1658
+ fin: true,
1659
+ generateMask: this._generateMask,
1660
+ mask,
1661
+ maskBuffer: this._maskBuffer,
1662
+ opcode: 10,
1663
+ readOnly,
1664
+ rsv1: false
1665
+ };
1666
+ if (isBlob(data)) if (this._state !== DEFAULT) this.enqueue([
1667
+ this.getBlobData,
1668
+ data,
1669
+ false,
1670
+ options,
1671
+ cb
1672
+ ]);
1673
+ else this.getBlobData(data, false, options, cb);
1674
+ else if (this._state !== DEFAULT) this.enqueue([
1675
+ this.dispatch,
1676
+ data,
1677
+ false,
1678
+ options,
1679
+ cb
1680
+ ]);
1681
+ else this.sendFrame(Sender.frame(data, options), cb);
1682
+ }
1683
+ /**
1684
+ * Sends a data message to the other peer.
1685
+ *
1686
+ * @param {*} data The message to send
1687
+ * @param {Object} options Options object
1688
+ * @param {Boolean} [options.binary=false] Specifies whether `data` is binary
1689
+ * or text
1690
+ * @param {Boolean} [options.compress=false] Specifies whether or not to
1691
+ * compress `data`
1692
+ * @param {Boolean} [options.fin=false] Specifies whether the fragment is the
1693
+ * last one
1694
+ * @param {Boolean} [options.mask=false] Specifies whether or not to mask
1695
+ * `data`
1696
+ * @param {Function} [cb] Callback
1697
+ * @public
1698
+ */
1699
+ send(data, options, cb) {
1700
+ const perMessageDeflate = this._extensions[PerMessageDeflate.extensionName];
1701
+ let opcode = options.binary ? 2 : 1;
1702
+ let rsv1 = options.compress;
1703
+ let byteLength;
1704
+ let readOnly;
1705
+ if (typeof data === "string") {
1706
+ byteLength = Buffer.byteLength(data);
1707
+ readOnly = false;
1708
+ } else if (isBlob(data)) {
1709
+ byteLength = data.size;
1710
+ readOnly = false;
1711
+ } else {
1712
+ data = toBuffer(data);
1713
+ byteLength = data.length;
1714
+ readOnly = toBuffer.readOnly;
1715
+ }
1716
+ if (this._firstFragment) {
1717
+ this._firstFragment = false;
1718
+ if (rsv1 && perMessageDeflate && perMessageDeflate.params[perMessageDeflate._isServer ? "server_no_context_takeover" : "client_no_context_takeover"]) rsv1 = byteLength >= perMessageDeflate._threshold;
1719
+ this._compress = rsv1;
1720
+ } else {
1721
+ rsv1 = false;
1722
+ opcode = 0;
1723
+ }
1724
+ if (options.fin) this._firstFragment = true;
1725
+ const opts = {
1726
+ [kByteLength]: byteLength,
1727
+ fin: options.fin,
1728
+ generateMask: this._generateMask,
1729
+ mask: options.mask,
1730
+ maskBuffer: this._maskBuffer,
1731
+ opcode,
1732
+ readOnly,
1733
+ rsv1
1734
+ };
1735
+ if (isBlob(data)) if (this._state !== DEFAULT) this.enqueue([
1736
+ this.getBlobData,
1737
+ data,
1738
+ this._compress,
1739
+ opts,
1740
+ cb
1741
+ ]);
1742
+ else this.getBlobData(data, this._compress, opts, cb);
1743
+ else if (this._state !== DEFAULT) this.enqueue([
1744
+ this.dispatch,
1745
+ data,
1746
+ this._compress,
1747
+ opts,
1748
+ cb
1749
+ ]);
1750
+ else this.dispatch(data, this._compress, opts, cb);
1751
+ }
1752
+ /**
1753
+ * Gets the contents of a blob as binary data.
1754
+ *
1755
+ * @param {Blob} blob The blob
1756
+ * @param {Boolean} [compress=false] Specifies whether or not to compress
1757
+ * the data
1758
+ * @param {Object} options Options object
1759
+ * @param {Boolean} [options.fin=false] Specifies whether or not to set the
1760
+ * FIN bit
1761
+ * @param {Function} [options.generateMask] The function used to generate the
1762
+ * masking key
1763
+ * @param {Boolean} [options.mask=false] Specifies whether or not to mask
1764
+ * `data`
1765
+ * @param {Buffer} [options.maskBuffer] The buffer used to store the masking
1766
+ * key
1767
+ * @param {Number} options.opcode The opcode
1768
+ * @param {Boolean} [options.readOnly=false] Specifies whether `data` can be
1769
+ * modified
1770
+ * @param {Boolean} [options.rsv1=false] Specifies whether or not to set the
1771
+ * RSV1 bit
1772
+ * @param {Function} [cb] Callback
1773
+ * @private
1774
+ */
1775
+ getBlobData(blob, compress, options, cb) {
1776
+ this._bufferedBytes += options[kByteLength];
1777
+ this._state = GET_BLOB_DATA;
1778
+ blob.arrayBuffer().then((arrayBuffer) => {
1779
+ if (this._socket.destroyed) {
1780
+ const err = /* @__PURE__ */ new Error("The socket was closed while the blob was being read");
1781
+ process.nextTick(callCallbacks, this, err, cb);
1782
+ return;
1783
+ }
1784
+ this._bufferedBytes -= options[kByteLength];
1785
+ const data = toBuffer(arrayBuffer);
1786
+ if (!compress) {
1787
+ this._state = DEFAULT;
1788
+ this.sendFrame(Sender.frame(data, options), cb);
1789
+ this.dequeue();
1790
+ } else this.dispatch(data, compress, options, cb);
1791
+ }).catch((err) => {
1792
+ process.nextTick(onError, this, err, cb);
1793
+ });
1794
+ }
1795
+ /**
1796
+ * Dispatches a message.
1797
+ *
1798
+ * @param {(Buffer|String)} data The message to send
1799
+ * @param {Boolean} [compress=false] Specifies whether or not to compress
1800
+ * `data`
1801
+ * @param {Object} options Options object
1802
+ * @param {Boolean} [options.fin=false] Specifies whether or not to set the
1803
+ * FIN bit
1804
+ * @param {Function} [options.generateMask] The function used to generate the
1805
+ * masking key
1806
+ * @param {Boolean} [options.mask=false] Specifies whether or not to mask
1807
+ * `data`
1808
+ * @param {Buffer} [options.maskBuffer] The buffer used to store the masking
1809
+ * key
1810
+ * @param {Number} options.opcode The opcode
1811
+ * @param {Boolean} [options.readOnly=false] Specifies whether `data` can be
1812
+ * modified
1813
+ * @param {Boolean} [options.rsv1=false] Specifies whether or not to set the
1814
+ * RSV1 bit
1815
+ * @param {Function} [cb] Callback
1816
+ * @private
1817
+ */
1818
+ dispatch(data, compress, options, cb) {
1819
+ if (!compress) {
1820
+ this.sendFrame(Sender.frame(data, options), cb);
1821
+ return;
1822
+ }
1823
+ const perMessageDeflate = this._extensions[PerMessageDeflate.extensionName];
1824
+ this._bufferedBytes += options[kByteLength];
1825
+ this._state = DEFLATING;
1826
+ perMessageDeflate.compress(data, options.fin, (_, buf) => {
1827
+ if (this._socket.destroyed) {
1828
+ const err = /* @__PURE__ */ new Error("The socket was closed while data was being compressed");
1829
+ callCallbacks(this, err, cb);
1830
+ return;
1831
+ }
1832
+ this._bufferedBytes -= options[kByteLength];
1833
+ this._state = DEFAULT;
1834
+ options.readOnly = false;
1835
+ this.sendFrame(Sender.frame(buf, options), cb);
1836
+ this.dequeue();
1837
+ });
1838
+ }
1839
+ /**
1840
+ * Executes queued send operations.
1841
+ *
1842
+ * @private
1843
+ */
1844
+ dequeue() {
1845
+ while (this._state === DEFAULT && this._queue.length) {
1846
+ const params = this._queue.shift();
1847
+ this._bufferedBytes -= params[3][kByteLength];
1848
+ Reflect.apply(params[0], this, params.slice(1));
1849
+ }
1850
+ }
1851
+ /**
1852
+ * Enqueues a send operation.
1853
+ *
1854
+ * @param {Array} params Send operation parameters.
1855
+ * @private
1856
+ */
1857
+ enqueue(params) {
1858
+ this._bufferedBytes += params[3][kByteLength];
1859
+ this._queue.push(params);
1860
+ }
1861
+ /**
1862
+ * Sends a frame.
1863
+ *
1864
+ * @param {(Buffer | String)[]} list The frame to send
1865
+ * @param {Function} [cb] Callback
1866
+ * @private
1867
+ */
1868
+ sendFrame(list, cb) {
1869
+ if (list.length === 2) {
1870
+ this._socket.cork();
1871
+ this._socket.write(list[0]);
1872
+ this._socket.write(list[1], cb);
1873
+ this._socket.uncork();
1874
+ } else this._socket.write(list[0], cb);
1875
+ }
1876
+ };
1877
+ /**
1878
+ * Calls queued callbacks with an error.
1879
+ *
1880
+ * @param {Sender} sender The `Sender` instance
1881
+ * @param {Error} err The error to call the callbacks with
1882
+ * @param {Function} [cb] The first callback
1883
+ * @private
1884
+ */
1885
+ function callCallbacks(sender, err, cb) {
1886
+ if (typeof cb === "function") cb(err);
1887
+ for (let i = 0; i < sender._queue.length; i++) {
1888
+ const params = sender._queue[i];
1889
+ const callback = params[params.length - 1];
1890
+ if (typeof callback === "function") callback(err);
315
1891
  }
316
1892
  }
317
1893
  /**
318
- * 断开 WebSocket 连接
1894
+ * Handles a `Sender` error.
1895
+ *
1896
+ * @param {Sender} sender The `Sender` instance
1897
+ * @param {Error} err The error
1898
+ * @param {Function} [cb] The first pending callback
1899
+ * @private
319
1900
  */
320
- disconnect() {
321
- this.intentionalClose = true;
322
- this.clearTimers();
323
- if (this.ws) {
324
- if (this.ws.readyState === WebSocket.OPEN || this.ws.readyState === WebSocket.CONNECTING) this.ws.close(1e3, "Client disconnect");
325
- this.ws = null;
1901
+ function onError(sender, err, cb) {
1902
+ callCallbacks(sender, err, cb);
1903
+ sender.onerror(err);
1904
+ }
1905
+ }));
1906
+ //#endregion
1907
+ //#region node_modules/.pnpm/ws@8.20.0/node_modules/ws/lib/event-target.js
1908
+ var require_event_target = /* @__PURE__ */ __commonJSMin(((exports, module) => {
1909
+ const { kForOnEventAttribute, kListener } = require_constants();
1910
+ const kCode = Symbol("kCode");
1911
+ const kData = Symbol("kData");
1912
+ const kError = Symbol("kError");
1913
+ const kMessage = Symbol("kMessage");
1914
+ const kReason = Symbol("kReason");
1915
+ const kTarget = Symbol("kTarget");
1916
+ const kType = Symbol("kType");
1917
+ const kWasClean = Symbol("kWasClean");
1918
+ /**
1919
+ * Class representing an event.
1920
+ */
1921
+ var Event = class {
1922
+ /**
1923
+ * Create a new `Event`.
1924
+ *
1925
+ * @param {String} type The name of the event
1926
+ * @throws {TypeError} If the `type` argument is not specified
1927
+ */
1928
+ constructor(type) {
1929
+ this[kTarget] = null;
1930
+ this[kType] = type;
326
1931
  }
327
- this.reconnectAttempts = 0;
328
- this.setState("disconnected");
329
- this.emitter.emit("disconnect", void 0);
1932
+ /**
1933
+ * @type {*}
1934
+ */
1935
+ get target() {
1936
+ return this[kTarget];
1937
+ }
1938
+ /**
1939
+ * @type {String}
1940
+ */
1941
+ get type() {
1942
+ return this[kType];
1943
+ }
1944
+ };
1945
+ Object.defineProperty(Event.prototype, "target", { enumerable: true });
1946
+ Object.defineProperty(Event.prototype, "type", { enumerable: true });
1947
+ /**
1948
+ * Class representing a close event.
1949
+ *
1950
+ * @extends Event
1951
+ */
1952
+ var CloseEvent = class extends Event {
1953
+ /**
1954
+ * Create a new `CloseEvent`.
1955
+ *
1956
+ * @param {String} type The name of the event
1957
+ * @param {Object} [options] A dictionary object that allows for setting
1958
+ * attributes via object members of the same name
1959
+ * @param {Number} [options.code=0] The status code explaining why the
1960
+ * connection was closed
1961
+ * @param {String} [options.reason=''] A human-readable string explaining why
1962
+ * the connection was closed
1963
+ * @param {Boolean} [options.wasClean=false] Indicates whether or not the
1964
+ * connection was cleanly closed
1965
+ */
1966
+ constructor(type, options = {}) {
1967
+ super(type);
1968
+ this[kCode] = options.code === void 0 ? 0 : options.code;
1969
+ this[kReason] = options.reason === void 0 ? "" : options.reason;
1970
+ this[kWasClean] = options.wasClean === void 0 ? false : options.wasClean;
1971
+ }
1972
+ /**
1973
+ * @type {Number}
1974
+ */
1975
+ get code() {
1976
+ return this[kCode];
1977
+ }
1978
+ /**
1979
+ * @type {String}
1980
+ */
1981
+ get reason() {
1982
+ return this[kReason];
1983
+ }
1984
+ /**
1985
+ * @type {Boolean}
1986
+ */
1987
+ get wasClean() {
1988
+ return this[kWasClean];
1989
+ }
1990
+ };
1991
+ Object.defineProperty(CloseEvent.prototype, "code", { enumerable: true });
1992
+ Object.defineProperty(CloseEvent.prototype, "reason", { enumerable: true });
1993
+ Object.defineProperty(CloseEvent.prototype, "wasClean", { enumerable: true });
1994
+ /**
1995
+ * Class representing an error event.
1996
+ *
1997
+ * @extends Event
1998
+ */
1999
+ var ErrorEvent = class extends Event {
2000
+ /**
2001
+ * Create a new `ErrorEvent`.
2002
+ *
2003
+ * @param {String} type The name of the event
2004
+ * @param {Object} [options] A dictionary object that allows for setting
2005
+ * attributes via object members of the same name
2006
+ * @param {*} [options.error=null] The error that generated this event
2007
+ * @param {String} [options.message=''] The error message
2008
+ */
2009
+ constructor(type, options = {}) {
2010
+ super(type);
2011
+ this[kError] = options.error === void 0 ? null : options.error;
2012
+ this[kMessage] = options.message === void 0 ? "" : options.message;
2013
+ }
2014
+ /**
2015
+ * @type {*}
2016
+ */
2017
+ get error() {
2018
+ return this[kError];
2019
+ }
2020
+ /**
2021
+ * @type {String}
2022
+ */
2023
+ get message() {
2024
+ return this[kMessage];
2025
+ }
2026
+ };
2027
+ Object.defineProperty(ErrorEvent.prototype, "error", { enumerable: true });
2028
+ Object.defineProperty(ErrorEvent.prototype, "message", { enumerable: true });
2029
+ /**
2030
+ * Class representing a message event.
2031
+ *
2032
+ * @extends Event
2033
+ */
2034
+ var MessageEvent = class extends Event {
2035
+ /**
2036
+ * Create a new `MessageEvent`.
2037
+ *
2038
+ * @param {String} type The name of the event
2039
+ * @param {Object} [options] A dictionary object that allows for setting
2040
+ * attributes via object members of the same name
2041
+ * @param {*} [options.data=null] The message content
2042
+ */
2043
+ constructor(type, options = {}) {
2044
+ super(type);
2045
+ this[kData] = options.data === void 0 ? null : options.data;
2046
+ }
2047
+ /**
2048
+ * @type {*}
2049
+ */
2050
+ get data() {
2051
+ return this[kData];
2052
+ }
2053
+ };
2054
+ Object.defineProperty(MessageEvent.prototype, "data", { enumerable: true });
2055
+ module.exports = {
2056
+ CloseEvent,
2057
+ ErrorEvent,
2058
+ Event,
2059
+ EventTarget: {
2060
+ addEventListener(type, handler, options = {}) {
2061
+ for (const listener of this.listeners(type)) if (!options[kForOnEventAttribute] && listener[kListener] === handler && !listener[kForOnEventAttribute]) return;
2062
+ let wrapper;
2063
+ if (type === "message") wrapper = function onMessage(data, isBinary) {
2064
+ const event = new MessageEvent("message", { data: isBinary ? data : data.toString() });
2065
+ event[kTarget] = this;
2066
+ callListener(handler, this, event);
2067
+ };
2068
+ else if (type === "close") wrapper = function onClose(code, message) {
2069
+ const event = new CloseEvent("close", {
2070
+ code,
2071
+ reason: message.toString(),
2072
+ wasClean: this._closeFrameReceived && this._closeFrameSent
2073
+ });
2074
+ event[kTarget] = this;
2075
+ callListener(handler, this, event);
2076
+ };
2077
+ else if (type === "error") wrapper = function onError(error) {
2078
+ const event = new ErrorEvent("error", {
2079
+ error,
2080
+ message: error.message
2081
+ });
2082
+ event[kTarget] = this;
2083
+ callListener(handler, this, event);
2084
+ };
2085
+ else if (type === "open") wrapper = function onOpen() {
2086
+ const event = new Event("open");
2087
+ event[kTarget] = this;
2088
+ callListener(handler, this, event);
2089
+ };
2090
+ else return;
2091
+ wrapper[kForOnEventAttribute] = !!options[kForOnEventAttribute];
2092
+ wrapper[kListener] = handler;
2093
+ if (options.once) this.once(type, wrapper);
2094
+ else this.on(type, wrapper);
2095
+ },
2096
+ removeEventListener(type, handler) {
2097
+ for (const listener of this.listeners(type)) if (listener[kListener] === handler && !listener[kForOnEventAttribute]) {
2098
+ this.removeListener(type, listener);
2099
+ break;
2100
+ }
2101
+ }
2102
+ },
2103
+ MessageEvent
2104
+ };
2105
+ /**
2106
+ * Call an event listener
2107
+ *
2108
+ * @param {(Function|Object)} listener The listener to call
2109
+ * @param {*} thisArg The value to use as `this`` when calling the listener
2110
+ * @param {Event} event The event to pass to the listener
2111
+ * @private
2112
+ */
2113
+ function callListener(listener, thisArg, event) {
2114
+ if (typeof listener === "object" && listener.handleEvent) listener.handleEvent.call(listener, event);
2115
+ else listener.call(thisArg, event);
2116
+ }
2117
+ }));
2118
+ //#endregion
2119
+ //#region node_modules/.pnpm/ws@8.20.0/node_modules/ws/lib/extension.js
2120
+ var require_extension = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2121
+ const { tokenChars } = require_validation();
2122
+ /**
2123
+ * Adds an offer to the map of extension offers or a parameter to the map of
2124
+ * parameters.
2125
+ *
2126
+ * @param {Object} dest The map of extension offers or parameters
2127
+ * @param {String} name The extension or parameter name
2128
+ * @param {(Object|Boolean|String)} elem The extension parameters or the
2129
+ * parameter value
2130
+ * @private
2131
+ */
2132
+ function push(dest, name, elem) {
2133
+ if (dest[name] === void 0) dest[name] = [elem];
2134
+ else dest[name].push(elem);
2135
+ }
2136
+ /**
2137
+ * Parses the `Sec-WebSocket-Extensions` header into an object.
2138
+ *
2139
+ * @param {String} header The field value of the header
2140
+ * @return {Object} The parsed object
2141
+ * @public
2142
+ */
2143
+ function parse(header) {
2144
+ const offers = Object.create(null);
2145
+ let params = Object.create(null);
2146
+ let mustUnescape = false;
2147
+ let isEscaping = false;
2148
+ let inQuotes = false;
2149
+ let extensionName;
2150
+ let paramName;
2151
+ let start = -1;
2152
+ let code = -1;
2153
+ let end = -1;
2154
+ let i = 0;
2155
+ for (; i < header.length; i++) {
2156
+ code = header.charCodeAt(i);
2157
+ if (extensionName === void 0) if (end === -1 && tokenChars[code] === 1) {
2158
+ if (start === -1) start = i;
2159
+ } else if (i !== 0 && (code === 32 || code === 9)) {
2160
+ if (end === -1 && start !== -1) end = i;
2161
+ } else if (code === 59 || code === 44) {
2162
+ if (start === -1) throw new SyntaxError(`Unexpected character at index ${i}`);
2163
+ if (end === -1) end = i;
2164
+ const name = header.slice(start, end);
2165
+ if (code === 44) {
2166
+ push(offers, name, params);
2167
+ params = Object.create(null);
2168
+ } else extensionName = name;
2169
+ start = end = -1;
2170
+ } else throw new SyntaxError(`Unexpected character at index ${i}`);
2171
+ else if (paramName === void 0) if (end === -1 && tokenChars[code] === 1) {
2172
+ if (start === -1) start = i;
2173
+ } else if (code === 32 || code === 9) {
2174
+ if (end === -1 && start !== -1) end = i;
2175
+ } else if (code === 59 || code === 44) {
2176
+ if (start === -1) throw new SyntaxError(`Unexpected character at index ${i}`);
2177
+ if (end === -1) end = i;
2178
+ push(params, header.slice(start, end), true);
2179
+ if (code === 44) {
2180
+ push(offers, extensionName, params);
2181
+ params = Object.create(null);
2182
+ extensionName = void 0;
2183
+ }
2184
+ start = end = -1;
2185
+ } else if (code === 61 && start !== -1 && end === -1) {
2186
+ paramName = header.slice(start, i);
2187
+ start = end = -1;
2188
+ } else throw new SyntaxError(`Unexpected character at index ${i}`);
2189
+ else if (isEscaping) {
2190
+ if (tokenChars[code] !== 1) throw new SyntaxError(`Unexpected character at index ${i}`);
2191
+ if (start === -1) start = i;
2192
+ else if (!mustUnescape) mustUnescape = true;
2193
+ isEscaping = false;
2194
+ } else if (inQuotes) if (tokenChars[code] === 1) {
2195
+ if (start === -1) start = i;
2196
+ } else if (code === 34 && start !== -1) {
2197
+ inQuotes = false;
2198
+ end = i;
2199
+ } else if (code === 92) isEscaping = true;
2200
+ else throw new SyntaxError(`Unexpected character at index ${i}`);
2201
+ else if (code === 34 && header.charCodeAt(i - 1) === 61) inQuotes = true;
2202
+ else if (end === -1 && tokenChars[code] === 1) {
2203
+ if (start === -1) start = i;
2204
+ } else if (start !== -1 && (code === 32 || code === 9)) {
2205
+ if (end === -1) end = i;
2206
+ } else if (code === 59 || code === 44) {
2207
+ if (start === -1) throw new SyntaxError(`Unexpected character at index ${i}`);
2208
+ if (end === -1) end = i;
2209
+ let value = header.slice(start, end);
2210
+ if (mustUnescape) {
2211
+ value = value.replace(/\\/g, "");
2212
+ mustUnescape = false;
2213
+ }
2214
+ push(params, paramName, value);
2215
+ if (code === 44) {
2216
+ push(offers, extensionName, params);
2217
+ params = Object.create(null);
2218
+ extensionName = void 0;
2219
+ }
2220
+ paramName = void 0;
2221
+ start = end = -1;
2222
+ } else throw new SyntaxError(`Unexpected character at index ${i}`);
2223
+ }
2224
+ if (start === -1 || inQuotes || code === 32 || code === 9) throw new SyntaxError("Unexpected end of input");
2225
+ if (end === -1) end = i;
2226
+ const token = header.slice(start, end);
2227
+ if (extensionName === void 0) push(offers, token, params);
2228
+ else {
2229
+ if (paramName === void 0) push(params, token, true);
2230
+ else if (mustUnescape) push(params, paramName, token.replace(/\\/g, ""));
2231
+ else push(params, paramName, token);
2232
+ push(offers, extensionName, params);
2233
+ }
2234
+ return offers;
2235
+ }
2236
+ /**
2237
+ * Builds the `Sec-WebSocket-Extensions` header field value.
2238
+ *
2239
+ * @param {Object} extensions The map of extensions and parameters to format
2240
+ * @return {String} A string representing the given object
2241
+ * @public
2242
+ */
2243
+ function format(extensions) {
2244
+ return Object.keys(extensions).map((extension) => {
2245
+ let configurations = extensions[extension];
2246
+ if (!Array.isArray(configurations)) configurations = [configurations];
2247
+ return configurations.map((params) => {
2248
+ return [extension].concat(Object.keys(params).map((k) => {
2249
+ let values = params[k];
2250
+ if (!Array.isArray(values)) values = [values];
2251
+ return values.map((v) => v === true ? k : `${k}=${v}`).join("; ");
2252
+ })).join("; ");
2253
+ }).join(", ");
2254
+ }).join(", ");
2255
+ }
2256
+ module.exports = {
2257
+ format,
2258
+ parse
2259
+ };
2260
+ }));
2261
+ //#endregion
2262
+ //#region node_modules/.pnpm/ws@8.20.0/node_modules/ws/lib/websocket.js
2263
+ var require_websocket = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2264
+ const EventEmitter$2 = __require("events");
2265
+ const https = __require("https");
2266
+ const http$1 = __require("http");
2267
+ const net = __require("net");
2268
+ const tls = __require("tls");
2269
+ const { randomBytes, createHash: createHash$1 } = __require("crypto");
2270
+ const { Duplex: Duplex$2, Readable } = __require("stream");
2271
+ const { URL: URL$1 } = __require("url");
2272
+ const PerMessageDeflate = require_permessage_deflate();
2273
+ const Receiver = require_receiver();
2274
+ const Sender = require_sender();
2275
+ const { isBlob } = require_validation();
2276
+ const { BINARY_TYPES, CLOSE_TIMEOUT, EMPTY_BUFFER, GUID, kForOnEventAttribute, kListener, kStatusCode, kWebSocket, NOOP } = require_constants();
2277
+ const { EventTarget: { addEventListener, removeEventListener } } = require_event_target();
2278
+ const { format, parse } = require_extension();
2279
+ const { toBuffer } = require_buffer_util();
2280
+ const kAborted = Symbol("kAborted");
2281
+ const protocolVersions = [8, 13];
2282
+ const readyStates = [
2283
+ "CONNECTING",
2284
+ "OPEN",
2285
+ "CLOSING",
2286
+ "CLOSED"
2287
+ ];
2288
+ const subprotocolRegex = /^[!#$%&'*+\-.0-9A-Z^_`|a-z~]+$/;
2289
+ /**
2290
+ * Class representing a WebSocket.
2291
+ *
2292
+ * @extends EventEmitter
2293
+ */
2294
+ var WebSocket = class WebSocket extends EventEmitter$2 {
2295
+ /**
2296
+ * Create a new `WebSocket`.
2297
+ *
2298
+ * @param {(String|URL)} address The URL to which to connect
2299
+ * @param {(String|String[])} [protocols] The subprotocols
2300
+ * @param {Object} [options] Connection options
2301
+ */
2302
+ constructor(address, protocols, options) {
2303
+ super();
2304
+ this._binaryType = BINARY_TYPES[0];
2305
+ this._closeCode = 1006;
2306
+ this._closeFrameReceived = false;
2307
+ this._closeFrameSent = false;
2308
+ this._closeMessage = EMPTY_BUFFER;
2309
+ this._closeTimer = null;
2310
+ this._errorEmitted = false;
2311
+ this._extensions = {};
2312
+ this._paused = false;
2313
+ this._protocol = "";
2314
+ this._readyState = WebSocket.CONNECTING;
2315
+ this._receiver = null;
2316
+ this._sender = null;
2317
+ this._socket = null;
2318
+ if (address !== null) {
2319
+ this._bufferedAmount = 0;
2320
+ this._isServer = false;
2321
+ this._redirects = 0;
2322
+ if (protocols === void 0) protocols = [];
2323
+ else if (!Array.isArray(protocols)) if (typeof protocols === "object" && protocols !== null) {
2324
+ options = protocols;
2325
+ protocols = [];
2326
+ } else protocols = [protocols];
2327
+ initAsClient(this, address, protocols, options);
2328
+ } else {
2329
+ this._autoPong = options.autoPong;
2330
+ this._closeTimeout = options.closeTimeout;
2331
+ this._isServer = true;
2332
+ }
2333
+ }
2334
+ /**
2335
+ * For historical reasons, the custom "nodebuffer" type is used by the default
2336
+ * instead of "blob".
2337
+ *
2338
+ * @type {String}
2339
+ */
2340
+ get binaryType() {
2341
+ return this._binaryType;
2342
+ }
2343
+ set binaryType(type) {
2344
+ if (!BINARY_TYPES.includes(type)) return;
2345
+ this._binaryType = type;
2346
+ if (this._receiver) this._receiver._binaryType = type;
2347
+ }
2348
+ /**
2349
+ * @type {Number}
2350
+ */
2351
+ get bufferedAmount() {
2352
+ if (!this._socket) return this._bufferedAmount;
2353
+ return this._socket._writableState.length + this._sender._bufferedBytes;
2354
+ }
2355
+ /**
2356
+ * @type {String}
2357
+ */
2358
+ get extensions() {
2359
+ return Object.keys(this._extensions).join();
2360
+ }
2361
+ /**
2362
+ * @type {Boolean}
2363
+ */
2364
+ get isPaused() {
2365
+ return this._paused;
2366
+ }
2367
+ /**
2368
+ * @type {Function}
2369
+ */
2370
+ /* istanbul ignore next */
2371
+ get onclose() {
2372
+ return null;
2373
+ }
2374
+ /**
2375
+ * @type {Function}
2376
+ */
2377
+ /* istanbul ignore next */
2378
+ get onerror() {
2379
+ return null;
2380
+ }
2381
+ /**
2382
+ * @type {Function}
2383
+ */
2384
+ /* istanbul ignore next */
2385
+ get onopen() {
2386
+ return null;
2387
+ }
2388
+ /**
2389
+ * @type {Function}
2390
+ */
2391
+ /* istanbul ignore next */
2392
+ get onmessage() {
2393
+ return null;
2394
+ }
2395
+ /**
2396
+ * @type {String}
2397
+ */
2398
+ get protocol() {
2399
+ return this._protocol;
2400
+ }
2401
+ /**
2402
+ * @type {Number}
2403
+ */
2404
+ get readyState() {
2405
+ return this._readyState;
2406
+ }
2407
+ /**
2408
+ * @type {String}
2409
+ */
2410
+ get url() {
2411
+ return this._url;
2412
+ }
2413
+ /**
2414
+ * Set up the socket and the internal resources.
2415
+ *
2416
+ * @param {Duplex} socket The network socket between the server and client
2417
+ * @param {Buffer} head The first packet of the upgraded stream
2418
+ * @param {Object} options Options object
2419
+ * @param {Boolean} [options.allowSynchronousEvents=false] Specifies whether
2420
+ * any of the `'message'`, `'ping'`, and `'pong'` events can be emitted
2421
+ * multiple times in the same tick
2422
+ * @param {Function} [options.generateMask] The function used to generate the
2423
+ * masking key
2424
+ * @param {Number} [options.maxPayload=0] The maximum allowed message size
2425
+ * @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or
2426
+ * not to skip UTF-8 validation for text and close messages
2427
+ * @private
2428
+ */
2429
+ setSocket(socket, head, options) {
2430
+ const receiver = new Receiver({
2431
+ allowSynchronousEvents: options.allowSynchronousEvents,
2432
+ binaryType: this.binaryType,
2433
+ extensions: this._extensions,
2434
+ isServer: this._isServer,
2435
+ maxPayload: options.maxPayload,
2436
+ skipUTF8Validation: options.skipUTF8Validation
2437
+ });
2438
+ const sender = new Sender(socket, this._extensions, options.generateMask);
2439
+ this._receiver = receiver;
2440
+ this._sender = sender;
2441
+ this._socket = socket;
2442
+ receiver[kWebSocket] = this;
2443
+ sender[kWebSocket] = this;
2444
+ socket[kWebSocket] = this;
2445
+ receiver.on("conclude", receiverOnConclude);
2446
+ receiver.on("drain", receiverOnDrain);
2447
+ receiver.on("error", receiverOnError);
2448
+ receiver.on("message", receiverOnMessage);
2449
+ receiver.on("ping", receiverOnPing);
2450
+ receiver.on("pong", receiverOnPong);
2451
+ sender.onerror = senderOnError;
2452
+ if (socket.setTimeout) socket.setTimeout(0);
2453
+ if (socket.setNoDelay) socket.setNoDelay();
2454
+ if (head.length > 0) socket.unshift(head);
2455
+ socket.on("close", socketOnClose);
2456
+ socket.on("data", socketOnData);
2457
+ socket.on("end", socketOnEnd);
2458
+ socket.on("error", socketOnError);
2459
+ this._readyState = WebSocket.OPEN;
2460
+ this.emit("open");
2461
+ }
2462
+ /**
2463
+ * Emit the `'close'` event.
2464
+ *
2465
+ * @private
2466
+ */
2467
+ emitClose() {
2468
+ if (!this._socket) {
2469
+ this._readyState = WebSocket.CLOSED;
2470
+ this.emit("close", this._closeCode, this._closeMessage);
2471
+ return;
2472
+ }
2473
+ if (this._extensions[PerMessageDeflate.extensionName]) this._extensions[PerMessageDeflate.extensionName].cleanup();
2474
+ this._receiver.removeAllListeners();
2475
+ this._readyState = WebSocket.CLOSED;
2476
+ this.emit("close", this._closeCode, this._closeMessage);
2477
+ }
2478
+ /**
2479
+ * Start a closing handshake.
2480
+ *
2481
+ * +----------+ +-----------+ +----------+
2482
+ * - - -|ws.close()|-->|close frame|-->|ws.close()|- - -
2483
+ * | +----------+ +-----------+ +----------+ |
2484
+ * +----------+ +-----------+ |
2485
+ * CLOSING |ws.close()|<--|close frame|<--+-----+ CLOSING
2486
+ * +----------+ +-----------+ |
2487
+ * | | | +---+ |
2488
+ * +------------------------+-->|fin| - - - -
2489
+ * | +---+ | +---+
2490
+ * - - - - -|fin|<---------------------+
2491
+ * +---+
2492
+ *
2493
+ * @param {Number} [code] Status code explaining why the connection is closing
2494
+ * @param {(String|Buffer)} [data] The reason why the connection is
2495
+ * closing
2496
+ * @public
2497
+ */
2498
+ close(code, data) {
2499
+ if (this.readyState === WebSocket.CLOSED) return;
2500
+ if (this.readyState === WebSocket.CONNECTING) {
2501
+ abortHandshake(this, this._req, "WebSocket was closed before the connection was established");
2502
+ return;
2503
+ }
2504
+ if (this.readyState === WebSocket.CLOSING) {
2505
+ if (this._closeFrameSent && (this._closeFrameReceived || this._receiver._writableState.errorEmitted)) this._socket.end();
2506
+ return;
2507
+ }
2508
+ this._readyState = WebSocket.CLOSING;
2509
+ this._sender.close(code, data, !this._isServer, (err) => {
2510
+ if (err) return;
2511
+ this._closeFrameSent = true;
2512
+ if (this._closeFrameReceived || this._receiver._writableState.errorEmitted) this._socket.end();
2513
+ });
2514
+ setCloseTimer(this);
2515
+ }
2516
+ /**
2517
+ * Pause the socket.
2518
+ *
2519
+ * @public
2520
+ */
2521
+ pause() {
2522
+ if (this.readyState === WebSocket.CONNECTING || this.readyState === WebSocket.CLOSED) return;
2523
+ this._paused = true;
2524
+ this._socket.pause();
2525
+ }
2526
+ /**
2527
+ * Send a ping.
2528
+ *
2529
+ * @param {*} [data] The data to send
2530
+ * @param {Boolean} [mask] Indicates whether or not to mask `data`
2531
+ * @param {Function} [cb] Callback which is executed when the ping is sent
2532
+ * @public
2533
+ */
2534
+ ping(data, mask, cb) {
2535
+ if (this.readyState === WebSocket.CONNECTING) throw new Error("WebSocket is not open: readyState 0 (CONNECTING)");
2536
+ if (typeof data === "function") {
2537
+ cb = data;
2538
+ data = mask = void 0;
2539
+ } else if (typeof mask === "function") {
2540
+ cb = mask;
2541
+ mask = void 0;
2542
+ }
2543
+ if (typeof data === "number") data = data.toString();
2544
+ if (this.readyState !== WebSocket.OPEN) {
2545
+ sendAfterClose(this, data, cb);
2546
+ return;
2547
+ }
2548
+ if (mask === void 0) mask = !this._isServer;
2549
+ this._sender.ping(data || EMPTY_BUFFER, mask, cb);
2550
+ }
2551
+ /**
2552
+ * Send a pong.
2553
+ *
2554
+ * @param {*} [data] The data to send
2555
+ * @param {Boolean} [mask] Indicates whether or not to mask `data`
2556
+ * @param {Function} [cb] Callback which is executed when the pong is sent
2557
+ * @public
2558
+ */
2559
+ pong(data, mask, cb) {
2560
+ if (this.readyState === WebSocket.CONNECTING) throw new Error("WebSocket is not open: readyState 0 (CONNECTING)");
2561
+ if (typeof data === "function") {
2562
+ cb = data;
2563
+ data = mask = void 0;
2564
+ } else if (typeof mask === "function") {
2565
+ cb = mask;
2566
+ mask = void 0;
2567
+ }
2568
+ if (typeof data === "number") data = data.toString();
2569
+ if (this.readyState !== WebSocket.OPEN) {
2570
+ sendAfterClose(this, data, cb);
2571
+ return;
2572
+ }
2573
+ if (mask === void 0) mask = !this._isServer;
2574
+ this._sender.pong(data || EMPTY_BUFFER, mask, cb);
2575
+ }
2576
+ /**
2577
+ * Resume the socket.
2578
+ *
2579
+ * @public
2580
+ */
2581
+ resume() {
2582
+ if (this.readyState === WebSocket.CONNECTING || this.readyState === WebSocket.CLOSED) return;
2583
+ this._paused = false;
2584
+ if (!this._receiver._writableState.needDrain) this._socket.resume();
2585
+ }
2586
+ /**
2587
+ * Send a data message.
2588
+ *
2589
+ * @param {*} data The message to send
2590
+ * @param {Object} [options] Options object
2591
+ * @param {Boolean} [options.binary] Specifies whether `data` is binary or
2592
+ * text
2593
+ * @param {Boolean} [options.compress] Specifies whether or not to compress
2594
+ * `data`
2595
+ * @param {Boolean} [options.fin=true] Specifies whether the fragment is the
2596
+ * last one
2597
+ * @param {Boolean} [options.mask] Specifies whether or not to mask `data`
2598
+ * @param {Function} [cb] Callback which is executed when data is written out
2599
+ * @public
2600
+ */
2601
+ send(data, options, cb) {
2602
+ if (this.readyState === WebSocket.CONNECTING) throw new Error("WebSocket is not open: readyState 0 (CONNECTING)");
2603
+ if (typeof options === "function") {
2604
+ cb = options;
2605
+ options = {};
2606
+ }
2607
+ if (typeof data === "number") data = data.toString();
2608
+ if (this.readyState !== WebSocket.OPEN) {
2609
+ sendAfterClose(this, data, cb);
2610
+ return;
2611
+ }
2612
+ const opts = {
2613
+ binary: typeof data !== "string",
2614
+ mask: !this._isServer,
2615
+ compress: true,
2616
+ fin: true,
2617
+ ...options
2618
+ };
2619
+ if (!this._extensions[PerMessageDeflate.extensionName]) opts.compress = false;
2620
+ this._sender.send(data || EMPTY_BUFFER, opts, cb);
2621
+ }
2622
+ /**
2623
+ * Forcibly close the connection.
2624
+ *
2625
+ * @public
2626
+ */
2627
+ terminate() {
2628
+ if (this.readyState === WebSocket.CLOSED) return;
2629
+ if (this.readyState === WebSocket.CONNECTING) {
2630
+ abortHandshake(this, this._req, "WebSocket was closed before the connection was established");
2631
+ return;
2632
+ }
2633
+ if (this._socket) {
2634
+ this._readyState = WebSocket.CLOSING;
2635
+ this._socket.destroy();
2636
+ }
2637
+ }
2638
+ };
2639
+ /**
2640
+ * @constant {Number} CONNECTING
2641
+ * @memberof WebSocket
2642
+ */
2643
+ Object.defineProperty(WebSocket, "CONNECTING", {
2644
+ enumerable: true,
2645
+ value: readyStates.indexOf("CONNECTING")
2646
+ });
2647
+ /**
2648
+ * @constant {Number} CONNECTING
2649
+ * @memberof WebSocket.prototype
2650
+ */
2651
+ Object.defineProperty(WebSocket.prototype, "CONNECTING", {
2652
+ enumerable: true,
2653
+ value: readyStates.indexOf("CONNECTING")
2654
+ });
2655
+ /**
2656
+ * @constant {Number} OPEN
2657
+ * @memberof WebSocket
2658
+ */
2659
+ Object.defineProperty(WebSocket, "OPEN", {
2660
+ enumerable: true,
2661
+ value: readyStates.indexOf("OPEN")
2662
+ });
2663
+ /**
2664
+ * @constant {Number} OPEN
2665
+ * @memberof WebSocket.prototype
2666
+ */
2667
+ Object.defineProperty(WebSocket.prototype, "OPEN", {
2668
+ enumerable: true,
2669
+ value: readyStates.indexOf("OPEN")
2670
+ });
2671
+ /**
2672
+ * @constant {Number} CLOSING
2673
+ * @memberof WebSocket
2674
+ */
2675
+ Object.defineProperty(WebSocket, "CLOSING", {
2676
+ enumerable: true,
2677
+ value: readyStates.indexOf("CLOSING")
2678
+ });
2679
+ /**
2680
+ * @constant {Number} CLOSING
2681
+ * @memberof WebSocket.prototype
2682
+ */
2683
+ Object.defineProperty(WebSocket.prototype, "CLOSING", {
2684
+ enumerable: true,
2685
+ value: readyStates.indexOf("CLOSING")
2686
+ });
2687
+ /**
2688
+ * @constant {Number} CLOSED
2689
+ * @memberof WebSocket
2690
+ */
2691
+ Object.defineProperty(WebSocket, "CLOSED", {
2692
+ enumerable: true,
2693
+ value: readyStates.indexOf("CLOSED")
2694
+ });
2695
+ /**
2696
+ * @constant {Number} CLOSED
2697
+ * @memberof WebSocket.prototype
2698
+ */
2699
+ Object.defineProperty(WebSocket.prototype, "CLOSED", {
2700
+ enumerable: true,
2701
+ value: readyStates.indexOf("CLOSED")
2702
+ });
2703
+ [
2704
+ "binaryType",
2705
+ "bufferedAmount",
2706
+ "extensions",
2707
+ "isPaused",
2708
+ "protocol",
2709
+ "readyState",
2710
+ "url"
2711
+ ].forEach((property) => {
2712
+ Object.defineProperty(WebSocket.prototype, property, { enumerable: true });
2713
+ });
2714
+ [
2715
+ "open",
2716
+ "error",
2717
+ "close",
2718
+ "message"
2719
+ ].forEach((method) => {
2720
+ Object.defineProperty(WebSocket.prototype, `on${method}`, {
2721
+ enumerable: true,
2722
+ get() {
2723
+ for (const listener of this.listeners(method)) if (listener[kForOnEventAttribute]) return listener[kListener];
2724
+ return null;
2725
+ },
2726
+ set(handler) {
2727
+ for (const listener of this.listeners(method)) if (listener[kForOnEventAttribute]) {
2728
+ this.removeListener(method, listener);
2729
+ break;
2730
+ }
2731
+ if (typeof handler !== "function") return;
2732
+ this.addEventListener(method, handler, { [kForOnEventAttribute]: true });
2733
+ }
2734
+ });
2735
+ });
2736
+ WebSocket.prototype.addEventListener = addEventListener;
2737
+ WebSocket.prototype.removeEventListener = removeEventListener;
2738
+ module.exports = WebSocket;
2739
+ /**
2740
+ * Initialize a WebSocket client.
2741
+ *
2742
+ * @param {WebSocket} websocket The client to initialize
2743
+ * @param {(String|URL)} address The URL to which to connect
2744
+ * @param {Array} protocols The subprotocols
2745
+ * @param {Object} [options] Connection options
2746
+ * @param {Boolean} [options.allowSynchronousEvents=true] Specifies whether any
2747
+ * of the `'message'`, `'ping'`, and `'pong'` events can be emitted multiple
2748
+ * times in the same tick
2749
+ * @param {Boolean} [options.autoPong=true] Specifies whether or not to
2750
+ * automatically send a pong in response to a ping
2751
+ * @param {Number} [options.closeTimeout=30000] Duration in milliseconds to wait
2752
+ * for the closing handshake to finish after `websocket.close()` is called
2753
+ * @param {Function} [options.finishRequest] A function which can be used to
2754
+ * customize the headers of each http request before it is sent
2755
+ * @param {Boolean} [options.followRedirects=false] Whether or not to follow
2756
+ * redirects
2757
+ * @param {Function} [options.generateMask] The function used to generate the
2758
+ * masking key
2759
+ * @param {Number} [options.handshakeTimeout] Timeout in milliseconds for the
2760
+ * handshake request
2761
+ * @param {Number} [options.maxPayload=104857600] The maximum allowed message
2762
+ * size
2763
+ * @param {Number} [options.maxRedirects=10] The maximum number of redirects
2764
+ * allowed
2765
+ * @param {String} [options.origin] Value of the `Origin` or
2766
+ * `Sec-WebSocket-Origin` header
2767
+ * @param {(Boolean|Object)} [options.perMessageDeflate=true] Enable/disable
2768
+ * permessage-deflate
2769
+ * @param {Number} [options.protocolVersion=13] Value of the
2770
+ * `Sec-WebSocket-Version` header
2771
+ * @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or
2772
+ * not to skip UTF-8 validation for text and close messages
2773
+ * @private
2774
+ */
2775
+ function initAsClient(websocket, address, protocols, options) {
2776
+ const opts = {
2777
+ allowSynchronousEvents: true,
2778
+ autoPong: true,
2779
+ closeTimeout: CLOSE_TIMEOUT,
2780
+ protocolVersion: protocolVersions[1],
2781
+ maxPayload: 100 * 1024 * 1024,
2782
+ skipUTF8Validation: false,
2783
+ perMessageDeflate: true,
2784
+ followRedirects: false,
2785
+ maxRedirects: 10,
2786
+ ...options,
2787
+ socketPath: void 0,
2788
+ hostname: void 0,
2789
+ protocol: void 0,
2790
+ timeout: void 0,
2791
+ method: "GET",
2792
+ host: void 0,
2793
+ path: void 0,
2794
+ port: void 0
2795
+ };
2796
+ websocket._autoPong = opts.autoPong;
2797
+ websocket._closeTimeout = opts.closeTimeout;
2798
+ if (!protocolVersions.includes(opts.protocolVersion)) throw new RangeError(`Unsupported protocol version: ${opts.protocolVersion} (supported versions: ${protocolVersions.join(", ")})`);
2799
+ let parsedUrl;
2800
+ if (address instanceof URL$1) parsedUrl = address;
2801
+ else try {
2802
+ parsedUrl = new URL$1(address);
2803
+ } catch {
2804
+ throw new SyntaxError(`Invalid URL: ${address}`);
2805
+ }
2806
+ if (parsedUrl.protocol === "http:") parsedUrl.protocol = "ws:";
2807
+ else if (parsedUrl.protocol === "https:") parsedUrl.protocol = "wss:";
2808
+ websocket._url = parsedUrl.href;
2809
+ const isSecure = parsedUrl.protocol === "wss:";
2810
+ const isIpcUrl = parsedUrl.protocol === "ws+unix:";
2811
+ let invalidUrlMessage;
2812
+ if (parsedUrl.protocol !== "ws:" && !isSecure && !isIpcUrl) invalidUrlMessage = "The URL's protocol must be one of \"ws:\", \"wss:\", \"http:\", \"https:\", or \"ws+unix:\"";
2813
+ else if (isIpcUrl && !parsedUrl.pathname) invalidUrlMessage = "The URL's pathname is empty";
2814
+ else if (parsedUrl.hash) invalidUrlMessage = "The URL contains a fragment identifier";
2815
+ if (invalidUrlMessage) {
2816
+ const err = new SyntaxError(invalidUrlMessage);
2817
+ if (websocket._redirects === 0) throw err;
2818
+ else {
2819
+ emitErrorAndClose(websocket, err);
2820
+ return;
2821
+ }
2822
+ }
2823
+ const defaultPort = isSecure ? 443 : 80;
2824
+ const key = randomBytes(16).toString("base64");
2825
+ const request = isSecure ? https.request : http$1.request;
2826
+ const protocolSet = /* @__PURE__ */ new Set();
2827
+ let perMessageDeflate;
2828
+ opts.createConnection = opts.createConnection || (isSecure ? tlsConnect : netConnect);
2829
+ opts.defaultPort = opts.defaultPort || defaultPort;
2830
+ opts.port = parsedUrl.port || defaultPort;
2831
+ opts.host = parsedUrl.hostname.startsWith("[") ? parsedUrl.hostname.slice(1, -1) : parsedUrl.hostname;
2832
+ opts.headers = {
2833
+ ...opts.headers,
2834
+ "Sec-WebSocket-Version": opts.protocolVersion,
2835
+ "Sec-WebSocket-Key": key,
2836
+ Connection: "Upgrade",
2837
+ Upgrade: "websocket"
2838
+ };
2839
+ opts.path = parsedUrl.pathname + parsedUrl.search;
2840
+ opts.timeout = opts.handshakeTimeout;
2841
+ if (opts.perMessageDeflate) {
2842
+ perMessageDeflate = new PerMessageDeflate({
2843
+ ...opts.perMessageDeflate,
2844
+ isServer: false,
2845
+ maxPayload: opts.maxPayload
2846
+ });
2847
+ opts.headers["Sec-WebSocket-Extensions"] = format({ [PerMessageDeflate.extensionName]: perMessageDeflate.offer() });
2848
+ }
2849
+ if (protocols.length) {
2850
+ for (const protocol of protocols) {
2851
+ if (typeof protocol !== "string" || !subprotocolRegex.test(protocol) || protocolSet.has(protocol)) throw new SyntaxError("An invalid or duplicated subprotocol was specified");
2852
+ protocolSet.add(protocol);
2853
+ }
2854
+ opts.headers["Sec-WebSocket-Protocol"] = protocols.join(",");
2855
+ }
2856
+ if (opts.origin) if (opts.protocolVersion < 13) opts.headers["Sec-WebSocket-Origin"] = opts.origin;
2857
+ else opts.headers.Origin = opts.origin;
2858
+ if (parsedUrl.username || parsedUrl.password) opts.auth = `${parsedUrl.username}:${parsedUrl.password}`;
2859
+ if (isIpcUrl) {
2860
+ const parts = opts.path.split(":");
2861
+ opts.socketPath = parts[0];
2862
+ opts.path = parts[1];
2863
+ }
2864
+ let req;
2865
+ if (opts.followRedirects) {
2866
+ if (websocket._redirects === 0) {
2867
+ websocket._originalIpc = isIpcUrl;
2868
+ websocket._originalSecure = isSecure;
2869
+ websocket._originalHostOrSocketPath = isIpcUrl ? opts.socketPath : parsedUrl.host;
2870
+ const headers = options && options.headers;
2871
+ options = {
2872
+ ...options,
2873
+ headers: {}
2874
+ };
2875
+ if (headers) for (const [key, value] of Object.entries(headers)) options.headers[key.toLowerCase()] = value;
2876
+ } else if (websocket.listenerCount("redirect") === 0) {
2877
+ const isSameHost = isIpcUrl ? websocket._originalIpc ? opts.socketPath === websocket._originalHostOrSocketPath : false : websocket._originalIpc ? false : parsedUrl.host === websocket._originalHostOrSocketPath;
2878
+ if (!isSameHost || websocket._originalSecure && !isSecure) {
2879
+ delete opts.headers.authorization;
2880
+ delete opts.headers.cookie;
2881
+ if (!isSameHost) delete opts.headers.host;
2882
+ opts.auth = void 0;
2883
+ }
2884
+ }
2885
+ if (opts.auth && !options.headers.authorization) options.headers.authorization = "Basic " + Buffer.from(opts.auth).toString("base64");
2886
+ req = websocket._req = request(opts);
2887
+ if (websocket._redirects) websocket.emit("redirect", websocket.url, req);
2888
+ } else req = websocket._req = request(opts);
2889
+ if (opts.timeout) req.on("timeout", () => {
2890
+ abortHandshake(websocket, req, "Opening handshake has timed out");
2891
+ });
2892
+ req.on("error", (err) => {
2893
+ if (req === null || req[kAborted]) return;
2894
+ req = websocket._req = null;
2895
+ emitErrorAndClose(websocket, err);
2896
+ });
2897
+ req.on("response", (res) => {
2898
+ const location = res.headers.location;
2899
+ const statusCode = res.statusCode;
2900
+ if (location && opts.followRedirects && statusCode >= 300 && statusCode < 400) {
2901
+ if (++websocket._redirects > opts.maxRedirects) {
2902
+ abortHandshake(websocket, req, "Maximum redirects exceeded");
2903
+ return;
2904
+ }
2905
+ req.abort();
2906
+ let addr;
2907
+ try {
2908
+ addr = new URL$1(location, address);
2909
+ } catch (e) {
2910
+ emitErrorAndClose(websocket, /* @__PURE__ */ new SyntaxError(`Invalid URL: ${location}`));
2911
+ return;
2912
+ }
2913
+ initAsClient(websocket, addr, protocols, options);
2914
+ } else if (!websocket.emit("unexpected-response", req, res)) abortHandshake(websocket, req, `Unexpected server response: ${res.statusCode}`);
2915
+ });
2916
+ req.on("upgrade", (res, socket, head) => {
2917
+ websocket.emit("upgrade", res);
2918
+ if (websocket.readyState !== WebSocket.CONNECTING) return;
2919
+ req = websocket._req = null;
2920
+ const upgrade = res.headers.upgrade;
2921
+ if (upgrade === void 0 || upgrade.toLowerCase() !== "websocket") {
2922
+ abortHandshake(websocket, socket, "Invalid Upgrade header");
2923
+ return;
2924
+ }
2925
+ const digest = createHash$1("sha1").update(key + GUID).digest("base64");
2926
+ if (res.headers["sec-websocket-accept"] !== digest) {
2927
+ abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Accept header");
2928
+ return;
2929
+ }
2930
+ const serverProt = res.headers["sec-websocket-protocol"];
2931
+ let protError;
2932
+ if (serverProt !== void 0) {
2933
+ if (!protocolSet.size) protError = "Server sent a subprotocol but none was requested";
2934
+ else if (!protocolSet.has(serverProt)) protError = "Server sent an invalid subprotocol";
2935
+ } else if (protocolSet.size) protError = "Server sent no subprotocol";
2936
+ if (protError) {
2937
+ abortHandshake(websocket, socket, protError);
2938
+ return;
2939
+ }
2940
+ if (serverProt) websocket._protocol = serverProt;
2941
+ const secWebSocketExtensions = res.headers["sec-websocket-extensions"];
2942
+ if (secWebSocketExtensions !== void 0) {
2943
+ if (!perMessageDeflate) {
2944
+ abortHandshake(websocket, socket, "Server sent a Sec-WebSocket-Extensions header but no extension was requested");
2945
+ return;
2946
+ }
2947
+ let extensions;
2948
+ try {
2949
+ extensions = parse(secWebSocketExtensions);
2950
+ } catch (err) {
2951
+ abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Extensions header");
2952
+ return;
2953
+ }
2954
+ const extensionNames = Object.keys(extensions);
2955
+ if (extensionNames.length !== 1 || extensionNames[0] !== PerMessageDeflate.extensionName) {
2956
+ abortHandshake(websocket, socket, "Server indicated an extension that was not requested");
2957
+ return;
2958
+ }
2959
+ try {
2960
+ perMessageDeflate.accept(extensions[PerMessageDeflate.extensionName]);
2961
+ } catch (err) {
2962
+ abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Extensions header");
2963
+ return;
2964
+ }
2965
+ websocket._extensions[PerMessageDeflate.extensionName] = perMessageDeflate;
2966
+ }
2967
+ websocket.setSocket(socket, head, {
2968
+ allowSynchronousEvents: opts.allowSynchronousEvents,
2969
+ generateMask: opts.generateMask,
2970
+ maxPayload: opts.maxPayload,
2971
+ skipUTF8Validation: opts.skipUTF8Validation
2972
+ });
2973
+ });
2974
+ if (opts.finishRequest) opts.finishRequest(req, websocket);
2975
+ else req.end();
2976
+ }
2977
+ /**
2978
+ * Emit the `'error'` and `'close'` events.
2979
+ *
2980
+ * @param {WebSocket} websocket The WebSocket instance
2981
+ * @param {Error} The error to emit
2982
+ * @private
2983
+ */
2984
+ function emitErrorAndClose(websocket, err) {
2985
+ websocket._readyState = WebSocket.CLOSING;
2986
+ websocket._errorEmitted = true;
2987
+ websocket.emit("error", err);
2988
+ websocket.emitClose();
2989
+ }
2990
+ /**
2991
+ * Create a `net.Socket` and initiate a connection.
2992
+ *
2993
+ * @param {Object} options Connection options
2994
+ * @return {net.Socket} The newly created socket used to start the connection
2995
+ * @private
2996
+ */
2997
+ function netConnect(options) {
2998
+ options.path = options.socketPath;
2999
+ return net.connect(options);
3000
+ }
3001
+ /**
3002
+ * Create a `tls.TLSSocket` and initiate a connection.
3003
+ *
3004
+ * @param {Object} options Connection options
3005
+ * @return {tls.TLSSocket} The newly created socket used to start the connection
3006
+ * @private
3007
+ */
3008
+ function tlsConnect(options) {
3009
+ options.path = void 0;
3010
+ if (!options.servername && options.servername !== "") options.servername = net.isIP(options.host) ? "" : options.host;
3011
+ return tls.connect(options);
3012
+ }
3013
+ /**
3014
+ * Abort the handshake and emit an error.
3015
+ *
3016
+ * @param {WebSocket} websocket The WebSocket instance
3017
+ * @param {(http.ClientRequest|net.Socket|tls.Socket)} stream The request to
3018
+ * abort or the socket to destroy
3019
+ * @param {String} message The error message
3020
+ * @private
3021
+ */
3022
+ function abortHandshake(websocket, stream, message) {
3023
+ websocket._readyState = WebSocket.CLOSING;
3024
+ const err = new Error(message);
3025
+ Error.captureStackTrace(err, abortHandshake);
3026
+ if (stream.setHeader) {
3027
+ stream[kAborted] = true;
3028
+ stream.abort();
3029
+ if (stream.socket && !stream.socket.destroyed) stream.socket.destroy();
3030
+ process.nextTick(emitErrorAndClose, websocket, err);
3031
+ } else {
3032
+ stream.destroy(err);
3033
+ stream.once("error", websocket.emit.bind(websocket, "error"));
3034
+ stream.once("close", websocket.emitClose.bind(websocket));
3035
+ }
3036
+ }
3037
+ /**
3038
+ * Handle cases where the `ping()`, `pong()`, or `send()` methods are called
3039
+ * when the `readyState` attribute is `CLOSING` or `CLOSED`.
3040
+ *
3041
+ * @param {WebSocket} websocket The WebSocket instance
3042
+ * @param {*} [data] The data to send
3043
+ * @param {Function} [cb] Callback
3044
+ * @private
3045
+ */
3046
+ function sendAfterClose(websocket, data, cb) {
3047
+ if (data) {
3048
+ const length = isBlob(data) ? data.size : toBuffer(data).length;
3049
+ if (websocket._socket) websocket._sender._bufferedBytes += length;
3050
+ else websocket._bufferedAmount += length;
3051
+ }
3052
+ if (cb) {
3053
+ const err = /* @__PURE__ */ new Error(`WebSocket is not open: readyState ${websocket.readyState} (${readyStates[websocket.readyState]})`);
3054
+ process.nextTick(cb, err);
3055
+ }
3056
+ }
3057
+ /**
3058
+ * The listener of the `Receiver` `'conclude'` event.
3059
+ *
3060
+ * @param {Number} code The status code
3061
+ * @param {Buffer} reason The reason for closing
3062
+ * @private
3063
+ */
3064
+ function receiverOnConclude(code, reason) {
3065
+ const websocket = this[kWebSocket];
3066
+ websocket._closeFrameReceived = true;
3067
+ websocket._closeMessage = reason;
3068
+ websocket._closeCode = code;
3069
+ if (websocket._socket[kWebSocket] === void 0) return;
3070
+ websocket._socket.removeListener("data", socketOnData);
3071
+ process.nextTick(resume, websocket._socket);
3072
+ if (code === 1005) websocket.close();
3073
+ else websocket.close(code, reason);
3074
+ }
3075
+ /**
3076
+ * The listener of the `Receiver` `'drain'` event.
3077
+ *
3078
+ * @private
3079
+ */
3080
+ function receiverOnDrain() {
3081
+ const websocket = this[kWebSocket];
3082
+ if (!websocket.isPaused) websocket._socket.resume();
3083
+ }
3084
+ /**
3085
+ * The listener of the `Receiver` `'error'` event.
3086
+ *
3087
+ * @param {(RangeError|Error)} err The emitted error
3088
+ * @private
3089
+ */
3090
+ function receiverOnError(err) {
3091
+ const websocket = this[kWebSocket];
3092
+ if (websocket._socket[kWebSocket] !== void 0) {
3093
+ websocket._socket.removeListener("data", socketOnData);
3094
+ process.nextTick(resume, websocket._socket);
3095
+ websocket.close(err[kStatusCode]);
3096
+ }
3097
+ if (!websocket._errorEmitted) {
3098
+ websocket._errorEmitted = true;
3099
+ websocket.emit("error", err);
3100
+ }
3101
+ }
3102
+ /**
3103
+ * The listener of the `Receiver` `'finish'` event.
3104
+ *
3105
+ * @private
3106
+ */
3107
+ function receiverOnFinish() {
3108
+ this[kWebSocket].emitClose();
3109
+ }
3110
+ /**
3111
+ * The listener of the `Receiver` `'message'` event.
3112
+ *
3113
+ * @param {Buffer|ArrayBuffer|Buffer[])} data The message
3114
+ * @param {Boolean} isBinary Specifies whether the message is binary or not
3115
+ * @private
3116
+ */
3117
+ function receiverOnMessage(data, isBinary) {
3118
+ this[kWebSocket].emit("message", data, isBinary);
3119
+ }
3120
+ /**
3121
+ * The listener of the `Receiver` `'ping'` event.
3122
+ *
3123
+ * @param {Buffer} data The data included in the ping frame
3124
+ * @private
3125
+ */
3126
+ function receiverOnPing(data) {
3127
+ const websocket = this[kWebSocket];
3128
+ if (websocket._autoPong) websocket.pong(data, !this._isServer, NOOP);
3129
+ websocket.emit("ping", data);
3130
+ }
3131
+ /**
3132
+ * The listener of the `Receiver` `'pong'` event.
3133
+ *
3134
+ * @param {Buffer} data The data included in the pong frame
3135
+ * @private
3136
+ */
3137
+ function receiverOnPong(data) {
3138
+ this[kWebSocket].emit("pong", data);
3139
+ }
3140
+ /**
3141
+ * Resume a readable stream
3142
+ *
3143
+ * @param {Readable} stream The readable stream
3144
+ * @private
3145
+ */
3146
+ function resume(stream) {
3147
+ stream.resume();
3148
+ }
3149
+ /**
3150
+ * The `Sender` error event handler.
3151
+ *
3152
+ * @param {Error} The error
3153
+ * @private
3154
+ */
3155
+ function senderOnError(err) {
3156
+ const websocket = this[kWebSocket];
3157
+ if (websocket.readyState === WebSocket.CLOSED) return;
3158
+ if (websocket.readyState === WebSocket.OPEN) {
3159
+ websocket._readyState = WebSocket.CLOSING;
3160
+ setCloseTimer(websocket);
3161
+ }
3162
+ this._socket.end();
3163
+ if (!websocket._errorEmitted) {
3164
+ websocket._errorEmitted = true;
3165
+ websocket.emit("error", err);
3166
+ }
3167
+ }
3168
+ /**
3169
+ * Set a timer to destroy the underlying raw socket of a WebSocket.
3170
+ *
3171
+ * @param {WebSocket} websocket The WebSocket instance
3172
+ * @private
3173
+ */
3174
+ function setCloseTimer(websocket) {
3175
+ websocket._closeTimer = setTimeout(websocket._socket.destroy.bind(websocket._socket), websocket._closeTimeout);
3176
+ }
3177
+ /**
3178
+ * The listener of the socket `'close'` event.
3179
+ *
3180
+ * @private
3181
+ */
3182
+ function socketOnClose() {
3183
+ const websocket = this[kWebSocket];
3184
+ this.removeListener("close", socketOnClose);
3185
+ this.removeListener("data", socketOnData);
3186
+ this.removeListener("end", socketOnEnd);
3187
+ websocket._readyState = WebSocket.CLOSING;
3188
+ if (!this._readableState.endEmitted && !websocket._closeFrameReceived && !websocket._receiver._writableState.errorEmitted && this._readableState.length !== 0) {
3189
+ const chunk = this.read(this._readableState.length);
3190
+ websocket._receiver.write(chunk);
3191
+ }
3192
+ websocket._receiver.end();
3193
+ this[kWebSocket] = void 0;
3194
+ clearTimeout(websocket._closeTimer);
3195
+ if (websocket._receiver._writableState.finished || websocket._receiver._writableState.errorEmitted) websocket.emitClose();
3196
+ else {
3197
+ websocket._receiver.on("error", receiverOnFinish);
3198
+ websocket._receiver.on("finish", receiverOnFinish);
3199
+ }
3200
+ }
3201
+ /**
3202
+ * The listener of the socket `'data'` event.
3203
+ *
3204
+ * @param {Buffer} chunk A chunk of data
3205
+ * @private
3206
+ */
3207
+ function socketOnData(chunk) {
3208
+ if (!this[kWebSocket]._receiver.write(chunk)) this.pause();
3209
+ }
3210
+ /**
3211
+ * The listener of the socket `'end'` event.
3212
+ *
3213
+ * @private
3214
+ */
3215
+ function socketOnEnd() {
3216
+ const websocket = this[kWebSocket];
3217
+ websocket._readyState = WebSocket.CLOSING;
3218
+ websocket._receiver.end();
3219
+ this.end();
3220
+ }
3221
+ /**
3222
+ * The listener of the socket `'error'` event.
3223
+ *
3224
+ * @private
3225
+ */
3226
+ function socketOnError() {
3227
+ const websocket = this[kWebSocket];
3228
+ this.removeListener("error", socketOnError);
3229
+ this.on("error", NOOP);
3230
+ if (websocket) {
3231
+ websocket._readyState = WebSocket.CLOSING;
3232
+ this.destroy();
3233
+ }
3234
+ }
3235
+ }));
3236
+ //#endregion
3237
+ //#region node_modules/.pnpm/ws@8.20.0/node_modules/ws/lib/stream.js
3238
+ var require_stream = /* @__PURE__ */ __commonJSMin(((exports, module) => {
3239
+ require_websocket();
3240
+ const { Duplex: Duplex$1 } = __require("stream");
3241
+ /**
3242
+ * Emits the `'close'` event on a stream.
3243
+ *
3244
+ * @param {Duplex} stream The stream.
3245
+ * @private
3246
+ */
3247
+ function emitClose(stream) {
3248
+ stream.emit("close");
3249
+ }
3250
+ /**
3251
+ * The listener of the `'end'` event.
3252
+ *
3253
+ * @private
3254
+ */
3255
+ function duplexOnEnd() {
3256
+ if (!this.destroyed && this._writableState.finished) this.destroy();
3257
+ }
3258
+ /**
3259
+ * The listener of the `'error'` event.
3260
+ *
3261
+ * @param {Error} err The error
3262
+ * @private
3263
+ */
3264
+ function duplexOnError(err) {
3265
+ this.removeListener("error", duplexOnError);
3266
+ this.destroy();
3267
+ if (this.listenerCount("error") === 0) this.emit("error", err);
3268
+ }
3269
+ /**
3270
+ * Wraps a `WebSocket` in a duplex stream.
3271
+ *
3272
+ * @param {WebSocket} ws The `WebSocket` to wrap
3273
+ * @param {Object} [options] The options for the `Duplex` constructor
3274
+ * @return {Duplex} The duplex stream
3275
+ * @public
3276
+ */
3277
+ function createWebSocketStream(ws, options) {
3278
+ let terminateOnDestroy = true;
3279
+ const duplex = new Duplex$1({
3280
+ ...options,
3281
+ autoDestroy: false,
3282
+ emitClose: false,
3283
+ objectMode: false,
3284
+ writableObjectMode: false
3285
+ });
3286
+ ws.on("message", function message(msg, isBinary) {
3287
+ const data = !isBinary && duplex._readableState.objectMode ? msg.toString() : msg;
3288
+ if (!duplex.push(data)) ws.pause();
3289
+ });
3290
+ ws.once("error", function error(err) {
3291
+ if (duplex.destroyed) return;
3292
+ terminateOnDestroy = false;
3293
+ duplex.destroy(err);
3294
+ });
3295
+ ws.once("close", function close() {
3296
+ if (duplex.destroyed) return;
3297
+ duplex.push(null);
3298
+ });
3299
+ duplex._destroy = function(err, callback) {
3300
+ if (ws.readyState === ws.CLOSED) {
3301
+ callback(err);
3302
+ process.nextTick(emitClose, duplex);
3303
+ return;
3304
+ }
3305
+ let called = false;
3306
+ ws.once("error", function error(err) {
3307
+ called = true;
3308
+ callback(err);
3309
+ });
3310
+ ws.once("close", function close() {
3311
+ if (!called) callback(err);
3312
+ process.nextTick(emitClose, duplex);
3313
+ });
3314
+ if (terminateOnDestroy) ws.terminate();
3315
+ };
3316
+ duplex._final = function(callback) {
3317
+ if (ws.readyState === ws.CONNECTING) {
3318
+ ws.once("open", function open() {
3319
+ duplex._final(callback);
3320
+ });
3321
+ return;
3322
+ }
3323
+ if (ws._socket === null) return;
3324
+ if (ws._socket._writableState.finished) {
3325
+ callback();
3326
+ if (duplex._readableState.endEmitted) duplex.destroy();
3327
+ } else {
3328
+ ws._socket.once("finish", function finish() {
3329
+ callback();
3330
+ });
3331
+ ws.close();
3332
+ }
3333
+ };
3334
+ duplex._read = function() {
3335
+ if (ws.isPaused) ws.resume();
3336
+ };
3337
+ duplex._write = function(chunk, encoding, callback) {
3338
+ if (ws.readyState === ws.CONNECTING) {
3339
+ ws.once("open", function open() {
3340
+ duplex._write(chunk, encoding, callback);
3341
+ });
3342
+ return;
3343
+ }
3344
+ ws.send(chunk, callback);
3345
+ };
3346
+ duplex.on("end", duplexOnEnd);
3347
+ duplex.on("error", duplexOnError);
3348
+ return duplex;
3349
+ }
3350
+ module.exports = createWebSocketStream;
3351
+ }));
3352
+ //#endregion
3353
+ //#region node_modules/.pnpm/ws@8.20.0/node_modules/ws/lib/subprotocol.js
3354
+ var require_subprotocol = /* @__PURE__ */ __commonJSMin(((exports, module) => {
3355
+ const { tokenChars } = require_validation();
3356
+ /**
3357
+ * Parses the `Sec-WebSocket-Protocol` header into a set of subprotocol names.
3358
+ *
3359
+ * @param {String} header The field value of the header
3360
+ * @return {Set} The subprotocol names
3361
+ * @public
3362
+ */
3363
+ function parse(header) {
3364
+ const protocols = /* @__PURE__ */ new Set();
3365
+ let start = -1;
3366
+ let end = -1;
3367
+ let i = 0;
3368
+ for (; i < header.length; i++) {
3369
+ const code = header.charCodeAt(i);
3370
+ if (end === -1 && tokenChars[code] === 1) {
3371
+ if (start === -1) start = i;
3372
+ } else if (i !== 0 && (code === 32 || code === 9)) {
3373
+ if (end === -1 && start !== -1) end = i;
3374
+ } else if (code === 44) {
3375
+ if (start === -1) throw new SyntaxError(`Unexpected character at index ${i}`);
3376
+ if (end === -1) end = i;
3377
+ const protocol = header.slice(start, end);
3378
+ if (protocols.has(protocol)) throw new SyntaxError(`The "${protocol}" subprotocol is duplicated`);
3379
+ protocols.add(protocol);
3380
+ start = end = -1;
3381
+ } else throw new SyntaxError(`Unexpected character at index ${i}`);
3382
+ }
3383
+ if (start === -1 || end !== -1) throw new SyntaxError("Unexpected end of input");
3384
+ const protocol = header.slice(start, i);
3385
+ if (protocols.has(protocol)) throw new SyntaxError(`The "${protocol}" subprotocol is duplicated`);
3386
+ protocols.add(protocol);
3387
+ return protocols;
3388
+ }
3389
+ module.exports = { parse };
3390
+ }));
3391
+ //#endregion
3392
+ //#region node_modules/.pnpm/ws@8.20.0/node_modules/ws/lib/websocket-server.js
3393
+ var require_websocket_server = /* @__PURE__ */ __commonJSMin(((exports, module) => {
3394
+ const EventEmitter$1 = __require("events");
3395
+ const http = __require("http");
3396
+ const { Duplex } = __require("stream");
3397
+ const { createHash } = __require("crypto");
3398
+ const extension = require_extension();
3399
+ const PerMessageDeflate = require_permessage_deflate();
3400
+ const subprotocol = require_subprotocol();
3401
+ const WebSocket = require_websocket();
3402
+ const { CLOSE_TIMEOUT, GUID, kWebSocket } = require_constants();
3403
+ const keyRegex = /^[+/0-9A-Za-z]{22}==$/;
3404
+ const RUNNING = 0;
3405
+ const CLOSING = 1;
3406
+ const CLOSED = 2;
3407
+ /**
3408
+ * Class representing a WebSocket server.
3409
+ *
3410
+ * @extends EventEmitter
3411
+ */
3412
+ var WebSocketServer = class extends EventEmitter$1 {
3413
+ /**
3414
+ * Create a `WebSocketServer` instance.
3415
+ *
3416
+ * @param {Object} options Configuration options
3417
+ * @param {Boolean} [options.allowSynchronousEvents=true] Specifies whether
3418
+ * any of the `'message'`, `'ping'`, and `'pong'` events can be emitted
3419
+ * multiple times in the same tick
3420
+ * @param {Boolean} [options.autoPong=true] Specifies whether or not to
3421
+ * automatically send a pong in response to a ping
3422
+ * @param {Number} [options.backlog=511] The maximum length of the queue of
3423
+ * pending connections
3424
+ * @param {Boolean} [options.clientTracking=true] Specifies whether or not to
3425
+ * track clients
3426
+ * @param {Number} [options.closeTimeout=30000] Duration in milliseconds to
3427
+ * wait for the closing handshake to finish after `websocket.close()` is
3428
+ * called
3429
+ * @param {Function} [options.handleProtocols] A hook to handle protocols
3430
+ * @param {String} [options.host] The hostname where to bind the server
3431
+ * @param {Number} [options.maxPayload=104857600] The maximum allowed message
3432
+ * size
3433
+ * @param {Boolean} [options.noServer=false] Enable no server mode
3434
+ * @param {String} [options.path] Accept only connections matching this path
3435
+ * @param {(Boolean|Object)} [options.perMessageDeflate=false] Enable/disable
3436
+ * permessage-deflate
3437
+ * @param {Number} [options.port] The port where to bind the server
3438
+ * @param {(http.Server|https.Server)} [options.server] A pre-created HTTP/S
3439
+ * server to use
3440
+ * @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or
3441
+ * not to skip UTF-8 validation for text and close messages
3442
+ * @param {Function} [options.verifyClient] A hook to reject connections
3443
+ * @param {Function} [options.WebSocket=WebSocket] Specifies the `WebSocket`
3444
+ * class to use. It must be the `WebSocket` class or class that extends it
3445
+ * @param {Function} [callback] A listener for the `listening` event
3446
+ */
3447
+ constructor(options, callback) {
3448
+ super();
3449
+ options = {
3450
+ allowSynchronousEvents: true,
3451
+ autoPong: true,
3452
+ maxPayload: 100 * 1024 * 1024,
3453
+ skipUTF8Validation: false,
3454
+ perMessageDeflate: false,
3455
+ handleProtocols: null,
3456
+ clientTracking: true,
3457
+ closeTimeout: CLOSE_TIMEOUT,
3458
+ verifyClient: null,
3459
+ noServer: false,
3460
+ backlog: null,
3461
+ server: null,
3462
+ host: null,
3463
+ path: null,
3464
+ port: null,
3465
+ WebSocket,
3466
+ ...options
3467
+ };
3468
+ 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");
3469
+ if (options.port != null) {
3470
+ this._server = http.createServer((req, res) => {
3471
+ const body = http.STATUS_CODES[426];
3472
+ res.writeHead(426, {
3473
+ "Content-Length": body.length,
3474
+ "Content-Type": "text/plain"
3475
+ });
3476
+ res.end(body);
3477
+ });
3478
+ this._server.listen(options.port, options.host, options.backlog, callback);
3479
+ } else if (options.server) this._server = options.server;
3480
+ if (this._server) {
3481
+ const emitConnection = this.emit.bind(this, "connection");
3482
+ this._removeListeners = addListeners(this._server, {
3483
+ listening: this.emit.bind(this, "listening"),
3484
+ error: this.emit.bind(this, "error"),
3485
+ upgrade: (req, socket, head) => {
3486
+ this.handleUpgrade(req, socket, head, emitConnection);
3487
+ }
3488
+ });
3489
+ }
3490
+ if (options.perMessageDeflate === true) options.perMessageDeflate = {};
3491
+ if (options.clientTracking) {
3492
+ this.clients = /* @__PURE__ */ new Set();
3493
+ this._shouldEmitClose = false;
3494
+ }
3495
+ this.options = options;
3496
+ this._state = RUNNING;
3497
+ }
3498
+ /**
3499
+ * Returns the bound address, the address family name, and port of the server
3500
+ * as reported by the operating system if listening on an IP socket.
3501
+ * If the server is listening on a pipe or UNIX domain socket, the name is
3502
+ * returned as a string.
3503
+ *
3504
+ * @return {(Object|String|null)} The address of the server
3505
+ * @public
3506
+ */
3507
+ address() {
3508
+ if (this.options.noServer) throw new Error("The server is operating in \"noServer\" mode");
3509
+ if (!this._server) return null;
3510
+ return this._server.address();
3511
+ }
3512
+ /**
3513
+ * Stop the server from accepting new connections and emit the `'close'` event
3514
+ * when all existing connections are closed.
3515
+ *
3516
+ * @param {Function} [cb] A one-time listener for the `'close'` event
3517
+ * @public
3518
+ */
3519
+ close(cb) {
3520
+ if (this._state === CLOSED) {
3521
+ if (cb) this.once("close", () => {
3522
+ cb(/* @__PURE__ */ new Error("The server is not running"));
3523
+ });
3524
+ process.nextTick(emitClose, this);
3525
+ return;
3526
+ }
3527
+ if (cb) this.once("close", cb);
3528
+ if (this._state === CLOSING) return;
3529
+ this._state = CLOSING;
3530
+ if (this.options.noServer || this.options.server) {
3531
+ if (this._server) {
3532
+ this._removeListeners();
3533
+ this._removeListeners = this._server = null;
3534
+ }
3535
+ if (this.clients) if (!this.clients.size) process.nextTick(emitClose, this);
3536
+ else this._shouldEmitClose = true;
3537
+ else process.nextTick(emitClose, this);
3538
+ } else {
3539
+ const server = this._server;
3540
+ this._removeListeners();
3541
+ this._removeListeners = this._server = null;
3542
+ server.close(() => {
3543
+ emitClose(this);
3544
+ });
3545
+ }
3546
+ }
3547
+ /**
3548
+ * See if a given request should be handled by this server instance.
3549
+ *
3550
+ * @param {http.IncomingMessage} req Request object to inspect
3551
+ * @return {Boolean} `true` if the request is valid, else `false`
3552
+ * @public
3553
+ */
3554
+ shouldHandle(req) {
3555
+ if (this.options.path) {
3556
+ const index = req.url.indexOf("?");
3557
+ if ((index !== -1 ? req.url.slice(0, index) : req.url) !== this.options.path) return false;
3558
+ }
3559
+ return true;
3560
+ }
3561
+ /**
3562
+ * Handle a HTTP Upgrade request.
3563
+ *
3564
+ * @param {http.IncomingMessage} req The request object
3565
+ * @param {Duplex} socket The network socket between the server and client
3566
+ * @param {Buffer} head The first packet of the upgraded stream
3567
+ * @param {Function} cb Callback
3568
+ * @public
3569
+ */
3570
+ handleUpgrade(req, socket, head, cb) {
3571
+ socket.on("error", socketOnError);
3572
+ const key = req.headers["sec-websocket-key"];
3573
+ const upgrade = req.headers.upgrade;
3574
+ const version = +req.headers["sec-websocket-version"];
3575
+ if (req.method !== "GET") {
3576
+ abortHandshakeOrEmitwsClientError(this, req, socket, 405, "Invalid HTTP method");
3577
+ return;
3578
+ }
3579
+ if (upgrade === void 0 || upgrade.toLowerCase() !== "websocket") {
3580
+ abortHandshakeOrEmitwsClientError(this, req, socket, 400, "Invalid Upgrade header");
3581
+ return;
3582
+ }
3583
+ if (key === void 0 || !keyRegex.test(key)) {
3584
+ abortHandshakeOrEmitwsClientError(this, req, socket, 400, "Missing or invalid Sec-WebSocket-Key header");
3585
+ return;
3586
+ }
3587
+ if (version !== 13 && version !== 8) {
3588
+ abortHandshakeOrEmitwsClientError(this, req, socket, 400, "Missing or invalid Sec-WebSocket-Version header", { "Sec-WebSocket-Version": "13, 8" });
3589
+ return;
3590
+ }
3591
+ if (!this.shouldHandle(req)) {
3592
+ abortHandshake(socket, 400);
3593
+ return;
3594
+ }
3595
+ const secWebSocketProtocol = req.headers["sec-websocket-protocol"];
3596
+ let protocols = /* @__PURE__ */ new Set();
3597
+ if (secWebSocketProtocol !== void 0) try {
3598
+ protocols = subprotocol.parse(secWebSocketProtocol);
3599
+ } catch (err) {
3600
+ abortHandshakeOrEmitwsClientError(this, req, socket, 400, "Invalid Sec-WebSocket-Protocol header");
3601
+ return;
3602
+ }
3603
+ const secWebSocketExtensions = req.headers["sec-websocket-extensions"];
3604
+ const extensions = {};
3605
+ if (this.options.perMessageDeflate && secWebSocketExtensions !== void 0) {
3606
+ const perMessageDeflate = new PerMessageDeflate({
3607
+ ...this.options.perMessageDeflate,
3608
+ isServer: true,
3609
+ maxPayload: this.options.maxPayload
3610
+ });
3611
+ try {
3612
+ const offers = extension.parse(secWebSocketExtensions);
3613
+ if (offers[PerMessageDeflate.extensionName]) {
3614
+ perMessageDeflate.accept(offers[PerMessageDeflate.extensionName]);
3615
+ extensions[PerMessageDeflate.extensionName] = perMessageDeflate;
3616
+ }
3617
+ } catch (err) {
3618
+ abortHandshakeOrEmitwsClientError(this, req, socket, 400, "Invalid or unacceptable Sec-WebSocket-Extensions header");
3619
+ return;
3620
+ }
3621
+ }
3622
+ if (this.options.verifyClient) {
3623
+ const info = {
3624
+ origin: req.headers[`${version === 8 ? "sec-websocket-origin" : "origin"}`],
3625
+ secure: !!(req.socket.authorized || req.socket.encrypted),
3626
+ req
3627
+ };
3628
+ if (this.options.verifyClient.length === 2) {
3629
+ this.options.verifyClient(info, (verified, code, message, headers) => {
3630
+ if (!verified) return abortHandshake(socket, code || 401, message, headers);
3631
+ this.completeUpgrade(extensions, key, protocols, req, socket, head, cb);
3632
+ });
3633
+ return;
3634
+ }
3635
+ if (!this.options.verifyClient(info)) return abortHandshake(socket, 401);
3636
+ }
3637
+ this.completeUpgrade(extensions, key, protocols, req, socket, head, cb);
3638
+ }
3639
+ /**
3640
+ * Upgrade the connection to WebSocket.
3641
+ *
3642
+ * @param {Object} extensions The accepted extensions
3643
+ * @param {String} key The value of the `Sec-WebSocket-Key` header
3644
+ * @param {Set} protocols The subprotocols
3645
+ * @param {http.IncomingMessage} req The request object
3646
+ * @param {Duplex} socket The network socket between the server and client
3647
+ * @param {Buffer} head The first packet of the upgraded stream
3648
+ * @param {Function} cb Callback
3649
+ * @throws {Error} If called more than once with the same socket
3650
+ * @private
3651
+ */
3652
+ completeUpgrade(extensions, key, protocols, req, socket, head, cb) {
3653
+ if (!socket.readable || !socket.writable) return socket.destroy();
3654
+ if (socket[kWebSocket]) throw new Error("server.handleUpgrade() was called more than once with the same socket, possibly due to a misconfiguration");
3655
+ if (this._state > RUNNING) return abortHandshake(socket, 503);
3656
+ const headers = [
3657
+ "HTTP/1.1 101 Switching Protocols",
3658
+ "Upgrade: websocket",
3659
+ "Connection: Upgrade",
3660
+ `Sec-WebSocket-Accept: ${createHash("sha1").update(key + GUID).digest("base64")}`
3661
+ ];
3662
+ const ws = new this.options.WebSocket(null, void 0, this.options);
3663
+ if (protocols.size) {
3664
+ const protocol = this.options.handleProtocols ? this.options.handleProtocols(protocols, req) : protocols.values().next().value;
3665
+ if (protocol) {
3666
+ headers.push(`Sec-WebSocket-Protocol: ${protocol}`);
3667
+ ws._protocol = protocol;
3668
+ }
3669
+ }
3670
+ if (extensions[PerMessageDeflate.extensionName]) {
3671
+ const params = extensions[PerMessageDeflate.extensionName].params;
3672
+ const value = extension.format({ [PerMessageDeflate.extensionName]: [params] });
3673
+ headers.push(`Sec-WebSocket-Extensions: ${value}`);
3674
+ ws._extensions = extensions;
3675
+ }
3676
+ this.emit("headers", headers, req);
3677
+ socket.write(headers.concat("\r\n").join("\r\n"));
3678
+ socket.removeListener("error", socketOnError);
3679
+ ws.setSocket(socket, head, {
3680
+ allowSynchronousEvents: this.options.allowSynchronousEvents,
3681
+ maxPayload: this.options.maxPayload,
3682
+ skipUTF8Validation: this.options.skipUTF8Validation
3683
+ });
3684
+ if (this.clients) {
3685
+ this.clients.add(ws);
3686
+ ws.on("close", () => {
3687
+ this.clients.delete(ws);
3688
+ if (this._shouldEmitClose && !this.clients.size) process.nextTick(emitClose, this);
3689
+ });
3690
+ }
3691
+ cb(ws, req);
3692
+ }
3693
+ };
3694
+ module.exports = WebSocketServer;
3695
+ /**
3696
+ * Add event listeners on an `EventEmitter` using a map of <event, listener>
3697
+ * pairs.
3698
+ *
3699
+ * @param {EventEmitter} server The event emitter
3700
+ * @param {Object.<String, Function>} map The listeners to add
3701
+ * @return {Function} A function that will remove the added listeners when
3702
+ * called
3703
+ * @private
3704
+ */
3705
+ function addListeners(server, map) {
3706
+ for (const event of Object.keys(map)) server.on(event, map[event]);
3707
+ return function removeListeners() {
3708
+ for (const event of Object.keys(map)) server.removeListener(event, map[event]);
3709
+ };
3710
+ }
3711
+ /**
3712
+ * Emit a `'close'` event on an `EventEmitter`.
3713
+ *
3714
+ * @param {EventEmitter} server The event emitter
3715
+ * @private
3716
+ */
3717
+ function emitClose(server) {
3718
+ server._state = CLOSED;
3719
+ server.emit("close");
3720
+ }
3721
+ /**
3722
+ * Handle socket errors.
3723
+ *
3724
+ * @private
3725
+ */
3726
+ function socketOnError() {
3727
+ this.destroy();
3728
+ }
3729
+ /**
3730
+ * Close the connection when preconditions are not fulfilled.
3731
+ *
3732
+ * @param {Duplex} socket The socket of the upgrade request
3733
+ * @param {Number} code The HTTP response status code
3734
+ * @param {String} [message] The HTTP response body
3735
+ * @param {Object} [headers] Additional HTTP response headers
3736
+ * @private
3737
+ */
3738
+ function abortHandshake(socket, code, message, headers) {
3739
+ message = message || http.STATUS_CODES[code];
3740
+ headers = {
3741
+ Connection: "close",
3742
+ "Content-Type": "text/html",
3743
+ "Content-Length": Buffer.byteLength(message),
3744
+ ...headers
3745
+ };
3746
+ socket.once("finish", socket.destroy);
3747
+ 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);
3748
+ }
3749
+ /**
3750
+ * Emit a `'wsClientError'` event on a `WebSocketServer` if there is at least
3751
+ * one listener for it, otherwise call `abortHandshake()`.
3752
+ *
3753
+ * @param {WebSocketServer} server The WebSocket server
3754
+ * @param {http.IncomingMessage} req The request object
3755
+ * @param {Duplex} socket The socket of the upgrade request
3756
+ * @param {Number} code The HTTP response status code
3757
+ * @param {String} message The HTTP response body
3758
+ * @param {Object} [headers] The HTTP response headers
3759
+ * @private
3760
+ */
3761
+ function abortHandshakeOrEmitwsClientError(server, req, socket, code, message, headers) {
3762
+ if (server.listenerCount("wsClientError")) {
3763
+ const err = new Error(message);
3764
+ Error.captureStackTrace(err, abortHandshakeOrEmitwsClientError);
3765
+ server.emit("wsClientError", err, socket, req);
3766
+ } else abortHandshake(socket, code, message, headers);
3767
+ }
3768
+ }));
3769
+ require_stream();
3770
+ require_extension();
3771
+ require_permessage_deflate();
3772
+ require_receiver();
3773
+ require_sender();
3774
+ require_subprotocol();
3775
+ var import_websocket = /* @__PURE__ */ __toESM(require_websocket(), 1);
3776
+ require_websocket_server();
3777
+ var wrapper_default = import_websocket.default;
3778
+ //#endregion
3779
+ //#region websocket.ts
3780
+ /**
3781
+ * WebSocket 连接管理器
3782
+ */
3783
+ var WebSocketManager = class {
3784
+ constructor(options, emitter) {
3785
+ this.ws = null;
3786
+ this.currentState = "disconnected";
3787
+ this.reconnectAttempts = 0;
3788
+ this.reconnectTimer = null;
3789
+ this.heartbeatTimer = null;
3790
+ this.messageQueue = [];
3791
+ this.token = null;
3792
+ this.intentionalClose = false;
3793
+ this.options = {
3794
+ baseURL: options.baseURL,
3795
+ gatewayURL: options.gatewayURL,
3796
+ reconnectInterval: options.reconnectInterval ?? 3e3,
3797
+ maxReconnectAttempts: options.maxReconnectAttempts ?? 10,
3798
+ heartbeatInterval: options.heartbeatInterval ?? 3e4,
3799
+ messageBufferSize: options.messageBufferSize ?? 100
3800
+ };
3801
+ this.emitter = emitter;
3802
+ }
3803
+ /**
3804
+ * 设置认证 Token
3805
+ */
3806
+ setToken(token) {
3807
+ this.token = token;
3808
+ }
3809
+ /**
3810
+ * 清除认证 Token
3811
+ */
3812
+ clearToken() {
3813
+ this.token = null;
3814
+ }
3815
+ /**
3816
+ * 获取当前连接状态
3817
+ */
3818
+ getState() {
3819
+ return this.currentState;
3820
+ }
3821
+ /**
3822
+ * 是否已连接
3823
+ */
3824
+ isConnected() {
3825
+ return this.currentState === "connected" && this.ws?.readyState === wrapper_default.OPEN;
3826
+ }
3827
+ /**
3828
+ * 更新连接状态并触发事件
3829
+ */
3830
+ setState(newState) {
3831
+ const previousState = this.currentState;
3832
+ this.currentState = newState;
3833
+ this.emitter.emit("connection:state:change", createStateChange(newState, previousState));
3834
+ }
3835
+ /**
3836
+ * 连接到 WebSocket 网关
3837
+ */
3838
+ async connect() {
3839
+ if (this.isConnected()) return;
3840
+ if (!this.token) throw new Error("Token is required before connecting to WebSocket");
3841
+ this.intentionalClose = false;
3842
+ this.setState("connecting");
3843
+ try {
3844
+ const wsUrl = new URL(this.options.gatewayURL);
3845
+ this.ws = new wrapper_default(wsUrl.toString(), { headers: { Authorization: `Bearer ${this.token}` } });
3846
+ await this.setupWebSocketHandlers();
3847
+ } catch (error) {
3848
+ this.setState("error");
3849
+ this.emitter.emit("error", createError("WS_CONNECT_FAILED", "Failed to connect to WebSocket", error instanceof Error ? error : void 0));
3850
+ this.scheduleReconnect();
3851
+ throw error;
3852
+ }
3853
+ }
3854
+ /**
3855
+ * 断开 WebSocket 连接
3856
+ */
3857
+ disconnect() {
3858
+ this.intentionalClose = true;
3859
+ this.clearTimers();
3860
+ if (this.ws) {
3861
+ if (this.ws.readyState === wrapper_default.OPEN || this.ws.readyState === wrapper_default.CONNECTING) this.ws.close(1e3, "Client disconnect");
3862
+ this.ws = null;
3863
+ }
3864
+ this.reconnectAttempts = 0;
3865
+ this.setState("disconnected");
3866
+ this.emitter.emit("disconnect", {
3867
+ code: 1e3,
3868
+ reason: "Client disconnect"
3869
+ });
330
3870
  }
331
3871
  /**
332
3872
  * 发送消息
@@ -346,8 +3886,7 @@ var WebSocketManager = class {
346
3886
  buildMessage(req) {
347
3887
  return {
348
3888
  client_msg_id: req.client_msg_id,
349
- receiver_id: req.receiver_id,
350
- chat_type: req.chat_type,
3889
+ room_id: req.room_id,
351
3890
  msg_type: req.msg_type,
352
3891
  payload: req.payload,
353
3892
  ...req.reply_to_msg_id && { reply_to_msg_id: req.reply_to_msg_id },
@@ -366,13 +3905,14 @@ var WebSocketManager = class {
366
3905
  this.ws.onopen = () => {
367
3906
  this.reconnectAttempts = 0;
368
3907
  this.setState("connected");
369
- this.emitter.emit("connect", void 0);
3908
+ this.emitter.emit("connect", { timestamp: Date.now() });
370
3909
  this.startHeartbeat();
371
3910
  this.flushMessageQueue();
372
3911
  resolve();
373
3912
  };
374
3913
  this.ws.onmessage = (event) => {
375
- this.handleMessage(event.data);
3914
+ const data = typeof event.data === "string" ? event.data : event.data.toString();
3915
+ this.handleMessage(data);
376
3916
  };
377
3917
  this.ws.onclose = (event) => {
378
3918
  this.clearTimers();
@@ -388,8 +3928,9 @@ var WebSocketManager = class {
388
3928
  }
389
3929
  };
390
3930
  this.ws.onerror = (error) => {
391
- this.emitter.emit("error", createError("WS_ERROR", "WebSocket error occurred", error instanceof Error ? error : void 0));
392
- reject(error);
3931
+ const err = error;
3932
+ this.emitter.emit("error", createError("WS_ERROR", err.message || "WebSocket error occurred", err));
3933
+ reject(err);
393
3934
  };
394
3935
  });
395
3936
  }
@@ -479,8 +4020,7 @@ var WebSocketManager = class {
479
4020
  *
480
4021
  * // 发送文本消息
481
4022
  * sdk.sendTextMessage({
482
- * receiver_id: 'xxx',
483
- * chat_type: ChatType.Single,
4023
+ * room_id: 'xxx',
484
4024
  * text: 'Hello!',
485
4025
  * });
486
4026
  * ```