@replit/river 0.23.8 → 0.23.10

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 (54) hide show
  1. package/dist/{chunk-WQRQFAP6.js → chunk-B323CECK.js} +473 -15
  2. package/dist/chunk-B323CECK.js.map +1 -0
  3. package/dist/{chunk-ELZRZNA5.js → chunk-FRICSBDW.js} +2 -2
  4. package/dist/chunk-FRICSBDW.js.map +1 -0
  5. package/dist/{chunk-RJ6CXPBM.js → chunk-KBAZ5TWE.js} +129 -65
  6. package/dist/chunk-KBAZ5TWE.js.map +1 -0
  7. package/dist/{chunk-DXTG3E3B.js → chunk-UXQMGZKP.js} +2 -2
  8. package/dist/{chunk-CBNCT4B3.js → chunk-Z4G27Y2I.js} +2 -2
  9. package/dist/{connection-6ce35bd5.d.ts → connection-700340c4.d.ts} +1 -1
  10. package/dist/{connection-a3fdfa3a.d.ts → connection-efcd4e1a.d.ts} +1 -1
  11. package/dist/router/index.cjs +473 -14
  12. package/dist/router/index.cjs.map +1 -1
  13. package/dist/router/index.d.cts +41 -7
  14. package/dist/router/index.d.ts +41 -7
  15. package/dist/router/index.js +4 -2
  16. package/dist/{services-fd8a9894.d.ts → services-409c5545.d.ts} +10 -9
  17. package/dist/transport/impls/uds/client.cjs +122 -58
  18. package/dist/transport/impls/uds/client.cjs.map +1 -1
  19. package/dist/transport/impls/uds/client.d.cts +2 -2
  20. package/dist/transport/impls/uds/client.d.ts +2 -2
  21. package/dist/transport/impls/uds/client.js +3 -3
  22. package/dist/transport/impls/uds/server.cjs +103 -47
  23. package/dist/transport/impls/uds/server.cjs.map +1 -1
  24. package/dist/transport/impls/uds/server.d.cts +2 -2
  25. package/dist/transport/impls/uds/server.d.ts +2 -2
  26. package/dist/transport/impls/uds/server.js +3 -3
  27. package/dist/transport/impls/ws/client.cjs +125 -58
  28. package/dist/transport/impls/ws/client.cjs.map +1 -1
  29. package/dist/transport/impls/ws/client.d.cts +2 -2
  30. package/dist/transport/impls/ws/client.d.ts +2 -2
  31. package/dist/transport/impls/ws/client.js +6 -3
  32. package/dist/transport/impls/ws/client.js.map +1 -1
  33. package/dist/transport/impls/ws/server.cjs +103 -47
  34. package/dist/transport/impls/ws/server.cjs.map +1 -1
  35. package/dist/transport/impls/ws/server.d.cts +2 -2
  36. package/dist/transport/impls/ws/server.d.ts +2 -2
  37. package/dist/transport/impls/ws/server.js +3 -3
  38. package/dist/transport/index.cjs +128 -64
  39. package/dist/transport/index.cjs.map +1 -1
  40. package/dist/transport/index.d.cts +1 -1
  41. package/dist/transport/index.d.ts +1 -1
  42. package/dist/transport/index.js +2 -2
  43. package/dist/{transport-3d34f714.d.ts → transport-cf856c41.d.ts} +46 -24
  44. package/dist/util/testHelpers.cjs +46 -4
  45. package/dist/util/testHelpers.cjs.map +1 -1
  46. package/dist/util/testHelpers.d.cts +2 -2
  47. package/dist/util/testHelpers.d.ts +2 -2
  48. package/dist/util/testHelpers.js +3 -3
  49. package/package.json +3 -3
  50. package/dist/chunk-ELZRZNA5.js.map +0 -1
  51. package/dist/chunk-RJ6CXPBM.js.map +0 -1
  52. package/dist/chunk-WQRQFAP6.js.map +0 -1
  53. /package/dist/{chunk-DXTG3E3B.js.map → chunk-UXQMGZKP.js.map} +0 -0
  54. /package/dist/{chunk-CBNCT4B3.js.map → chunk-Z4G27Y2I.js.map} +0 -0
@@ -1,14 +1,49 @@
1
- import { A as AnyServiceSchemaMap, I as InstantiatedServiceSchemaMap, P as PayloadType, b as Result, R as RiverError } from '../services-fd8a9894.js';
2
- export { C as Client, E as Err, O as Ok, x as Output, j as ProcErrors, f as ProcHandler, g as ProcInit, h as ProcInput, i as ProcOutput, k as ProcType, a as Procedure, n as ProcedureMap, d as ProcedureResult, o as RPCProcedure, w as ResultUnwrapErr, v as ResultUnwrapOk, u as RiverErrorSchema, c as RiverUncaughtSchema, m as SerializedServerSchema, S as Service, e as ServiceConfiguration, l as ServiceSchema, q as StreamProcedure, p as SubscriptionProcedure, t as UNCAUGHT_ERROR, U as UploadProcedure, V as ValidProcType, r as createClient, s as serializeSchema } from '../services-fd8a9894.js';
1
+ import { S as SerializedServerSchema, A as AnyServiceSchemaMap, I as InstantiatedServiceSchemaMap, P as PayloadType, b as Result, R as RiverError } from '../services-409c5545.js';
2
+ export { C as Client, E as Err, O as Ok, z as Output, k as ProcErrors, g as ProcHandler, h as ProcInit, i as ProcInput, j as ProcOutput, l 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, n as SerializedServiceSchema, e as Service, f as ServiceConfiguration, m 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-409c5545.js';
3
3
  import { Static } from '@sinclair/typebox';
4
- import { d as ServerTransport, C as Connection, f as ServerHandshakeOptions, b as ServiceContext } from '../transport-3d34f714.js';
5
- export { g as ParsedMetadata, h as ServiceContextWithState, i as ServiceContextWithTransportInfo, j as createClientHandshakeOptions, k as createServerHandshakeOptions } from '../transport-3d34f714.js';
4
+ import { d as ServerTransport, C as Connection, f as ServerHandshakeOptions, b as ServiceContext } from '../transport-cf856c41.js';
5
+ export { g as ParsedMetadata, h as ServiceContextWithState, i as ServiceContextWithTransportInfo, j as createClientHandshakeOptions, k as createServerHandshakeOptions } from '../transport-cf856c41.js';
6
6
  import { Pushable } from 'it-pushable';
7
7
  import '../index-60f03cb7.js';
8
8
  import '@sinclair/typebox/value';
9
9
  import '@opentelemetry/api';
10
10
  import '../types-3e5768ec.js';
11
11
 
12
+ interface ServerBreakage {
13
+ serviceBreakages: Record<string, ServiceBreakage>;
14
+ }
15
+ type ServiceBreakage = {
16
+ reason: 'removed';
17
+ } | {
18
+ reason: 'modified';
19
+ procedureBreakages: Record<string, ProcedureBreakage>;
20
+ };
21
+ type ProcedureBreakage = {
22
+ reason: 'removed';
23
+ } | {
24
+ reason: 'type-changed';
25
+ oldType: string;
26
+ newType: string;
27
+ } | {
28
+ reason: 'modified';
29
+ input?: PayloadBreakage;
30
+ init?: PayloadBreakage;
31
+ output?: PayloadBreakage;
32
+ };
33
+ type PayloadBreakage = {
34
+ reason: 'type-changed';
35
+ oldType: string;
36
+ newType: string;
37
+ } | {
38
+ reason: 'new-required';
39
+ } | {
40
+ reason: 'removed-required';
41
+ } | {
42
+ reason: 'field-breakage';
43
+ fieldBreakages: Record<string, PayloadBreakage>;
44
+ };
45
+ declare function diffServerSchema(oldServer: SerializedServerSchema, newServer: SerializedServerSchema): ServerBreakage | null;
46
+
12
47
  /**
13
48
  * Represents a server with a set of services. Use {@link createServer} to create it.
14
49
  * @template Services - The type of services provided by the server.
@@ -16,7 +51,6 @@ import '../types-3e5768ec.js';
16
51
  interface Server<Services extends AnyServiceSchemaMap> {
17
52
  services: InstantiatedServiceSchemaMap<Services>;
18
53
  streams: Map<string, ProcStream>;
19
- close(): Promise<void>;
20
54
  }
21
55
  interface ProcStream {
22
56
  id: string;
@@ -43,6 +77,6 @@ declare function createServer<Services extends AnyServiceSchemaMap>(transport: S
43
77
  extendedContext?: Omit<ServiceContext, 'state'>;
44
78
  }>): Server<Services>;
45
79
 
46
- var version = "0.23.8";
80
+ var version = "0.23.10";
47
81
 
48
- export { PayloadType, version as RIVER_VERSION, Result, RiverError, Server, ServiceContext, createServer };
82
+ export { PayloadBreakage, PayloadType, ProcedureBreakage, version as RIVER_VERSION, Result, RiverError, SerializedServerSchema, Server, ServerBreakage, ServiceBreakage, ServiceContext, createServer, diffServerSchema };
@@ -1,14 +1,49 @@
1
- import { A as AnyServiceSchemaMap, I as InstantiatedServiceSchemaMap, P as PayloadType, b as Result, R as RiverError } from '../services-fd8a9894.js';
2
- export { C as Client, E as Err, O as Ok, x as Output, j as ProcErrors, f as ProcHandler, g as ProcInit, h as ProcInput, i as ProcOutput, k as ProcType, a as Procedure, n as ProcedureMap, d as ProcedureResult, o as RPCProcedure, w as ResultUnwrapErr, v as ResultUnwrapOk, u as RiverErrorSchema, c as RiverUncaughtSchema, m as SerializedServerSchema, S as Service, e as ServiceConfiguration, l as ServiceSchema, q as StreamProcedure, p as SubscriptionProcedure, t as UNCAUGHT_ERROR, U as UploadProcedure, V as ValidProcType, r as createClient, s as serializeSchema } from '../services-fd8a9894.js';
1
+ import { S as SerializedServerSchema, A as AnyServiceSchemaMap, I as InstantiatedServiceSchemaMap, P as PayloadType, b as Result, R as RiverError } from '../services-409c5545.js';
2
+ export { C as Client, E as Err, O as Ok, z as Output, k as ProcErrors, g as ProcHandler, h as ProcInit, i as ProcInput, j as ProcOutput, l 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, n as SerializedServiceSchema, e as Service, f as ServiceConfiguration, m 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-409c5545.js';
3
3
  import { Static } from '@sinclair/typebox';
4
- import { d as ServerTransport, C as Connection, f as ServerHandshakeOptions, b as ServiceContext } from '../transport-3d34f714.js';
5
- export { g as ParsedMetadata, h as ServiceContextWithState, i as ServiceContextWithTransportInfo, j as createClientHandshakeOptions, k as createServerHandshakeOptions } from '../transport-3d34f714.js';
4
+ import { d as ServerTransport, C as Connection, f as ServerHandshakeOptions, b as ServiceContext } from '../transport-cf856c41.js';
5
+ export { g as ParsedMetadata, h as ServiceContextWithState, i as ServiceContextWithTransportInfo, j as createClientHandshakeOptions, k as createServerHandshakeOptions } from '../transport-cf856c41.js';
6
6
  import { Pushable } from 'it-pushable';
7
7
  import '../index-60f03cb7.js';
8
8
  import '@sinclair/typebox/value';
9
9
  import '@opentelemetry/api';
10
10
  import '../types-3e5768ec.js';
11
11
 
12
+ interface ServerBreakage {
13
+ serviceBreakages: Record<string, ServiceBreakage>;
14
+ }
15
+ type ServiceBreakage = {
16
+ reason: 'removed';
17
+ } | {
18
+ reason: 'modified';
19
+ procedureBreakages: Record<string, ProcedureBreakage>;
20
+ };
21
+ type ProcedureBreakage = {
22
+ reason: 'removed';
23
+ } | {
24
+ reason: 'type-changed';
25
+ oldType: string;
26
+ newType: string;
27
+ } | {
28
+ reason: 'modified';
29
+ input?: PayloadBreakage;
30
+ init?: PayloadBreakage;
31
+ output?: PayloadBreakage;
32
+ };
33
+ type PayloadBreakage = {
34
+ reason: 'type-changed';
35
+ oldType: string;
36
+ newType: string;
37
+ } | {
38
+ reason: 'new-required';
39
+ } | {
40
+ reason: 'removed-required';
41
+ } | {
42
+ reason: 'field-breakage';
43
+ fieldBreakages: Record<string, PayloadBreakage>;
44
+ };
45
+ declare function diffServerSchema(oldServer: SerializedServerSchema, newServer: SerializedServerSchema): ServerBreakage | null;
46
+
12
47
  /**
13
48
  * Represents a server with a set of services. Use {@link createServer} to create it.
14
49
  * @template Services - The type of services provided by the server.
@@ -16,7 +51,6 @@ import '../types-3e5768ec.js';
16
51
  interface Server<Services extends AnyServiceSchemaMap> {
17
52
  services: InstantiatedServiceSchemaMap<Services>;
18
53
  streams: Map<string, ProcStream>;
19
- close(): Promise<void>;
20
54
  }
21
55
  interface ProcStream {
22
56
  id: string;
@@ -43,6 +77,6 @@ declare function createServer<Services extends AnyServiceSchemaMap>(transport: S
43
77
  extendedContext?: Omit<ServiceContext, 'state'>;
44
78
  }>): Server<Services>;
45
79
 
46
- var version = "0.23.8";
80
+ var version = "0.23.10";
47
81
 
48
- export { PayloadType, version as RIVER_VERSION, Result, RiverError, Server, ServiceContext, createServer };
82
+ export { PayloadBreakage, PayloadType, ProcedureBreakage, version as RIVER_VERSION, Result, RiverError, SerializedServerSchema, Server, ServerBreakage, ServiceBreakage, ServiceContext, createServer, diffServerSchema };
@@ -9,11 +9,12 @@ import {
9
9
  createClientHandshakeOptions,
10
10
  createServer,
11
11
  createServerHandshakeOptions,
12
+ diffServerSchema,
12
13
  serializeSchema
13
- } from "../chunk-WQRQFAP6.js";
14
+ } from "../chunk-B323CECK.js";
14
15
  import {
15
16
  version
16
- } from "../chunk-ELZRZNA5.js";
17
+ } from "../chunk-FRICSBDW.js";
17
18
  export {
18
19
  Err,
19
20
  Ok,
@@ -26,6 +27,7 @@ export {
26
27
  createClientHandshakeOptions,
27
28
  createServer,
28
29
  createServerHandshakeOptions,
30
+ diffServerSchema,
29
31
  serializeSchema
30
32
  };
31
33
  //# sourceMappingURL=index.js.map
@@ -1,5 +1,5 @@
1
1
  import { Static, TObject, TUnion, TString, TSchema, TNever, TLiteral } from '@sinclair/typebox';
2
- import { c as ClientTransport, C as Connection, l as ClientHandshakeOptions, i as ServiceContextWithTransportInfo } from './transport-3d34f714.js';
2
+ import { c as ClientTransport, C as Connection, l as ClientHandshakeOptions, i as ServiceContextWithTransportInfo } from './transport-cf856c41.js';
3
3
  import { Pushable } from 'it-pushable';
4
4
  import { T as TransportClientId } from './index-60f03cb7.js';
5
5
 
@@ -477,14 +477,15 @@ interface ServiceConfiguration<State extends object> {
477
477
  */
478
478
  initializeState: () => State;
479
479
  }
480
+ interface SerializedProcedureSchema {
481
+ input: PayloadType;
482
+ output: PayloadType;
483
+ errors?: RiverError;
484
+ type: 'rpc' | 'subscription' | 'upload' | 'stream';
485
+ init?: PayloadType;
486
+ }
480
487
  interface SerializedServiceSchema {
481
- procedures: Record<string, {
482
- input: PayloadType;
483
- output: PayloadType;
484
- errors?: RiverError;
485
- type: 'rpc' | 'subscription' | 'upload' | 'stream';
486
- init?: PayloadType;
487
- }>;
488
+ procedures: Record<string, SerializedProcedureSchema>;
488
489
  }
489
490
  interface SerializedServerSchema {
490
491
  handshakeSchema?: TSchema;
@@ -704,4 +705,4 @@ declare class ServiceScaffold<State extends object> {
704
705
  }>;
705
706
  }
706
707
 
707
- export { AnyServiceSchemaMap as A, Client as C, Err as E, InstantiatedServiceSchemaMap as I, Ok as O, PayloadType as P, RiverError as R, Service as S, UploadProcedure as U, ValidProcType as V, Procedure as a, Result as b, RiverUncaughtSchema as c, ProcedureResult as d, ServiceConfiguration as e, ProcHandler as f, ProcInit as g, ProcInput as h, ProcOutput as i, ProcErrors as j, ProcType as k, ServiceSchema as l, SerializedServerSchema as m, ProcedureMap as n, RpcProcedure as o, SubscriptionProcedure as p, StreamProcedure as q, createClient as r, serializeSchema as s, UNCAUGHT_ERROR as t, RiverErrorSchema as u, ResultUnwrapOk as v, ResultUnwrapErr as w, Output as x };
708
+ export { AnyServiceSchemaMap as A, Client as C, Err as E, InstantiatedServiceSchemaMap as I, Ok as O, PayloadType as P, RiverError as R, SerializedServerSchema as S, UploadProcedure as U, ValidProcType as V, Procedure as a, Result as b, RiverUncaughtSchema as c, ProcedureResult as d, Service as e, ServiceConfiguration as f, ProcHandler as g, ProcInit as h, ProcInput as i, ProcOutput as j, ProcErrors as k, ProcType as l, ServiceSchema as m, SerializedServiceSchema as n, SerializedProcedureSchema as o, ProcedureMap as p, RpcProcedure as q, SubscriptionProcedure as r, serializeSchema as s, StreamProcedure as t, createClient as u, UNCAUGHT_ERROR as v, RiverErrorSchema as w, ResultUnwrapOk as x, ResultUnwrapErr as y, Output as z };
@@ -110,7 +110,7 @@ function isAck(controlFlag) {
110
110
  var import_api = require("@opentelemetry/api");
111
111
 
112
112
  // package.json
113
- var version = "0.23.8";
113
+ var version = "0.23.10";
114
114
 
115
115
  // tracing/index.ts
116
116
  function getPropagationContext(ctx) {
@@ -169,7 +169,7 @@ var Connection = class {
169
169
  get loggingMetadata() {
170
170
  const metadata = { connId: this.id };
171
171
  const spanContext = this.telemetry?.span.spanContext();
172
- if (spanContext) {
172
+ if (this.telemetry?.span.isRecording() && spanContext) {
173
173
  metadata.telemetry = {
174
174
  traceId: spanContext.traceId,
175
175
  spanId: spanContext.spanId
@@ -190,6 +190,11 @@ var Session = class {
190
190
  * The active connection associated with this session
191
191
  */
192
192
  connection;
193
+ /**
194
+ * A connection that is currently undergoing handshaking. Used to distinguish between the active
195
+ * connection, but still be able to close it if needed.
196
+ */
197
+ handshakingConnection;
193
198
  from;
194
199
  to;
195
200
  /**
@@ -369,23 +374,60 @@ var Session = class {
369
374
  this.cancelGrace();
370
375
  this.sendBufferedMessages(newConn);
371
376
  this.connection = newConn;
377
+ this.handshakingConnection = void 0;
378
+ }
379
+ replaceWithNewHandshakingConnection(newConn) {
380
+ this.handshakingConnection = newConn;
372
381
  }
373
382
  beginGrace(cb) {
374
383
  this.log?.info(
375
384
  `starting ${this.options.sessionDisconnectGraceMs}ms grace period until session to ${this.to} is closed`,
376
385
  this.loggingMetadata
377
386
  );
387
+ this.cancelGrace({ keepHeartbeatMisses: true });
378
388
  this.disconnectionGrace = setTimeout(() => {
379
- this.close();
389
+ if (this.connection !== void 0) {
390
+ this.log?.warn(
391
+ `grace period for ${this.to} elapsed while connected. not calling callback`,
392
+ {
393
+ ...this.loggingMetadata,
394
+ connId: this.connection.id,
395
+ tags: ["invariant-violation"]
396
+ }
397
+ );
398
+ return;
399
+ }
400
+ this.log?.info(
401
+ `grace period for ${this.to} elapsed`,
402
+ this.loggingMetadata
403
+ );
380
404
  cb();
381
405
  }, this.options.sessionDisconnectGraceMs);
382
406
  }
383
407
  // called on reconnect of the underlying session
384
- cancelGrace() {
385
- this.heartbeatMisses = 0;
408
+ cancelGrace({ keepHeartbeatMisses } = {
409
+ keepHeartbeatMisses: false
410
+ }) {
411
+ if (!keepHeartbeatMisses) {
412
+ this.heartbeatMisses = 0;
413
+ }
414
+ if (this.disconnectionGrace === void 0)
415
+ return;
386
416
  clearTimeout(this.disconnectionGrace);
387
417
  this.disconnectionGrace = void 0;
388
418
  }
419
+ /**
420
+ * Used to close the handshaking connection, if set.
421
+ */
422
+ closeHandshakingConnection(expectedHandshakingConn) {
423
+ if (this.handshakingConnection === void 0)
424
+ return;
425
+ if (expectedHandshakingConn !== void 0 && this.handshakingConnection === expectedHandshakingConn) {
426
+ return;
427
+ }
428
+ this.handshakingConnection.close();
429
+ this.handshakingConnection = void 0;
430
+ }
389
431
  // closed when we want to discard the whole session
390
432
  // (i.e. shutdown or session disconnect)
391
433
  close() {
@@ -576,11 +618,13 @@ var createLogProxy = (log) => ({
576
618
  var ProtocolError = {
577
619
  RetriesExceeded: "conn_retry_exceeded",
578
620
  HandshakeFailed: "handshake_failed",
579
- UseAfterDestroy: "use_after_destroy",
580
621
  MessageOrderingViolated: "message_ordering_violated"
581
622
  };
582
623
  var EventDispatcher = class {
583
624
  eventListeners = {};
625
+ removeAllListeners() {
626
+ this.eventListeners = {};
627
+ }
584
628
  numberOfListeners(eventType) {
585
629
  return this.eventListeners[eventType]?.size ?? 0;
586
630
  }
@@ -599,7 +643,8 @@ var EventDispatcher = class {
599
643
  dispatchEvent(eventType, event) {
600
644
  const handlers = this.eventListeners[eventType];
601
645
  if (handlers) {
602
- for (const handler of handlers) {
646
+ const copy = [...handlers];
647
+ for (const handler of copy) {
603
648
  handler(event);
604
649
  }
605
650
  }
@@ -761,10 +806,9 @@ var defaultServerTransportOptions = {
761
806
  };
762
807
  var Transport = class {
763
808
  /**
764
- * A flag indicating whether the transport has been destroyed.
765
- * A destroyed transport will not attempt to reconnect and cannot be used again.
809
+ * The status of the transport.
766
810
  */
767
- state;
811
+ status;
768
812
  /**
769
813
  * The {@link Codec} used to encode and decode messages.
770
814
  */
@@ -806,7 +850,7 @@ var Transport = class {
806
850
  this.sessions = /* @__PURE__ */ new Map();
807
851
  this.codec = this.options.codec;
808
852
  this.clientId = clientId;
809
- this.state = "open";
853
+ this.status = "open";
810
854
  }
811
855
  bindLogger(fn, level) {
812
856
  if (typeof fn === "function") {
@@ -854,7 +898,13 @@ var Transport = class {
854
898
  });
855
899
  return session;
856
900
  }
857
- getOrCreateSession(to, conn, sessionId, propagationCtx) {
901
+ getOrCreateSession({
902
+ to,
903
+ conn,
904
+ handshakingConn,
905
+ sessionId,
906
+ propagationCtx
907
+ }) {
858
908
  let session = this.sessions.get(to);
859
909
  let isReconnect = session !== void 0;
860
910
  if (session?.advertisedSessionId !== void 0 && sessionId !== void 0 && session.advertisedSessionId !== sessionId) {
@@ -862,7 +912,11 @@ var Transport = class {
862
912
  `session for ${to} already exists but has a different session id (expected: ${session.advertisedSessionId}, got: ${sessionId}), creating a new one`,
863
913
  session.loggingMetadata
864
914
  );
865
- this.deleteSession(session);
915
+ this.deleteSession({
916
+ session,
917
+ closeHandshakingConnection: handshakingConn !== void 0,
918
+ handshakingConn
919
+ });
866
920
  isReconnect = false;
867
921
  session = void 0;
868
922
  }
@@ -876,9 +930,19 @@ var Transport = class {
876
930
  if (sessionId !== void 0) {
877
931
  session.advertisedSessionId = sessionId;
878
932
  }
933
+ if (handshakingConn !== void 0) {
934
+ session.replaceWithNewHandshakingConnection(handshakingConn);
935
+ }
879
936
  return { session, isReconnect };
880
937
  }
881
- deleteSession(session) {
938
+ deleteSession({
939
+ session,
940
+ closeHandshakingConnection,
941
+ handshakingConn
942
+ }) {
943
+ if (closeHandshakingConnection) {
944
+ session.closeHandshakingConnection(handshakingConn);
945
+ }
882
946
  session.close();
883
947
  session.telemetry.span.end();
884
948
  this.sessions.delete(session.to);
@@ -905,7 +969,11 @@ var Transport = class {
905
969
  session.connection = void 0;
906
970
  session.beginGrace(() => {
907
971
  session.telemetry.span.addEvent("session grace period expired");
908
- this.deleteSession(session);
972
+ this.deleteSession({
973
+ session,
974
+ closeHandshakingConnection: true,
975
+ handshakingConn: conn
976
+ });
909
977
  });
910
978
  }
911
979
  /**
@@ -944,7 +1012,7 @@ var Transport = class {
944
1012
  * @param msg The received message.
945
1013
  */
946
1014
  handleMsg(msg, conn) {
947
- if (this.state !== "open")
1015
+ if (this.getStatus() !== "open")
948
1016
  return;
949
1017
  const session = this.sessions.get(msg.from);
950
1018
  if (!session) {
@@ -985,7 +1053,7 @@ var Transport = class {
985
1053
  code: import_api3.SpanStatusCode.ERROR,
986
1054
  message: "message order violated"
987
1055
  });
988
- session.close();
1056
+ this.deleteSession({ session, closeHandshakingConnection: true });
989
1057
  }
990
1058
  return;
991
1059
  }
@@ -1023,23 +1091,16 @@ var Transport = class {
1023
1091
  * @returns The ID of the sent message or undefined if it wasn't sent
1024
1092
  */
1025
1093
  send(to, msg) {
1026
- if (this.state === "destroyed") {
1027
- const err = "transport is destroyed, cant send";
1094
+ if (this.getStatus() === "closed") {
1095
+ const err = "transport is closed, cant send";
1028
1096
  this.log?.error(err, {
1029
1097
  clientId: this.clientId,
1030
1098
  transportMessage: msg,
1031
1099
  tags: ["invariant-violation"]
1032
1100
  });
1033
- this.protocolError(ProtocolError.UseAfterDestroy, err);
1034
- return void 0;
1035
- } else if (this.state === "closed") {
1036
- this.log?.info(`transport closed when sending, discarding`, {
1037
- clientId: this.clientId,
1038
- transportMessage: msg
1039
- });
1040
- return void 0;
1101
+ throw new Error(err);
1041
1102
  }
1042
- return this.getOrCreateSession(to).session.send(msg);
1103
+ return this.getOrCreateSession({ to }).session.send(msg);
1043
1104
  }
1044
1105
  // control helpers
1045
1106
  sendCloseStream(to, streamId) {
@@ -1060,23 +1121,18 @@ var Transport = class {
1060
1121
  * Closes the transport. Any messages sent while the transport is closed will be silently discarded.
1061
1122
  */
1062
1123
  close() {
1063
- this.state = "closed";
1124
+ this.status = "closed";
1064
1125
  for (const session of this.sessions.values()) {
1065
- this.deleteSession(session);
1126
+ this.deleteSession({ session, closeHandshakingConnection: true });
1066
1127
  }
1128
+ this.eventDispatcher.dispatchEvent("transportStatus", {
1129
+ status: this.status
1130
+ });
1131
+ this.eventDispatcher.removeAllListeners();
1067
1132
  this.log?.info(`manually closed transport`, { clientId: this.clientId });
1068
1133
  }
1069
- /**
1070
- * Default destroy implementation for transports. You should override this in the downstream
1071
- * implementation if you need to do any additional cleanup and call super.destroy() at the end.
1072
- * Destroys the transport. Any messages sent while the transport is destroyed will throw an error.
1073
- */
1074
- destroy() {
1075
- this.state = "destroyed";
1076
- for (const session of this.sessions.values()) {
1077
- this.deleteSession(session);
1078
- }
1079
- this.log?.info(`manually destroyed transport`, { clientId: this.clientId });
1134
+ getStatus() {
1135
+ return this.status;
1080
1136
  }
1081
1137
  };
1082
1138
  var ClientTransport = class extends Transport {
@@ -1113,26 +1169,26 @@ var ClientTransport = class extends Transport {
1113
1169
  this.handshakeExtensions = options;
1114
1170
  }
1115
1171
  handleConnection(conn, to) {
1116
- if (this.state !== "open")
1172
+ if (this.getStatus() !== "open")
1117
1173
  return;
1118
1174
  let session = void 0;
1119
1175
  const handshakeTimeout = setTimeout(() => {
1120
- if (!session) {
1121
- this.log?.warn(
1122
- `connection to ${to} timed out waiting for handshake, closing`,
1123
- { ...conn.loggingMetadata, clientId: this.clientId, connectedTo: to }
1124
- );
1125
- conn.close();
1126
- }
1176
+ if (session)
1177
+ return;
1178
+ this.log?.warn(
1179
+ `connection to ${to} timed out waiting for handshake, closing`,
1180
+ { ...conn.loggingMetadata, clientId: this.clientId, connectedTo: to }
1181
+ );
1182
+ conn.close();
1127
1183
  }, this.options.sessionDisconnectGraceMs);
1128
1184
  const handshakeHandler = (data) => {
1129
1185
  const maybeSession = this.receiveHandshakeResponseMessage(data, conn);
1186
+ clearTimeout(handshakeTimeout);
1130
1187
  if (!maybeSession) {
1131
1188
  conn.close();
1132
1189
  return;
1133
1190
  } else {
1134
1191
  session = maybeSession;
1135
- clearTimeout(handshakeTimeout);
1136
1192
  }
1137
1193
  conn.removeDataListener(handshakeHandler);
1138
1194
  conn.addDataListener((data2) => {
@@ -1239,11 +1295,11 @@ var ClientTransport = class extends Transport {
1239
1295
  connectedTo: parsed.from,
1240
1296
  transportMessage: parsed
1241
1297
  });
1242
- const { session, isReconnect } = this.getOrCreateSession(
1243
- parsed.from,
1298
+ const { session, isReconnect } = this.getOrCreateSession({
1299
+ to: parsed.from,
1244
1300
  conn,
1245
- parsed.payload.status.sessionId
1246
- );
1301
+ sessionId: parsed.payload.status.sessionId
1302
+ });
1247
1303
  this.onConnect(conn, parsed.from, session, isReconnect);
1248
1304
  this.retryBudget.startRestoringBudget(parsed.from);
1249
1305
  return session;
@@ -1253,7 +1309,7 @@ var ClientTransport = class extends Transport {
1253
1309
  * @param to The client ID of the node to connect to.
1254
1310
  */
1255
1311
  async connect(to) {
1256
- const canProceedWithConnection = () => this.state === "open";
1312
+ const canProceedWithConnection = () => this.getStatus() === "open";
1257
1313
  if (!canProceedWithConnection()) {
1258
1314
  this.log?.info(
1259
1315
  `transport state is no longer open, cancelling attempt to connect to ${to}`,
@@ -1349,9 +1405,17 @@ var ClientTransport = class extends Transport {
1349
1405
  }
1350
1406
  }
1351
1407
  }
1352
- deleteSession(session) {
1408
+ deleteSession({
1409
+ session,
1410
+ closeHandshakingConnection,
1411
+ handshakingConn
1412
+ }) {
1353
1413
  this.inflightConnectionPromises.delete(session.to);
1354
- super.deleteSession(session);
1414
+ super.deleteSession({
1415
+ session,
1416
+ closeHandshakingConnection,
1417
+ handshakingConn
1418
+ });
1355
1419
  }
1356
1420
  async sendHandshake(to, conn) {
1357
1421
  let metadata = void 0;
@@ -1378,7 +1442,7 @@ var ClientTransport = class extends Transport {
1378
1442
  return false;
1379
1443
  }
1380
1444
  }
1381
- const { session } = this.getOrCreateSession(to);
1445
+ const { session } = this.getOrCreateSession({ to, handshakingConn: conn });
1382
1446
  const requestMsg = handshakeRequestMessage(
1383
1447
  this.clientId,
1384
1448
  to,