@replit/river 0.23.12 → 0.23.14
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-3AW3IXVD.js → chunk-4PVU7J25.js} +1 -21
- package/dist/chunk-4PVU7J25.js.map +1 -0
- package/dist/{chunk-HDBVL7EF.js → chunk-BEALFLCB.js} +2 -2
- package/dist/chunk-D2DHRRBN.js +476 -0
- package/dist/chunk-D2DHRRBN.js.map +1 -0
- package/dist/{chunk-7RUKEUKE.js → chunk-GCCRVSMR.js} +33 -4
- package/dist/chunk-GCCRVSMR.js.map +1 -0
- package/dist/{chunk-XZ6IOBM5.js → chunk-GN4YEXT7.js} +2 -2
- package/dist/chunk-GN4YEXT7.js.map +1 -0
- package/dist/chunk-O2AVDJCQ.js +335 -0
- package/dist/chunk-O2AVDJCQ.js.map +1 -0
- package/dist/chunk-OTVTKAN6.js +451 -0
- package/dist/chunk-OTVTKAN6.js.map +1 -0
- package/dist/chunk-WUL63FR6.js +335 -0
- package/dist/chunk-WUL63FR6.js.map +1 -0
- package/dist/{chunk-H6KTH6W6.js → chunk-YCLZWES2.js} +2 -2
- package/dist/client-e13979ac.d.ts +52 -0
- package/dist/codec/index.js +20 -2
- package/dist/codec/index.js.map +1 -1
- package/dist/{connection-8debd45f.d.ts → connection-5d0978ce.d.ts} +1 -1
- package/dist/{connection-581558f8.d.ts → connection-e57e98ea.d.ts} +1 -1
- package/dist/{transport-47af1c81.d.ts → handshake-5665ffd3.d.ts} +101 -153
- package/dist/{index-60f03cb7.d.ts → index-ea74cdbb.d.ts} +1 -1
- package/dist/logging/index.d.cts +1 -1
- package/dist/logging/index.d.ts +1 -1
- package/dist/router/index.cjs +16 -1
- package/dist/router/index.cjs.map +1 -1
- package/dist/router/index.d.cts +8 -6
- package/dist/router/index.d.ts +8 -6
- package/dist/router/index.js +2 -2
- package/dist/server-1cfc88d1.d.ts +24 -0
- package/dist/{services-ca72c9f8.d.ts → services-86c4d10d.d.ts} +3 -2
- package/dist/transport/impls/uds/client.cjs +303 -180
- package/dist/transport/impls/uds/client.cjs.map +1 -1
- package/dist/transport/impls/uds/client.d.cts +6 -5
- package/dist/transport/impls/uds/client.d.ts +6 -5
- package/dist/transport/impls/uds/client.js +6 -4
- package/dist/transport/impls/uds/client.js.map +1 -1
- package/dist/transport/impls/uds/server.cjs +396 -234
- package/dist/transport/impls/uds/server.cjs.map +1 -1
- package/dist/transport/impls/uds/server.d.cts +6 -5
- package/dist/transport/impls/uds/server.d.ts +6 -5
- package/dist/transport/impls/uds/server.js +8 -6
- package/dist/transport/impls/uds/server.js.map +1 -1
- package/dist/transport/impls/ws/client.cjs +305 -182
- package/dist/transport/impls/ws/client.cjs.map +1 -1
- package/dist/transport/impls/ws/client.d.cts +6 -5
- package/dist/transport/impls/ws/client.d.ts +6 -5
- package/dist/transport/impls/ws/client.js +6 -4
- package/dist/transport/impls/ws/client.js.map +1 -1
- package/dist/transport/impls/ws/server.cjs +350 -188
- package/dist/transport/impls/ws/server.cjs.map +1 -1
- package/dist/transport/impls/ws/server.d.cts +4 -3
- package/dist/transport/impls/ws/server.d.ts +4 -3
- package/dist/transport/impls/ws/server.js +8 -6
- package/dist/transport/impls/ws/server.js.map +1 -1
- package/dist/transport/index.cjs +338 -142
- package/dist/transport/index.cjs.map +1 -1
- package/dist/transport/index.d.cts +4 -2
- package/dist/transport/index.d.ts +4 -2
- package/dist/transport/index.js +14 -8
- package/dist/util/testHelpers.cjs +10 -6
- 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 +4 -5
- package/dist/util/testHelpers.js.map +1 -1
- package/package.json +13 -14
- package/dist/chunk-3AW3IXVD.js.map +0 -1
- package/dist/chunk-7RUKEUKE.js.map +0 -1
- package/dist/chunk-VRU4IKRT.js +0 -1392
- package/dist/chunk-VRU4IKRT.js.map +0 -1
- package/dist/chunk-XZ6IOBM5.js.map +0 -1
- /package/dist/{chunk-HDBVL7EF.js.map → chunk-BEALFLCB.js.map} +0 -0
- /package/dist/{chunk-H6KTH6W6.js.map → chunk-YCLZWES2.js.map} +0 -0
package/dist/transport/index.cjs
CHANGED
|
@@ -66,6 +66,21 @@ var ControlMessageHandshakeRequestSchema = import_typebox.Type.Object({
|
|
|
66
66
|
type: import_typebox.Type.Literal("HANDSHAKE_REQ"),
|
|
67
67
|
protocolVersion: import_typebox.Type.String(),
|
|
68
68
|
sessionId: import_typebox.Type.String(),
|
|
69
|
+
/**
|
|
70
|
+
* Specifies what the server's expected session state (from the pov of the client). This can be
|
|
71
|
+
* used by the server to know whether this is a new or a reestablished connection, and whether it
|
|
72
|
+
* is compatible with what it already has.
|
|
73
|
+
*/
|
|
74
|
+
expectedSessionState: import_typebox.Type.Optional(
|
|
75
|
+
import_typebox.Type.Object({
|
|
76
|
+
/**
|
|
77
|
+
* reconnect is set to true if the client explicitly wants to reestablish an existing
|
|
78
|
+
* connection.
|
|
79
|
+
*/
|
|
80
|
+
reconnect: import_typebox.Type.Boolean(),
|
|
81
|
+
nextExpectedSeq: import_typebox.Type.Integer()
|
|
82
|
+
})
|
|
83
|
+
),
|
|
69
84
|
metadata: import_typebox.Type.Optional(import_typebox.Type.Unknown())
|
|
70
85
|
});
|
|
71
86
|
var ControlMessageHandshakeResponseSchema = import_typebox.Type.Object({
|
|
@@ -90,7 +105,14 @@ var ControlMessagePayloadSchema = import_typebox.Type.Union([
|
|
|
90
105
|
var OpaqueTransportMessageSchema = TransportMessageSchema(
|
|
91
106
|
import_typebox.Type.Unknown()
|
|
92
107
|
);
|
|
93
|
-
function handshakeRequestMessage(
|
|
108
|
+
function handshakeRequestMessage({
|
|
109
|
+
from,
|
|
110
|
+
to,
|
|
111
|
+
sessionId,
|
|
112
|
+
expectedSessionState,
|
|
113
|
+
metadata,
|
|
114
|
+
tracing
|
|
115
|
+
}) {
|
|
94
116
|
return {
|
|
95
117
|
id: (0, import_nanoid.nanoid)(),
|
|
96
118
|
from,
|
|
@@ -104,11 +126,17 @@ function handshakeRequestMessage(from, to, sessionId, metadata, tracing) {
|
|
|
104
126
|
type: "HANDSHAKE_REQ",
|
|
105
127
|
protocolVersion: PROTOCOL_VERSION,
|
|
106
128
|
sessionId,
|
|
129
|
+
expectedSessionState,
|
|
107
130
|
metadata
|
|
108
131
|
}
|
|
109
132
|
};
|
|
110
133
|
}
|
|
111
|
-
|
|
134
|
+
var SESSION_STATE_MISMATCH = "session state mismatch";
|
|
135
|
+
function handshakeResponseMessage({
|
|
136
|
+
from,
|
|
137
|
+
to,
|
|
138
|
+
status
|
|
139
|
+
}) {
|
|
112
140
|
return {
|
|
113
141
|
id: (0, import_nanoid.nanoid)(),
|
|
114
142
|
from,
|
|
@@ -224,7 +252,7 @@ var import_nanoid2 = require("nanoid");
|
|
|
224
252
|
var import_api = require("@opentelemetry/api");
|
|
225
253
|
|
|
226
254
|
// package.json
|
|
227
|
-
var version = "0.23.
|
|
255
|
+
var version = "0.23.14";
|
|
228
256
|
|
|
229
257
|
// tracing/index.ts
|
|
230
258
|
function getPropagationContext(ctx) {
|
|
@@ -538,9 +566,17 @@ var Session = class {
|
|
|
538
566
|
get connected() {
|
|
539
567
|
return this.connection !== void 0;
|
|
540
568
|
}
|
|
569
|
+
get nextExpectedAck() {
|
|
570
|
+
return this.seq;
|
|
571
|
+
}
|
|
541
572
|
get nextExpectedSeq() {
|
|
542
573
|
return this.ack;
|
|
543
574
|
}
|
|
575
|
+
// This is only used in tests to make the session misbehave.
|
|
576
|
+
/* @internal */
|
|
577
|
+
advanceAckForTesting(by) {
|
|
578
|
+
this.ack += by;
|
|
579
|
+
}
|
|
544
580
|
constructMsg(partialMsg) {
|
|
545
581
|
const msg = {
|
|
546
582
|
...partialMsg,
|
|
@@ -559,84 +595,8 @@ var Session = class {
|
|
|
559
595
|
}
|
|
560
596
|
};
|
|
561
597
|
|
|
562
|
-
//
|
|
563
|
-
|
|
564
|
-
if (err instanceof Error) {
|
|
565
|
-
return err.message || "unknown reason";
|
|
566
|
-
}
|
|
567
|
-
return `[coerced to error] ${String(err)}`;
|
|
568
|
-
}
|
|
569
|
-
|
|
570
|
-
// transport/rateLimit.ts
|
|
571
|
-
var LeakyBucketRateLimit = class {
|
|
572
|
-
budgetConsumed;
|
|
573
|
-
intervalHandles;
|
|
574
|
-
options;
|
|
575
|
-
constructor(options) {
|
|
576
|
-
this.options = options;
|
|
577
|
-
this.budgetConsumed = /* @__PURE__ */ new Map();
|
|
578
|
-
this.intervalHandles = /* @__PURE__ */ new Map();
|
|
579
|
-
}
|
|
580
|
-
getBackoffMs(user) {
|
|
581
|
-
if (!this.budgetConsumed.has(user))
|
|
582
|
-
return 0;
|
|
583
|
-
const exponent = Math.max(0, this.getBudgetConsumed(user) - 1);
|
|
584
|
-
const jitter = Math.floor(Math.random() * this.options.maxJitterMs);
|
|
585
|
-
const backoffMs = Math.min(
|
|
586
|
-
this.options.baseIntervalMs * 2 ** exponent,
|
|
587
|
-
this.options.maxBackoffMs
|
|
588
|
-
);
|
|
589
|
-
return backoffMs + jitter;
|
|
590
|
-
}
|
|
591
|
-
get totalBudgetRestoreTime() {
|
|
592
|
-
return this.options.budgetRestoreIntervalMs * this.options.attemptBudgetCapacity;
|
|
593
|
-
}
|
|
594
|
-
consumeBudget(user) {
|
|
595
|
-
this.stopLeak(user);
|
|
596
|
-
this.budgetConsumed.set(user, this.getBudgetConsumed(user) + 1);
|
|
597
|
-
}
|
|
598
|
-
getBudgetConsumed(user) {
|
|
599
|
-
return this.budgetConsumed.get(user) ?? 0;
|
|
600
|
-
}
|
|
601
|
-
hasBudget(user) {
|
|
602
|
-
return this.getBudgetConsumed(user) < this.options.attemptBudgetCapacity;
|
|
603
|
-
}
|
|
604
|
-
startRestoringBudget(user) {
|
|
605
|
-
if (this.intervalHandles.has(user)) {
|
|
606
|
-
return;
|
|
607
|
-
}
|
|
608
|
-
const restoreBudgetForUser = () => {
|
|
609
|
-
const currentBudget = this.budgetConsumed.get(user);
|
|
610
|
-
if (!currentBudget) {
|
|
611
|
-
this.stopLeak(user);
|
|
612
|
-
return;
|
|
613
|
-
}
|
|
614
|
-
const newBudget = currentBudget - 1;
|
|
615
|
-
if (newBudget === 0) {
|
|
616
|
-
this.budgetConsumed.delete(user);
|
|
617
|
-
return;
|
|
618
|
-
}
|
|
619
|
-
this.budgetConsumed.set(user, newBudget);
|
|
620
|
-
};
|
|
621
|
-
const intervalHandle = setInterval(
|
|
622
|
-
restoreBudgetForUser,
|
|
623
|
-
this.options.budgetRestoreIntervalMs
|
|
624
|
-
);
|
|
625
|
-
this.intervalHandles.set(user, intervalHandle);
|
|
626
|
-
}
|
|
627
|
-
stopLeak(user) {
|
|
628
|
-
if (!this.intervalHandles.has(user)) {
|
|
629
|
-
return;
|
|
630
|
-
}
|
|
631
|
-
clearInterval(this.intervalHandles.get(user));
|
|
632
|
-
this.intervalHandles.delete(user);
|
|
633
|
-
}
|
|
634
|
-
close() {
|
|
635
|
-
for (const user of this.intervalHandles.keys()) {
|
|
636
|
-
this.stopLeak(user);
|
|
637
|
-
}
|
|
638
|
-
}
|
|
639
|
-
};
|
|
598
|
+
// transport/transport.ts
|
|
599
|
+
var import_api3 = require("@opentelemetry/api");
|
|
640
600
|
|
|
641
601
|
// codec/json.ts
|
|
642
602
|
var encoder = new TextEncoder();
|
|
@@ -690,8 +650,7 @@ var NaiveJsonCodec = {
|
|
|
690
650
|
}
|
|
691
651
|
};
|
|
692
652
|
|
|
693
|
-
// transport/
|
|
694
|
-
var import_api3 = require("@opentelemetry/api");
|
|
653
|
+
// transport/options.ts
|
|
695
654
|
var defaultTransportOptions = {
|
|
696
655
|
heartbeatIntervalMs: 1e3,
|
|
697
656
|
heartbeatsUntilDead: 2,
|
|
@@ -712,6 +671,8 @@ var defaultClientTransportOptions = {
|
|
|
712
671
|
var defaultServerTransportOptions = {
|
|
713
672
|
...defaultTransportOptions
|
|
714
673
|
};
|
|
674
|
+
|
|
675
|
+
// transport/transport.ts
|
|
715
676
|
var Transport = class {
|
|
716
677
|
/**
|
|
717
678
|
* The status of the transport.
|
|
@@ -802,6 +763,49 @@ var Transport = class {
|
|
|
802
763
|
});
|
|
803
764
|
return session;
|
|
804
765
|
}
|
|
766
|
+
createNewSession({
|
|
767
|
+
to,
|
|
768
|
+
conn,
|
|
769
|
+
sessionId,
|
|
770
|
+
propagationCtx
|
|
771
|
+
}) {
|
|
772
|
+
let session = this.sessions.get(to);
|
|
773
|
+
if (session !== void 0) {
|
|
774
|
+
this.log?.info(
|
|
775
|
+
`session for ${to} already exists, replacing it with a new session as requested`,
|
|
776
|
+
session.loggingMetadata
|
|
777
|
+
);
|
|
778
|
+
this.deleteSession({
|
|
779
|
+
session,
|
|
780
|
+
closeHandshakingConnection: false
|
|
781
|
+
});
|
|
782
|
+
session = void 0;
|
|
783
|
+
}
|
|
784
|
+
session = this.createSession(to, conn, propagationCtx);
|
|
785
|
+
session.advertisedSessionId = sessionId;
|
|
786
|
+
this.log?.info(`created new session for ${to}`, session.loggingMetadata);
|
|
787
|
+
return session;
|
|
788
|
+
}
|
|
789
|
+
getExistingSession({
|
|
790
|
+
to,
|
|
791
|
+
sessionId,
|
|
792
|
+
nextExpectedSeq
|
|
793
|
+
}) {
|
|
794
|
+
const session = this.sessions.get(to);
|
|
795
|
+
if (
|
|
796
|
+
// reject this request if there was no previous session to replace
|
|
797
|
+
session === void 0 || // or if both parties do not agree about the next expected sequence number
|
|
798
|
+
session.nextExpectedAck < nextExpectedSeq || // or if both parties do not agree on the advertised session id
|
|
799
|
+
session.advertisedSessionId !== sessionId
|
|
800
|
+
) {
|
|
801
|
+
return false;
|
|
802
|
+
}
|
|
803
|
+
this.log?.info(
|
|
804
|
+
`reused existing session for ${to}`,
|
|
805
|
+
session.loggingMetadata
|
|
806
|
+
);
|
|
807
|
+
return session;
|
|
808
|
+
}
|
|
805
809
|
getOrCreateSession({
|
|
806
810
|
to,
|
|
807
811
|
conn,
|
|
@@ -866,6 +870,16 @@ var Transport = class {
|
|
|
866
870
|
* @param connectedTo The peer we are connected to.
|
|
867
871
|
*/
|
|
868
872
|
onDisconnect(conn, session) {
|
|
873
|
+
if (session.connection !== void 0 && session.connection.id !== conn.id) {
|
|
874
|
+
session.telemetry.span.addEvent("onDisconnect race");
|
|
875
|
+
this.log?.warn("onDisconnect race", {
|
|
876
|
+
clientId: this.clientId,
|
|
877
|
+
...session.loggingMetadata,
|
|
878
|
+
...conn.loggingMetadata,
|
|
879
|
+
tags: ["invariant-violation"]
|
|
880
|
+
});
|
|
881
|
+
return;
|
|
882
|
+
}
|
|
869
883
|
conn.telemetry?.span.end();
|
|
870
884
|
this.eventDispatcher.dispatchEvent("connectionStatus", {
|
|
871
885
|
status: "disconnect",
|
|
@@ -873,6 +887,16 @@ var Transport = class {
|
|
|
873
887
|
});
|
|
874
888
|
session.connection = void 0;
|
|
875
889
|
session.beginGrace(() => {
|
|
890
|
+
if (session.connection !== void 0) {
|
|
891
|
+
session.telemetry.span.addEvent("session grace period race");
|
|
892
|
+
this.log?.warn("session grace period race", {
|
|
893
|
+
clientId: this.clientId,
|
|
894
|
+
...session.loggingMetadata,
|
|
895
|
+
...conn.loggingMetadata,
|
|
896
|
+
tags: ["invariant-violation"]
|
|
897
|
+
});
|
|
898
|
+
return;
|
|
899
|
+
}
|
|
876
900
|
session.telemetry.span.addEvent("session grace period expired");
|
|
877
901
|
this.deleteSession({
|
|
878
902
|
session,
|
|
@@ -1040,6 +1064,91 @@ var Transport = class {
|
|
|
1040
1064
|
return this.status;
|
|
1041
1065
|
}
|
|
1042
1066
|
};
|
|
1067
|
+
|
|
1068
|
+
// transport/client.ts
|
|
1069
|
+
var import_api4 = require("@opentelemetry/api");
|
|
1070
|
+
|
|
1071
|
+
// transport/rateLimit.ts
|
|
1072
|
+
var LeakyBucketRateLimit = class {
|
|
1073
|
+
budgetConsumed;
|
|
1074
|
+
intervalHandles;
|
|
1075
|
+
options;
|
|
1076
|
+
constructor(options) {
|
|
1077
|
+
this.options = options;
|
|
1078
|
+
this.budgetConsumed = /* @__PURE__ */ new Map();
|
|
1079
|
+
this.intervalHandles = /* @__PURE__ */ new Map();
|
|
1080
|
+
}
|
|
1081
|
+
getBackoffMs(user) {
|
|
1082
|
+
if (!this.budgetConsumed.has(user))
|
|
1083
|
+
return 0;
|
|
1084
|
+
const exponent = Math.max(0, this.getBudgetConsumed(user) - 1);
|
|
1085
|
+
const jitter = Math.floor(Math.random() * this.options.maxJitterMs);
|
|
1086
|
+
const backoffMs = Math.min(
|
|
1087
|
+
this.options.baseIntervalMs * 2 ** exponent,
|
|
1088
|
+
this.options.maxBackoffMs
|
|
1089
|
+
);
|
|
1090
|
+
return backoffMs + jitter;
|
|
1091
|
+
}
|
|
1092
|
+
get totalBudgetRestoreTime() {
|
|
1093
|
+
return this.options.budgetRestoreIntervalMs * this.options.attemptBudgetCapacity;
|
|
1094
|
+
}
|
|
1095
|
+
consumeBudget(user) {
|
|
1096
|
+
this.stopLeak(user);
|
|
1097
|
+
this.budgetConsumed.set(user, this.getBudgetConsumed(user) + 1);
|
|
1098
|
+
}
|
|
1099
|
+
getBudgetConsumed(user) {
|
|
1100
|
+
return this.budgetConsumed.get(user) ?? 0;
|
|
1101
|
+
}
|
|
1102
|
+
hasBudget(user) {
|
|
1103
|
+
return this.getBudgetConsumed(user) < this.options.attemptBudgetCapacity;
|
|
1104
|
+
}
|
|
1105
|
+
startRestoringBudget(user) {
|
|
1106
|
+
if (this.intervalHandles.has(user)) {
|
|
1107
|
+
return;
|
|
1108
|
+
}
|
|
1109
|
+
const restoreBudgetForUser = () => {
|
|
1110
|
+
const currentBudget = this.budgetConsumed.get(user);
|
|
1111
|
+
if (!currentBudget) {
|
|
1112
|
+
this.stopLeak(user);
|
|
1113
|
+
return;
|
|
1114
|
+
}
|
|
1115
|
+
const newBudget = currentBudget - 1;
|
|
1116
|
+
if (newBudget === 0) {
|
|
1117
|
+
this.budgetConsumed.delete(user);
|
|
1118
|
+
return;
|
|
1119
|
+
}
|
|
1120
|
+
this.budgetConsumed.set(user, newBudget);
|
|
1121
|
+
};
|
|
1122
|
+
const intervalHandle = setInterval(
|
|
1123
|
+
restoreBudgetForUser,
|
|
1124
|
+
this.options.budgetRestoreIntervalMs
|
|
1125
|
+
);
|
|
1126
|
+
this.intervalHandles.set(user, intervalHandle);
|
|
1127
|
+
}
|
|
1128
|
+
stopLeak(user) {
|
|
1129
|
+
if (!this.intervalHandles.has(user)) {
|
|
1130
|
+
return;
|
|
1131
|
+
}
|
|
1132
|
+
clearInterval(this.intervalHandles.get(user));
|
|
1133
|
+
this.intervalHandles.delete(user);
|
|
1134
|
+
}
|
|
1135
|
+
close() {
|
|
1136
|
+
for (const user of this.intervalHandles.keys()) {
|
|
1137
|
+
this.stopLeak(user);
|
|
1138
|
+
}
|
|
1139
|
+
}
|
|
1140
|
+
};
|
|
1141
|
+
|
|
1142
|
+
// util/stringify.ts
|
|
1143
|
+
function coerceErrorString(err) {
|
|
1144
|
+
if (err instanceof Error) {
|
|
1145
|
+
return err.message || "unknown reason";
|
|
1146
|
+
}
|
|
1147
|
+
return `[coerced to error] ${String(err)}`;
|
|
1148
|
+
}
|
|
1149
|
+
|
|
1150
|
+
// transport/client.ts
|
|
1151
|
+
var import_value2 = require("@sinclair/typebox/value");
|
|
1043
1152
|
var ClientTransport = class extends Transport {
|
|
1044
1153
|
/**
|
|
1045
1154
|
* The options for this transport.
|
|
@@ -1100,7 +1209,7 @@ var ClientTransport = class extends Transport {
|
|
|
1100
1209
|
const parsed = this.parseMsg(data2, conn);
|
|
1101
1210
|
if (!parsed) {
|
|
1102
1211
|
conn.telemetry?.span.setStatus({
|
|
1103
|
-
code:
|
|
1212
|
+
code: import_api4.SpanStatusCode.ERROR,
|
|
1104
1213
|
message: "message parse failure"
|
|
1105
1214
|
});
|
|
1106
1215
|
conn.close();
|
|
@@ -1131,7 +1240,7 @@ var ClientTransport = class extends Transport {
|
|
|
1131
1240
|
});
|
|
1132
1241
|
conn.addErrorListener((err) => {
|
|
1133
1242
|
conn.telemetry?.span.setStatus({
|
|
1134
|
-
code:
|
|
1243
|
+
code: import_api4.SpanStatusCode.ERROR,
|
|
1135
1244
|
message: "connection error"
|
|
1136
1245
|
});
|
|
1137
1246
|
this.log?.warn(
|
|
@@ -1149,7 +1258,7 @@ var ClientTransport = class extends Transport {
|
|
|
1149
1258
|
const parsed = this.parseMsg(data, conn);
|
|
1150
1259
|
if (!parsed) {
|
|
1151
1260
|
conn.telemetry?.span.setStatus({
|
|
1152
|
-
code:
|
|
1261
|
+
code: import_api4.SpanStatusCode.ERROR,
|
|
1153
1262
|
message: "non-transport message"
|
|
1154
1263
|
});
|
|
1155
1264
|
this.protocolError(
|
|
@@ -1158,9 +1267,9 @@ var ClientTransport = class extends Transport {
|
|
|
1158
1267
|
);
|
|
1159
1268
|
return false;
|
|
1160
1269
|
}
|
|
1161
|
-
if (!
|
|
1270
|
+
if (!import_value2.Value.Check(ControlMessageHandshakeResponseSchema, parsed.payload)) {
|
|
1162
1271
|
conn.telemetry?.span.setStatus({
|
|
1163
|
-
code:
|
|
1272
|
+
code: import_api4.SpanStatusCode.ERROR,
|
|
1164
1273
|
message: "invalid handshake response"
|
|
1165
1274
|
});
|
|
1166
1275
|
this.log?.warn(`received invalid handshake resp`, {
|
|
@@ -1169,7 +1278,7 @@ var ClientTransport = class extends Transport {
|
|
|
1169
1278
|
connectedTo: parsed.from,
|
|
1170
1279
|
transportMessage: parsed,
|
|
1171
1280
|
validationErrors: [
|
|
1172
|
-
...
|
|
1281
|
+
...import_value2.Value.Errors(
|
|
1173
1282
|
ControlMessageHandshakeResponseSchema,
|
|
1174
1283
|
parsed.payload
|
|
1175
1284
|
)
|
|
@@ -1181,31 +1290,47 @@ var ClientTransport = class extends Transport {
|
|
|
1181
1290
|
);
|
|
1182
1291
|
return false;
|
|
1183
1292
|
}
|
|
1293
|
+
const previousSession = this.sessions.get(parsed.from);
|
|
1184
1294
|
if (!parsed.payload.status.ok) {
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1295
|
+
if (parsed.payload.status.reason === SESSION_STATE_MISMATCH) {
|
|
1296
|
+
if (previousSession) {
|
|
1297
|
+
this.deleteSession({
|
|
1298
|
+
session: previousSession,
|
|
1299
|
+
closeHandshakingConnection: true
|
|
1300
|
+
});
|
|
1301
|
+
}
|
|
1302
|
+
conn.telemetry?.span.setStatus({
|
|
1303
|
+
code: import_api4.SpanStatusCode.ERROR,
|
|
1304
|
+
message: parsed.payload.status.reason
|
|
1305
|
+
});
|
|
1306
|
+
} else {
|
|
1307
|
+
conn.telemetry?.span.setStatus({
|
|
1308
|
+
code: import_api4.SpanStatusCode.ERROR,
|
|
1309
|
+
message: "handshake rejected"
|
|
1310
|
+
});
|
|
1311
|
+
}
|
|
1312
|
+
this.log?.warn(
|
|
1313
|
+
`received handshake rejection: ${parsed.payload.status.reason}`,
|
|
1314
|
+
{
|
|
1315
|
+
...conn.loggingMetadata,
|
|
1316
|
+
clientId: this.clientId,
|
|
1317
|
+
connectedTo: parsed.from,
|
|
1318
|
+
transportMessage: parsed
|
|
1319
|
+
}
|
|
1320
|
+
);
|
|
1195
1321
|
this.protocolError(
|
|
1196
1322
|
ProtocolError.HandshakeFailed,
|
|
1197
1323
|
parsed.payload.status.reason
|
|
1198
1324
|
);
|
|
1199
1325
|
return false;
|
|
1200
1326
|
}
|
|
1201
|
-
const previousSession = this.sessions.get(parsed.from);
|
|
1202
1327
|
if (previousSession?.advertisedSessionId && previousSession.advertisedSessionId !== parsed.payload.status.sessionId) {
|
|
1203
1328
|
this.deleteSession({
|
|
1204
1329
|
session: previousSession,
|
|
1205
1330
|
closeHandshakingConnection: true
|
|
1206
1331
|
});
|
|
1207
1332
|
conn.telemetry?.span.setStatus({
|
|
1208
|
-
code:
|
|
1333
|
+
code: import_api4.SpanStatusCode.ERROR,
|
|
1209
1334
|
message: "session id mismatch"
|
|
1210
1335
|
});
|
|
1211
1336
|
this.log?.warn(`handshake from ${parsed.from} session id mismatch`, {
|
|
@@ -1305,7 +1430,7 @@ var ClientTransport = class extends Transport {
|
|
|
1305
1430
|
} catch (err) {
|
|
1306
1431
|
const errStr = coerceErrorString(err);
|
|
1307
1432
|
span.recordException(errStr);
|
|
1308
|
-
span.setStatus({ code:
|
|
1433
|
+
span.setStatus({ code: import_api4.SpanStatusCode.ERROR });
|
|
1309
1434
|
throw err;
|
|
1310
1435
|
} finally {
|
|
1311
1436
|
span.end();
|
|
@@ -1356,13 +1481,13 @@ var ClientTransport = class extends Transport {
|
|
|
1356
1481
|
let metadata = void 0;
|
|
1357
1482
|
if (this.handshakeExtensions) {
|
|
1358
1483
|
metadata = await this.handshakeExtensions.construct();
|
|
1359
|
-
if (!
|
|
1484
|
+
if (!import_value2.Value.Check(this.handshakeExtensions.schema, metadata)) {
|
|
1360
1485
|
this.log?.error(`constructed handshake metadata did not match schema`, {
|
|
1361
1486
|
...conn.loggingMetadata,
|
|
1362
1487
|
clientId: this.clientId,
|
|
1363
1488
|
connectedTo: to,
|
|
1364
1489
|
validationErrors: [
|
|
1365
|
-
...
|
|
1490
|
+
...import_value2.Value.Errors(this.handshakeExtensions.schema, metadata)
|
|
1366
1491
|
],
|
|
1367
1492
|
tags: ["invariant-violation"]
|
|
1368
1493
|
});
|
|
@@ -1371,20 +1496,24 @@ var ClientTransport = class extends Transport {
|
|
|
1371
1496
|
"handshake metadata did not match schema"
|
|
1372
1497
|
);
|
|
1373
1498
|
conn.telemetry?.span.setStatus({
|
|
1374
|
-
code:
|
|
1499
|
+
code: import_api4.SpanStatusCode.ERROR,
|
|
1375
1500
|
message: "handshake meta mismatch"
|
|
1376
1501
|
});
|
|
1377
1502
|
return false;
|
|
1378
1503
|
}
|
|
1379
1504
|
}
|
|
1380
1505
|
const { session } = this.getOrCreateSession({ to, handshakingConn: conn });
|
|
1381
|
-
const requestMsg = handshakeRequestMessage(
|
|
1382
|
-
this.clientId,
|
|
1506
|
+
const requestMsg = handshakeRequestMessage({
|
|
1507
|
+
from: this.clientId,
|
|
1383
1508
|
to,
|
|
1384
|
-
session.id,
|
|
1509
|
+
sessionId: session.id,
|
|
1510
|
+
expectedSessionState: {
|
|
1511
|
+
reconnect: session.advertisedSessionId !== void 0,
|
|
1512
|
+
nextExpectedSeq: session.nextExpectedSeq
|
|
1513
|
+
},
|
|
1385
1514
|
metadata,
|
|
1386
|
-
getPropagationContext(session.telemetry.ctx)
|
|
1387
|
-
);
|
|
1515
|
+
tracing: getPropagationContext(session.telemetry.ctx)
|
|
1516
|
+
});
|
|
1388
1517
|
this.log?.debug(`sending handshake request to ${to}`, {
|
|
1389
1518
|
...conn.loggingMetadata,
|
|
1390
1519
|
clientId: this.clientId,
|
|
@@ -1399,6 +1528,10 @@ var ClientTransport = class extends Transport {
|
|
|
1399
1528
|
super.close();
|
|
1400
1529
|
}
|
|
1401
1530
|
};
|
|
1531
|
+
|
|
1532
|
+
// transport/server.ts
|
|
1533
|
+
var import_api5 = require("@opentelemetry/api");
|
|
1534
|
+
var import_value3 = require("@sinclair/typebox/value");
|
|
1402
1535
|
var ServerTransport = class extends Transport {
|
|
1403
1536
|
/**
|
|
1404
1537
|
* The options for this transport.
|
|
@@ -1447,7 +1580,7 @@ var ServerTransport = class extends Transport {
|
|
|
1447
1580
|
}
|
|
1448
1581
|
);
|
|
1449
1582
|
conn.telemetry?.span.setStatus({
|
|
1450
|
-
code:
|
|
1583
|
+
code: import_api5.SpanStatusCode.ERROR,
|
|
1451
1584
|
message: "handshake timeout"
|
|
1452
1585
|
});
|
|
1453
1586
|
conn.close();
|
|
@@ -1498,7 +1631,7 @@ var ServerTransport = class extends Transport {
|
|
|
1498
1631
|
});
|
|
1499
1632
|
conn.addErrorListener((err) => {
|
|
1500
1633
|
conn.telemetry?.span.setStatus({
|
|
1501
|
-
code:
|
|
1634
|
+
code: import_api5.SpanStatusCode.ERROR,
|
|
1502
1635
|
message: "connection error"
|
|
1503
1636
|
});
|
|
1504
1637
|
if (!session)
|
|
@@ -1512,22 +1645,26 @@ var ServerTransport = class extends Transport {
|
|
|
1512
1645
|
async validateHandshakeMetadata(conn, session, rawMetadata, from) {
|
|
1513
1646
|
let parsedMetadata = {};
|
|
1514
1647
|
if (this.handshakeExtensions) {
|
|
1515
|
-
if (!
|
|
1648
|
+
if (!import_value3.Value.Check(this.handshakeExtensions.schema, rawMetadata)) {
|
|
1516
1649
|
conn.telemetry?.span.setStatus({
|
|
1517
|
-
code:
|
|
1650
|
+
code: import_api5.SpanStatusCode.ERROR,
|
|
1518
1651
|
message: "malformed handshake meta"
|
|
1519
1652
|
});
|
|
1520
1653
|
const reason = "received malformed handshake metadata";
|
|
1521
|
-
const responseMsg = handshakeResponseMessage(
|
|
1522
|
-
|
|
1523
|
-
|
|
1654
|
+
const responseMsg = handshakeResponseMessage({
|
|
1655
|
+
from: this.clientId,
|
|
1656
|
+
to: from,
|
|
1657
|
+
status: {
|
|
1658
|
+
ok: false,
|
|
1659
|
+
reason
|
|
1660
|
+
}
|
|
1524
1661
|
});
|
|
1525
1662
|
conn.send(this.codec.toBuffer(responseMsg));
|
|
1526
1663
|
this.log?.warn(`received malformed handshake metadata from ${from}`, {
|
|
1527
1664
|
...conn.loggingMetadata,
|
|
1528
1665
|
clientId: this.clientId,
|
|
1529
1666
|
validationErrors: [
|
|
1530
|
-
...
|
|
1667
|
+
...import_value3.Value.Errors(this.handshakeExtensions.schema, rawMetadata)
|
|
1531
1668
|
]
|
|
1532
1669
|
});
|
|
1533
1670
|
this.protocolError(ProtocolError.HandshakeFailed, reason);
|
|
@@ -1541,12 +1678,16 @@ var ServerTransport = class extends Transport {
|
|
|
1541
1678
|
if (parsedMetadata === false) {
|
|
1542
1679
|
const reason = "rejected by handshake handler";
|
|
1543
1680
|
conn.telemetry?.span.setStatus({
|
|
1544
|
-
code:
|
|
1681
|
+
code: import_api5.SpanStatusCode.ERROR,
|
|
1545
1682
|
message: reason
|
|
1546
1683
|
});
|
|
1547
|
-
const responseMsg = handshakeResponseMessage(
|
|
1548
|
-
|
|
1549
|
-
|
|
1684
|
+
const responseMsg = handshakeResponseMessage({
|
|
1685
|
+
from: this.clientId,
|
|
1686
|
+
to: from,
|
|
1687
|
+
status: {
|
|
1688
|
+
ok: false,
|
|
1689
|
+
reason
|
|
1690
|
+
}
|
|
1550
1691
|
});
|
|
1551
1692
|
conn.send(this.codec.toBuffer(responseMsg));
|
|
1552
1693
|
this.log?.warn(`rejected handshake from ${from}`, {
|
|
@@ -1563,7 +1704,7 @@ var ServerTransport = class extends Transport {
|
|
|
1563
1704
|
const parsed = this.parseMsg(data, conn);
|
|
1564
1705
|
if (!parsed) {
|
|
1565
1706
|
conn.telemetry?.span.setStatus({
|
|
1566
|
-
code:
|
|
1707
|
+
code: import_api5.SpanStatusCode.ERROR,
|
|
1567
1708
|
message: "non-transport message"
|
|
1568
1709
|
});
|
|
1569
1710
|
this.protocolError(
|
|
@@ -1572,15 +1713,19 @@ var ServerTransport = class extends Transport {
|
|
|
1572
1713
|
);
|
|
1573
1714
|
return false;
|
|
1574
1715
|
}
|
|
1575
|
-
if (!
|
|
1716
|
+
if (!import_value3.Value.Check(ControlMessageHandshakeRequestSchema, parsed.payload)) {
|
|
1576
1717
|
conn.telemetry?.span.setStatus({
|
|
1577
|
-
code:
|
|
1718
|
+
code: import_api5.SpanStatusCode.ERROR,
|
|
1578
1719
|
message: "invalid handshake request"
|
|
1579
1720
|
});
|
|
1580
1721
|
const reason = "received invalid handshake msg";
|
|
1581
|
-
const responseMsg2 = handshakeResponseMessage(
|
|
1582
|
-
|
|
1583
|
-
|
|
1722
|
+
const responseMsg2 = handshakeResponseMessage({
|
|
1723
|
+
from: this.clientId,
|
|
1724
|
+
to: parsed.from,
|
|
1725
|
+
status: {
|
|
1726
|
+
ok: false,
|
|
1727
|
+
reason
|
|
1728
|
+
}
|
|
1584
1729
|
});
|
|
1585
1730
|
conn.send(this.codec.toBuffer(responseMsg2));
|
|
1586
1731
|
this.log?.warn(reason, {
|
|
@@ -1590,7 +1735,7 @@ var ServerTransport = class extends Transport {
|
|
|
1590
1735
|
// before passing it to user-land
|
|
1591
1736
|
transportMessage: parsed,
|
|
1592
1737
|
validationErrors: [
|
|
1593
|
-
...
|
|
1738
|
+
...import_value3.Value.Errors(ControlMessageHandshakeRequestSchema, parsed.payload)
|
|
1594
1739
|
]
|
|
1595
1740
|
});
|
|
1596
1741
|
this.protocolError(
|
|
@@ -1602,13 +1747,17 @@ var ServerTransport = class extends Transport {
|
|
|
1602
1747
|
const gotVersion = parsed.payload.protocolVersion;
|
|
1603
1748
|
if (gotVersion !== PROTOCOL_VERSION) {
|
|
1604
1749
|
conn.telemetry?.span.setStatus({
|
|
1605
|
-
code:
|
|
1750
|
+
code: import_api5.SpanStatusCode.ERROR,
|
|
1606
1751
|
message: "incorrect protocol version"
|
|
1607
1752
|
});
|
|
1608
1753
|
const reason = `incorrect version (got: ${gotVersion} wanted ${PROTOCOL_VERSION})`;
|
|
1609
|
-
const responseMsg2 = handshakeResponseMessage(
|
|
1610
|
-
|
|
1611
|
-
|
|
1754
|
+
const responseMsg2 = handshakeResponseMessage({
|
|
1755
|
+
from: this.clientId,
|
|
1756
|
+
to: parsed.from,
|
|
1757
|
+
status: {
|
|
1758
|
+
ok: false,
|
|
1759
|
+
reason
|
|
1760
|
+
}
|
|
1612
1761
|
});
|
|
1613
1762
|
conn.send(this.codec.toBuffer(responseMsg2));
|
|
1614
1763
|
this.log?.warn(
|
|
@@ -1628,20 +1777,67 @@ var ServerTransport = class extends Transport {
|
|
|
1628
1777
|
if (parsedMetadata === false) {
|
|
1629
1778
|
return false;
|
|
1630
1779
|
}
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1780
|
+
let session;
|
|
1781
|
+
let isTransparentReconnect;
|
|
1782
|
+
if (!parsed.payload.expectedSessionState) {
|
|
1783
|
+
({ session, isTransparentReconnect } = this.getOrCreateSession({
|
|
1784
|
+
to: parsed.from,
|
|
1785
|
+
conn,
|
|
1786
|
+
sessionId: parsed.payload.sessionId,
|
|
1787
|
+
propagationCtx: parsed.tracing
|
|
1788
|
+
}));
|
|
1789
|
+
} else if (parsed.payload.expectedSessionState.reconnect) {
|
|
1790
|
+
const existingSession = this.getExistingSession({
|
|
1791
|
+
to: parsed.from,
|
|
1792
|
+
sessionId: parsed.payload.sessionId,
|
|
1793
|
+
nextExpectedSeq: parsed.payload.expectedSessionState.nextExpectedSeq
|
|
1794
|
+
});
|
|
1795
|
+
if (existingSession === false) {
|
|
1796
|
+
conn.telemetry?.span.setStatus({
|
|
1797
|
+
code: import_api5.SpanStatusCode.ERROR,
|
|
1798
|
+
message: SESSION_STATE_MISMATCH
|
|
1799
|
+
});
|
|
1800
|
+
const reason = SESSION_STATE_MISMATCH;
|
|
1801
|
+
const responseMsg2 = handshakeResponseMessage({
|
|
1802
|
+
from: this.clientId,
|
|
1803
|
+
to: parsed.from,
|
|
1804
|
+
status: {
|
|
1805
|
+
ok: false,
|
|
1806
|
+
reason
|
|
1807
|
+
}
|
|
1808
|
+
});
|
|
1809
|
+
conn.send(this.codec.toBuffer(responseMsg2));
|
|
1810
|
+
this.log?.warn(
|
|
1811
|
+
`'received handshake msg with incompatible existing session state: ${parsed.payload.sessionId}`,
|
|
1812
|
+
{ ...conn.loggingMetadata, clientId: this.clientId }
|
|
1813
|
+
);
|
|
1814
|
+
this.protocolError(ProtocolError.HandshakeFailed, reason);
|
|
1815
|
+
return false;
|
|
1816
|
+
}
|
|
1817
|
+
session = existingSession;
|
|
1818
|
+
isTransparentReconnect = false;
|
|
1819
|
+
} else {
|
|
1820
|
+
const createdSession = this.createNewSession({
|
|
1821
|
+
to: parsed.from,
|
|
1822
|
+
conn,
|
|
1823
|
+
sessionId: parsed.payload.sessionId,
|
|
1824
|
+
propagationCtx: parsed.tracing
|
|
1825
|
+
});
|
|
1826
|
+
session = createdSession;
|
|
1827
|
+
isTransparentReconnect = false;
|
|
1828
|
+
}
|
|
1637
1829
|
this.sessionHandshakeMetadata.set(session, parsedMetadata);
|
|
1638
1830
|
this.log?.debug(
|
|
1639
1831
|
`handshake from ${parsed.from} ok, responding with handshake success`,
|
|
1640
1832
|
conn.loggingMetadata
|
|
1641
1833
|
);
|
|
1642
|
-
const responseMsg = handshakeResponseMessage(
|
|
1643
|
-
|
|
1644
|
-
|
|
1834
|
+
const responseMsg = handshakeResponseMessage({
|
|
1835
|
+
from: this.clientId,
|
|
1836
|
+
to: parsed.from,
|
|
1837
|
+
status: {
|
|
1838
|
+
ok: true,
|
|
1839
|
+
sessionId: session.id
|
|
1840
|
+
}
|
|
1645
1841
|
});
|
|
1646
1842
|
conn.send(this.codec.toBuffer(responseMsg));
|
|
1647
1843
|
this.onConnect(conn, session, isTransparentReconnect);
|