@nanolink/mirrors 1.0.9 → 1.0.11
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/DelegateMap.js +42 -37
- package/dist/DelegateMap.js.map +1 -1
- package/dist/MirrorSync.js +162 -110
- package/dist/MirrorSync.js.map +1 -1
- package/dist/SubscriptionClient.js +176 -109
- package/dist/SubscriptionClient.js.map +1 -1
- package/dist/index.js +115 -45
- package/dist/index.js.map +1 -1
- package/dist-compat/index.js +730 -13
- package/dist-compat/index.js.map +1 -1
- package/package.json +32 -11
package/dist-compat/index.js
CHANGED
|
@@ -7,6 +7,7 @@ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
|
7
7
|
var __getProtoOf = Object.getPrototypeOf;
|
|
8
8
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
9
|
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
10
|
+
var __knownSymbol = (name, symbol) => (symbol = Symbol[name]) ? symbol : Symbol.for("Symbol." + name);
|
|
10
11
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
11
12
|
var __spreadValues = (a, b) => {
|
|
12
13
|
for (var prop in b || (b = {}))
|
|
@@ -40,6 +41,22 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
40
41
|
mod
|
|
41
42
|
));
|
|
42
43
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
44
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
45
|
+
var __await = function(promise, isYieldStar) {
|
|
46
|
+
this[0] = promise;
|
|
47
|
+
this[1] = isYieldStar;
|
|
48
|
+
};
|
|
49
|
+
var __asyncGenerator = (__this, __arguments, generator) => {
|
|
50
|
+
var resume = (k, v, yes, no) => {
|
|
51
|
+
try {
|
|
52
|
+
var x = generator[k](v), isAwait = (v = x.value) instanceof __await, done = x.done;
|
|
53
|
+
Promise.resolve(isAwait ? v[0] : v).then((y) => isAwait ? resume(k === "return" ? k : "next", v[1] ? { done: y.done, value: y.value } : y, yes, no) : yes({ value: y, done })).catch((e) => resume("throw", e, yes, no));
|
|
54
|
+
} catch (e) {
|
|
55
|
+
no(e);
|
|
56
|
+
}
|
|
57
|
+
}, method = (k) => it[k] = (x) => new Promise((yes, no) => resume(k, x, yes, no)), it = {};
|
|
58
|
+
return generator = generator.apply(__this, __arguments), it[__knownSymbol("asyncIterator")] = () => it, method("next"), method("throw"), method("return"), it;
|
|
59
|
+
};
|
|
43
60
|
|
|
44
61
|
// src/index.ts
|
|
45
62
|
var index_exports = {};
|
|
@@ -340,8 +357,702 @@ var MirrorSync = class extends import_eventemitter3.default {
|
|
|
340
357
|
}
|
|
341
358
|
};
|
|
342
359
|
|
|
360
|
+
// node_modules/graphql-ws/dist/common-CGW11Fyb.js
|
|
361
|
+
function extendedTypeof(val) {
|
|
362
|
+
if (val === null) {
|
|
363
|
+
return "null";
|
|
364
|
+
}
|
|
365
|
+
if (Array.isArray(val)) {
|
|
366
|
+
return "array";
|
|
367
|
+
}
|
|
368
|
+
return typeof val;
|
|
369
|
+
}
|
|
370
|
+
function isObject(val) {
|
|
371
|
+
return extendedTypeof(val) === "object";
|
|
372
|
+
}
|
|
373
|
+
function areGraphQLFormattedErrors(obj) {
|
|
374
|
+
return Array.isArray(obj) && // must be at least one error
|
|
375
|
+
obj.length > 0 && // error has at least a message
|
|
376
|
+
obj.every((ob) => "message" in ob);
|
|
377
|
+
}
|
|
378
|
+
function limitCloseReason(reason, whenTooLong) {
|
|
379
|
+
return reason.length < 124 ? reason : whenTooLong;
|
|
380
|
+
}
|
|
381
|
+
var GRAPHQL_TRANSPORT_WS_PROTOCOL = "graphql-transport-ws";
|
|
382
|
+
var CloseCode = /* @__PURE__ */ ((CloseCode2) => {
|
|
383
|
+
CloseCode2[CloseCode2["InternalServerError"] = 4500] = "InternalServerError";
|
|
384
|
+
CloseCode2[CloseCode2["InternalClientError"] = 4005] = "InternalClientError";
|
|
385
|
+
CloseCode2[CloseCode2["BadRequest"] = 4400] = "BadRequest";
|
|
386
|
+
CloseCode2[CloseCode2["BadResponse"] = 4004] = "BadResponse";
|
|
387
|
+
CloseCode2[CloseCode2["Unauthorized"] = 4401] = "Unauthorized";
|
|
388
|
+
CloseCode2[CloseCode2["Forbidden"] = 4403] = "Forbidden";
|
|
389
|
+
CloseCode2[CloseCode2["SubprotocolNotAcceptable"] = 4406] = "SubprotocolNotAcceptable";
|
|
390
|
+
CloseCode2[CloseCode2["ConnectionInitialisationTimeout"] = 4408] = "ConnectionInitialisationTimeout";
|
|
391
|
+
CloseCode2[CloseCode2["ConnectionAcknowledgementTimeout"] = 4504] = "ConnectionAcknowledgementTimeout";
|
|
392
|
+
CloseCode2[CloseCode2["SubscriberAlreadyExists"] = 4409] = "SubscriberAlreadyExists";
|
|
393
|
+
CloseCode2[CloseCode2["TooManyInitialisationRequests"] = 4429] = "TooManyInitialisationRequests";
|
|
394
|
+
return CloseCode2;
|
|
395
|
+
})(CloseCode || {});
|
|
396
|
+
var MessageType = /* @__PURE__ */ ((MessageType2) => {
|
|
397
|
+
MessageType2["ConnectionInit"] = "connection_init";
|
|
398
|
+
MessageType2["ConnectionAck"] = "connection_ack";
|
|
399
|
+
MessageType2["Ping"] = "ping";
|
|
400
|
+
MessageType2["Pong"] = "pong";
|
|
401
|
+
MessageType2["Subscribe"] = "subscribe";
|
|
402
|
+
MessageType2["Next"] = "next";
|
|
403
|
+
MessageType2["Error"] = "error";
|
|
404
|
+
MessageType2["Complete"] = "complete";
|
|
405
|
+
return MessageType2;
|
|
406
|
+
})(MessageType || {});
|
|
407
|
+
function validateMessage(val) {
|
|
408
|
+
if (!isObject(val)) {
|
|
409
|
+
throw new Error(
|
|
410
|
+
`Message is expected to be an object, but got ${extendedTypeof(val)}`
|
|
411
|
+
);
|
|
412
|
+
}
|
|
413
|
+
if (!val.type) {
|
|
414
|
+
throw new Error(`Message is missing the 'type' property`);
|
|
415
|
+
}
|
|
416
|
+
if (typeof val.type !== "string") {
|
|
417
|
+
throw new Error(
|
|
418
|
+
`Message is expects the 'type' property to be a string, but got ${extendedTypeof(
|
|
419
|
+
val.type
|
|
420
|
+
)}`
|
|
421
|
+
);
|
|
422
|
+
}
|
|
423
|
+
switch (val.type) {
|
|
424
|
+
case "connection_init":
|
|
425
|
+
case "connection_ack":
|
|
426
|
+
case "ping":
|
|
427
|
+
case "pong": {
|
|
428
|
+
if (val.payload != null && !isObject(val.payload)) {
|
|
429
|
+
throw new Error(
|
|
430
|
+
`"${val.type}" message expects the 'payload' property to be an object or nullish or missing, but got "${val.payload}"`
|
|
431
|
+
);
|
|
432
|
+
}
|
|
433
|
+
break;
|
|
434
|
+
}
|
|
435
|
+
case "subscribe": {
|
|
436
|
+
if (typeof val.id !== "string") {
|
|
437
|
+
throw new Error(
|
|
438
|
+
`"${val.type}" message expects the 'id' property to be a string, but got ${extendedTypeof(
|
|
439
|
+
val.id
|
|
440
|
+
)}`
|
|
441
|
+
);
|
|
442
|
+
}
|
|
443
|
+
if (!val.id) {
|
|
444
|
+
throw new Error(
|
|
445
|
+
`"${val.type}" message requires a non-empty 'id' property`
|
|
446
|
+
);
|
|
447
|
+
}
|
|
448
|
+
if (!isObject(val.payload)) {
|
|
449
|
+
throw new Error(
|
|
450
|
+
`"${val.type}" message expects the 'payload' property to be an object, but got ${extendedTypeof(
|
|
451
|
+
val.payload
|
|
452
|
+
)}`
|
|
453
|
+
);
|
|
454
|
+
}
|
|
455
|
+
if (typeof val.payload.query !== "string") {
|
|
456
|
+
throw new Error(
|
|
457
|
+
`"${val.type}" message payload expects the 'query' property to be a string, but got ${extendedTypeof(
|
|
458
|
+
val.payload.query
|
|
459
|
+
)}`
|
|
460
|
+
);
|
|
461
|
+
}
|
|
462
|
+
if (val.payload.variables != null && !isObject(val.payload.variables)) {
|
|
463
|
+
throw new Error(
|
|
464
|
+
`"${val.type}" message payload expects the 'variables' property to be a an object or nullish or missing, but got ${extendedTypeof(
|
|
465
|
+
val.payload.variables
|
|
466
|
+
)}`
|
|
467
|
+
);
|
|
468
|
+
}
|
|
469
|
+
if (val.payload.operationName != null && extendedTypeof(val.payload.operationName) !== "string") {
|
|
470
|
+
throw new Error(
|
|
471
|
+
`"${val.type}" message payload expects the 'operationName' property to be a string or nullish or missing, but got ${extendedTypeof(
|
|
472
|
+
val.payload.operationName
|
|
473
|
+
)}`
|
|
474
|
+
);
|
|
475
|
+
}
|
|
476
|
+
if (val.payload.extensions != null && !isObject(val.payload.extensions)) {
|
|
477
|
+
throw new Error(
|
|
478
|
+
`"${val.type}" message payload expects the 'extensions' property to be a an object or nullish or missing, but got ${extendedTypeof(
|
|
479
|
+
val.payload.extensions
|
|
480
|
+
)}`
|
|
481
|
+
);
|
|
482
|
+
}
|
|
483
|
+
break;
|
|
484
|
+
}
|
|
485
|
+
case "next": {
|
|
486
|
+
if (typeof val.id !== "string") {
|
|
487
|
+
throw new Error(
|
|
488
|
+
`"${val.type}" message expects the 'id' property to be a string, but got ${extendedTypeof(
|
|
489
|
+
val.id
|
|
490
|
+
)}`
|
|
491
|
+
);
|
|
492
|
+
}
|
|
493
|
+
if (!val.id) {
|
|
494
|
+
throw new Error(
|
|
495
|
+
`"${val.type}" message requires a non-empty 'id' property`
|
|
496
|
+
);
|
|
497
|
+
}
|
|
498
|
+
if (!isObject(val.payload)) {
|
|
499
|
+
throw new Error(
|
|
500
|
+
`"${val.type}" message expects the 'payload' property to be an object, but got ${extendedTypeof(
|
|
501
|
+
val.payload
|
|
502
|
+
)}`
|
|
503
|
+
);
|
|
504
|
+
}
|
|
505
|
+
break;
|
|
506
|
+
}
|
|
507
|
+
case "error": {
|
|
508
|
+
if (typeof val.id !== "string") {
|
|
509
|
+
throw new Error(
|
|
510
|
+
`"${val.type}" message expects the 'id' property to be a string, but got ${extendedTypeof(
|
|
511
|
+
val.id
|
|
512
|
+
)}`
|
|
513
|
+
);
|
|
514
|
+
}
|
|
515
|
+
if (!val.id) {
|
|
516
|
+
throw new Error(
|
|
517
|
+
`"${val.type}" message requires a non-empty 'id' property`
|
|
518
|
+
);
|
|
519
|
+
}
|
|
520
|
+
if (!areGraphQLFormattedErrors(val.payload)) {
|
|
521
|
+
throw new Error(
|
|
522
|
+
`"${val.type}" message expects the 'payload' property to be an array of GraphQL errors, but got ${JSON.stringify(
|
|
523
|
+
val.payload
|
|
524
|
+
)}`
|
|
525
|
+
);
|
|
526
|
+
}
|
|
527
|
+
break;
|
|
528
|
+
}
|
|
529
|
+
case "complete": {
|
|
530
|
+
if (typeof val.id !== "string") {
|
|
531
|
+
throw new Error(
|
|
532
|
+
`"${val.type}" message expects the 'id' property to be a string, but got ${extendedTypeof(
|
|
533
|
+
val.id
|
|
534
|
+
)}`
|
|
535
|
+
);
|
|
536
|
+
}
|
|
537
|
+
if (!val.id) {
|
|
538
|
+
throw new Error(
|
|
539
|
+
`"${val.type}" message requires a non-empty 'id' property`
|
|
540
|
+
);
|
|
541
|
+
}
|
|
542
|
+
break;
|
|
543
|
+
}
|
|
544
|
+
default:
|
|
545
|
+
throw new Error(`Invalid message 'type' property "${val.type}"`);
|
|
546
|
+
}
|
|
547
|
+
return val;
|
|
548
|
+
}
|
|
549
|
+
function parseMessage(data, reviver) {
|
|
550
|
+
return validateMessage(
|
|
551
|
+
typeof data === "string" ? JSON.parse(data, reviver) : data
|
|
552
|
+
);
|
|
553
|
+
}
|
|
554
|
+
function stringifyMessage(msg, replacer) {
|
|
555
|
+
validateMessage(msg);
|
|
556
|
+
return JSON.stringify(msg, replacer);
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
// node_modules/graphql-ws/dist/client.js
|
|
560
|
+
function createClient(options) {
|
|
561
|
+
const {
|
|
562
|
+
url,
|
|
563
|
+
connectionParams,
|
|
564
|
+
lazy = true,
|
|
565
|
+
onNonLazyError = console.error,
|
|
566
|
+
lazyCloseTimeout: lazyCloseTimeoutMs = 0,
|
|
567
|
+
keepAlive = 0,
|
|
568
|
+
disablePong,
|
|
569
|
+
connectionAckWaitTimeout = 0,
|
|
570
|
+
retryAttempts = 5,
|
|
571
|
+
retryWait = async function randomisedExponentialBackoff(retries2) {
|
|
572
|
+
const retryDelaySeconds = Math.pow(2, retries2);
|
|
573
|
+
await new Promise(
|
|
574
|
+
(resolve) => setTimeout(
|
|
575
|
+
resolve,
|
|
576
|
+
retryDelaySeconds * 1e3 + // add random timeout from 300ms to 3s
|
|
577
|
+
Math.floor(Math.random() * (3e3 - 300) + 300)
|
|
578
|
+
)
|
|
579
|
+
);
|
|
580
|
+
},
|
|
581
|
+
shouldRetry = isLikeCloseEvent,
|
|
582
|
+
on,
|
|
583
|
+
webSocketImpl,
|
|
584
|
+
/**
|
|
585
|
+
* Generates a v4 UUID to be used as the ID using `Math`
|
|
586
|
+
* as the random number generator. Supply your own generator
|
|
587
|
+
* in case you need more uniqueness.
|
|
588
|
+
*
|
|
589
|
+
* Reference: https://gist.github.com/jed/982883
|
|
590
|
+
*/
|
|
591
|
+
generateID = function generateUUID() {
|
|
592
|
+
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
|
|
593
|
+
const r = Math.random() * 16 | 0, v = c == "x" ? r : r & 3 | 8;
|
|
594
|
+
return v.toString(16);
|
|
595
|
+
});
|
|
596
|
+
},
|
|
597
|
+
jsonMessageReplacer: replacer,
|
|
598
|
+
jsonMessageReviver: reviver
|
|
599
|
+
} = options;
|
|
600
|
+
let ws;
|
|
601
|
+
if (webSocketImpl) {
|
|
602
|
+
if (!isWebSocket(webSocketImpl)) {
|
|
603
|
+
throw new Error("Invalid WebSocket implementation provided");
|
|
604
|
+
}
|
|
605
|
+
ws = webSocketImpl;
|
|
606
|
+
} else if (typeof WebSocket !== "undefined") {
|
|
607
|
+
ws = WebSocket;
|
|
608
|
+
} else if (typeof global !== "undefined") {
|
|
609
|
+
ws = global.WebSocket || // @ts-expect-error: Support more browsers
|
|
610
|
+
global.MozWebSocket;
|
|
611
|
+
} else if (typeof window !== "undefined") {
|
|
612
|
+
ws = window.WebSocket || // @ts-expect-error: Support more browsers
|
|
613
|
+
window.MozWebSocket;
|
|
614
|
+
}
|
|
615
|
+
if (!ws)
|
|
616
|
+
throw new Error(
|
|
617
|
+
"WebSocket implementation missing; on Node you can `import WebSocket from 'ws';` and pass `webSocketImpl: WebSocket` to `createClient`"
|
|
618
|
+
);
|
|
619
|
+
const WebSocketImpl = ws;
|
|
620
|
+
const emitter = (() => {
|
|
621
|
+
const message = /* @__PURE__ */ (() => {
|
|
622
|
+
const listeners2 = {};
|
|
623
|
+
return {
|
|
624
|
+
on(id, listener) {
|
|
625
|
+
listeners2[id] = listener;
|
|
626
|
+
return () => {
|
|
627
|
+
delete listeners2[id];
|
|
628
|
+
};
|
|
629
|
+
},
|
|
630
|
+
emit(message2) {
|
|
631
|
+
var _a;
|
|
632
|
+
if ("id" in message2) (_a = listeners2[message2.id]) == null ? void 0 : _a.call(listeners2, message2);
|
|
633
|
+
}
|
|
634
|
+
};
|
|
635
|
+
})();
|
|
636
|
+
const listeners = {
|
|
637
|
+
connecting: (on == null ? void 0 : on.connecting) ? [on.connecting] : [],
|
|
638
|
+
opened: (on == null ? void 0 : on.opened) ? [on.opened] : [],
|
|
639
|
+
connected: (on == null ? void 0 : on.connected) ? [on.connected] : [],
|
|
640
|
+
ping: (on == null ? void 0 : on.ping) ? [on.ping] : [],
|
|
641
|
+
pong: (on == null ? void 0 : on.pong) ? [on.pong] : [],
|
|
642
|
+
message: (on == null ? void 0 : on.message) ? [message.emit, on.message] : [message.emit],
|
|
643
|
+
closed: (on == null ? void 0 : on.closed) ? [on.closed] : [],
|
|
644
|
+
error: (on == null ? void 0 : on.error) ? [on.error] : []
|
|
645
|
+
};
|
|
646
|
+
return {
|
|
647
|
+
onMessage: message.on,
|
|
648
|
+
on(event, listener) {
|
|
649
|
+
const l = listeners[event];
|
|
650
|
+
l.push(listener);
|
|
651
|
+
return () => {
|
|
652
|
+
l.splice(l.indexOf(listener), 1);
|
|
653
|
+
};
|
|
654
|
+
},
|
|
655
|
+
emit(event, ...args) {
|
|
656
|
+
for (const listener of [...listeners[event]]) {
|
|
657
|
+
listener(...args);
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
};
|
|
661
|
+
})();
|
|
662
|
+
function errorOrClosed(cb) {
|
|
663
|
+
const listening = [
|
|
664
|
+
// errors are fatal and more critical than close events, throw them first
|
|
665
|
+
emitter.on("error", (err) => {
|
|
666
|
+
listening.forEach((unlisten) => unlisten());
|
|
667
|
+
cb(err);
|
|
668
|
+
}),
|
|
669
|
+
// closes can be graceful and not fatal, throw them second (if error didnt throw)
|
|
670
|
+
emitter.on("closed", (event) => {
|
|
671
|
+
listening.forEach((unlisten) => unlisten());
|
|
672
|
+
cb(event);
|
|
673
|
+
})
|
|
674
|
+
];
|
|
675
|
+
}
|
|
676
|
+
let connecting, locks = 0, lazyCloseTimeout, retrying = false, retries = 0, disposed = false;
|
|
677
|
+
async function connect() {
|
|
678
|
+
clearTimeout(lazyCloseTimeout);
|
|
679
|
+
const [socket, throwOnClose] = await (connecting != null ? connecting : connecting = new Promise(
|
|
680
|
+
(connected, denied) => (async () => {
|
|
681
|
+
if (retrying) {
|
|
682
|
+
await retryWait(retries);
|
|
683
|
+
if (!locks) {
|
|
684
|
+
connecting = void 0;
|
|
685
|
+
return denied({ code: 1e3, reason: "All Subscriptions Gone" });
|
|
686
|
+
}
|
|
687
|
+
retries++;
|
|
688
|
+
}
|
|
689
|
+
emitter.emit("connecting", retrying);
|
|
690
|
+
const socket2 = new WebSocketImpl(
|
|
691
|
+
typeof url === "function" ? await url() : url,
|
|
692
|
+
GRAPHQL_TRANSPORT_WS_PROTOCOL
|
|
693
|
+
);
|
|
694
|
+
let connectionAckTimeout, queuedPing;
|
|
695
|
+
function enqueuePing() {
|
|
696
|
+
if (isFinite(keepAlive) && keepAlive > 0) {
|
|
697
|
+
clearTimeout(queuedPing);
|
|
698
|
+
queuedPing = setTimeout(() => {
|
|
699
|
+
if (socket2.readyState === WebSocketImpl.OPEN) {
|
|
700
|
+
socket2.send(stringifyMessage({ type: MessageType.Ping }));
|
|
701
|
+
emitter.emit("ping", false, void 0);
|
|
702
|
+
}
|
|
703
|
+
}, keepAlive);
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
errorOrClosed((errOrEvent) => {
|
|
707
|
+
connecting = void 0;
|
|
708
|
+
clearTimeout(connectionAckTimeout);
|
|
709
|
+
clearTimeout(queuedPing);
|
|
710
|
+
denied(errOrEvent);
|
|
711
|
+
if (errOrEvent instanceof TerminatedCloseEvent) {
|
|
712
|
+
socket2.close(4499, "Terminated");
|
|
713
|
+
socket2.onerror = null;
|
|
714
|
+
socket2.onclose = null;
|
|
715
|
+
}
|
|
716
|
+
});
|
|
717
|
+
socket2.onerror = (err) => emitter.emit("error", err);
|
|
718
|
+
socket2.onclose = (event) => emitter.emit("closed", event);
|
|
719
|
+
socket2.onopen = async () => {
|
|
720
|
+
try {
|
|
721
|
+
emitter.emit("opened", socket2);
|
|
722
|
+
const payload = typeof connectionParams === "function" ? await connectionParams() : connectionParams;
|
|
723
|
+
if (socket2.readyState !== WebSocketImpl.OPEN) return;
|
|
724
|
+
socket2.send(
|
|
725
|
+
stringifyMessage(
|
|
726
|
+
payload ? {
|
|
727
|
+
type: MessageType.ConnectionInit,
|
|
728
|
+
payload
|
|
729
|
+
} : {
|
|
730
|
+
type: MessageType.ConnectionInit
|
|
731
|
+
// payload is completely absent if not provided
|
|
732
|
+
},
|
|
733
|
+
replacer
|
|
734
|
+
)
|
|
735
|
+
);
|
|
736
|
+
if (isFinite(connectionAckWaitTimeout) && connectionAckWaitTimeout > 0) {
|
|
737
|
+
connectionAckTimeout = setTimeout(() => {
|
|
738
|
+
socket2.close(
|
|
739
|
+
CloseCode.ConnectionAcknowledgementTimeout,
|
|
740
|
+
"Connection acknowledgement timeout"
|
|
741
|
+
);
|
|
742
|
+
}, connectionAckWaitTimeout);
|
|
743
|
+
}
|
|
744
|
+
enqueuePing();
|
|
745
|
+
} catch (err) {
|
|
746
|
+
emitter.emit("error", err);
|
|
747
|
+
socket2.close(
|
|
748
|
+
CloseCode.InternalClientError,
|
|
749
|
+
limitCloseReason(
|
|
750
|
+
err instanceof Error ? err.message : String(err),
|
|
751
|
+
"Internal client error"
|
|
752
|
+
)
|
|
753
|
+
);
|
|
754
|
+
}
|
|
755
|
+
};
|
|
756
|
+
let acknowledged = false;
|
|
757
|
+
socket2.onmessage = ({ data }) => {
|
|
758
|
+
try {
|
|
759
|
+
const message = parseMessage(data, reviver);
|
|
760
|
+
emitter.emit("message", message);
|
|
761
|
+
if (message.type === "ping" || message.type === "pong") {
|
|
762
|
+
emitter.emit(message.type, true, message.payload);
|
|
763
|
+
if (message.type === "pong") {
|
|
764
|
+
enqueuePing();
|
|
765
|
+
} else if (!disablePong) {
|
|
766
|
+
socket2.send(
|
|
767
|
+
stringifyMessage(
|
|
768
|
+
message.payload ? {
|
|
769
|
+
type: MessageType.Pong,
|
|
770
|
+
payload: message.payload
|
|
771
|
+
} : {
|
|
772
|
+
type: MessageType.Pong
|
|
773
|
+
// payload is completely absent if not provided
|
|
774
|
+
}
|
|
775
|
+
)
|
|
776
|
+
);
|
|
777
|
+
emitter.emit("pong", false, message.payload);
|
|
778
|
+
}
|
|
779
|
+
return;
|
|
780
|
+
}
|
|
781
|
+
if (acknowledged) return;
|
|
782
|
+
if (message.type !== MessageType.ConnectionAck)
|
|
783
|
+
throw new Error(
|
|
784
|
+
`First message cannot be of type ${message.type}`
|
|
785
|
+
);
|
|
786
|
+
clearTimeout(connectionAckTimeout);
|
|
787
|
+
acknowledged = true;
|
|
788
|
+
emitter.emit("connected", socket2, message.payload, retrying);
|
|
789
|
+
retrying = false;
|
|
790
|
+
retries = 0;
|
|
791
|
+
connected([
|
|
792
|
+
socket2,
|
|
793
|
+
new Promise((_, reject) => errorOrClosed(reject))
|
|
794
|
+
]);
|
|
795
|
+
} catch (err) {
|
|
796
|
+
socket2.onmessage = null;
|
|
797
|
+
emitter.emit("error", err);
|
|
798
|
+
socket2.close(
|
|
799
|
+
CloseCode.BadResponse,
|
|
800
|
+
limitCloseReason(
|
|
801
|
+
err instanceof Error ? err.message : String(err),
|
|
802
|
+
"Bad response"
|
|
803
|
+
)
|
|
804
|
+
);
|
|
805
|
+
}
|
|
806
|
+
};
|
|
807
|
+
})()
|
|
808
|
+
));
|
|
809
|
+
if (socket.readyState === WebSocketImpl.CLOSING) await throwOnClose;
|
|
810
|
+
let release = () => {
|
|
811
|
+
};
|
|
812
|
+
const released = new Promise((resolve) => release = resolve);
|
|
813
|
+
return [
|
|
814
|
+
socket,
|
|
815
|
+
release,
|
|
816
|
+
Promise.race([
|
|
817
|
+
// wait for
|
|
818
|
+
released.then(() => {
|
|
819
|
+
if (!locks) {
|
|
820
|
+
const complete = () => socket.close(1e3, "Normal Closure");
|
|
821
|
+
if (isFinite(lazyCloseTimeoutMs) && lazyCloseTimeoutMs > 0) {
|
|
822
|
+
lazyCloseTimeout = setTimeout(() => {
|
|
823
|
+
if (socket.readyState === WebSocketImpl.OPEN) complete();
|
|
824
|
+
}, lazyCloseTimeoutMs);
|
|
825
|
+
} else {
|
|
826
|
+
complete();
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
}),
|
|
830
|
+
// or
|
|
831
|
+
throwOnClose
|
|
832
|
+
])
|
|
833
|
+
];
|
|
834
|
+
}
|
|
835
|
+
function shouldRetryConnectOrThrow(errOrCloseEvent) {
|
|
836
|
+
if (isLikeCloseEvent(errOrCloseEvent) && (isFatalInternalCloseCode(errOrCloseEvent.code) || [
|
|
837
|
+
CloseCode.InternalServerError,
|
|
838
|
+
CloseCode.InternalClientError,
|
|
839
|
+
CloseCode.BadRequest,
|
|
840
|
+
CloseCode.BadResponse,
|
|
841
|
+
CloseCode.Unauthorized,
|
|
842
|
+
// CloseCode.Forbidden, might grant access out after retry
|
|
843
|
+
CloseCode.SubprotocolNotAcceptable,
|
|
844
|
+
// CloseCode.ConnectionInitialisationTimeout, might not time out after retry
|
|
845
|
+
// CloseCode.ConnectionAcknowledgementTimeout, might not time out after retry
|
|
846
|
+
CloseCode.SubscriberAlreadyExists,
|
|
847
|
+
CloseCode.TooManyInitialisationRequests
|
|
848
|
+
// 4499, // Terminated, probably because the socket froze, we want to retry
|
|
849
|
+
].includes(errOrCloseEvent.code)))
|
|
850
|
+
throw errOrCloseEvent;
|
|
851
|
+
if (disposed) return false;
|
|
852
|
+
if (isLikeCloseEvent(errOrCloseEvent) && errOrCloseEvent.code === 1e3)
|
|
853
|
+
return locks > 0;
|
|
854
|
+
if (!retryAttempts || retries >= retryAttempts) throw errOrCloseEvent;
|
|
855
|
+
if (!shouldRetry(errOrCloseEvent)) throw errOrCloseEvent;
|
|
856
|
+
return retrying = true;
|
|
857
|
+
}
|
|
858
|
+
if (!lazy) {
|
|
859
|
+
(async () => {
|
|
860
|
+
locks++;
|
|
861
|
+
for (; ; ) {
|
|
862
|
+
try {
|
|
863
|
+
const [, , throwOnClose] = await connect();
|
|
864
|
+
await throwOnClose;
|
|
865
|
+
} catch (errOrCloseEvent) {
|
|
866
|
+
try {
|
|
867
|
+
if (!shouldRetryConnectOrThrow(errOrCloseEvent)) return;
|
|
868
|
+
} catch (errOrCloseEvent2) {
|
|
869
|
+
return onNonLazyError == null ? void 0 : onNonLazyError(errOrCloseEvent2);
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
})();
|
|
874
|
+
}
|
|
875
|
+
function subscribe(payload, sink) {
|
|
876
|
+
const id = generateID(payload);
|
|
877
|
+
let done = false, errored = false, releaser = () => {
|
|
878
|
+
locks--;
|
|
879
|
+
done = true;
|
|
880
|
+
};
|
|
881
|
+
(async () => {
|
|
882
|
+
locks++;
|
|
883
|
+
for (; ; ) {
|
|
884
|
+
try {
|
|
885
|
+
const [socket, release, waitForReleaseOrThrowOnClose] = await connect();
|
|
886
|
+
if (done) return release();
|
|
887
|
+
const unlisten = emitter.onMessage(id, (message) => {
|
|
888
|
+
switch (message.type) {
|
|
889
|
+
case MessageType.Next: {
|
|
890
|
+
sink.next(message.payload);
|
|
891
|
+
return;
|
|
892
|
+
}
|
|
893
|
+
case MessageType.Error: {
|
|
894
|
+
errored = true, done = true;
|
|
895
|
+
sink.error(message.payload);
|
|
896
|
+
releaser();
|
|
897
|
+
return;
|
|
898
|
+
}
|
|
899
|
+
case MessageType.Complete: {
|
|
900
|
+
done = true;
|
|
901
|
+
releaser();
|
|
902
|
+
return;
|
|
903
|
+
}
|
|
904
|
+
}
|
|
905
|
+
});
|
|
906
|
+
socket.send(
|
|
907
|
+
stringifyMessage(
|
|
908
|
+
{
|
|
909
|
+
id,
|
|
910
|
+
type: MessageType.Subscribe,
|
|
911
|
+
payload
|
|
912
|
+
},
|
|
913
|
+
replacer
|
|
914
|
+
)
|
|
915
|
+
);
|
|
916
|
+
releaser = () => {
|
|
917
|
+
if (!done && socket.readyState === WebSocketImpl.OPEN)
|
|
918
|
+
socket.send(
|
|
919
|
+
stringifyMessage(
|
|
920
|
+
{
|
|
921
|
+
id,
|
|
922
|
+
type: MessageType.Complete
|
|
923
|
+
},
|
|
924
|
+
replacer
|
|
925
|
+
)
|
|
926
|
+
);
|
|
927
|
+
locks--;
|
|
928
|
+
done = true;
|
|
929
|
+
release();
|
|
930
|
+
};
|
|
931
|
+
await waitForReleaseOrThrowOnClose.finally(unlisten);
|
|
932
|
+
return;
|
|
933
|
+
} catch (errOrCloseEvent) {
|
|
934
|
+
if (!shouldRetryConnectOrThrow(errOrCloseEvent)) return;
|
|
935
|
+
}
|
|
936
|
+
}
|
|
937
|
+
})().then(() => {
|
|
938
|
+
if (!errored) sink.complete();
|
|
939
|
+
}).catch((err) => {
|
|
940
|
+
sink.error(err);
|
|
941
|
+
});
|
|
942
|
+
return () => {
|
|
943
|
+
if (!done) releaser();
|
|
944
|
+
};
|
|
945
|
+
}
|
|
946
|
+
return {
|
|
947
|
+
on: emitter.on,
|
|
948
|
+
subscribe,
|
|
949
|
+
iterate(request) {
|
|
950
|
+
const pending = [];
|
|
951
|
+
const deferred = {
|
|
952
|
+
done: false,
|
|
953
|
+
error: null,
|
|
954
|
+
resolve: () => {
|
|
955
|
+
}
|
|
956
|
+
};
|
|
957
|
+
const dispose = subscribe(request, {
|
|
958
|
+
next(val) {
|
|
959
|
+
pending.push(val);
|
|
960
|
+
deferred.resolve();
|
|
961
|
+
},
|
|
962
|
+
error(err) {
|
|
963
|
+
deferred.done = true;
|
|
964
|
+
deferred.error = err;
|
|
965
|
+
deferred.resolve();
|
|
966
|
+
},
|
|
967
|
+
complete() {
|
|
968
|
+
deferred.done = true;
|
|
969
|
+
deferred.resolve();
|
|
970
|
+
}
|
|
971
|
+
});
|
|
972
|
+
const iterator = (function iterator2() {
|
|
973
|
+
return __asyncGenerator(this, null, function* () {
|
|
974
|
+
for (; ; ) {
|
|
975
|
+
if (!pending.length) {
|
|
976
|
+
yield new __await(new Promise((resolve) => deferred.resolve = resolve));
|
|
977
|
+
}
|
|
978
|
+
while (pending.length) {
|
|
979
|
+
yield pending.shift();
|
|
980
|
+
}
|
|
981
|
+
if (deferred.error) {
|
|
982
|
+
throw deferred.error;
|
|
983
|
+
}
|
|
984
|
+
if (deferred.done) {
|
|
985
|
+
return;
|
|
986
|
+
}
|
|
987
|
+
}
|
|
988
|
+
});
|
|
989
|
+
})();
|
|
990
|
+
iterator.throw = async (err) => {
|
|
991
|
+
if (!deferred.done) {
|
|
992
|
+
deferred.done = true;
|
|
993
|
+
deferred.error = err;
|
|
994
|
+
deferred.resolve();
|
|
995
|
+
}
|
|
996
|
+
return { done: true, value: void 0 };
|
|
997
|
+
};
|
|
998
|
+
iterator.return = async () => {
|
|
999
|
+
dispose();
|
|
1000
|
+
return { done: true, value: void 0 };
|
|
1001
|
+
};
|
|
1002
|
+
return iterator;
|
|
1003
|
+
},
|
|
1004
|
+
async dispose() {
|
|
1005
|
+
disposed = true;
|
|
1006
|
+
if (connecting) {
|
|
1007
|
+
const [socket] = await connecting;
|
|
1008
|
+
socket.close(1e3, "Normal Closure");
|
|
1009
|
+
}
|
|
1010
|
+
},
|
|
1011
|
+
terminate() {
|
|
1012
|
+
if (connecting) {
|
|
1013
|
+
emitter.emit("closed", new TerminatedCloseEvent());
|
|
1014
|
+
}
|
|
1015
|
+
}
|
|
1016
|
+
};
|
|
1017
|
+
}
|
|
1018
|
+
var TerminatedCloseEvent = class extends Error {
|
|
1019
|
+
constructor() {
|
|
1020
|
+
super(...arguments);
|
|
1021
|
+
__publicField(this, "name", "TerminatedCloseEvent");
|
|
1022
|
+
__publicField(this, "message", "4499: Terminated");
|
|
1023
|
+
__publicField(this, "code", 4499);
|
|
1024
|
+
__publicField(this, "reason", "Terminated");
|
|
1025
|
+
__publicField(this, "wasClean", false);
|
|
1026
|
+
}
|
|
1027
|
+
};
|
|
1028
|
+
function isLikeCloseEvent(val) {
|
|
1029
|
+
return isObject(val) && "code" in val && "reason" in val;
|
|
1030
|
+
}
|
|
1031
|
+
function isFatalInternalCloseCode(code) {
|
|
1032
|
+
if ([
|
|
1033
|
+
1e3,
|
|
1034
|
+
// Normal Closure is not an erroneous close code
|
|
1035
|
+
1001,
|
|
1036
|
+
// Going Away
|
|
1037
|
+
1006,
|
|
1038
|
+
// Abnormal Closure
|
|
1039
|
+
1005,
|
|
1040
|
+
// No Status Received
|
|
1041
|
+
1012,
|
|
1042
|
+
// Service Restart
|
|
1043
|
+
1013,
|
|
1044
|
+
// Try Again Later
|
|
1045
|
+
1014
|
|
1046
|
+
// Bad Gateway
|
|
1047
|
+
].includes(code))
|
|
1048
|
+
return false;
|
|
1049
|
+
return code >= 1e3 && code <= 1999;
|
|
1050
|
+
}
|
|
1051
|
+
function isWebSocket(val) {
|
|
1052
|
+
return typeof val === "function" && "constructor" in val && "CLOSED" in val && "CLOSING" in val && "CONNECTING" in val && "OPEN" in val;
|
|
1053
|
+
}
|
|
1054
|
+
|
|
343
1055
|
// src/SubscriptionClient.ts
|
|
344
|
-
var import_graphql_ws = require("graphql-ws");
|
|
345
1056
|
var import_eventemitter32 = __toESM(require("eventemitter3"));
|
|
346
1057
|
var SubscriptionClient = class extends import_eventemitter32.default {
|
|
347
1058
|
constructor(opts) {
|
|
@@ -365,21 +1076,27 @@ var SubscriptionClient = class extends import_eventemitter32.default {
|
|
|
365
1076
|
}
|
|
366
1077
|
resolveWebSocketImpl() {
|
|
367
1078
|
if (this.options.webSocketImpl) return this.options.webSocketImpl;
|
|
368
|
-
|
|
369
|
-
|
|
1079
|
+
if (true) {
|
|
1080
|
+
const g = globalThis;
|
|
1081
|
+
if (typeof g.WebSocket === "function") return g.WebSocket;
|
|
1082
|
+
throw new Error("No WebSocket implementation found in browser. Provide webSocketImpl.");
|
|
1083
|
+
} else {
|
|
1084
|
+
const proxyEnv = process.env.ALL_PROXY || process.env.HTTPS_PROXY || process.env.HTTP_PROXY || process.env.GLOBAL_AGENT_HTTP_PROXY;
|
|
1085
|
+
if (proxyEnv) {
|
|
1086
|
+
try {
|
|
1087
|
+
return null;
|
|
1088
|
+
} catch (e) {
|
|
1089
|
+
this.log("Proxy detected but failed to load ws package", e);
|
|
1090
|
+
}
|
|
1091
|
+
}
|
|
1092
|
+
const g = globalThis;
|
|
1093
|
+
if (typeof g.WebSocket === "function") return g.WebSocket;
|
|
370
1094
|
try {
|
|
371
|
-
return
|
|
1095
|
+
return null;
|
|
372
1096
|
} catch (e) {
|
|
373
|
-
|
|
1097
|
+
throw new Error("No WebSocket implementation found. Provide webSocketImpl in SubscriptionClientOptions.");
|
|
374
1098
|
}
|
|
375
1099
|
}
|
|
376
|
-
const g = globalThis;
|
|
377
|
-
if (typeof g.WebSocket === "function") return g.WebSocket;
|
|
378
|
-
try {
|
|
379
|
-
return require("ws");
|
|
380
|
-
} catch (e) {
|
|
381
|
-
throw new Error("No WebSocket implementation found. Provide webSocketImpl in SubscriptionClientOptions.");
|
|
382
|
-
}
|
|
383
1100
|
}
|
|
384
1101
|
/** Returns true if an underlying websocket client exists (connected or in-flight). */
|
|
385
1102
|
isConnected() {
|
|
@@ -392,7 +1109,7 @@ var SubscriptionClient = class extends import_eventemitter32.default {
|
|
|
392
1109
|
if (this.client) return;
|
|
393
1110
|
const { url, connectionParams } = this.options;
|
|
394
1111
|
const webSocketImpl = this.resolveWebSocketImpl();
|
|
395
|
-
this.client =
|
|
1112
|
+
this.client = createClient({
|
|
396
1113
|
url,
|
|
397
1114
|
connectionParams,
|
|
398
1115
|
webSocketImpl,
|