@replit/river 0.26.1 → 0.26.3
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/{chunk-4W5LENT2.js → chunk-3JCZNGF7.js} +2 -2
- package/dist/{chunk-XRI2BXMM.js → chunk-BB2E5L4U.js} +25 -13
- package/dist/chunk-BB2E5L4U.js.map +1 -0
- package/dist/{chunk-6UVTCZ6K.js → chunk-JI6FFDY5.js} +5 -4
- package/dist/{chunk-6UVTCZ6K.js.map → chunk-JI6FFDY5.js.map} +1 -1
- package/dist/{chunk-UQOD22AN.js → chunk-MZELCWJK.js} +2 -2
- package/dist/{chunk-UQOD22AN.js.map → chunk-MZELCWJK.js.map} +1 -1
- package/dist/{chunk-M43R4RPL.js → chunk-OCL2FUTQ.js} +128 -45
- package/dist/chunk-OCL2FUTQ.js.map +1 -0
- package/dist/{chunk-IVNX5H6C.js → chunk-X35QRIA5.js} +54 -55
- package/dist/chunk-X35QRIA5.js.map +1 -0
- package/dist/{chunk-AYIMQWS7.js → chunk-ZY2HYJ5Y.js} +2 -2
- package/dist/{client-0f636b3a.d.ts → client-1894a9c9.d.ts} +2 -4
- package/dist/{connection-07e97a79.d.ts → connection-03ffb583.d.ts} +1 -1
- package/dist/{handshake-8752f79e.d.ts → handshake-154a0bb2.d.ts} +82 -39
- package/dist/logging/index.d.cts +1 -1
- package/dist/logging/index.d.ts +1 -1
- package/dist/{message-57296605.d.ts → message-ff78a233.d.ts} +1 -1
- package/dist/router/index.cjs +1 -1
- package/dist/router/index.cjs.map +1 -1
- package/dist/router/index.d.cts +9 -8
- package/dist/router/index.d.ts +9 -8
- package/dist/router/index.js +2 -2
- package/dist/{server-e304daec.d.ts → server-1f5eb427.d.ts} +27 -6
- package/dist/{services-fc99aae1.d.ts → services-491d8c32.d.ts} +3 -3
- package/dist/transport/impls/ws/client.cjs +153 -56
- package/dist/transport/impls/ws/client.cjs.map +1 -1
- package/dist/transport/impls/ws/client.d.cts +5 -4
- package/dist/transport/impls/ws/client.d.ts +5 -4
- package/dist/transport/impls/ws/client.js +8 -7
- package/dist/transport/impls/ws/client.js.map +1 -1
- package/dist/transport/impls/ws/server.cjs +179 -96
- package/dist/transport/impls/ws/server.cjs.map +1 -1
- package/dist/transport/impls/ws/server.d.cts +5 -4
- package/dist/transport/impls/ws/server.d.ts +5 -4
- package/dist/transport/impls/ws/server.js +5 -5
- package/dist/transport/index.cjs +200 -105
- package/dist/transport/index.cjs.map +1 -1
- package/dist/transport/index.d.cts +5 -4
- package/dist/transport/index.d.ts +5 -4
- package/dist/transport/index.js +5 -5
- package/dist/util/testHelpers.cjs +127 -44
- package/dist/util/testHelpers.cjs.map +1 -1
- package/dist/util/testHelpers.d.cts +5 -4
- package/dist/util/testHelpers.d.ts +5 -4
- package/dist/util/testHelpers.js +3 -3
- package/package.json +1 -1
- package/dist/chunk-IVNX5H6C.js.map +0 -1
- package/dist/chunk-M43R4RPL.js.map +0 -1
- package/dist/chunk-XRI2BXMM.js.map +0 -1
- /package/dist/{chunk-4W5LENT2.js.map → chunk-3JCZNGF7.js.map} +0 -0
- /package/dist/{chunk-AYIMQWS7.js.map → chunk-ZY2HYJ5Y.js.map} +0 -0
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import { C as ClientTransport } from '../../../client-
|
|
2
|
-
import { c as TransportClientId } from '../../../message-
|
|
3
|
-
import { b as ProvidedClientTransportOptions } from '../../../handshake-
|
|
4
|
-
import { W as WebSocketConnection } from '../../../connection-
|
|
1
|
+
import { C as ClientTransport } from '../../../client-1894a9c9.js';
|
|
2
|
+
import { c as TransportClientId } from '../../../message-ff78a233.js';
|
|
3
|
+
import { b as ProvidedClientTransportOptions } from '../../../handshake-154a0bb2.js';
|
|
4
|
+
import { W as WebSocketConnection } from '../../../connection-03ffb583.js';
|
|
5
5
|
import { W as WsLike } from '../../../wslike-e0b32dd5.js';
|
|
6
6
|
import '@sinclair/typebox/value';
|
|
7
7
|
import '@sinclair/typebox';
|
|
8
8
|
import '@opentelemetry/api';
|
|
9
|
+
import '@sinclair/typebox/errors';
|
|
9
10
|
import '../../../types-3e5768ec.js';
|
|
10
11
|
|
|
11
12
|
/**
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import { C as ClientTransport } from '../../../client-
|
|
2
|
-
import { c as TransportClientId } from '../../../message-
|
|
3
|
-
import { b as ProvidedClientTransportOptions } from '../../../handshake-
|
|
4
|
-
import { W as WebSocketConnection } from '../../../connection-
|
|
1
|
+
import { C as ClientTransport } from '../../../client-1894a9c9.js';
|
|
2
|
+
import { c as TransportClientId } from '../../../message-ff78a233.js';
|
|
3
|
+
import { b as ProvidedClientTransportOptions } from '../../../handshake-154a0bb2.js';
|
|
4
|
+
import { W as WebSocketConnection } from '../../../connection-03ffb583.js';
|
|
5
5
|
import { W as WsLike } from '../../../wslike-e0b32dd5.js';
|
|
6
6
|
import '@sinclair/typebox/value';
|
|
7
7
|
import '@sinclair/typebox';
|
|
8
8
|
import '@opentelemetry/api';
|
|
9
|
+
import '@sinclair/typebox/errors';
|
|
9
10
|
import '../../../types-3e5768ec.js';
|
|
10
11
|
|
|
11
12
|
/**
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ClientTransport
|
|
3
|
-
} from "../../../chunk-
|
|
3
|
+
} from "../../../chunk-BB2E5L4U.js";
|
|
4
4
|
import {
|
|
5
5
|
WebSocketConnection
|
|
6
|
-
} from "../../../chunk-
|
|
7
|
-
import "../../../chunk-
|
|
6
|
+
} from "../../../chunk-ZY2HYJ5Y.js";
|
|
7
|
+
import "../../../chunk-JI6FFDY5.js";
|
|
8
8
|
import "../../../chunk-TAH2GVTJ.js";
|
|
9
|
-
import "../../../chunk-
|
|
10
|
-
import "../../../chunk-
|
|
9
|
+
import "../../../chunk-OCL2FUTQ.js";
|
|
10
|
+
import "../../../chunk-MZELCWJK.js";
|
|
11
11
|
import "../../../chunk-4PVU7J25.js";
|
|
12
12
|
|
|
13
13
|
// transport/impls/ws/client.ts
|
|
@@ -53,9 +53,10 @@ var WebSocketClientTransport = class extends ClientTransport {
|
|
|
53
53
|
};
|
|
54
54
|
});
|
|
55
55
|
const conn = new WebSocketConnection(ws);
|
|
56
|
-
this.log?.info(`raw websocket to ${to} ok
|
|
56
|
+
this.log?.info(`raw websocket to ${to} ok`, {
|
|
57
57
|
clientId: this.clientId,
|
|
58
|
-
connectedTo: to
|
|
58
|
+
connectedTo: to,
|
|
59
|
+
...conn.loggingMetadata
|
|
59
60
|
});
|
|
60
61
|
return conn;
|
|
61
62
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../transport/impls/ws/client.ts"],"sourcesContent":["import { ClientTransport } from '../../client';\nimport { TransportClientId } from '../../message';\nimport { ProvidedClientTransportOptions } from '../../options';\nimport { WebSocketConnection } from './connection';\nimport { WsLike } from './wslike';\n\n/**\n * A transport implementation that uses a WebSocket connection with automatic reconnection.\n * @class\n * @extends Transport\n */\nexport class WebSocketClientTransport extends ClientTransport<WebSocketConnection> {\n /**\n * A function that returns a Promise that resolves to a websocket URL.\n */\n wsGetter: (to: TransportClientId) => Promise<WsLike> | WsLike;\n\n /**\n * Creates a new WebSocketClientTransport instance.\n * @param wsGetter A function that returns a Promise that resolves to a WebSocket instance.\n * @param clientId The ID of the client using the transport. This should be unique per session.\n * @param serverId The ID of the server this transport is connecting to.\n * @param providedOptions An optional object containing configuration options for the transport.\n */\n constructor(\n wsGetter: (to: TransportClientId) => Promise<WsLike> | WsLike,\n clientId: TransportClientId,\n providedOptions?: ProvidedClientTransportOptions,\n ) {\n super(clientId, providedOptions);\n this.wsGetter = wsGetter;\n }\n\n async createNewOutgoingConnection(to: string) {\n this.log?.info(`establishing a new websocket to ${to}`, {\n clientId: this.clientId,\n connectedTo: to,\n });\n\n const ws = await this.wsGetter(to);\n\n await new Promise<void>((resolve, reject) => {\n if (ws.readyState === ws.OPEN) {\n resolve();\n return;\n }\n\n if (ws.readyState === ws.CLOSING || ws.readyState === ws.CLOSED) {\n reject(new Error('ws is closing or closed'));\n return;\n }\n\n ws.onopen = () => {\n resolve();\n };\n\n ws.onclose = (evt) => {\n reject(new Error(evt.reason));\n };\n\n ws.onerror = (err) => {\n reject(new Error(err.message));\n };\n });\n\n const conn = new WebSocketConnection(ws);\n this.log?.info(`raw websocket to ${to} ok
|
|
1
|
+
{"version":3,"sources":["../../../../transport/impls/ws/client.ts"],"sourcesContent":["import { ClientTransport } from '../../client';\nimport { TransportClientId } from '../../message';\nimport { ProvidedClientTransportOptions } from '../../options';\nimport { WebSocketConnection } from './connection';\nimport { WsLike } from './wslike';\n\n/**\n * A transport implementation that uses a WebSocket connection with automatic reconnection.\n * @class\n * @extends Transport\n */\nexport class WebSocketClientTransport extends ClientTransport<WebSocketConnection> {\n /**\n * A function that returns a Promise that resolves to a websocket URL.\n */\n wsGetter: (to: TransportClientId) => Promise<WsLike> | WsLike;\n\n /**\n * Creates a new WebSocketClientTransport instance.\n * @param wsGetter A function that returns a Promise that resolves to a WebSocket instance.\n * @param clientId The ID of the client using the transport. This should be unique per session.\n * @param serverId The ID of the server this transport is connecting to.\n * @param providedOptions An optional object containing configuration options for the transport.\n */\n constructor(\n wsGetter: (to: TransportClientId) => Promise<WsLike> | WsLike,\n clientId: TransportClientId,\n providedOptions?: ProvidedClientTransportOptions,\n ) {\n super(clientId, providedOptions);\n this.wsGetter = wsGetter;\n }\n\n async createNewOutgoingConnection(to: string) {\n this.log?.info(`establishing a new websocket to ${to}`, {\n clientId: this.clientId,\n connectedTo: to,\n });\n\n const ws = await this.wsGetter(to);\n\n await new Promise<void>((resolve, reject) => {\n if (ws.readyState === ws.OPEN) {\n resolve();\n return;\n }\n\n if (ws.readyState === ws.CLOSING || ws.readyState === ws.CLOSED) {\n reject(new Error('ws is closing or closed'));\n return;\n }\n\n ws.onopen = () => {\n resolve();\n };\n\n ws.onclose = (evt) => {\n reject(new Error(evt.reason));\n };\n\n ws.onerror = (err) => {\n reject(new Error(err.message));\n };\n });\n\n const conn = new WebSocketConnection(ws);\n this.log?.info(`raw websocket to ${to} ok`, {\n clientId: this.clientId,\n connectedTo: to,\n ...conn.loggingMetadata,\n });\n\n return conn;\n }\n}\n"],"mappings":";;;;;;;;;;;;;AAWO,IAAM,2BAAN,cAAuC,gBAAqC;AAAA;AAAA;AAAA;AAAA,EAIjF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,YACE,UACA,UACA,iBACA;AACA,UAAM,UAAU,eAAe;AAC/B,SAAK,WAAW;AAAA,EAClB;AAAA,EAEA,MAAM,4BAA4B,IAAY;AAC5C,SAAK,KAAK,KAAK,mCAAmC,EAAE,IAAI;AAAA,MACtD,UAAU,KAAK;AAAA,MACf,aAAa;AAAA,IACf,CAAC;AAED,UAAM,KAAK,MAAM,KAAK,SAAS,EAAE;AAEjC,UAAM,IAAI,QAAc,CAAC,SAAS,WAAW;AAC3C,UAAI,GAAG,eAAe,GAAG,MAAM;AAC7B,gBAAQ;AACR;AAAA,MACF;AAEA,UAAI,GAAG,eAAe,GAAG,WAAW,GAAG,eAAe,GAAG,QAAQ;AAC/D,eAAO,IAAI,MAAM,yBAAyB,CAAC;AAC3C;AAAA,MACF;AAEA,SAAG,SAAS,MAAM;AAChB,gBAAQ;AAAA,MACV;AAEA,SAAG,UAAU,CAAC,QAAQ;AACpB,eAAO,IAAI,MAAM,IAAI,MAAM,CAAC;AAAA,MAC9B;AAEA,SAAG,UAAU,CAAC,QAAQ;AACpB,eAAO,IAAI,MAAM,IAAI,OAAO,CAAC;AAAA,MAC/B;AAAA,IACF,CAAC;AAED,UAAM,OAAO,IAAI,oBAAoB,EAAE;AACvC,SAAK,KAAK,KAAK,oBAAoB,EAAE,OAAO;AAAA,MAC1C,UAAU,KAAK;AAAA,MACf,aAAa;AAAA,MACb,GAAG,KAAK;AAAA,IACV,CAAC;AAED,WAAO;AAAA,EACT;AACF;","names":[]}
|
|
@@ -322,6 +322,7 @@ var defaultTransportOptions = {
|
|
|
322
322
|
sessionDisconnectGraceMs: 5e3,
|
|
323
323
|
connectionTimeoutMs: 2e3,
|
|
324
324
|
handshakeTimeoutMs: 1e3,
|
|
325
|
+
enableTransparentSessionReconnects: true,
|
|
325
326
|
codec: NaiveJsonCodec
|
|
326
327
|
};
|
|
327
328
|
var defaultConnectionRetryOptions = {
|
|
@@ -456,6 +457,7 @@ var StateMachineState = class {
|
|
|
456
457
|
}
|
|
457
458
|
if (prop === "_handleClose") {
|
|
458
459
|
return () => {
|
|
460
|
+
target._isConsumed = true;
|
|
459
461
|
target._handleStateExit();
|
|
460
462
|
target._handleClose();
|
|
461
463
|
};
|
|
@@ -536,15 +538,18 @@ var IdentifiedSession = class extends CommonSession {
|
|
|
536
538
|
}
|
|
537
539
|
get loggingMetadata() {
|
|
538
540
|
const spanContext = this.telemetry.span.spanContext();
|
|
539
|
-
|
|
541
|
+
const metadata = {
|
|
540
542
|
clientId: this.from,
|
|
541
543
|
connectedTo: this.to,
|
|
542
|
-
sessionId: this.id
|
|
543
|
-
|
|
544
|
+
sessionId: this.id
|
|
545
|
+
};
|
|
546
|
+
if (this.telemetry.span.isRecording()) {
|
|
547
|
+
metadata.telemetry = {
|
|
544
548
|
traceId: spanContext.traceId,
|
|
545
549
|
spanId: spanContext.spanId
|
|
546
|
-
}
|
|
547
|
-
}
|
|
550
|
+
};
|
|
551
|
+
}
|
|
552
|
+
return metadata;
|
|
548
553
|
}
|
|
549
554
|
constructMsg(partialMsg) {
|
|
550
555
|
const msg = {
|
|
@@ -573,9 +578,32 @@ var IdentifiedSession = class extends CommonSession {
|
|
|
573
578
|
this.telemetry.span.end();
|
|
574
579
|
}
|
|
575
580
|
};
|
|
581
|
+
var IdentifiedSessionWithGracePeriod = class extends IdentifiedSession {
|
|
582
|
+
graceExpiryTime;
|
|
583
|
+
gracePeriodTimeout;
|
|
584
|
+
listeners;
|
|
585
|
+
constructor(props) {
|
|
586
|
+
super(props);
|
|
587
|
+
this.listeners = props.listeners;
|
|
588
|
+
this.graceExpiryTime = props.graceExpiryTime;
|
|
589
|
+
this.gracePeriodTimeout = setTimeout(() => {
|
|
590
|
+
this.listeners.onSessionGracePeriodElapsed();
|
|
591
|
+
}, this.graceExpiryTime - Date.now());
|
|
592
|
+
}
|
|
593
|
+
_handleStateExit() {
|
|
594
|
+
super._handleStateExit();
|
|
595
|
+
if (this.gracePeriodTimeout) {
|
|
596
|
+
clearTimeout(this.gracePeriodTimeout);
|
|
597
|
+
this.gracePeriodTimeout = void 0;
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
_handleClose() {
|
|
601
|
+
super._handleClose();
|
|
602
|
+
}
|
|
603
|
+
};
|
|
576
604
|
|
|
577
605
|
// transport/sessionStateMachine/SessionConnecting.ts
|
|
578
|
-
var SessionConnecting = class extends
|
|
606
|
+
var SessionConnecting = class extends IdentifiedSessionWithGracePeriod {
|
|
579
607
|
state = "Connecting" /* Connecting */;
|
|
580
608
|
connPromise;
|
|
581
609
|
listeners;
|
|
@@ -603,13 +631,24 @@ var SessionConnecting = class extends IdentifiedSession {
|
|
|
603
631
|
// close a pending connection if it resolves, ignore errors if the promise
|
|
604
632
|
// ends up rejected anyways
|
|
605
633
|
bestEffortClose() {
|
|
606
|
-
void this.connPromise.then((conn) =>
|
|
634
|
+
void this.connPromise.then((conn) => {
|
|
635
|
+
conn.close();
|
|
636
|
+
this.log?.info(
|
|
637
|
+
"connection eventually resolved but session has transitioned, closed connection",
|
|
638
|
+
{
|
|
639
|
+
...this.loggingMetadata,
|
|
640
|
+
...conn.loggingMetadata
|
|
641
|
+
}
|
|
642
|
+
);
|
|
643
|
+
}).catch(() => {
|
|
607
644
|
});
|
|
608
645
|
}
|
|
609
646
|
_handleStateExit() {
|
|
610
647
|
super._handleStateExit();
|
|
611
|
-
|
|
612
|
-
|
|
648
|
+
if (this.connectionTimeout) {
|
|
649
|
+
clearTimeout(this.connectionTimeout);
|
|
650
|
+
this.connectionTimeout = void 0;
|
|
651
|
+
}
|
|
613
652
|
}
|
|
614
653
|
_handleClose() {
|
|
615
654
|
this.bestEffortClose();
|
|
@@ -618,26 +657,13 @@ var SessionConnecting = class extends IdentifiedSession {
|
|
|
618
657
|
};
|
|
619
658
|
|
|
620
659
|
// transport/sessionStateMachine/SessionNoConnection.ts
|
|
621
|
-
var SessionNoConnection = class extends
|
|
660
|
+
var SessionNoConnection = class extends IdentifiedSessionWithGracePeriod {
|
|
622
661
|
state = "NoConnection" /* NoConnection */;
|
|
623
|
-
listeners;
|
|
624
|
-
gracePeriodTimeout;
|
|
625
|
-
constructor(props) {
|
|
626
|
-
super(props);
|
|
627
|
-
this.listeners = props.listeners;
|
|
628
|
-
this.gracePeriodTimeout = setTimeout(() => {
|
|
629
|
-
this.listeners.onSessionGracePeriodElapsed();
|
|
630
|
-
}, this.options.sessionDisconnectGraceMs);
|
|
631
|
-
}
|
|
632
662
|
_handleClose() {
|
|
633
663
|
super._handleClose();
|
|
634
664
|
}
|
|
635
665
|
_handleStateExit() {
|
|
636
666
|
super._handleStateExit();
|
|
637
|
-
if (this.gracePeriodTimeout) {
|
|
638
|
-
clearTimeout(this.gracePeriodTimeout);
|
|
639
|
-
this.gracePeriodTimeout = void 0;
|
|
640
|
-
}
|
|
641
667
|
}
|
|
642
668
|
};
|
|
643
669
|
|
|
@@ -645,7 +671,7 @@ var SessionNoConnection = class extends IdentifiedSession {
|
|
|
645
671
|
var import_api = require("@opentelemetry/api");
|
|
646
672
|
|
|
647
673
|
// package.json
|
|
648
|
-
var version = "0.26.
|
|
674
|
+
var version = "0.26.3";
|
|
649
675
|
|
|
650
676
|
// tracing/index.ts
|
|
651
677
|
function createSessionTelemetryInfo(sessionId, to, from, propagationCtx) {
|
|
@@ -684,6 +710,13 @@ var SessionWaitingForHandshake = class extends CommonSession {
|
|
|
684
710
|
this.conn.addErrorListener(this.listeners.onConnectionErrored);
|
|
685
711
|
this.conn.addCloseListener(this.listeners.onConnectionClosed);
|
|
686
712
|
}
|
|
713
|
+
get loggingMetadata() {
|
|
714
|
+
return {
|
|
715
|
+
clientId: this.from,
|
|
716
|
+
connId: this.conn.id,
|
|
717
|
+
...this.conn.loggingMetadata
|
|
718
|
+
};
|
|
719
|
+
}
|
|
687
720
|
onHandshakeData = (msg) => {
|
|
688
721
|
const parsedMsg = this.parseMsg(msg);
|
|
689
722
|
if (parsedMsg === null) {
|
|
@@ -695,12 +728,6 @@ var SessionWaitingForHandshake = class extends CommonSession {
|
|
|
695
728
|
}
|
|
696
729
|
this.listeners.onHandshake(parsedMsg);
|
|
697
730
|
};
|
|
698
|
-
get loggingMetadata() {
|
|
699
|
-
return {
|
|
700
|
-
clientId: this.from,
|
|
701
|
-
connId: this.conn.id
|
|
702
|
-
};
|
|
703
|
-
}
|
|
704
731
|
sendHandshake(msg) {
|
|
705
732
|
return this.conn.send(this.options.codec.toBuffer(msg));
|
|
706
733
|
}
|
|
@@ -717,7 +744,7 @@ var SessionWaitingForHandshake = class extends CommonSession {
|
|
|
717
744
|
};
|
|
718
745
|
|
|
719
746
|
// transport/sessionStateMachine/SessionHandshaking.ts
|
|
720
|
-
var SessionHandshaking = class extends
|
|
747
|
+
var SessionHandshaking = class extends IdentifiedSessionWithGracePeriod {
|
|
721
748
|
state = "Handshaking" /* Handshaking */;
|
|
722
749
|
conn;
|
|
723
750
|
listeners;
|
|
@@ -733,6 +760,12 @@ var SessionHandshaking = class extends IdentifiedSession {
|
|
|
733
760
|
this.conn.addErrorListener(this.listeners.onConnectionErrored);
|
|
734
761
|
this.conn.addCloseListener(this.listeners.onConnectionClosed);
|
|
735
762
|
}
|
|
763
|
+
get loggingMetadata() {
|
|
764
|
+
return {
|
|
765
|
+
...super.loggingMetadata,
|
|
766
|
+
...this.conn.loggingMetadata
|
|
767
|
+
};
|
|
768
|
+
}
|
|
736
769
|
onHandshakeData = (msg) => {
|
|
737
770
|
const parsedMsg = this.parseMsg(msg);
|
|
738
771
|
if (parsedMsg === null) {
|
|
@@ -752,7 +785,10 @@ var SessionHandshaking = class extends IdentifiedSession {
|
|
|
752
785
|
this.conn.removeDataListener(this.onHandshakeData);
|
|
753
786
|
this.conn.removeErrorListener(this.listeners.onConnectionErrored);
|
|
754
787
|
this.conn.removeCloseListener(this.listeners.onConnectionClosed);
|
|
755
|
-
|
|
788
|
+
if (this.handshakeTimeout) {
|
|
789
|
+
clearTimeout(this.handshakeTimeout);
|
|
790
|
+
this.handshakeTimeout = void 0;
|
|
791
|
+
}
|
|
756
792
|
}
|
|
757
793
|
_handleClose() {
|
|
758
794
|
super._handleClose();
|
|
@@ -817,6 +853,12 @@ var SessionConnected = class extends IdentifiedSession {
|
|
|
817
853
|
this.heartbeatMisses++;
|
|
818
854
|
}, this.options.heartbeatIntervalMs);
|
|
819
855
|
}
|
|
856
|
+
get loggingMetadata() {
|
|
857
|
+
return {
|
|
858
|
+
...super.loggingMetadata,
|
|
859
|
+
...this.conn.loggingMetadata
|
|
860
|
+
};
|
|
861
|
+
}
|
|
820
862
|
startActiveHeartbeat() {
|
|
821
863
|
this.isActivelyHeartbeating = true;
|
|
822
864
|
}
|
|
@@ -832,8 +874,10 @@ var SessionConnected = class extends IdentifiedSession {
|
|
|
832
874
|
}
|
|
833
875
|
onMessageData = (msg) => {
|
|
834
876
|
const parsedMsg = this.parseMsg(msg);
|
|
835
|
-
if (parsedMsg === null)
|
|
877
|
+
if (parsedMsg === null) {
|
|
878
|
+
this.listeners.onInvalidMessage("could not parse message");
|
|
836
879
|
return;
|
|
880
|
+
}
|
|
837
881
|
if (parsedMsg.seq !== this.ack) {
|
|
838
882
|
if (parsedMsg.seq < this.ack) {
|
|
839
883
|
this.log?.debug(
|
|
@@ -890,7 +934,7 @@ var SessionConnected = class extends IdentifiedSession {
|
|
|
890
934
|
};
|
|
891
935
|
|
|
892
936
|
// transport/sessionStateMachine/SessionBackingOff.ts
|
|
893
|
-
var SessionBackingOff = class extends
|
|
937
|
+
var SessionBackingOff = class extends IdentifiedSessionWithGracePeriod {
|
|
894
938
|
state = "BackingOff" /* BackingOff */;
|
|
895
939
|
listeners;
|
|
896
940
|
backoffTimeout;
|
|
@@ -927,6 +971,12 @@ function inheritSharedSession(session) {
|
|
|
927
971
|
log: session.log
|
|
928
972
|
};
|
|
929
973
|
}
|
|
974
|
+
function inheritSharedSessionWithGrace(session) {
|
|
975
|
+
return {
|
|
976
|
+
...inheritSharedSession(session),
|
|
977
|
+
graceExpiryTime: session.graceExpiryTime
|
|
978
|
+
};
|
|
979
|
+
}
|
|
930
980
|
var SessionStateGraph = {
|
|
931
981
|
entrypoints: {
|
|
932
982
|
NoConnection: (to, from, listeners, options, log) => {
|
|
@@ -940,6 +990,7 @@ var SessionStateGraph = {
|
|
|
940
990
|
to,
|
|
941
991
|
seq: 0,
|
|
942
992
|
ack: 0,
|
|
993
|
+
graceExpiryTime: Date.now() + options.sessionDisconnectGraceMs,
|
|
943
994
|
sendBuffer,
|
|
944
995
|
telemetry,
|
|
945
996
|
options,
|
|
@@ -971,7 +1022,7 @@ var SessionStateGraph = {
|
|
|
971
1022
|
transition: {
|
|
972
1023
|
// happy path transitions
|
|
973
1024
|
NoConnectionToBackingOff: (oldSession, backoffMs, listeners) => {
|
|
974
|
-
const carriedState =
|
|
1025
|
+
const carriedState = inheritSharedSessionWithGrace(oldSession);
|
|
975
1026
|
oldSession._handleStateExit();
|
|
976
1027
|
const session = new SessionBackingOff({
|
|
977
1028
|
backoffMs,
|
|
@@ -988,7 +1039,7 @@ var SessionStateGraph = {
|
|
|
988
1039
|
return session;
|
|
989
1040
|
},
|
|
990
1041
|
BackingOffToConnecting: (oldSession, connPromise, listeners) => {
|
|
991
|
-
const carriedState =
|
|
1042
|
+
const carriedState = inheritSharedSessionWithGrace(oldSession);
|
|
992
1043
|
oldSession._handleStateExit();
|
|
993
1044
|
const session = new SessionConnecting({
|
|
994
1045
|
connPromise,
|
|
@@ -1005,7 +1056,7 @@ var SessionStateGraph = {
|
|
|
1005
1056
|
return session;
|
|
1006
1057
|
},
|
|
1007
1058
|
ConnectingToHandshaking: (oldSession, conn, listeners) => {
|
|
1008
|
-
const carriedState =
|
|
1059
|
+
const carriedState = inheritSharedSessionWithGrace(oldSession);
|
|
1009
1060
|
oldSession._handleStateExit();
|
|
1010
1061
|
const session = new SessionHandshaking({
|
|
1011
1062
|
conn,
|
|
@@ -1082,9 +1133,12 @@ var SessionStateGraph = {
|
|
|
1082
1133
|
},
|
|
1083
1134
|
// disconnect paths
|
|
1084
1135
|
BackingOffToNoConnection: (oldSession, listeners) => {
|
|
1085
|
-
const carriedState =
|
|
1136
|
+
const carriedState = inheritSharedSessionWithGrace(oldSession);
|
|
1086
1137
|
oldSession._handleStateExit();
|
|
1087
|
-
const session = new SessionNoConnection({
|
|
1138
|
+
const session = new SessionNoConnection({
|
|
1139
|
+
listeners,
|
|
1140
|
+
...carriedState
|
|
1141
|
+
});
|
|
1088
1142
|
session.log?.info(
|
|
1089
1143
|
`session ${session.id} transition from BackingOff to NoConnection`,
|
|
1090
1144
|
{
|
|
@@ -1095,10 +1149,13 @@ var SessionStateGraph = {
|
|
|
1095
1149
|
return session;
|
|
1096
1150
|
},
|
|
1097
1151
|
ConnectingToNoConnection: (oldSession, listeners) => {
|
|
1098
|
-
const carriedState =
|
|
1152
|
+
const carriedState = inheritSharedSessionWithGrace(oldSession);
|
|
1099
1153
|
oldSession.bestEffortClose();
|
|
1100
1154
|
oldSession._handleStateExit();
|
|
1101
|
-
const session = new SessionNoConnection({
|
|
1155
|
+
const session = new SessionNoConnection({
|
|
1156
|
+
listeners,
|
|
1157
|
+
...carriedState
|
|
1158
|
+
});
|
|
1102
1159
|
session.log?.info(
|
|
1103
1160
|
`session ${session.id} transition from Connecting to NoConnection`,
|
|
1104
1161
|
{
|
|
@@ -1109,10 +1166,13 @@ var SessionStateGraph = {
|
|
|
1109
1166
|
return session;
|
|
1110
1167
|
},
|
|
1111
1168
|
HandshakingToNoConnection: (oldSession, listeners) => {
|
|
1112
|
-
const carriedState =
|
|
1169
|
+
const carriedState = inheritSharedSessionWithGrace(oldSession);
|
|
1113
1170
|
oldSession.conn.close();
|
|
1114
1171
|
oldSession._handleStateExit();
|
|
1115
|
-
const session = new SessionNoConnection({
|
|
1172
|
+
const session = new SessionNoConnection({
|
|
1173
|
+
listeners,
|
|
1174
|
+
...carriedState
|
|
1175
|
+
});
|
|
1116
1176
|
session.log?.info(
|
|
1117
1177
|
`session ${session.id} transition from Handshaking to NoConnection`,
|
|
1118
1178
|
{
|
|
@@ -1124,9 +1184,14 @@ var SessionStateGraph = {
|
|
|
1124
1184
|
},
|
|
1125
1185
|
ConnectedToNoConnection: (oldSession, listeners) => {
|
|
1126
1186
|
const carriedState = inheritSharedSession(oldSession);
|
|
1187
|
+
const graceExpiryTime = Date.now() + oldSession.options.sessionDisconnectGraceMs;
|
|
1127
1188
|
oldSession.conn.close();
|
|
1128
1189
|
oldSession._handleStateExit();
|
|
1129
|
-
const session = new SessionNoConnection({
|
|
1190
|
+
const session = new SessionNoConnection({
|
|
1191
|
+
listeners,
|
|
1192
|
+
graceExpiryTime,
|
|
1193
|
+
...carriedState
|
|
1194
|
+
});
|
|
1130
1195
|
session.log?.info(
|
|
1131
1196
|
`session ${session.id} transition from Connected to NoConnection`,
|
|
1132
1197
|
{
|
|
@@ -1143,24 +1208,42 @@ var ClientSessionStateGraph = {
|
|
|
1143
1208
|
entrypoint: SessionStateGraph.entrypoints.NoConnection,
|
|
1144
1209
|
transition: {
|
|
1145
1210
|
// happy paths
|
|
1211
|
+
// NoConnection -> BackingOff: attempt to connect
|
|
1146
1212
|
NoConnectionToBackingOff: transitions.NoConnectionToBackingOff,
|
|
1213
|
+
// BackingOff -> Connecting: backoff period elapsed, start connection
|
|
1147
1214
|
BackingOffToConnecting: transitions.BackingOffToConnecting,
|
|
1215
|
+
// Connecting -> Handshaking: connection established, start handshake
|
|
1148
1216
|
ConnectingToHandshaking: transitions.ConnectingToHandshaking,
|
|
1217
|
+
// Handshaking -> Connected: handshake complete, session ready
|
|
1149
1218
|
HandshakingToConnected: transitions.HandshakingToConnected,
|
|
1150
1219
|
// disconnect paths
|
|
1220
|
+
// BackingOff -> NoConnection: unused
|
|
1151
1221
|
BackingOffToNoConnection: transitions.BackingOffToNoConnection,
|
|
1222
|
+
// Connecting -> NoConnection: connection failed or connection timeout
|
|
1152
1223
|
ConnectingToNoConnection: transitions.ConnectingToNoConnection,
|
|
1224
|
+
// Handshaking -> NoConnection: connection closed or handshake timeout
|
|
1153
1225
|
HandshakingToNoConnection: transitions.HandshakingToNoConnection,
|
|
1226
|
+
// Connected -> NoConnection: connection closed
|
|
1154
1227
|
ConnectedToNoConnection: transitions.ConnectedToNoConnection
|
|
1228
|
+
// destroy/close paths
|
|
1229
|
+
// NoConnection -> x: grace period elapsed
|
|
1230
|
+
// BackingOff -> x: grace period elapsed
|
|
1231
|
+
// Connecting -> x: grace period elapsed
|
|
1232
|
+
// Handshaking -> x: grace period elapsed or invalid handshake message or handshake rejection
|
|
1233
|
+
// Connected -> x: grace period elapsed or invalid message
|
|
1155
1234
|
}
|
|
1156
1235
|
};
|
|
1157
1236
|
var ServerSessionStateGraph = {
|
|
1158
1237
|
entrypoint: SessionStateGraph.entrypoints.WaitingForHandshake,
|
|
1159
1238
|
transition: {
|
|
1160
1239
|
// happy paths
|
|
1240
|
+
// WaitingForHandshake -> Connected: handshake complete, session ready
|
|
1161
1241
|
WaitingForHandshakeToConnected: transitions.WaitingForHandshakeToConnected,
|
|
1162
1242
|
// disconnect paths
|
|
1243
|
+
// Connected -> NoConnection: connection closed
|
|
1163
1244
|
ConnectedToNoConnection: transitions.ConnectedToNoConnection
|
|
1245
|
+
// destroy/close paths
|
|
1246
|
+
// WaitingForHandshake -> x: handshake timeout elapsed or invalid handshake message or handshake rejection or connection closed
|
|
1164
1247
|
}
|
|
1165
1248
|
};
|
|
1166
1249
|
|
|
@@ -1277,8 +1360,9 @@ var Transport = class {
|
|
|
1277
1360
|
status: "disconnect",
|
|
1278
1361
|
session
|
|
1279
1362
|
});
|
|
1363
|
+
const to = session.to;
|
|
1280
1364
|
session.close();
|
|
1281
|
-
this.sessions.delete(
|
|
1365
|
+
this.sessions.delete(to);
|
|
1282
1366
|
}
|
|
1283
1367
|
// common listeners
|
|
1284
1368
|
onSessionGracePeriodElapsed(session) {
|
|
@@ -1511,19 +1595,58 @@ var ServerTransport = class extends Transport {
|
|
|
1511
1595
|
return;
|
|
1512
1596
|
}
|
|
1513
1597
|
let oldSession = this.sessions.get(msg.from);
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1598
|
+
let parsedMetadata = {};
|
|
1599
|
+
if (this.handshakeExtensions) {
|
|
1600
|
+
if (!import_value2.Value.Check(this.handshakeExtensions.schema, msg.payload.metadata)) {
|
|
1601
|
+
this.rejectHandshakeRequest(
|
|
1602
|
+
session,
|
|
1603
|
+
msg.from,
|
|
1604
|
+
"received malformed handshake metadata",
|
|
1605
|
+
"MALFORMED_HANDSHAKE_META",
|
|
1606
|
+
{
|
|
1607
|
+
...session.loggingMetadata,
|
|
1608
|
+
connectedTo: msg.from,
|
|
1609
|
+
validationErrors: [
|
|
1610
|
+
...import_value2.Value.Errors(
|
|
1611
|
+
this.handshakeExtensions.schema,
|
|
1612
|
+
msg.payload.metadata
|
|
1613
|
+
)
|
|
1614
|
+
]
|
|
1615
|
+
}
|
|
1616
|
+
);
|
|
1617
|
+
return;
|
|
1618
|
+
}
|
|
1619
|
+
const previousParsedMetadata = oldSession ? this.sessionHandshakeMetadata.get(oldSession.to) : void 0;
|
|
1620
|
+
const parsedMetadataOrFailureCode = await this.handshakeExtensions.validate(
|
|
1621
|
+
msg.payload.metadata,
|
|
1622
|
+
previousParsedMetadata
|
|
1623
|
+
);
|
|
1624
|
+
if (session._isConsumed) {
|
|
1625
|
+
return;
|
|
1626
|
+
}
|
|
1627
|
+
if (import_value2.Value.Check(
|
|
1628
|
+
HandshakeErrorCustomHandlerFatalResponseCodes,
|
|
1629
|
+
parsedMetadataOrFailureCode
|
|
1630
|
+
)) {
|
|
1631
|
+
this.rejectHandshakeRequest(
|
|
1632
|
+
session,
|
|
1633
|
+
msg.from,
|
|
1634
|
+
"rejected by handshake handler",
|
|
1635
|
+
parsedMetadataOrFailureCode,
|
|
1636
|
+
{
|
|
1637
|
+
...session.loggingMetadata,
|
|
1638
|
+
connectedTo: msg.from,
|
|
1639
|
+
clientId: this.clientId
|
|
1640
|
+
}
|
|
1641
|
+
);
|
|
1642
|
+
return;
|
|
1643
|
+
}
|
|
1644
|
+
parsedMetadata = parsedMetadataOrFailureCode;
|
|
1522
1645
|
}
|
|
1523
1646
|
let connectCase = "new session";
|
|
1524
1647
|
const clientNextExpectedSeq = msg.payload.expectedSessionState.nextExpectedSeq;
|
|
1525
1648
|
const clientNextSentSeq = msg.payload.expectedSessionState.nextSentSeq ?? 0;
|
|
1526
|
-
if (oldSession && oldSession.id === msg.payload.sessionId) {
|
|
1649
|
+
if (this.options.enableTransparentSessionReconnects && oldSession && oldSession.id === msg.payload.sessionId) {
|
|
1527
1650
|
connectCase = "transparent reconnection";
|
|
1528
1651
|
const ourNextSeq = oldSession.nextSeq();
|
|
1529
1652
|
const ourAck = oldSession.ack;
|
|
@@ -1582,10 +1705,11 @@ var ServerTransport = class extends Transport {
|
|
|
1582
1705
|
}
|
|
1583
1706
|
if (!oldSession && (clientNextSentSeq > 0 || clientNextExpectedSeq > 0)) {
|
|
1584
1707
|
connectCase = "unknown session";
|
|
1708
|
+
const rejectionMessage = this.options.enableTransparentSessionReconnects ? `client is trying to reconnect to a session the server don't know about: ${msg.payload.sessionId}` : `client is attempting a transparent reconnect to a session but the server does not support it: ${msg.payload.sessionId}`;
|
|
1585
1709
|
this.rejectHandshakeRequest(
|
|
1586
1710
|
session,
|
|
1587
1711
|
msg.from,
|
|
1588
|
-
|
|
1712
|
+
rejectionMessage,
|
|
1589
1713
|
"SESSION_STATE_MISMATCH",
|
|
1590
1714
|
{
|
|
1591
1715
|
...session.loggingMetadata,
|
|
@@ -1649,47 +1773,6 @@ var ServerTransport = class extends Transport {
|
|
|
1649
1773
|
this.pendingSessions.delete(session);
|
|
1650
1774
|
connectedSession.startActiveHeartbeat();
|
|
1651
1775
|
}
|
|
1652
|
-
async validateHandshakeMetadata(handshakingSession, existingSession, rawMetadata, from) {
|
|
1653
|
-
if (!this.handshakeExtensions) {
|
|
1654
|
-
return {};
|
|
1655
|
-
}
|
|
1656
|
-
if (!import_value2.Value.Check(this.handshakeExtensions.schema, rawMetadata)) {
|
|
1657
|
-
this.rejectHandshakeRequest(
|
|
1658
|
-
handshakingSession,
|
|
1659
|
-
from,
|
|
1660
|
-
"received malformed handshake metadata",
|
|
1661
|
-
"MALFORMED_HANDSHAKE_META",
|
|
1662
|
-
{
|
|
1663
|
-
...handshakingSession.loggingMetadata,
|
|
1664
|
-
connectedTo: from,
|
|
1665
|
-
validationErrors: [
|
|
1666
|
-
...import_value2.Value.Errors(this.handshakeExtensions.schema, rawMetadata)
|
|
1667
|
-
]
|
|
1668
|
-
}
|
|
1669
|
-
);
|
|
1670
|
-
return false;
|
|
1671
|
-
}
|
|
1672
|
-
const previousParsedMetadata = existingSession ? this.sessionHandshakeMetadata.get(existingSession.to) : void 0;
|
|
1673
|
-
const parsedMetadata = await this.handshakeExtensions.validate(
|
|
1674
|
-
rawMetadata,
|
|
1675
|
-
previousParsedMetadata
|
|
1676
|
-
);
|
|
1677
|
-
if (import_value2.Value.Check(HandshakeErrorCustomHandlerFatalResponseCodes, parsedMetadata)) {
|
|
1678
|
-
this.rejectHandshakeRequest(
|
|
1679
|
-
handshakingSession,
|
|
1680
|
-
from,
|
|
1681
|
-
"rejected by handshake handler",
|
|
1682
|
-
parsedMetadata,
|
|
1683
|
-
{
|
|
1684
|
-
...handshakingSession.loggingMetadata,
|
|
1685
|
-
connectedTo: from,
|
|
1686
|
-
clientId: this.clientId
|
|
1687
|
-
}
|
|
1688
|
-
);
|
|
1689
|
-
return false;
|
|
1690
|
-
}
|
|
1691
|
-
return parsedMetadata;
|
|
1692
|
-
}
|
|
1693
1776
|
};
|
|
1694
1777
|
|
|
1695
1778
|
// transport/impls/ws/server.ts
|