ventiws 1.0.0-rc.2 → 1.0.0-rc.4
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/README.md +1 -1
- package/dist/index.cjs +98 -113
- package/dist/index.mjs +98 -113
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@ observable behaviour rather than its source. ventiws is not affiliated with the
|
|
|
12
12
|
as the pinned contract, credited in
|
|
13
13
|
[THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md).
|
|
14
14
|
|
|
15
|
-
**ventiws is at `1.0.0-rc.
|
|
15
|
+
**ventiws is at `1.0.0-rc.4`.** The surface may change between beta
|
|
16
16
|
releases. What "beta" means here is bounded: the `ws` compatibility
|
|
17
17
|
contract is tracked row by row in
|
|
18
18
|
[COMPATIBILITY.md](COMPATIBILITY.md), and the four places ventiws knowingly
|
package/dist/index.cjs
CHANGED
|
@@ -459,6 +459,97 @@ function createEmitter(state) {
|
|
|
459
459
|
}
|
|
460
460
|
};
|
|
461
461
|
}
|
|
462
|
+
function normalizeParameters(parameters, isServer) {
|
|
463
|
+
const out = {};
|
|
464
|
+
for (const [key, values] of Object.entries(parameters)) {
|
|
465
|
+
if (values.length > 1) return null;
|
|
466
|
+
const parsed = parseParameter(key, values[0] ?? "", isServer);
|
|
467
|
+
if (parsed === null) return null;
|
|
468
|
+
out[key] = parsed;
|
|
469
|
+
}
|
|
470
|
+
return {
|
|
471
|
+
server_no_context_takeover: out.server_no_context_takeover === true,
|
|
472
|
+
client_no_context_takeover: out.client_no_context_takeover === true,
|
|
473
|
+
server_max_window_bits: numberOf(out.server_max_window_bits),
|
|
474
|
+
client_max_window_bits: windowOf(out.client_max_window_bits)
|
|
475
|
+
};
|
|
476
|
+
}
|
|
477
|
+
function parseParameter(key, value, isServer) {
|
|
478
|
+
if (key === "server_no_context_takeover" || key === "client_no_context_takeover") return value === "" ? true : null;
|
|
479
|
+
if (key === "client_max_window_bits") {
|
|
480
|
+
if (value === "") return isServer ? true : null;
|
|
481
|
+
return windowSize(value);
|
|
482
|
+
}
|
|
483
|
+
if (key === "server_max_window_bits") return value === "" ? null : windowSize(value);
|
|
484
|
+
return null;
|
|
485
|
+
}
|
|
486
|
+
function windowSize(value) {
|
|
487
|
+
const parsed = Number(value);
|
|
488
|
+
if (!Number.isInteger(parsed) || parsed < 8 || parsed > 15) return null;
|
|
489
|
+
return parsed;
|
|
490
|
+
}
|
|
491
|
+
function windowOf(value) {
|
|
492
|
+
return typeof value === "number" || value === true ? value : void 0;
|
|
493
|
+
}
|
|
494
|
+
function numberOf(value) {
|
|
495
|
+
return typeof value === "number" ? value : void 0;
|
|
496
|
+
}
|
|
497
|
+
//#endregion
|
|
498
|
+
//#region src/compat/options/shared.ts
|
|
499
|
+
const DEFAULT_MAX_PAYLOAD = 104857600;
|
|
500
|
+
const DEFAULT_MAX_FRAGMENTS = 16384;
|
|
501
|
+
const DEFAULT_MAX_BUFFERED_CHUNKS = 262144;
|
|
502
|
+
const DEFAULT_CLOSE_TIMEOUT = 3e4;
|
|
503
|
+
const SUBPROTOCOL_PATTERN = /^[!#$%&'*+\-.0-9A-Z^_`|a-z~]+$/;
|
|
504
|
+
function isProtocolToken(value) {
|
|
505
|
+
return typeof value === "string" && SUBPROTOCOL_PATTERN.test(value);
|
|
506
|
+
}
|
|
507
|
+
function invalidOption(message, constructor = TypeError) {
|
|
508
|
+
throw createError("ERR_INVALID_OPTION", message, constructor);
|
|
509
|
+
}
|
|
510
|
+
function normalizeProtocols(protocols) {
|
|
511
|
+
if (protocols === void 0) return [];
|
|
512
|
+
const list = typeof protocols === "string" ? [protocols] : protocols;
|
|
513
|
+
const candidates = Array.isArray(list) ? list : [list];
|
|
514
|
+
const seen = /* @__PURE__ */ new Set();
|
|
515
|
+
const result = [];
|
|
516
|
+
for (const protocol of candidates) {
|
|
517
|
+
if (typeof protocol !== "string" || !SUBPROTOCOL_PATTERN.test(protocol) || seen.has(protocol)) invalidOption("An invalid or duplicated subprotocol was specified", SyntaxError);
|
|
518
|
+
seen.add(protocol);
|
|
519
|
+
result.push(protocol);
|
|
520
|
+
}
|
|
521
|
+
return result;
|
|
522
|
+
}
|
|
523
|
+
function parseProtocolHeader(header) {
|
|
524
|
+
return normalizeProtocols(header.split(",").map((protocol) => protocol.trim()));
|
|
525
|
+
}
|
|
526
|
+
function windowBitsOf(name, raw) {
|
|
527
|
+
if (raw === void 0 || raw === false) return raw;
|
|
528
|
+
if (typeof raw === "number" && Number.isInteger(raw) && raw >= 8 && raw <= 15) return raw;
|
|
529
|
+
return invalidOption(`The ${name} option must be an integer in [8, 15] (received ${String(raw)})`, RangeError);
|
|
530
|
+
}
|
|
531
|
+
function normalizePerMessageDeflate(value, fallback) {
|
|
532
|
+
if (value !== void 0 && !value) return false;
|
|
533
|
+
const resolved = value ?? fallback;
|
|
534
|
+
if (!resolved) return false;
|
|
535
|
+
const options = resolved === true ? {} : resolved;
|
|
536
|
+
return {
|
|
537
|
+
serverNoContextTakeover: options.serverNoContextTakeover,
|
|
538
|
+
clientNoContextTakeover: options.clientNoContextTakeover,
|
|
539
|
+
serverMaxWindowBits: windowBitsOf("serverMaxWindowBits", options.serverMaxWindowBits),
|
|
540
|
+
clientMaxWindowBits: windowBitsOf("clientMaxWindowBits", options.clientMaxWindowBits),
|
|
541
|
+
threshold: options.threshold ?? 1024,
|
|
542
|
+
concurrencyLimit: options.concurrencyLimit ?? 10,
|
|
543
|
+
zlibDeflateOptions: options.zlibDeflateOptions,
|
|
544
|
+
zlibInflateOptions: options.zlibInflateOptions
|
|
545
|
+
};
|
|
546
|
+
}
|
|
547
|
+
function closeTimeoutOf(source) {
|
|
548
|
+
const raw = source.closeTimeout;
|
|
549
|
+
if (raw === void 0) return DEFAULT_CLOSE_TIMEOUT;
|
|
550
|
+
if (typeof raw !== "number" || !Number.isFinite(raw) || raw < 0) invalidOption(`The closeTimeout option must be a non-negative number (received ${String(raw)})`, RangeError);
|
|
551
|
+
return raw;
|
|
552
|
+
}
|
|
462
553
|
//#endregion
|
|
463
554
|
//#region src/compat/server/clients.ts
|
|
464
555
|
function clientCount(state) {
|
|
@@ -475,7 +566,7 @@ function trackClient(state, socket) {
|
|
|
475
566
|
}
|
|
476
567
|
//#endregion
|
|
477
568
|
//#region package.json
|
|
478
|
-
var version = "1.0.0-rc.
|
|
569
|
+
var version = "1.0.0-rc.4";
|
|
479
570
|
//#endregion
|
|
480
571
|
//#region src/logging/lifecycle.ts
|
|
481
572
|
const CONTROL = /\p{Cc}/gu;
|
|
@@ -557,97 +648,6 @@ function closeWebSocketServer(state, callback) {
|
|
|
557
648
|
emitClose(state);
|
|
558
649
|
});
|
|
559
650
|
}
|
|
560
|
-
function normalizeParameters(parameters, isServer) {
|
|
561
|
-
const out = {};
|
|
562
|
-
for (const [key, values] of Object.entries(parameters)) {
|
|
563
|
-
if (values.length > 1) return null;
|
|
564
|
-
const parsed = parseParameter(key, values[0] ?? "", isServer);
|
|
565
|
-
if (parsed === null) return null;
|
|
566
|
-
out[key] = parsed;
|
|
567
|
-
}
|
|
568
|
-
return {
|
|
569
|
-
server_no_context_takeover: out.server_no_context_takeover === true,
|
|
570
|
-
client_no_context_takeover: out.client_no_context_takeover === true,
|
|
571
|
-
server_max_window_bits: numberOf(out.server_max_window_bits),
|
|
572
|
-
client_max_window_bits: windowOf(out.client_max_window_bits)
|
|
573
|
-
};
|
|
574
|
-
}
|
|
575
|
-
function parseParameter(key, value, isServer) {
|
|
576
|
-
if (key === "server_no_context_takeover" || key === "client_no_context_takeover") return value === "" ? true : null;
|
|
577
|
-
if (key === "client_max_window_bits") {
|
|
578
|
-
if (value === "") return isServer ? true : null;
|
|
579
|
-
return windowSize(value);
|
|
580
|
-
}
|
|
581
|
-
if (key === "server_max_window_bits") return value === "" ? null : windowSize(value);
|
|
582
|
-
return null;
|
|
583
|
-
}
|
|
584
|
-
function windowSize(value) {
|
|
585
|
-
const parsed = Number(value);
|
|
586
|
-
if (!Number.isInteger(parsed) || parsed < 8 || parsed > 15) return null;
|
|
587
|
-
return parsed;
|
|
588
|
-
}
|
|
589
|
-
function windowOf(value) {
|
|
590
|
-
return typeof value === "number" || value === true ? value : void 0;
|
|
591
|
-
}
|
|
592
|
-
function numberOf(value) {
|
|
593
|
-
return typeof value === "number" ? value : void 0;
|
|
594
|
-
}
|
|
595
|
-
//#endregion
|
|
596
|
-
//#region src/compat/options/shared.ts
|
|
597
|
-
const DEFAULT_MAX_PAYLOAD = 104857600;
|
|
598
|
-
const DEFAULT_MAX_FRAGMENTS = 16384;
|
|
599
|
-
const DEFAULT_MAX_BUFFERED_CHUNKS = 262144;
|
|
600
|
-
const DEFAULT_CLOSE_TIMEOUT = 3e4;
|
|
601
|
-
const SUBPROTOCOL_PATTERN = /^[!#$%&'*+\-.0-9A-Z^_`|a-z~]+$/;
|
|
602
|
-
function isProtocolToken(value) {
|
|
603
|
-
return typeof value === "string" && SUBPROTOCOL_PATTERN.test(value);
|
|
604
|
-
}
|
|
605
|
-
function invalidOption(message, constructor = TypeError) {
|
|
606
|
-
throw createError("ERR_INVALID_OPTION", message, constructor);
|
|
607
|
-
}
|
|
608
|
-
function normalizeProtocols$1(protocols) {
|
|
609
|
-
if (protocols === void 0) return [];
|
|
610
|
-
const list = typeof protocols === "string" ? [protocols] : protocols;
|
|
611
|
-
const candidates = Array.isArray(list) ? list : [list];
|
|
612
|
-
const seen = /* @__PURE__ */ new Set();
|
|
613
|
-
const result = [];
|
|
614
|
-
for (const protocol of candidates) {
|
|
615
|
-
if (typeof protocol !== "string" || !SUBPROTOCOL_PATTERN.test(protocol) || seen.has(protocol)) invalidOption("An invalid or duplicated subprotocol was specified", SyntaxError);
|
|
616
|
-
seen.add(protocol);
|
|
617
|
-
result.push(protocol);
|
|
618
|
-
}
|
|
619
|
-
return result;
|
|
620
|
-
}
|
|
621
|
-
function parseProtocolHeader(header) {
|
|
622
|
-
return normalizeProtocols$1(header.split(",").map((protocol) => protocol.trim()));
|
|
623
|
-
}
|
|
624
|
-
function windowBitsOf(name, raw) {
|
|
625
|
-
if (raw === void 0 || raw === false) return raw;
|
|
626
|
-
if (typeof raw === "number" && Number.isInteger(raw) && raw >= 8 && raw <= 15) return raw;
|
|
627
|
-
return invalidOption(`The ${name} option must be an integer in [8, 15] (received ${String(raw)})`, RangeError);
|
|
628
|
-
}
|
|
629
|
-
function normalizePerMessageDeflate(value, fallback) {
|
|
630
|
-
if (value !== void 0 && !value) return false;
|
|
631
|
-
const resolved = value ?? fallback;
|
|
632
|
-
if (!resolved) return false;
|
|
633
|
-
const options = resolved === true ? {} : resolved;
|
|
634
|
-
return {
|
|
635
|
-
serverNoContextTakeover: options.serverNoContextTakeover,
|
|
636
|
-
clientNoContextTakeover: options.clientNoContextTakeover,
|
|
637
|
-
serverMaxWindowBits: windowBitsOf("serverMaxWindowBits", options.serverMaxWindowBits),
|
|
638
|
-
clientMaxWindowBits: windowBitsOf("clientMaxWindowBits", options.clientMaxWindowBits),
|
|
639
|
-
threshold: options.threshold ?? 1024,
|
|
640
|
-
concurrencyLimit: options.concurrencyLimit ?? 10,
|
|
641
|
-
zlibDeflateOptions: options.zlibDeflateOptions,
|
|
642
|
-
zlibInflateOptions: options.zlibInflateOptions
|
|
643
|
-
};
|
|
644
|
-
}
|
|
645
|
-
function closeTimeoutOf(source) {
|
|
646
|
-
const raw = source.closeTimeout;
|
|
647
|
-
if (raw === void 0) return DEFAULT_CLOSE_TIMEOUT;
|
|
648
|
-
if (typeof raw !== "number" || !Number.isFinite(raw) || raw < 0) invalidOption(`The closeTimeout option must be a non-negative number (received ${String(raw)})`, RangeError);
|
|
649
|
-
return raw;
|
|
650
|
-
}
|
|
651
651
|
//#endregion
|
|
652
652
|
//#region src/compat/server/handshake.ts
|
|
653
653
|
const KEY_PATTERN = /^[+/0-9A-Za-z]{22}==$/;
|
|
@@ -1903,7 +1903,7 @@ function answer(options, offer) {
|
|
|
1903
1903
|
}
|
|
1904
1904
|
//#endregion
|
|
1905
1905
|
//#region src/compat/extensions/scan.ts
|
|
1906
|
-
const TOKEN
|
|
1906
|
+
const TOKEN = /^[!#$%&'*+\-.0-9A-Z^_`|a-z~]+$/;
|
|
1907
1907
|
const COMMA$1 = 44;
|
|
1908
1908
|
const SEMICOLON = 59;
|
|
1909
1909
|
const EQUALS = 61;
|
|
@@ -1953,7 +1953,7 @@ function readValue(header, start) {
|
|
|
1953
1953
|
if (header.charCodeAt(start) !== QUOTE) {
|
|
1954
1954
|
const token = readToken(header, start, "a parameter value");
|
|
1955
1955
|
if (token === null) throw unexpectedEnd(header, start);
|
|
1956
|
-
if (!TOKEN
|
|
1956
|
+
if (!TOKEN.test(token)) throw syntax(header, start, "invalid parameter value");
|
|
1957
1957
|
return {
|
|
1958
1958
|
value: token,
|
|
1959
1959
|
end: start + token.length
|
|
@@ -2280,10 +2280,10 @@ function createWebSocketServer(socketClass, options, callback) {
|
|
|
2280
2280
|
const resolved = {
|
|
2281
2281
|
allowSynchronousEvents: true,
|
|
2282
2282
|
autoPong: true,
|
|
2283
|
-
maxBufferedChunks:
|
|
2284
|
-
maxFragments:
|
|
2285
|
-
closeTimeout:
|
|
2286
|
-
maxPayload:
|
|
2283
|
+
maxBufferedChunks: DEFAULT_MAX_BUFFERED_CHUNKS,
|
|
2284
|
+
maxFragments: DEFAULT_MAX_FRAGMENTS,
|
|
2285
|
+
closeTimeout: DEFAULT_CLOSE_TIMEOUT,
|
|
2286
|
+
maxPayload: DEFAULT_MAX_PAYLOAD,
|
|
2287
2287
|
skipUTF8Validation: false,
|
|
2288
2288
|
perMessageDeflate: false,
|
|
2289
2289
|
handleProtocols: null,
|
|
@@ -2350,21 +2350,6 @@ function createWebSocketServer(socketClass, options, callback) {
|
|
|
2350
2350
|
}
|
|
2351
2351
|
//#endregion
|
|
2352
2352
|
//#region src/compat/client/protocols.ts
|
|
2353
|
-
const TOKEN = /^[!#$%&'*+\-.^_`|~\dA-Za-z]+$/;
|
|
2354
|
-
function invalidProtocols() {
|
|
2355
|
-
return createError("ERR_INVALID_OPTION", "An invalid or duplicated subprotocol was specified", SyntaxError);
|
|
2356
|
-
}
|
|
2357
|
-
function normalizeProtocols(protocols) {
|
|
2358
|
-
if (protocols === void 0) return [];
|
|
2359
|
-
const list = typeof protocols === "string" ? [protocols] : protocols;
|
|
2360
|
-
if (!Array.isArray(list)) throw invalidProtocols();
|
|
2361
|
-
const seen = /* @__PURE__ */ new Set();
|
|
2362
|
-
for (const protocol of list) {
|
|
2363
|
-
if (typeof protocol !== "string" || !TOKEN.test(protocol) || seen.has(protocol)) throw invalidProtocols();
|
|
2364
|
-
seen.add(protocol);
|
|
2365
|
-
}
|
|
2366
|
-
return [...list];
|
|
2367
|
-
}
|
|
2368
2353
|
function protocolSet(protocols) {
|
|
2369
2354
|
return new Set(protocols);
|
|
2370
2355
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -432,6 +432,97 @@ function createEmitter(state) {
|
|
|
432
432
|
}
|
|
433
433
|
};
|
|
434
434
|
}
|
|
435
|
+
function normalizeParameters(parameters, isServer) {
|
|
436
|
+
const out = {};
|
|
437
|
+
for (const [key, values] of Object.entries(parameters)) {
|
|
438
|
+
if (values.length > 1) return null;
|
|
439
|
+
const parsed = parseParameter(key, values[0] ?? "", isServer);
|
|
440
|
+
if (parsed === null) return null;
|
|
441
|
+
out[key] = parsed;
|
|
442
|
+
}
|
|
443
|
+
return {
|
|
444
|
+
server_no_context_takeover: out.server_no_context_takeover === true,
|
|
445
|
+
client_no_context_takeover: out.client_no_context_takeover === true,
|
|
446
|
+
server_max_window_bits: numberOf(out.server_max_window_bits),
|
|
447
|
+
client_max_window_bits: windowOf(out.client_max_window_bits)
|
|
448
|
+
};
|
|
449
|
+
}
|
|
450
|
+
function parseParameter(key, value, isServer) {
|
|
451
|
+
if (key === "server_no_context_takeover" || key === "client_no_context_takeover") return value === "" ? true : null;
|
|
452
|
+
if (key === "client_max_window_bits") {
|
|
453
|
+
if (value === "") return isServer ? true : null;
|
|
454
|
+
return windowSize(value);
|
|
455
|
+
}
|
|
456
|
+
if (key === "server_max_window_bits") return value === "" ? null : windowSize(value);
|
|
457
|
+
return null;
|
|
458
|
+
}
|
|
459
|
+
function windowSize(value) {
|
|
460
|
+
const parsed = Number(value);
|
|
461
|
+
if (!Number.isInteger(parsed) || parsed < 8 || parsed > 15) return null;
|
|
462
|
+
return parsed;
|
|
463
|
+
}
|
|
464
|
+
function windowOf(value) {
|
|
465
|
+
return typeof value === "number" || value === true ? value : void 0;
|
|
466
|
+
}
|
|
467
|
+
function numberOf(value) {
|
|
468
|
+
return typeof value === "number" ? value : void 0;
|
|
469
|
+
}
|
|
470
|
+
//#endregion
|
|
471
|
+
//#region src/compat/options/shared.ts
|
|
472
|
+
const DEFAULT_MAX_PAYLOAD = 104857600;
|
|
473
|
+
const DEFAULT_MAX_FRAGMENTS = 16384;
|
|
474
|
+
const DEFAULT_MAX_BUFFERED_CHUNKS = 262144;
|
|
475
|
+
const DEFAULT_CLOSE_TIMEOUT = 3e4;
|
|
476
|
+
const SUBPROTOCOL_PATTERN = /^[!#$%&'*+\-.0-9A-Z^_`|a-z~]+$/;
|
|
477
|
+
function isProtocolToken(value) {
|
|
478
|
+
return typeof value === "string" && SUBPROTOCOL_PATTERN.test(value);
|
|
479
|
+
}
|
|
480
|
+
function invalidOption(message, constructor = TypeError) {
|
|
481
|
+
throw createError("ERR_INVALID_OPTION", message, constructor);
|
|
482
|
+
}
|
|
483
|
+
function normalizeProtocols(protocols) {
|
|
484
|
+
if (protocols === void 0) return [];
|
|
485
|
+
const list = typeof protocols === "string" ? [protocols] : protocols;
|
|
486
|
+
const candidates = Array.isArray(list) ? list : [list];
|
|
487
|
+
const seen = /* @__PURE__ */ new Set();
|
|
488
|
+
const result = [];
|
|
489
|
+
for (const protocol of candidates) {
|
|
490
|
+
if (typeof protocol !== "string" || !SUBPROTOCOL_PATTERN.test(protocol) || seen.has(protocol)) invalidOption("An invalid or duplicated subprotocol was specified", SyntaxError);
|
|
491
|
+
seen.add(protocol);
|
|
492
|
+
result.push(protocol);
|
|
493
|
+
}
|
|
494
|
+
return result;
|
|
495
|
+
}
|
|
496
|
+
function parseProtocolHeader(header) {
|
|
497
|
+
return normalizeProtocols(header.split(",").map((protocol) => protocol.trim()));
|
|
498
|
+
}
|
|
499
|
+
function windowBitsOf(name, raw) {
|
|
500
|
+
if (raw === void 0 || raw === false) return raw;
|
|
501
|
+
if (typeof raw === "number" && Number.isInteger(raw) && raw >= 8 && raw <= 15) return raw;
|
|
502
|
+
return invalidOption(`The ${name} option must be an integer in [8, 15] (received ${String(raw)})`, RangeError);
|
|
503
|
+
}
|
|
504
|
+
function normalizePerMessageDeflate(value, fallback) {
|
|
505
|
+
if (value !== void 0 && !value) return false;
|
|
506
|
+
const resolved = value ?? fallback;
|
|
507
|
+
if (!resolved) return false;
|
|
508
|
+
const options = resolved === true ? {} : resolved;
|
|
509
|
+
return {
|
|
510
|
+
serverNoContextTakeover: options.serverNoContextTakeover,
|
|
511
|
+
clientNoContextTakeover: options.clientNoContextTakeover,
|
|
512
|
+
serverMaxWindowBits: windowBitsOf("serverMaxWindowBits", options.serverMaxWindowBits),
|
|
513
|
+
clientMaxWindowBits: windowBitsOf("clientMaxWindowBits", options.clientMaxWindowBits),
|
|
514
|
+
threshold: options.threshold ?? 1024,
|
|
515
|
+
concurrencyLimit: options.concurrencyLimit ?? 10,
|
|
516
|
+
zlibDeflateOptions: options.zlibDeflateOptions,
|
|
517
|
+
zlibInflateOptions: options.zlibInflateOptions
|
|
518
|
+
};
|
|
519
|
+
}
|
|
520
|
+
function closeTimeoutOf(source) {
|
|
521
|
+
const raw = source.closeTimeout;
|
|
522
|
+
if (raw === void 0) return DEFAULT_CLOSE_TIMEOUT;
|
|
523
|
+
if (typeof raw !== "number" || !Number.isFinite(raw) || raw < 0) invalidOption(`The closeTimeout option must be a non-negative number (received ${String(raw)})`, RangeError);
|
|
524
|
+
return raw;
|
|
525
|
+
}
|
|
435
526
|
//#endregion
|
|
436
527
|
//#region src/compat/server/clients.ts
|
|
437
528
|
function clientCount(state) {
|
|
@@ -448,7 +539,7 @@ function trackClient(state, socket) {
|
|
|
448
539
|
}
|
|
449
540
|
//#endregion
|
|
450
541
|
//#region package.json
|
|
451
|
-
var version = "1.0.0-rc.
|
|
542
|
+
var version = "1.0.0-rc.4";
|
|
452
543
|
//#endregion
|
|
453
544
|
//#region src/logging/lifecycle.ts
|
|
454
545
|
const CONTROL = /\p{Cc}/gu;
|
|
@@ -530,97 +621,6 @@ function closeWebSocketServer(state, callback) {
|
|
|
530
621
|
emitClose(state);
|
|
531
622
|
});
|
|
532
623
|
}
|
|
533
|
-
function normalizeParameters(parameters, isServer) {
|
|
534
|
-
const out = {};
|
|
535
|
-
for (const [key, values] of Object.entries(parameters)) {
|
|
536
|
-
if (values.length > 1) return null;
|
|
537
|
-
const parsed = parseParameter(key, values[0] ?? "", isServer);
|
|
538
|
-
if (parsed === null) return null;
|
|
539
|
-
out[key] = parsed;
|
|
540
|
-
}
|
|
541
|
-
return {
|
|
542
|
-
server_no_context_takeover: out.server_no_context_takeover === true,
|
|
543
|
-
client_no_context_takeover: out.client_no_context_takeover === true,
|
|
544
|
-
server_max_window_bits: numberOf(out.server_max_window_bits),
|
|
545
|
-
client_max_window_bits: windowOf(out.client_max_window_bits)
|
|
546
|
-
};
|
|
547
|
-
}
|
|
548
|
-
function parseParameter(key, value, isServer) {
|
|
549
|
-
if (key === "server_no_context_takeover" || key === "client_no_context_takeover") return value === "" ? true : null;
|
|
550
|
-
if (key === "client_max_window_bits") {
|
|
551
|
-
if (value === "") return isServer ? true : null;
|
|
552
|
-
return windowSize(value);
|
|
553
|
-
}
|
|
554
|
-
if (key === "server_max_window_bits") return value === "" ? null : windowSize(value);
|
|
555
|
-
return null;
|
|
556
|
-
}
|
|
557
|
-
function windowSize(value) {
|
|
558
|
-
const parsed = Number(value);
|
|
559
|
-
if (!Number.isInteger(parsed) || parsed < 8 || parsed > 15) return null;
|
|
560
|
-
return parsed;
|
|
561
|
-
}
|
|
562
|
-
function windowOf(value) {
|
|
563
|
-
return typeof value === "number" || value === true ? value : void 0;
|
|
564
|
-
}
|
|
565
|
-
function numberOf(value) {
|
|
566
|
-
return typeof value === "number" ? value : void 0;
|
|
567
|
-
}
|
|
568
|
-
//#endregion
|
|
569
|
-
//#region src/compat/options/shared.ts
|
|
570
|
-
const DEFAULT_MAX_PAYLOAD = 104857600;
|
|
571
|
-
const DEFAULT_MAX_FRAGMENTS = 16384;
|
|
572
|
-
const DEFAULT_MAX_BUFFERED_CHUNKS = 262144;
|
|
573
|
-
const DEFAULT_CLOSE_TIMEOUT = 3e4;
|
|
574
|
-
const SUBPROTOCOL_PATTERN = /^[!#$%&'*+\-.0-9A-Z^_`|a-z~]+$/;
|
|
575
|
-
function isProtocolToken(value) {
|
|
576
|
-
return typeof value === "string" && SUBPROTOCOL_PATTERN.test(value);
|
|
577
|
-
}
|
|
578
|
-
function invalidOption(message, constructor = TypeError) {
|
|
579
|
-
throw createError("ERR_INVALID_OPTION", message, constructor);
|
|
580
|
-
}
|
|
581
|
-
function normalizeProtocols$1(protocols) {
|
|
582
|
-
if (protocols === void 0) return [];
|
|
583
|
-
const list = typeof protocols === "string" ? [protocols] : protocols;
|
|
584
|
-
const candidates = Array.isArray(list) ? list : [list];
|
|
585
|
-
const seen = /* @__PURE__ */ new Set();
|
|
586
|
-
const result = [];
|
|
587
|
-
for (const protocol of candidates) {
|
|
588
|
-
if (typeof protocol !== "string" || !SUBPROTOCOL_PATTERN.test(protocol) || seen.has(protocol)) invalidOption("An invalid or duplicated subprotocol was specified", SyntaxError);
|
|
589
|
-
seen.add(protocol);
|
|
590
|
-
result.push(protocol);
|
|
591
|
-
}
|
|
592
|
-
return result;
|
|
593
|
-
}
|
|
594
|
-
function parseProtocolHeader(header) {
|
|
595
|
-
return normalizeProtocols$1(header.split(",").map((protocol) => protocol.trim()));
|
|
596
|
-
}
|
|
597
|
-
function windowBitsOf(name, raw) {
|
|
598
|
-
if (raw === void 0 || raw === false) return raw;
|
|
599
|
-
if (typeof raw === "number" && Number.isInteger(raw) && raw >= 8 && raw <= 15) return raw;
|
|
600
|
-
return invalidOption(`The ${name} option must be an integer in [8, 15] (received ${String(raw)})`, RangeError);
|
|
601
|
-
}
|
|
602
|
-
function normalizePerMessageDeflate(value, fallback) {
|
|
603
|
-
if (value !== void 0 && !value) return false;
|
|
604
|
-
const resolved = value ?? fallback;
|
|
605
|
-
if (!resolved) return false;
|
|
606
|
-
const options = resolved === true ? {} : resolved;
|
|
607
|
-
return {
|
|
608
|
-
serverNoContextTakeover: options.serverNoContextTakeover,
|
|
609
|
-
clientNoContextTakeover: options.clientNoContextTakeover,
|
|
610
|
-
serverMaxWindowBits: windowBitsOf("serverMaxWindowBits", options.serverMaxWindowBits),
|
|
611
|
-
clientMaxWindowBits: windowBitsOf("clientMaxWindowBits", options.clientMaxWindowBits),
|
|
612
|
-
threshold: options.threshold ?? 1024,
|
|
613
|
-
concurrencyLimit: options.concurrencyLimit ?? 10,
|
|
614
|
-
zlibDeflateOptions: options.zlibDeflateOptions,
|
|
615
|
-
zlibInflateOptions: options.zlibInflateOptions
|
|
616
|
-
};
|
|
617
|
-
}
|
|
618
|
-
function closeTimeoutOf(source) {
|
|
619
|
-
const raw = source.closeTimeout;
|
|
620
|
-
if (raw === void 0) return DEFAULT_CLOSE_TIMEOUT;
|
|
621
|
-
if (typeof raw !== "number" || !Number.isFinite(raw) || raw < 0) invalidOption(`The closeTimeout option must be a non-negative number (received ${String(raw)})`, RangeError);
|
|
622
|
-
return raw;
|
|
623
|
-
}
|
|
624
624
|
//#endregion
|
|
625
625
|
//#region src/compat/server/handshake.ts
|
|
626
626
|
const KEY_PATTERN = /^[+/0-9A-Za-z]{22}==$/;
|
|
@@ -1876,7 +1876,7 @@ function answer(options, offer) {
|
|
|
1876
1876
|
}
|
|
1877
1877
|
//#endregion
|
|
1878
1878
|
//#region src/compat/extensions/scan.ts
|
|
1879
|
-
const TOKEN
|
|
1879
|
+
const TOKEN = /^[!#$%&'*+\-.0-9A-Z^_`|a-z~]+$/;
|
|
1880
1880
|
const COMMA$1 = 44;
|
|
1881
1881
|
const SEMICOLON = 59;
|
|
1882
1882
|
const EQUALS = 61;
|
|
@@ -1926,7 +1926,7 @@ function readValue(header, start) {
|
|
|
1926
1926
|
if (header.charCodeAt(start) !== QUOTE) {
|
|
1927
1927
|
const token = readToken(header, start, "a parameter value");
|
|
1928
1928
|
if (token === null) throw unexpectedEnd(header, start);
|
|
1929
|
-
if (!TOKEN
|
|
1929
|
+
if (!TOKEN.test(token)) throw syntax(header, start, "invalid parameter value");
|
|
1930
1930
|
return {
|
|
1931
1931
|
value: token,
|
|
1932
1932
|
end: start + token.length
|
|
@@ -2253,10 +2253,10 @@ function createWebSocketServer(socketClass, options, callback) {
|
|
|
2253
2253
|
const resolved = {
|
|
2254
2254
|
allowSynchronousEvents: true,
|
|
2255
2255
|
autoPong: true,
|
|
2256
|
-
maxBufferedChunks:
|
|
2257
|
-
maxFragments:
|
|
2258
|
-
closeTimeout:
|
|
2259
|
-
maxPayload:
|
|
2256
|
+
maxBufferedChunks: DEFAULT_MAX_BUFFERED_CHUNKS,
|
|
2257
|
+
maxFragments: DEFAULT_MAX_FRAGMENTS,
|
|
2258
|
+
closeTimeout: DEFAULT_CLOSE_TIMEOUT,
|
|
2259
|
+
maxPayload: DEFAULT_MAX_PAYLOAD,
|
|
2260
2260
|
skipUTF8Validation: false,
|
|
2261
2261
|
perMessageDeflate: false,
|
|
2262
2262
|
handleProtocols: null,
|
|
@@ -2323,21 +2323,6 @@ function createWebSocketServer(socketClass, options, callback) {
|
|
|
2323
2323
|
}
|
|
2324
2324
|
//#endregion
|
|
2325
2325
|
//#region src/compat/client/protocols.ts
|
|
2326
|
-
const TOKEN = /^[!#$%&'*+\-.^_`|~\dA-Za-z]+$/;
|
|
2327
|
-
function invalidProtocols() {
|
|
2328
|
-
return createError("ERR_INVALID_OPTION", "An invalid or duplicated subprotocol was specified", SyntaxError);
|
|
2329
|
-
}
|
|
2330
|
-
function normalizeProtocols(protocols) {
|
|
2331
|
-
if (protocols === void 0) return [];
|
|
2332
|
-
const list = typeof protocols === "string" ? [protocols] : protocols;
|
|
2333
|
-
if (!Array.isArray(list)) throw invalidProtocols();
|
|
2334
|
-
const seen = /* @__PURE__ */ new Set();
|
|
2335
|
-
for (const protocol of list) {
|
|
2336
|
-
if (typeof protocol !== "string" || !TOKEN.test(protocol) || seen.has(protocol)) throw invalidProtocols();
|
|
2337
|
-
seen.add(protocol);
|
|
2338
|
-
}
|
|
2339
|
-
return [...list];
|
|
2340
|
-
}
|
|
2341
2326
|
function protocolSet(protocols) {
|
|
2342
2327
|
return new Set(protocols);
|
|
2343
2328
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ventiws",
|
|
3
|
-
"version": "1.0.0-rc.
|
|
3
|
+
"version": "1.0.0-rc.4",
|
|
4
4
|
"description": "A drop-in replacement for ws for Node.js, built on the first-party µWebZockets Zig engine via napi-zig.",
|
|
5
5
|
"homepage": "https://github.com/farbenbuilds/ventiws#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -34,10 +34,10 @@
|
|
|
34
34
|
"node": ">=22.12.0"
|
|
35
35
|
},
|
|
36
36
|
"optionalDependencies": {
|
|
37
|
-
"@ventiws/binding-darwin-arm64": "1.0.0-rc.
|
|
38
|
-
"@ventiws/binding-darwin-x64": "1.0.0-rc.
|
|
39
|
-
"@ventiws/binding-linux-arm64-gnu": "1.0.0-rc.
|
|
40
|
-
"@ventiws/binding-linux-x64-gnu": "1.0.0-rc.
|
|
41
|
-
"@ventiws/binding-linux-x64-musl": "1.0.0-rc.
|
|
37
|
+
"@ventiws/binding-darwin-arm64": "1.0.0-rc.4",
|
|
38
|
+
"@ventiws/binding-darwin-x64": "1.0.0-rc.4",
|
|
39
|
+
"@ventiws/binding-linux-arm64-gnu": "1.0.0-rc.4",
|
|
40
|
+
"@ventiws/binding-linux-x64-gnu": "1.0.0-rc.4",
|
|
41
|
+
"@ventiws/binding-linux-x64-musl": "1.0.0-rc.4"
|
|
42
42
|
}
|
|
43
43
|
}
|