@replit/river 0.23.11 → 0.23.13

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 (74) hide show
  1. package/dist/chunk-2FNLANTJ.js +327 -0
  2. package/dist/chunk-2FNLANTJ.js.map +1 -0
  3. package/dist/{chunk-3AW3IXVD.js → chunk-4PVU7J25.js} +1 -21
  4. package/dist/chunk-4PVU7J25.js.map +1 -0
  5. package/dist/{chunk-T6YEMFUF.js → chunk-4QZOW4DH.js} +2 -2
  6. package/dist/{chunk-MEHCOYKJ.js → chunk-ES4XO2XD.js} +2 -2
  7. package/dist/{chunk-MEHCOYKJ.js.map → chunk-ES4XO2XD.js.map} +1 -1
  8. package/dist/{chunk-ZSKCZYVU.js → chunk-KFTGQ3QC.js} +2 -2
  9. package/dist/chunk-KFTGQ3QC.js.map +1 -0
  10. package/dist/chunk-S4DUN7KK.js +455 -0
  11. package/dist/chunk-S4DUN7KK.js.map +1 -0
  12. package/dist/{chunk-HM7VDTDJ.js → chunk-SX6HI63Q.js} +2 -2
  13. package/dist/chunk-XM656KMN.js +408 -0
  14. package/dist/chunk-XM656KMN.js.map +1 -0
  15. package/dist/chunk-ZUKDZY54.js +271 -0
  16. package/dist/chunk-ZUKDZY54.js.map +1 -0
  17. package/dist/client-dd5c9dd0.d.ts +52 -0
  18. package/dist/codec/index.js +20 -2
  19. package/dist/codec/index.js.map +1 -1
  20. package/dist/{connection-261eee8f.d.ts → connection-39816c00.d.ts} +1 -1
  21. package/dist/{connection-c1eeb95d.d.ts → connection-40318f22.d.ts} +1 -1
  22. package/dist/{transport-c8f36f6d.d.ts → handshake-e428d1c8.d.ts} +91 -155
  23. package/dist/{index-60f03cb7.d.ts → index-ea74cdbb.d.ts} +1 -1
  24. package/dist/logging/index.d.cts +1 -1
  25. package/dist/logging/index.d.ts +1 -1
  26. package/dist/router/index.cjs +1 -1
  27. package/dist/router/index.cjs.map +1 -1
  28. package/dist/router/index.d.cts +8 -6
  29. package/dist/router/index.d.ts +8 -6
  30. package/dist/router/index.js +2 -2
  31. package/dist/server-ebf80863.d.ts +24 -0
  32. package/dist/{services-524bab79.d.ts → services-f406b3aa.d.ts} +3 -2
  33. package/dist/transport/impls/uds/client.cjs +222 -174
  34. package/dist/transport/impls/uds/client.cjs.map +1 -1
  35. package/dist/transport/impls/uds/client.d.cts +6 -5
  36. package/dist/transport/impls/uds/client.d.ts +6 -5
  37. package/dist/transport/impls/uds/client.js +6 -4
  38. package/dist/transport/impls/uds/client.js.map +1 -1
  39. package/dist/transport/impls/uds/server.cjs +252 -223
  40. package/dist/transport/impls/uds/server.cjs.map +1 -1
  41. package/dist/transport/impls/uds/server.d.cts +6 -5
  42. package/dist/transport/impls/uds/server.d.ts +6 -5
  43. package/dist/transport/impls/uds/server.js +8 -6
  44. package/dist/transport/impls/uds/server.js.map +1 -1
  45. package/dist/transport/impls/ws/client.cjs +224 -176
  46. package/dist/transport/impls/ws/client.cjs.map +1 -1
  47. package/dist/transport/impls/ws/client.d.cts +6 -5
  48. package/dist/transport/impls/ws/client.d.ts +6 -5
  49. package/dist/transport/impls/ws/client.js +6 -4
  50. package/dist/transport/impls/ws/client.js.map +1 -1
  51. package/dist/transport/impls/ws/server.cjs +206 -177
  52. package/dist/transport/impls/ws/server.cjs.map +1 -1
  53. package/dist/transport/impls/ws/server.d.cts +4 -3
  54. package/dist/transport/impls/ws/server.d.ts +4 -3
  55. package/dist/transport/impls/ws/server.js +8 -6
  56. package/dist/transport/impls/ws/server.js.map +1 -1
  57. package/dist/transport/index.cjs +170 -116
  58. package/dist/transport/index.cjs.map +1 -1
  59. package/dist/transport/index.d.cts +4 -2
  60. package/dist/transport/index.d.ts +4 -2
  61. package/dist/transport/index.js +14 -8
  62. package/dist/util/testHelpers.cjs +6 -8
  63. package/dist/util/testHelpers.cjs.map +1 -1
  64. package/dist/util/testHelpers.d.cts +5 -4
  65. package/dist/util/testHelpers.d.ts +5 -4
  66. package/dist/util/testHelpers.js +4 -5
  67. package/dist/util/testHelpers.js.map +1 -1
  68. package/package.json +1 -1
  69. package/dist/chunk-3AW3IXVD.js.map +0 -1
  70. package/dist/chunk-EOJMKMDO.js +0 -1372
  71. package/dist/chunk-EOJMKMDO.js.map +0 -1
  72. package/dist/chunk-ZSKCZYVU.js.map +0 -1
  73. /package/dist/{chunk-T6YEMFUF.js.map → chunk-4QZOW4DH.js.map} +0 -0
  74. /package/dist/{chunk-HM7VDTDJ.js.map → chunk-SX6HI63Q.js.map} +0 -0
@@ -1,12 +1,14 @@
1
- import { S as SerializedServerSchema, A as AnyServiceSchemaMap, I as InstantiatedServiceSchemaMap, P as PayloadType, b as Result, R as RiverError } from '../services-524bab79.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-524bab79.js';
1
+ import { S as SerializedServerSchema, A as AnyServiceSchemaMap, I as InstantiatedServiceSchemaMap, P as PayloadType, b as Result, R as RiverError } from '../services-f406b3aa.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-f406b3aa.js';
3
3
  import { Static } from '@sinclair/typebox';
4
- import { d as ServerTransport, C as Connection, f as ServerHandshakeOptions, b as ServiceContext } from '../transport-c8f36f6d.js';
5
- export { g as ParsedMetadata, h as ServiceContextWithState, i as ServiceContextWithTransportInfo, j as createClientHandshakeOptions, k as createServerHandshakeOptions } from '../transport-c8f36f6d.js';
6
4
  import { Pushable } from 'it-pushable';
7
- import '../index-60f03cb7.js';
5
+ import { C as Connection, m as ServerHandshakeOptions, i as ServiceContext } from '../handshake-e428d1c8.js';
6
+ export { n as ParsedMetadata, o as ServiceContextWithState, p as ServiceContextWithTransportInfo, q as createClientHandshakeOptions, r as createServerHandshakeOptions } from '../handshake-e428d1c8.js';
7
+ import { S as ServerTransport } from '../server-ebf80863.js';
8
+ import '../index-ea74cdbb.js';
8
9
  import '@sinclair/typebox/value';
9
10
  import '@opentelemetry/api';
11
+ import '../client-dd5c9dd0.js';
10
12
  import '../types-3e5768ec.js';
11
13
 
12
14
  interface ServerBreakage {
@@ -81,6 +83,6 @@ declare function createServer<Services extends AnyServiceSchemaMap>(transport: S
81
83
  extendedContext?: Omit<ServiceContext, 'state'>;
82
84
  }>): Server<Services>;
83
85
 
84
- var version = "0.23.11";
86
+ var version = "0.23.13";
85
87
 
86
88
  export { DiffOptions, PayloadBreakage, PayloadType, ProcedureBreakage, version as RIVER_VERSION, Result, RiverError, SerializedServerSchema, Server, ServerBreakage, ServiceBreakage, ServiceContext, createServer, diffServerSchema };
@@ -1,12 +1,14 @@
1
- import { S as SerializedServerSchema, A as AnyServiceSchemaMap, I as InstantiatedServiceSchemaMap, P as PayloadType, b as Result, R as RiverError } from '../services-524bab79.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-524bab79.js';
1
+ import { S as SerializedServerSchema, A as AnyServiceSchemaMap, I as InstantiatedServiceSchemaMap, P as PayloadType, b as Result, R as RiverError } from '../services-f406b3aa.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-f406b3aa.js';
3
3
  import { Static } from '@sinclair/typebox';
4
- import { d as ServerTransport, C as Connection, f as ServerHandshakeOptions, b as ServiceContext } from '../transport-c8f36f6d.js';
5
- export { g as ParsedMetadata, h as ServiceContextWithState, i as ServiceContextWithTransportInfo, j as createClientHandshakeOptions, k as createServerHandshakeOptions } from '../transport-c8f36f6d.js';
6
4
  import { Pushable } from 'it-pushable';
7
- import '../index-60f03cb7.js';
5
+ import { C as Connection, m as ServerHandshakeOptions, i as ServiceContext } from '../handshake-e428d1c8.js';
6
+ export { n as ParsedMetadata, o as ServiceContextWithState, p as ServiceContextWithTransportInfo, q as createClientHandshakeOptions, r as createServerHandshakeOptions } from '../handshake-e428d1c8.js';
7
+ import { S as ServerTransport } from '../server-ebf80863.js';
8
+ import '../index-ea74cdbb.js';
8
9
  import '@sinclair/typebox/value';
9
10
  import '@opentelemetry/api';
11
+ import '../client-dd5c9dd0.js';
10
12
  import '../types-3e5768ec.js';
11
13
 
12
14
  interface ServerBreakage {
@@ -81,6 +83,6 @@ declare function createServer<Services extends AnyServiceSchemaMap>(transport: S
81
83
  extendedContext?: Omit<ServiceContext, 'state'>;
82
84
  }>): Server<Services>;
83
85
 
84
- var version = "0.23.11";
86
+ var version = "0.23.13";
85
87
 
86
88
  export { DiffOptions, PayloadBreakage, PayloadType, ProcedureBreakage, version as RIVER_VERSION, Result, RiverError, SerializedServerSchema, Server, ServerBreakage, ServiceBreakage, ServiceContext, createServer, diffServerSchema };
@@ -11,10 +11,10 @@ import {
11
11
  createServerHandshakeOptions,
12
12
  diffServerSchema,
13
13
  serializeSchema
14
- } from "../chunk-ZSKCZYVU.js";
14
+ } from "../chunk-KFTGQ3QC.js";
15
15
  import {
16
16
  version
17
- } from "../chunk-MEHCOYKJ.js";
17
+ } from "../chunk-ES4XO2XD.js";
18
18
  export {
19
19
  Err,
20
20
  Ok,
@@ -0,0 +1,24 @@
1
+ import { C as Connection, T as Transport, l as ServerTransportOptions, m as ServerHandshakeOptions, S as Session, n as ParsedMetadata, c as ProvidedServerTransportOptions } from './handshake-e428d1c8.js';
2
+ import { c as TransportClientId } from './index-ea74cdbb.js';
3
+
4
+ declare abstract class ServerTransport<ConnType extends Connection> extends Transport<ConnType> {
5
+ /**
6
+ * The options for this transport.
7
+ */
8
+ protected options: ServerTransportOptions;
9
+ /**
10
+ * Optional handshake options for the server.
11
+ */
12
+ handshakeExtensions?: ServerHandshakeOptions;
13
+ /**
14
+ * A map of session handshake data for each session.
15
+ */
16
+ sessionHandshakeMetadata: WeakMap<Session<ConnType>, ParsedMetadata>;
17
+ constructor(clientId: TransportClientId, providedOptions?: ProvidedServerTransportOptions);
18
+ extendHandshake(options: ServerHandshakeOptions): void;
19
+ protected handleConnection(conn: ConnType): void;
20
+ private validateHandshakeMetadata;
21
+ receiveHandshakeRequestMessage(data: Uint8Array, conn: ConnType): Promise<Session<ConnType> | false>;
22
+ }
23
+
24
+ export { ServerTransport as S };
@@ -1,7 +1,8 @@
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-c8f36f6d.js';
3
2
  import { Pushable } from 'it-pushable';
4
- import { T as TransportClientId } from './index-60f03cb7.js';
3
+ import { C as Connection, k as ClientHandshakeOptions, p as ServiceContextWithTransportInfo } from './handshake-e428d1c8.js';
4
+ import { c as TransportClientId } from './index-ea74cdbb.js';
5
+ import { C as ClientTransport } from './client-dd5c9dd0.js';
5
6
 
6
7
  type AsyncIter<T> = AsyncGenerator<T, T>;
7
8
  /**
@@ -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.11";
113
+ var version = "0.23.13";
114
114
 
115
115
  // tracing/index.ts
116
116
  function getPropagationContext(ctx) {
@@ -369,10 +369,12 @@ var Session = class {
369
369
  this.connection.close();
370
370
  this.connection = void 0;
371
371
  }
372
- replaceWithNewConnection(newConn) {
372
+ replaceWithNewConnection(newConn, isTransparentReconnect) {
373
373
  this.closeStaleConnection(newConn);
374
374
  this.cancelGrace();
375
- this.sendBufferedMessages(newConn);
375
+ if (isTransparentReconnect) {
376
+ this.sendBufferedMessages(newConn);
377
+ }
376
378
  this.connection = newConn;
377
379
  this.handshakingConnection = void 0;
378
380
  }
@@ -541,6 +543,154 @@ var UdsConnection = class extends Connection {
541
543
  }
542
544
  };
543
545
 
546
+ // transport/client.ts
547
+ var import_api4 = require("@opentelemetry/api");
548
+
549
+ // codec/json.ts
550
+ var encoder = new TextEncoder();
551
+ var decoder = new TextDecoder();
552
+ function uint8ArrayToBase64(uint8Array) {
553
+ let binary = "";
554
+ uint8Array.forEach((byte) => {
555
+ binary += String.fromCharCode(byte);
556
+ });
557
+ return btoa(binary);
558
+ }
559
+ function base64ToUint8Array(base64) {
560
+ const binaryString = atob(base64);
561
+ const uint8Array = new Uint8Array(binaryString.length);
562
+ for (let i = 0; i < binaryString.length; i++) {
563
+ uint8Array[i] = binaryString.charCodeAt(i);
564
+ }
565
+ return uint8Array;
566
+ }
567
+ var NaiveJsonCodec = {
568
+ toBuffer: (obj) => {
569
+ return encoder.encode(
570
+ JSON.stringify(obj, function replacer(key) {
571
+ const val = this[key];
572
+ if (val instanceof Uint8Array) {
573
+ return { $t: uint8ArrayToBase64(val) };
574
+ } else {
575
+ return val;
576
+ }
577
+ })
578
+ );
579
+ },
580
+ fromBuffer: (buff) => {
581
+ try {
582
+ const parsed = JSON.parse(
583
+ decoder.decode(buff),
584
+ function reviver(_key, val) {
585
+ if (val?.$t) {
586
+ return base64ToUint8Array(val.$t);
587
+ } else {
588
+ return val;
589
+ }
590
+ }
591
+ );
592
+ if (typeof parsed === "object")
593
+ return parsed;
594
+ return null;
595
+ } catch {
596
+ return null;
597
+ }
598
+ }
599
+ };
600
+
601
+ // transport/options.ts
602
+ var defaultTransportOptions = {
603
+ heartbeatIntervalMs: 1e3,
604
+ heartbeatsUntilDead: 2,
605
+ sessionDisconnectGraceMs: 5e3,
606
+ codec: NaiveJsonCodec
607
+ };
608
+ var defaultConnectionRetryOptions = {
609
+ baseIntervalMs: 250,
610
+ maxJitterMs: 200,
611
+ maxBackoffMs: 32e3,
612
+ attemptBudgetCapacity: 5,
613
+ budgetRestoreIntervalMs: 200
614
+ };
615
+ var defaultClientTransportOptions = {
616
+ ...defaultTransportOptions,
617
+ ...defaultConnectionRetryOptions
618
+ };
619
+ var defaultServerTransportOptions = {
620
+ ...defaultTransportOptions
621
+ };
622
+
623
+ // transport/rateLimit.ts
624
+ var LeakyBucketRateLimit = class {
625
+ budgetConsumed;
626
+ intervalHandles;
627
+ options;
628
+ constructor(options) {
629
+ this.options = options;
630
+ this.budgetConsumed = /* @__PURE__ */ new Map();
631
+ this.intervalHandles = /* @__PURE__ */ new Map();
632
+ }
633
+ getBackoffMs(user) {
634
+ if (!this.budgetConsumed.has(user))
635
+ return 0;
636
+ const exponent = Math.max(0, this.getBudgetConsumed(user) - 1);
637
+ const jitter = Math.floor(Math.random() * this.options.maxJitterMs);
638
+ const backoffMs = Math.min(
639
+ this.options.baseIntervalMs * 2 ** exponent,
640
+ this.options.maxBackoffMs
641
+ );
642
+ return backoffMs + jitter;
643
+ }
644
+ get totalBudgetRestoreTime() {
645
+ return this.options.budgetRestoreIntervalMs * this.options.attemptBudgetCapacity;
646
+ }
647
+ consumeBudget(user) {
648
+ this.stopLeak(user);
649
+ this.budgetConsumed.set(user, this.getBudgetConsumed(user) + 1);
650
+ }
651
+ getBudgetConsumed(user) {
652
+ return this.budgetConsumed.get(user) ?? 0;
653
+ }
654
+ hasBudget(user) {
655
+ return this.getBudgetConsumed(user) < this.options.attemptBudgetCapacity;
656
+ }
657
+ startRestoringBudget(user) {
658
+ if (this.intervalHandles.has(user)) {
659
+ return;
660
+ }
661
+ const restoreBudgetForUser = () => {
662
+ const currentBudget = this.budgetConsumed.get(user);
663
+ if (!currentBudget) {
664
+ this.stopLeak(user);
665
+ return;
666
+ }
667
+ const newBudget = currentBudget - 1;
668
+ if (newBudget === 0) {
669
+ this.budgetConsumed.delete(user);
670
+ return;
671
+ }
672
+ this.budgetConsumed.set(user, newBudget);
673
+ };
674
+ const intervalHandle = setInterval(
675
+ restoreBudgetForUser,
676
+ this.options.budgetRestoreIntervalMs
677
+ );
678
+ this.intervalHandles.set(user, intervalHandle);
679
+ }
680
+ stopLeak(user) {
681
+ if (!this.intervalHandles.has(user)) {
682
+ return;
683
+ }
684
+ clearInterval(this.intervalHandles.get(user));
685
+ this.intervalHandles.delete(user);
686
+ }
687
+ close() {
688
+ for (const user of this.intervalHandles.keys()) {
689
+ this.stopLeak(user);
690
+ }
691
+ }
692
+ };
693
+
544
694
  // transport/transport.ts
545
695
  var import_value = require("@sinclair/typebox/value");
546
696
 
@@ -634,159 +784,8 @@ var EventDispatcher = class {
634
784
  }
635
785
  };
636
786
 
637
- // util/stringify.ts
638
- function coerceErrorString(err) {
639
- if (err instanceof Error) {
640
- return err.message || "unknown reason";
641
- }
642
- return `[coerced to error] ${String(err)}`;
643
- }
644
-
645
- // transport/rateLimit.ts
646
- var LeakyBucketRateLimit = class {
647
- budgetConsumed;
648
- intervalHandles;
649
- options;
650
- constructor(options) {
651
- this.options = options;
652
- this.budgetConsumed = /* @__PURE__ */ new Map();
653
- this.intervalHandles = /* @__PURE__ */ new Map();
654
- }
655
- getBackoffMs(user) {
656
- if (!this.budgetConsumed.has(user))
657
- return 0;
658
- const exponent = Math.max(0, this.getBudgetConsumed(user) - 1);
659
- const jitter = Math.floor(Math.random() * this.options.maxJitterMs);
660
- const backoffMs = Math.min(
661
- this.options.baseIntervalMs * 2 ** exponent,
662
- this.options.maxBackoffMs
663
- );
664
- return backoffMs + jitter;
665
- }
666
- get totalBudgetRestoreTime() {
667
- return this.options.budgetRestoreIntervalMs * this.options.attemptBudgetCapacity;
668
- }
669
- consumeBudget(user) {
670
- this.stopLeak(user);
671
- this.budgetConsumed.set(user, this.getBudgetConsumed(user) + 1);
672
- }
673
- getBudgetConsumed(user) {
674
- return this.budgetConsumed.get(user) ?? 0;
675
- }
676
- hasBudget(user) {
677
- return this.getBudgetConsumed(user) < this.options.attemptBudgetCapacity;
678
- }
679
- startRestoringBudget(user) {
680
- if (this.intervalHandles.has(user)) {
681
- return;
682
- }
683
- const restoreBudgetForUser = () => {
684
- const currentBudget = this.budgetConsumed.get(user);
685
- if (!currentBudget) {
686
- this.stopLeak(user);
687
- return;
688
- }
689
- const newBudget = currentBudget - 1;
690
- if (newBudget === 0) {
691
- this.budgetConsumed.delete(user);
692
- return;
693
- }
694
- this.budgetConsumed.set(user, newBudget);
695
- };
696
- const intervalHandle = setInterval(
697
- restoreBudgetForUser,
698
- this.options.budgetRestoreIntervalMs
699
- );
700
- this.intervalHandles.set(user, intervalHandle);
701
- }
702
- stopLeak(user) {
703
- if (!this.intervalHandles.has(user)) {
704
- return;
705
- }
706
- clearInterval(this.intervalHandles.get(user));
707
- this.intervalHandles.delete(user);
708
- }
709
- close() {
710
- for (const user of this.intervalHandles.keys()) {
711
- this.stopLeak(user);
712
- }
713
- }
714
- };
715
-
716
- // codec/json.ts
717
- var encoder = new TextEncoder();
718
- var decoder = new TextDecoder();
719
- function uint8ArrayToBase64(uint8Array) {
720
- let binary = "";
721
- uint8Array.forEach((byte) => {
722
- binary += String.fromCharCode(byte);
723
- });
724
- return btoa(binary);
725
- }
726
- function base64ToUint8Array(base64) {
727
- const binaryString = atob(base64);
728
- const uint8Array = new Uint8Array(binaryString.length);
729
- for (let i = 0; i < binaryString.length; i++) {
730
- uint8Array[i] = binaryString.charCodeAt(i);
731
- }
732
- return uint8Array;
733
- }
734
- var NaiveJsonCodec = {
735
- toBuffer: (obj) => {
736
- return encoder.encode(
737
- JSON.stringify(obj, function replacer(key) {
738
- const val = this[key];
739
- if (val instanceof Uint8Array) {
740
- return { $t: uint8ArrayToBase64(val) };
741
- } else {
742
- return val;
743
- }
744
- })
745
- );
746
- },
747
- fromBuffer: (buff) => {
748
- try {
749
- const parsed = JSON.parse(
750
- decoder.decode(buff),
751
- function reviver(_key, val) {
752
- if (val?.$t) {
753
- return base64ToUint8Array(val.$t);
754
- } else {
755
- return val;
756
- }
757
- }
758
- );
759
- if (typeof parsed === "object")
760
- return parsed;
761
- return null;
762
- } catch {
763
- return null;
764
- }
765
- }
766
- };
767
-
768
787
  // transport/transport.ts
769
788
  var import_api3 = require("@opentelemetry/api");
770
- var defaultTransportOptions = {
771
- heartbeatIntervalMs: 1e3,
772
- heartbeatsUntilDead: 2,
773
- sessionDisconnectGraceMs: 5e3,
774
- codec: NaiveJsonCodec
775
- };
776
- var defaultConnectionRetryOptions = {
777
- baseIntervalMs: 250,
778
- maxJitterMs: 200,
779
- maxBackoffMs: 32e3,
780
- attemptBudgetCapacity: 5,
781
- budgetRestoreIntervalMs: 200
782
- };
783
- var defaultClientTransportOptions = {
784
- ...defaultTransportOptions,
785
- ...defaultConnectionRetryOptions
786
- };
787
- var defaultServerTransportOptions = {
788
- ...defaultTransportOptions
789
- };
790
789
  var Transport = class {
791
790
  /**
792
791
  * The status of the transport.
@@ -847,15 +846,13 @@ var Transport = class {
847
846
  * and we know the identity of the connected client.
848
847
  * @param conn The connection object.
849
848
  */
850
- onConnect(conn, session, isReconnect) {
849
+ onConnect(conn, session, isTransparentReconnect) {
851
850
  this.eventDispatcher.dispatchEvent("connectionStatus", {
852
851
  status: "connect",
853
852
  conn
854
853
  });
855
854
  conn.telemetry = createConnectionTelemetryInfo(conn, session.telemetry);
856
- if (isReconnect) {
857
- session.replaceWithNewConnection(conn);
858
- }
855
+ session.replaceWithNewConnection(conn, isTransparentReconnect);
859
856
  this.log?.info(`connected to ${session.to}`, {
860
857
  ...conn.loggingMetadata,
861
858
  ...session.loggingMetadata
@@ -887,7 +884,8 @@ var Transport = class {
887
884
  propagationCtx
888
885
  }) {
889
886
  let session = this.sessions.get(to);
890
- let isReconnect = session !== void 0;
887
+ const isReconnect = session !== void 0;
888
+ let isTransparentReconnect = isReconnect;
891
889
  if (session?.advertisedSessionId !== void 0 && sessionId !== void 0 && session.advertisedSessionId !== sessionId) {
892
890
  this.log?.info(
893
891
  `session for ${to} already exists but has a different session id (expected: ${session.advertisedSessionId}, got: ${sessionId}), creating a new one`,
@@ -898,7 +896,7 @@ var Transport = class {
898
896
  closeHandshakingConnection: handshakingConn !== void 0,
899
897
  handshakingConn
900
898
  });
901
- isReconnect = false;
899
+ isTransparentReconnect = false;
902
900
  session = void 0;
903
901
  }
904
902
  if (!session) {
@@ -914,7 +912,7 @@ var Transport = class {
914
912
  if (handshakingConn !== void 0) {
915
913
  session.replaceWithNewHandshakingConnection(handshakingConn);
916
914
  }
917
- return { session, isReconnect };
915
+ return { session, isReconnect, isTransparentReconnect };
918
916
  }
919
917
  deleteSession({
920
918
  session,
@@ -942,6 +940,16 @@ var Transport = class {
942
940
  * @param connectedTo The peer we are connected to.
943
941
  */
944
942
  onDisconnect(conn, session) {
943
+ if (session.connection !== void 0 && session.connection.id !== conn.id) {
944
+ session.telemetry.span.addEvent("onDisconnect race");
945
+ this.log?.warn("onDisconnect race", {
946
+ clientId: this.clientId,
947
+ ...session.loggingMetadata,
948
+ ...conn.loggingMetadata,
949
+ tags: ["invariant-violation"]
950
+ });
951
+ return;
952
+ }
945
953
  conn.telemetry?.span.end();
946
954
  this.eventDispatcher.dispatchEvent("connectionStatus", {
947
955
  status: "disconnect",
@@ -949,6 +957,16 @@ var Transport = class {
949
957
  });
950
958
  session.connection = void 0;
951
959
  session.beginGrace(() => {
960
+ if (session.connection !== void 0) {
961
+ session.telemetry.span.addEvent("session grace period race");
962
+ this.log?.warn("session grace period race", {
963
+ clientId: this.clientId,
964
+ ...session.loggingMetadata,
965
+ ...conn.loggingMetadata,
966
+ tags: ["invariant-violation"]
967
+ });
968
+ return;
969
+ }
952
970
  session.telemetry.span.addEvent("session grace period expired");
953
971
  this.deleteSession({
954
972
  session,
@@ -1116,6 +1134,17 @@ var Transport = class {
1116
1134
  return this.status;
1117
1135
  }
1118
1136
  };
1137
+
1138
+ // util/stringify.ts
1139
+ function coerceErrorString(err) {
1140
+ if (err instanceof Error) {
1141
+ return err.message || "unknown reason";
1142
+ }
1143
+ return `[coerced to error] ${String(err)}`;
1144
+ }
1145
+
1146
+ // transport/client.ts
1147
+ var import_value2 = require("@sinclair/typebox/value");
1119
1148
  var ClientTransport = class extends Transport {
1120
1149
  /**
1121
1150
  * The options for this transport.
@@ -1176,7 +1205,7 @@ var ClientTransport = class extends Transport {
1176
1205
  const parsed = this.parseMsg(data2, conn);
1177
1206
  if (!parsed) {
1178
1207
  conn.telemetry?.span.setStatus({
1179
- code: import_api3.SpanStatusCode.ERROR,
1208
+ code: import_api4.SpanStatusCode.ERROR,
1180
1209
  message: "message parse failure"
1181
1210
  });
1182
1211
  conn.close();
@@ -1207,7 +1236,7 @@ var ClientTransport = class extends Transport {
1207
1236
  });
1208
1237
  conn.addErrorListener((err) => {
1209
1238
  conn.telemetry?.span.setStatus({
1210
- code: import_api3.SpanStatusCode.ERROR,
1239
+ code: import_api4.SpanStatusCode.ERROR,
1211
1240
  message: "connection error"
1212
1241
  });
1213
1242
  this.log?.warn(
@@ -1225,7 +1254,7 @@ var ClientTransport = class extends Transport {
1225
1254
  const parsed = this.parseMsg(data, conn);
1226
1255
  if (!parsed) {
1227
1256
  conn.telemetry?.span.setStatus({
1228
- code: import_api3.SpanStatusCode.ERROR,
1257
+ code: import_api4.SpanStatusCode.ERROR,
1229
1258
  message: "non-transport message"
1230
1259
  });
1231
1260
  this.protocolError(
@@ -1234,9 +1263,9 @@ var ClientTransport = class extends Transport {
1234
1263
  );
1235
1264
  return false;
1236
1265
  }
1237
- if (!import_value.Value.Check(ControlMessageHandshakeResponseSchema, parsed.payload)) {
1266
+ if (!import_value2.Value.Check(ControlMessageHandshakeResponseSchema, parsed.payload)) {
1238
1267
  conn.telemetry?.span.setStatus({
1239
- code: import_api3.SpanStatusCode.ERROR,
1268
+ code: import_api4.SpanStatusCode.ERROR,
1240
1269
  message: "invalid handshake response"
1241
1270
  });
1242
1271
  this.log?.warn(`received invalid handshake resp`, {
@@ -1245,7 +1274,7 @@ var ClientTransport = class extends Transport {
1245
1274
  connectedTo: parsed.from,
1246
1275
  transportMessage: parsed,
1247
1276
  validationErrors: [
1248
- ...import_value.Value.Errors(
1277
+ ...import_value2.Value.Errors(
1249
1278
  ControlMessageHandshakeResponseSchema,
1250
1279
  parsed.payload
1251
1280
  )
@@ -1259,7 +1288,7 @@ var ClientTransport = class extends Transport {
1259
1288
  }
1260
1289
  if (!parsed.payload.status.ok) {
1261
1290
  conn.telemetry?.span.setStatus({
1262
- code: import_api3.SpanStatusCode.ERROR,
1291
+ code: import_api4.SpanStatusCode.ERROR,
1263
1292
  message: "handshake rejected"
1264
1293
  });
1265
1294
  this.log?.warn(`received handshake rejection`, {
@@ -1274,18 +1303,37 @@ var ClientTransport = class extends Transport {
1274
1303
  );
1275
1304
  return false;
1276
1305
  }
1306
+ const previousSession = this.sessions.get(parsed.from);
1307
+ if (previousSession?.advertisedSessionId && previousSession.advertisedSessionId !== parsed.payload.status.sessionId) {
1308
+ this.deleteSession({
1309
+ session: previousSession,
1310
+ closeHandshakingConnection: true
1311
+ });
1312
+ conn.telemetry?.span.setStatus({
1313
+ code: import_api4.SpanStatusCode.ERROR,
1314
+ message: "session id mismatch"
1315
+ });
1316
+ this.log?.warn(`handshake from ${parsed.from} session id mismatch`, {
1317
+ ...conn.loggingMetadata,
1318
+ clientId: this.clientId,
1319
+ connectedTo: parsed.from,
1320
+ transportMessage: parsed
1321
+ });
1322
+ this.protocolError(ProtocolError.HandshakeFailed, "session id mismatch");
1323
+ return false;
1324
+ }
1277
1325
  this.log?.debug(`handshake from ${parsed.from} ok`, {
1278
1326
  ...conn.loggingMetadata,
1279
1327
  clientId: this.clientId,
1280
1328
  connectedTo: parsed.from,
1281
1329
  transportMessage: parsed
1282
1330
  });
1283
- const { session, isReconnect } = this.getOrCreateSession({
1331
+ const { session, isTransparentReconnect } = this.getOrCreateSession({
1284
1332
  to: parsed.from,
1285
1333
  conn,
1286
1334
  sessionId: parsed.payload.status.sessionId
1287
1335
  });
1288
- this.onConnect(conn, session, isReconnect);
1336
+ this.onConnect(conn, session, isTransparentReconnect);
1289
1337
  this.retryBudget.startRestoringBudget(session.to);
1290
1338
  return session;
1291
1339
  }
@@ -1362,7 +1410,7 @@ var ClientTransport = class extends Transport {
1362
1410
  } catch (err) {
1363
1411
  const errStr = coerceErrorString(err);
1364
1412
  span.recordException(errStr);
1365
- span.setStatus({ code: import_api3.SpanStatusCode.ERROR });
1413
+ span.setStatus({ code: import_api4.SpanStatusCode.ERROR });
1366
1414
  throw err;
1367
1415
  } finally {
1368
1416
  span.end();
@@ -1413,13 +1461,13 @@ var ClientTransport = class extends Transport {
1413
1461
  let metadata = void 0;
1414
1462
  if (this.handshakeExtensions) {
1415
1463
  metadata = await this.handshakeExtensions.construct();
1416
- if (!import_value.Value.Check(this.handshakeExtensions.schema, metadata)) {
1464
+ if (!import_value2.Value.Check(this.handshakeExtensions.schema, metadata)) {
1417
1465
  this.log?.error(`constructed handshake metadata did not match schema`, {
1418
1466
  ...conn.loggingMetadata,
1419
1467
  clientId: this.clientId,
1420
1468
  connectedTo: to,
1421
1469
  validationErrors: [
1422
- ...import_value.Value.Errors(this.handshakeExtensions.schema, metadata)
1470
+ ...import_value2.Value.Errors(this.handshakeExtensions.schema, metadata)
1423
1471
  ],
1424
1472
  tags: ["invariant-violation"]
1425
1473
  });
@@ -1428,7 +1476,7 @@ var ClientTransport = class extends Transport {
1428
1476
  "handshake metadata did not match schema"
1429
1477
  );
1430
1478
  conn.telemetry?.span.setStatus({
1431
- code: import_api3.SpanStatusCode.ERROR,
1479
+ code: import_api4.SpanStatusCode.ERROR,
1432
1480
  message: "handshake meta mismatch"
1433
1481
  });
1434
1482
  return false;