@replit/river 0.207.2 → 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-4HE7UYRL.js → chunk-B7REV3ZV.js} +6 -5
- package/dist/{chunk-4HE7UYRL.js.map → chunk-B7REV3ZV.js.map} +1 -1
- package/dist/{chunk-24EWYOGK.js → chunk-BO7MFCO6.js} +1136 -143
- package/dist/chunk-BO7MFCO6.js.map +1 -0
- package/dist/{chunk-46IVOKJU.js → chunk-QGPYCXV4.js} +2 -2
- package/dist/{chunk-46IVOKJU.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-a18e31d5.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-43528f4b.d.ts → services-87887bc5.d.ts} +16 -12
- package/dist/testUtil/index.cjs +809 -657
- 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 -204
- 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 -128
- 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 -270
- 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-24EWYOGK.js.map +0 -1
- package/dist/chunk-A7RGOVRV.js +0 -438
- package/dist/chunk-A7RGOVRV.js.map +0 -1
- package/dist/chunk-AJGIY2UB.js +0 -56
- package/dist/chunk-AJGIY2UB.js.map +0 -1
- package/dist/chunk-XV4RQ62N.js +0 -377
- package/dist/chunk-XV4RQ62N.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,25 +832,15 @@ var SessionConnected = class extends IdentifiedSession {
|
|
|
836
832
|
conn;
|
|
837
833
|
listeners;
|
|
838
834
|
heartbeatHandle;
|
|
839
|
-
|
|
840
|
-
isActivelyHeartbeating;
|
|
841
|
-
lastConstructedMsgs = [];
|
|
842
|
-
pushLastConstructedMsgs = (msg) => {
|
|
843
|
-
const trackedMsg = {
|
|
844
|
-
id: msg.id,
|
|
845
|
-
seq: msg.seq,
|
|
846
|
-
streamId: msg.streamId,
|
|
847
|
-
stack: new Error().stack
|
|
848
|
-
};
|
|
849
|
-
this.lastConstructedMsgs.push(trackedMsg);
|
|
850
|
-
if (this.lastConstructedMsgs.length > 10) {
|
|
851
|
-
this.lastConstructedMsgs.shift();
|
|
852
|
-
}
|
|
853
|
-
};
|
|
835
|
+
heartbeatMissTimeout;
|
|
836
|
+
isActivelyHeartbeating = false;
|
|
854
837
|
updateBookkeeping(ack, seq) {
|
|
855
838
|
this.sendBuffer = this.sendBuffer.filter((unacked) => unacked.seq >= ack);
|
|
856
839
|
this.ack = seq + 1;
|
|
857
|
-
this.
|
|
840
|
+
if (this.heartbeatMissTimeout) {
|
|
841
|
+
clearTimeout(this.heartbeatMissTimeout);
|
|
842
|
+
}
|
|
843
|
+
this.startMissingHeartbeatTimeout();
|
|
858
844
|
}
|
|
859
845
|
assertSendOrdering(constructedMsg) {
|
|
860
846
|
if (constructedMsg.seq > this.seqSent + 1) {
|
|
@@ -862,22 +848,22 @@ var SessionConnected = class extends IdentifiedSession {
|
|
|
862
848
|
this.log?.error(msg, {
|
|
863
849
|
...this.loggingMetadata,
|
|
864
850
|
transportMessage: constructedMsg,
|
|
865
|
-
tags: ["invariant-violation"]
|
|
866
|
-
extras: {
|
|
867
|
-
lastConstructedMsgs: this.lastConstructedMsgs
|
|
868
|
-
}
|
|
851
|
+
tags: ["invariant-violation"]
|
|
869
852
|
});
|
|
870
853
|
throw new Error(msg);
|
|
871
854
|
}
|
|
872
855
|
}
|
|
873
856
|
send(msg) {
|
|
874
857
|
const constructedMsg = this.constructMsg(msg);
|
|
875
|
-
this.pushLastConstructedMsgs(constructedMsg);
|
|
876
858
|
this.assertSendOrdering(constructedMsg);
|
|
877
859
|
this.sendBuffer.push(constructedMsg);
|
|
878
|
-
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
|
+
}
|
|
879
865
|
this.seqSent = constructedMsg.seq;
|
|
880
|
-
return
|
|
866
|
+
return res;
|
|
881
867
|
}
|
|
882
868
|
constructor(props) {
|
|
883
869
|
super(props);
|
|
@@ -886,6 +872,8 @@ var SessionConnected = class extends IdentifiedSession {
|
|
|
886
872
|
this.conn.addDataListener(this.onMessageData);
|
|
887
873
|
this.conn.addCloseListener(this.listeners.onConnectionClosed);
|
|
888
874
|
this.conn.addErrorListener(this.listeners.onConnectionErrored);
|
|
875
|
+
}
|
|
876
|
+
sendBufferedMessages() {
|
|
889
877
|
if (this.sendBuffer.length > 0) {
|
|
890
878
|
this.log?.info(
|
|
891
879
|
`sending ${this.sendBuffer.length} buffered messages, starting at seq ${this.nextSeq()}`,
|
|
@@ -893,30 +881,15 @@ var SessionConnected = class extends IdentifiedSession {
|
|
|
893
881
|
);
|
|
894
882
|
for (const msg of this.sendBuffer) {
|
|
895
883
|
this.assertSendOrdering(msg);
|
|
896
|
-
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
|
+
}
|
|
897
889
|
this.seqSent = msg.seq;
|
|
898
890
|
}
|
|
899
891
|
}
|
|
900
|
-
|
|
901
|
-
this.heartbeatHandle = setInterval(() => {
|
|
902
|
-
const misses = this.heartbeatMisses;
|
|
903
|
-
const missDuration = misses * this.options.heartbeatIntervalMs;
|
|
904
|
-
if (misses >= this.options.heartbeatsUntilDead) {
|
|
905
|
-
this.log?.info(
|
|
906
|
-
`closing connection to ${this.to} due to inactivity (missed ${misses} heartbeats which is ${missDuration}ms)`,
|
|
907
|
-
this.loggingMetadata
|
|
908
|
-
);
|
|
909
|
-
this.telemetry.span.addEvent("closing connection due to inactivity");
|
|
910
|
-
this.conn.close();
|
|
911
|
-
clearInterval(this.heartbeatHandle);
|
|
912
|
-
this.heartbeatHandle = void 0;
|
|
913
|
-
return;
|
|
914
|
-
}
|
|
915
|
-
if (this.isActivelyHeartbeating) {
|
|
916
|
-
this.sendHeartbeat();
|
|
917
|
-
}
|
|
918
|
-
this.heartbeatMisses++;
|
|
919
|
-
}, this.options.heartbeatIntervalMs);
|
|
892
|
+
return { ok: true, value: void 0 };
|
|
920
893
|
}
|
|
921
894
|
get loggingMetadata() {
|
|
922
895
|
return {
|
|
@@ -924,25 +897,46 @@ var SessionConnected = class extends IdentifiedSession {
|
|
|
924
897
|
...this.conn.loggingMetadata
|
|
925
898
|
};
|
|
926
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
|
+
}
|
|
927
914
|
startActiveHeartbeat() {
|
|
928
915
|
this.isActivelyHeartbeating = true;
|
|
916
|
+
this.heartbeatHandle = setInterval(() => {
|
|
917
|
+
this.sendHeartbeat();
|
|
918
|
+
}, this.options.heartbeatIntervalMs);
|
|
929
919
|
}
|
|
930
920
|
sendHeartbeat() {
|
|
931
921
|
this.log?.debug("sending heartbeat", this.loggingMetadata);
|
|
932
|
-
|
|
922
|
+
const heartbeat = {
|
|
933
923
|
streamId: "heartbeat",
|
|
934
924
|
controlFlags: 1 /* AckBit */,
|
|
935
925
|
payload: {
|
|
936
926
|
type: "ACK"
|
|
937
927
|
}
|
|
938
|
-
}
|
|
928
|
+
};
|
|
929
|
+
this.send(heartbeat);
|
|
939
930
|
}
|
|
940
931
|
onMessageData = (msg) => {
|
|
941
|
-
const
|
|
942
|
-
if (
|
|
943
|
-
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
|
+
);
|
|
944
937
|
return;
|
|
945
938
|
}
|
|
939
|
+
const parsedMsg = parsedMsgRes.value;
|
|
946
940
|
if (parsedMsg.seq !== this.ack) {
|
|
947
941
|
if (parsedMsg.seq < this.ack) {
|
|
948
942
|
this.log?.debug(
|
|
@@ -981,9 +975,7 @@ var SessionConnected = class extends IdentifiedSession {
|
|
|
981
975
|
transportMessage: parsedMsg
|
|
982
976
|
});
|
|
983
977
|
if (!this.isActivelyHeartbeating) {
|
|
984
|
-
|
|
985
|
-
this.sendHeartbeat();
|
|
986
|
-
});
|
|
978
|
+
this.sendHeartbeat();
|
|
987
979
|
}
|
|
988
980
|
};
|
|
989
981
|
_handleStateExit() {
|
|
@@ -995,6 +987,10 @@ var SessionConnected = class extends IdentifiedSession {
|
|
|
995
987
|
clearInterval(this.heartbeatHandle);
|
|
996
988
|
this.heartbeatHandle = void 0;
|
|
997
989
|
}
|
|
990
|
+
if (this.heartbeatMissTimeout) {
|
|
991
|
+
clearTimeout(this.heartbeatMissTimeout);
|
|
992
|
+
this.heartbeatMissTimeout = void 0;
|
|
993
|
+
}
|
|
998
994
|
}
|
|
999
995
|
_handleClose() {
|
|
1000
996
|
super._handleClose();
|
|
@@ -1026,6 +1022,136 @@ var SessionBackingOff = class extends IdentifiedSessionWithGracePeriod {
|
|
|
1026
1022
|
}
|
|
1027
1023
|
};
|
|
1028
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
|
+
|
|
1029
1155
|
// transport/sessionStateMachine/transitions.ts
|
|
1030
1156
|
function inheritSharedSession(session) {
|
|
1031
1157
|
return {
|
|
@@ -1040,7 +1166,8 @@ function inheritSharedSession(session) {
|
|
|
1040
1166
|
options: session.options,
|
|
1041
1167
|
log: session.log,
|
|
1042
1168
|
tracer: session.tracer,
|
|
1043
|
-
protocolVersion: session.protocolVersion
|
|
1169
|
+
protocolVersion: session.protocolVersion,
|
|
1170
|
+
codec: session.codec
|
|
1044
1171
|
};
|
|
1045
1172
|
}
|
|
1046
1173
|
function inheritSharedSessionWithGrace(session) {
|
|
@@ -1069,7 +1196,8 @@ var SessionStateGraph = {
|
|
|
1069
1196
|
options,
|
|
1070
1197
|
protocolVersion,
|
|
1071
1198
|
tracer,
|
|
1072
|
-
log
|
|
1199
|
+
log,
|
|
1200
|
+
codec: new CodecMessageAdapter(options.codec)
|
|
1073
1201
|
});
|
|
1074
1202
|
session.log?.info(`session ${session.id} created in NoConnection state`, {
|
|
1075
1203
|
...session.loggingMetadata,
|
|
@@ -1084,7 +1212,8 @@ var SessionStateGraph = {
|
|
|
1084
1212
|
from,
|
|
1085
1213
|
options,
|
|
1086
1214
|
tracer,
|
|
1087
|
-
log
|
|
1215
|
+
log,
|
|
1216
|
+
codec: new CodecMessageAdapter(options.codec)
|
|
1088
1217
|
});
|
|
1089
1218
|
session.log?.info(`session created in WaitingForHandshake state`, {
|
|
1090
1219
|
...session.loggingMetadata,
|
|
@@ -1162,6 +1291,7 @@ var SessionStateGraph = {
|
|
|
1162
1291
|
listeners,
|
|
1163
1292
|
...carriedState
|
|
1164
1293
|
});
|
|
1294
|
+
session.startMissingHeartbeatTimeout();
|
|
1165
1295
|
session.log?.info(
|
|
1166
1296
|
`session ${session.id} transition from Handshaking to Connected`,
|
|
1167
1297
|
{
|
|
@@ -1197,7 +1327,8 @@ var SessionStateGraph = {
|
|
|
1197
1327
|
options,
|
|
1198
1328
|
tracer: pendingSession.tracer,
|
|
1199
1329
|
log: pendingSession.log,
|
|
1200
|
-
protocolVersion
|
|
1330
|
+
protocolVersion,
|
|
1331
|
+
codec: new CodecMessageAdapter(options.codec)
|
|
1201
1332
|
}
|
|
1202
1333
|
);
|
|
1203
1334
|
pendingSession._handleStateExit();
|
|
@@ -1207,6 +1338,7 @@ var SessionStateGraph = {
|
|
|
1207
1338
|
listeners,
|
|
1208
1339
|
...carriedState
|
|
1209
1340
|
});
|
|
1341
|
+
session.startMissingHeartbeatTimeout();
|
|
1210
1342
|
conn.telemetry = createConnectionTelemetryInfo(
|
|
1211
1343
|
session.tracer,
|
|
1212
1344
|
conn,
|
|
@@ -1547,12 +1679,16 @@ var Transport = class {
|
|
|
1547
1679
|
);
|
|
1548
1680
|
}
|
|
1549
1681
|
const sameSession = session.id === sessionId;
|
|
1550
|
-
if (!sameSession) {
|
|
1682
|
+
if (!sameSession || session._isConsumed) {
|
|
1551
1683
|
throw new Error(
|
|
1552
1684
|
`session scope for ${sessionId} has ended (transition), can't send`
|
|
1553
1685
|
);
|
|
1554
1686
|
}
|
|
1555
|
-
|
|
1687
|
+
const res = session.send(msg);
|
|
1688
|
+
if (!res.ok) {
|
|
1689
|
+
throw new Error(res.reason);
|
|
1690
|
+
}
|
|
1691
|
+
return res.value;
|
|
1556
1692
|
};
|
|
1557
1693
|
}
|
|
1558
1694
|
};
|
|
@@ -1753,13 +1889,41 @@ var ClientTransport = class extends Transport {
|
|
|
1753
1889
|
this.handleMsg(msg2);
|
|
1754
1890
|
},
|
|
1755
1891
|
onInvalidMessage: (reason) => {
|
|
1756
|
-
this.
|
|
1892
|
+
this.log?.error(`invalid message: ${reason}`, {
|
|
1893
|
+
...connectedSession.loggingMetadata,
|
|
1894
|
+
transportMessage: msg
|
|
1895
|
+
});
|
|
1757
1896
|
this.protocolError({
|
|
1758
1897
|
type: ProtocolError.InvalidMessage,
|
|
1759
1898
|
message: reason
|
|
1760
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 });
|
|
1761
1912
|
}
|
|
1762
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
|
+
}
|
|
1763
1927
|
this.updateSession(connectedSession);
|
|
1764
1928
|
this.retryBudget.startRestoringBudget();
|
|
1765
1929
|
}
|
|
@@ -1898,7 +2062,18 @@ var ClientTransport = class extends Transport {
|
|
|
1898
2062
|
...session.loggingMetadata,
|
|
1899
2063
|
transportMessage: requestMsg
|
|
1900
2064
|
});
|
|
1901
|
-
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
|
+
}
|
|
1902
2077
|
}
|
|
1903
2078
|
close() {
|
|
1904
2079
|
this.retryBudget.close();
|
|
@@ -1906,93 +2081,6 @@ var ClientTransport = class extends Transport {
|
|
|
1906
2081
|
}
|
|
1907
2082
|
};
|
|
1908
2083
|
|
|
1909
|
-
// transport/connection.ts
|
|
1910
|
-
var Connection = class {
|
|
1911
|
-
id;
|
|
1912
|
-
telemetry;
|
|
1913
|
-
constructor() {
|
|
1914
|
-
this.id = `conn-${generateId()}`;
|
|
1915
|
-
}
|
|
1916
|
-
get loggingMetadata() {
|
|
1917
|
-
const metadata = { connId: this.id };
|
|
1918
|
-
if (this.telemetry?.span.isRecording()) {
|
|
1919
|
-
const spanContext = this.telemetry.span.spanContext();
|
|
1920
|
-
metadata.telemetry = {
|
|
1921
|
-
traceId: spanContext.traceId,
|
|
1922
|
-
spanId: spanContext.spanId
|
|
1923
|
-
};
|
|
1924
|
-
}
|
|
1925
|
-
return metadata;
|
|
1926
|
-
}
|
|
1927
|
-
// can't use event emitter because we need this to work in both node + browser
|
|
1928
|
-
_dataListeners = /* @__PURE__ */ new Set();
|
|
1929
|
-
_closeListeners = /* @__PURE__ */ new Set();
|
|
1930
|
-
_errorListeners = /* @__PURE__ */ new Set();
|
|
1931
|
-
get dataListeners() {
|
|
1932
|
-
return [...this._dataListeners];
|
|
1933
|
-
}
|
|
1934
|
-
get closeListeners() {
|
|
1935
|
-
return [...this._closeListeners];
|
|
1936
|
-
}
|
|
1937
|
-
get errorListeners() {
|
|
1938
|
-
return [...this._errorListeners];
|
|
1939
|
-
}
|
|
1940
|
-
onData(msg) {
|
|
1941
|
-
for (const cb of this.dataListeners) {
|
|
1942
|
-
cb(msg);
|
|
1943
|
-
}
|
|
1944
|
-
}
|
|
1945
|
-
onError(err) {
|
|
1946
|
-
for (const cb of this.errorListeners) {
|
|
1947
|
-
cb(err);
|
|
1948
|
-
}
|
|
1949
|
-
}
|
|
1950
|
-
onClose() {
|
|
1951
|
-
for (const cb of this.closeListeners) {
|
|
1952
|
-
cb();
|
|
1953
|
-
}
|
|
1954
|
-
this.telemetry?.span.end();
|
|
1955
|
-
}
|
|
1956
|
-
/**
|
|
1957
|
-
* Handle adding a callback for when a message is received.
|
|
1958
|
-
* @param msg The message that was received.
|
|
1959
|
-
*/
|
|
1960
|
-
addDataListener(cb) {
|
|
1961
|
-
this._dataListeners.add(cb);
|
|
1962
|
-
}
|
|
1963
|
-
removeDataListener(cb) {
|
|
1964
|
-
this._dataListeners.delete(cb);
|
|
1965
|
-
}
|
|
1966
|
-
/**
|
|
1967
|
-
* Handle adding a callback for when the connection is closed.
|
|
1968
|
-
* This should also be called if an error happens and after notifying all the error listeners.
|
|
1969
|
-
* @param cb The callback to call when the connection is closed.
|
|
1970
|
-
*/
|
|
1971
|
-
addCloseListener(cb) {
|
|
1972
|
-
this._closeListeners.add(cb);
|
|
1973
|
-
}
|
|
1974
|
-
removeCloseListener(cb) {
|
|
1975
|
-
this._closeListeners.delete(cb);
|
|
1976
|
-
}
|
|
1977
|
-
/**
|
|
1978
|
-
* Handle adding a callback for when an error is received.
|
|
1979
|
-
* This should only be used for this.logging errors, all cleanup
|
|
1980
|
-
* should be delegated to addCloseListener.
|
|
1981
|
-
*
|
|
1982
|
-
* The implementer should take care such that the implemented
|
|
1983
|
-
* connection will call both the close and error callbacks
|
|
1984
|
-
* on an error.
|
|
1985
|
-
*
|
|
1986
|
-
* @param cb The callback to call when an error is received.
|
|
1987
|
-
*/
|
|
1988
|
-
addErrorListener(cb) {
|
|
1989
|
-
this._errorListeners.add(cb);
|
|
1990
|
-
}
|
|
1991
|
-
removeErrorListener(cb) {
|
|
1992
|
-
this._errorListeners.delete(cb);
|
|
1993
|
-
}
|
|
1994
|
-
};
|
|
1995
|
-
|
|
1996
2084
|
// transport/impls/ws/connection.ts
|
|
1997
2085
|
var WS_HEALTHY_CLOSE_CODE = 1e3;
|
|
1998
2086
|
var WebSocketConnection = class extends Connection {
|
|
@@ -2028,11 +2116,12 @@ var WebSocketConnection = class extends Connection {
|
|
|
2028
2116
|
};
|
|
2029
2117
|
}
|
|
2030
2118
|
send(payload) {
|
|
2031
|
-
|
|
2119
|
+
try {
|
|
2120
|
+
this.ws.send(payload);
|
|
2121
|
+
return true;
|
|
2122
|
+
} catch {
|
|
2032
2123
|
return false;
|
|
2033
2124
|
}
|
|
2034
|
-
this.ws.send(payload);
|
|
2035
|
-
return true;
|
|
2036
2125
|
}
|
|
2037
2126
|
close() {
|
|
2038
2127
|
this.ws.close(WS_HEALTHY_CLOSE_CODE);
|