@replit/river 0.26.1 → 0.26.3

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-4W5LENT2.js → chunk-3JCZNGF7.js} +2 -2
  2. package/dist/{chunk-XRI2BXMM.js → chunk-BB2E5L4U.js} +25 -13
  3. package/dist/chunk-BB2E5L4U.js.map +1 -0
  4. package/dist/{chunk-6UVTCZ6K.js → chunk-JI6FFDY5.js} +5 -4
  5. package/dist/{chunk-6UVTCZ6K.js.map → chunk-JI6FFDY5.js.map} +1 -1
  6. package/dist/{chunk-UQOD22AN.js → chunk-MZELCWJK.js} +2 -2
  7. package/dist/{chunk-UQOD22AN.js.map → chunk-MZELCWJK.js.map} +1 -1
  8. package/dist/{chunk-M43R4RPL.js → chunk-OCL2FUTQ.js} +128 -45
  9. package/dist/chunk-OCL2FUTQ.js.map +1 -0
  10. package/dist/{chunk-IVNX5H6C.js → chunk-X35QRIA5.js} +54 -55
  11. package/dist/chunk-X35QRIA5.js.map +1 -0
  12. package/dist/{chunk-AYIMQWS7.js → chunk-ZY2HYJ5Y.js} +2 -2
  13. package/dist/{client-0f636b3a.d.ts → client-1894a9c9.d.ts} +2 -4
  14. package/dist/{connection-07e97a79.d.ts → connection-03ffb583.d.ts} +1 -1
  15. package/dist/{handshake-8752f79e.d.ts → handshake-154a0bb2.d.ts} +82 -39
  16. package/dist/logging/index.d.cts +1 -1
  17. package/dist/logging/index.d.ts +1 -1
  18. package/dist/{message-57296605.d.ts → message-ff78a233.d.ts} +1 -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 +9 -8
  22. package/dist/router/index.d.ts +9 -8
  23. package/dist/router/index.js +2 -2
  24. package/dist/{server-e304daec.d.ts → server-1f5eb427.d.ts} +27 -6
  25. package/dist/{services-fc99aae1.d.ts → services-491d8c32.d.ts} +3 -3
  26. package/dist/transport/impls/ws/client.cjs +153 -56
  27. package/dist/transport/impls/ws/client.cjs.map +1 -1
  28. package/dist/transport/impls/ws/client.d.cts +5 -4
  29. package/dist/transport/impls/ws/client.d.ts +5 -4
  30. package/dist/transport/impls/ws/client.js +8 -7
  31. package/dist/transport/impls/ws/client.js.map +1 -1
  32. package/dist/transport/impls/ws/server.cjs +179 -96
  33. package/dist/transport/impls/ws/server.cjs.map +1 -1
  34. package/dist/transport/impls/ws/server.d.cts +5 -4
  35. package/dist/transport/impls/ws/server.d.ts +5 -4
  36. package/dist/transport/impls/ws/server.js +5 -5
  37. package/dist/transport/index.cjs +200 -105
  38. package/dist/transport/index.cjs.map +1 -1
  39. package/dist/transport/index.d.cts +5 -4
  40. package/dist/transport/index.d.ts +5 -4
  41. package/dist/transport/index.js +5 -5
  42. package/dist/util/testHelpers.cjs +127 -44
  43. package/dist/util/testHelpers.cjs.map +1 -1
  44. package/dist/util/testHelpers.d.cts +5 -4
  45. package/dist/util/testHelpers.d.ts +5 -4
  46. package/dist/util/testHelpers.js +3 -3
  47. package/package.json +1 -1
  48. package/dist/chunk-IVNX5H6C.js.map +0 -1
  49. package/dist/chunk-M43R4RPL.js.map +0 -1
  50. package/dist/chunk-XRI2BXMM.js.map +0 -1
  51. /package/dist/{chunk-4W5LENT2.js.map → chunk-3JCZNGF7.js.map} +0 -0
  52. /package/dist/{chunk-AYIMQWS7.js.map → chunk-ZY2HYJ5Y.js.map} +0 -0
@@ -1,14 +1,15 @@
1
- import { A as AnyServiceSchemaMap, I as InstantiatedServiceSchemaMap, P as PayloadType, b as Result, R as RiverError } from '../services-fc99aae1.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-fc99aae1.js';
1
+ import { A as AnyServiceSchemaMap, I as InstantiatedServiceSchemaMap, P as PayloadType, b as Result, R as RiverError } from '../services-491d8c32.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-491d8c32.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-8752f79e.js';
6
- export { t as ParsedMetadata, u as ServiceContextWithState, v as ServiceContextWithTransportInfo, w as createClientHandshakeOptions, x as createServerHandshakeOptions } from '../handshake-8752f79e.js';
7
- import { S as ServerTransport } from '../server-e304daec.js';
8
- import '../message-57296605.js';
5
+ import { C as Connection, s as ServerHandshakeOptions, o as ServiceContext } from '../handshake-154a0bb2.js';
6
+ export { t as ParsedMetadata, u as ServiceContextWithState, v as ServiceContextWithTransportInfo, w as createClientHandshakeOptions, x as createServerHandshakeOptions } from '../handshake-154a0bb2.js';
7
+ import { S as ServerTransport } from '../server-1f5eb427.js';
8
+ import '../message-ff78a233.js';
9
9
  import '@sinclair/typebox/value';
10
10
  import '@opentelemetry/api';
11
- import '../client-0f636b3a.js';
11
+ import '../client-1894a9c9.js';
12
+ import '@sinclair/typebox/errors';
12
13
  import '../types-3e5768ec.js';
13
14
 
14
15
  /**
@@ -45,6 +46,6 @@ declare function createServer<Services extends AnyServiceSchemaMap>(transport: S
45
46
  extendedContext?: Omit<ServiceContext, 'state'>;
46
47
  }>): Server<Services>;
47
48
 
48
- var version = "0.26.1";
49
+ var version = "0.26.3";
49
50
 
50
51
  export { PayloadType, version as RIVER_VERSION, Result, RiverError, Server, ServiceContext, createServer };
@@ -1,14 +1,15 @@
1
- import { A as AnyServiceSchemaMap, I as InstantiatedServiceSchemaMap, P as PayloadType, b as Result, R as RiverError } from '../services-fc99aae1.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-fc99aae1.js';
1
+ import { A as AnyServiceSchemaMap, I as InstantiatedServiceSchemaMap, P as PayloadType, b as Result, R as RiverError } from '../services-491d8c32.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-491d8c32.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-8752f79e.js';
6
- export { t as ParsedMetadata, u as ServiceContextWithState, v as ServiceContextWithTransportInfo, w as createClientHandshakeOptions, x as createServerHandshakeOptions } from '../handshake-8752f79e.js';
7
- import { S as ServerTransport } from '../server-e304daec.js';
8
- import '../message-57296605.js';
5
+ import { C as Connection, s as ServerHandshakeOptions, o as ServiceContext } from '../handshake-154a0bb2.js';
6
+ export { t as ParsedMetadata, u as ServiceContextWithState, v as ServiceContextWithTransportInfo, w as createClientHandshakeOptions, x as createServerHandshakeOptions } from '../handshake-154a0bb2.js';
7
+ import { S as ServerTransport } from '../server-1f5eb427.js';
8
+ import '../message-ff78a233.js';
9
9
  import '@sinclair/typebox/value';
10
10
  import '@opentelemetry/api';
11
- import '../client-0f636b3a.js';
11
+ import '../client-1894a9c9.js';
12
+ import '@sinclair/typebox/errors';
12
13
  import '../types-3e5768ec.js';
13
14
 
14
15
  /**
@@ -45,6 +46,6 @@ declare function createServer<Services extends AnyServiceSchemaMap>(transport: S
45
46
  extendedContext?: Omit<ServiceContext, 'state'>;
46
47
  }>): Server<Services>;
47
48
 
48
- var version = "0.26.1";
49
+ var version = "0.26.3";
49
50
 
50
51
  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-4W5LENT2.js";
13
+ } from "../chunk-3JCZNGF7.js";
14
14
  import {
15
15
  version
16
- } from "../chunk-UQOD22AN.js";
16
+ } from "../chunk-MZELCWJK.js";
17
17
  export {
18
18
  Err,
19
19
  Ok,
@@ -1,18 +1,40 @@
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-8752f79e.js';
2
- import { M as MessageMetadata, a as TransportMessage, c as TransportClientId, P as PartialTransportMessage, b as OpaqueTransportMessage } from './message-57296605.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-154a0bb2.js';
2
+ import { b as OpaqueTransportMessage, e as Tags, a as TransportMessage, H as HandshakeErrorResponseCodes, c as TransportClientId, P as PartialTransportMessage } from './message-ff78a233.js';
3
+ import * as _sinclair_typebox_errors from '@sinclair/typebox/errors';
4
+ import { Static } from '@sinclair/typebox';
3
5
 
6
+ interface SessionWaitingForHandshakeListeners {
7
+ onConnectionErrored: (err: unknown) => void;
8
+ onConnectionClosed: () => void;
9
+ onHandshake: (msg: OpaqueTransportMessage) => void;
10
+ onInvalidHandshake: (reason: string, code: Static<typeof HandshakeErrorResponseCodes>) => void;
11
+ onHandshakeTimeout: () => void;
12
+ }
4
13
  interface SessionWaitingForHandshakeProps<ConnType extends Connection> extends CommonSessionProps {
5
14
  conn: ConnType;
6
- listeners: SessionHandshakingListeners;
15
+ listeners: SessionWaitingForHandshakeListeners;
7
16
  }
8
17
  declare class SessionWaitingForHandshake<ConnType extends Connection> extends CommonSession {
9
18
  readonly state: SessionState.WaitingForHandshake;
10
19
  conn: ConnType;
11
- listeners: SessionHandshakingListeners;
20
+ listeners: SessionWaitingForHandshakeListeners;
12
21
  handshakeTimeout?: ReturnType<typeof setTimeout>;
13
22
  constructor(props: SessionWaitingForHandshakeProps<ConnType>);
23
+ get loggingMetadata(): {
24
+ protocolVersion?: string | undefined;
25
+ clientId: string;
26
+ connectedTo?: string | undefined;
27
+ sessionId?: string | undefined;
28
+ connId: string;
29
+ transportMessage?: Partial<OpaqueTransportMessage> | undefined;
30
+ validationErrors?: _sinclair_typebox_errors.ValueError[] | undefined;
31
+ tags?: Tags[] | undefined;
32
+ telemetry?: {
33
+ traceId: string;
34
+ spanId: string;
35
+ } | undefined;
36
+ };
14
37
  onHandshakeData: (msg: Uint8Array) => void;
15
- get loggingMetadata(): MessageMetadata;
16
38
  sendHandshake(msg: TransportMessage): boolean;
17
39
  _handleStateExit(): void;
18
40
  _handleClose(): void;
@@ -41,7 +63,6 @@ declare abstract class ServerTransport<ConnType extends Connection> extends Tran
41
63
  protected handleConnection(conn: ConnType): void;
42
64
  private rejectHandshakeRequest;
43
65
  protected onHandshakeRequest(session: SessionWaitingForHandshake<ConnType>, msg: OpaqueTransportMessage): Promise<void>;
44
- private validateHandshakeMetadata;
45
66
  }
46
67
 
47
68
  export { ServerTransport as S, SessionWaitingForHandshake as a };
@@ -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-8752f79e.js';
4
- import { c as TransportClientId } from './message-57296605.js';
5
- import { C as ClientTransport } from './client-0f636b3a.js';
3
+ import { C as Connection, p as ClientHandshakeOptions, v as ServiceContextWithTransportInfo, o as ServiceContext } from './handshake-154a0bb2.js';
4
+ import { c as TransportClientId } from './message-ff78a233.js';
5
+ import { C as ClientTransport } from './client-1894a9c9.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 = {
@@ -419,6 +420,7 @@ var StateMachineState = class {
419
420
  }
420
421
  if (prop === "_handleClose") {
421
422
  return () => {
423
+ target._isConsumed = true;
422
424
  target._handleStateExit();
423
425
  target._handleClose();
424
426
  };
@@ -499,15 +501,18 @@ var IdentifiedSession = class extends CommonSession {
499
501
  }
500
502
  get loggingMetadata() {
501
503
  const spanContext = this.telemetry.span.spanContext();
502
- return {
504
+ const metadata = {
503
505
  clientId: this.from,
504
506
  connectedTo: this.to,
505
- sessionId: this.id,
506
- telemetry: {
507
+ sessionId: this.id
508
+ };
509
+ if (this.telemetry.span.isRecording()) {
510
+ metadata.telemetry = {
507
511
  traceId: spanContext.traceId,
508
512
  spanId: spanContext.spanId
509
- }
510
- };
513
+ };
514
+ }
515
+ return metadata;
511
516
  }
512
517
  constructMsg(partialMsg) {
513
518
  const msg = {
@@ -536,9 +541,32 @@ var IdentifiedSession = class extends CommonSession {
536
541
  this.telemetry.span.end();
537
542
  }
538
543
  };
544
+ var IdentifiedSessionWithGracePeriod = class extends IdentifiedSession {
545
+ graceExpiryTime;
546
+ gracePeriodTimeout;
547
+ listeners;
548
+ constructor(props) {
549
+ super(props);
550
+ this.listeners = props.listeners;
551
+ this.graceExpiryTime = props.graceExpiryTime;
552
+ this.gracePeriodTimeout = setTimeout(() => {
553
+ this.listeners.onSessionGracePeriodElapsed();
554
+ }, this.graceExpiryTime - Date.now());
555
+ }
556
+ _handleStateExit() {
557
+ super._handleStateExit();
558
+ if (this.gracePeriodTimeout) {
559
+ clearTimeout(this.gracePeriodTimeout);
560
+ this.gracePeriodTimeout = void 0;
561
+ }
562
+ }
563
+ _handleClose() {
564
+ super._handleClose();
565
+ }
566
+ };
539
567
 
540
568
  // transport/sessionStateMachine/SessionConnecting.ts
541
- var SessionConnecting = class extends IdentifiedSession {
569
+ var SessionConnecting = class extends IdentifiedSessionWithGracePeriod {
542
570
  state = "Connecting" /* Connecting */;
543
571
  connPromise;
544
572
  listeners;
@@ -566,13 +594,24 @@ var SessionConnecting = class extends IdentifiedSession {
566
594
  // close a pending connection if it resolves, ignore errors if the promise
567
595
  // ends up rejected anyways
568
596
  bestEffortClose() {
569
- void this.connPromise.then((conn) => conn.close()).catch(() => {
597
+ void this.connPromise.then((conn) => {
598
+ conn.close();
599
+ this.log?.info(
600
+ "connection eventually resolved but session has transitioned, closed connection",
601
+ {
602
+ ...this.loggingMetadata,
603
+ ...conn.loggingMetadata
604
+ }
605
+ );
606
+ }).catch(() => {
570
607
  });
571
608
  }
572
609
  _handleStateExit() {
573
610
  super._handleStateExit();
574
- clearTimeout(this.connectionTimeout);
575
- this.connectionTimeout = void 0;
611
+ if (this.connectionTimeout) {
612
+ clearTimeout(this.connectionTimeout);
613
+ this.connectionTimeout = void 0;
614
+ }
576
615
  }
577
616
  _handleClose() {
578
617
  this.bestEffortClose();
@@ -581,26 +620,13 @@ var SessionConnecting = class extends IdentifiedSession {
581
620
  };
582
621
 
583
622
  // transport/sessionStateMachine/SessionNoConnection.ts
584
- var SessionNoConnection = class extends IdentifiedSession {
623
+ var SessionNoConnection = class extends IdentifiedSessionWithGracePeriod {
585
624
  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
625
  _handleClose() {
596
626
  super._handleClose();
597
627
  }
598
628
  _handleStateExit() {
599
629
  super._handleStateExit();
600
- if (this.gracePeriodTimeout) {
601
- clearTimeout(this.gracePeriodTimeout);
602
- this.gracePeriodTimeout = void 0;
603
- }
604
630
  }
605
631
  };
606
632
 
@@ -608,7 +634,7 @@ var SessionNoConnection = class extends IdentifiedSession {
608
634
  var import_api = require("@opentelemetry/api");
609
635
 
610
636
  // package.json
611
- var version = "0.26.1";
637
+ var version = "0.26.3";
612
638
 
613
639
  // tracing/index.ts
614
640
  function getPropagationContext(ctx) {
@@ -656,6 +682,13 @@ var SessionWaitingForHandshake = class extends CommonSession {
656
682
  this.conn.addErrorListener(this.listeners.onConnectionErrored);
657
683
  this.conn.addCloseListener(this.listeners.onConnectionClosed);
658
684
  }
685
+ get loggingMetadata() {
686
+ return {
687
+ clientId: this.from,
688
+ connId: this.conn.id,
689
+ ...this.conn.loggingMetadata
690
+ };
691
+ }
659
692
  onHandshakeData = (msg) => {
660
693
  const parsedMsg = this.parseMsg(msg);
661
694
  if (parsedMsg === null) {
@@ -667,12 +700,6 @@ var SessionWaitingForHandshake = class extends CommonSession {
667
700
  }
668
701
  this.listeners.onHandshake(parsedMsg);
669
702
  };
670
- get loggingMetadata() {
671
- return {
672
- clientId: this.from,
673
- connId: this.conn.id
674
- };
675
- }
676
703
  sendHandshake(msg) {
677
704
  return this.conn.send(this.options.codec.toBuffer(msg));
678
705
  }
@@ -689,7 +716,7 @@ var SessionWaitingForHandshake = class extends CommonSession {
689
716
  };
690
717
 
691
718
  // transport/sessionStateMachine/SessionHandshaking.ts
692
- var SessionHandshaking = class extends IdentifiedSession {
719
+ var SessionHandshaking = class extends IdentifiedSessionWithGracePeriod {
693
720
  state = "Handshaking" /* Handshaking */;
694
721
  conn;
695
722
  listeners;
@@ -705,6 +732,12 @@ var SessionHandshaking = class extends IdentifiedSession {
705
732
  this.conn.addErrorListener(this.listeners.onConnectionErrored);
706
733
  this.conn.addCloseListener(this.listeners.onConnectionClosed);
707
734
  }
735
+ get loggingMetadata() {
736
+ return {
737
+ ...super.loggingMetadata,
738
+ ...this.conn.loggingMetadata
739
+ };
740
+ }
708
741
  onHandshakeData = (msg) => {
709
742
  const parsedMsg = this.parseMsg(msg);
710
743
  if (parsedMsg === null) {
@@ -724,7 +757,10 @@ var SessionHandshaking = class extends IdentifiedSession {
724
757
  this.conn.removeDataListener(this.onHandshakeData);
725
758
  this.conn.removeErrorListener(this.listeners.onConnectionErrored);
726
759
  this.conn.removeCloseListener(this.listeners.onConnectionClosed);
727
- clearTimeout(this.handshakeTimeout);
760
+ if (this.handshakeTimeout) {
761
+ clearTimeout(this.handshakeTimeout);
762
+ this.handshakeTimeout = void 0;
763
+ }
728
764
  }
729
765
  _handleClose() {
730
766
  super._handleClose();
@@ -789,6 +825,12 @@ var SessionConnected = class extends IdentifiedSession {
789
825
  this.heartbeatMisses++;
790
826
  }, this.options.heartbeatIntervalMs);
791
827
  }
828
+ get loggingMetadata() {
829
+ return {
830
+ ...super.loggingMetadata,
831
+ ...this.conn.loggingMetadata
832
+ };
833
+ }
792
834
  startActiveHeartbeat() {
793
835
  this.isActivelyHeartbeating = true;
794
836
  }
@@ -804,8 +846,10 @@ var SessionConnected = class extends IdentifiedSession {
804
846
  }
805
847
  onMessageData = (msg) => {
806
848
  const parsedMsg = this.parseMsg(msg);
807
- if (parsedMsg === null)
849
+ if (parsedMsg === null) {
850
+ this.listeners.onInvalidMessage("could not parse message");
808
851
  return;
852
+ }
809
853
  if (parsedMsg.seq !== this.ack) {
810
854
  if (parsedMsg.seq < this.ack) {
811
855
  this.log?.debug(
@@ -862,7 +906,7 @@ var SessionConnected = class extends IdentifiedSession {
862
906
  };
863
907
 
864
908
  // transport/sessionStateMachine/SessionBackingOff.ts
865
- var SessionBackingOff = class extends IdentifiedSession {
909
+ var SessionBackingOff = class extends IdentifiedSessionWithGracePeriod {
866
910
  state = "BackingOff" /* BackingOff */;
867
911
  listeners;
868
912
  backoffTimeout;
@@ -899,6 +943,12 @@ function inheritSharedSession(session) {
899
943
  log: session.log
900
944
  };
901
945
  }
946
+ function inheritSharedSessionWithGrace(session) {
947
+ return {
948
+ ...inheritSharedSession(session),
949
+ graceExpiryTime: session.graceExpiryTime
950
+ };
951
+ }
902
952
  var SessionStateGraph = {
903
953
  entrypoints: {
904
954
  NoConnection: (to, from, listeners, options, log) => {
@@ -912,6 +962,7 @@ var SessionStateGraph = {
912
962
  to,
913
963
  seq: 0,
914
964
  ack: 0,
965
+ graceExpiryTime: Date.now() + options.sessionDisconnectGraceMs,
915
966
  sendBuffer,
916
967
  telemetry,
917
968
  options,
@@ -943,7 +994,7 @@ var SessionStateGraph = {
943
994
  transition: {
944
995
  // happy path transitions
945
996
  NoConnectionToBackingOff: (oldSession, backoffMs, listeners) => {
946
- const carriedState = inheritSharedSession(oldSession);
997
+ const carriedState = inheritSharedSessionWithGrace(oldSession);
947
998
  oldSession._handleStateExit();
948
999
  const session = new SessionBackingOff({
949
1000
  backoffMs,
@@ -960,7 +1011,7 @@ var SessionStateGraph = {
960
1011
  return session;
961
1012
  },
962
1013
  BackingOffToConnecting: (oldSession, connPromise, listeners) => {
963
- const carriedState = inheritSharedSession(oldSession);
1014
+ const carriedState = inheritSharedSessionWithGrace(oldSession);
964
1015
  oldSession._handleStateExit();
965
1016
  const session = new SessionConnecting({
966
1017
  connPromise,
@@ -977,7 +1028,7 @@ var SessionStateGraph = {
977
1028
  return session;
978
1029
  },
979
1030
  ConnectingToHandshaking: (oldSession, conn, listeners) => {
980
- const carriedState = inheritSharedSession(oldSession);
1031
+ const carriedState = inheritSharedSessionWithGrace(oldSession);
981
1032
  oldSession._handleStateExit();
982
1033
  const session = new SessionHandshaking({
983
1034
  conn,
@@ -1054,9 +1105,12 @@ var SessionStateGraph = {
1054
1105
  },
1055
1106
  // disconnect paths
1056
1107
  BackingOffToNoConnection: (oldSession, listeners) => {
1057
- const carriedState = inheritSharedSession(oldSession);
1108
+ const carriedState = inheritSharedSessionWithGrace(oldSession);
1058
1109
  oldSession._handleStateExit();
1059
- const session = new SessionNoConnection({ listeners, ...carriedState });
1110
+ const session = new SessionNoConnection({
1111
+ listeners,
1112
+ ...carriedState
1113
+ });
1060
1114
  session.log?.info(
1061
1115
  `session ${session.id} transition from BackingOff to NoConnection`,
1062
1116
  {
@@ -1067,10 +1121,13 @@ var SessionStateGraph = {
1067
1121
  return session;
1068
1122
  },
1069
1123
  ConnectingToNoConnection: (oldSession, listeners) => {
1070
- const carriedState = inheritSharedSession(oldSession);
1124
+ const carriedState = inheritSharedSessionWithGrace(oldSession);
1071
1125
  oldSession.bestEffortClose();
1072
1126
  oldSession._handleStateExit();
1073
- const session = new SessionNoConnection({ listeners, ...carriedState });
1127
+ const session = new SessionNoConnection({
1128
+ listeners,
1129
+ ...carriedState
1130
+ });
1074
1131
  session.log?.info(
1075
1132
  `session ${session.id} transition from Connecting to NoConnection`,
1076
1133
  {
@@ -1081,10 +1138,13 @@ var SessionStateGraph = {
1081
1138
  return session;
1082
1139
  },
1083
1140
  HandshakingToNoConnection: (oldSession, listeners) => {
1084
- const carriedState = inheritSharedSession(oldSession);
1141
+ const carriedState = inheritSharedSessionWithGrace(oldSession);
1085
1142
  oldSession.conn.close();
1086
1143
  oldSession._handleStateExit();
1087
- const session = new SessionNoConnection({ listeners, ...carriedState });
1144
+ const session = new SessionNoConnection({
1145
+ listeners,
1146
+ ...carriedState
1147
+ });
1088
1148
  session.log?.info(
1089
1149
  `session ${session.id} transition from Handshaking to NoConnection`,
1090
1150
  {
@@ -1096,9 +1156,14 @@ var SessionStateGraph = {
1096
1156
  },
1097
1157
  ConnectedToNoConnection: (oldSession, listeners) => {
1098
1158
  const carriedState = inheritSharedSession(oldSession);
1159
+ const graceExpiryTime = Date.now() + oldSession.options.sessionDisconnectGraceMs;
1099
1160
  oldSession.conn.close();
1100
1161
  oldSession._handleStateExit();
1101
- const session = new SessionNoConnection({ listeners, ...carriedState });
1162
+ const session = new SessionNoConnection({
1163
+ listeners,
1164
+ graceExpiryTime,
1165
+ ...carriedState
1166
+ });
1102
1167
  session.log?.info(
1103
1168
  `session ${session.id} transition from Connected to NoConnection`,
1104
1169
  {
@@ -1115,24 +1180,42 @@ var ClientSessionStateGraph = {
1115
1180
  entrypoint: SessionStateGraph.entrypoints.NoConnection,
1116
1181
  transition: {
1117
1182
  // happy paths
1183
+ // NoConnection -> BackingOff: attempt to connect
1118
1184
  NoConnectionToBackingOff: transitions.NoConnectionToBackingOff,
1185
+ // BackingOff -> Connecting: backoff period elapsed, start connection
1119
1186
  BackingOffToConnecting: transitions.BackingOffToConnecting,
1187
+ // Connecting -> Handshaking: connection established, start handshake
1120
1188
  ConnectingToHandshaking: transitions.ConnectingToHandshaking,
1189
+ // Handshaking -> Connected: handshake complete, session ready
1121
1190
  HandshakingToConnected: transitions.HandshakingToConnected,
1122
1191
  // disconnect paths
1192
+ // BackingOff -> NoConnection: unused
1123
1193
  BackingOffToNoConnection: transitions.BackingOffToNoConnection,
1194
+ // Connecting -> NoConnection: connection failed or connection timeout
1124
1195
  ConnectingToNoConnection: transitions.ConnectingToNoConnection,
1196
+ // Handshaking -> NoConnection: connection closed or handshake timeout
1125
1197
  HandshakingToNoConnection: transitions.HandshakingToNoConnection,
1198
+ // Connected -> NoConnection: connection closed
1126
1199
  ConnectedToNoConnection: transitions.ConnectedToNoConnection
1200
+ // destroy/close paths
1201
+ // NoConnection -> x: grace period elapsed
1202
+ // BackingOff -> x: grace period elapsed
1203
+ // Connecting -> x: grace period elapsed
1204
+ // Handshaking -> x: grace period elapsed or invalid handshake message or handshake rejection
1205
+ // Connected -> x: grace period elapsed or invalid message
1127
1206
  }
1128
1207
  };
1129
1208
  var ServerSessionStateGraph = {
1130
1209
  entrypoint: SessionStateGraph.entrypoints.WaitingForHandshake,
1131
1210
  transition: {
1132
1211
  // happy paths
1212
+ // WaitingForHandshake -> Connected: handshake complete, session ready
1133
1213
  WaitingForHandshakeToConnected: transitions.WaitingForHandshakeToConnected,
1134
1214
  // disconnect paths
1215
+ // Connected -> NoConnection: connection closed
1135
1216
  ConnectedToNoConnection: transitions.ConnectedToNoConnection
1217
+ // destroy/close paths
1218
+ // WaitingForHandshake -> x: handshake timeout elapsed or invalid handshake message or handshake rejection or connection closed
1136
1219
  }
1137
1220
  };
1138
1221
 
@@ -1249,8 +1332,9 @@ var Transport = class {
1249
1332
  status: "disconnect",
1250
1333
  session
1251
1334
  });
1335
+ const to = session.to;
1252
1336
  session.close();
1253
- this.sessions.delete(session.to);
1337
+ this.sessions.delete(to);
1254
1338
  }
1255
1339
  // common listeners
1256
1340
  onSessionGracePeriodElapsed(session) {
@@ -1328,6 +1412,10 @@ var ClientTransport = class extends Transport {
1328
1412
  this.handshakeExtensions = options;
1329
1413
  }
1330
1414
  tryReconnecting(to) {
1415
+ const oldSession = this.sessions.get(to);
1416
+ if (!this.options.enableTransparentSessionReconnects && oldSession) {
1417
+ this.deleteSession(oldSession);
1418
+ }
1331
1419
  if (this.reconnectOnConnectionDrop && this.getStatus() === "open") {
1332
1420
  this.connect(to);
1333
1421
  }
@@ -1414,6 +1502,9 @@ var ClientTransport = class extends Transport {
1414
1502
  handshakingSession.loggingMetadata
1415
1503
  );
1416
1504
  this.onConnClosed(handshakingSession);
1505
+ },
1506
+ onSessionGracePeriodElapsed: () => {
1507
+ this.onSessionGracePeriodElapsed(handshakingSession);
1417
1508
  }
1418
1509
  }
1419
1510
  );
@@ -1447,14 +1538,14 @@ var ClientTransport = class extends Transport {
1447
1538
  msg.payload.status.code
1448
1539
  ) : false;
1449
1540
  const reason = `handshake failed: ${msg.payload.status.reason}`;
1541
+ const to = session.to;
1450
1542
  this.rejectHandshakeResponse(session, reason, {
1451
1543
  ...session.loggingMetadata,
1452
1544
  transportMessage: msg
1453
1545
  });
1454
1546
  if (retriable) {
1455
- this.tryReconnecting(session.to);
1547
+ this.tryReconnecting(to);
1456
1548
  } else {
1457
- this.deleteSession(session);
1458
1549
  this.protocolError({
1459
1550
  type: ProtocolError.HandshakeFailed,
1460
1551
  code: msg.payload.status.code,
@@ -1507,6 +1598,12 @@ var ClientTransport = class extends Transport {
1507
1598
  * @param to The client ID of the node to connect to.
1508
1599
  */
1509
1600
  connect(to) {
1601
+ if (this.getStatus() !== "open") {
1602
+ this.log?.info(
1603
+ `transport state is no longer open, cancelling attempt to connect to ${to}`
1604
+ );
1605
+ return;
1606
+ }
1510
1607
  let session = this.sessions.get(to);
1511
1608
  session ??= this.createUnconnectedSession(to);
1512
1609
  if (session.state !== "NoConnection" /* NoConnection */) {
@@ -1516,13 +1613,6 @@ var ClientTransport = class extends Transport {
1516
1613
  );
1517
1614
  return;
1518
1615
  }
1519
- if (this.getStatus() !== "open") {
1520
- this.log?.info(
1521
- `transport state is no longer open, cancelling attempt to connect to ${to}`,
1522
- session.loggingMetadata
1523
- );
1524
- return;
1525
- }
1526
1616
  if (!this.retryBudget.hasBudget()) {
1527
1617
  const budgetConsumed = this.retryBudget.getBudgetConsumed();
1528
1618
  const errMsg = `tried to connect to ${to} but retry budget exceeded (more than ${budgetConsumed} attempts in the last ${this.retryBudget.totalBudgetRestoreTime}ms)`;
@@ -1560,6 +1650,9 @@ var ClientTransport = class extends Transport {
1560
1650
  }
1561
1651
  );
1562
1652
  this.onBackoffFinished(backingOffSession, reconnectPromise);
1653
+ },
1654
+ onSessionGracePeriodElapsed: () => {
1655
+ this.onSessionGracePeriodElapsed(backingOffSession);
1563
1656
  }
1564
1657
  }
1565
1658
  );
@@ -1591,6 +1684,9 @@ var ClientTransport = class extends Transport {
1591
1684
  connectingSession.loggingMetadata
1592
1685
  );
1593
1686
  this.onConnectingFailed(connectingSession);
1687
+ },
1688
+ onSessionGracePeriodElapsed: () => {
1689
+ this.onSessionGracePeriodElapsed(connectingSession);
1594
1690
  }
1595
1691
  }
1596
1692
  );
@@ -1780,9 +1876,10 @@ var WebSocketClientTransport = class extends ClientTransport {
1780
1876
  };
1781
1877
  });
1782
1878
  const conn = new WebSocketConnection(ws);
1783
- this.log?.info(`raw websocket to ${to} ok, starting handshake`, {
1879
+ this.log?.info(`raw websocket to ${to} ok`, {
1784
1880
  clientId: this.clientId,
1785
- connectedTo: to
1881
+ connectedTo: to,
1882
+ ...conn.loggingMetadata
1786
1883
  });
1787
1884
  return conn;
1788
1885
  }