@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
|
@@ -24,8 +24,8 @@ __export(client_exports, {
|
|
|
24
24
|
});
|
|
25
25
|
module.exports = __toCommonJS(client_exports);
|
|
26
26
|
|
|
27
|
-
// transport/
|
|
28
|
-
var
|
|
27
|
+
// transport/client.ts
|
|
28
|
+
var import_api4 = require("@opentelemetry/api");
|
|
29
29
|
|
|
30
30
|
// transport/message.ts
|
|
31
31
|
var import_typebox = require("@sinclair/typebox");
|
|
@@ -59,6 +59,21 @@ var ControlMessageHandshakeRequestSchema = import_typebox.Type.Object({
|
|
|
59
59
|
type: import_typebox.Type.Literal("HANDSHAKE_REQ"),
|
|
60
60
|
protocolVersion: import_typebox.Type.String(),
|
|
61
61
|
sessionId: import_typebox.Type.String(),
|
|
62
|
+
/**
|
|
63
|
+
* Specifies what the server's expected session state (from the pov of the client). This can be
|
|
64
|
+
* used by the server to know whether this is a new or a reestablished connection, and whether it
|
|
65
|
+
* is compatible with what it already has.
|
|
66
|
+
*/
|
|
67
|
+
expectedSessionState: import_typebox.Type.Optional(
|
|
68
|
+
import_typebox.Type.Object({
|
|
69
|
+
/**
|
|
70
|
+
* reconnect is set to true if the client explicitly wants to reestablish an existing
|
|
71
|
+
* connection.
|
|
72
|
+
*/
|
|
73
|
+
reconnect: import_typebox.Type.Boolean(),
|
|
74
|
+
nextExpectedSeq: import_typebox.Type.Integer()
|
|
75
|
+
})
|
|
76
|
+
),
|
|
62
77
|
metadata: import_typebox.Type.Optional(import_typebox.Type.Unknown())
|
|
63
78
|
});
|
|
64
79
|
var ControlMessageHandshakeResponseSchema = import_typebox.Type.Object({
|
|
@@ -83,7 +98,14 @@ var ControlMessagePayloadSchema = import_typebox.Type.Union([
|
|
|
83
98
|
var OpaqueTransportMessageSchema = TransportMessageSchema(
|
|
84
99
|
import_typebox.Type.Unknown()
|
|
85
100
|
);
|
|
86
|
-
function handshakeRequestMessage(
|
|
101
|
+
function handshakeRequestMessage({
|
|
102
|
+
from,
|
|
103
|
+
to,
|
|
104
|
+
sessionId,
|
|
105
|
+
expectedSessionState,
|
|
106
|
+
metadata,
|
|
107
|
+
tracing
|
|
108
|
+
}) {
|
|
87
109
|
return {
|
|
88
110
|
id: (0, import_nanoid.nanoid)(),
|
|
89
111
|
from,
|
|
@@ -97,14 +119,164 @@ function handshakeRequestMessage(from, to, sessionId, metadata, tracing) {
|
|
|
97
119
|
type: "HANDSHAKE_REQ",
|
|
98
120
|
protocolVersion: PROTOCOL_VERSION,
|
|
99
121
|
sessionId,
|
|
122
|
+
expectedSessionState,
|
|
100
123
|
metadata
|
|
101
124
|
}
|
|
102
125
|
};
|
|
103
126
|
}
|
|
127
|
+
var SESSION_STATE_MISMATCH = "session state mismatch";
|
|
104
128
|
function isAck(controlFlag) {
|
|
105
129
|
return (controlFlag & 1 /* AckBit */) === 1 /* AckBit */;
|
|
106
130
|
}
|
|
107
131
|
|
|
132
|
+
// codec/json.ts
|
|
133
|
+
var encoder = new TextEncoder();
|
|
134
|
+
var decoder = new TextDecoder();
|
|
135
|
+
function uint8ArrayToBase64(uint8Array) {
|
|
136
|
+
let binary = "";
|
|
137
|
+
uint8Array.forEach((byte) => {
|
|
138
|
+
binary += String.fromCharCode(byte);
|
|
139
|
+
});
|
|
140
|
+
return btoa(binary);
|
|
141
|
+
}
|
|
142
|
+
function base64ToUint8Array(base64) {
|
|
143
|
+
const binaryString = atob(base64);
|
|
144
|
+
const uint8Array = new Uint8Array(binaryString.length);
|
|
145
|
+
for (let i = 0; i < binaryString.length; i++) {
|
|
146
|
+
uint8Array[i] = binaryString.charCodeAt(i);
|
|
147
|
+
}
|
|
148
|
+
return uint8Array;
|
|
149
|
+
}
|
|
150
|
+
var NaiveJsonCodec = {
|
|
151
|
+
toBuffer: (obj) => {
|
|
152
|
+
return encoder.encode(
|
|
153
|
+
JSON.stringify(obj, function replacer(key) {
|
|
154
|
+
const val = this[key];
|
|
155
|
+
if (val instanceof Uint8Array) {
|
|
156
|
+
return { $t: uint8ArrayToBase64(val) };
|
|
157
|
+
} else {
|
|
158
|
+
return val;
|
|
159
|
+
}
|
|
160
|
+
})
|
|
161
|
+
);
|
|
162
|
+
},
|
|
163
|
+
fromBuffer: (buff) => {
|
|
164
|
+
try {
|
|
165
|
+
const parsed = JSON.parse(
|
|
166
|
+
decoder.decode(buff),
|
|
167
|
+
function reviver(_key, val) {
|
|
168
|
+
if (val?.$t) {
|
|
169
|
+
return base64ToUint8Array(val.$t);
|
|
170
|
+
} else {
|
|
171
|
+
return val;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
);
|
|
175
|
+
if (typeof parsed === "object")
|
|
176
|
+
return parsed;
|
|
177
|
+
return null;
|
|
178
|
+
} catch {
|
|
179
|
+
return null;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
// transport/options.ts
|
|
185
|
+
var defaultTransportOptions = {
|
|
186
|
+
heartbeatIntervalMs: 1e3,
|
|
187
|
+
heartbeatsUntilDead: 2,
|
|
188
|
+
sessionDisconnectGraceMs: 5e3,
|
|
189
|
+
codec: NaiveJsonCodec
|
|
190
|
+
};
|
|
191
|
+
var defaultConnectionRetryOptions = {
|
|
192
|
+
baseIntervalMs: 250,
|
|
193
|
+
maxJitterMs: 200,
|
|
194
|
+
maxBackoffMs: 32e3,
|
|
195
|
+
attemptBudgetCapacity: 5,
|
|
196
|
+
budgetRestoreIntervalMs: 200
|
|
197
|
+
};
|
|
198
|
+
var defaultClientTransportOptions = {
|
|
199
|
+
...defaultTransportOptions,
|
|
200
|
+
...defaultConnectionRetryOptions
|
|
201
|
+
};
|
|
202
|
+
var defaultServerTransportOptions = {
|
|
203
|
+
...defaultTransportOptions
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
// transport/rateLimit.ts
|
|
207
|
+
var LeakyBucketRateLimit = class {
|
|
208
|
+
budgetConsumed;
|
|
209
|
+
intervalHandles;
|
|
210
|
+
options;
|
|
211
|
+
constructor(options) {
|
|
212
|
+
this.options = options;
|
|
213
|
+
this.budgetConsumed = /* @__PURE__ */ new Map();
|
|
214
|
+
this.intervalHandles = /* @__PURE__ */ new Map();
|
|
215
|
+
}
|
|
216
|
+
getBackoffMs(user) {
|
|
217
|
+
if (!this.budgetConsumed.has(user))
|
|
218
|
+
return 0;
|
|
219
|
+
const exponent = Math.max(0, this.getBudgetConsumed(user) - 1);
|
|
220
|
+
const jitter = Math.floor(Math.random() * this.options.maxJitterMs);
|
|
221
|
+
const backoffMs = Math.min(
|
|
222
|
+
this.options.baseIntervalMs * 2 ** exponent,
|
|
223
|
+
this.options.maxBackoffMs
|
|
224
|
+
);
|
|
225
|
+
return backoffMs + jitter;
|
|
226
|
+
}
|
|
227
|
+
get totalBudgetRestoreTime() {
|
|
228
|
+
return this.options.budgetRestoreIntervalMs * this.options.attemptBudgetCapacity;
|
|
229
|
+
}
|
|
230
|
+
consumeBudget(user) {
|
|
231
|
+
this.stopLeak(user);
|
|
232
|
+
this.budgetConsumed.set(user, this.getBudgetConsumed(user) + 1);
|
|
233
|
+
}
|
|
234
|
+
getBudgetConsumed(user) {
|
|
235
|
+
return this.budgetConsumed.get(user) ?? 0;
|
|
236
|
+
}
|
|
237
|
+
hasBudget(user) {
|
|
238
|
+
return this.getBudgetConsumed(user) < this.options.attemptBudgetCapacity;
|
|
239
|
+
}
|
|
240
|
+
startRestoringBudget(user) {
|
|
241
|
+
if (this.intervalHandles.has(user)) {
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
const restoreBudgetForUser = () => {
|
|
245
|
+
const currentBudget = this.budgetConsumed.get(user);
|
|
246
|
+
if (!currentBudget) {
|
|
247
|
+
this.stopLeak(user);
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
const newBudget = currentBudget - 1;
|
|
251
|
+
if (newBudget === 0) {
|
|
252
|
+
this.budgetConsumed.delete(user);
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
this.budgetConsumed.set(user, newBudget);
|
|
256
|
+
};
|
|
257
|
+
const intervalHandle = setInterval(
|
|
258
|
+
restoreBudgetForUser,
|
|
259
|
+
this.options.budgetRestoreIntervalMs
|
|
260
|
+
);
|
|
261
|
+
this.intervalHandles.set(user, intervalHandle);
|
|
262
|
+
}
|
|
263
|
+
stopLeak(user) {
|
|
264
|
+
if (!this.intervalHandles.has(user)) {
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
clearInterval(this.intervalHandles.get(user));
|
|
268
|
+
this.intervalHandles.delete(user);
|
|
269
|
+
}
|
|
270
|
+
close() {
|
|
271
|
+
for (const user of this.intervalHandles.keys()) {
|
|
272
|
+
this.stopLeak(user);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
};
|
|
276
|
+
|
|
277
|
+
// transport/transport.ts
|
|
278
|
+
var import_value = require("@sinclair/typebox/value");
|
|
279
|
+
|
|
108
280
|
// logging/log.ts
|
|
109
281
|
var LoggingLevels = {
|
|
110
282
|
debug: -1,
|
|
@@ -202,7 +374,7 @@ var import_nanoid2 = require("nanoid");
|
|
|
202
374
|
var import_api = require("@opentelemetry/api");
|
|
203
375
|
|
|
204
376
|
// package.json
|
|
205
|
-
var version = "0.23.
|
|
377
|
+
var version = "0.23.14";
|
|
206
378
|
|
|
207
379
|
// tracing/index.ts
|
|
208
380
|
function getPropagationContext(ctx) {
|
|
@@ -516,9 +688,17 @@ var Session = class {
|
|
|
516
688
|
get connected() {
|
|
517
689
|
return this.connection !== void 0;
|
|
518
690
|
}
|
|
691
|
+
get nextExpectedAck() {
|
|
692
|
+
return this.seq;
|
|
693
|
+
}
|
|
519
694
|
get nextExpectedSeq() {
|
|
520
695
|
return this.ack;
|
|
521
696
|
}
|
|
697
|
+
// This is only used in tests to make the session misbehave.
|
|
698
|
+
/* @internal */
|
|
699
|
+
advanceAckForTesting(by) {
|
|
700
|
+
this.ack += by;
|
|
701
|
+
}
|
|
522
702
|
constructMsg(partialMsg) {
|
|
523
703
|
const msg = {
|
|
524
704
|
...partialMsg,
|
|
@@ -537,159 +717,8 @@ var Session = class {
|
|
|
537
717
|
}
|
|
538
718
|
};
|
|
539
719
|
|
|
540
|
-
// util/stringify.ts
|
|
541
|
-
function coerceErrorString(err) {
|
|
542
|
-
if (err instanceof Error) {
|
|
543
|
-
return err.message || "unknown reason";
|
|
544
|
-
}
|
|
545
|
-
return `[coerced to error] ${String(err)}`;
|
|
546
|
-
}
|
|
547
|
-
|
|
548
|
-
// transport/rateLimit.ts
|
|
549
|
-
var LeakyBucketRateLimit = class {
|
|
550
|
-
budgetConsumed;
|
|
551
|
-
intervalHandles;
|
|
552
|
-
options;
|
|
553
|
-
constructor(options) {
|
|
554
|
-
this.options = options;
|
|
555
|
-
this.budgetConsumed = /* @__PURE__ */ new Map();
|
|
556
|
-
this.intervalHandles = /* @__PURE__ */ new Map();
|
|
557
|
-
}
|
|
558
|
-
getBackoffMs(user) {
|
|
559
|
-
if (!this.budgetConsumed.has(user))
|
|
560
|
-
return 0;
|
|
561
|
-
const exponent = Math.max(0, this.getBudgetConsumed(user) - 1);
|
|
562
|
-
const jitter = Math.floor(Math.random() * this.options.maxJitterMs);
|
|
563
|
-
const backoffMs = Math.min(
|
|
564
|
-
this.options.baseIntervalMs * 2 ** exponent,
|
|
565
|
-
this.options.maxBackoffMs
|
|
566
|
-
);
|
|
567
|
-
return backoffMs + jitter;
|
|
568
|
-
}
|
|
569
|
-
get totalBudgetRestoreTime() {
|
|
570
|
-
return this.options.budgetRestoreIntervalMs * this.options.attemptBudgetCapacity;
|
|
571
|
-
}
|
|
572
|
-
consumeBudget(user) {
|
|
573
|
-
this.stopLeak(user);
|
|
574
|
-
this.budgetConsumed.set(user, this.getBudgetConsumed(user) + 1);
|
|
575
|
-
}
|
|
576
|
-
getBudgetConsumed(user) {
|
|
577
|
-
return this.budgetConsumed.get(user) ?? 0;
|
|
578
|
-
}
|
|
579
|
-
hasBudget(user) {
|
|
580
|
-
return this.getBudgetConsumed(user) < this.options.attemptBudgetCapacity;
|
|
581
|
-
}
|
|
582
|
-
startRestoringBudget(user) {
|
|
583
|
-
if (this.intervalHandles.has(user)) {
|
|
584
|
-
return;
|
|
585
|
-
}
|
|
586
|
-
const restoreBudgetForUser = () => {
|
|
587
|
-
const currentBudget = this.budgetConsumed.get(user);
|
|
588
|
-
if (!currentBudget) {
|
|
589
|
-
this.stopLeak(user);
|
|
590
|
-
return;
|
|
591
|
-
}
|
|
592
|
-
const newBudget = currentBudget - 1;
|
|
593
|
-
if (newBudget === 0) {
|
|
594
|
-
this.budgetConsumed.delete(user);
|
|
595
|
-
return;
|
|
596
|
-
}
|
|
597
|
-
this.budgetConsumed.set(user, newBudget);
|
|
598
|
-
};
|
|
599
|
-
const intervalHandle = setInterval(
|
|
600
|
-
restoreBudgetForUser,
|
|
601
|
-
this.options.budgetRestoreIntervalMs
|
|
602
|
-
);
|
|
603
|
-
this.intervalHandles.set(user, intervalHandle);
|
|
604
|
-
}
|
|
605
|
-
stopLeak(user) {
|
|
606
|
-
if (!this.intervalHandles.has(user)) {
|
|
607
|
-
return;
|
|
608
|
-
}
|
|
609
|
-
clearInterval(this.intervalHandles.get(user));
|
|
610
|
-
this.intervalHandles.delete(user);
|
|
611
|
-
}
|
|
612
|
-
close() {
|
|
613
|
-
for (const user of this.intervalHandles.keys()) {
|
|
614
|
-
this.stopLeak(user);
|
|
615
|
-
}
|
|
616
|
-
}
|
|
617
|
-
};
|
|
618
|
-
|
|
619
|
-
// codec/json.ts
|
|
620
|
-
var encoder = new TextEncoder();
|
|
621
|
-
var decoder = new TextDecoder();
|
|
622
|
-
function uint8ArrayToBase64(uint8Array) {
|
|
623
|
-
let binary = "";
|
|
624
|
-
uint8Array.forEach((byte) => {
|
|
625
|
-
binary += String.fromCharCode(byte);
|
|
626
|
-
});
|
|
627
|
-
return btoa(binary);
|
|
628
|
-
}
|
|
629
|
-
function base64ToUint8Array(base64) {
|
|
630
|
-
const binaryString = atob(base64);
|
|
631
|
-
const uint8Array = new Uint8Array(binaryString.length);
|
|
632
|
-
for (let i = 0; i < binaryString.length; i++) {
|
|
633
|
-
uint8Array[i] = binaryString.charCodeAt(i);
|
|
634
|
-
}
|
|
635
|
-
return uint8Array;
|
|
636
|
-
}
|
|
637
|
-
var NaiveJsonCodec = {
|
|
638
|
-
toBuffer: (obj) => {
|
|
639
|
-
return encoder.encode(
|
|
640
|
-
JSON.stringify(obj, function replacer(key) {
|
|
641
|
-
const val = this[key];
|
|
642
|
-
if (val instanceof Uint8Array) {
|
|
643
|
-
return { $t: uint8ArrayToBase64(val) };
|
|
644
|
-
} else {
|
|
645
|
-
return val;
|
|
646
|
-
}
|
|
647
|
-
})
|
|
648
|
-
);
|
|
649
|
-
},
|
|
650
|
-
fromBuffer: (buff) => {
|
|
651
|
-
try {
|
|
652
|
-
const parsed = JSON.parse(
|
|
653
|
-
decoder.decode(buff),
|
|
654
|
-
function reviver(_key, val) {
|
|
655
|
-
if (val?.$t) {
|
|
656
|
-
return base64ToUint8Array(val.$t);
|
|
657
|
-
} else {
|
|
658
|
-
return val;
|
|
659
|
-
}
|
|
660
|
-
}
|
|
661
|
-
);
|
|
662
|
-
if (typeof parsed === "object")
|
|
663
|
-
return parsed;
|
|
664
|
-
return null;
|
|
665
|
-
} catch {
|
|
666
|
-
return null;
|
|
667
|
-
}
|
|
668
|
-
}
|
|
669
|
-
};
|
|
670
|
-
|
|
671
720
|
// transport/transport.ts
|
|
672
721
|
var import_api3 = require("@opentelemetry/api");
|
|
673
|
-
var defaultTransportOptions = {
|
|
674
|
-
heartbeatIntervalMs: 1e3,
|
|
675
|
-
heartbeatsUntilDead: 2,
|
|
676
|
-
sessionDisconnectGraceMs: 5e3,
|
|
677
|
-
codec: NaiveJsonCodec
|
|
678
|
-
};
|
|
679
|
-
var defaultConnectionRetryOptions = {
|
|
680
|
-
baseIntervalMs: 250,
|
|
681
|
-
maxJitterMs: 200,
|
|
682
|
-
maxBackoffMs: 32e3,
|
|
683
|
-
attemptBudgetCapacity: 5,
|
|
684
|
-
budgetRestoreIntervalMs: 200
|
|
685
|
-
};
|
|
686
|
-
var defaultClientTransportOptions = {
|
|
687
|
-
...defaultTransportOptions,
|
|
688
|
-
...defaultConnectionRetryOptions
|
|
689
|
-
};
|
|
690
|
-
var defaultServerTransportOptions = {
|
|
691
|
-
...defaultTransportOptions
|
|
692
|
-
};
|
|
693
722
|
var Transport = class {
|
|
694
723
|
/**
|
|
695
724
|
* The status of the transport.
|
|
@@ -780,6 +809,49 @@ var Transport = class {
|
|
|
780
809
|
});
|
|
781
810
|
return session;
|
|
782
811
|
}
|
|
812
|
+
createNewSession({
|
|
813
|
+
to,
|
|
814
|
+
conn,
|
|
815
|
+
sessionId,
|
|
816
|
+
propagationCtx
|
|
817
|
+
}) {
|
|
818
|
+
let session = this.sessions.get(to);
|
|
819
|
+
if (session !== void 0) {
|
|
820
|
+
this.log?.info(
|
|
821
|
+
`session for ${to} already exists, replacing it with a new session as requested`,
|
|
822
|
+
session.loggingMetadata
|
|
823
|
+
);
|
|
824
|
+
this.deleteSession({
|
|
825
|
+
session,
|
|
826
|
+
closeHandshakingConnection: false
|
|
827
|
+
});
|
|
828
|
+
session = void 0;
|
|
829
|
+
}
|
|
830
|
+
session = this.createSession(to, conn, propagationCtx);
|
|
831
|
+
session.advertisedSessionId = sessionId;
|
|
832
|
+
this.log?.info(`created new session for ${to}`, session.loggingMetadata);
|
|
833
|
+
return session;
|
|
834
|
+
}
|
|
835
|
+
getExistingSession({
|
|
836
|
+
to,
|
|
837
|
+
sessionId,
|
|
838
|
+
nextExpectedSeq
|
|
839
|
+
}) {
|
|
840
|
+
const session = this.sessions.get(to);
|
|
841
|
+
if (
|
|
842
|
+
// reject this request if there was no previous session to replace
|
|
843
|
+
session === void 0 || // or if both parties do not agree about the next expected sequence number
|
|
844
|
+
session.nextExpectedAck < nextExpectedSeq || // or if both parties do not agree on the advertised session id
|
|
845
|
+
session.advertisedSessionId !== sessionId
|
|
846
|
+
) {
|
|
847
|
+
return false;
|
|
848
|
+
}
|
|
849
|
+
this.log?.info(
|
|
850
|
+
`reused existing session for ${to}`,
|
|
851
|
+
session.loggingMetadata
|
|
852
|
+
);
|
|
853
|
+
return session;
|
|
854
|
+
}
|
|
783
855
|
getOrCreateSession({
|
|
784
856
|
to,
|
|
785
857
|
conn,
|
|
@@ -844,6 +916,16 @@ var Transport = class {
|
|
|
844
916
|
* @param connectedTo The peer we are connected to.
|
|
845
917
|
*/
|
|
846
918
|
onDisconnect(conn, session) {
|
|
919
|
+
if (session.connection !== void 0 && session.connection.id !== conn.id) {
|
|
920
|
+
session.telemetry.span.addEvent("onDisconnect race");
|
|
921
|
+
this.log?.warn("onDisconnect race", {
|
|
922
|
+
clientId: this.clientId,
|
|
923
|
+
...session.loggingMetadata,
|
|
924
|
+
...conn.loggingMetadata,
|
|
925
|
+
tags: ["invariant-violation"]
|
|
926
|
+
});
|
|
927
|
+
return;
|
|
928
|
+
}
|
|
847
929
|
conn.telemetry?.span.end();
|
|
848
930
|
this.eventDispatcher.dispatchEvent("connectionStatus", {
|
|
849
931
|
status: "disconnect",
|
|
@@ -851,6 +933,16 @@ var Transport = class {
|
|
|
851
933
|
});
|
|
852
934
|
session.connection = void 0;
|
|
853
935
|
session.beginGrace(() => {
|
|
936
|
+
if (session.connection !== void 0) {
|
|
937
|
+
session.telemetry.span.addEvent("session grace period race");
|
|
938
|
+
this.log?.warn("session grace period race", {
|
|
939
|
+
clientId: this.clientId,
|
|
940
|
+
...session.loggingMetadata,
|
|
941
|
+
...conn.loggingMetadata,
|
|
942
|
+
tags: ["invariant-violation"]
|
|
943
|
+
});
|
|
944
|
+
return;
|
|
945
|
+
}
|
|
854
946
|
session.telemetry.span.addEvent("session grace period expired");
|
|
855
947
|
this.deleteSession({
|
|
856
948
|
session,
|
|
@@ -1018,6 +1110,17 @@ var Transport = class {
|
|
|
1018
1110
|
return this.status;
|
|
1019
1111
|
}
|
|
1020
1112
|
};
|
|
1113
|
+
|
|
1114
|
+
// util/stringify.ts
|
|
1115
|
+
function coerceErrorString(err) {
|
|
1116
|
+
if (err instanceof Error) {
|
|
1117
|
+
return err.message || "unknown reason";
|
|
1118
|
+
}
|
|
1119
|
+
return `[coerced to error] ${String(err)}`;
|
|
1120
|
+
}
|
|
1121
|
+
|
|
1122
|
+
// transport/client.ts
|
|
1123
|
+
var import_value2 = require("@sinclair/typebox/value");
|
|
1021
1124
|
var ClientTransport = class extends Transport {
|
|
1022
1125
|
/**
|
|
1023
1126
|
* The options for this transport.
|
|
@@ -1078,7 +1181,7 @@ var ClientTransport = class extends Transport {
|
|
|
1078
1181
|
const parsed = this.parseMsg(data2, conn);
|
|
1079
1182
|
if (!parsed) {
|
|
1080
1183
|
conn.telemetry?.span.setStatus({
|
|
1081
|
-
code:
|
|
1184
|
+
code: import_api4.SpanStatusCode.ERROR,
|
|
1082
1185
|
message: "message parse failure"
|
|
1083
1186
|
});
|
|
1084
1187
|
conn.close();
|
|
@@ -1109,7 +1212,7 @@ var ClientTransport = class extends Transport {
|
|
|
1109
1212
|
});
|
|
1110
1213
|
conn.addErrorListener((err) => {
|
|
1111
1214
|
conn.telemetry?.span.setStatus({
|
|
1112
|
-
code:
|
|
1215
|
+
code: import_api4.SpanStatusCode.ERROR,
|
|
1113
1216
|
message: "connection error"
|
|
1114
1217
|
});
|
|
1115
1218
|
this.log?.warn(
|
|
@@ -1127,7 +1230,7 @@ var ClientTransport = class extends Transport {
|
|
|
1127
1230
|
const parsed = this.parseMsg(data, conn);
|
|
1128
1231
|
if (!parsed) {
|
|
1129
1232
|
conn.telemetry?.span.setStatus({
|
|
1130
|
-
code:
|
|
1233
|
+
code: import_api4.SpanStatusCode.ERROR,
|
|
1131
1234
|
message: "non-transport message"
|
|
1132
1235
|
});
|
|
1133
1236
|
this.protocolError(
|
|
@@ -1136,9 +1239,9 @@ var ClientTransport = class extends Transport {
|
|
|
1136
1239
|
);
|
|
1137
1240
|
return false;
|
|
1138
1241
|
}
|
|
1139
|
-
if (!
|
|
1242
|
+
if (!import_value2.Value.Check(ControlMessageHandshakeResponseSchema, parsed.payload)) {
|
|
1140
1243
|
conn.telemetry?.span.setStatus({
|
|
1141
|
-
code:
|
|
1244
|
+
code: import_api4.SpanStatusCode.ERROR,
|
|
1142
1245
|
message: "invalid handshake response"
|
|
1143
1246
|
});
|
|
1144
1247
|
this.log?.warn(`received invalid handshake resp`, {
|
|
@@ -1147,7 +1250,7 @@ var ClientTransport = class extends Transport {
|
|
|
1147
1250
|
connectedTo: parsed.from,
|
|
1148
1251
|
transportMessage: parsed,
|
|
1149
1252
|
validationErrors: [
|
|
1150
|
-
...
|
|
1253
|
+
...import_value2.Value.Errors(
|
|
1151
1254
|
ControlMessageHandshakeResponseSchema,
|
|
1152
1255
|
parsed.payload
|
|
1153
1256
|
)
|
|
@@ -1159,31 +1262,47 @@ var ClientTransport = class extends Transport {
|
|
|
1159
1262
|
);
|
|
1160
1263
|
return false;
|
|
1161
1264
|
}
|
|
1265
|
+
const previousSession = this.sessions.get(parsed.from);
|
|
1162
1266
|
if (!parsed.payload.status.ok) {
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1267
|
+
if (parsed.payload.status.reason === SESSION_STATE_MISMATCH) {
|
|
1268
|
+
if (previousSession) {
|
|
1269
|
+
this.deleteSession({
|
|
1270
|
+
session: previousSession,
|
|
1271
|
+
closeHandshakingConnection: true
|
|
1272
|
+
});
|
|
1273
|
+
}
|
|
1274
|
+
conn.telemetry?.span.setStatus({
|
|
1275
|
+
code: import_api4.SpanStatusCode.ERROR,
|
|
1276
|
+
message: parsed.payload.status.reason
|
|
1277
|
+
});
|
|
1278
|
+
} else {
|
|
1279
|
+
conn.telemetry?.span.setStatus({
|
|
1280
|
+
code: import_api4.SpanStatusCode.ERROR,
|
|
1281
|
+
message: "handshake rejected"
|
|
1282
|
+
});
|
|
1283
|
+
}
|
|
1284
|
+
this.log?.warn(
|
|
1285
|
+
`received handshake rejection: ${parsed.payload.status.reason}`,
|
|
1286
|
+
{
|
|
1287
|
+
...conn.loggingMetadata,
|
|
1288
|
+
clientId: this.clientId,
|
|
1289
|
+
connectedTo: parsed.from,
|
|
1290
|
+
transportMessage: parsed
|
|
1291
|
+
}
|
|
1292
|
+
);
|
|
1173
1293
|
this.protocolError(
|
|
1174
1294
|
ProtocolError.HandshakeFailed,
|
|
1175
1295
|
parsed.payload.status.reason
|
|
1176
1296
|
);
|
|
1177
1297
|
return false;
|
|
1178
1298
|
}
|
|
1179
|
-
const previousSession = this.sessions.get(parsed.from);
|
|
1180
1299
|
if (previousSession?.advertisedSessionId && previousSession.advertisedSessionId !== parsed.payload.status.sessionId) {
|
|
1181
1300
|
this.deleteSession({
|
|
1182
1301
|
session: previousSession,
|
|
1183
1302
|
closeHandshakingConnection: true
|
|
1184
1303
|
});
|
|
1185
1304
|
conn.telemetry?.span.setStatus({
|
|
1186
|
-
code:
|
|
1305
|
+
code: import_api4.SpanStatusCode.ERROR,
|
|
1187
1306
|
message: "session id mismatch"
|
|
1188
1307
|
});
|
|
1189
1308
|
this.log?.warn(`handshake from ${parsed.from} session id mismatch`, {
|
|
@@ -1283,7 +1402,7 @@ var ClientTransport = class extends Transport {
|
|
|
1283
1402
|
} catch (err) {
|
|
1284
1403
|
const errStr = coerceErrorString(err);
|
|
1285
1404
|
span.recordException(errStr);
|
|
1286
|
-
span.setStatus({ code:
|
|
1405
|
+
span.setStatus({ code: import_api4.SpanStatusCode.ERROR });
|
|
1287
1406
|
throw err;
|
|
1288
1407
|
} finally {
|
|
1289
1408
|
span.end();
|
|
@@ -1334,13 +1453,13 @@ var ClientTransport = class extends Transport {
|
|
|
1334
1453
|
let metadata = void 0;
|
|
1335
1454
|
if (this.handshakeExtensions) {
|
|
1336
1455
|
metadata = await this.handshakeExtensions.construct();
|
|
1337
|
-
if (!
|
|
1456
|
+
if (!import_value2.Value.Check(this.handshakeExtensions.schema, metadata)) {
|
|
1338
1457
|
this.log?.error(`constructed handshake metadata did not match schema`, {
|
|
1339
1458
|
...conn.loggingMetadata,
|
|
1340
1459
|
clientId: this.clientId,
|
|
1341
1460
|
connectedTo: to,
|
|
1342
1461
|
validationErrors: [
|
|
1343
|
-
...
|
|
1462
|
+
...import_value2.Value.Errors(this.handshakeExtensions.schema, metadata)
|
|
1344
1463
|
],
|
|
1345
1464
|
tags: ["invariant-violation"]
|
|
1346
1465
|
});
|
|
@@ -1349,20 +1468,24 @@ var ClientTransport = class extends Transport {
|
|
|
1349
1468
|
"handshake metadata did not match schema"
|
|
1350
1469
|
);
|
|
1351
1470
|
conn.telemetry?.span.setStatus({
|
|
1352
|
-
code:
|
|
1471
|
+
code: import_api4.SpanStatusCode.ERROR,
|
|
1353
1472
|
message: "handshake meta mismatch"
|
|
1354
1473
|
});
|
|
1355
1474
|
return false;
|
|
1356
1475
|
}
|
|
1357
1476
|
}
|
|
1358
1477
|
const { session } = this.getOrCreateSession({ to, handshakingConn: conn });
|
|
1359
|
-
const requestMsg = handshakeRequestMessage(
|
|
1360
|
-
this.clientId,
|
|
1478
|
+
const requestMsg = handshakeRequestMessage({
|
|
1479
|
+
from: this.clientId,
|
|
1361
1480
|
to,
|
|
1362
|
-
session.id,
|
|
1481
|
+
sessionId: session.id,
|
|
1482
|
+
expectedSessionState: {
|
|
1483
|
+
reconnect: session.advertisedSessionId !== void 0,
|
|
1484
|
+
nextExpectedSeq: session.nextExpectedSeq
|
|
1485
|
+
},
|
|
1363
1486
|
metadata,
|
|
1364
|
-
getPropagationContext(session.telemetry.ctx)
|
|
1365
|
-
);
|
|
1487
|
+
tracing: getPropagationContext(session.telemetry.ctx)
|
|
1488
|
+
});
|
|
1366
1489
|
this.log?.debug(`sending handshake request to ${to}`, {
|
|
1367
1490
|
...conn.loggingMetadata,
|
|
1368
1491
|
clientId: this.clientId,
|