@alfe.ai/openclaw 0.0.17 → 0.0.19

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