@replit/river 0.26.0 → 0.26.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 (52) hide show
  1. package/dist/{chunk-KP4UB5NW.js → chunk-AWCUCZY4.js} +2 -2
  2. package/dist/{chunk-5S64PXTU.js → chunk-IV27BICV.js} +36 -9
  3. package/dist/chunk-IV27BICV.js.map +1 -0
  4. package/dist/{chunk-5FDAIAQ5.js → chunk-M5X4JTU3.js} +5 -5
  5. package/dist/chunk-M5X4JTU3.js.map +1 -0
  6. package/dist/{chunk-CCUYKR5C.js → chunk-M75K5TJS.js} +2 -2
  7. package/dist/{chunk-CCUYKR5C.js.map → chunk-M75K5TJS.js.map} +1 -1
  8. package/dist/{chunk-BNNELZM4.js → chunk-MREEJE3X.js} +2 -2
  9. package/dist/{chunk-JSU2KACV.js → chunk-NC54BC47.js} +98 -35
  10. package/dist/chunk-NC54BC47.js.map +1 -0
  11. package/dist/{chunk-7ETNUCOL.js → chunk-YQABPD3C.js} +29 -14
  12. package/dist/chunk-YQABPD3C.js.map +1 -0
  13. package/dist/{client-162c509c.d.ts → client-654098be.d.ts} +2 -4
  14. package/dist/{connection-6a404bb8.d.ts → connection-bc2454dc.d.ts} +1 -1
  15. package/dist/{handshake-3342bb94.d.ts → handshake-1a86f06d.d.ts} +60 -42
  16. package/dist/logging/index.d.cts +1 -1
  17. package/dist/logging/index.d.ts +1 -1
  18. package/dist/{message-1a434848.d.ts → message-57296605.d.ts} +2 -1
  19. package/dist/router/index.cjs +1 -1
  20. package/dist/router/index.cjs.map +1 -1
  21. package/dist/router/index.d.cts +8 -8
  22. package/dist/router/index.d.ts +8 -8
  23. package/dist/router/index.js +2 -2
  24. package/dist/{server-1b695374.d.ts → server-9a6b5a8e.d.ts} +12 -4
  25. package/dist/{services-c17f7eff.d.ts → services-7daa60a0.d.ts} +3 -3
  26. package/dist/transport/impls/ws/client.cjs +131 -41
  27. package/dist/transport/impls/ws/client.cjs.map +1 -1
  28. package/dist/transport/impls/ws/client.d.cts +4 -4
  29. package/dist/transport/impls/ws/client.d.ts +4 -4
  30. package/dist/transport/impls/ws/client.js +5 -5
  31. package/dist/transport/impls/ws/server.cjs +124 -46
  32. package/dist/transport/impls/ws/server.cjs.map +1 -1
  33. package/dist/transport/impls/ws/server.d.cts +4 -4
  34. package/dist/transport/impls/ws/server.d.ts +4 -4
  35. package/dist/transport/impls/ws/server.js +5 -5
  36. package/dist/transport/index.cjs +156 -51
  37. package/dist/transport/index.cjs.map +1 -1
  38. package/dist/transport/index.d.cts +4 -4
  39. package/dist/transport/index.d.ts +4 -4
  40. package/dist/transport/index.js +5 -5
  41. package/dist/util/testHelpers.cjs +97 -34
  42. package/dist/util/testHelpers.cjs.map +1 -1
  43. package/dist/util/testHelpers.d.cts +4 -4
  44. package/dist/util/testHelpers.d.ts +4 -4
  45. package/dist/util/testHelpers.js +3 -3
  46. package/package.json +1 -1
  47. package/dist/chunk-5FDAIAQ5.js.map +0 -1
  48. package/dist/chunk-5S64PXTU.js.map +0 -1
  49. package/dist/chunk-7ETNUCOL.js.map +0 -1
  50. package/dist/chunk-JSU2KACV.js.map +0 -1
  51. /package/dist/{chunk-KP4UB5NW.js.map → chunk-AWCUCZY4.js.map} +0 -0
  52. /package/dist/{chunk-BNNELZM4.js.map → chunk-MREEJE3X.js.map} +0 -0
@@ -1,14 +1,14 @@
1
- import { A as AnyServiceSchemaMap, I as InstantiatedServiceSchemaMap, P as PayloadType, b as Result, R as RiverError } from '../services-c17f7eff.js';
2
- export { C as Client, E as Err, O as Ok, z as Output, j as ProcErrors, f as ProcHandler, g as ProcInit, h as ProcInput, i as ProcOutput, k as ProcType, a as Procedure, p as ProcedureMap, d as ProcedureResult, q as RPCProcedure, y as ResultUnwrapErr, x as ResultUnwrapOk, w as RiverErrorSchema, c as RiverUncaughtSchema, o as SerializedProcedureSchema, m as SerializedServerSchema, n as SerializedServiceSchema, S as Service, e as ServiceConfiguration, l as ServiceSchema, t as StreamProcedure, r as SubscriptionProcedure, v as UNCAUGHT_ERROR, U as UploadProcedure, V as ValidProcType, u as createClient, s as serializeSchema } from '../services-c17f7eff.js';
1
+ import { A as AnyServiceSchemaMap, I as InstantiatedServiceSchemaMap, P as PayloadType, b as Result, R as RiverError } from '../services-7daa60a0.js';
2
+ export { C as Client, E as Err, O as Ok, z as Output, j as ProcErrors, f as ProcHandler, g as ProcInit, h as ProcInput, i as ProcOutput, k as ProcType, a as Procedure, p as ProcedureMap, d as ProcedureResult, q as RPCProcedure, y as ResultUnwrapErr, x as ResultUnwrapOk, w as RiverErrorSchema, c as RiverUncaughtSchema, o as SerializedProcedureSchema, m as SerializedServerSchema, n as SerializedServiceSchema, S as Service, e as ServiceConfiguration, l as ServiceSchema, t as StreamProcedure, r as SubscriptionProcedure, v as UNCAUGHT_ERROR, U as UploadProcedure, V as ValidProcType, u as createClient, s as serializeSchema } from '../services-7daa60a0.js';
3
3
  import { Static } from '@sinclair/typebox';
4
4
  import { Pushable } from 'it-pushable';
5
- import { C as Connection, s as ServerHandshakeOptions, o as ServiceContext } from '../handshake-3342bb94.js';
6
- export { t as ParsedMetadata, u as ServiceContextWithState, v as ServiceContextWithTransportInfo, w as createClientHandshakeOptions, x as createServerHandshakeOptions } from '../handshake-3342bb94.js';
7
- import { S as ServerTransport } from '../server-1b695374.js';
8
- import '../message-1a434848.js';
5
+ import { C as Connection, s as ServerHandshakeOptions, o as ServiceContext } from '../handshake-1a86f06d.js';
6
+ export { t as ParsedMetadata, u as ServiceContextWithState, v as ServiceContextWithTransportInfo, w as createClientHandshakeOptions, x as createServerHandshakeOptions } from '../handshake-1a86f06d.js';
7
+ import { S as ServerTransport } from '../server-9a6b5a8e.js';
8
+ import '../message-57296605.js';
9
9
  import '@sinclair/typebox/value';
10
10
  import '@opentelemetry/api';
11
- import '../client-162c509c.js';
11
+ import '../client-654098be.js';
12
12
  import '../types-3e5768ec.js';
13
13
 
14
14
  /**
@@ -45,6 +45,6 @@ declare function createServer<Services extends AnyServiceSchemaMap>(transport: S
45
45
  extendedContext?: Omit<ServiceContext, 'state'>;
46
46
  }>): Server<Services>;
47
47
 
48
- var version = "0.26.0";
48
+ var version = "0.26.2";
49
49
 
50
50
  export { PayloadType, version as RIVER_VERSION, Result, RiverError, Server, ServiceContext, createServer };
@@ -1,14 +1,14 @@
1
- import { A as AnyServiceSchemaMap, I as InstantiatedServiceSchemaMap, P as PayloadType, b as Result, R as RiverError } from '../services-c17f7eff.js';
2
- export { C as Client, E as Err, O as Ok, z as Output, j as ProcErrors, f as ProcHandler, g as ProcInit, h as ProcInput, i as ProcOutput, k as ProcType, a as Procedure, p as ProcedureMap, d as ProcedureResult, q as RPCProcedure, y as ResultUnwrapErr, x as ResultUnwrapOk, w as RiverErrorSchema, c as RiverUncaughtSchema, o as SerializedProcedureSchema, m as SerializedServerSchema, n as SerializedServiceSchema, S as Service, e as ServiceConfiguration, l as ServiceSchema, t as StreamProcedure, r as SubscriptionProcedure, v as UNCAUGHT_ERROR, U as UploadProcedure, V as ValidProcType, u as createClient, s as serializeSchema } from '../services-c17f7eff.js';
1
+ import { A as AnyServiceSchemaMap, I as InstantiatedServiceSchemaMap, P as PayloadType, b as Result, R as RiverError } from '../services-7daa60a0.js';
2
+ export { C as Client, E as Err, O as Ok, z as Output, j as ProcErrors, f as ProcHandler, g as ProcInit, h as ProcInput, i as ProcOutput, k as ProcType, a as Procedure, p as ProcedureMap, d as ProcedureResult, q as RPCProcedure, y as ResultUnwrapErr, x as ResultUnwrapOk, w as RiverErrorSchema, c as RiverUncaughtSchema, o as SerializedProcedureSchema, m as SerializedServerSchema, n as SerializedServiceSchema, S as Service, e as ServiceConfiguration, l as ServiceSchema, t as StreamProcedure, r as SubscriptionProcedure, v as UNCAUGHT_ERROR, U as UploadProcedure, V as ValidProcType, u as createClient, s as serializeSchema } from '../services-7daa60a0.js';
3
3
  import { Static } from '@sinclair/typebox';
4
4
  import { Pushable } from 'it-pushable';
5
- import { C as Connection, s as ServerHandshakeOptions, o as ServiceContext } from '../handshake-3342bb94.js';
6
- export { t as ParsedMetadata, u as ServiceContextWithState, v as ServiceContextWithTransportInfo, w as createClientHandshakeOptions, x as createServerHandshakeOptions } from '../handshake-3342bb94.js';
7
- import { S as ServerTransport } from '../server-1b695374.js';
8
- import '../message-1a434848.js';
5
+ import { C as Connection, s as ServerHandshakeOptions, o as ServiceContext } from '../handshake-1a86f06d.js';
6
+ export { t as ParsedMetadata, u as ServiceContextWithState, v as ServiceContextWithTransportInfo, w as createClientHandshakeOptions, x as createServerHandshakeOptions } from '../handshake-1a86f06d.js';
7
+ import { S as ServerTransport } from '../server-9a6b5a8e.js';
8
+ import '../message-57296605.js';
9
9
  import '@sinclair/typebox/value';
10
10
  import '@opentelemetry/api';
11
- import '../client-162c509c.js';
11
+ import '../client-654098be.js';
12
12
  import '../types-3e5768ec.js';
13
13
 
14
14
  /**
@@ -45,6 +45,6 @@ declare function createServer<Services extends AnyServiceSchemaMap>(transport: S
45
45
  extendedContext?: Omit<ServiceContext, 'state'>;
46
46
  }>): Server<Services>;
47
47
 
48
- var version = "0.26.0";
48
+ var version = "0.26.2";
49
49
 
50
50
  export { PayloadType, version as RIVER_VERSION, Result, RiverError, Server, ServiceContext, createServer };
@@ -10,10 +10,10 @@ import {
10
10
  createServer,
11
11
  createServerHandshakeOptions,
12
12
  serializeSchema
13
- } from "../chunk-BNNELZM4.js";
13
+ } from "../chunk-MREEJE3X.js";
14
14
  import {
15
15
  version
16
- } from "../chunk-CCUYKR5C.js";
16
+ } from "../chunk-M75K5TJS.js";
17
17
  export {
18
18
  Err,
19
19
  Ok,
@@ -1,14 +1,22 @@
1
- import { C as Connection, y as CommonSession, d as SessionState, z as SessionHandshakingListeners, A as CommonSessionProps, T as Transport, B as ServerTransportOptions, s as ServerHandshakeOptions, t as ParsedMetadata, D as ServerSession, c as ProvidedServerTransportOptions } from './handshake-3342bb94.js';
2
- import { M as MessageMetadata, a as TransportMessage, c as TransportClientId, P as PartialTransportMessage, b as OpaqueTransportMessage } from './message-1a434848.js';
1
+ import { C as Connection, y as CommonSession, d as SessionState, z as CommonSessionProps, T as Transport, A as ServerTransportOptions, s as ServerHandshakeOptions, t as ParsedMetadata, B as ServerSession, c as ProvidedServerTransportOptions } from './handshake-1a86f06d.js';
2
+ import { M as MessageMetadata, a as TransportMessage, b as OpaqueTransportMessage, H as HandshakeErrorResponseCodes, c as TransportClientId, P as PartialTransportMessage } from './message-57296605.js';
3
+ import { Static } from '@sinclair/typebox';
3
4
 
5
+ interface SessionWaitingForHandshakeListeners {
6
+ onConnectionErrored: (err: unknown) => void;
7
+ onConnectionClosed: () => void;
8
+ onHandshake: (msg: OpaqueTransportMessage) => void;
9
+ onInvalidHandshake: (reason: string, code: Static<typeof HandshakeErrorResponseCodes>) => void;
10
+ onHandshakeTimeout: () => void;
11
+ }
4
12
  interface SessionWaitingForHandshakeProps<ConnType extends Connection> extends CommonSessionProps {
5
13
  conn: ConnType;
6
- listeners: SessionHandshakingListeners;
14
+ listeners: SessionWaitingForHandshakeListeners;
7
15
  }
8
16
  declare class SessionWaitingForHandshake<ConnType extends Connection> extends CommonSession {
9
17
  readonly state: SessionState.WaitingForHandshake;
10
18
  conn: ConnType;
11
- listeners: SessionHandshakingListeners;
19
+ listeners: SessionWaitingForHandshakeListeners;
12
20
  handshakeTimeout?: ReturnType<typeof setTimeout>;
13
21
  constructor(props: SessionWaitingForHandshakeProps<ConnType>);
14
22
  onHandshakeData: (msg: Uint8Array) => void;
@@ -1,8 +1,8 @@
1
1
  import { Static, TObject, TUnion, TString, TSchema, TNever, TLiteral } from '@sinclair/typebox';
2
2
  import { Pushable } from 'it-pushable';
3
- import { C as Connection, p as ClientHandshakeOptions, v as ServiceContextWithTransportInfo, o as ServiceContext } from './handshake-3342bb94.js';
4
- import { c as TransportClientId } from './message-1a434848.js';
5
- import { C as ClientTransport } from './client-162c509c.js';
3
+ import { C as Connection, p as ClientHandshakeOptions, v as ServiceContextWithTransportInfo, o as ServiceContext } from './handshake-1a86f06d.js';
4
+ import { c as TransportClientId } from './message-57296605.js';
5
+ import { C as ClientTransport } from './client-654098be.js';
6
6
 
7
7
  type AsyncIter<T> = AsyncGenerator<T, T>;
8
8
  /**
@@ -218,6 +218,7 @@ var defaultTransportOptions = {
218
218
  sessionDisconnectGraceMs: 5e3,
219
219
  connectionTimeoutMs: 2e3,
220
220
  handshakeTimeoutMs: 1e3,
221
+ enableTransparentSessionReconnects: true,
221
222
  codec: NaiveJsonCodec
222
223
  };
223
224
  var defaultConnectionRetryOptions = {
@@ -536,9 +537,32 @@ var IdentifiedSession = class extends CommonSession {
536
537
  this.telemetry.span.end();
537
538
  }
538
539
  };
540
+ var IdentifiedSessionWithGracePeriod = class extends IdentifiedSession {
541
+ graceExpiryTime;
542
+ gracePeriodTimeout;
543
+ listeners;
544
+ constructor(props) {
545
+ super(props);
546
+ this.listeners = props.listeners;
547
+ this.graceExpiryTime = props.graceExpiryTime;
548
+ this.gracePeriodTimeout = setTimeout(() => {
549
+ this.listeners.onSessionGracePeriodElapsed();
550
+ }, this.graceExpiryTime - Date.now());
551
+ }
552
+ _handleStateExit() {
553
+ super._handleStateExit();
554
+ if (this.gracePeriodTimeout) {
555
+ clearTimeout(this.gracePeriodTimeout);
556
+ this.gracePeriodTimeout = void 0;
557
+ }
558
+ }
559
+ _handleClose() {
560
+ super._handleClose();
561
+ }
562
+ };
539
563
 
540
564
  // transport/sessionStateMachine/SessionConnecting.ts
541
- var SessionConnecting = class extends IdentifiedSession {
565
+ var SessionConnecting = class extends IdentifiedSessionWithGracePeriod {
542
566
  state = "Connecting" /* Connecting */;
543
567
  connPromise;
544
568
  listeners;
@@ -571,8 +595,10 @@ var SessionConnecting = class extends IdentifiedSession {
571
595
  }
572
596
  _handleStateExit() {
573
597
  super._handleStateExit();
574
- clearTimeout(this.connectionTimeout);
575
- this.connectionTimeout = void 0;
598
+ if (this.connectionTimeout) {
599
+ clearTimeout(this.connectionTimeout);
600
+ this.connectionTimeout = void 0;
601
+ }
576
602
  }
577
603
  _handleClose() {
578
604
  this.bestEffortClose();
@@ -581,26 +607,13 @@ var SessionConnecting = class extends IdentifiedSession {
581
607
  };
582
608
 
583
609
  // transport/sessionStateMachine/SessionNoConnection.ts
584
- var SessionNoConnection = class extends IdentifiedSession {
610
+ var SessionNoConnection = class extends IdentifiedSessionWithGracePeriod {
585
611
  state = "NoConnection" /* NoConnection */;
586
- listeners;
587
- gracePeriodTimeout;
588
- constructor(props) {
589
- super(props);
590
- this.listeners = props.listeners;
591
- this.gracePeriodTimeout = setTimeout(() => {
592
- this.listeners.onSessionGracePeriodElapsed();
593
- }, this.options.sessionDisconnectGraceMs);
594
- }
595
612
  _handleClose() {
596
613
  super._handleClose();
597
614
  }
598
615
  _handleStateExit() {
599
616
  super._handleStateExit();
600
- if (this.gracePeriodTimeout) {
601
- clearTimeout(this.gracePeriodTimeout);
602
- this.gracePeriodTimeout = void 0;
603
- }
604
617
  }
605
618
  };
606
619
 
@@ -608,7 +621,7 @@ var SessionNoConnection = class extends IdentifiedSession {
608
621
  var import_api = require("@opentelemetry/api");
609
622
 
610
623
  // package.json
611
- var version = "0.26.0";
624
+ var version = "0.26.2";
612
625
 
613
626
  // tracing/index.ts
614
627
  function getPropagationContext(ctx) {
@@ -659,7 +672,10 @@ var SessionWaitingForHandshake = class extends CommonSession {
659
672
  onHandshakeData = (msg) => {
660
673
  const parsedMsg = this.parseMsg(msg);
661
674
  if (parsedMsg === null) {
662
- this.listeners.onInvalidHandshake("could not parse message");
675
+ this.listeners.onInvalidHandshake(
676
+ "could not parse message",
677
+ "MALFORMED_HANDSHAKE"
678
+ );
663
679
  return;
664
680
  }
665
681
  this.listeners.onHandshake(parsedMsg);
@@ -686,7 +702,7 @@ var SessionWaitingForHandshake = class extends CommonSession {
686
702
  };
687
703
 
688
704
  // transport/sessionStateMachine/SessionHandshaking.ts
689
- var SessionHandshaking = class extends IdentifiedSession {
705
+ var SessionHandshaking = class extends IdentifiedSessionWithGracePeriod {
690
706
  state = "Handshaking" /* Handshaking */;
691
707
  conn;
692
708
  listeners;
@@ -705,7 +721,10 @@ var SessionHandshaking = class extends IdentifiedSession {
705
721
  onHandshakeData = (msg) => {
706
722
  const parsedMsg = this.parseMsg(msg);
707
723
  if (parsedMsg === null) {
708
- this.listeners.onInvalidHandshake("could not parse message");
724
+ this.listeners.onInvalidHandshake(
725
+ "could not parse message",
726
+ "MALFORMED_HANDSHAKE"
727
+ );
709
728
  return;
710
729
  }
711
730
  this.listeners.onHandshake(parsedMsg);
@@ -718,7 +737,10 @@ var SessionHandshaking = class extends IdentifiedSession {
718
737
  this.conn.removeDataListener(this.onHandshakeData);
719
738
  this.conn.removeErrorListener(this.listeners.onConnectionErrored);
720
739
  this.conn.removeCloseListener(this.listeners.onConnectionClosed);
721
- clearTimeout(this.handshakeTimeout);
740
+ if (this.handshakeTimeout) {
741
+ clearTimeout(this.handshakeTimeout);
742
+ this.handshakeTimeout = void 0;
743
+ }
722
744
  }
723
745
  _handleClose() {
724
746
  super._handleClose();
@@ -798,8 +820,10 @@ var SessionConnected = class extends IdentifiedSession {
798
820
  }
799
821
  onMessageData = (msg) => {
800
822
  const parsedMsg = this.parseMsg(msg);
801
- if (parsedMsg === null)
823
+ if (parsedMsg === null) {
824
+ this.listeners.onInvalidMessage("could not parse message");
802
825
  return;
826
+ }
803
827
  if (parsedMsg.seq !== this.ack) {
804
828
  if (parsedMsg.seq < this.ack) {
805
829
  this.log?.debug(
@@ -856,7 +880,7 @@ var SessionConnected = class extends IdentifiedSession {
856
880
  };
857
881
 
858
882
  // transport/sessionStateMachine/SessionBackingOff.ts
859
- var SessionBackingOff = class extends IdentifiedSession {
883
+ var SessionBackingOff = class extends IdentifiedSessionWithGracePeriod {
860
884
  state = "BackingOff" /* BackingOff */;
861
885
  listeners;
862
886
  backoffTimeout;
@@ -893,6 +917,12 @@ function inheritSharedSession(session) {
893
917
  log: session.log
894
918
  };
895
919
  }
920
+ function inheritSharedSessionWithGrace(session) {
921
+ return {
922
+ ...inheritSharedSession(session),
923
+ graceExpiryTime: session.graceExpiryTime
924
+ };
925
+ }
896
926
  var SessionStateGraph = {
897
927
  entrypoints: {
898
928
  NoConnection: (to, from, listeners, options, log) => {
@@ -906,6 +936,7 @@ var SessionStateGraph = {
906
936
  to,
907
937
  seq: 0,
908
938
  ack: 0,
939
+ graceExpiryTime: Date.now() + options.sessionDisconnectGraceMs,
909
940
  sendBuffer,
910
941
  telemetry,
911
942
  options,
@@ -937,7 +968,7 @@ var SessionStateGraph = {
937
968
  transition: {
938
969
  // happy path transitions
939
970
  NoConnectionToBackingOff: (oldSession, backoffMs, listeners) => {
940
- const carriedState = inheritSharedSession(oldSession);
971
+ const carriedState = inheritSharedSessionWithGrace(oldSession);
941
972
  oldSession._handleStateExit();
942
973
  const session = new SessionBackingOff({
943
974
  backoffMs,
@@ -954,7 +985,7 @@ var SessionStateGraph = {
954
985
  return session;
955
986
  },
956
987
  BackingOffToConnecting: (oldSession, connPromise, listeners) => {
957
- const carriedState = inheritSharedSession(oldSession);
988
+ const carriedState = inheritSharedSessionWithGrace(oldSession);
958
989
  oldSession._handleStateExit();
959
990
  const session = new SessionConnecting({
960
991
  connPromise,
@@ -971,7 +1002,7 @@ var SessionStateGraph = {
971
1002
  return session;
972
1003
  },
973
1004
  ConnectingToHandshaking: (oldSession, conn, listeners) => {
974
- const carriedState = inheritSharedSession(oldSession);
1005
+ const carriedState = inheritSharedSessionWithGrace(oldSession);
975
1006
  oldSession._handleStateExit();
976
1007
  const session = new SessionHandshaking({
977
1008
  conn,
@@ -1048,9 +1079,12 @@ var SessionStateGraph = {
1048
1079
  },
1049
1080
  // disconnect paths
1050
1081
  BackingOffToNoConnection: (oldSession, listeners) => {
1051
- const carriedState = inheritSharedSession(oldSession);
1082
+ const carriedState = inheritSharedSessionWithGrace(oldSession);
1052
1083
  oldSession._handleStateExit();
1053
- const session = new SessionNoConnection({ listeners, ...carriedState });
1084
+ const session = new SessionNoConnection({
1085
+ listeners,
1086
+ ...carriedState
1087
+ });
1054
1088
  session.log?.info(
1055
1089
  `session ${session.id} transition from BackingOff to NoConnection`,
1056
1090
  {
@@ -1061,10 +1095,13 @@ var SessionStateGraph = {
1061
1095
  return session;
1062
1096
  },
1063
1097
  ConnectingToNoConnection: (oldSession, listeners) => {
1064
- const carriedState = inheritSharedSession(oldSession);
1098
+ const carriedState = inheritSharedSessionWithGrace(oldSession);
1065
1099
  oldSession.bestEffortClose();
1066
1100
  oldSession._handleStateExit();
1067
- const session = new SessionNoConnection({ listeners, ...carriedState });
1101
+ const session = new SessionNoConnection({
1102
+ listeners,
1103
+ ...carriedState
1104
+ });
1068
1105
  session.log?.info(
1069
1106
  `session ${session.id} transition from Connecting to NoConnection`,
1070
1107
  {
@@ -1075,10 +1112,13 @@ var SessionStateGraph = {
1075
1112
  return session;
1076
1113
  },
1077
1114
  HandshakingToNoConnection: (oldSession, listeners) => {
1078
- const carriedState = inheritSharedSession(oldSession);
1115
+ const carriedState = inheritSharedSessionWithGrace(oldSession);
1079
1116
  oldSession.conn.close();
1080
1117
  oldSession._handleStateExit();
1081
- const session = new SessionNoConnection({ listeners, ...carriedState });
1118
+ const session = new SessionNoConnection({
1119
+ listeners,
1120
+ ...carriedState
1121
+ });
1082
1122
  session.log?.info(
1083
1123
  `session ${session.id} transition from Handshaking to NoConnection`,
1084
1124
  {
@@ -1090,9 +1130,14 @@ var SessionStateGraph = {
1090
1130
  },
1091
1131
  ConnectedToNoConnection: (oldSession, listeners) => {
1092
1132
  const carriedState = inheritSharedSession(oldSession);
1133
+ const graceExpiryTime = Date.now() + oldSession.options.sessionDisconnectGraceMs;
1093
1134
  oldSession.conn.close();
1094
1135
  oldSession._handleStateExit();
1095
- const session = new SessionNoConnection({ listeners, ...carriedState });
1136
+ const session = new SessionNoConnection({
1137
+ listeners,
1138
+ graceExpiryTime,
1139
+ ...carriedState
1140
+ });
1096
1141
  session.log?.info(
1097
1142
  `session ${session.id} transition from Connected to NoConnection`,
1098
1143
  {
@@ -1109,24 +1154,42 @@ var ClientSessionStateGraph = {
1109
1154
  entrypoint: SessionStateGraph.entrypoints.NoConnection,
1110
1155
  transition: {
1111
1156
  // happy paths
1157
+ // NoConnection -> BackingOff: attempt to connect
1112
1158
  NoConnectionToBackingOff: transitions.NoConnectionToBackingOff,
1159
+ // BackingOff -> Connecting: backoff period elapsed, start connection
1113
1160
  BackingOffToConnecting: transitions.BackingOffToConnecting,
1161
+ // Connecting -> Handshaking: connection established, start handshake
1114
1162
  ConnectingToHandshaking: transitions.ConnectingToHandshaking,
1163
+ // Handshaking -> Connected: handshake complete, session ready
1115
1164
  HandshakingToConnected: transitions.HandshakingToConnected,
1116
1165
  // disconnect paths
1166
+ // BackingOff -> NoConnection: unused
1117
1167
  BackingOffToNoConnection: transitions.BackingOffToNoConnection,
1168
+ // Connecting -> NoConnection: connection failed or connection timeout
1118
1169
  ConnectingToNoConnection: transitions.ConnectingToNoConnection,
1170
+ // Handshaking -> NoConnection: connection closed or handshake timeout
1119
1171
  HandshakingToNoConnection: transitions.HandshakingToNoConnection,
1172
+ // Connected -> NoConnection: connection closed
1120
1173
  ConnectedToNoConnection: transitions.ConnectedToNoConnection
1174
+ // destroy/close paths
1175
+ // NoConnection -> x: grace period elapsed
1176
+ // BackingOff -> x: grace period elapsed
1177
+ // Connecting -> x: grace period elapsed
1178
+ // Handshaking -> x: grace period elapsed or invalid handshake message or handshake rejection
1179
+ // Connected -> x: grace period elapsed or invalid message
1121
1180
  }
1122
1181
  };
1123
1182
  var ServerSessionStateGraph = {
1124
1183
  entrypoint: SessionStateGraph.entrypoints.WaitingForHandshake,
1125
1184
  transition: {
1126
1185
  // happy paths
1186
+ // WaitingForHandshake -> Connected: handshake complete, session ready
1127
1187
  WaitingForHandshakeToConnected: transitions.WaitingForHandshakeToConnected,
1128
1188
  // disconnect paths
1189
+ // Connected -> NoConnection: connection closed
1129
1190
  ConnectedToNoConnection: transitions.ConnectedToNoConnection
1191
+ // destroy/close paths
1192
+ // WaitingForHandshake -> x: handshake timeout elapsed or invalid handshake message or handshake rejection or connection closed
1130
1193
  }
1131
1194
  };
1132
1195
 
@@ -1195,8 +1258,8 @@ var Transport = class {
1195
1258
  removeEventListener(type, handler) {
1196
1259
  this.eventDispatcher.removeEventListener(type, handler);
1197
1260
  }
1198
- protocolError(type, message) {
1199
- this.eventDispatcher.dispatchEvent("protocolError", { type, message });
1261
+ protocolError(message) {
1262
+ this.eventDispatcher.dispatchEvent("protocolError", message);
1200
1263
  }
1201
1264
  /**
1202
1265
  * Default close implementation for transports. You should override this in the downstream
@@ -1322,6 +1385,10 @@ var ClientTransport = class extends Transport {
1322
1385
  this.handshakeExtensions = options;
1323
1386
  }
1324
1387
  tryReconnecting(to) {
1388
+ const oldSession = this.sessions.get(to);
1389
+ if (!this.options.enableTransparentSessionReconnects && oldSession) {
1390
+ this.deleteSession(oldSession);
1391
+ }
1325
1392
  if (this.reconnectOnConnectionDrop && this.getStatus() === "open") {
1326
1393
  this.connect(to);
1327
1394
  }
@@ -1390,13 +1457,17 @@ var ClientTransport = class extends Transport {
1390
1457
  onHandshake: (msg) => {
1391
1458
  this.onHandshakeResponse(handshakingSession, msg);
1392
1459
  },
1393
- onInvalidHandshake: (reason) => {
1460
+ onInvalidHandshake: (reason, code) => {
1394
1461
  this.log?.error(
1395
1462
  `invalid handshake: ${reason}`,
1396
1463
  handshakingSession.loggingMetadata
1397
1464
  );
1398
1465
  this.deleteSession(session);
1399
- this.protocolError(ProtocolError.HandshakeFailed, reason);
1466
+ this.protocolError({
1467
+ type: ProtocolError.HandshakeFailed,
1468
+ code,
1469
+ message: reason
1470
+ });
1400
1471
  },
1401
1472
  onHandshakeTimeout: () => {
1402
1473
  this.log?.error(
@@ -1404,6 +1475,9 @@ var ClientTransport = class extends Transport {
1404
1475
  handshakingSession.loggingMetadata
1405
1476
  );
1406
1477
  this.onConnClosed(handshakingSession);
1478
+ },
1479
+ onSessionGracePeriodElapsed: () => {
1480
+ this.onSessionGracePeriodElapsed(handshakingSession);
1407
1481
  }
1408
1482
  }
1409
1483
  );
@@ -1445,7 +1519,11 @@ var ClientTransport = class extends Transport {
1445
1519
  this.tryReconnecting(session.to);
1446
1520
  } else {
1447
1521
  this.deleteSession(session);
1448
- this.protocolError(ProtocolError.HandshakeFailed, reason);
1522
+ this.protocolError({
1523
+ type: ProtocolError.HandshakeFailed,
1524
+ code: msg.payload.status.code,
1525
+ message: reason
1526
+ });
1449
1527
  }
1450
1528
  return;
1451
1529
  }
@@ -1479,7 +1557,10 @@ var ClientTransport = class extends Transport {
1479
1557
  onMessage: (msg2) => this.handleMsg(msg2),
1480
1558
  onInvalidMessage: (reason) => {
1481
1559
  this.deleteSession(connectedSession);
1482
- this.protocolError(ProtocolError.MessageOrderingViolated, reason);
1560
+ this.protocolError({
1561
+ type: ProtocolError.MessageOrderingViolated,
1562
+ message: reason
1563
+ });
1483
1564
  }
1484
1565
  });
1485
1566
  this.updateSession(connectedSession);
@@ -1510,7 +1591,10 @@ var ClientTransport = class extends Transport {
1510
1591
  const budgetConsumed = this.retryBudget.getBudgetConsumed();
1511
1592
  const errMsg = `tried to connect to ${to} but retry budget exceeded (more than ${budgetConsumed} attempts in the last ${this.retryBudget.totalBudgetRestoreTime}ms)`;
1512
1593
  this.log?.error(errMsg, session.loggingMetadata);
1513
- this.protocolError(ProtocolError.RetriesExceeded, errMsg);
1594
+ this.protocolError({
1595
+ type: ProtocolError.RetriesExceeded,
1596
+ message: errMsg
1597
+ });
1514
1598
  return;
1515
1599
  }
1516
1600
  const backoffMs = this.retryBudget.getBackoffMs();
@@ -1540,6 +1624,9 @@ var ClientTransport = class extends Transport {
1540
1624
  }
1541
1625
  );
1542
1626
  this.onBackoffFinished(backingOffSession, reconnectPromise);
1627
+ },
1628
+ onSessionGracePeriodElapsed: () => {
1629
+ this.onSessionGracePeriodElapsed(backingOffSession);
1543
1630
  }
1544
1631
  }
1545
1632
  );
@@ -1571,6 +1658,9 @@ var ClientTransport = class extends Transport {
1571
1658
  connectingSession.loggingMetadata
1572
1659
  );
1573
1660
  this.onConnectingFailed(connectingSession);
1661
+ },
1662
+ onSessionGracePeriodElapsed: () => {
1663
+ this.onSessionGracePeriodElapsed(connectingSession);
1574
1664
  }
1575
1665
  }
1576
1666
  );