wreq-js 1.7.0 → 2.0.1
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 +110 -26
- package/dist/wreq-js.cjs +796 -94
- package/dist/wreq-js.cjs.map +1 -1
- package/dist/wreq-js.d.cts +248 -102
- package/dist/wreq-js.d.ts +248 -102
- package/dist/wreq-js.js +796 -94
- package/dist/wreq-js.js.map +1 -1
- package/package.json +6 -2
- package/rust/wreq-js.darwin-arm64.node +0 -0
- package/rust/wreq-js.darwin-x64.node +0 -0
- package/rust/wreq-js.linux-arm64-gnu.node +0 -0
- package/rust/wreq-js.linux-x64-gnu.node +0 -0
- package/rust/wreq-js.linux-x64-musl.node +0 -0
- package/rust/wreq-js.win32-x64-msvc.node +0 -0
package/dist/wreq-js.js
CHANGED
|
@@ -5,7 +5,7 @@ import { createRequire } from "module";
|
|
|
5
5
|
import { ReadableStream } from "stream/web";
|
|
6
6
|
|
|
7
7
|
// src/types.ts
|
|
8
|
-
var RequestError = class extends
|
|
8
|
+
var RequestError = class extends TypeError {
|
|
9
9
|
constructor(message) {
|
|
10
10
|
super(message);
|
|
11
11
|
this.name = "RequestError";
|
|
@@ -86,6 +86,7 @@ var bodyHandleFinalizer = typeof FinalizationRegistry === "function" ? new Final
|
|
|
86
86
|
}) : void 0;
|
|
87
87
|
var DEFAULT_BROWSER = "chrome_142";
|
|
88
88
|
var DEFAULT_OS = "macos";
|
|
89
|
+
var DEFAULT_REQUEST_TIMEOUT_MS = 3e4;
|
|
89
90
|
var SUPPORTED_OSES = ["windows", "macos", "linux", "android", "ios"];
|
|
90
91
|
var UTF8_DECODER = new TextDecoder("utf-8");
|
|
91
92
|
var ephemeralIdCounter = 0;
|
|
@@ -254,27 +255,7 @@ var Headers = class _Headers {
|
|
|
254
255
|
}
|
|
255
256
|
};
|
|
256
257
|
function headersToTuples(init) {
|
|
257
|
-
|
|
258
|
-
return init;
|
|
259
|
-
}
|
|
260
|
-
if (init instanceof Headers) {
|
|
261
|
-
return init.toTuples();
|
|
262
|
-
}
|
|
263
|
-
const out = [];
|
|
264
|
-
if (isPlainObject(init)) {
|
|
265
|
-
return new Headers(init).toTuples();
|
|
266
|
-
}
|
|
267
|
-
if (isIterable(init)) {
|
|
268
|
-
for (const tuple of init) {
|
|
269
|
-
if (!tuple) {
|
|
270
|
-
continue;
|
|
271
|
-
}
|
|
272
|
-
const [name, value] = tuple;
|
|
273
|
-
out.push([name, value]);
|
|
274
|
-
}
|
|
275
|
-
return out;
|
|
276
|
-
}
|
|
277
|
-
return out;
|
|
258
|
+
return new Headers(init).toTuples();
|
|
278
259
|
}
|
|
279
260
|
function hasHeaderName(tuples, name) {
|
|
280
261
|
if (!tuples) {
|
|
@@ -288,6 +269,24 @@ function hasHeaderName(tuples, name) {
|
|
|
288
269
|
}
|
|
289
270
|
return false;
|
|
290
271
|
}
|
|
272
|
+
function hasWebSocketProtocolHeader(headers) {
|
|
273
|
+
const protocolHeaderName = "Sec-WebSocket-Protocol";
|
|
274
|
+
if (!headers) {
|
|
275
|
+
return false;
|
|
276
|
+
}
|
|
277
|
+
return hasHeaderName(headersToTuples(headers), protocolHeaderName);
|
|
278
|
+
}
|
|
279
|
+
function assertNoManualWebSocketProtocolHeader(headers) {
|
|
280
|
+
if (hasWebSocketProtocolHeader(headers)) {
|
|
281
|
+
throw new RequestError("Do not set `Sec-WebSocket-Protocol` header manually; use the `protocols` option instead.");
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
function normalizeWebSocketProtocolList(protocols) {
|
|
285
|
+
if (protocols === void 0) {
|
|
286
|
+
return void 0;
|
|
287
|
+
}
|
|
288
|
+
return typeof protocols === "string" ? [protocols] : [...protocols];
|
|
289
|
+
}
|
|
291
290
|
function mergeHeaderTuples(defaults, overrides) {
|
|
292
291
|
if (!defaults) {
|
|
293
292
|
return overrides === void 0 ? void 0 : headersToTuples(overrides);
|
|
@@ -368,13 +367,16 @@ function createNativeBodyStream(handle) {
|
|
|
368
367
|
}
|
|
369
368
|
function wrapBodyStream(source, onFirstUse) {
|
|
370
369
|
let started = false;
|
|
371
|
-
|
|
370
|
+
let reader = null;
|
|
372
371
|
return new ReadableStream({
|
|
373
372
|
async pull(controller) {
|
|
374
373
|
if (!started) {
|
|
375
374
|
started = true;
|
|
376
375
|
onFirstUse();
|
|
377
376
|
}
|
|
377
|
+
if (!reader) {
|
|
378
|
+
reader = source.getReader();
|
|
379
|
+
}
|
|
378
380
|
try {
|
|
379
381
|
const { done, value } = await reader.read();
|
|
380
382
|
if (done) {
|
|
@@ -387,6 +389,9 @@ function wrapBodyStream(source, onFirstUse) {
|
|
|
387
389
|
}
|
|
388
390
|
},
|
|
389
391
|
cancel(reason) {
|
|
392
|
+
if (!reader) {
|
|
393
|
+
return source.cancel(reason);
|
|
394
|
+
}
|
|
390
395
|
return reader.cancel(reason);
|
|
391
396
|
}
|
|
392
397
|
});
|
|
@@ -533,8 +538,22 @@ var Response = class _Response {
|
|
|
533
538
|
const bytes = await this.consumeBody();
|
|
534
539
|
return UTF8_DECODER.decode(bytes);
|
|
535
540
|
}
|
|
541
|
+
async blob() {
|
|
542
|
+
const bytes = await this.consumeBody();
|
|
543
|
+
const contentType = this.headers.get("content-type") ?? "";
|
|
544
|
+
return new Blob([bytes], contentType ? { type: contentType } : void 0);
|
|
545
|
+
}
|
|
546
|
+
async formData() {
|
|
547
|
+
const bytes = await this.consumeBody();
|
|
548
|
+
const contentType = this.headers.get("content-type");
|
|
549
|
+
const response = new globalThis.Response(
|
|
550
|
+
bytes,
|
|
551
|
+
contentType ? { headers: { "content-type": contentType } } : void 0
|
|
552
|
+
);
|
|
553
|
+
return response.formData();
|
|
554
|
+
}
|
|
536
555
|
clone() {
|
|
537
|
-
if (this.bodyUsed
|
|
556
|
+
if (this.bodyUsed) {
|
|
538
557
|
throw new TypeError("Cannot clone a Response whose body is already used");
|
|
539
558
|
}
|
|
540
559
|
if (this.nativeHandleAvailable && this.payload.bodyHandle !== null) {
|
|
@@ -669,6 +688,36 @@ var Session = class {
|
|
|
669
688
|
throw new RequestError(String(error));
|
|
670
689
|
}
|
|
671
690
|
}
|
|
691
|
+
async websocket(urlOrOptions, options) {
|
|
692
|
+
this.ensureActive();
|
|
693
|
+
const normalized = normalizeSessionWebSocketArgs(urlOrOptions, options);
|
|
694
|
+
validateWebSocketProtocols(normalized.options.protocols);
|
|
695
|
+
assertNoManualWebSocketProtocolHeader(normalized.options.headers);
|
|
696
|
+
const protocols = normalizeWebSocketProtocolList(normalized.options.protocols);
|
|
697
|
+
const transportId = this.defaults.transportId;
|
|
698
|
+
if (!transportId) {
|
|
699
|
+
throw new RequestError(
|
|
700
|
+
"Session has no transport. Create the session with browser/os options or pass a transport to use session.websocket()."
|
|
701
|
+
);
|
|
702
|
+
}
|
|
703
|
+
return WebSocket._connectWithInit({
|
|
704
|
+
_internal: true,
|
|
705
|
+
url: normalized.url,
|
|
706
|
+
options: normalized.options,
|
|
707
|
+
openDispatchMode: "deferred",
|
|
708
|
+
connect: (callbacks) => nativeBinding.websocketConnectSession({
|
|
709
|
+
url: normalized.url,
|
|
710
|
+
sessionId: this.id,
|
|
711
|
+
transportId,
|
|
712
|
+
headers: headersToTuples(normalized.options.headers ?? {}),
|
|
713
|
+
...protocols && protocols.length > 0 && { protocols },
|
|
714
|
+
onMessage: callbacks.onMessage,
|
|
715
|
+
onClose: callbacks.onClose,
|
|
716
|
+
onError: callbacks.onError
|
|
717
|
+
}),
|
|
718
|
+
legacyCallbacks: normalized.legacyCallbacks
|
|
719
|
+
});
|
|
720
|
+
}
|
|
672
721
|
async close() {
|
|
673
722
|
if (this.disposed) {
|
|
674
723
|
return;
|
|
@@ -749,7 +798,7 @@ function resolveTransportContext(config, sessionDefaults) {
|
|
|
749
798
|
if (config.transport.closed) {
|
|
750
799
|
throw new RequestError("Transport has been closed");
|
|
751
800
|
}
|
|
752
|
-
const hasProxy =
|
|
801
|
+
const hasProxy = config.proxy !== void 0;
|
|
753
802
|
if (config.browser !== void 0 || config.os !== void 0 || hasProxy || config.insecure !== void 0) {
|
|
754
803
|
throw new RequestError("`transport` cannot be combined with browser/os/proxy/insecure options");
|
|
755
804
|
}
|
|
@@ -849,7 +898,7 @@ function setupAbort(signal, cancelNative) {
|
|
|
849
898
|
return { promise, cleanup };
|
|
850
899
|
}
|
|
851
900
|
function coerceUrlInput(input) {
|
|
852
|
-
if (
|
|
901
|
+
if (input instanceof URL) {
|
|
853
902
|
return input.href;
|
|
854
903
|
}
|
|
855
904
|
if (input.length === 0) {
|
|
@@ -864,6 +913,41 @@ function coerceUrlInput(input) {
|
|
|
864
913
|
}
|
|
865
914
|
return trimmed;
|
|
866
915
|
}
|
|
916
|
+
function isRequestLike(input) {
|
|
917
|
+
if (!input || typeof input !== "object") {
|
|
918
|
+
return false;
|
|
919
|
+
}
|
|
920
|
+
if (typeof Request !== "undefined" && input instanceof Request) {
|
|
921
|
+
return true;
|
|
922
|
+
}
|
|
923
|
+
const candidate = input;
|
|
924
|
+
return typeof candidate.url === "string" && typeof candidate.method === "string" && typeof candidate.arrayBuffer === "function" && typeof candidate.redirect === "string";
|
|
925
|
+
}
|
|
926
|
+
async function resolveFetchArgs(input, init) {
|
|
927
|
+
if (!isRequestLike(input)) {
|
|
928
|
+
return { url: coerceUrlInput(input), init: init ?? {} };
|
|
929
|
+
}
|
|
930
|
+
const mergedInit = init ? { ...init } : {};
|
|
931
|
+
if (mergedInit.method === void 0) {
|
|
932
|
+
mergedInit.method = input.method;
|
|
933
|
+
}
|
|
934
|
+
if (mergedInit.headers === void 0) {
|
|
935
|
+
mergedInit.headers = input.headers;
|
|
936
|
+
}
|
|
937
|
+
if (mergedInit.redirect === void 0 && (input.redirect === "follow" || input.redirect === "manual" || input.redirect === "error")) {
|
|
938
|
+
mergedInit.redirect = input.redirect;
|
|
939
|
+
}
|
|
940
|
+
if (mergedInit.signal === void 0) {
|
|
941
|
+
mergedInit.signal = input.signal;
|
|
942
|
+
}
|
|
943
|
+
if (mergedInit.body === void 0 && input.body !== null) {
|
|
944
|
+
if (input.bodyUsed) {
|
|
945
|
+
throw new TypeError("Request body is already used");
|
|
946
|
+
}
|
|
947
|
+
mergedInit.body = Buffer.from(await input.arrayBuffer());
|
|
948
|
+
}
|
|
949
|
+
return { url: coerceUrlInput(input.url), init: mergedInit };
|
|
950
|
+
}
|
|
867
951
|
function normalizeUrlForComparison(value) {
|
|
868
952
|
try {
|
|
869
953
|
return new URL(value).toString();
|
|
@@ -939,17 +1023,23 @@ function ensureBodyAllowed(method, body) {
|
|
|
939
1023
|
}
|
|
940
1024
|
}
|
|
941
1025
|
function validateBrowserProfile(browser) {
|
|
942
|
-
if (
|
|
1026
|
+
if (browser === void 0) {
|
|
943
1027
|
return;
|
|
944
1028
|
}
|
|
1029
|
+
if (typeof browser !== "string" || browser.trim().length === 0) {
|
|
1030
|
+
throw new RequestError("Browser profile must not be empty");
|
|
1031
|
+
}
|
|
945
1032
|
if (!getProfileSet().has(browser)) {
|
|
946
1033
|
throw new RequestError(`Invalid browser profile: ${browser}. Available profiles: ${getProfiles().join(", ")}`);
|
|
947
1034
|
}
|
|
948
1035
|
}
|
|
949
1036
|
function validateOperatingSystem(os) {
|
|
950
|
-
if (
|
|
1037
|
+
if (os === void 0) {
|
|
951
1038
|
return;
|
|
952
1039
|
}
|
|
1040
|
+
if (typeof os !== "string" || os.trim().length === 0) {
|
|
1041
|
+
throw new RequestError("Operating system must not be empty");
|
|
1042
|
+
}
|
|
953
1043
|
if (!getOperatingSystemSet().has(os)) {
|
|
954
1044
|
throw new RequestError(`Invalid operating system: ${os}. Available options: ${getOperatingSystems().join(", ")}`);
|
|
955
1045
|
}
|
|
@@ -961,8 +1051,8 @@ function validateTimeout(timeout) {
|
|
|
961
1051
|
if (typeof timeout !== "number" || !Number.isFinite(timeout)) {
|
|
962
1052
|
throw new RequestError("Timeout must be a finite number");
|
|
963
1053
|
}
|
|
964
|
-
if (timeout
|
|
965
|
-
throw new RequestError("Timeout must be
|
|
1054
|
+
if (timeout < 0) {
|
|
1055
|
+
throw new RequestError("Timeout must be 0 (no timeout) or a positive number");
|
|
966
1056
|
}
|
|
967
1057
|
}
|
|
968
1058
|
function validatePositiveNumber(value, label) {
|
|
@@ -1029,8 +1119,9 @@ async function dispatchRequest(options, requestUrl, signal) {
|
|
|
1029
1119
|
return new Response(payload, requestUrl);
|
|
1030
1120
|
}
|
|
1031
1121
|
async function fetch(input, init) {
|
|
1032
|
-
const
|
|
1033
|
-
const
|
|
1122
|
+
const resolved = await resolveFetchArgs(input, init);
|
|
1123
|
+
const url = resolved.url;
|
|
1124
|
+
const config = resolved.init;
|
|
1034
1125
|
const sessionContext = resolveSessionContext(config);
|
|
1035
1126
|
const sessionDefaults = sessionContext.defaults;
|
|
1036
1127
|
validateRedirectMode(config.redirect);
|
|
@@ -1049,7 +1140,7 @@ async function fetch(input, init) {
|
|
|
1049
1140
|
headerTuples.push(["Content-Type", serializedBody.contentType]);
|
|
1050
1141
|
}
|
|
1051
1142
|
const transport = resolveTransportContext(config, sessionDefaults);
|
|
1052
|
-
const timeout = config.timeout ?? sessionDefaults?.timeout;
|
|
1143
|
+
const timeout = config.timeout ?? sessionDefaults?.timeout ?? DEFAULT_REQUEST_TIMEOUT_MS;
|
|
1053
1144
|
const requestOptions = {
|
|
1054
1145
|
url,
|
|
1055
1146
|
method,
|
|
@@ -1071,9 +1162,7 @@ async function fetch(input, init) {
|
|
|
1071
1162
|
requestOptions.insecure = transport.insecure;
|
|
1072
1163
|
}
|
|
1073
1164
|
}
|
|
1074
|
-
|
|
1075
|
-
requestOptions.timeout = timeout;
|
|
1076
|
-
}
|
|
1165
|
+
requestOptions.timeout = timeout;
|
|
1077
1166
|
if (config.redirect !== void 0) {
|
|
1078
1167
|
requestOptions.redirect = config.redirect;
|
|
1079
1168
|
}
|
|
@@ -1261,84 +1350,696 @@ async function post(url, body, init) {
|
|
|
1261
1350
|
}
|
|
1262
1351
|
return fetch(url, config);
|
|
1263
1352
|
}
|
|
1264
|
-
|
|
1353
|
+
function normalizeWebSocketUrl(url) {
|
|
1354
|
+
const normalized = String(url).trim();
|
|
1355
|
+
if (!normalized) {
|
|
1356
|
+
throw new RequestError("URL is required");
|
|
1357
|
+
}
|
|
1358
|
+
let parsed;
|
|
1359
|
+
try {
|
|
1360
|
+
parsed = new URL(normalized);
|
|
1361
|
+
} catch (error) {
|
|
1362
|
+
throw new RequestError(String(error));
|
|
1363
|
+
}
|
|
1364
|
+
if (parsed.hash) {
|
|
1365
|
+
throw new RequestError("WebSocket URL must not include a hash fragment");
|
|
1366
|
+
}
|
|
1367
|
+
if (parsed.protocol === "http:") {
|
|
1368
|
+
parsed.protocol = "ws:";
|
|
1369
|
+
} else if (parsed.protocol === "https:") {
|
|
1370
|
+
parsed.protocol = "wss:";
|
|
1371
|
+
}
|
|
1372
|
+
if (parsed.protocol !== "ws:" && parsed.protocol !== "wss:") {
|
|
1373
|
+
throw new RequestError("expected a ws: or wss: url");
|
|
1374
|
+
}
|
|
1375
|
+
return parsed.toString();
|
|
1376
|
+
}
|
|
1377
|
+
function validateWebSocketProtocols(protocols) {
|
|
1378
|
+
if (protocols === void 0) {
|
|
1379
|
+
return;
|
|
1380
|
+
}
|
|
1381
|
+
const protocolList = typeof protocols === "string" ? [protocols] : protocols;
|
|
1382
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1383
|
+
const validToken = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/;
|
|
1384
|
+
for (const protocol of protocolList) {
|
|
1385
|
+
if (typeof protocol !== "string" || protocol.length === 0) {
|
|
1386
|
+
throw new RequestError("WebSocket protocol values must be non-empty strings");
|
|
1387
|
+
}
|
|
1388
|
+
if (!validToken.test(protocol)) {
|
|
1389
|
+
throw new RequestError(`Invalid WebSocket protocol value: ${protocol}`);
|
|
1390
|
+
}
|
|
1391
|
+
if (seen.has(protocol)) {
|
|
1392
|
+
throw new RequestError(`Duplicate WebSocket protocol: ${protocol}`);
|
|
1393
|
+
}
|
|
1394
|
+
seen.add(protocol);
|
|
1395
|
+
}
|
|
1396
|
+
}
|
|
1397
|
+
function normalizeStandaloneWebSocketOptions(options) {
|
|
1398
|
+
const normalized = {};
|
|
1399
|
+
if (!options) {
|
|
1400
|
+
return normalized;
|
|
1401
|
+
}
|
|
1402
|
+
if (options.browser !== void 0) {
|
|
1403
|
+
normalized.browser = options.browser;
|
|
1404
|
+
}
|
|
1405
|
+
if (options.os !== void 0) {
|
|
1406
|
+
normalized.os = options.os;
|
|
1407
|
+
}
|
|
1408
|
+
if (options.headers !== void 0) {
|
|
1409
|
+
normalized.headers = options.headers;
|
|
1410
|
+
}
|
|
1411
|
+
if (options.proxy !== void 0) {
|
|
1412
|
+
normalized.proxy = options.proxy;
|
|
1413
|
+
}
|
|
1414
|
+
if (options.protocols !== void 0) {
|
|
1415
|
+
normalized.protocols = options.protocols;
|
|
1416
|
+
}
|
|
1417
|
+
if (options.binaryType !== void 0) {
|
|
1418
|
+
if (options.binaryType !== "nodebuffer" && options.binaryType !== "arraybuffer" && options.binaryType !== "blob") {
|
|
1419
|
+
throw new RequestError("binaryType must be one of: 'nodebuffer', 'arraybuffer', 'blob'");
|
|
1420
|
+
}
|
|
1421
|
+
normalized.binaryType = options.binaryType;
|
|
1422
|
+
}
|
|
1423
|
+
return normalized;
|
|
1424
|
+
}
|
|
1425
|
+
function normalizeSessionWebSocketOptions(options) {
|
|
1426
|
+
const normalized = {};
|
|
1427
|
+
if (!options) {
|
|
1428
|
+
return normalized;
|
|
1429
|
+
}
|
|
1430
|
+
const optionsWithOverrides = options;
|
|
1431
|
+
if (optionsWithOverrides.browser !== void 0) {
|
|
1432
|
+
throw new RequestError(
|
|
1433
|
+
"`browser` is not supported in session.websocket(); the session controls browser emulation."
|
|
1434
|
+
);
|
|
1435
|
+
}
|
|
1436
|
+
if (optionsWithOverrides.os !== void 0) {
|
|
1437
|
+
throw new RequestError("`os` is not supported in session.websocket(); the session controls OS emulation.");
|
|
1438
|
+
}
|
|
1439
|
+
if (optionsWithOverrides.proxy !== void 0) {
|
|
1440
|
+
throw new RequestError("`proxy` is not supported in session.websocket(); the session transport controls proxying.");
|
|
1441
|
+
}
|
|
1442
|
+
if (options.headers !== void 0) {
|
|
1443
|
+
normalized.headers = options.headers;
|
|
1444
|
+
}
|
|
1445
|
+
if (options.protocols !== void 0) {
|
|
1446
|
+
normalized.protocols = options.protocols;
|
|
1447
|
+
}
|
|
1448
|
+
if (options.binaryType !== void 0) {
|
|
1449
|
+
if (options.binaryType !== "nodebuffer" && options.binaryType !== "arraybuffer" && options.binaryType !== "blob") {
|
|
1450
|
+
throw new RequestError("binaryType must be one of: 'nodebuffer', 'arraybuffer', 'blob'");
|
|
1451
|
+
}
|
|
1452
|
+
normalized.binaryType = options.binaryType;
|
|
1453
|
+
}
|
|
1454
|
+
return normalized;
|
|
1455
|
+
}
|
|
1456
|
+
function extractLegacyWebSocketCallbacks(options) {
|
|
1457
|
+
if (!isPlainObject(options)) {
|
|
1458
|
+
return void 0;
|
|
1459
|
+
}
|
|
1460
|
+
const maybeCallbacks = options;
|
|
1461
|
+
const callbacks = {};
|
|
1462
|
+
if (typeof maybeCallbacks.onMessage === "function") {
|
|
1463
|
+
callbacks.onMessage = maybeCallbacks.onMessage;
|
|
1464
|
+
}
|
|
1465
|
+
if (typeof maybeCallbacks.onClose === "function") {
|
|
1466
|
+
callbacks.onClose = maybeCallbacks.onClose;
|
|
1467
|
+
}
|
|
1468
|
+
if (typeof maybeCallbacks.onError === "function") {
|
|
1469
|
+
callbacks.onError = maybeCallbacks.onError;
|
|
1470
|
+
}
|
|
1471
|
+
return Object.keys(callbacks).length > 0 ? callbacks : void 0;
|
|
1472
|
+
}
|
|
1473
|
+
function normalizeWebSocketCloseOptions(code, reason) {
|
|
1474
|
+
if (code === void 0 && reason === void 0) {
|
|
1475
|
+
return void 0;
|
|
1476
|
+
}
|
|
1477
|
+
if (code === void 0) {
|
|
1478
|
+
throw new RequestError("A close code is required when providing a close reason");
|
|
1479
|
+
}
|
|
1480
|
+
if (!Number.isInteger(code)) {
|
|
1481
|
+
throw new RequestError("Close code must be an integer");
|
|
1482
|
+
}
|
|
1483
|
+
if (code !== 1e3 && (code < 3e3 || code > 4999)) {
|
|
1484
|
+
throw new RequestError("Close code must be 1000 or in range 3000-4999");
|
|
1485
|
+
}
|
|
1486
|
+
const normalizedReason = reason ?? "";
|
|
1487
|
+
if (Buffer.byteLength(normalizedReason, "utf8") > 123) {
|
|
1488
|
+
throw new RequestError("Close reason must be 123 bytes or fewer");
|
|
1489
|
+
}
|
|
1490
|
+
return {
|
|
1491
|
+
code,
|
|
1492
|
+
reason: normalizedReason
|
|
1493
|
+
};
|
|
1494
|
+
}
|
|
1495
|
+
function isWebSocketListenerType(type) {
|
|
1496
|
+
return type === "open" || type === "message" || type === "close" || type === "error";
|
|
1497
|
+
}
|
|
1498
|
+
var WebSocket = class _WebSocket {
|
|
1499
|
+
static CONNECTING = 0;
|
|
1500
|
+
static OPEN = 1;
|
|
1501
|
+
static CLOSING = 2;
|
|
1502
|
+
static CLOSED = 3;
|
|
1503
|
+
url;
|
|
1504
|
+
protocol = "";
|
|
1505
|
+
extensions = "";
|
|
1506
|
+
readyState = _WebSocket.CONNECTING;
|
|
1507
|
+
_binaryType = "nodebuffer";
|
|
1508
|
+
_bufferedAmount = 0;
|
|
1509
|
+
_onopen = null;
|
|
1510
|
+
_onmessage = null;
|
|
1511
|
+
_onclose = null;
|
|
1512
|
+
_onerror = null;
|
|
1513
|
+
_onHandlerOrder = {
|
|
1514
|
+
open: -1,
|
|
1515
|
+
message: -1,
|
|
1516
|
+
close: -1,
|
|
1517
|
+
error: -1
|
|
1518
|
+
};
|
|
1519
|
+
_listenerOrderCounter = 0;
|
|
1520
|
+
_listeners = {
|
|
1521
|
+
open: /* @__PURE__ */ new Map(),
|
|
1522
|
+
message: /* @__PURE__ */ new Map(),
|
|
1523
|
+
close: /* @__PURE__ */ new Map(),
|
|
1524
|
+
error: /* @__PURE__ */ new Map()
|
|
1525
|
+
};
|
|
1526
|
+
_legacyCallbacks;
|
|
1527
|
+
_openDispatchMode;
|
|
1265
1528
|
_connection;
|
|
1529
|
+
_connectPromise;
|
|
1530
|
+
_closeOptions;
|
|
1266
1531
|
_finalizerToken;
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1532
|
+
_openEventDispatched = false;
|
|
1533
|
+
_openEventQueued = false;
|
|
1534
|
+
_closeEventDispatched = false;
|
|
1535
|
+
_nativeCloseStarted = false;
|
|
1536
|
+
_pendingMessages = [];
|
|
1537
|
+
_sendChain = Promise.resolve();
|
|
1538
|
+
constructor(urlOrInit, protocolsOrOptions, maybeOptions) {
|
|
1539
|
+
let init;
|
|
1540
|
+
if (isInternalWebSocketInit(urlOrInit)) {
|
|
1541
|
+
init = urlOrInit;
|
|
1542
|
+
} else {
|
|
1543
|
+
init = _WebSocket.buildStandaloneInit(urlOrInit, protocolsOrOptions, maybeOptions);
|
|
1544
|
+
}
|
|
1545
|
+
this.url = init.url;
|
|
1546
|
+
this.binaryType = init.options.binaryType ?? "nodebuffer";
|
|
1547
|
+
this._legacyCallbacks = init.legacyCallbacks;
|
|
1548
|
+
this._openDispatchMode = init.openDispatchMode;
|
|
1549
|
+
this._connectPromise = this.connect(init.connect);
|
|
1550
|
+
void this._connectPromise.catch(() => void 0);
|
|
1551
|
+
}
|
|
1552
|
+
get binaryType() {
|
|
1553
|
+
return this._binaryType;
|
|
1554
|
+
}
|
|
1555
|
+
set binaryType(value) {
|
|
1556
|
+
if (value === "arraybuffer" || value === "blob" || value === "nodebuffer") {
|
|
1557
|
+
this._binaryType = value;
|
|
1558
|
+
}
|
|
1559
|
+
}
|
|
1560
|
+
get bufferedAmount() {
|
|
1561
|
+
return this._bufferedAmount;
|
|
1562
|
+
}
|
|
1563
|
+
get onopen() {
|
|
1564
|
+
return this._onopen;
|
|
1565
|
+
}
|
|
1566
|
+
set onopen(listener) {
|
|
1567
|
+
this._onopen = listener;
|
|
1568
|
+
this._onHandlerOrder.open = listener ? ++this._listenerOrderCounter : -1;
|
|
1569
|
+
}
|
|
1570
|
+
get onmessage() {
|
|
1571
|
+
return this._onmessage;
|
|
1572
|
+
}
|
|
1573
|
+
set onmessage(listener) {
|
|
1574
|
+
this._onmessage = listener;
|
|
1575
|
+
this._onHandlerOrder.message = listener ? ++this._listenerOrderCounter : -1;
|
|
1576
|
+
}
|
|
1577
|
+
get onclose() {
|
|
1578
|
+
return this._onclose;
|
|
1579
|
+
}
|
|
1580
|
+
set onclose(listener) {
|
|
1581
|
+
this._onclose = listener;
|
|
1582
|
+
this._onHandlerOrder.close = listener ? ++this._listenerOrderCounter : -1;
|
|
1583
|
+
}
|
|
1584
|
+
get onerror() {
|
|
1585
|
+
return this._onerror;
|
|
1586
|
+
}
|
|
1587
|
+
set onerror(listener) {
|
|
1588
|
+
this._onerror = listener;
|
|
1589
|
+
this._onHandlerOrder.error = listener ? ++this._listenerOrderCounter : -1;
|
|
1590
|
+
}
|
|
1591
|
+
static async _connectWithInit(init) {
|
|
1592
|
+
const ws = new _WebSocket(init);
|
|
1593
|
+
await ws._waitUntilConnected();
|
|
1594
|
+
ws.scheduleOpenEventAfterAwait();
|
|
1595
|
+
return ws;
|
|
1596
|
+
}
|
|
1597
|
+
static buildStandaloneInit(url, protocolsOrOptions, maybeOptions) {
|
|
1598
|
+
const optionsCandidate = typeof protocolsOrOptions === "string" || Array.isArray(protocolsOrOptions) ? maybeOptions : protocolsOrOptions ?? maybeOptions;
|
|
1599
|
+
const normalizedOptions = normalizeStandaloneWebSocketOptions(optionsCandidate);
|
|
1600
|
+
validateWebSocketProtocols(
|
|
1601
|
+
typeof protocolsOrOptions === "string" || Array.isArray(protocolsOrOptions) ? protocolsOrOptions : normalizedOptions.protocols
|
|
1602
|
+
);
|
|
1603
|
+
assertNoManualWebSocketProtocolHeader(normalizedOptions.headers);
|
|
1604
|
+
validateBrowserProfile(normalizedOptions.browser);
|
|
1605
|
+
const os = normalizedOptions.os ?? DEFAULT_OS;
|
|
1606
|
+
validateOperatingSystem(os);
|
|
1607
|
+
const browser = normalizedOptions.browser ?? DEFAULT_BROWSER;
|
|
1608
|
+
const protocols = normalizeWebSocketProtocolList(
|
|
1609
|
+
typeof protocolsOrOptions === "string" || Array.isArray(protocolsOrOptions) ? protocolsOrOptions : normalizedOptions.protocols
|
|
1610
|
+
);
|
|
1611
|
+
return {
|
|
1612
|
+
_internal: true,
|
|
1613
|
+
url: normalizeWebSocketUrl(url),
|
|
1614
|
+
options: normalizedOptions,
|
|
1615
|
+
openDispatchMode: "automatic",
|
|
1616
|
+
connect: (callbacks) => nativeBinding.websocketConnect({
|
|
1617
|
+
url: normalizeWebSocketUrl(url),
|
|
1618
|
+
browser,
|
|
1619
|
+
os,
|
|
1620
|
+
headers: headersToTuples(normalizedOptions.headers ?? {}),
|
|
1621
|
+
...protocols && protocols.length > 0 && { protocols },
|
|
1622
|
+
...normalizedOptions.proxy !== void 0 && { proxy: normalizedOptions.proxy },
|
|
1623
|
+
onMessage: callbacks.onMessage,
|
|
1624
|
+
onClose: callbacks.onClose,
|
|
1625
|
+
onError: callbacks.onError
|
|
1626
|
+
}),
|
|
1627
|
+
legacyCallbacks: extractLegacyWebSocketCallbacks(optionsCandidate)
|
|
1628
|
+
};
|
|
1629
|
+
}
|
|
1630
|
+
async connect(connectFn) {
|
|
1283
1631
|
try {
|
|
1284
|
-
await
|
|
1632
|
+
const connection = await connectFn({
|
|
1633
|
+
onMessage: (data) => {
|
|
1634
|
+
this.handleNativeMessage(data);
|
|
1635
|
+
},
|
|
1636
|
+
onClose: (event) => {
|
|
1637
|
+
this.handleNativeClose(event);
|
|
1638
|
+
},
|
|
1639
|
+
onError: (message) => {
|
|
1640
|
+
this.handleNativeError(message);
|
|
1641
|
+
}
|
|
1642
|
+
});
|
|
1643
|
+
this._connection = connection;
|
|
1644
|
+
this.protocol = connection.protocol ?? "";
|
|
1645
|
+
this.extensions = connection.extensions ?? "";
|
|
1646
|
+
if (websocketFinalizer) {
|
|
1647
|
+
this._finalizerToken = connection;
|
|
1648
|
+
websocketFinalizer.register(this, connection, connection);
|
|
1649
|
+
}
|
|
1650
|
+
if (this.readyState === _WebSocket.CLOSING) {
|
|
1651
|
+
this.startNativeClose();
|
|
1652
|
+
return;
|
|
1653
|
+
}
|
|
1654
|
+
this.readyState = _WebSocket.OPEN;
|
|
1655
|
+
if (this._openDispatchMode === "automatic") {
|
|
1656
|
+
this.scheduleOpenEventAfterConnect();
|
|
1657
|
+
}
|
|
1285
1658
|
} catch (error) {
|
|
1659
|
+
this.handleNativeError(String(error));
|
|
1660
|
+
this.finalizeClosed({ code: 1006, reason: "" }, false);
|
|
1286
1661
|
throw new RequestError(String(error));
|
|
1287
1662
|
}
|
|
1288
1663
|
}
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1664
|
+
_waitUntilConnected() {
|
|
1665
|
+
return this._connectPromise;
|
|
1666
|
+
}
|
|
1667
|
+
scheduleOpenEventAfterConnect() {
|
|
1668
|
+
this.scheduleOpenEventWithDepth(2);
|
|
1669
|
+
}
|
|
1670
|
+
scheduleOpenEventAfterAwait() {
|
|
1671
|
+
this.scheduleOpenEventWithDepth(3);
|
|
1672
|
+
}
|
|
1673
|
+
scheduleOpenEventWithDepth(depth) {
|
|
1674
|
+
if (this._openEventDispatched || this._openEventQueued || this.readyState !== _WebSocket.OPEN) {
|
|
1675
|
+
return;
|
|
1676
|
+
}
|
|
1677
|
+
this._openEventQueued = true;
|
|
1678
|
+
const queue = (remaining) => {
|
|
1679
|
+
if (remaining === 0) {
|
|
1680
|
+
this._openEventQueued = false;
|
|
1681
|
+
if (this._openEventDispatched || this.readyState !== _WebSocket.OPEN) {
|
|
1682
|
+
return;
|
|
1683
|
+
}
|
|
1684
|
+
this._openEventDispatched = true;
|
|
1685
|
+
this.dispatchOpenEvent();
|
|
1686
|
+
return;
|
|
1687
|
+
}
|
|
1688
|
+
queueMicrotask(() => {
|
|
1689
|
+
queue(remaining - 1);
|
|
1690
|
+
});
|
|
1691
|
+
};
|
|
1692
|
+
queue(depth);
|
|
1693
|
+
}
|
|
1694
|
+
releaseConnectionTracking() {
|
|
1695
|
+
if (!this._finalizerToken || !websocketFinalizer) {
|
|
1696
|
+
return;
|
|
1697
|
+
}
|
|
1698
|
+
websocketFinalizer.unregister(this._finalizerToken);
|
|
1699
|
+
this._finalizerToken = void 0;
|
|
1700
|
+
}
|
|
1701
|
+
toMessageEventData(data) {
|
|
1702
|
+
if (typeof data === "string") {
|
|
1703
|
+
return data;
|
|
1704
|
+
}
|
|
1705
|
+
if (this._binaryType === "arraybuffer") {
|
|
1706
|
+
const arrayBuffer = new ArrayBuffer(data.byteLength);
|
|
1707
|
+
new Uint8Array(arrayBuffer).set(data);
|
|
1708
|
+
return arrayBuffer;
|
|
1709
|
+
}
|
|
1710
|
+
if (this._binaryType === "blob") {
|
|
1711
|
+
return new Blob([data]);
|
|
1712
|
+
}
|
|
1713
|
+
return data;
|
|
1714
|
+
}
|
|
1715
|
+
invokeListener(listener, event) {
|
|
1716
|
+
try {
|
|
1717
|
+
if (typeof listener === "function") {
|
|
1718
|
+
listener.call(this, event);
|
|
1719
|
+
} else {
|
|
1720
|
+
listener.handleEvent(event);
|
|
1721
|
+
}
|
|
1722
|
+
} catch {
|
|
1723
|
+
}
|
|
1724
|
+
}
|
|
1725
|
+
createBaseEvent(type) {
|
|
1726
|
+
return {
|
|
1727
|
+
type,
|
|
1728
|
+
isTrusted: false,
|
|
1729
|
+
timeStamp: Date.now(),
|
|
1730
|
+
target: this,
|
|
1731
|
+
currentTarget: this
|
|
1732
|
+
};
|
|
1733
|
+
}
|
|
1734
|
+
getOnHandler(type) {
|
|
1735
|
+
switch (type) {
|
|
1736
|
+
case "open":
|
|
1737
|
+
return this._onopen;
|
|
1738
|
+
case "message":
|
|
1739
|
+
return this._onmessage;
|
|
1740
|
+
case "close":
|
|
1741
|
+
return this._onclose;
|
|
1742
|
+
case "error":
|
|
1743
|
+
return this._onerror;
|
|
1744
|
+
default:
|
|
1745
|
+
return null;
|
|
1746
|
+
}
|
|
1747
|
+
}
|
|
1748
|
+
getOnHandlerOrder(type) {
|
|
1749
|
+
return this._onHandlerOrder[type];
|
|
1750
|
+
}
|
|
1751
|
+
getListenerMap(type) {
|
|
1752
|
+
return this._listeners[type];
|
|
1753
|
+
}
|
|
1754
|
+
dispatchEvent(type, event) {
|
|
1755
|
+
const listenerMap = this.getListenerMap(type);
|
|
1756
|
+
const onHandler = this.getOnHandler(type);
|
|
1757
|
+
if (listenerMap.size === 0 && !onHandler) {
|
|
1758
|
+
return;
|
|
1759
|
+
}
|
|
1760
|
+
const ordered = [];
|
|
1761
|
+
for (const descriptor of listenerMap.values()) {
|
|
1762
|
+
ordered.push({
|
|
1763
|
+
order: descriptor.order,
|
|
1764
|
+
listener: descriptor.listener,
|
|
1765
|
+
once: descriptor.once
|
|
1766
|
+
});
|
|
1767
|
+
}
|
|
1768
|
+
if (onHandler) {
|
|
1769
|
+
ordered.push({
|
|
1770
|
+
order: this.getOnHandlerOrder(type),
|
|
1771
|
+
listener: onHandler,
|
|
1772
|
+
once: false
|
|
1773
|
+
});
|
|
1774
|
+
}
|
|
1775
|
+
ordered.sort((a, b) => a.order - b.order);
|
|
1776
|
+
for (const entry of ordered) {
|
|
1777
|
+
if (entry.once) {
|
|
1778
|
+
this.removeEventListener(type, entry.listener);
|
|
1779
|
+
}
|
|
1780
|
+
this.invokeListener(entry.listener, event);
|
|
1781
|
+
}
|
|
1782
|
+
}
|
|
1783
|
+
dispatchOpenEvent() {
|
|
1784
|
+
const event = this.createBaseEvent("open");
|
|
1785
|
+
this.dispatchEvent("open", event);
|
|
1786
|
+
if (!this._closeEventDispatched && this._pendingMessages.length > 0) {
|
|
1787
|
+
const pending = this._pendingMessages;
|
|
1788
|
+
this._pendingMessages = [];
|
|
1789
|
+
for (const data of pending) {
|
|
1790
|
+
this.dispatchMessageEvent(this.toMessageEventData(data));
|
|
1791
|
+
}
|
|
1792
|
+
}
|
|
1793
|
+
}
|
|
1794
|
+
dispatchMessageEvent(data) {
|
|
1795
|
+
const event = {
|
|
1796
|
+
...this.createBaseEvent("message"),
|
|
1797
|
+
data
|
|
1798
|
+
};
|
|
1799
|
+
this.dispatchEvent("message", event);
|
|
1800
|
+
}
|
|
1801
|
+
dispatchCloseEvent(event) {
|
|
1802
|
+
this.dispatchEvent("close", event);
|
|
1803
|
+
}
|
|
1804
|
+
dispatchErrorEvent(message) {
|
|
1805
|
+
const event = {
|
|
1806
|
+
...this.createBaseEvent("error"),
|
|
1807
|
+
...message !== void 0 && { message }
|
|
1808
|
+
};
|
|
1809
|
+
this.dispatchEvent("error", event);
|
|
1810
|
+
}
|
|
1811
|
+
handleNativeMessage(data) {
|
|
1812
|
+
if (this._closeEventDispatched) {
|
|
1813
|
+
return;
|
|
1814
|
+
}
|
|
1815
|
+
this._legacyCallbacks?.onMessage?.(data);
|
|
1816
|
+
if (!this._openEventDispatched && this.readyState === _WebSocket.OPEN) {
|
|
1817
|
+
this._pendingMessages.push(data);
|
|
1818
|
+
return;
|
|
1819
|
+
}
|
|
1820
|
+
this.dispatchMessageEvent(this.toMessageEventData(data));
|
|
1821
|
+
}
|
|
1822
|
+
handleNativeError(message) {
|
|
1823
|
+
this._legacyCallbacks?.onError?.(message);
|
|
1824
|
+
this.dispatchErrorEvent(message);
|
|
1825
|
+
}
|
|
1826
|
+
handleNativeClose(event) {
|
|
1827
|
+
const wasClean = this.readyState === _WebSocket.CLOSING || event.code === 1e3;
|
|
1828
|
+
this.finalizeClosed(event, wasClean);
|
|
1829
|
+
}
|
|
1830
|
+
finalizeClosed(event, wasClean) {
|
|
1831
|
+
if (this._closeEventDispatched) {
|
|
1832
|
+
return;
|
|
1833
|
+
}
|
|
1834
|
+
this.readyState = _WebSocket.CLOSED;
|
|
1835
|
+
this._closeEventDispatched = true;
|
|
1836
|
+
this._pendingMessages = [];
|
|
1837
|
+
this.releaseConnectionTracking();
|
|
1838
|
+
const closeEvent = {
|
|
1839
|
+
...this.createBaseEvent("close"),
|
|
1840
|
+
code: event.code,
|
|
1841
|
+
reason: event.reason,
|
|
1842
|
+
wasClean
|
|
1843
|
+
};
|
|
1844
|
+
this._legacyCallbacks?.onClose?.(closeEvent);
|
|
1845
|
+
this.dispatchCloseEvent(closeEvent);
|
|
1846
|
+
}
|
|
1847
|
+
startNativeClose() {
|
|
1848
|
+
if (this._nativeCloseStarted || !this._connection) {
|
|
1294
1849
|
return;
|
|
1295
1850
|
}
|
|
1296
|
-
|
|
1297
|
-
|
|
1851
|
+
this._nativeCloseStarted = true;
|
|
1852
|
+
const connection = this._connection;
|
|
1853
|
+
const closeOptions = this._closeOptions;
|
|
1854
|
+
void nativeBinding.websocketClose(connection, closeOptions).catch((error) => {
|
|
1855
|
+
this.handleNativeError(String(error));
|
|
1856
|
+
this.finalizeClosed({ code: 1006, reason: "" }, false);
|
|
1857
|
+
});
|
|
1858
|
+
}
|
|
1859
|
+
addEventListener(type, listener, options) {
|
|
1860
|
+
if (!listener || !isWebSocketListenerType(type)) {
|
|
1861
|
+
return;
|
|
1862
|
+
}
|
|
1863
|
+
const normalizedListener = listener;
|
|
1864
|
+
if (typeof normalizedListener !== "function" && (typeof normalizedListener !== "object" || normalizedListener === null || typeof normalizedListener.handleEvent !== "function")) {
|
|
1865
|
+
return;
|
|
1866
|
+
}
|
|
1867
|
+
const listenerMap = this.getListenerMap(type);
|
|
1868
|
+
if (listenerMap.has(normalizedListener)) {
|
|
1869
|
+
return;
|
|
1870
|
+
}
|
|
1871
|
+
const parsedOptions = typeof options === "boolean" ? {} : options ?? {};
|
|
1872
|
+
const once = parsedOptions.once === true;
|
|
1873
|
+
const signal = parsedOptions.signal;
|
|
1874
|
+
if (signal?.aborted) {
|
|
1875
|
+
return;
|
|
1876
|
+
}
|
|
1877
|
+
const descriptor = {
|
|
1878
|
+
listener: normalizedListener,
|
|
1879
|
+
order: ++this._listenerOrderCounter,
|
|
1880
|
+
once
|
|
1881
|
+
};
|
|
1882
|
+
if (signal) {
|
|
1883
|
+
const onAbort = () => {
|
|
1884
|
+
this.removeEventListener(type, normalizedListener);
|
|
1885
|
+
};
|
|
1886
|
+
descriptor.abortSignal = signal;
|
|
1887
|
+
descriptor.abortHandler = onAbort;
|
|
1888
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
1889
|
+
}
|
|
1890
|
+
listenerMap.set(normalizedListener, descriptor);
|
|
1891
|
+
}
|
|
1892
|
+
removeEventListener(type, listener) {
|
|
1893
|
+
if (!listener || !isWebSocketListenerType(type)) {
|
|
1894
|
+
return;
|
|
1895
|
+
}
|
|
1896
|
+
const normalizedListener = listener;
|
|
1897
|
+
if (typeof normalizedListener !== "function" && typeof normalizedListener !== "object") {
|
|
1898
|
+
return;
|
|
1899
|
+
}
|
|
1900
|
+
const listenerMap = this.getListenerMap(type);
|
|
1901
|
+
const descriptor = listenerMap.get(normalizedListener);
|
|
1902
|
+
if (!descriptor) {
|
|
1903
|
+
return;
|
|
1904
|
+
}
|
|
1905
|
+
if (descriptor.abortSignal && descriptor.abortHandler) {
|
|
1906
|
+
descriptor.abortSignal.removeEventListener("abort", descriptor.abortHandler);
|
|
1907
|
+
}
|
|
1908
|
+
listenerMap.delete(normalizedListener);
|
|
1909
|
+
}
|
|
1910
|
+
getSendByteLength(data) {
|
|
1911
|
+
if (typeof data === "string") {
|
|
1912
|
+
return Buffer.byteLength(data);
|
|
1913
|
+
}
|
|
1914
|
+
if (Buffer.isBuffer(data)) {
|
|
1915
|
+
return data.byteLength;
|
|
1916
|
+
}
|
|
1917
|
+
if (data instanceof ArrayBuffer) {
|
|
1918
|
+
return data.byteLength;
|
|
1919
|
+
}
|
|
1920
|
+
if (ArrayBuffer.isView(data)) {
|
|
1921
|
+
return data.byteLength;
|
|
1922
|
+
}
|
|
1923
|
+
if (typeof Blob !== "undefined" && data instanceof Blob) {
|
|
1924
|
+
return data.size;
|
|
1298
1925
|
}
|
|
1299
|
-
|
|
1926
|
+
throw new TypeError("WebSocket data must be a string, Buffer, ArrayBuffer, ArrayBufferView, or Blob");
|
|
1927
|
+
}
|
|
1928
|
+
async normalizeSendPayload(data) {
|
|
1929
|
+
if (typeof data === "string") {
|
|
1930
|
+
return data;
|
|
1931
|
+
}
|
|
1932
|
+
if (Buffer.isBuffer(data)) {
|
|
1933
|
+
return data;
|
|
1934
|
+
}
|
|
1935
|
+
if (data instanceof ArrayBuffer) {
|
|
1936
|
+
return Buffer.from(data);
|
|
1937
|
+
}
|
|
1938
|
+
if (ArrayBuffer.isView(data)) {
|
|
1939
|
+
return Buffer.from(data.buffer, data.byteOffset, data.byteLength);
|
|
1940
|
+
}
|
|
1941
|
+
if (typeof Blob !== "undefined" && data instanceof Blob) {
|
|
1942
|
+
return Buffer.from(await data.arrayBuffer());
|
|
1943
|
+
}
|
|
1944
|
+
throw new TypeError("WebSocket data must be a string, Buffer, ArrayBuffer, ArrayBufferView, or Blob");
|
|
1945
|
+
}
|
|
1946
|
+
send(data) {
|
|
1947
|
+
if (this.readyState !== _WebSocket.OPEN || !this._connection) {
|
|
1948
|
+
throw new RequestError("WebSocket is not open");
|
|
1949
|
+
}
|
|
1950
|
+
const queuedBytes = this.getSendByteLength(data);
|
|
1951
|
+
const connection = this._connection;
|
|
1952
|
+
this._bufferedAmount += queuedBytes;
|
|
1953
|
+
const sendTask = async () => {
|
|
1300
1954
|
try {
|
|
1301
|
-
await
|
|
1302
|
-
|
|
1303
|
-
if (this._finalizerToken && websocketFinalizer) {
|
|
1304
|
-
websocketFinalizer.unregister(this._finalizerToken);
|
|
1305
|
-
this._finalizerToken = void 0;
|
|
1306
|
-
}
|
|
1955
|
+
const payload = await this.normalizeSendPayload(data);
|
|
1956
|
+
await nativeBinding.websocketSend(connection, payload);
|
|
1307
1957
|
} catch (error) {
|
|
1308
|
-
|
|
1958
|
+
this.handleNativeError(String(error));
|
|
1959
|
+
this.finalizeClosed({ code: 1006, reason: "" }, false);
|
|
1309
1960
|
} finally {
|
|
1310
|
-
this.
|
|
1961
|
+
this._bufferedAmount = Math.max(0, this._bufferedAmount - queuedBytes);
|
|
1311
1962
|
}
|
|
1312
|
-
}
|
|
1313
|
-
|
|
1963
|
+
};
|
|
1964
|
+
this._sendChain = this._sendChain.then(sendTask, sendTask);
|
|
1965
|
+
}
|
|
1966
|
+
close(code, reason) {
|
|
1967
|
+
if (this.readyState === _WebSocket.CLOSING || this.readyState === _WebSocket.CLOSED) {
|
|
1968
|
+
return;
|
|
1969
|
+
}
|
|
1970
|
+
this._closeOptions = normalizeWebSocketCloseOptions(code, reason);
|
|
1971
|
+
this.readyState = _WebSocket.CLOSING;
|
|
1972
|
+
this.startNativeClose();
|
|
1314
1973
|
}
|
|
1315
1974
|
};
|
|
1316
|
-
|
|
1317
|
-
if (!
|
|
1318
|
-
|
|
1975
|
+
function isInternalWebSocketInit(value) {
|
|
1976
|
+
if (!isPlainObject(value)) {
|
|
1977
|
+
return false;
|
|
1319
1978
|
}
|
|
1320
|
-
|
|
1321
|
-
|
|
1979
|
+
const candidate = value;
|
|
1980
|
+
return candidate._internal === true && typeof candidate.url === "string" && typeof candidate.connect === "function";
|
|
1981
|
+
}
|
|
1982
|
+
function normalizeStandaloneWebSocketArgs(urlOrOptions, options) {
|
|
1983
|
+
if (typeof urlOrOptions === "string" || urlOrOptions instanceof URL) {
|
|
1984
|
+
const normalizedOptions2 = normalizeStandaloneWebSocketOptions(options);
|
|
1985
|
+
return {
|
|
1986
|
+
url: normalizeWebSocketUrl(urlOrOptions),
|
|
1987
|
+
options: normalizedOptions2,
|
|
1988
|
+
legacyCallbacks: extractLegacyWebSocketCallbacks(options)
|
|
1989
|
+
};
|
|
1322
1990
|
}
|
|
1323
|
-
|
|
1324
|
-
const
|
|
1991
|
+
const legacy = urlOrOptions;
|
|
1992
|
+
const normalizedOptions = normalizeStandaloneWebSocketOptions(legacy);
|
|
1993
|
+
return {
|
|
1994
|
+
url: normalizeWebSocketUrl(legacy.url),
|
|
1995
|
+
options: normalizedOptions,
|
|
1996
|
+
legacyCallbacks: extractLegacyWebSocketCallbacks(legacy)
|
|
1997
|
+
};
|
|
1998
|
+
}
|
|
1999
|
+
function normalizeSessionWebSocketArgs(urlOrOptions, options) {
|
|
2000
|
+
if (typeof urlOrOptions === "string" || urlOrOptions instanceof URL) {
|
|
2001
|
+
const normalizedOptions2 = normalizeSessionWebSocketOptions(options);
|
|
2002
|
+
return {
|
|
2003
|
+
url: normalizeWebSocketUrl(urlOrOptions),
|
|
2004
|
+
options: normalizedOptions2,
|
|
2005
|
+
legacyCallbacks: extractLegacyWebSocketCallbacks(options)
|
|
2006
|
+
};
|
|
2007
|
+
}
|
|
2008
|
+
const legacy = urlOrOptions;
|
|
2009
|
+
const normalizedOptions = normalizeSessionWebSocketOptions(legacy);
|
|
2010
|
+
return {
|
|
2011
|
+
url: normalizeWebSocketUrl(legacy.url),
|
|
2012
|
+
options: normalizedOptions,
|
|
2013
|
+
legacyCallbacks: extractLegacyWebSocketCallbacks(legacy)
|
|
2014
|
+
};
|
|
2015
|
+
}
|
|
2016
|
+
async function websocket(urlOrOptions, options) {
|
|
2017
|
+
const normalized = normalizeStandaloneWebSocketArgs(urlOrOptions, options);
|
|
2018
|
+
validateWebSocketProtocols(normalized.options.protocols);
|
|
2019
|
+
assertNoManualWebSocketProtocolHeader(normalized.options.headers);
|
|
2020
|
+
validateBrowserProfile(normalized.options.browser);
|
|
2021
|
+
const os = normalized.options.os ?? DEFAULT_OS;
|
|
1325
2022
|
validateOperatingSystem(os);
|
|
1326
|
-
const browser = options.browser ?? DEFAULT_BROWSER;
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
2023
|
+
const browser = normalized.options.browser ?? DEFAULT_BROWSER;
|
|
2024
|
+
const protocols = normalizeWebSocketProtocolList(normalized.options.protocols);
|
|
2025
|
+
return WebSocket._connectWithInit({
|
|
2026
|
+
_internal: true,
|
|
2027
|
+
url: normalized.url,
|
|
2028
|
+
options: normalized.options,
|
|
2029
|
+
openDispatchMode: "deferred",
|
|
2030
|
+
connect: (callbacks) => nativeBinding.websocketConnect({
|
|
2031
|
+
url: normalized.url,
|
|
1330
2032
|
browser,
|
|
1331
2033
|
os,
|
|
1332
|
-
headers: options.headers ?? {},
|
|
1333
|
-
...
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
}
|
|
2034
|
+
headers: headersToTuples(normalized.options.headers ?? {}),
|
|
2035
|
+
...protocols && protocols.length > 0 && { protocols },
|
|
2036
|
+
...normalized.options.proxy !== void 0 && { proxy: normalized.options.proxy },
|
|
2037
|
+
onMessage: callbacks.onMessage,
|
|
2038
|
+
onClose: callbacks.onClose,
|
|
2039
|
+
onError: callbacks.onError
|
|
2040
|
+
}),
|
|
2041
|
+
legacyCallbacks: normalized.legacyCallbacks
|
|
2042
|
+
});
|
|
1342
2043
|
}
|
|
1343
2044
|
var wreq_js_default = {
|
|
1344
2045
|
fetch,
|
|
@@ -1355,7 +2056,8 @@ var wreq_js_default = {
|
|
|
1355
2056
|
Headers,
|
|
1356
2057
|
Response,
|
|
1357
2058
|
Transport,
|
|
1358
|
-
Session
|
|
2059
|
+
Session,
|
|
2060
|
+
RequestError
|
|
1359
2061
|
};
|
|
1360
2062
|
export {
|
|
1361
2063
|
Headers,
|