@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.
Files changed (75) hide show
  1. package/dist/{chunk-3AW3IXVD.js → chunk-4PVU7J25.js} +1 -21
  2. package/dist/chunk-4PVU7J25.js.map +1 -0
  3. package/dist/{chunk-HDBVL7EF.js → chunk-BEALFLCB.js} +2 -2
  4. package/dist/chunk-D2DHRRBN.js +476 -0
  5. package/dist/chunk-D2DHRRBN.js.map +1 -0
  6. package/dist/{chunk-7RUKEUKE.js → chunk-GCCRVSMR.js} +33 -4
  7. package/dist/chunk-GCCRVSMR.js.map +1 -0
  8. package/dist/{chunk-XZ6IOBM5.js → chunk-GN4YEXT7.js} +2 -2
  9. package/dist/chunk-GN4YEXT7.js.map +1 -0
  10. package/dist/chunk-O2AVDJCQ.js +335 -0
  11. package/dist/chunk-O2AVDJCQ.js.map +1 -0
  12. package/dist/chunk-OTVTKAN6.js +451 -0
  13. package/dist/chunk-OTVTKAN6.js.map +1 -0
  14. package/dist/chunk-WUL63FR6.js +335 -0
  15. package/dist/chunk-WUL63FR6.js.map +1 -0
  16. package/dist/{chunk-H6KTH6W6.js → chunk-YCLZWES2.js} +2 -2
  17. package/dist/client-e13979ac.d.ts +52 -0
  18. package/dist/codec/index.js +20 -2
  19. package/dist/codec/index.js.map +1 -1
  20. package/dist/{connection-8debd45f.d.ts → connection-5d0978ce.d.ts} +1 -1
  21. package/dist/{connection-581558f8.d.ts → connection-e57e98ea.d.ts} +1 -1
  22. package/dist/{transport-47af1c81.d.ts → handshake-5665ffd3.d.ts} +101 -153
  23. package/dist/{index-60f03cb7.d.ts → index-ea74cdbb.d.ts} +1 -1
  24. package/dist/logging/index.d.cts +1 -1
  25. package/dist/logging/index.d.ts +1 -1
  26. package/dist/router/index.cjs +16 -1
  27. package/dist/router/index.cjs.map +1 -1
  28. package/dist/router/index.d.cts +8 -6
  29. package/dist/router/index.d.ts +8 -6
  30. package/dist/router/index.js +2 -2
  31. package/dist/server-1cfc88d1.d.ts +24 -0
  32. package/dist/{services-ca72c9f8.d.ts → services-86c4d10d.d.ts} +3 -2
  33. package/dist/transport/impls/uds/client.cjs +303 -180
  34. package/dist/transport/impls/uds/client.cjs.map +1 -1
  35. package/dist/transport/impls/uds/client.d.cts +6 -5
  36. package/dist/transport/impls/uds/client.d.ts +6 -5
  37. package/dist/transport/impls/uds/client.js +6 -4
  38. package/dist/transport/impls/uds/client.js.map +1 -1
  39. package/dist/transport/impls/uds/server.cjs +396 -234
  40. package/dist/transport/impls/uds/server.cjs.map +1 -1
  41. package/dist/transport/impls/uds/server.d.cts +6 -5
  42. package/dist/transport/impls/uds/server.d.ts +6 -5
  43. package/dist/transport/impls/uds/server.js +8 -6
  44. package/dist/transport/impls/uds/server.js.map +1 -1
  45. package/dist/transport/impls/ws/client.cjs +305 -182
  46. package/dist/transport/impls/ws/client.cjs.map +1 -1
  47. package/dist/transport/impls/ws/client.d.cts +6 -5
  48. package/dist/transport/impls/ws/client.d.ts +6 -5
  49. package/dist/transport/impls/ws/client.js +6 -4
  50. package/dist/transport/impls/ws/client.js.map +1 -1
  51. package/dist/transport/impls/ws/server.cjs +350 -188
  52. package/dist/transport/impls/ws/server.cjs.map +1 -1
  53. package/dist/transport/impls/ws/server.d.cts +4 -3
  54. package/dist/transport/impls/ws/server.d.ts +4 -3
  55. package/dist/transport/impls/ws/server.js +8 -6
  56. package/dist/transport/impls/ws/server.js.map +1 -1
  57. package/dist/transport/index.cjs +338 -142
  58. package/dist/transport/index.cjs.map +1 -1
  59. package/dist/transport/index.d.cts +4 -2
  60. package/dist/transport/index.d.ts +4 -2
  61. package/dist/transport/index.js +14 -8
  62. package/dist/util/testHelpers.cjs +10 -6
  63. package/dist/util/testHelpers.cjs.map +1 -1
  64. package/dist/util/testHelpers.d.cts +5 -4
  65. package/dist/util/testHelpers.d.ts +5 -4
  66. package/dist/util/testHelpers.js +4 -5
  67. package/dist/util/testHelpers.js.map +1 -1
  68. package/package.json +13 -14
  69. package/dist/chunk-3AW3IXVD.js.map +0 -1
  70. package/dist/chunk-7RUKEUKE.js.map +0 -1
  71. package/dist/chunk-VRU4IKRT.js +0 -1392
  72. package/dist/chunk-VRU4IKRT.js.map +0 -1
  73. package/dist/chunk-XZ6IOBM5.js.map +0 -1
  74. /package/dist/{chunk-HDBVL7EF.js.map → chunk-BEALFLCB.js.map} +0 -0
  75. /package/dist/{chunk-H6KTH6W6.js.map → chunk-YCLZWES2.js.map} +0 -0
@@ -60,6 +60,21 @@ var ControlMessageHandshakeRequestSchema = import_typebox.Type.Object({
60
60
  type: import_typebox.Type.Literal("HANDSHAKE_REQ"),
61
61
  protocolVersion: import_typebox.Type.String(),
62
62
  sessionId: import_typebox.Type.String(),
63
+ /**
64
+ * Specifies what the server's expected session state (from the pov of the client). This can be
65
+ * used by the server to know whether this is a new or a reestablished connection, and whether it
66
+ * is compatible with what it already has.
67
+ */
68
+ expectedSessionState: import_typebox.Type.Optional(
69
+ import_typebox.Type.Object({
70
+ /**
71
+ * reconnect is set to true if the client explicitly wants to reestablish an existing
72
+ * connection.
73
+ */
74
+ reconnect: import_typebox.Type.Boolean(),
75
+ nextExpectedSeq: import_typebox.Type.Integer()
76
+ })
77
+ ),
63
78
  metadata: import_typebox.Type.Optional(import_typebox.Type.Unknown())
64
79
  });
65
80
  var ControlMessageHandshakeResponseSchema = import_typebox.Type.Object({
@@ -84,7 +99,14 @@ var ControlMessagePayloadSchema = import_typebox.Type.Union([
84
99
  var OpaqueTransportMessageSchema = TransportMessageSchema(
85
100
  import_typebox.Type.Unknown()
86
101
  );
87
- function handshakeRequestMessage(from, to, sessionId, metadata, tracing) {
102
+ function handshakeRequestMessage({
103
+ from,
104
+ to,
105
+ sessionId,
106
+ expectedSessionState,
107
+ metadata,
108
+ tracing
109
+ }) {
88
110
  return {
89
111
  id: (0, import_nanoid.nanoid)(),
90
112
  from,
@@ -98,10 +120,12 @@ function handshakeRequestMessage(from, to, sessionId, metadata, tracing) {
98
120
  type: "HANDSHAKE_REQ",
99
121
  protocolVersion: PROTOCOL_VERSION,
100
122
  sessionId,
123
+ expectedSessionState,
101
124
  metadata
102
125
  }
103
126
  };
104
127
  }
128
+ var SESSION_STATE_MISMATCH = "session state mismatch";
105
129
  function isAck(controlFlag) {
106
130
  return (controlFlag & 1 /* AckBit */) === 1 /* AckBit */;
107
131
  }
@@ -110,7 +134,7 @@ function isAck(controlFlag) {
110
134
  var import_api = require("@opentelemetry/api");
111
135
 
112
136
  // package.json
113
- var version = "0.23.12";
137
+ var version = "0.23.14";
114
138
 
115
139
  // tracing/index.ts
116
140
  function getPropagationContext(ctx) {
@@ -424,9 +448,17 @@ var Session = class {
424
448
  get connected() {
425
449
  return this.connection !== void 0;
426
450
  }
451
+ get nextExpectedAck() {
452
+ return this.seq;
453
+ }
427
454
  get nextExpectedSeq() {
428
455
  return this.ack;
429
456
  }
457
+ // This is only used in tests to make the session misbehave.
458
+ /* @internal */
459
+ advanceAckForTesting(by) {
460
+ this.ack += by;
461
+ }
430
462
  constructMsg(partialMsg) {
431
463
  const msg = {
432
464
  ...partialMsg,
@@ -543,6 +575,154 @@ var UdsConnection = class extends Connection {
543
575
  }
544
576
  };
545
577
 
578
+ // transport/client.ts
579
+ var import_api4 = require("@opentelemetry/api");
580
+
581
+ // codec/json.ts
582
+ var encoder = new TextEncoder();
583
+ var decoder = new TextDecoder();
584
+ function uint8ArrayToBase64(uint8Array) {
585
+ let binary = "";
586
+ uint8Array.forEach((byte) => {
587
+ binary += String.fromCharCode(byte);
588
+ });
589
+ return btoa(binary);
590
+ }
591
+ function base64ToUint8Array(base64) {
592
+ const binaryString = atob(base64);
593
+ const uint8Array = new Uint8Array(binaryString.length);
594
+ for (let i = 0; i < binaryString.length; i++) {
595
+ uint8Array[i] = binaryString.charCodeAt(i);
596
+ }
597
+ return uint8Array;
598
+ }
599
+ var NaiveJsonCodec = {
600
+ toBuffer: (obj) => {
601
+ return encoder.encode(
602
+ JSON.stringify(obj, function replacer(key) {
603
+ const val = this[key];
604
+ if (val instanceof Uint8Array) {
605
+ return { $t: uint8ArrayToBase64(val) };
606
+ } else {
607
+ return val;
608
+ }
609
+ })
610
+ );
611
+ },
612
+ fromBuffer: (buff) => {
613
+ try {
614
+ const parsed = JSON.parse(
615
+ decoder.decode(buff),
616
+ function reviver(_key, val) {
617
+ if (val?.$t) {
618
+ return base64ToUint8Array(val.$t);
619
+ } else {
620
+ return val;
621
+ }
622
+ }
623
+ );
624
+ if (typeof parsed === "object")
625
+ return parsed;
626
+ return null;
627
+ } catch {
628
+ return null;
629
+ }
630
+ }
631
+ };
632
+
633
+ // transport/options.ts
634
+ var defaultTransportOptions = {
635
+ heartbeatIntervalMs: 1e3,
636
+ heartbeatsUntilDead: 2,
637
+ sessionDisconnectGraceMs: 5e3,
638
+ codec: NaiveJsonCodec
639
+ };
640
+ var defaultConnectionRetryOptions = {
641
+ baseIntervalMs: 250,
642
+ maxJitterMs: 200,
643
+ maxBackoffMs: 32e3,
644
+ attemptBudgetCapacity: 5,
645
+ budgetRestoreIntervalMs: 200
646
+ };
647
+ var defaultClientTransportOptions = {
648
+ ...defaultTransportOptions,
649
+ ...defaultConnectionRetryOptions
650
+ };
651
+ var defaultServerTransportOptions = {
652
+ ...defaultTransportOptions
653
+ };
654
+
655
+ // transport/rateLimit.ts
656
+ var LeakyBucketRateLimit = class {
657
+ budgetConsumed;
658
+ intervalHandles;
659
+ options;
660
+ constructor(options) {
661
+ this.options = options;
662
+ this.budgetConsumed = /* @__PURE__ */ new Map();
663
+ this.intervalHandles = /* @__PURE__ */ new Map();
664
+ }
665
+ getBackoffMs(user) {
666
+ if (!this.budgetConsumed.has(user))
667
+ return 0;
668
+ const exponent = Math.max(0, this.getBudgetConsumed(user) - 1);
669
+ const jitter = Math.floor(Math.random() * this.options.maxJitterMs);
670
+ const backoffMs = Math.min(
671
+ this.options.baseIntervalMs * 2 ** exponent,
672
+ this.options.maxBackoffMs
673
+ );
674
+ return backoffMs + jitter;
675
+ }
676
+ get totalBudgetRestoreTime() {
677
+ return this.options.budgetRestoreIntervalMs * this.options.attemptBudgetCapacity;
678
+ }
679
+ consumeBudget(user) {
680
+ this.stopLeak(user);
681
+ this.budgetConsumed.set(user, this.getBudgetConsumed(user) + 1);
682
+ }
683
+ getBudgetConsumed(user) {
684
+ return this.budgetConsumed.get(user) ?? 0;
685
+ }
686
+ hasBudget(user) {
687
+ return this.getBudgetConsumed(user) < this.options.attemptBudgetCapacity;
688
+ }
689
+ startRestoringBudget(user) {
690
+ if (this.intervalHandles.has(user)) {
691
+ return;
692
+ }
693
+ const restoreBudgetForUser = () => {
694
+ const currentBudget = this.budgetConsumed.get(user);
695
+ if (!currentBudget) {
696
+ this.stopLeak(user);
697
+ return;
698
+ }
699
+ const newBudget = currentBudget - 1;
700
+ if (newBudget === 0) {
701
+ this.budgetConsumed.delete(user);
702
+ return;
703
+ }
704
+ this.budgetConsumed.set(user, newBudget);
705
+ };
706
+ const intervalHandle = setInterval(
707
+ restoreBudgetForUser,
708
+ this.options.budgetRestoreIntervalMs
709
+ );
710
+ this.intervalHandles.set(user, intervalHandle);
711
+ }
712
+ stopLeak(user) {
713
+ if (!this.intervalHandles.has(user)) {
714
+ return;
715
+ }
716
+ clearInterval(this.intervalHandles.get(user));
717
+ this.intervalHandles.delete(user);
718
+ }
719
+ close() {
720
+ for (const user of this.intervalHandles.keys()) {
721
+ this.stopLeak(user);
722
+ }
723
+ }
724
+ };
725
+
546
726
  // transport/transport.ts
547
727
  var import_value = require("@sinclair/typebox/value");
548
728
 
@@ -636,159 +816,8 @@ var EventDispatcher = class {
636
816
  }
637
817
  };
638
818
 
639
- // util/stringify.ts
640
- function coerceErrorString(err) {
641
- if (err instanceof Error) {
642
- return err.message || "unknown reason";
643
- }
644
- return `[coerced to error] ${String(err)}`;
645
- }
646
-
647
- // transport/rateLimit.ts
648
- var LeakyBucketRateLimit = class {
649
- budgetConsumed;
650
- intervalHandles;
651
- options;
652
- constructor(options) {
653
- this.options = options;
654
- this.budgetConsumed = /* @__PURE__ */ new Map();
655
- this.intervalHandles = /* @__PURE__ */ new Map();
656
- }
657
- getBackoffMs(user) {
658
- if (!this.budgetConsumed.has(user))
659
- return 0;
660
- const exponent = Math.max(0, this.getBudgetConsumed(user) - 1);
661
- const jitter = Math.floor(Math.random() * this.options.maxJitterMs);
662
- const backoffMs = Math.min(
663
- this.options.baseIntervalMs * 2 ** exponent,
664
- this.options.maxBackoffMs
665
- );
666
- return backoffMs + jitter;
667
- }
668
- get totalBudgetRestoreTime() {
669
- return this.options.budgetRestoreIntervalMs * this.options.attemptBudgetCapacity;
670
- }
671
- consumeBudget(user) {
672
- this.stopLeak(user);
673
- this.budgetConsumed.set(user, this.getBudgetConsumed(user) + 1);
674
- }
675
- getBudgetConsumed(user) {
676
- return this.budgetConsumed.get(user) ?? 0;
677
- }
678
- hasBudget(user) {
679
- return this.getBudgetConsumed(user) < this.options.attemptBudgetCapacity;
680
- }
681
- startRestoringBudget(user) {
682
- if (this.intervalHandles.has(user)) {
683
- return;
684
- }
685
- const restoreBudgetForUser = () => {
686
- const currentBudget = this.budgetConsumed.get(user);
687
- if (!currentBudget) {
688
- this.stopLeak(user);
689
- return;
690
- }
691
- const newBudget = currentBudget - 1;
692
- if (newBudget === 0) {
693
- this.budgetConsumed.delete(user);
694
- return;
695
- }
696
- this.budgetConsumed.set(user, newBudget);
697
- };
698
- const intervalHandle = setInterval(
699
- restoreBudgetForUser,
700
- this.options.budgetRestoreIntervalMs
701
- );
702
- this.intervalHandles.set(user, intervalHandle);
703
- }
704
- stopLeak(user) {
705
- if (!this.intervalHandles.has(user)) {
706
- return;
707
- }
708
- clearInterval(this.intervalHandles.get(user));
709
- this.intervalHandles.delete(user);
710
- }
711
- close() {
712
- for (const user of this.intervalHandles.keys()) {
713
- this.stopLeak(user);
714
- }
715
- }
716
- };
717
-
718
- // codec/json.ts
719
- var encoder = new TextEncoder();
720
- var decoder = new TextDecoder();
721
- function uint8ArrayToBase64(uint8Array) {
722
- let binary = "";
723
- uint8Array.forEach((byte) => {
724
- binary += String.fromCharCode(byte);
725
- });
726
- return btoa(binary);
727
- }
728
- function base64ToUint8Array(base64) {
729
- const binaryString = atob(base64);
730
- const uint8Array = new Uint8Array(binaryString.length);
731
- for (let i = 0; i < binaryString.length; i++) {
732
- uint8Array[i] = binaryString.charCodeAt(i);
733
- }
734
- return uint8Array;
735
- }
736
- var NaiveJsonCodec = {
737
- toBuffer: (obj) => {
738
- return encoder.encode(
739
- JSON.stringify(obj, function replacer(key) {
740
- const val = this[key];
741
- if (val instanceof Uint8Array) {
742
- return { $t: uint8ArrayToBase64(val) };
743
- } else {
744
- return val;
745
- }
746
- })
747
- );
748
- },
749
- fromBuffer: (buff) => {
750
- try {
751
- const parsed = JSON.parse(
752
- decoder.decode(buff),
753
- function reviver(_key, val) {
754
- if (val?.$t) {
755
- return base64ToUint8Array(val.$t);
756
- } else {
757
- return val;
758
- }
759
- }
760
- );
761
- if (typeof parsed === "object")
762
- return parsed;
763
- return null;
764
- } catch {
765
- return null;
766
- }
767
- }
768
- };
769
-
770
819
  // transport/transport.ts
771
820
  var import_api3 = require("@opentelemetry/api");
772
- var defaultTransportOptions = {
773
- heartbeatIntervalMs: 1e3,
774
- heartbeatsUntilDead: 2,
775
- sessionDisconnectGraceMs: 5e3,
776
- codec: NaiveJsonCodec
777
- };
778
- var defaultConnectionRetryOptions = {
779
- baseIntervalMs: 250,
780
- maxJitterMs: 200,
781
- maxBackoffMs: 32e3,
782
- attemptBudgetCapacity: 5,
783
- budgetRestoreIntervalMs: 200
784
- };
785
- var defaultClientTransportOptions = {
786
- ...defaultTransportOptions,
787
- ...defaultConnectionRetryOptions
788
- };
789
- var defaultServerTransportOptions = {
790
- ...defaultTransportOptions
791
- };
792
821
  var Transport = class {
793
822
  /**
794
823
  * The status of the transport.
@@ -879,6 +908,49 @@ var Transport = class {
879
908
  });
880
909
  return session;
881
910
  }
911
+ createNewSession({
912
+ to,
913
+ conn,
914
+ sessionId,
915
+ propagationCtx
916
+ }) {
917
+ let session = this.sessions.get(to);
918
+ if (session !== void 0) {
919
+ this.log?.info(
920
+ `session for ${to} already exists, replacing it with a new session as requested`,
921
+ session.loggingMetadata
922
+ );
923
+ this.deleteSession({
924
+ session,
925
+ closeHandshakingConnection: false
926
+ });
927
+ session = void 0;
928
+ }
929
+ session = this.createSession(to, conn, propagationCtx);
930
+ session.advertisedSessionId = sessionId;
931
+ this.log?.info(`created new session for ${to}`, session.loggingMetadata);
932
+ return session;
933
+ }
934
+ getExistingSession({
935
+ to,
936
+ sessionId,
937
+ nextExpectedSeq
938
+ }) {
939
+ const session = this.sessions.get(to);
940
+ if (
941
+ // reject this request if there was no previous session to replace
942
+ session === void 0 || // or if both parties do not agree about the next expected sequence number
943
+ session.nextExpectedAck < nextExpectedSeq || // or if both parties do not agree on the advertised session id
944
+ session.advertisedSessionId !== sessionId
945
+ ) {
946
+ return false;
947
+ }
948
+ this.log?.info(
949
+ `reused existing session for ${to}`,
950
+ session.loggingMetadata
951
+ );
952
+ return session;
953
+ }
882
954
  getOrCreateSession({
883
955
  to,
884
956
  conn,
@@ -943,6 +1015,16 @@ var Transport = class {
943
1015
  * @param connectedTo The peer we are connected to.
944
1016
  */
945
1017
  onDisconnect(conn, session) {
1018
+ if (session.connection !== void 0 && session.connection.id !== conn.id) {
1019
+ session.telemetry.span.addEvent("onDisconnect race");
1020
+ this.log?.warn("onDisconnect race", {
1021
+ clientId: this.clientId,
1022
+ ...session.loggingMetadata,
1023
+ ...conn.loggingMetadata,
1024
+ tags: ["invariant-violation"]
1025
+ });
1026
+ return;
1027
+ }
946
1028
  conn.telemetry?.span.end();
947
1029
  this.eventDispatcher.dispatchEvent("connectionStatus", {
948
1030
  status: "disconnect",
@@ -950,6 +1032,16 @@ var Transport = class {
950
1032
  });
951
1033
  session.connection = void 0;
952
1034
  session.beginGrace(() => {
1035
+ if (session.connection !== void 0) {
1036
+ session.telemetry.span.addEvent("session grace period race");
1037
+ this.log?.warn("session grace period race", {
1038
+ clientId: this.clientId,
1039
+ ...session.loggingMetadata,
1040
+ ...conn.loggingMetadata,
1041
+ tags: ["invariant-violation"]
1042
+ });
1043
+ return;
1044
+ }
953
1045
  session.telemetry.span.addEvent("session grace period expired");
954
1046
  this.deleteSession({
955
1047
  session,
@@ -1117,6 +1209,17 @@ var Transport = class {
1117
1209
  return this.status;
1118
1210
  }
1119
1211
  };
1212
+
1213
+ // util/stringify.ts
1214
+ function coerceErrorString(err) {
1215
+ if (err instanceof Error) {
1216
+ return err.message || "unknown reason";
1217
+ }
1218
+ return `[coerced to error] ${String(err)}`;
1219
+ }
1220
+
1221
+ // transport/client.ts
1222
+ var import_value2 = require("@sinclair/typebox/value");
1120
1223
  var ClientTransport = class extends Transport {
1121
1224
  /**
1122
1225
  * The options for this transport.
@@ -1177,7 +1280,7 @@ var ClientTransport = class extends Transport {
1177
1280
  const parsed = this.parseMsg(data2, conn);
1178
1281
  if (!parsed) {
1179
1282
  conn.telemetry?.span.setStatus({
1180
- code: import_api3.SpanStatusCode.ERROR,
1283
+ code: import_api4.SpanStatusCode.ERROR,
1181
1284
  message: "message parse failure"
1182
1285
  });
1183
1286
  conn.close();
@@ -1208,7 +1311,7 @@ var ClientTransport = class extends Transport {
1208
1311
  });
1209
1312
  conn.addErrorListener((err) => {
1210
1313
  conn.telemetry?.span.setStatus({
1211
- code: import_api3.SpanStatusCode.ERROR,
1314
+ code: import_api4.SpanStatusCode.ERROR,
1212
1315
  message: "connection error"
1213
1316
  });
1214
1317
  this.log?.warn(
@@ -1226,7 +1329,7 @@ var ClientTransport = class extends Transport {
1226
1329
  const parsed = this.parseMsg(data, conn);
1227
1330
  if (!parsed) {
1228
1331
  conn.telemetry?.span.setStatus({
1229
- code: import_api3.SpanStatusCode.ERROR,
1332
+ code: import_api4.SpanStatusCode.ERROR,
1230
1333
  message: "non-transport message"
1231
1334
  });
1232
1335
  this.protocolError(
@@ -1235,9 +1338,9 @@ var ClientTransport = class extends Transport {
1235
1338
  );
1236
1339
  return false;
1237
1340
  }
1238
- if (!import_value.Value.Check(ControlMessageHandshakeResponseSchema, parsed.payload)) {
1341
+ if (!import_value2.Value.Check(ControlMessageHandshakeResponseSchema, parsed.payload)) {
1239
1342
  conn.telemetry?.span.setStatus({
1240
- code: import_api3.SpanStatusCode.ERROR,
1343
+ code: import_api4.SpanStatusCode.ERROR,
1241
1344
  message: "invalid handshake response"
1242
1345
  });
1243
1346
  this.log?.warn(`received invalid handshake resp`, {
@@ -1246,7 +1349,7 @@ var ClientTransport = class extends Transport {
1246
1349
  connectedTo: parsed.from,
1247
1350
  transportMessage: parsed,
1248
1351
  validationErrors: [
1249
- ...import_value.Value.Errors(
1352
+ ...import_value2.Value.Errors(
1250
1353
  ControlMessageHandshakeResponseSchema,
1251
1354
  parsed.payload
1252
1355
  )
@@ -1258,31 +1361,47 @@ var ClientTransport = class extends Transport {
1258
1361
  );
1259
1362
  return false;
1260
1363
  }
1364
+ const previousSession = this.sessions.get(parsed.from);
1261
1365
  if (!parsed.payload.status.ok) {
1262
- conn.telemetry?.span.setStatus({
1263
- code: import_api3.SpanStatusCode.ERROR,
1264
- message: "handshake rejected"
1265
- });
1266
- this.log?.warn(`received handshake rejection`, {
1267
- ...conn.loggingMetadata,
1268
- clientId: this.clientId,
1269
- connectedTo: parsed.from,
1270
- transportMessage: parsed
1271
- });
1366
+ if (parsed.payload.status.reason === SESSION_STATE_MISMATCH) {
1367
+ if (previousSession) {
1368
+ this.deleteSession({
1369
+ session: previousSession,
1370
+ closeHandshakingConnection: true
1371
+ });
1372
+ }
1373
+ conn.telemetry?.span.setStatus({
1374
+ code: import_api4.SpanStatusCode.ERROR,
1375
+ message: parsed.payload.status.reason
1376
+ });
1377
+ } else {
1378
+ conn.telemetry?.span.setStatus({
1379
+ code: import_api4.SpanStatusCode.ERROR,
1380
+ message: "handshake rejected"
1381
+ });
1382
+ }
1383
+ this.log?.warn(
1384
+ `received handshake rejection: ${parsed.payload.status.reason}`,
1385
+ {
1386
+ ...conn.loggingMetadata,
1387
+ clientId: this.clientId,
1388
+ connectedTo: parsed.from,
1389
+ transportMessage: parsed
1390
+ }
1391
+ );
1272
1392
  this.protocolError(
1273
1393
  ProtocolError.HandshakeFailed,
1274
1394
  parsed.payload.status.reason
1275
1395
  );
1276
1396
  return false;
1277
1397
  }
1278
- const previousSession = this.sessions.get(parsed.from);
1279
1398
  if (previousSession?.advertisedSessionId && previousSession.advertisedSessionId !== parsed.payload.status.sessionId) {
1280
1399
  this.deleteSession({
1281
1400
  session: previousSession,
1282
1401
  closeHandshakingConnection: true
1283
1402
  });
1284
1403
  conn.telemetry?.span.setStatus({
1285
- code: import_api3.SpanStatusCode.ERROR,
1404
+ code: import_api4.SpanStatusCode.ERROR,
1286
1405
  message: "session id mismatch"
1287
1406
  });
1288
1407
  this.log?.warn(`handshake from ${parsed.from} session id mismatch`, {
@@ -1382,7 +1501,7 @@ var ClientTransport = class extends Transport {
1382
1501
  } catch (err) {
1383
1502
  const errStr = coerceErrorString(err);
1384
1503
  span.recordException(errStr);
1385
- span.setStatus({ code: import_api3.SpanStatusCode.ERROR });
1504
+ span.setStatus({ code: import_api4.SpanStatusCode.ERROR });
1386
1505
  throw err;
1387
1506
  } finally {
1388
1507
  span.end();
@@ -1433,13 +1552,13 @@ var ClientTransport = class extends Transport {
1433
1552
  let metadata = void 0;
1434
1553
  if (this.handshakeExtensions) {
1435
1554
  metadata = await this.handshakeExtensions.construct();
1436
- if (!import_value.Value.Check(this.handshakeExtensions.schema, metadata)) {
1555
+ if (!import_value2.Value.Check(this.handshakeExtensions.schema, metadata)) {
1437
1556
  this.log?.error(`constructed handshake metadata did not match schema`, {
1438
1557
  ...conn.loggingMetadata,
1439
1558
  clientId: this.clientId,
1440
1559
  connectedTo: to,
1441
1560
  validationErrors: [
1442
- ...import_value.Value.Errors(this.handshakeExtensions.schema, metadata)
1561
+ ...import_value2.Value.Errors(this.handshakeExtensions.schema, metadata)
1443
1562
  ],
1444
1563
  tags: ["invariant-violation"]
1445
1564
  });
@@ -1448,20 +1567,24 @@ var ClientTransport = class extends Transport {
1448
1567
  "handshake metadata did not match schema"
1449
1568
  );
1450
1569
  conn.telemetry?.span.setStatus({
1451
- code: import_api3.SpanStatusCode.ERROR,
1570
+ code: import_api4.SpanStatusCode.ERROR,
1452
1571
  message: "handshake meta mismatch"
1453
1572
  });
1454
1573
  return false;
1455
1574
  }
1456
1575
  }
1457
1576
  const { session } = this.getOrCreateSession({ to, handshakingConn: conn });
1458
- const requestMsg = handshakeRequestMessage(
1459
- this.clientId,
1577
+ const requestMsg = handshakeRequestMessage({
1578
+ from: this.clientId,
1460
1579
  to,
1461
- session.id,
1580
+ sessionId: session.id,
1581
+ expectedSessionState: {
1582
+ reconnect: session.advertisedSessionId !== void 0,
1583
+ nextExpectedSeq: session.nextExpectedSeq
1584
+ },
1462
1585
  metadata,
1463
- getPropagationContext(session.telemetry.ctx)
1464
- );
1586
+ tracing: getPropagationContext(session.telemetry.ctx)
1587
+ });
1465
1588
  this.log?.debug(`sending handshake request to ${to}`, {
1466
1589
  ...conn.loggingMetadata,
1467
1590
  clientId: this.clientId,