@replit/river 0.207.1 → 0.207.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/adapter-f2b6e211.d.ts +46 -0
- package/dist/{chunk-7LMZNSVC.js → chunk-B7REV3ZV.js} +6 -5
- package/dist/{chunk-7LMZNSVC.js.map → chunk-B7REV3ZV.js.map} +1 -1
- package/dist/{chunk-QMAVXV4Z.js → chunk-BO7MFCO6.js} +1136 -132
- package/dist/chunk-BO7MFCO6.js.map +1 -0
- package/dist/{chunk-BCCZA7SX.js → chunk-QGPYCXV4.js} +2 -2
- package/dist/{chunk-BCCZA7SX.js.map → chunk-QGPYCXV4.js.map} +1 -1
- package/dist/codec/index.cjs +157 -23
- package/dist/codec/index.cjs.map +1 -1
- package/dist/codec/index.d.cts +5 -1
- package/dist/codec/index.d.ts +5 -1
- package/dist/codec/index.js +6 -20
- package/dist/codec/index.js.map +1 -1
- package/dist/{connection-933c87b2.d.ts → connection-06d72f2e.d.ts} +3 -2
- package/dist/index-02554794.d.ts +37 -0
- package/dist/logging/index.d.cts +2 -1
- package/dist/logging/index.d.ts +2 -1
- package/dist/{message-ffacb98a.d.ts → message-01c3e85a.d.ts} +1 -35
- package/dist/router/index.cjs +1 -1
- package/dist/router/index.cjs.map +1 -1
- package/dist/router/index.d.cts +6 -5
- package/dist/router/index.d.ts +6 -5
- package/dist/router/index.js +1 -1
- package/dist/{services-4cd29829.d.ts → services-87887bc5.d.ts} +16 -11
- package/dist/testUtil/index.cjs +992 -829
- package/dist/testUtil/index.cjs.map +1 -1
- package/dist/testUtil/index.d.cts +4 -3
- package/dist/testUtil/index.d.ts +4 -3
- package/dist/testUtil/index.js +18 -13
- package/dist/testUtil/index.js.map +1 -1
- package/dist/transport/impls/ws/client.cjs +293 -193
- 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 +5 -7
- package/dist/transport/impls/ws/client.js.map +1 -1
- package/dist/transport/impls/ws/server.cjs +230 -117
- 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 -7
- package/dist/transport/impls/ws/server.js.map +1 -1
- package/dist/transport/index.cjs +408 -259
- package/dist/transport/index.cjs.map +1 -1
- package/dist/transport/index.d.cts +7 -6
- package/dist/transport/index.d.ts +7 -6
- package/dist/transport/index.js +4 -9
- package/package.json +1 -1
- package/dist/chunk-AJGIY2UB.js +0 -56
- package/dist/chunk-AJGIY2UB.js.map +0 -1
- package/dist/chunk-CRD3HDVN.js +0 -438
- package/dist/chunk-CRD3HDVN.js.map +0 -1
- package/dist/chunk-I27WBSMZ.js +0 -377
- package/dist/chunk-I27WBSMZ.js.map +0 -1
- package/dist/chunk-QMAVXV4Z.js.map +0 -1
- package/dist/types-3e5768ec.d.ts +0 -20
|
@@ -186,23 +186,20 @@ var NaiveJsonCodec = {
|
|
|
186
186
|
);
|
|
187
187
|
},
|
|
188
188
|
fromBuffer: (buff) => {
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
return val;
|
|
197
|
-
}
|
|
189
|
+
const parsed = JSON.parse(
|
|
190
|
+
decoder.decode(buff),
|
|
191
|
+
function reviver(_key, val) {
|
|
192
|
+
if (val?.$t) {
|
|
193
|
+
return base64ToUint8Array(val.$t);
|
|
194
|
+
} else {
|
|
195
|
+
return val;
|
|
198
196
|
}
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
} catch {
|
|
204
|
-
return null;
|
|
197
|
+
}
|
|
198
|
+
);
|
|
199
|
+
if (typeof parsed !== "object" || parsed === null) {
|
|
200
|
+
throw new Error("unpacked msg is not an object");
|
|
205
201
|
}
|
|
202
|
+
return parsed;
|
|
206
203
|
}
|
|
207
204
|
};
|
|
208
205
|
|
|
@@ -366,7 +363,8 @@ var ProtocolError = {
|
|
|
366
363
|
RetriesExceeded: "conn_retry_exceeded",
|
|
367
364
|
HandshakeFailed: "handshake_failed",
|
|
368
365
|
MessageOrderingViolated: "message_ordering_violated",
|
|
369
|
-
InvalidMessage: "invalid_message"
|
|
366
|
+
InvalidMessage: "invalid_message",
|
|
367
|
+
MessageSendFailure: "message_send_failure"
|
|
370
368
|
};
|
|
371
369
|
var EventDispatcher = class {
|
|
372
370
|
eventListeners = {};
|
|
@@ -400,7 +398,6 @@ var EventDispatcher = class {
|
|
|
400
398
|
};
|
|
401
399
|
|
|
402
400
|
// transport/sessionStateMachine/common.ts
|
|
403
|
-
var import_value = require("@sinclair/typebox/value");
|
|
404
401
|
var ERR_CONSUMED = `session state has been consumed and is no longer valid`;
|
|
405
402
|
var StateMachineState = class {
|
|
406
403
|
/*
|
|
@@ -460,34 +457,16 @@ var StateMachineState = class {
|
|
|
460
457
|
var CommonSession = class extends StateMachineState {
|
|
461
458
|
from;
|
|
462
459
|
options;
|
|
460
|
+
codec;
|
|
463
461
|
tracer;
|
|
464
462
|
log;
|
|
465
|
-
constructor({ from, options, log, tracer }) {
|
|
463
|
+
constructor({ from, options, log, tracer, codec }) {
|
|
466
464
|
super();
|
|
467
465
|
this.from = from;
|
|
468
466
|
this.options = options;
|
|
469
467
|
this.log = log;
|
|
470
468
|
this.tracer = tracer;
|
|
471
|
-
|
|
472
|
-
parseMsg(msg) {
|
|
473
|
-
const parsedMsg = this.options.codec.fromBuffer(msg);
|
|
474
|
-
if (parsedMsg === null) {
|
|
475
|
-
this.log?.error(
|
|
476
|
-
`received malformed msg: ${Buffer.from(msg).toString("base64")}`,
|
|
477
|
-
this.loggingMetadata
|
|
478
|
-
);
|
|
479
|
-
return null;
|
|
480
|
-
}
|
|
481
|
-
if (!import_value.Value.Check(OpaqueTransportMessageSchema, parsedMsg)) {
|
|
482
|
-
this.log?.error(`received invalid msg: ${JSON.stringify(parsedMsg)}`, {
|
|
483
|
-
...this.loggingMetadata,
|
|
484
|
-
validationErrors: [
|
|
485
|
-
...import_value.Value.Errors(OpaqueTransportMessageSchema, parsedMsg)
|
|
486
|
-
]
|
|
487
|
-
});
|
|
488
|
-
return null;
|
|
489
|
-
}
|
|
490
|
-
return parsedMsg;
|
|
469
|
+
this.codec = codec;
|
|
491
470
|
}
|
|
492
471
|
};
|
|
493
472
|
var IdentifiedSession = class extends CommonSession {
|
|
@@ -547,9 +526,6 @@ var IdentifiedSession = class extends CommonSession {
|
|
|
547
526
|
return metadata;
|
|
548
527
|
}
|
|
549
528
|
constructMsg(partialMsg) {
|
|
550
|
-
if (this._isConsumed) {
|
|
551
|
-
throw new Error(ERR_CONSUMED);
|
|
552
|
-
}
|
|
553
529
|
const msg = {
|
|
554
530
|
...partialMsg,
|
|
555
531
|
id: generateId(),
|
|
@@ -567,7 +543,10 @@ var IdentifiedSession = class extends CommonSession {
|
|
|
567
543
|
send(msg) {
|
|
568
544
|
const constructedMsg = this.constructMsg(msg);
|
|
569
545
|
this.sendBuffer.push(constructedMsg);
|
|
570
|
-
return
|
|
546
|
+
return {
|
|
547
|
+
ok: true,
|
|
548
|
+
value: constructedMsg.id
|
|
549
|
+
};
|
|
571
550
|
}
|
|
572
551
|
_handleStateExit() {
|
|
573
552
|
}
|
|
@@ -599,6 +578,23 @@ var IdentifiedSessionWithGracePeriod = class extends IdentifiedSession {
|
|
|
599
578
|
super._handleClose();
|
|
600
579
|
}
|
|
601
580
|
};
|
|
581
|
+
function sendMessage(conn, codec, msg) {
|
|
582
|
+
const buff = codec.toBuffer(msg);
|
|
583
|
+
if (!buff.ok) {
|
|
584
|
+
return buff;
|
|
585
|
+
}
|
|
586
|
+
const sent = conn.send(buff.value);
|
|
587
|
+
if (!sent) {
|
|
588
|
+
return {
|
|
589
|
+
ok: false,
|
|
590
|
+
reason: "failed to send message"
|
|
591
|
+
};
|
|
592
|
+
}
|
|
593
|
+
return {
|
|
594
|
+
ok: true,
|
|
595
|
+
value: msg.id
|
|
596
|
+
};
|
|
597
|
+
}
|
|
602
598
|
|
|
603
599
|
// transport/sessionStateMachine/SessionConnecting.ts
|
|
604
600
|
var SessionConnecting = class extends IdentifiedSessionWithGracePeriod {
|
|
@@ -651,8 +647,8 @@ var SessionConnecting = class extends IdentifiedSessionWithGracePeriod {
|
|
|
651
647
|
}
|
|
652
648
|
}
|
|
653
649
|
_handleClose() {
|
|
654
|
-
this.bestEffortClose();
|
|
655
650
|
super._handleClose();
|
|
651
|
+
this.bestEffortClose();
|
|
656
652
|
}
|
|
657
653
|
};
|
|
658
654
|
|
|
@@ -679,7 +675,7 @@ function coerceErrorString(err) {
|
|
|
679
675
|
}
|
|
680
676
|
|
|
681
677
|
// package.json
|
|
682
|
-
var version = "0.207.
|
|
678
|
+
var version = "0.207.3";
|
|
683
679
|
|
|
684
680
|
// tracing/index.ts
|
|
685
681
|
function getPropagationContext(ctx) {
|
|
@@ -751,18 +747,18 @@ var SessionWaitingForHandshake = class extends CommonSession {
|
|
|
751
747
|
};
|
|
752
748
|
}
|
|
753
749
|
onHandshakeData = (msg) => {
|
|
754
|
-
const
|
|
755
|
-
if (
|
|
750
|
+
const parsedMsgRes = this.codec.fromBuffer(msg);
|
|
751
|
+
if (!parsedMsgRes.ok) {
|
|
756
752
|
this.listeners.onInvalidHandshake(
|
|
757
|
-
|
|
753
|
+
`could not parse handshake message: ${parsedMsgRes.reason}`,
|
|
758
754
|
"MALFORMED_HANDSHAKE"
|
|
759
755
|
);
|
|
760
756
|
return;
|
|
761
757
|
}
|
|
762
|
-
this.listeners.onHandshake(
|
|
758
|
+
this.listeners.onHandshake(parsedMsgRes.value);
|
|
763
759
|
};
|
|
764
760
|
sendHandshake(msg) {
|
|
765
|
-
return this.conn
|
|
761
|
+
return sendMessage(this.conn, this.codec, msg);
|
|
766
762
|
}
|
|
767
763
|
_handleStateExit() {
|
|
768
764
|
this.conn.removeDataListener(this.onHandshakeData);
|
|
@@ -800,18 +796,18 @@ var SessionHandshaking = class extends IdentifiedSessionWithGracePeriod {
|
|
|
800
796
|
};
|
|
801
797
|
}
|
|
802
798
|
onHandshakeData = (msg) => {
|
|
803
|
-
const
|
|
804
|
-
if (
|
|
799
|
+
const parsedMsgRes = this.codec.fromBuffer(msg);
|
|
800
|
+
if (!parsedMsgRes.ok) {
|
|
805
801
|
this.listeners.onInvalidHandshake(
|
|
806
|
-
|
|
802
|
+
`could not parse handshake message: ${parsedMsgRes.reason}`,
|
|
807
803
|
"MALFORMED_HANDSHAKE"
|
|
808
804
|
);
|
|
809
805
|
return;
|
|
810
806
|
}
|
|
811
|
-
this.listeners.onHandshake(
|
|
807
|
+
this.listeners.onHandshake(parsedMsgRes.value);
|
|
812
808
|
};
|
|
813
809
|
sendHandshake(msg) {
|
|
814
|
-
return this.conn
|
|
810
|
+
return sendMessage(this.conn, this.codec, msg);
|
|
815
811
|
}
|
|
816
812
|
_handleStateExit() {
|
|
817
813
|
super._handleStateExit();
|
|
@@ -836,12 +832,15 @@ var SessionConnected = class extends IdentifiedSession {
|
|
|
836
832
|
conn;
|
|
837
833
|
listeners;
|
|
838
834
|
heartbeatHandle;
|
|
839
|
-
|
|
840
|
-
isActivelyHeartbeating;
|
|
835
|
+
heartbeatMissTimeout;
|
|
836
|
+
isActivelyHeartbeating = false;
|
|
841
837
|
updateBookkeeping(ack, seq) {
|
|
842
838
|
this.sendBuffer = this.sendBuffer.filter((unacked) => unacked.seq >= ack);
|
|
843
839
|
this.ack = seq + 1;
|
|
844
|
-
this.
|
|
840
|
+
if (this.heartbeatMissTimeout) {
|
|
841
|
+
clearTimeout(this.heartbeatMissTimeout);
|
|
842
|
+
}
|
|
843
|
+
this.startMissingHeartbeatTimeout();
|
|
845
844
|
}
|
|
846
845
|
assertSendOrdering(constructedMsg) {
|
|
847
846
|
if (constructedMsg.seq > this.seqSent + 1) {
|
|
@@ -858,9 +857,13 @@ var SessionConnected = class extends IdentifiedSession {
|
|
|
858
857
|
const constructedMsg = this.constructMsg(msg);
|
|
859
858
|
this.assertSendOrdering(constructedMsg);
|
|
860
859
|
this.sendBuffer.push(constructedMsg);
|
|
861
|
-
this.conn
|
|
860
|
+
const res = sendMessage(this.conn, this.codec, constructedMsg);
|
|
861
|
+
if (!res.ok) {
|
|
862
|
+
this.listeners.onMessageSendFailure(constructedMsg, res.reason);
|
|
863
|
+
return res;
|
|
864
|
+
}
|
|
862
865
|
this.seqSent = constructedMsg.seq;
|
|
863
|
-
return
|
|
866
|
+
return res;
|
|
864
867
|
}
|
|
865
868
|
constructor(props) {
|
|
866
869
|
super(props);
|
|
@@ -869,6 +872,8 @@ var SessionConnected = class extends IdentifiedSession {
|
|
|
869
872
|
this.conn.addDataListener(this.onMessageData);
|
|
870
873
|
this.conn.addCloseListener(this.listeners.onConnectionClosed);
|
|
871
874
|
this.conn.addErrorListener(this.listeners.onConnectionErrored);
|
|
875
|
+
}
|
|
876
|
+
sendBufferedMessages() {
|
|
872
877
|
if (this.sendBuffer.length > 0) {
|
|
873
878
|
this.log?.info(
|
|
874
879
|
`sending ${this.sendBuffer.length} buffered messages, starting at seq ${this.nextSeq()}`,
|
|
@@ -876,30 +881,15 @@ var SessionConnected = class extends IdentifiedSession {
|
|
|
876
881
|
);
|
|
877
882
|
for (const msg of this.sendBuffer) {
|
|
878
883
|
this.assertSendOrdering(msg);
|
|
879
|
-
this.conn
|
|
884
|
+
const res = sendMessage(this.conn, this.codec, msg);
|
|
885
|
+
if (!res.ok) {
|
|
886
|
+
this.listeners.onMessageSendFailure(msg, res.reason);
|
|
887
|
+
return res;
|
|
888
|
+
}
|
|
880
889
|
this.seqSent = msg.seq;
|
|
881
890
|
}
|
|
882
891
|
}
|
|
883
|
-
|
|
884
|
-
this.heartbeatHandle = setInterval(() => {
|
|
885
|
-
const misses = this.heartbeatMisses;
|
|
886
|
-
const missDuration = misses * this.options.heartbeatIntervalMs;
|
|
887
|
-
if (misses >= this.options.heartbeatsUntilDead) {
|
|
888
|
-
this.log?.info(
|
|
889
|
-
`closing connection to ${this.to} due to inactivity (missed ${misses} heartbeats which is ${missDuration}ms)`,
|
|
890
|
-
this.loggingMetadata
|
|
891
|
-
);
|
|
892
|
-
this.telemetry.span.addEvent("closing connection due to inactivity");
|
|
893
|
-
this.conn.close();
|
|
894
|
-
clearInterval(this.heartbeatHandle);
|
|
895
|
-
this.heartbeatHandle = void 0;
|
|
896
|
-
return;
|
|
897
|
-
}
|
|
898
|
-
if (this.isActivelyHeartbeating) {
|
|
899
|
-
this.sendHeartbeat();
|
|
900
|
-
}
|
|
901
|
-
this.heartbeatMisses++;
|
|
902
|
-
}, this.options.heartbeatIntervalMs);
|
|
892
|
+
return { ok: true, value: void 0 };
|
|
903
893
|
}
|
|
904
894
|
get loggingMetadata() {
|
|
905
895
|
return {
|
|
@@ -907,31 +897,46 @@ var SessionConnected = class extends IdentifiedSession {
|
|
|
907
897
|
...this.conn.loggingMetadata
|
|
908
898
|
};
|
|
909
899
|
}
|
|
900
|
+
startMissingHeartbeatTimeout() {
|
|
901
|
+
const maxMisses = this.options.heartbeatsUntilDead;
|
|
902
|
+
const missDuration = maxMisses * this.options.heartbeatIntervalMs;
|
|
903
|
+
this.heartbeatMissTimeout = setTimeout(() => {
|
|
904
|
+
this.log?.info(
|
|
905
|
+
`closing connection to ${this.to} due to inactivity (missed ${maxMisses} heartbeats which is ${missDuration}ms)`,
|
|
906
|
+
this.loggingMetadata
|
|
907
|
+
);
|
|
908
|
+
this.telemetry.span.addEvent(
|
|
909
|
+
"closing connection due to missing heartbeat"
|
|
910
|
+
);
|
|
911
|
+
this.conn.close();
|
|
912
|
+
}, missDuration);
|
|
913
|
+
}
|
|
910
914
|
startActiveHeartbeat() {
|
|
911
915
|
this.isActivelyHeartbeating = true;
|
|
916
|
+
this.heartbeatHandle = setInterval(() => {
|
|
917
|
+
this.sendHeartbeat();
|
|
918
|
+
}, this.options.heartbeatIntervalMs);
|
|
912
919
|
}
|
|
913
920
|
sendHeartbeat() {
|
|
914
921
|
this.log?.debug("sending heartbeat", this.loggingMetadata);
|
|
915
|
-
|
|
922
|
+
const heartbeat = {
|
|
916
923
|
streamId: "heartbeat",
|
|
917
924
|
controlFlags: 1 /* AckBit */,
|
|
918
925
|
payload: {
|
|
919
926
|
type: "ACK"
|
|
920
927
|
}
|
|
921
|
-
}
|
|
922
|
-
|
|
923
|
-
closeConnection() {
|
|
924
|
-
this.conn.removeDataListener(this.onMessageData);
|
|
925
|
-
this.conn.removeCloseListener(this.listeners.onConnectionClosed);
|
|
926
|
-
this.conn.removeErrorListener(this.listeners.onConnectionErrored);
|
|
927
|
-
this.conn.close();
|
|
928
|
+
};
|
|
929
|
+
this.send(heartbeat);
|
|
928
930
|
}
|
|
929
931
|
onMessageData = (msg) => {
|
|
930
|
-
const
|
|
931
|
-
if (
|
|
932
|
-
this.listeners.onInvalidMessage(
|
|
932
|
+
const parsedMsgRes = this.codec.fromBuffer(msg);
|
|
933
|
+
if (!parsedMsgRes.ok) {
|
|
934
|
+
this.listeners.onInvalidMessage(
|
|
935
|
+
`could not parse message: ${parsedMsgRes.reason}`
|
|
936
|
+
);
|
|
933
937
|
return;
|
|
934
938
|
}
|
|
939
|
+
const parsedMsg = parsedMsgRes.value;
|
|
935
940
|
if (parsedMsg.seq !== this.ack) {
|
|
936
941
|
if (parsedMsg.seq < this.ack) {
|
|
937
942
|
this.log?.debug(
|
|
@@ -952,7 +957,7 @@ var SessionConnected = class extends IdentifiedSession {
|
|
|
952
957
|
code: import_api3.SpanStatusCode.ERROR,
|
|
953
958
|
message: reason
|
|
954
959
|
});
|
|
955
|
-
this.
|
|
960
|
+
this.conn.close();
|
|
956
961
|
}
|
|
957
962
|
return;
|
|
958
963
|
}
|
|
@@ -970,9 +975,7 @@ var SessionConnected = class extends IdentifiedSession {
|
|
|
970
975
|
transportMessage: parsedMsg
|
|
971
976
|
});
|
|
972
977
|
if (!this.isActivelyHeartbeating) {
|
|
973
|
-
|
|
974
|
-
this.sendHeartbeat();
|
|
975
|
-
});
|
|
978
|
+
this.sendHeartbeat();
|
|
976
979
|
}
|
|
977
980
|
};
|
|
978
981
|
_handleStateExit() {
|
|
@@ -984,6 +987,10 @@ var SessionConnected = class extends IdentifiedSession {
|
|
|
984
987
|
clearInterval(this.heartbeatHandle);
|
|
985
988
|
this.heartbeatHandle = void 0;
|
|
986
989
|
}
|
|
990
|
+
if (this.heartbeatMissTimeout) {
|
|
991
|
+
clearTimeout(this.heartbeatMissTimeout);
|
|
992
|
+
this.heartbeatMissTimeout = void 0;
|
|
993
|
+
}
|
|
987
994
|
}
|
|
988
995
|
_handleClose() {
|
|
989
996
|
super._handleClose();
|
|
@@ -1015,6 +1022,136 @@ var SessionBackingOff = class extends IdentifiedSessionWithGracePeriod {
|
|
|
1015
1022
|
}
|
|
1016
1023
|
};
|
|
1017
1024
|
|
|
1025
|
+
// codec/adapter.ts
|
|
1026
|
+
var import_value = require("@sinclair/typebox/value");
|
|
1027
|
+
|
|
1028
|
+
// transport/connection.ts
|
|
1029
|
+
var Connection = class {
|
|
1030
|
+
id;
|
|
1031
|
+
telemetry;
|
|
1032
|
+
constructor() {
|
|
1033
|
+
this.id = `conn-${generateId()}`;
|
|
1034
|
+
}
|
|
1035
|
+
get loggingMetadata() {
|
|
1036
|
+
const metadata = { connId: this.id };
|
|
1037
|
+
if (this.telemetry?.span.isRecording()) {
|
|
1038
|
+
const spanContext = this.telemetry.span.spanContext();
|
|
1039
|
+
metadata.telemetry = {
|
|
1040
|
+
traceId: spanContext.traceId,
|
|
1041
|
+
spanId: spanContext.spanId
|
|
1042
|
+
};
|
|
1043
|
+
}
|
|
1044
|
+
return metadata;
|
|
1045
|
+
}
|
|
1046
|
+
// can't use event emitter because we need this to work in both node + browser
|
|
1047
|
+
_dataListeners = /* @__PURE__ */ new Set();
|
|
1048
|
+
_closeListeners = /* @__PURE__ */ new Set();
|
|
1049
|
+
_errorListeners = /* @__PURE__ */ new Set();
|
|
1050
|
+
get dataListeners() {
|
|
1051
|
+
return [...this._dataListeners];
|
|
1052
|
+
}
|
|
1053
|
+
get closeListeners() {
|
|
1054
|
+
return [...this._closeListeners];
|
|
1055
|
+
}
|
|
1056
|
+
get errorListeners() {
|
|
1057
|
+
return [...this._errorListeners];
|
|
1058
|
+
}
|
|
1059
|
+
onData(msg) {
|
|
1060
|
+
for (const cb of this.dataListeners) {
|
|
1061
|
+
cb(msg);
|
|
1062
|
+
}
|
|
1063
|
+
}
|
|
1064
|
+
onError(err) {
|
|
1065
|
+
for (const cb of this.errorListeners) {
|
|
1066
|
+
cb(err);
|
|
1067
|
+
}
|
|
1068
|
+
}
|
|
1069
|
+
onClose() {
|
|
1070
|
+
for (const cb of this.closeListeners) {
|
|
1071
|
+
cb();
|
|
1072
|
+
}
|
|
1073
|
+
this.telemetry?.span.end();
|
|
1074
|
+
}
|
|
1075
|
+
/**
|
|
1076
|
+
* Handle adding a callback for when a message is received.
|
|
1077
|
+
* @param msg The message that was received.
|
|
1078
|
+
*/
|
|
1079
|
+
addDataListener(cb) {
|
|
1080
|
+
this._dataListeners.add(cb);
|
|
1081
|
+
}
|
|
1082
|
+
removeDataListener(cb) {
|
|
1083
|
+
this._dataListeners.delete(cb);
|
|
1084
|
+
}
|
|
1085
|
+
/**
|
|
1086
|
+
* Handle adding a callback for when the connection is closed.
|
|
1087
|
+
* This should also be called if an error happens and after notifying all the error listeners.
|
|
1088
|
+
* @param cb The callback to call when the connection is closed.
|
|
1089
|
+
*/
|
|
1090
|
+
addCloseListener(cb) {
|
|
1091
|
+
this._closeListeners.add(cb);
|
|
1092
|
+
}
|
|
1093
|
+
removeCloseListener(cb) {
|
|
1094
|
+
this._closeListeners.delete(cb);
|
|
1095
|
+
}
|
|
1096
|
+
/**
|
|
1097
|
+
* Handle adding a callback for when an error is received.
|
|
1098
|
+
* This should only be used for this.logging errors, all cleanup
|
|
1099
|
+
* should be delegated to addCloseListener.
|
|
1100
|
+
*
|
|
1101
|
+
* The implementer should take care such that the implemented
|
|
1102
|
+
* connection will call both the close and error callbacks
|
|
1103
|
+
* on an error.
|
|
1104
|
+
*
|
|
1105
|
+
* @param cb The callback to call when an error is received.
|
|
1106
|
+
*/
|
|
1107
|
+
addErrorListener(cb) {
|
|
1108
|
+
this._errorListeners.add(cb);
|
|
1109
|
+
}
|
|
1110
|
+
removeErrorListener(cb) {
|
|
1111
|
+
this._errorListeners.delete(cb);
|
|
1112
|
+
}
|
|
1113
|
+
};
|
|
1114
|
+
|
|
1115
|
+
// codec/adapter.ts
|
|
1116
|
+
var CodecMessageAdapter = class {
|
|
1117
|
+
constructor(codec) {
|
|
1118
|
+
this.codec = codec;
|
|
1119
|
+
}
|
|
1120
|
+
toBuffer(msg) {
|
|
1121
|
+
try {
|
|
1122
|
+
return {
|
|
1123
|
+
ok: true,
|
|
1124
|
+
value: this.codec.toBuffer(msg)
|
|
1125
|
+
};
|
|
1126
|
+
} catch (e) {
|
|
1127
|
+
return {
|
|
1128
|
+
ok: false,
|
|
1129
|
+
reason: coerceErrorString(e)
|
|
1130
|
+
};
|
|
1131
|
+
}
|
|
1132
|
+
}
|
|
1133
|
+
fromBuffer(buf) {
|
|
1134
|
+
try {
|
|
1135
|
+
const parsedMsg = this.codec.fromBuffer(buf);
|
|
1136
|
+
if (!import_value.Value.Check(OpaqueTransportMessageSchema, parsedMsg)) {
|
|
1137
|
+
return {
|
|
1138
|
+
ok: false,
|
|
1139
|
+
reason: "transport message schema mismatch"
|
|
1140
|
+
};
|
|
1141
|
+
}
|
|
1142
|
+
return {
|
|
1143
|
+
ok: true,
|
|
1144
|
+
value: parsedMsg
|
|
1145
|
+
};
|
|
1146
|
+
} catch (e) {
|
|
1147
|
+
return {
|
|
1148
|
+
ok: false,
|
|
1149
|
+
reason: coerceErrorString(e)
|
|
1150
|
+
};
|
|
1151
|
+
}
|
|
1152
|
+
}
|
|
1153
|
+
};
|
|
1154
|
+
|
|
1018
1155
|
// transport/sessionStateMachine/transitions.ts
|
|
1019
1156
|
function inheritSharedSession(session) {
|
|
1020
1157
|
return {
|
|
@@ -1029,7 +1166,8 @@ function inheritSharedSession(session) {
|
|
|
1029
1166
|
options: session.options,
|
|
1030
1167
|
log: session.log,
|
|
1031
1168
|
tracer: session.tracer,
|
|
1032
|
-
protocolVersion: session.protocolVersion
|
|
1169
|
+
protocolVersion: session.protocolVersion,
|
|
1170
|
+
codec: session.codec
|
|
1033
1171
|
};
|
|
1034
1172
|
}
|
|
1035
1173
|
function inheritSharedSessionWithGrace(session) {
|
|
@@ -1058,7 +1196,8 @@ var SessionStateGraph = {
|
|
|
1058
1196
|
options,
|
|
1059
1197
|
protocolVersion,
|
|
1060
1198
|
tracer,
|
|
1061
|
-
log
|
|
1199
|
+
log,
|
|
1200
|
+
codec: new CodecMessageAdapter(options.codec)
|
|
1062
1201
|
});
|
|
1063
1202
|
session.log?.info(`session ${session.id} created in NoConnection state`, {
|
|
1064
1203
|
...session.loggingMetadata,
|
|
@@ -1073,7 +1212,8 @@ var SessionStateGraph = {
|
|
|
1073
1212
|
from,
|
|
1074
1213
|
options,
|
|
1075
1214
|
tracer,
|
|
1076
|
-
log
|
|
1215
|
+
log,
|
|
1216
|
+
codec: new CodecMessageAdapter(options.codec)
|
|
1077
1217
|
});
|
|
1078
1218
|
session.log?.info(`session created in WaitingForHandshake state`, {
|
|
1079
1219
|
...session.loggingMetadata,
|
|
@@ -1151,6 +1291,7 @@ var SessionStateGraph = {
|
|
|
1151
1291
|
listeners,
|
|
1152
1292
|
...carriedState
|
|
1153
1293
|
});
|
|
1294
|
+
session.startMissingHeartbeatTimeout();
|
|
1154
1295
|
session.log?.info(
|
|
1155
1296
|
`session ${session.id} transition from Handshaking to Connected`,
|
|
1156
1297
|
{
|
|
@@ -1186,7 +1327,8 @@ var SessionStateGraph = {
|
|
|
1186
1327
|
options,
|
|
1187
1328
|
tracer: pendingSession.tracer,
|
|
1188
1329
|
log: pendingSession.log,
|
|
1189
|
-
protocolVersion
|
|
1330
|
+
protocolVersion,
|
|
1331
|
+
codec: new CodecMessageAdapter(options.codec)
|
|
1190
1332
|
}
|
|
1191
1333
|
);
|
|
1192
1334
|
pendingSession._handleStateExit();
|
|
@@ -1196,6 +1338,7 @@ var SessionStateGraph = {
|
|
|
1196
1338
|
listeners,
|
|
1197
1339
|
...carriedState
|
|
1198
1340
|
});
|
|
1341
|
+
session.startMissingHeartbeatTimeout();
|
|
1199
1342
|
conn.telemetry = createConnectionTelemetryInfo(
|
|
1200
1343
|
session.tracer,
|
|
1201
1344
|
conn,
|
|
@@ -1536,12 +1679,16 @@ var Transport = class {
|
|
|
1536
1679
|
);
|
|
1537
1680
|
}
|
|
1538
1681
|
const sameSession = session.id === sessionId;
|
|
1539
|
-
if (!sameSession) {
|
|
1682
|
+
if (!sameSession || session._isConsumed) {
|
|
1540
1683
|
throw new Error(
|
|
1541
1684
|
`session scope for ${sessionId} has ended (transition), can't send`
|
|
1542
1685
|
);
|
|
1543
1686
|
}
|
|
1544
|
-
|
|
1687
|
+
const res = session.send(msg);
|
|
1688
|
+
if (!res.ok) {
|
|
1689
|
+
throw new Error(res.reason);
|
|
1690
|
+
}
|
|
1691
|
+
return res.value;
|
|
1545
1692
|
};
|
|
1546
1693
|
}
|
|
1547
1694
|
};
|
|
@@ -1742,13 +1889,41 @@ var ClientTransport = class extends Transport {
|
|
|
1742
1889
|
this.handleMsg(msg2);
|
|
1743
1890
|
},
|
|
1744
1891
|
onInvalidMessage: (reason) => {
|
|
1745
|
-
this.
|
|
1892
|
+
this.log?.error(`invalid message: ${reason}`, {
|
|
1893
|
+
...connectedSession.loggingMetadata,
|
|
1894
|
+
transportMessage: msg
|
|
1895
|
+
});
|
|
1746
1896
|
this.protocolError({
|
|
1747
1897
|
type: ProtocolError.InvalidMessage,
|
|
1748
1898
|
message: reason
|
|
1749
1899
|
});
|
|
1900
|
+
this.deleteSession(connectedSession, { unhealthy: true });
|
|
1901
|
+
},
|
|
1902
|
+
onMessageSendFailure: (msg2, reason) => {
|
|
1903
|
+
this.log?.error(`failed to send message: ${reason}`, {
|
|
1904
|
+
...connectedSession.loggingMetadata,
|
|
1905
|
+
transportMessage: msg2
|
|
1906
|
+
});
|
|
1907
|
+
this.protocolError({
|
|
1908
|
+
type: ProtocolError.MessageSendFailure,
|
|
1909
|
+
message: reason
|
|
1910
|
+
});
|
|
1911
|
+
this.deleteSession(connectedSession, { unhealthy: true });
|
|
1750
1912
|
}
|
|
1751
1913
|
});
|
|
1914
|
+
const res = connectedSession.sendBufferedMessages();
|
|
1915
|
+
if (!res.ok) {
|
|
1916
|
+
this.log?.error(`failed to send buffered messages: ${res.reason}`, {
|
|
1917
|
+
...connectedSession.loggingMetadata,
|
|
1918
|
+
transportMessage: msg
|
|
1919
|
+
});
|
|
1920
|
+
this.protocolError({
|
|
1921
|
+
type: ProtocolError.MessageSendFailure,
|
|
1922
|
+
message: res.reason
|
|
1923
|
+
});
|
|
1924
|
+
this.deleteSession(connectedSession, { unhealthy: true });
|
|
1925
|
+
return;
|
|
1926
|
+
}
|
|
1752
1927
|
this.updateSession(connectedSession);
|
|
1753
1928
|
this.retryBudget.startRestoringBudget();
|
|
1754
1929
|
}
|
|
@@ -1887,7 +2062,18 @@ var ClientTransport = class extends Transport {
|
|
|
1887
2062
|
...session.loggingMetadata,
|
|
1888
2063
|
transportMessage: requestMsg
|
|
1889
2064
|
});
|
|
1890
|
-
session.sendHandshake(requestMsg);
|
|
2065
|
+
const res = session.sendHandshake(requestMsg);
|
|
2066
|
+
if (!res.ok) {
|
|
2067
|
+
this.log?.error(`failed to send handshake request: ${res.reason}`, {
|
|
2068
|
+
...session.loggingMetadata,
|
|
2069
|
+
transportMessage: requestMsg
|
|
2070
|
+
});
|
|
2071
|
+
this.protocolError({
|
|
2072
|
+
type: ProtocolError.MessageSendFailure,
|
|
2073
|
+
message: res.reason
|
|
2074
|
+
});
|
|
2075
|
+
this.deleteSession(session, { unhealthy: true });
|
|
2076
|
+
}
|
|
1891
2077
|
}
|
|
1892
2078
|
close() {
|
|
1893
2079
|
this.retryBudget.close();
|
|
@@ -1895,93 +2081,6 @@ var ClientTransport = class extends Transport {
|
|
|
1895
2081
|
}
|
|
1896
2082
|
};
|
|
1897
2083
|
|
|
1898
|
-
// transport/connection.ts
|
|
1899
|
-
var Connection = class {
|
|
1900
|
-
id;
|
|
1901
|
-
telemetry;
|
|
1902
|
-
constructor() {
|
|
1903
|
-
this.id = `conn-${generateId()}`;
|
|
1904
|
-
}
|
|
1905
|
-
get loggingMetadata() {
|
|
1906
|
-
const metadata = { connId: this.id };
|
|
1907
|
-
if (this.telemetry?.span.isRecording()) {
|
|
1908
|
-
const spanContext = this.telemetry.span.spanContext();
|
|
1909
|
-
metadata.telemetry = {
|
|
1910
|
-
traceId: spanContext.traceId,
|
|
1911
|
-
spanId: spanContext.spanId
|
|
1912
|
-
};
|
|
1913
|
-
}
|
|
1914
|
-
return metadata;
|
|
1915
|
-
}
|
|
1916
|
-
// can't use event emitter because we need this to work in both node + browser
|
|
1917
|
-
_dataListeners = /* @__PURE__ */ new Set();
|
|
1918
|
-
_closeListeners = /* @__PURE__ */ new Set();
|
|
1919
|
-
_errorListeners = /* @__PURE__ */ new Set();
|
|
1920
|
-
get dataListeners() {
|
|
1921
|
-
return [...this._dataListeners];
|
|
1922
|
-
}
|
|
1923
|
-
get closeListeners() {
|
|
1924
|
-
return [...this._closeListeners];
|
|
1925
|
-
}
|
|
1926
|
-
get errorListeners() {
|
|
1927
|
-
return [...this._errorListeners];
|
|
1928
|
-
}
|
|
1929
|
-
onData(msg) {
|
|
1930
|
-
for (const cb of this.dataListeners) {
|
|
1931
|
-
cb(msg);
|
|
1932
|
-
}
|
|
1933
|
-
}
|
|
1934
|
-
onError(err) {
|
|
1935
|
-
for (const cb of this.errorListeners) {
|
|
1936
|
-
cb(err);
|
|
1937
|
-
}
|
|
1938
|
-
}
|
|
1939
|
-
onClose() {
|
|
1940
|
-
for (const cb of this.closeListeners) {
|
|
1941
|
-
cb();
|
|
1942
|
-
}
|
|
1943
|
-
this.telemetry?.span.end();
|
|
1944
|
-
}
|
|
1945
|
-
/**
|
|
1946
|
-
* Handle adding a callback for when a message is received.
|
|
1947
|
-
* @param msg The message that was received.
|
|
1948
|
-
*/
|
|
1949
|
-
addDataListener(cb) {
|
|
1950
|
-
this._dataListeners.add(cb);
|
|
1951
|
-
}
|
|
1952
|
-
removeDataListener(cb) {
|
|
1953
|
-
this._dataListeners.delete(cb);
|
|
1954
|
-
}
|
|
1955
|
-
/**
|
|
1956
|
-
* Handle adding a callback for when the connection is closed.
|
|
1957
|
-
* This should also be called if an error happens and after notifying all the error listeners.
|
|
1958
|
-
* @param cb The callback to call when the connection is closed.
|
|
1959
|
-
*/
|
|
1960
|
-
addCloseListener(cb) {
|
|
1961
|
-
this._closeListeners.add(cb);
|
|
1962
|
-
}
|
|
1963
|
-
removeCloseListener(cb) {
|
|
1964
|
-
this._closeListeners.delete(cb);
|
|
1965
|
-
}
|
|
1966
|
-
/**
|
|
1967
|
-
* Handle adding a callback for when an error is received.
|
|
1968
|
-
* This should only be used for this.logging errors, all cleanup
|
|
1969
|
-
* should be delegated to addCloseListener.
|
|
1970
|
-
*
|
|
1971
|
-
* The implementer should take care such that the implemented
|
|
1972
|
-
* connection will call both the close and error callbacks
|
|
1973
|
-
* on an error.
|
|
1974
|
-
*
|
|
1975
|
-
* @param cb The callback to call when an error is received.
|
|
1976
|
-
*/
|
|
1977
|
-
addErrorListener(cb) {
|
|
1978
|
-
this._errorListeners.add(cb);
|
|
1979
|
-
}
|
|
1980
|
-
removeErrorListener(cb) {
|
|
1981
|
-
this._errorListeners.delete(cb);
|
|
1982
|
-
}
|
|
1983
|
-
};
|
|
1984
|
-
|
|
1985
2084
|
// transport/impls/ws/connection.ts
|
|
1986
2085
|
var WS_HEALTHY_CLOSE_CODE = 1e3;
|
|
1987
2086
|
var WebSocketConnection = class extends Connection {
|
|
@@ -2017,11 +2116,12 @@ var WebSocketConnection = class extends Connection {
|
|
|
2017
2116
|
};
|
|
2018
2117
|
}
|
|
2019
2118
|
send(payload) {
|
|
2020
|
-
|
|
2119
|
+
try {
|
|
2120
|
+
this.ws.send(payload);
|
|
2121
|
+
return true;
|
|
2122
|
+
} catch {
|
|
2021
2123
|
return false;
|
|
2022
2124
|
}
|
|
2023
|
-
this.ws.send(payload);
|
|
2024
|
-
return true;
|
|
2025
2125
|
}
|
|
2026
2126
|
close() {
|
|
2027
2127
|
this.ws.close(WS_HEALTHY_CLOSE_CODE);
|