@replit/river 0.23.11 → 0.23.13
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-2FNLANTJ.js +327 -0
- package/dist/chunk-2FNLANTJ.js.map +1 -0
- package/dist/{chunk-3AW3IXVD.js → chunk-4PVU7J25.js} +1 -21
- package/dist/chunk-4PVU7J25.js.map +1 -0
- package/dist/{chunk-T6YEMFUF.js → chunk-4QZOW4DH.js} +2 -2
- package/dist/{chunk-MEHCOYKJ.js → chunk-ES4XO2XD.js} +2 -2
- package/dist/{chunk-MEHCOYKJ.js.map → chunk-ES4XO2XD.js.map} +1 -1
- package/dist/{chunk-ZSKCZYVU.js → chunk-KFTGQ3QC.js} +2 -2
- package/dist/chunk-KFTGQ3QC.js.map +1 -0
- package/dist/chunk-S4DUN7KK.js +455 -0
- package/dist/chunk-S4DUN7KK.js.map +1 -0
- package/dist/{chunk-HM7VDTDJ.js → chunk-SX6HI63Q.js} +2 -2
- package/dist/chunk-XM656KMN.js +408 -0
- package/dist/chunk-XM656KMN.js.map +1 -0
- package/dist/chunk-ZUKDZY54.js +271 -0
- package/dist/chunk-ZUKDZY54.js.map +1 -0
- package/dist/client-dd5c9dd0.d.ts +52 -0
- package/dist/codec/index.js +20 -2
- package/dist/codec/index.js.map +1 -1
- package/dist/{connection-261eee8f.d.ts → connection-39816c00.d.ts} +1 -1
- package/dist/{connection-c1eeb95d.d.ts → connection-40318f22.d.ts} +1 -1
- package/dist/{transport-c8f36f6d.d.ts → handshake-e428d1c8.d.ts} +91 -155
- 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 +1 -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-ebf80863.d.ts +24 -0
- package/dist/{services-524bab79.d.ts → services-f406b3aa.d.ts} +3 -2
- package/dist/transport/impls/uds/client.cjs +222 -174
- 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 +252 -223
- 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 +224 -176
- 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 +206 -177
- 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 +170 -116
- 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 +6 -8
- 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 +1 -1
- package/dist/chunk-3AW3IXVD.js.map +0 -1
- package/dist/chunk-EOJMKMDO.js +0 -1372
- package/dist/chunk-EOJMKMDO.js.map +0 -1
- package/dist/chunk-ZSKCZYVU.js.map +0 -1
- /package/dist/{chunk-T6YEMFUF.js.map → chunk-4QZOW4DH.js.map} +0 -0
- /package/dist/{chunk-HM7VDTDJ.js.map → chunk-SX6HI63Q.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");
|
|
@@ -105,6 +105,154 @@ function isAck(controlFlag) {
|
|
|
105
105
|
return (controlFlag & 1 /* AckBit */) === 1 /* AckBit */;
|
|
106
106
|
}
|
|
107
107
|
|
|
108
|
+
// codec/json.ts
|
|
109
|
+
var encoder = new TextEncoder();
|
|
110
|
+
var decoder = new TextDecoder();
|
|
111
|
+
function uint8ArrayToBase64(uint8Array) {
|
|
112
|
+
let binary = "";
|
|
113
|
+
uint8Array.forEach((byte) => {
|
|
114
|
+
binary += String.fromCharCode(byte);
|
|
115
|
+
});
|
|
116
|
+
return btoa(binary);
|
|
117
|
+
}
|
|
118
|
+
function base64ToUint8Array(base64) {
|
|
119
|
+
const binaryString = atob(base64);
|
|
120
|
+
const uint8Array = new Uint8Array(binaryString.length);
|
|
121
|
+
for (let i = 0; i < binaryString.length; i++) {
|
|
122
|
+
uint8Array[i] = binaryString.charCodeAt(i);
|
|
123
|
+
}
|
|
124
|
+
return uint8Array;
|
|
125
|
+
}
|
|
126
|
+
var NaiveJsonCodec = {
|
|
127
|
+
toBuffer: (obj) => {
|
|
128
|
+
return encoder.encode(
|
|
129
|
+
JSON.stringify(obj, function replacer(key) {
|
|
130
|
+
const val = this[key];
|
|
131
|
+
if (val instanceof Uint8Array) {
|
|
132
|
+
return { $t: uint8ArrayToBase64(val) };
|
|
133
|
+
} else {
|
|
134
|
+
return val;
|
|
135
|
+
}
|
|
136
|
+
})
|
|
137
|
+
);
|
|
138
|
+
},
|
|
139
|
+
fromBuffer: (buff) => {
|
|
140
|
+
try {
|
|
141
|
+
const parsed = JSON.parse(
|
|
142
|
+
decoder.decode(buff),
|
|
143
|
+
function reviver(_key, val) {
|
|
144
|
+
if (val?.$t) {
|
|
145
|
+
return base64ToUint8Array(val.$t);
|
|
146
|
+
} else {
|
|
147
|
+
return val;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
);
|
|
151
|
+
if (typeof parsed === "object")
|
|
152
|
+
return parsed;
|
|
153
|
+
return null;
|
|
154
|
+
} catch {
|
|
155
|
+
return null;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
// transport/options.ts
|
|
161
|
+
var defaultTransportOptions = {
|
|
162
|
+
heartbeatIntervalMs: 1e3,
|
|
163
|
+
heartbeatsUntilDead: 2,
|
|
164
|
+
sessionDisconnectGraceMs: 5e3,
|
|
165
|
+
codec: NaiveJsonCodec
|
|
166
|
+
};
|
|
167
|
+
var defaultConnectionRetryOptions = {
|
|
168
|
+
baseIntervalMs: 250,
|
|
169
|
+
maxJitterMs: 200,
|
|
170
|
+
maxBackoffMs: 32e3,
|
|
171
|
+
attemptBudgetCapacity: 5,
|
|
172
|
+
budgetRestoreIntervalMs: 200
|
|
173
|
+
};
|
|
174
|
+
var defaultClientTransportOptions = {
|
|
175
|
+
...defaultTransportOptions,
|
|
176
|
+
...defaultConnectionRetryOptions
|
|
177
|
+
};
|
|
178
|
+
var defaultServerTransportOptions = {
|
|
179
|
+
...defaultTransportOptions
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
// transport/rateLimit.ts
|
|
183
|
+
var LeakyBucketRateLimit = class {
|
|
184
|
+
budgetConsumed;
|
|
185
|
+
intervalHandles;
|
|
186
|
+
options;
|
|
187
|
+
constructor(options) {
|
|
188
|
+
this.options = options;
|
|
189
|
+
this.budgetConsumed = /* @__PURE__ */ new Map();
|
|
190
|
+
this.intervalHandles = /* @__PURE__ */ new Map();
|
|
191
|
+
}
|
|
192
|
+
getBackoffMs(user) {
|
|
193
|
+
if (!this.budgetConsumed.has(user))
|
|
194
|
+
return 0;
|
|
195
|
+
const exponent = Math.max(0, this.getBudgetConsumed(user) - 1);
|
|
196
|
+
const jitter = Math.floor(Math.random() * this.options.maxJitterMs);
|
|
197
|
+
const backoffMs = Math.min(
|
|
198
|
+
this.options.baseIntervalMs * 2 ** exponent,
|
|
199
|
+
this.options.maxBackoffMs
|
|
200
|
+
);
|
|
201
|
+
return backoffMs + jitter;
|
|
202
|
+
}
|
|
203
|
+
get totalBudgetRestoreTime() {
|
|
204
|
+
return this.options.budgetRestoreIntervalMs * this.options.attemptBudgetCapacity;
|
|
205
|
+
}
|
|
206
|
+
consumeBudget(user) {
|
|
207
|
+
this.stopLeak(user);
|
|
208
|
+
this.budgetConsumed.set(user, this.getBudgetConsumed(user) + 1);
|
|
209
|
+
}
|
|
210
|
+
getBudgetConsumed(user) {
|
|
211
|
+
return this.budgetConsumed.get(user) ?? 0;
|
|
212
|
+
}
|
|
213
|
+
hasBudget(user) {
|
|
214
|
+
return this.getBudgetConsumed(user) < this.options.attemptBudgetCapacity;
|
|
215
|
+
}
|
|
216
|
+
startRestoringBudget(user) {
|
|
217
|
+
if (this.intervalHandles.has(user)) {
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
const restoreBudgetForUser = () => {
|
|
221
|
+
const currentBudget = this.budgetConsumed.get(user);
|
|
222
|
+
if (!currentBudget) {
|
|
223
|
+
this.stopLeak(user);
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
const newBudget = currentBudget - 1;
|
|
227
|
+
if (newBudget === 0) {
|
|
228
|
+
this.budgetConsumed.delete(user);
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
this.budgetConsumed.set(user, newBudget);
|
|
232
|
+
};
|
|
233
|
+
const intervalHandle = setInterval(
|
|
234
|
+
restoreBudgetForUser,
|
|
235
|
+
this.options.budgetRestoreIntervalMs
|
|
236
|
+
);
|
|
237
|
+
this.intervalHandles.set(user, intervalHandle);
|
|
238
|
+
}
|
|
239
|
+
stopLeak(user) {
|
|
240
|
+
if (!this.intervalHandles.has(user)) {
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
clearInterval(this.intervalHandles.get(user));
|
|
244
|
+
this.intervalHandles.delete(user);
|
|
245
|
+
}
|
|
246
|
+
close() {
|
|
247
|
+
for (const user of this.intervalHandles.keys()) {
|
|
248
|
+
this.stopLeak(user);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
};
|
|
252
|
+
|
|
253
|
+
// transport/transport.ts
|
|
254
|
+
var import_value = require("@sinclair/typebox/value");
|
|
255
|
+
|
|
108
256
|
// logging/log.ts
|
|
109
257
|
var LoggingLevels = {
|
|
110
258
|
debug: -1,
|
|
@@ -202,7 +350,7 @@ var import_nanoid2 = require("nanoid");
|
|
|
202
350
|
var import_api = require("@opentelemetry/api");
|
|
203
351
|
|
|
204
352
|
// package.json
|
|
205
|
-
var version = "0.23.
|
|
353
|
+
var version = "0.23.13";
|
|
206
354
|
|
|
207
355
|
// tracing/index.ts
|
|
208
356
|
function getPropagationContext(ctx) {
|
|
@@ -461,10 +609,12 @@ var Session = class {
|
|
|
461
609
|
this.connection.close();
|
|
462
610
|
this.connection = void 0;
|
|
463
611
|
}
|
|
464
|
-
replaceWithNewConnection(newConn) {
|
|
612
|
+
replaceWithNewConnection(newConn, isTransparentReconnect) {
|
|
465
613
|
this.closeStaleConnection(newConn);
|
|
466
614
|
this.cancelGrace();
|
|
467
|
-
|
|
615
|
+
if (isTransparentReconnect) {
|
|
616
|
+
this.sendBufferedMessages(newConn);
|
|
617
|
+
}
|
|
468
618
|
this.connection = newConn;
|
|
469
619
|
this.handshakingConnection = void 0;
|
|
470
620
|
}
|
|
@@ -535,159 +685,8 @@ var Session = class {
|
|
|
535
685
|
}
|
|
536
686
|
};
|
|
537
687
|
|
|
538
|
-
// util/stringify.ts
|
|
539
|
-
function coerceErrorString(err) {
|
|
540
|
-
if (err instanceof Error) {
|
|
541
|
-
return err.message || "unknown reason";
|
|
542
|
-
}
|
|
543
|
-
return `[coerced to error] ${String(err)}`;
|
|
544
|
-
}
|
|
545
|
-
|
|
546
|
-
// transport/rateLimit.ts
|
|
547
|
-
var LeakyBucketRateLimit = class {
|
|
548
|
-
budgetConsumed;
|
|
549
|
-
intervalHandles;
|
|
550
|
-
options;
|
|
551
|
-
constructor(options) {
|
|
552
|
-
this.options = options;
|
|
553
|
-
this.budgetConsumed = /* @__PURE__ */ new Map();
|
|
554
|
-
this.intervalHandles = /* @__PURE__ */ new Map();
|
|
555
|
-
}
|
|
556
|
-
getBackoffMs(user) {
|
|
557
|
-
if (!this.budgetConsumed.has(user))
|
|
558
|
-
return 0;
|
|
559
|
-
const exponent = Math.max(0, this.getBudgetConsumed(user) - 1);
|
|
560
|
-
const jitter = Math.floor(Math.random() * this.options.maxJitterMs);
|
|
561
|
-
const backoffMs = Math.min(
|
|
562
|
-
this.options.baseIntervalMs * 2 ** exponent,
|
|
563
|
-
this.options.maxBackoffMs
|
|
564
|
-
);
|
|
565
|
-
return backoffMs + jitter;
|
|
566
|
-
}
|
|
567
|
-
get totalBudgetRestoreTime() {
|
|
568
|
-
return this.options.budgetRestoreIntervalMs * this.options.attemptBudgetCapacity;
|
|
569
|
-
}
|
|
570
|
-
consumeBudget(user) {
|
|
571
|
-
this.stopLeak(user);
|
|
572
|
-
this.budgetConsumed.set(user, this.getBudgetConsumed(user) + 1);
|
|
573
|
-
}
|
|
574
|
-
getBudgetConsumed(user) {
|
|
575
|
-
return this.budgetConsumed.get(user) ?? 0;
|
|
576
|
-
}
|
|
577
|
-
hasBudget(user) {
|
|
578
|
-
return this.getBudgetConsumed(user) < this.options.attemptBudgetCapacity;
|
|
579
|
-
}
|
|
580
|
-
startRestoringBudget(user) {
|
|
581
|
-
if (this.intervalHandles.has(user)) {
|
|
582
|
-
return;
|
|
583
|
-
}
|
|
584
|
-
const restoreBudgetForUser = () => {
|
|
585
|
-
const currentBudget = this.budgetConsumed.get(user);
|
|
586
|
-
if (!currentBudget) {
|
|
587
|
-
this.stopLeak(user);
|
|
588
|
-
return;
|
|
589
|
-
}
|
|
590
|
-
const newBudget = currentBudget - 1;
|
|
591
|
-
if (newBudget === 0) {
|
|
592
|
-
this.budgetConsumed.delete(user);
|
|
593
|
-
return;
|
|
594
|
-
}
|
|
595
|
-
this.budgetConsumed.set(user, newBudget);
|
|
596
|
-
};
|
|
597
|
-
const intervalHandle = setInterval(
|
|
598
|
-
restoreBudgetForUser,
|
|
599
|
-
this.options.budgetRestoreIntervalMs
|
|
600
|
-
);
|
|
601
|
-
this.intervalHandles.set(user, intervalHandle);
|
|
602
|
-
}
|
|
603
|
-
stopLeak(user) {
|
|
604
|
-
if (!this.intervalHandles.has(user)) {
|
|
605
|
-
return;
|
|
606
|
-
}
|
|
607
|
-
clearInterval(this.intervalHandles.get(user));
|
|
608
|
-
this.intervalHandles.delete(user);
|
|
609
|
-
}
|
|
610
|
-
close() {
|
|
611
|
-
for (const user of this.intervalHandles.keys()) {
|
|
612
|
-
this.stopLeak(user);
|
|
613
|
-
}
|
|
614
|
-
}
|
|
615
|
-
};
|
|
616
|
-
|
|
617
|
-
// codec/json.ts
|
|
618
|
-
var encoder = new TextEncoder();
|
|
619
|
-
var decoder = new TextDecoder();
|
|
620
|
-
function uint8ArrayToBase64(uint8Array) {
|
|
621
|
-
let binary = "";
|
|
622
|
-
uint8Array.forEach((byte) => {
|
|
623
|
-
binary += String.fromCharCode(byte);
|
|
624
|
-
});
|
|
625
|
-
return btoa(binary);
|
|
626
|
-
}
|
|
627
|
-
function base64ToUint8Array(base64) {
|
|
628
|
-
const binaryString = atob(base64);
|
|
629
|
-
const uint8Array = new Uint8Array(binaryString.length);
|
|
630
|
-
for (let i = 0; i < binaryString.length; i++) {
|
|
631
|
-
uint8Array[i] = binaryString.charCodeAt(i);
|
|
632
|
-
}
|
|
633
|
-
return uint8Array;
|
|
634
|
-
}
|
|
635
|
-
var NaiveJsonCodec = {
|
|
636
|
-
toBuffer: (obj) => {
|
|
637
|
-
return encoder.encode(
|
|
638
|
-
JSON.stringify(obj, function replacer(key) {
|
|
639
|
-
const val = this[key];
|
|
640
|
-
if (val instanceof Uint8Array) {
|
|
641
|
-
return { $t: uint8ArrayToBase64(val) };
|
|
642
|
-
} else {
|
|
643
|
-
return val;
|
|
644
|
-
}
|
|
645
|
-
})
|
|
646
|
-
);
|
|
647
|
-
},
|
|
648
|
-
fromBuffer: (buff) => {
|
|
649
|
-
try {
|
|
650
|
-
const parsed = JSON.parse(
|
|
651
|
-
decoder.decode(buff),
|
|
652
|
-
function reviver(_key, val) {
|
|
653
|
-
if (val?.$t) {
|
|
654
|
-
return base64ToUint8Array(val.$t);
|
|
655
|
-
} else {
|
|
656
|
-
return val;
|
|
657
|
-
}
|
|
658
|
-
}
|
|
659
|
-
);
|
|
660
|
-
if (typeof parsed === "object")
|
|
661
|
-
return parsed;
|
|
662
|
-
return null;
|
|
663
|
-
} catch {
|
|
664
|
-
return null;
|
|
665
|
-
}
|
|
666
|
-
}
|
|
667
|
-
};
|
|
668
|
-
|
|
669
688
|
// transport/transport.ts
|
|
670
689
|
var import_api3 = require("@opentelemetry/api");
|
|
671
|
-
var defaultTransportOptions = {
|
|
672
|
-
heartbeatIntervalMs: 1e3,
|
|
673
|
-
heartbeatsUntilDead: 2,
|
|
674
|
-
sessionDisconnectGraceMs: 5e3,
|
|
675
|
-
codec: NaiveJsonCodec
|
|
676
|
-
};
|
|
677
|
-
var defaultConnectionRetryOptions = {
|
|
678
|
-
baseIntervalMs: 250,
|
|
679
|
-
maxJitterMs: 200,
|
|
680
|
-
maxBackoffMs: 32e3,
|
|
681
|
-
attemptBudgetCapacity: 5,
|
|
682
|
-
budgetRestoreIntervalMs: 200
|
|
683
|
-
};
|
|
684
|
-
var defaultClientTransportOptions = {
|
|
685
|
-
...defaultTransportOptions,
|
|
686
|
-
...defaultConnectionRetryOptions
|
|
687
|
-
};
|
|
688
|
-
var defaultServerTransportOptions = {
|
|
689
|
-
...defaultTransportOptions
|
|
690
|
-
};
|
|
691
690
|
var Transport = class {
|
|
692
691
|
/**
|
|
693
692
|
* The status of the transport.
|
|
@@ -748,15 +747,13 @@ var Transport = class {
|
|
|
748
747
|
* and we know the identity of the connected client.
|
|
749
748
|
* @param conn The connection object.
|
|
750
749
|
*/
|
|
751
|
-
onConnect(conn, session,
|
|
750
|
+
onConnect(conn, session, isTransparentReconnect) {
|
|
752
751
|
this.eventDispatcher.dispatchEvent("connectionStatus", {
|
|
753
752
|
status: "connect",
|
|
754
753
|
conn
|
|
755
754
|
});
|
|
756
755
|
conn.telemetry = createConnectionTelemetryInfo(conn, session.telemetry);
|
|
757
|
-
|
|
758
|
-
session.replaceWithNewConnection(conn);
|
|
759
|
-
}
|
|
756
|
+
session.replaceWithNewConnection(conn, isTransparentReconnect);
|
|
760
757
|
this.log?.info(`connected to ${session.to}`, {
|
|
761
758
|
...conn.loggingMetadata,
|
|
762
759
|
...session.loggingMetadata
|
|
@@ -788,7 +785,8 @@ var Transport = class {
|
|
|
788
785
|
propagationCtx
|
|
789
786
|
}) {
|
|
790
787
|
let session = this.sessions.get(to);
|
|
791
|
-
|
|
788
|
+
const isReconnect = session !== void 0;
|
|
789
|
+
let isTransparentReconnect = isReconnect;
|
|
792
790
|
if (session?.advertisedSessionId !== void 0 && sessionId !== void 0 && session.advertisedSessionId !== sessionId) {
|
|
793
791
|
this.log?.info(
|
|
794
792
|
`session for ${to} already exists but has a different session id (expected: ${session.advertisedSessionId}, got: ${sessionId}), creating a new one`,
|
|
@@ -799,7 +797,7 @@ var Transport = class {
|
|
|
799
797
|
closeHandshakingConnection: handshakingConn !== void 0,
|
|
800
798
|
handshakingConn
|
|
801
799
|
});
|
|
802
|
-
|
|
800
|
+
isTransparentReconnect = false;
|
|
803
801
|
session = void 0;
|
|
804
802
|
}
|
|
805
803
|
if (!session) {
|
|
@@ -815,7 +813,7 @@ var Transport = class {
|
|
|
815
813
|
if (handshakingConn !== void 0) {
|
|
816
814
|
session.replaceWithNewHandshakingConnection(handshakingConn);
|
|
817
815
|
}
|
|
818
|
-
return { session, isReconnect };
|
|
816
|
+
return { session, isReconnect, isTransparentReconnect };
|
|
819
817
|
}
|
|
820
818
|
deleteSession({
|
|
821
819
|
session,
|
|
@@ -843,6 +841,16 @@ var Transport = class {
|
|
|
843
841
|
* @param connectedTo The peer we are connected to.
|
|
844
842
|
*/
|
|
845
843
|
onDisconnect(conn, session) {
|
|
844
|
+
if (session.connection !== void 0 && session.connection.id !== conn.id) {
|
|
845
|
+
session.telemetry.span.addEvent("onDisconnect race");
|
|
846
|
+
this.log?.warn("onDisconnect race", {
|
|
847
|
+
clientId: this.clientId,
|
|
848
|
+
...session.loggingMetadata,
|
|
849
|
+
...conn.loggingMetadata,
|
|
850
|
+
tags: ["invariant-violation"]
|
|
851
|
+
});
|
|
852
|
+
return;
|
|
853
|
+
}
|
|
846
854
|
conn.telemetry?.span.end();
|
|
847
855
|
this.eventDispatcher.dispatchEvent("connectionStatus", {
|
|
848
856
|
status: "disconnect",
|
|
@@ -850,6 +858,16 @@ var Transport = class {
|
|
|
850
858
|
});
|
|
851
859
|
session.connection = void 0;
|
|
852
860
|
session.beginGrace(() => {
|
|
861
|
+
if (session.connection !== void 0) {
|
|
862
|
+
session.telemetry.span.addEvent("session grace period race");
|
|
863
|
+
this.log?.warn("session grace period race", {
|
|
864
|
+
clientId: this.clientId,
|
|
865
|
+
...session.loggingMetadata,
|
|
866
|
+
...conn.loggingMetadata,
|
|
867
|
+
tags: ["invariant-violation"]
|
|
868
|
+
});
|
|
869
|
+
return;
|
|
870
|
+
}
|
|
853
871
|
session.telemetry.span.addEvent("session grace period expired");
|
|
854
872
|
this.deleteSession({
|
|
855
873
|
session,
|
|
@@ -1017,6 +1035,17 @@ var Transport = class {
|
|
|
1017
1035
|
return this.status;
|
|
1018
1036
|
}
|
|
1019
1037
|
};
|
|
1038
|
+
|
|
1039
|
+
// util/stringify.ts
|
|
1040
|
+
function coerceErrorString(err) {
|
|
1041
|
+
if (err instanceof Error) {
|
|
1042
|
+
return err.message || "unknown reason";
|
|
1043
|
+
}
|
|
1044
|
+
return `[coerced to error] ${String(err)}`;
|
|
1045
|
+
}
|
|
1046
|
+
|
|
1047
|
+
// transport/client.ts
|
|
1048
|
+
var import_value2 = require("@sinclair/typebox/value");
|
|
1020
1049
|
var ClientTransport = class extends Transport {
|
|
1021
1050
|
/**
|
|
1022
1051
|
* The options for this transport.
|
|
@@ -1077,7 +1106,7 @@ var ClientTransport = class extends Transport {
|
|
|
1077
1106
|
const parsed = this.parseMsg(data2, conn);
|
|
1078
1107
|
if (!parsed) {
|
|
1079
1108
|
conn.telemetry?.span.setStatus({
|
|
1080
|
-
code:
|
|
1109
|
+
code: import_api4.SpanStatusCode.ERROR,
|
|
1081
1110
|
message: "message parse failure"
|
|
1082
1111
|
});
|
|
1083
1112
|
conn.close();
|
|
@@ -1108,7 +1137,7 @@ var ClientTransport = class extends Transport {
|
|
|
1108
1137
|
});
|
|
1109
1138
|
conn.addErrorListener((err) => {
|
|
1110
1139
|
conn.telemetry?.span.setStatus({
|
|
1111
|
-
code:
|
|
1140
|
+
code: import_api4.SpanStatusCode.ERROR,
|
|
1112
1141
|
message: "connection error"
|
|
1113
1142
|
});
|
|
1114
1143
|
this.log?.warn(
|
|
@@ -1126,7 +1155,7 @@ var ClientTransport = class extends Transport {
|
|
|
1126
1155
|
const parsed = this.parseMsg(data, conn);
|
|
1127
1156
|
if (!parsed) {
|
|
1128
1157
|
conn.telemetry?.span.setStatus({
|
|
1129
|
-
code:
|
|
1158
|
+
code: import_api4.SpanStatusCode.ERROR,
|
|
1130
1159
|
message: "non-transport message"
|
|
1131
1160
|
});
|
|
1132
1161
|
this.protocolError(
|
|
@@ -1135,9 +1164,9 @@ var ClientTransport = class extends Transport {
|
|
|
1135
1164
|
);
|
|
1136
1165
|
return false;
|
|
1137
1166
|
}
|
|
1138
|
-
if (!
|
|
1167
|
+
if (!import_value2.Value.Check(ControlMessageHandshakeResponseSchema, parsed.payload)) {
|
|
1139
1168
|
conn.telemetry?.span.setStatus({
|
|
1140
|
-
code:
|
|
1169
|
+
code: import_api4.SpanStatusCode.ERROR,
|
|
1141
1170
|
message: "invalid handshake response"
|
|
1142
1171
|
});
|
|
1143
1172
|
this.log?.warn(`received invalid handshake resp`, {
|
|
@@ -1146,7 +1175,7 @@ var ClientTransport = class extends Transport {
|
|
|
1146
1175
|
connectedTo: parsed.from,
|
|
1147
1176
|
transportMessage: parsed,
|
|
1148
1177
|
validationErrors: [
|
|
1149
|
-
...
|
|
1178
|
+
...import_value2.Value.Errors(
|
|
1150
1179
|
ControlMessageHandshakeResponseSchema,
|
|
1151
1180
|
parsed.payload
|
|
1152
1181
|
)
|
|
@@ -1160,7 +1189,7 @@ var ClientTransport = class extends Transport {
|
|
|
1160
1189
|
}
|
|
1161
1190
|
if (!parsed.payload.status.ok) {
|
|
1162
1191
|
conn.telemetry?.span.setStatus({
|
|
1163
|
-
code:
|
|
1192
|
+
code: import_api4.SpanStatusCode.ERROR,
|
|
1164
1193
|
message: "handshake rejected"
|
|
1165
1194
|
});
|
|
1166
1195
|
this.log?.warn(`received handshake rejection`, {
|
|
@@ -1175,18 +1204,37 @@ var ClientTransport = class extends Transport {
|
|
|
1175
1204
|
);
|
|
1176
1205
|
return false;
|
|
1177
1206
|
}
|
|
1207
|
+
const previousSession = this.sessions.get(parsed.from);
|
|
1208
|
+
if (previousSession?.advertisedSessionId && previousSession.advertisedSessionId !== parsed.payload.status.sessionId) {
|
|
1209
|
+
this.deleteSession({
|
|
1210
|
+
session: previousSession,
|
|
1211
|
+
closeHandshakingConnection: true
|
|
1212
|
+
});
|
|
1213
|
+
conn.telemetry?.span.setStatus({
|
|
1214
|
+
code: import_api4.SpanStatusCode.ERROR,
|
|
1215
|
+
message: "session id mismatch"
|
|
1216
|
+
});
|
|
1217
|
+
this.log?.warn(`handshake from ${parsed.from} session id mismatch`, {
|
|
1218
|
+
...conn.loggingMetadata,
|
|
1219
|
+
clientId: this.clientId,
|
|
1220
|
+
connectedTo: parsed.from,
|
|
1221
|
+
transportMessage: parsed
|
|
1222
|
+
});
|
|
1223
|
+
this.protocolError(ProtocolError.HandshakeFailed, "session id mismatch");
|
|
1224
|
+
return false;
|
|
1225
|
+
}
|
|
1178
1226
|
this.log?.debug(`handshake from ${parsed.from} ok`, {
|
|
1179
1227
|
...conn.loggingMetadata,
|
|
1180
1228
|
clientId: this.clientId,
|
|
1181
1229
|
connectedTo: parsed.from,
|
|
1182
1230
|
transportMessage: parsed
|
|
1183
1231
|
});
|
|
1184
|
-
const { session,
|
|
1232
|
+
const { session, isTransparentReconnect } = this.getOrCreateSession({
|
|
1185
1233
|
to: parsed.from,
|
|
1186
1234
|
conn,
|
|
1187
1235
|
sessionId: parsed.payload.status.sessionId
|
|
1188
1236
|
});
|
|
1189
|
-
this.onConnect(conn, session,
|
|
1237
|
+
this.onConnect(conn, session, isTransparentReconnect);
|
|
1190
1238
|
this.retryBudget.startRestoringBudget(session.to);
|
|
1191
1239
|
return session;
|
|
1192
1240
|
}
|
|
@@ -1263,7 +1311,7 @@ var ClientTransport = class extends Transport {
|
|
|
1263
1311
|
} catch (err) {
|
|
1264
1312
|
const errStr = coerceErrorString(err);
|
|
1265
1313
|
span.recordException(errStr);
|
|
1266
|
-
span.setStatus({ code:
|
|
1314
|
+
span.setStatus({ code: import_api4.SpanStatusCode.ERROR });
|
|
1267
1315
|
throw err;
|
|
1268
1316
|
} finally {
|
|
1269
1317
|
span.end();
|
|
@@ -1314,13 +1362,13 @@ var ClientTransport = class extends Transport {
|
|
|
1314
1362
|
let metadata = void 0;
|
|
1315
1363
|
if (this.handshakeExtensions) {
|
|
1316
1364
|
metadata = await this.handshakeExtensions.construct();
|
|
1317
|
-
if (!
|
|
1365
|
+
if (!import_value2.Value.Check(this.handshakeExtensions.schema, metadata)) {
|
|
1318
1366
|
this.log?.error(`constructed handshake metadata did not match schema`, {
|
|
1319
1367
|
...conn.loggingMetadata,
|
|
1320
1368
|
clientId: this.clientId,
|
|
1321
1369
|
connectedTo: to,
|
|
1322
1370
|
validationErrors: [
|
|
1323
|
-
...
|
|
1371
|
+
...import_value2.Value.Errors(this.handshakeExtensions.schema, metadata)
|
|
1324
1372
|
],
|
|
1325
1373
|
tags: ["invariant-violation"]
|
|
1326
1374
|
});
|
|
@@ -1329,7 +1377,7 @@ var ClientTransport = class extends Transport {
|
|
|
1329
1377
|
"handshake metadata did not match schema"
|
|
1330
1378
|
);
|
|
1331
1379
|
conn.telemetry?.span.setStatus({
|
|
1332
|
-
code:
|
|
1380
|
+
code: import_api4.SpanStatusCode.ERROR,
|
|
1333
1381
|
message: "handshake meta mismatch"
|
|
1334
1382
|
});
|
|
1335
1383
|
return false;
|