@replit/river 0.25.1 → 0.25.2

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 (50) hide show
  1. package/dist/{chunk-SZ5NBBX7.js → chunk-EHD2JJBW.js} +2 -2
  2. package/dist/{chunk-SZ5NBBX7.js.map → chunk-EHD2JJBW.js.map} +1 -1
  3. package/dist/{chunk-SGSRNAWJ.js → chunk-GDHQCPWW.js} +2 -2
  4. package/dist/{chunk-5CNNIOAO.js → chunk-ONIPHO7J.js} +102 -95
  5. package/dist/chunk-ONIPHO7J.js.map +1 -0
  6. package/dist/{chunk-D5O3ERJU.js → chunk-PF74DCPQ.js} +3 -3
  7. package/dist/chunk-PF74DCPQ.js.map +1 -0
  8. package/dist/{chunk-YM5Y4NAT.js → chunk-Q3PZBJXR.js} +199 -117
  9. package/dist/chunk-Q3PZBJXR.js.map +1 -0
  10. package/dist/{chunk-PCBPPTXH.js → chunk-QXMZJ7LF.js} +17 -26
  11. package/dist/chunk-QXMZJ7LF.js.map +1 -0
  12. package/dist/{chunk-MBMEJIPU.js → chunk-ZWMWRM23.js} +2 -2
  13. package/dist/{client-1321630c.d.ts → client-edc8e2de.d.ts} +3 -1
  14. package/dist/{connection-bd907ca6.d.ts → connection-ef50ac3a.d.ts} +1 -1
  15. package/dist/{handshake-3772d7ca.d.ts → handshake-12d57161.d.ts} +131 -83
  16. package/dist/router/index.cjs +1 -1
  17. package/dist/router/index.cjs.map +1 -1
  18. package/dist/router/index.d.cts +7 -7
  19. package/dist/router/index.d.ts +7 -7
  20. package/dist/router/index.js +2 -2
  21. package/dist/{server-f0fd2b98.d.ts → server-f8228636.d.ts} +8 -3
  22. package/dist/{services-8d14ae16.d.ts → services-4b9e5232.d.ts} +2 -2
  23. package/dist/transport/impls/ws/client.cjs +291 -205
  24. package/dist/transport/impls/ws/client.cjs.map +1 -1
  25. package/dist/transport/impls/ws/client.d.cts +3 -3
  26. package/dist/transport/impls/ws/client.d.ts +3 -3
  27. package/dist/transport/impls/ws/client.js +5 -5
  28. package/dist/transport/impls/ws/server.cjs +206 -136
  29. package/dist/transport/impls/ws/server.cjs.map +1 -1
  30. package/dist/transport/impls/ws/server.d.cts +3 -3
  31. package/dist/transport/impls/ws/server.d.ts +3 -3
  32. package/dist/transport/impls/ws/server.js +5 -5
  33. package/dist/transport/index.cjs +304 -226
  34. package/dist/transport/index.cjs.map +1 -1
  35. package/dist/transport/index.d.cts +3 -3
  36. package/dist/transport/index.d.ts +3 -3
  37. package/dist/transport/index.js +5 -5
  38. package/dist/util/testHelpers.cjs +197 -115
  39. package/dist/util/testHelpers.cjs.map +1 -1
  40. package/dist/util/testHelpers.d.cts +5 -4
  41. package/dist/util/testHelpers.d.ts +5 -4
  42. package/dist/util/testHelpers.js +6 -3
  43. package/dist/util/testHelpers.js.map +1 -1
  44. package/package.json +14 -13
  45. package/dist/chunk-5CNNIOAO.js.map +0 -1
  46. package/dist/chunk-D5O3ERJU.js.map +0 -1
  47. package/dist/chunk-PCBPPTXH.js.map +0 -1
  48. package/dist/chunk-YM5Y4NAT.js.map +0 -1
  49. /package/dist/{chunk-SGSRNAWJ.js.map → chunk-GDHQCPWW.js.map} +0 -0
  50. /package/dist/{chunk-MBMEJIPU.js.map → chunk-ZWMWRM23.js.map} +0 -0
@@ -212,7 +212,7 @@ var defaultTransportOptions = {
212
212
  codec: NaiveJsonCodec
213
213
  };
214
214
  var defaultConnectionRetryOptions = {
215
- baseIntervalMs: 250,
215
+ baseIntervalMs: 150,
216
216
  maxJitterMs: 200,
217
217
  maxBackoffMs: 32e3,
218
218
  attemptBudgetCapacity: 5,
@@ -229,17 +229,17 @@ var defaultServerTransportOptions = {
229
229
  // transport/rateLimit.ts
230
230
  var LeakyBucketRateLimit = class {
231
231
  budgetConsumed;
232
- intervalHandles;
232
+ intervalHandle;
233
233
  options;
234
234
  constructor(options) {
235
235
  this.options = options;
236
- this.budgetConsumed = /* @__PURE__ */ new Map();
237
- this.intervalHandles = /* @__PURE__ */ new Map();
236
+ this.budgetConsumed = 0;
238
237
  }
239
- getBackoffMs(user) {
240
- if (!this.budgetConsumed.has(user))
238
+ getBackoffMs() {
239
+ if (this.getBudgetConsumed() === 0) {
241
240
  return 0;
242
- const exponent = Math.max(0, this.getBudgetConsumed(user) - 1);
241
+ }
242
+ const exponent = Math.max(0, this.getBudgetConsumed() - 1);
243
243
  const jitter = Math.floor(Math.random() * this.options.maxJitterMs);
244
244
  const backoffMs = Math.min(
245
245
  this.options.baseIntervalMs * 2 ** exponent,
@@ -250,50 +250,46 @@ var LeakyBucketRateLimit = class {
250
250
  get totalBudgetRestoreTime() {
251
251
  return this.options.budgetRestoreIntervalMs * this.options.attemptBudgetCapacity;
252
252
  }
253
- consumeBudget(user) {
254
- this.stopLeak(user);
255
- this.budgetConsumed.set(user, this.getBudgetConsumed(user) + 1);
253
+ consumeBudget() {
254
+ this.stopLeak();
255
+ this.budgetConsumed = this.getBudgetConsumed() + 1;
256
256
  }
257
- getBudgetConsumed(user) {
258
- return this.budgetConsumed.get(user) ?? 0;
257
+ getBudgetConsumed() {
258
+ return this.budgetConsumed;
259
259
  }
260
- hasBudget(user) {
261
- return this.getBudgetConsumed(user) < this.options.attemptBudgetCapacity;
260
+ hasBudget() {
261
+ return this.getBudgetConsumed() < this.options.attemptBudgetCapacity;
262
262
  }
263
- startRestoringBudget(user) {
264
- if (this.intervalHandles.has(user)) {
263
+ startRestoringBudget() {
264
+ if (this.intervalHandle) {
265
265
  return;
266
266
  }
267
267
  const restoreBudgetForUser = () => {
268
- const currentBudget = this.budgetConsumed.get(user);
268
+ const currentBudget = this.budgetConsumed;
269
269
  if (!currentBudget) {
270
- this.stopLeak(user);
270
+ this.stopLeak();
271
271
  return;
272
272
  }
273
273
  const newBudget = currentBudget - 1;
274
274
  if (newBudget === 0) {
275
- this.budgetConsumed.delete(user);
276
275
  return;
277
276
  }
278
- this.budgetConsumed.set(user, newBudget);
277
+ this.budgetConsumed = newBudget;
279
278
  };
280
- const intervalHandle = setInterval(
279
+ this.intervalHandle = setInterval(
281
280
  restoreBudgetForUser,
282
281
  this.options.budgetRestoreIntervalMs
283
282
  );
284
- this.intervalHandles.set(user, intervalHandle);
285
283
  }
286
- stopLeak(user) {
287
- if (!this.intervalHandles.has(user)) {
284
+ stopLeak() {
285
+ if (!this.intervalHandle) {
288
286
  return;
289
287
  }
290
- clearInterval(this.intervalHandles.get(user));
291
- this.intervalHandles.delete(user);
288
+ clearInterval(this.intervalHandle);
289
+ this.intervalHandle = void 0;
292
290
  }
293
291
  close() {
294
- for (const user of this.intervalHandles.keys()) {
295
- this.stopLeak(user);
296
- }
292
+ this.stopLeak();
297
293
  }
298
294
  };
299
295
 
@@ -440,7 +436,7 @@ var CommonSession = class extends StateMachineState {
440
436
  from;
441
437
  options;
442
438
  log;
443
- constructor(from, options, log) {
439
+ constructor({ from, options, log }) {
444
440
  super();
445
441
  this.from = from;
446
442
  this.options = options;
@@ -481,8 +477,9 @@ var IdentifiedSession = class extends CommonSession {
481
477
  */
482
478
  ack;
483
479
  sendBuffer;
484
- constructor(id, from, to, seq, ack, sendBuffer, telemetry, options, log) {
485
- super(from, options, log);
480
+ constructor(props) {
481
+ const { id, to, seq, ack, sendBuffer, telemetry, log } = props;
482
+ super(props);
486
483
  this.id = id;
487
484
  this.to = to;
488
485
  this.seq = seq;
@@ -537,23 +534,23 @@ var SessionConnecting = class extends IdentifiedSession {
537
534
  connPromise;
538
535
  listeners;
539
536
  connectionTimeout;
540
- constructor(connPromise, listeners, ...args) {
541
- super(...args);
542
- this.connPromise = connPromise;
543
- this.listeners = listeners;
537
+ constructor(props) {
538
+ super(props);
539
+ this.connPromise = props.connPromise;
540
+ this.listeners = props.listeners;
544
541
  this.connectionTimeout = setTimeout(() => {
545
- listeners.onConnectionTimeout();
542
+ this.listeners.onConnectionTimeout();
546
543
  }, this.options.connectionTimeoutMs);
547
- connPromise.then(
544
+ this.connPromise.then(
548
545
  (conn) => {
549
546
  if (this._isConsumed)
550
547
  return;
551
- listeners.onConnectionEstablished(conn);
548
+ this.listeners.onConnectionEstablished(conn);
552
549
  },
553
550
  (err) => {
554
551
  if (this._isConsumed)
555
552
  return;
556
- listeners.onConnectionFailed(err);
553
+ this.listeners.onConnectionFailed(err);
557
554
  }
558
555
  );
559
556
  }
@@ -579,9 +576,9 @@ var SessionNoConnection = class extends IdentifiedSession {
579
576
  state = "NoConnection" /* NoConnection */;
580
577
  listeners;
581
578
  gracePeriodTimeout;
582
- constructor(listeners, ...args) {
583
- super(...args);
584
- this.listeners = listeners;
579
+ constructor(props) {
580
+ super(props);
581
+ this.listeners = props.listeners;
585
582
  this.gracePeriodTimeout = setTimeout(() => {
586
583
  this.listeners.onSessionGracePeriodElapsed();
587
584
  }, this.options.sessionDisconnectGraceMs);
@@ -602,7 +599,7 @@ var SessionNoConnection = class extends IdentifiedSession {
602
599
  var import_api = require("@opentelemetry/api");
603
600
 
604
601
  // package.json
605
- var version = "0.25.1";
602
+ var version = "0.25.2";
606
603
 
607
604
  // tracing/index.ts
608
605
  function getPropagationContext(ctx) {
@@ -639,16 +636,16 @@ var SessionWaitingForHandshake = class extends CommonSession {
639
636
  conn;
640
637
  listeners;
641
638
  handshakeTimeout;
642
- constructor(conn, listeners, ...args) {
643
- super(...args);
644
- this.conn = conn;
645
- this.listeners = listeners;
639
+ constructor(props) {
640
+ super(props);
641
+ this.conn = props.conn;
642
+ this.listeners = props.listeners;
646
643
  this.handshakeTimeout = setTimeout(() => {
647
- listeners.onHandshakeTimeout();
644
+ this.listeners.onHandshakeTimeout();
648
645
  }, this.options.handshakeTimeoutMs);
649
646
  this.conn.addDataListener(this.onHandshakeData);
650
- this.conn.addErrorListener(listeners.onConnectionErrored);
651
- this.conn.addCloseListener(listeners.onConnectionClosed);
647
+ this.conn.addErrorListener(this.listeners.onConnectionErrored);
648
+ this.conn.addCloseListener(this.listeners.onConnectionClosed);
652
649
  }
653
650
  onHandshakeData = (msg) => {
654
651
  const parsedMsg = this.parseMsg(msg);
@@ -685,16 +682,16 @@ var SessionHandshaking = class extends IdentifiedSession {
685
682
  conn;
686
683
  listeners;
687
684
  handshakeTimeout;
688
- constructor(conn, listeners, ...args) {
689
- super(...args);
690
- this.conn = conn;
691
- this.listeners = listeners;
685
+ constructor(props) {
686
+ super(props);
687
+ this.conn = props.conn;
688
+ this.listeners = props.listeners;
692
689
  this.handshakeTimeout = setTimeout(() => {
693
- listeners.onHandshakeTimeout();
690
+ this.listeners.onHandshakeTimeout();
694
691
  }, this.options.handshakeTimeoutMs);
695
692
  this.conn.addDataListener(this.onHandshakeData);
696
- this.conn.addErrorListener(listeners.onConnectionErrored);
697
- this.conn.addCloseListener(listeners.onConnectionClosed);
693
+ this.conn.addErrorListener(this.listeners.onConnectionErrored);
694
+ this.conn.addCloseListener(this.listeners.onConnectionClosed);
698
695
  }
699
696
  onHandshakeData = (msg) => {
700
697
  const parsedMsg = this.parseMsg(msg);
@@ -726,16 +723,13 @@ var SessionConnected = class extends IdentifiedSession {
726
723
  state = "Connected" /* Connected */;
727
724
  conn;
728
725
  listeners;
729
- activeHeartbeatHandle;
730
- activeHeartbeatMisses = 0;
731
- passiveHeartbeatHandle;
732
- get isActivelyHeartbeating() {
733
- return this.activeHeartbeatHandle !== void 0;
734
- }
726
+ heartbeatHandle;
727
+ heartbeatMisses = 0;
728
+ isActivelyHeartbeating;
735
729
  updateBookkeeping(ack, seq) {
736
730
  this.sendBuffer = this.sendBuffer.filter((unacked) => unacked.seq >= ack);
737
731
  this.ack = seq + 1;
738
- this.activeHeartbeatMisses = 0;
732
+ this.heartbeatMisses = 0;
739
733
  }
740
734
  send(msg) {
741
735
  const constructedMsg = this.constructMsg(msg);
@@ -743,13 +737,13 @@ var SessionConnected = class extends IdentifiedSession {
743
737
  this.conn.send(this.options.codec.toBuffer(constructedMsg));
744
738
  return constructedMsg.id;
745
739
  }
746
- constructor(conn, listeners, ...args) {
747
- super(...args);
748
- this.conn = conn;
749
- this.listeners = listeners;
740
+ constructor(props) {
741
+ super(props);
742
+ this.conn = props.conn;
743
+ this.listeners = props.listeners;
750
744
  this.conn.addDataListener(this.onMessageData);
751
- this.conn.addCloseListener(listeners.onConnectionClosed);
752
- this.conn.addErrorListener(listeners.onConnectionErrored);
745
+ this.conn.addCloseListener(this.listeners.onConnectionClosed);
746
+ this.conn.addErrorListener(this.listeners.onConnectionErrored);
753
747
  if (this.sendBuffer.length > 0) {
754
748
  this.log?.debug(
755
749
  `sending ${this.sendBuffer.length} buffered messages`,
@@ -757,12 +751,11 @@ var SessionConnected = class extends IdentifiedSession {
757
751
  );
758
752
  }
759
753
  for (const msg of this.sendBuffer) {
760
- conn.send(this.options.codec.toBuffer(msg));
754
+ this.conn.send(this.options.codec.toBuffer(msg));
761
755
  }
762
- }
763
- startActiveHeartbeat() {
764
- this.activeHeartbeatHandle = setInterval(() => {
765
- const misses = this.activeHeartbeatMisses;
756
+ this.isActivelyHeartbeating = false;
757
+ this.heartbeatHandle = setInterval(() => {
758
+ const misses = this.heartbeatMisses;
766
759
  const missDuration = misses * this.options.heartbeatIntervalMs;
767
760
  if (misses >= this.options.heartbeatsUntilDead) {
768
761
  this.log?.info(
@@ -771,29 +764,18 @@ var SessionConnected = class extends IdentifiedSession {
771
764
  );
772
765
  this.telemetry.span.addEvent("closing connection due to inactivity");
773
766
  this.conn.close();
774
- clearInterval(this.activeHeartbeatHandle);
775
- this.activeHeartbeatHandle = void 0;
767
+ clearInterval(this.heartbeatHandle);
768
+ this.heartbeatHandle = void 0;
776
769
  return;
777
770
  }
778
- this.sendHeartbeat();
779
- this.activeHeartbeatMisses++;
771
+ if (this.isActivelyHeartbeating) {
772
+ this.sendHeartbeat();
773
+ }
774
+ this.heartbeatMisses++;
780
775
  }, this.options.heartbeatIntervalMs);
781
776
  }
782
- waitForNextHeartbeat() {
783
- const duration = this.options.heartbeatsUntilDead * this.options.heartbeatIntervalMs;
784
- if (this.passiveHeartbeatHandle) {
785
- clearTimeout(this.passiveHeartbeatHandle);
786
- this.passiveHeartbeatHandle = void 0;
787
- }
788
- this.passiveHeartbeatHandle = setTimeout(() => {
789
- this.log?.info(
790
- `closing connection to ${this.to} due to not receiving a heartbeat in the last ${duration}ms`,
791
- this.loggingMetadata
792
- );
793
- this.telemetry.span.addEvent("closing connection due to inactivity");
794
- this.conn.close();
795
- this.passiveHeartbeatHandle = void 0;
796
- }, duration);
777
+ startActiveHeartbeat() {
778
+ this.isActivelyHeartbeating = true;
797
779
  }
798
780
  sendHeartbeat() {
799
781
  this.log?.debug("sending heartbeat", this.loggingMetadata);
@@ -848,7 +830,6 @@ var SessionConnected = class extends IdentifiedSession {
848
830
  });
849
831
  if (!this.isActivelyHeartbeating) {
850
832
  this.sendHeartbeat();
851
- this.waitForNextHeartbeat();
852
833
  }
853
834
  };
854
835
  _handleStateExit() {
@@ -856,10 +837,8 @@ var SessionConnected = class extends IdentifiedSession {
856
837
  this.conn.removeDataListener(this.onMessageData);
857
838
  this.conn.removeCloseListener(this.listeners.onConnectionClosed);
858
839
  this.conn.removeErrorListener(this.listeners.onConnectionErrored);
859
- clearInterval(this.activeHeartbeatHandle);
860
- clearTimeout(this.passiveHeartbeatHandle);
861
- this.activeHeartbeatHandle = void 0;
862
- this.passiveHeartbeatHandle = void 0;
840
+ clearInterval(this.heartbeatHandle);
841
+ this.heartbeatHandle = void 0;
863
842
  }
864
843
  _handleClose() {
865
844
  super._handleClose();
@@ -867,52 +846,76 @@ var SessionConnected = class extends IdentifiedSession {
867
846
  }
868
847
  };
869
848
 
849
+ // transport/sessionStateMachine/SessionBackingOff.ts
850
+ var SessionBackingOff = class extends IdentifiedSession {
851
+ state = "BackingOff" /* BackingOff */;
852
+ listeners;
853
+ backoffTimeout;
854
+ constructor(props) {
855
+ super(props);
856
+ this.listeners = props.listeners;
857
+ this.backoffTimeout = setTimeout(() => {
858
+ this.listeners.onBackoffFinished();
859
+ }, props.backoffMs);
860
+ }
861
+ _handleClose() {
862
+ super._handleClose();
863
+ }
864
+ _handleStateExit() {
865
+ super._handleStateExit();
866
+ if (this.backoffTimeout) {
867
+ clearTimeout(this.backoffTimeout);
868
+ this.backoffTimeout = void 0;
869
+ }
870
+ }
871
+ };
872
+
870
873
  // transport/sessionStateMachine/transitions.ts
871
874
  function inheritSharedSession(session) {
872
- return [
873
- session.id,
874
- session.from,
875
- session.to,
876
- session.seq,
877
- session.ack,
878
- session.sendBuffer,
879
- session.telemetry,
880
- session.options,
881
- session.log
882
- ];
875
+ return {
876
+ id: session.id,
877
+ from: session.from,
878
+ to: session.to,
879
+ seq: session.seq,
880
+ ack: session.ack,
881
+ sendBuffer: session.sendBuffer,
882
+ telemetry: session.telemetry,
883
+ options: session.options,
884
+ log: session.log
885
+ };
883
886
  }
884
887
  var SessionStateGraph = {
885
888
  entrypoints: {
886
- NoConnection(to, from, listeners, options, log) {
889
+ NoConnection: (to, from, listeners, options, log) => {
887
890
  const id = `session-${generateId()}`;
888
891
  const telemetry = createSessionTelemetryInfo(id, to, from);
889
892
  const sendBuffer = [];
890
- const session = new SessionNoConnection(
893
+ const session = new SessionNoConnection({
891
894
  listeners,
892
895
  id,
893
896
  from,
894
897
  to,
895
- 0,
896
- 0,
898
+ seq: 0,
899
+ ack: 0,
897
900
  sendBuffer,
898
901
  telemetry,
899
902
  options,
900
903
  log
901
- );
904
+ });
902
905
  session.log?.info(`session ${session.id} created in NoConnection state`, {
903
906
  ...session.loggingMetadata,
904
907
  tags: ["state-transition"]
905
908
  });
906
909
  return session;
907
910
  },
908
- WaitingForHandshake(from, conn, listeners, options, log) {
909
- const session = new SessionWaitingForHandshake(
911
+ WaitingForHandshake: (from, conn, listeners, options, log) => {
912
+ const session = new SessionWaitingForHandshake({
910
913
  conn,
911
914
  listeners,
912
915
  from,
913
916
  options,
914
917
  log
915
- );
918
+ });
916
919
  session.log?.info(`session created in WaitingForHandshake state`, {
917
920
  ...session.loggingMetadata,
918
921
  tags: ["state-transition"]
@@ -924,16 +927,33 @@ var SessionStateGraph = {
924
927
  // After a session is transitioned, any usage of the old session will throw.
925
928
  transition: {
926
929
  // happy path transitions
927
- NoConnectionToConnecting(oldSession, connPromise, listeners) {
930
+ NoConnectionToBackingOff: (oldSession, backoffMs, listeners) => {
928
931
  const carriedState = inheritSharedSession(oldSession);
929
932
  oldSession._handleStateExit();
930
- const session = new SessionConnecting(
931
- connPromise,
933
+ const session = new SessionBackingOff({
934
+ backoffMs,
932
935
  listeners,
933
936
  ...carriedState
937
+ });
938
+ session.log?.info(
939
+ `session ${session.id} transition from NoConnection to BackingOff`,
940
+ {
941
+ ...session.loggingMetadata,
942
+ tags: ["state-transition"]
943
+ }
934
944
  );
945
+ return session;
946
+ },
947
+ BackingOffToConnecting: (oldSession, connPromise, listeners) => {
948
+ const carriedState = inheritSharedSession(oldSession);
949
+ oldSession._handleStateExit();
950
+ const session = new SessionConnecting({
951
+ connPromise,
952
+ listeners,
953
+ ...carriedState
954
+ });
935
955
  session.log?.info(
936
- `session ${session.id} transition from NoConnection to Connecting`,
956
+ `session ${session.id} transition from BackingOff to Connecting`,
937
957
  {
938
958
  ...session.loggingMetadata,
939
959
  tags: ["state-transition"]
@@ -941,10 +961,14 @@ var SessionStateGraph = {
941
961
  );
942
962
  return session;
943
963
  },
944
- ConnectingToHandshaking(oldSession, conn, listeners) {
964
+ ConnectingToHandshaking: (oldSession, conn, listeners) => {
945
965
  const carriedState = inheritSharedSession(oldSession);
946
966
  oldSession._handleStateExit();
947
- const session = new SessionHandshaking(conn, listeners, ...carriedState);
967
+ const session = new SessionHandshaking({
968
+ conn,
969
+ listeners,
970
+ ...carriedState
971
+ });
948
972
  session.log?.info(
949
973
  `session ${session.id} transition from Connecting to Handshaking`,
950
974
  {
@@ -954,11 +978,15 @@ var SessionStateGraph = {
954
978
  );
955
979
  return session;
956
980
  },
957
- HandshakingToConnected(oldSession, listeners) {
981
+ HandshakingToConnected: (oldSession, listeners) => {
958
982
  const carriedState = inheritSharedSession(oldSession);
959
983
  const conn = oldSession.conn;
960
984
  oldSession._handleStateExit();
961
- const session = new SessionConnected(conn, listeners, ...carriedState);
985
+ const session = new SessionConnected({
986
+ conn,
987
+ listeners,
988
+ ...carriedState
989
+ });
962
990
  session.log?.info(
963
991
  `session ${session.id} transition from Handshaking to Connected`,
964
992
  {
@@ -968,7 +996,7 @@ var SessionStateGraph = {
968
996
  );
969
997
  return session;
970
998
  },
971
- WaitingForHandshakeToConnected(pendingSession, oldSession, sessionId, to, propagationCtx, listeners) {
999
+ WaitingForHandshakeToConnected: (pendingSession, oldSession, sessionId, to, propagationCtx, listeners) => {
972
1000
  const conn = pendingSession.conn;
973
1001
  const { from, options } = pendingSession;
974
1002
  const carriedState = oldSession ? (
@@ -976,21 +1004,30 @@ var SessionStateGraph = {
976
1004
  inheritSharedSession(oldSession)
977
1005
  ) : (
978
1006
  // old session does not exist, create new state
979
- [
980
- sessionId,
1007
+ {
1008
+ id: sessionId,
981
1009
  from,
982
1010
  to,
983
- 0,
984
- 0,
985
- [],
986
- createSessionTelemetryInfo(sessionId, to, from, propagationCtx),
1011
+ seq: 0,
1012
+ ack: 0,
1013
+ sendBuffer: [],
1014
+ telemetry: createSessionTelemetryInfo(
1015
+ sessionId,
1016
+ to,
1017
+ from,
1018
+ propagationCtx
1019
+ ),
987
1020
  options,
988
- pendingSession.log
989
- ]
1021
+ log: pendingSession.log
1022
+ }
990
1023
  );
991
1024
  pendingSession._handleStateExit();
992
1025
  oldSession?._handleStateExit();
993
- const session = new SessionConnected(conn, listeners, ...carriedState);
1026
+ const session = new SessionConnected({
1027
+ conn,
1028
+ listeners,
1029
+ ...carriedState
1030
+ });
994
1031
  session.log?.info(
995
1032
  `session ${session.id} transition from WaitingForHandshake to Connected`,
996
1033
  {
@@ -1001,11 +1038,24 @@ var SessionStateGraph = {
1001
1038
  return session;
1002
1039
  },
1003
1040
  // disconnect paths
1004
- ConnectingToNoConnection(oldSession, listeners) {
1041
+ BackingOffToNoConnection: (oldSession, listeners) => {
1042
+ const carriedState = inheritSharedSession(oldSession);
1043
+ oldSession._handleStateExit();
1044
+ const session = new SessionNoConnection({ listeners, ...carriedState });
1045
+ session.log?.info(
1046
+ `session ${session.id} transition from BackingOff to NoConnection`,
1047
+ {
1048
+ ...session.loggingMetadata,
1049
+ tags: ["state-transition"]
1050
+ }
1051
+ );
1052
+ return session;
1053
+ },
1054
+ ConnectingToNoConnection: (oldSession, listeners) => {
1005
1055
  const carriedState = inheritSharedSession(oldSession);
1006
1056
  oldSession.bestEffortClose();
1007
1057
  oldSession._handleStateExit();
1008
- const session = new SessionNoConnection(listeners, ...carriedState);
1058
+ const session = new SessionNoConnection({ listeners, ...carriedState });
1009
1059
  session.log?.info(
1010
1060
  `session ${session.id} transition from Connecting to NoConnection`,
1011
1061
  {
@@ -1015,11 +1065,11 @@ var SessionStateGraph = {
1015
1065
  );
1016
1066
  return session;
1017
1067
  },
1018
- HandshakingToNoConnection(oldSession, listeners) {
1068
+ HandshakingToNoConnection: (oldSession, listeners) => {
1019
1069
  const carriedState = inheritSharedSession(oldSession);
1020
1070
  oldSession.conn.close();
1021
1071
  oldSession._handleStateExit();
1022
- const session = new SessionNoConnection(listeners, ...carriedState);
1072
+ const session = new SessionNoConnection({ listeners, ...carriedState });
1023
1073
  session.log?.info(
1024
1074
  `session ${session.id} transition from Handshaking to NoConnection`,
1025
1075
  {
@@ -1029,11 +1079,11 @@ var SessionStateGraph = {
1029
1079
  );
1030
1080
  return session;
1031
1081
  },
1032
- ConnectedToNoConnection(oldSession, listeners) {
1082
+ ConnectedToNoConnection: (oldSession, listeners) => {
1033
1083
  const carriedState = inheritSharedSession(oldSession);
1034
1084
  oldSession.conn.close();
1035
1085
  oldSession._handleStateExit();
1036
- const session = new SessionNoConnection(listeners, ...carriedState);
1086
+ const session = new SessionNoConnection({ listeners, ...carriedState });
1037
1087
  session.log?.info(
1038
1088
  `session ${session.id} transition from Connected to NoConnection`,
1039
1089
  {
@@ -1045,6 +1095,31 @@ var SessionStateGraph = {
1045
1095
  }
1046
1096
  }
1047
1097
  };
1098
+ var transitions = SessionStateGraph.transition;
1099
+ var ClientSessionStateGraph = {
1100
+ entrypoint: SessionStateGraph.entrypoints.NoConnection,
1101
+ transition: {
1102
+ // happy paths
1103
+ NoConnectionToBackingOff: transitions.NoConnectionToBackingOff,
1104
+ BackingOffToConnecting: transitions.BackingOffToConnecting,
1105
+ ConnectingToHandshaking: transitions.ConnectingToHandshaking,
1106
+ HandshakingToConnected: transitions.HandshakingToConnected,
1107
+ // disconnect paths
1108
+ BackingOffToNoConnection: transitions.BackingOffToNoConnection,
1109
+ ConnectingToNoConnection: transitions.ConnectingToNoConnection,
1110
+ HandshakingToNoConnection: transitions.HandshakingToNoConnection,
1111
+ ConnectedToNoConnection: transitions.ConnectedToNoConnection
1112
+ }
1113
+ };
1114
+ var ServerSessionStateGraph = {
1115
+ entrypoint: SessionStateGraph.entrypoints.WaitingForHandshake,
1116
+ transition: {
1117
+ // happy paths
1118
+ WaitingForHandshakeToConnected: transitions.WaitingForHandshakeToConnected,
1119
+ // disconnect paths
1120
+ ConnectedToNoConnection: transitions.ConnectedToNoConnection
1121
+ }
1122
+ };
1048
1123
 
1049
1124
  // transport/transport.ts
1050
1125
  var Transport = class {
@@ -1224,8 +1299,10 @@ var ClientTransport = class extends Transport {
1224
1299
  * Optional handshake options for this client.
1225
1300
  */
1226
1301
  handshakeExtensions;
1302
+ sessions;
1227
1303
  constructor(clientId, providedOptions) {
1228
1304
  super(clientId, providedOptions);
1305
+ this.sessions = /* @__PURE__ */ new Map();
1229
1306
  this.options = {
1230
1307
  ...defaultClientTransportOptions,
1231
1308
  ...providedOptions
@@ -1257,7 +1334,7 @@ var ClientTransport = class extends Transport {
1257
1334
  return session.send(msg);
1258
1335
  }
1259
1336
  createUnconnectedSession(to) {
1260
- const session = SessionStateGraph.entrypoints.NoConnection(
1337
+ const session = ClientSessionStateGraph.entrypoint(
1261
1338
  to,
1262
1339
  this.clientId,
1263
1340
  {
@@ -1283,40 +1360,44 @@ var ClientTransport = class extends Transport {
1283
1360
  return noConnectionSession;
1284
1361
  }
1285
1362
  onConnectionEstablished(session, conn) {
1286
- const handshakingSession = SessionStateGraph.transition.ConnectingToHandshaking(session, conn, {
1287
- onConnectionErrored: (err) => {
1288
- const errStr = coerceErrorString(err);
1289
- this.log?.error(
1290
- `connection to ${handshakingSession.to} errored during handshake: ${errStr}`,
1291
- handshakingSession.loggingMetadata
1292
- );
1293
- },
1294
- onConnectionClosed: () => {
1295
- this.log?.warn(
1296
- `connection to ${handshakingSession.to} closed during handshake`,
1297
- handshakingSession.loggingMetadata
1298
- );
1299
- this.onConnClosed(handshakingSession);
1300
- },
1301
- onHandshake: (msg) => {
1302
- this.onHandshakeResponse(handshakingSession, msg);
1303
- },
1304
- onInvalidHandshake: (reason) => {
1305
- this.log?.error(
1306
- `invalid handshake: ${reason}`,
1307
- handshakingSession.loggingMetadata
1308
- );
1309
- this.deleteSession(session);
1310
- this.protocolError(ProtocolError.HandshakeFailed, reason);
1311
- },
1312
- onHandshakeTimeout: () => {
1313
- this.log?.error(
1314
- `connection to ${handshakingSession.to} timed out during handshake`,
1315
- handshakingSession.loggingMetadata
1316
- );
1317
- this.onConnClosed(handshakingSession);
1363
+ const handshakingSession = ClientSessionStateGraph.transition.ConnectingToHandshaking(
1364
+ session,
1365
+ conn,
1366
+ {
1367
+ onConnectionErrored: (err) => {
1368
+ const errStr = coerceErrorString(err);
1369
+ this.log?.error(
1370
+ `connection to ${handshakingSession.to} errored during handshake: ${errStr}`,
1371
+ handshakingSession.loggingMetadata
1372
+ );
1373
+ },
1374
+ onConnectionClosed: () => {
1375
+ this.log?.warn(
1376
+ `connection to ${handshakingSession.to} closed during handshake`,
1377
+ handshakingSession.loggingMetadata
1378
+ );
1379
+ this.onConnClosed(handshakingSession);
1380
+ },
1381
+ onHandshake: (msg) => {
1382
+ this.onHandshakeResponse(handshakingSession, msg);
1383
+ },
1384
+ onInvalidHandshake: (reason) => {
1385
+ this.log?.error(
1386
+ `invalid handshake: ${reason}`,
1387
+ handshakingSession.loggingMetadata
1388
+ );
1389
+ this.deleteSession(session);
1390
+ this.protocolError(ProtocolError.HandshakeFailed, reason);
1391
+ },
1392
+ onHandshakeTimeout: () => {
1393
+ this.log?.error(
1394
+ `connection to ${handshakingSession.to} timed out during handshake`,
1395
+ handshakingSession.loggingMetadata
1396
+ );
1397
+ this.onConnClosed(handshakingSession);
1398
+ }
1318
1399
  }
1319
- });
1400
+ );
1320
1401
  this.updateSession(handshakingSession);
1321
1402
  void this.sendHandshake(handshakingSession);
1322
1403
  return handshakingSession;
@@ -1371,7 +1452,7 @@ var ClientTransport = class extends Transport {
1371
1452
  ...session.loggingMetadata,
1372
1453
  transportMessage: msg
1373
1454
  });
1374
- const connectedSession = SessionStateGraph.transition.HandshakingToConnected(session, {
1455
+ const connectedSession = ClientSessionStateGraph.transition.HandshakingToConnected(session, {
1375
1456
  onConnectionErrored: (err) => {
1376
1457
  const errStr = coerceErrorString(err);
1377
1458
  this.log?.warn(
@@ -1393,7 +1474,7 @@ var ClientTransport = class extends Transport {
1393
1474
  }
1394
1475
  });
1395
1476
  this.updateSession(connectedSession);
1396
- this.retryBudget.startRestoringBudget(connectedSession.to);
1477
+ this.retryBudget.startRestoringBudget();
1397
1478
  }
1398
1479
  /**
1399
1480
  * Manually attempts to connect to a client.
@@ -1416,44 +1497,49 @@ var ClientTransport = class extends Transport {
1416
1497
  );
1417
1498
  return;
1418
1499
  }
1419
- if (!this.retryBudget.hasBudget(to)) {
1420
- const budgetConsumed = this.retryBudget.getBudgetConsumed(to);
1500
+ if (!this.retryBudget.hasBudget()) {
1501
+ const budgetConsumed = this.retryBudget.getBudgetConsumed();
1421
1502
  const errMsg = `tried to connect to ${to} but retry budget exceeded (more than ${budgetConsumed} attempts in the last ${this.retryBudget.totalBudgetRestoreTime}ms)`;
1422
1503
  this.log?.error(errMsg, session.loggingMetadata);
1423
1504
  this.protocolError(ProtocolError.RetriesExceeded, errMsg);
1424
1505
  return;
1425
1506
  }
1426
- let sleep = Promise.resolve();
1427
- const backoffMs = this.retryBudget.getBackoffMs(to);
1428
- if (backoffMs > 0) {
1429
- sleep = new Promise((resolve) => setTimeout(resolve, backoffMs));
1430
- }
1507
+ const backoffMs = this.retryBudget.getBackoffMs();
1431
1508
  this.log?.info(
1432
1509
  `attempting connection to ${to} (${backoffMs}ms backoff)`,
1433
1510
  session.loggingMetadata
1434
1511
  );
1435
- this.retryBudget.consumeBudget(to);
1436
- const reconnectPromise = tracing_default.startActiveSpan("connect", async (span) => {
1437
- try {
1438
- span.addEvent("backoff", { backoffMs });
1439
- await sleep;
1440
- if (this.getStatus() !== "open") {
1441
- throw new Error("transport state is no longer open");
1512
+ this.retryBudget.consumeBudget();
1513
+ const backingOffSession = ClientSessionStateGraph.transition.NoConnectionToBackingOff(
1514
+ session,
1515
+ backoffMs,
1516
+ {
1517
+ onBackoffFinished: () => {
1518
+ const reconnectPromise = tracing_default.startActiveSpan(
1519
+ "connect",
1520
+ async (span) => {
1521
+ try {
1522
+ return await this.createNewOutgoingConnection(to);
1523
+ } catch (err) {
1524
+ const errStr = coerceErrorString(err);
1525
+ span.recordException(errStr);
1526
+ span.setStatus({ code: import_api3.SpanStatusCode.ERROR });
1527
+ throw err;
1528
+ } finally {
1529
+ span.end();
1530
+ }
1531
+ }
1532
+ );
1533
+ this.onBackoffFinished(backingOffSession, reconnectPromise);
1442
1534
  }
1443
- span.addEvent("connecting");
1444
- return await this.createNewOutgoingConnection(to);
1445
- } catch (err) {
1446
- const errStr = coerceErrorString(err);
1447
- span.recordException(errStr);
1448
- span.setStatus({ code: import_api3.SpanStatusCode.ERROR });
1449
- throw err;
1450
- } finally {
1451
- span.end();
1452
1535
  }
1453
- });
1454
- const connectingSession = SessionStateGraph.transition.NoConnectionToConnecting(
1536
+ );
1537
+ this.updateSession(backingOffSession);
1538
+ }
1539
+ onBackoffFinished(session, connPromise) {
1540
+ const connectingSession = ClientSessionStateGraph.transition.BackingOffToConnecting(
1455
1541
  session,
1456
- reconnectPromise,
1542
+ connPromise,
1457
1543
  {
1458
1544
  onConnectionEstablished: (conn) => {
1459
1545
  this.log?.debug(