@replit/river 0.21.1 → 0.22.0

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 (63) hide show
  1. package/README.md +1 -1
  2. package/dist/{chunk-5WFL722S.js → chunk-3MFX6NXA.js} +94 -3
  3. package/dist/chunk-3MFX6NXA.js.map +1 -0
  4. package/dist/{chunk-NCXUFDVL.js → chunk-GCLEWC26.js} +328 -500
  5. package/dist/chunk-GCLEWC26.js.map +1 -0
  6. package/dist/chunk-HUBFYN37.js +60 -0
  7. package/dist/chunk-HUBFYN37.js.map +1 -0
  8. package/dist/{chunk-FDLAPYCK.js → chunk-S3YKQT4J.js} +2 -2
  9. package/dist/{chunk-JMXO5L2X.js → chunk-ZPBWKBM5.js} +344 -384
  10. package/dist/chunk-ZPBWKBM5.js.map +1 -0
  11. package/dist/{connection-76c5ed01.d.ts → connection-8b059ac4.d.ts} +6 -4
  12. package/dist/{connection-975b25c9.d.ts → connection-bbfe1147.d.ts} +1 -1
  13. package/dist/{index-dfad460e.d.ts → index-2ece5234.d.ts} +16 -7
  14. package/dist/logging/index.d.cts +2 -1
  15. package/dist/logging/index.d.ts +2 -1
  16. package/dist/router/index.cjs +373 -486
  17. package/dist/router/index.cjs.map +1 -1
  18. package/dist/router/index.d.cts +5 -4
  19. package/dist/router/index.d.ts +5 -4
  20. package/dist/router/index.js +4 -3
  21. package/dist/{services-7b716dcf.d.ts → services-acbcc441.d.ts} +1 -1
  22. package/dist/{services-9c496c6e.d.ts → services-cb01a7a8.d.ts} +1 -1
  23. package/dist/transport/impls/uds/client.cjs +186 -145
  24. package/dist/transport/impls/uds/client.cjs.map +1 -1
  25. package/dist/transport/impls/uds/client.d.cts +3 -2
  26. package/dist/transport/impls/uds/client.d.ts +3 -2
  27. package/dist/transport/impls/uds/client.js +3 -3
  28. package/dist/transport/impls/uds/server.cjs +281 -256
  29. package/dist/transport/impls/uds/server.cjs.map +1 -1
  30. package/dist/transport/impls/uds/server.d.cts +3 -2
  31. package/dist/transport/impls/uds/server.d.ts +3 -2
  32. package/dist/transport/impls/uds/server.js +3 -3
  33. package/dist/transport/impls/ws/client.cjs +240 -204
  34. package/dist/transport/impls/ws/client.cjs.map +1 -1
  35. package/dist/transport/impls/ws/client.d.cts +6 -6
  36. package/dist/transport/impls/ws/client.d.ts +6 -6
  37. package/dist/transport/impls/ws/client.js +33 -48
  38. package/dist/transport/impls/ws/client.js.map +1 -1
  39. package/dist/transport/impls/ws/server.cjs +303 -270
  40. package/dist/transport/impls/ws/server.cjs.map +1 -1
  41. package/dist/transport/impls/ws/server.d.cts +5 -4
  42. package/dist/transport/impls/ws/server.d.ts +5 -4
  43. package/dist/transport/impls/ws/server.js +3 -3
  44. package/dist/transport/impls/ws/server.js.map +1 -1
  45. package/dist/transport/index.cjs +390 -382
  46. package/dist/transport/index.cjs.map +1 -1
  47. package/dist/transport/index.d.cts +5 -5
  48. package/dist/transport/index.d.ts +5 -5
  49. package/dist/transport/index.js +2 -2
  50. package/dist/util/testHelpers.cjs +57 -7
  51. package/dist/util/testHelpers.cjs.map +1 -1
  52. package/dist/util/testHelpers.d.cts +14 -5
  53. package/dist/util/testHelpers.d.ts +14 -5
  54. package/dist/util/testHelpers.js +10 -4
  55. package/dist/util/testHelpers.js.map +1 -1
  56. package/dist/wslike-e0b32dd5.d.ts +40 -0
  57. package/package.json +4 -5
  58. package/dist/chunk-3Y7AB5EB.js +0 -42
  59. package/dist/chunk-3Y7AB5EB.js.map +0 -1
  60. package/dist/chunk-5WFL722S.js.map +0 -1
  61. package/dist/chunk-JMXO5L2X.js.map +0 -1
  62. package/dist/chunk-NCXUFDVL.js.map +0 -1
  63. /package/dist/{chunk-FDLAPYCK.js.map → chunk-S3YKQT4J.js.map} +0 -0
@@ -1,10 +1,11 @@
1
- import { A as AnyServiceSchemaMap, I as InstantiatedServiceSchemaMap, P as PayloadType, b as Result, R as RiverError, S as ServiceContext } from '../services-7b716dcf.js';
2
- export { C as Client, E as Err, O as Ok, B as Output, k as ProcErrors, g as ProcHandler, h as ProcInit, i as ProcInput, j as ProcOutput, l as ProcType, a as Procedure, o as ProcedureMap, d as ProcedureResult, p as RPCProcedure, z as ResultUnwrapErr, y as ResultUnwrapOk, x as RiverErrorSchema, c as RiverUncaughtSchema, n as SerializedServerSchema, e as Service, f as ServiceConfiguration, u as ServiceContextWithState, v as ServiceContextWithTransportInfo, m as ServiceSchema, r as StreamProcedure, q as SubscriptionProcedure, w as UNCAUGHT_ERROR, U as UploadProcedure, V as ValidProcType, t as createClient, s as serializeSchema } from '../services-7b716dcf.js';
1
+ import { A as AnyServiceSchemaMap, I as InstantiatedServiceSchemaMap, P as PayloadType, b as Result, R as RiverError, S as ServiceContext } from '../services-acbcc441.js';
2
+ export { C as Client, E as Err, O as Ok, B as Output, k as ProcErrors, g as ProcHandler, h as ProcInit, i as ProcInput, j as ProcOutput, l as ProcType, a as Procedure, o as ProcedureMap, d as ProcedureResult, p as RPCProcedure, z as ResultUnwrapErr, y as ResultUnwrapOk, x as RiverErrorSchema, c as RiverUncaughtSchema, n as SerializedServerSchema, e as Service, f as ServiceConfiguration, u as ServiceContextWithState, v as ServiceContextWithTransportInfo, m as ServiceSchema, r as StreamProcedure, q as SubscriptionProcedure, w as UNCAUGHT_ERROR, U as UploadProcedure, V as ValidProcType, t as createClient, s as serializeSchema } from '../services-acbcc441.js';
3
3
  import { Static } from '@sinclair/typebox';
4
4
  import { ServerTransport } from '../transport/index.cjs';
5
5
  import { Pushable } from 'it-pushable';
6
- import { C as Connection } from '../index-dfad460e.js';
6
+ import { C as Connection } from '../index-2ece5234.js';
7
7
  import '../types-3e5768ec.js';
8
+ import '@opentelemetry/api';
8
9
 
9
10
  /**
10
11
  * Represents a server with a set of services. Use {@link createServer} to create it.
@@ -36,6 +37,6 @@ interface ProcStream {
36
37
  */
37
38
  declare function createServer<Services extends AnyServiceSchemaMap>(transport: ServerTransport<Connection>, services: Services, extendedContext?: Omit<ServiceContext, 'state'>): Server<Services>;
38
39
 
39
- var version = "0.21.1";
40
+ var version = "0.22.0";
40
41
 
41
42
  export { PayloadType, version as RIVER_VERSION, Result, RiverError, Server, ServiceContext, createServer };
@@ -1,10 +1,11 @@
1
- import { A as AnyServiceSchemaMap, I as InstantiatedServiceSchemaMap, P as PayloadType, b as Result, R as RiverError, S as ServiceContext } from '../services-9c496c6e.js';
2
- export { C as Client, E as Err, O as Ok, B as Output, k as ProcErrors, g as ProcHandler, h as ProcInit, i as ProcInput, j as ProcOutput, l as ProcType, a as Procedure, o as ProcedureMap, d as ProcedureResult, p as RPCProcedure, z as ResultUnwrapErr, y as ResultUnwrapOk, x as RiverErrorSchema, c as RiverUncaughtSchema, n as SerializedServerSchema, e as Service, f as ServiceConfiguration, u as ServiceContextWithState, v as ServiceContextWithTransportInfo, m as ServiceSchema, r as StreamProcedure, q as SubscriptionProcedure, w as UNCAUGHT_ERROR, U as UploadProcedure, V as ValidProcType, t as createClient, s as serializeSchema } from '../services-9c496c6e.js';
1
+ import { A as AnyServiceSchemaMap, I as InstantiatedServiceSchemaMap, P as PayloadType, b as Result, R as RiverError, S as ServiceContext } from '../services-cb01a7a8.js';
2
+ export { C as Client, E as Err, O as Ok, B as Output, k as ProcErrors, g as ProcHandler, h as ProcInit, i as ProcInput, j as ProcOutput, l as ProcType, a as Procedure, o as ProcedureMap, d as ProcedureResult, p as RPCProcedure, z as ResultUnwrapErr, y as ResultUnwrapOk, x as RiverErrorSchema, c as RiverUncaughtSchema, n as SerializedServerSchema, e as Service, f as ServiceConfiguration, u as ServiceContextWithState, v as ServiceContextWithTransportInfo, m as ServiceSchema, r as StreamProcedure, q as SubscriptionProcedure, w as UNCAUGHT_ERROR, U as UploadProcedure, V as ValidProcType, t as createClient, s as serializeSchema } from '../services-cb01a7a8.js';
3
3
  import { Static } from '@sinclair/typebox';
4
4
  import { ServerTransport } from '../transport/index.js';
5
5
  import { Pushable } from 'it-pushable';
6
- import { C as Connection } from '../index-dfad460e.js';
6
+ import { C as Connection } from '../index-2ece5234.js';
7
7
  import '../types-3e5768ec.js';
8
+ import '@opentelemetry/api';
8
9
 
9
10
  /**
10
11
  * Represents a server with a set of services. Use {@link createServer} to create it.
@@ -36,6 +37,6 @@ interface ProcStream {
36
37
  */
37
38
  declare function createServer<Services extends AnyServiceSchemaMap>(transport: ServerTransport<Connection>, services: Services, extendedContext?: Omit<ServiceContext, 'state'>): Server<Services>;
38
39
 
39
- var version = "0.21.1";
40
+ var version = "0.22.0";
40
41
 
41
42
  export { PayloadType, version as RIVER_VERSION, Result, RiverError, Server, ServiceContext, createServer };
@@ -7,10 +7,11 @@ import {
7
7
  UNCAUGHT_ERROR,
8
8
  createClient,
9
9
  createServer,
10
- serializeSchema,
10
+ serializeSchema
11
+ } from "../chunk-GCLEWC26.js";
12
+ import {
11
13
  version
12
- } from "../chunk-NCXUFDVL.js";
13
- import "../chunk-5WFL722S.js";
14
+ } from "../chunk-3MFX6NXA.js";
14
15
  import "../chunk-OTQNCLFH.js";
15
16
  export {
16
17
  Err,
@@ -1,7 +1,7 @@
1
1
  import { Static, TObject, TUnion, TString, TSchema, TNever, TLiteral } from '@sinclair/typebox';
2
2
  import { ClientTransport } from './transport/index.cjs';
3
3
  import { Pushable } from 'it-pushable';
4
- import { C as Connection, T as TransportClientId, a as Session, b as ParsedHandshakeMetadata } from './index-dfad460e.js';
4
+ import { C as Connection, T as TransportClientId, a as Session, b as ParsedHandshakeMetadata } from './index-2ece5234.js';
5
5
 
6
6
  type AsyncIter<T> = AsyncGenerator<T, T>;
7
7
  /**
@@ -1,7 +1,7 @@
1
1
  import { Static, TObject, TUnion, TString, TSchema, TNever, TLiteral } from '@sinclair/typebox';
2
2
  import { ClientTransport } from './transport/index.js';
3
3
  import { Pushable } from 'it-pushable';
4
- import { C as Connection, T as TransportClientId, a as Session, b as ParsedHandshakeMetadata } from './index-dfad460e.js';
4
+ import { C as Connection, T as TransportClientId, a as Session, b as ParsedHandshakeMetadata } from './index-2ece5234.js';
5
5
 
6
6
  type AsyncIter<T> = AsyncGenerator<T, T>;
7
7
  /**
@@ -109,18 +109,70 @@ function isAck(controlFlag) {
109
109
  return (controlFlag & 1 /* AckBit */) === 1 /* AckBit */;
110
110
  }
111
111
 
112
+ // tracing/index.ts
113
+ var import_api = require("@opentelemetry/api");
114
+
115
+ // package.json
116
+ var version = "0.22.0";
117
+
118
+ // tracing/index.ts
119
+ function getPropagationContext(ctx) {
120
+ const tracing = {
121
+ traceparent: "",
122
+ tracestate: ""
123
+ };
124
+ import_api.propagation.inject(ctx, tracing);
125
+ return tracing;
126
+ }
127
+ function createSessionTelemetryInfo(session, propagationCtx) {
128
+ const ctx = propagationCtx ? import_api.propagation.extract(import_api.context.active(), propagationCtx) : import_api.context.active();
129
+ const span = tracer.startSpan(
130
+ `session ${session.id}`,
131
+ {
132
+ attributes: {
133
+ component: "river",
134
+ "river.session.id": session.id,
135
+ "river.session.to": session.to,
136
+ "river.session.from": session.from
137
+ }
138
+ },
139
+ ctx
140
+ );
141
+ return { span, ctx };
142
+ }
143
+ function createConnectionTelemetryInfo(connection, sessionSpan) {
144
+ const ctx = import_api.trace.setSpan(import_api.context.active(), sessionSpan);
145
+ const span = tracer.startSpan(
146
+ `connection ${connection.id}`,
147
+ {
148
+ attributes: {
149
+ component: "river",
150
+ "river.connection.id": connection.id
151
+ },
152
+ links: [{ context: sessionSpan.spanContext() }]
153
+ },
154
+ ctx
155
+ );
156
+ return { span, ctx };
157
+ }
158
+ var tracer = import_api.trace.getTracer("river", version);
159
+ var tracing_default = tracer;
160
+
112
161
  // transport/session.ts
162
+ var import_api2 = require("@opentelemetry/api");
113
163
  var nanoid2 = (0, import_nanoid2.customAlphabet)("1234567890abcdefghijklmnopqrstuvxyz", 6);
114
164
  var unsafeId = () => nanoid2();
115
165
  var Connection = class {
116
- debugId;
166
+ id;
167
+ telemetry;
117
168
  constructor() {
118
- this.debugId = `conn-${unsafeId()}`;
169
+ this.id = `conn-${nanoid2(12)}`;
119
170
  }
120
171
  };
121
172
  var Session = class {
122
173
  codec;
123
174
  options;
175
+ telemetry;
124
176
  /**
125
177
  * The buffer of messages that have been sent but not yet acknowledged.
126
178
  */
@@ -167,7 +219,7 @@ var Session = class {
167
219
  * The interval for sending heartbeats.
168
220
  */
169
221
  heartbeat;
170
- constructor(conn, from, to, options) {
222
+ constructor(conn, from, to, options, propagationCtx) {
171
223
  this.id = `session-${nanoid2(12)}`;
172
224
  this.options = options;
173
225
  this.from = from;
@@ -179,13 +231,14 @@ var Session = class {
179
231
  () => this.sendHeartbeat(),
180
232
  options.heartbeatIntervalMs
181
233
  );
234
+ this.telemetry = createSessionTelemetryInfo(this, propagationCtx);
182
235
  }
183
236
  get loggingMetadata() {
184
237
  return {
185
238
  clientId: this.from,
186
239
  connectedTo: this.to,
187
240
  sessionId: this.id,
188
- connId: this.connection?.debugId
241
+ connId: this.connection?.id
189
242
  };
190
243
  }
191
244
  /**
@@ -230,6 +283,7 @@ var Session = class {
230
283
  `closing connection to ${this.to} due to inactivity (missed ${misses} heartbeats which is ${missDuration}ms)`,
231
284
  this.loggingMetadata
232
285
  );
286
+ this.telemetry.span.addEvent("closing connection due to inactivity");
233
287
  this.closeStaleConnection();
234
288
  }
235
289
  return;
@@ -251,21 +305,25 @@ var Session = class {
251
305
  sendBufferedMessages(conn) {
252
306
  log?.info(`resending ${this.sendBuffer.length} buffered messages`, {
253
307
  ...this.loggingMetadata,
254
- connId: conn.debugId
308
+ connId: conn.id
255
309
  });
256
310
  for (const msg of this.sendBuffer) {
257
311
  log?.debug(`resending msg`, {
258
312
  ...this.loggingMetadata,
259
313
  fullTransportMessage: msg,
260
- connId: conn.debugId
314
+ connId: conn.id
261
315
  });
262
316
  const ok = conn.send(this.codec.toBuffer(msg));
263
317
  if (!ok) {
264
318
  const errMsg = `failed to send buffered message to ${this.to} (sus, this is a fresh connection)`;
319
+ conn.telemetry?.span.setStatus({
320
+ code: import_api2.SpanStatusCode.ERROR,
321
+ message: errMsg
322
+ });
265
323
  log?.error(errMsg, {
266
324
  ...this.loggingMetadata,
267
325
  fullTransportMessage: msg,
268
- connId: conn.debugId,
326
+ connId: conn.id,
269
327
  tags: ["invariant-violation"]
270
328
  });
271
329
  conn.close();
@@ -448,7 +506,6 @@ var UdsConnection = class extends Connection {
448
506
 
449
507
  // transport/transport.ts
450
508
  var import_value = require("@sinclair/typebox/value");
451
- var import_api2 = require("@opentelemetry/api");
452
509
 
453
510
  // transport/events.ts
454
511
  var ProtocolError = {
@@ -484,11 +541,6 @@ var EventDispatcher = class {
484
541
  }
485
542
  };
486
543
 
487
- // tracing/index.ts
488
- var import_api = require("@opentelemetry/api");
489
- var tracer = import_api.trace.getTracer("river");
490
- var tracing_default = tracer;
491
-
492
544
  // util/stringify.ts
493
545
  function coerceErrorString(err) {
494
546
  if (err instanceof Error) {
@@ -621,6 +673,7 @@ var NaiveJsonCodec = {
621
673
  };
622
674
 
623
675
  // transport/transport.ts
676
+ var import_api3 = require("@opentelemetry/api");
624
677
  var defaultTransportOptions = {
625
678
  heartbeatIntervalMs: 1e3,
626
679
  heartbeatsUntilDead: 2,
@@ -699,17 +752,22 @@ var Transport = class {
699
752
  status: "connect",
700
753
  conn
701
754
  });
755
+ conn.telemetry = createConnectionTelemetryInfo(
756
+ conn,
757
+ session.telemetry.span
758
+ );
702
759
  if (isReconnect) {
703
760
  session.replaceWithNewConnection(conn);
704
761
  log?.info(`reconnected to ${connectedTo}`, session.loggingMetadata);
705
762
  }
706
763
  }
707
- createSession(to, conn) {
764
+ createSession(to, conn, propagationCtx) {
708
765
  const session = new Session(
709
766
  conn,
710
767
  this.clientId,
711
768
  to,
712
- this.options
769
+ this.options,
770
+ propagationCtx
713
771
  );
714
772
  this.sessions.set(session.to, session);
715
773
  this.eventDispatcher.dispatchEvent("sessionStatus", {
@@ -718,11 +776,11 @@ var Transport = class {
718
776
  });
719
777
  return session;
720
778
  }
721
- getOrCreateSession(to, conn, sessionId) {
779
+ getOrCreateSession(to, conn, sessionId, propagationCtx) {
722
780
  let session = this.sessions.get(to);
723
781
  let isReconnect = session !== void 0;
724
782
  if (session?.advertisedSessionId !== void 0 && sessionId !== void 0 && session.advertisedSessionId !== sessionId) {
725
- log?.warn(
783
+ log?.info(
726
784
  `session for ${to} already exists but has a different session id (expected: ${session.advertisedSessionId}, got: ${sessionId}), creating a new one`,
727
785
  session.loggingMetadata
728
786
  );
@@ -731,7 +789,7 @@ var Transport = class {
731
789
  session = void 0;
732
790
  }
733
791
  if (!session) {
734
- session = this.createSession(to, conn);
792
+ session = this.createSession(to, conn, propagationCtx);
735
793
  log?.info(
736
794
  `no session for ${to}, created a new one`,
737
795
  session.loggingMetadata
@@ -744,6 +802,7 @@ var Transport = class {
744
802
  }
745
803
  deleteSession(session) {
746
804
  session.close();
805
+ session.telemetry.span.end();
747
806
  this.sessions.delete(session.to);
748
807
  log?.info(
749
808
  `session ${session.id} disconnect from ${session.to}`,
@@ -760,12 +819,16 @@ var Transport = class {
760
819
  * @param connectedTo The peer we are connected to.
761
820
  */
762
821
  onDisconnect(conn, session) {
822
+ conn.telemetry?.span.end();
763
823
  this.eventDispatcher.dispatchEvent("connectionStatus", {
764
824
  status: "disconnect",
765
825
  conn
766
826
  });
767
827
  session.connection = void 0;
768
- session.beginGrace(() => this.deleteSession(session));
828
+ session.beginGrace(() => {
829
+ session.telemetry.span.addEvent("session grace period expired");
830
+ this.deleteSession(session);
831
+ });
769
832
  }
770
833
  /**
771
834
  * Parses a message from a Uint8Array into a {@link OpaqueTransportMessage}.
@@ -825,6 +888,10 @@ var Transport = class {
825
888
  tags: ["invariant-violation"]
826
889
  });
827
890
  this.protocolError(ProtocolError.MessageOrderingViolated, errMsg);
891
+ session.telemetry.span.setStatus({
892
+ code: import_api3.SpanStatusCode.ERROR,
893
+ message: "message order violated"
894
+ });
828
895
  session.close();
829
896
  }
830
897
  return;
@@ -952,7 +1019,7 @@ var ClientTransport = class extends Transport {
952
1019
  if (!session) {
953
1020
  log?.warn(
954
1021
  `connection to ${to} timed out waiting for handshake, closing`,
955
- { clientId: this.clientId, connectedTo: to, connId: conn.debugId }
1022
+ { clientId: this.clientId, connectedTo: to, connId: conn.id }
956
1023
  );
957
1024
  conn.close();
958
1025
  }
@@ -970,6 +1037,10 @@ var ClientTransport = class extends Transport {
970
1037
  conn.addDataListener((data2) => {
971
1038
  const parsed = this.parseMsg(data2);
972
1039
  if (!parsed) {
1040
+ conn.telemetry?.span.setStatus({
1041
+ code: import_api3.SpanStatusCode.ERROR,
1042
+ message: "message parse failure"
1043
+ });
973
1044
  conn.close();
974
1045
  return;
975
1046
  }
@@ -992,6 +1063,10 @@ var ClientTransport = class extends Transport {
992
1063
  }
993
1064
  });
994
1065
  conn.addErrorListener((err) => {
1066
+ conn.telemetry?.span.setStatus({
1067
+ code: import_api3.SpanStatusCode.ERROR,
1068
+ message: "connection error"
1069
+ });
995
1070
  log?.warn(`error in connection to ${to}: ${coerceErrorString(err)}`, {
996
1071
  ...session?.loggingMetadata,
997
1072
  clientId: this.clientId,
@@ -1002,6 +1077,10 @@ var ClientTransport = class extends Transport {
1002
1077
  receiveHandshakeResponseMessage(data, conn) {
1003
1078
  const parsed = this.parseMsg(data);
1004
1079
  if (!parsed) {
1080
+ conn.telemetry?.span.setStatus({
1081
+ code: import_api3.SpanStatusCode.ERROR,
1082
+ message: "non-transport message"
1083
+ });
1005
1084
  this.protocolError(
1006
1085
  ProtocolError.HandshakeFailed,
1007
1086
  "received non-transport message"
@@ -1009,6 +1088,10 @@ var ClientTransport = class extends Transport {
1009
1088
  return false;
1010
1089
  }
1011
1090
  if (!import_value.Value.Check(ControlMessageHandshakeResponseSchema, parsed.payload)) {
1091
+ conn.telemetry?.span.setStatus({
1092
+ code: import_api3.SpanStatusCode.ERROR,
1093
+ message: "invalid handshake response"
1094
+ });
1012
1095
  log?.warn(`received invalid handshake resp`, {
1013
1096
  clientId: this.clientId,
1014
1097
  connectedTo: parsed.from,
@@ -1021,7 +1104,11 @@ var ClientTransport = class extends Transport {
1021
1104
  return false;
1022
1105
  }
1023
1106
  if (!parsed.payload.status.ok) {
1024
- log?.warn(`received invalid handshake resp`, {
1107
+ conn.telemetry?.span.setStatus({
1108
+ code: import_api3.SpanStatusCode.ERROR,
1109
+ message: "handshake rejected"
1110
+ });
1111
+ log?.warn(`received handshake rejection`, {
1025
1112
  clientId: this.clientId,
1026
1113
  connectedTo: parsed.from,
1027
1114
  fullTransportMessage: parsed
@@ -1051,142 +1138,94 @@ var ClientTransport = class extends Transport {
1051
1138
  * @param to The client ID of the node to connect to.
1052
1139
  */
1053
1140
  async connect(to) {
1054
- return tracing_default.startActiveSpan(
1055
- "connect",
1056
- {
1057
- attributes: {
1058
- component: "river",
1059
- "span.kind": "client"
1060
- },
1061
- kind: import_api2.SpanKind.CLIENT
1062
- },
1063
- async (span) => {
1064
- try {
1065
- await this.connectAttempt(to);
1066
- } catch (e) {
1067
- if (e instanceof Error) {
1068
- span.recordException(e);
1069
- } else {
1070
- span.recordException(coerceErrorString(e));
1071
- }
1072
- span.setStatus({ code: import_api2.SpanStatusCode.ERROR });
1073
- } finally {
1074
- span.end();
1075
- }
1141
+ const canProceedWithConnection = () => this.state === "open";
1142
+ if (!canProceedWithConnection()) {
1143
+ log?.info(
1144
+ `transport state is no longer open, cancelling attempt to connect to ${to}`,
1145
+ { clientId: this.clientId, connectedTo: to }
1146
+ );
1147
+ return;
1148
+ }
1149
+ let reconnectPromise = this.inflightConnectionPromises.get(to);
1150
+ if (!reconnectPromise) {
1151
+ const budgetConsumed = this.retryBudget.getBudgetConsumed(to);
1152
+ if (!this.retryBudget.hasBudget(to)) {
1153
+ const errMsg = `tried to connect to ${to} but retry budget exceeded (more than ${budgetConsumed} attempts in the last ${this.retryBudget.totalBudgetRestoreTime}ms)`;
1154
+ log?.warn(errMsg, { clientId: this.clientId, connectedTo: to });
1155
+ this.protocolError(ProtocolError.RetriesExceeded, errMsg);
1156
+ return;
1076
1157
  }
1077
- );
1078
- }
1079
- async connectAttempt(to, attempt = 0) {
1080
- const retry = await tracing_default.startActiveSpan(
1081
- "connect",
1082
- {
1083
- attributes: {
1084
- component: "river",
1085
- "river.attempt": attempt,
1086
- "span.kind": "client"
1087
- },
1088
- kind: import_api2.SpanKind.CLIENT
1089
- },
1090
- async (span) => {
1158
+ let sleep = Promise.resolve();
1159
+ const backoffMs = this.retryBudget.getBackoffMs(to);
1160
+ if (backoffMs > 0) {
1161
+ sleep = new Promise((resolve) => setTimeout(resolve, backoffMs));
1162
+ }
1163
+ log?.info(`attempting connection to ${to} (${backoffMs}ms backoff)`, {
1164
+ clientId: this.clientId,
1165
+ connectedTo: to
1166
+ });
1167
+ this.retryBudget.consumeBudget(to);
1168
+ reconnectPromise = tracing_default.startActiveSpan("connect", async (span) => {
1091
1169
  try {
1092
- const canProceedWithConnection = () => this.state === "open";
1170
+ span.addEvent("backoff", { backoffMs });
1171
+ await sleep;
1093
1172
  if (!canProceedWithConnection()) {
1094
- log?.info(
1095
- `transport state is no longer open, cancelling attempt to connect to ${to}`,
1096
- { clientId: this.clientId, connectedTo: to }
1097
- );
1098
- return false;
1173
+ throw new Error("transport state is no longer open");
1099
1174
  }
1100
- let reconnectPromise = this.inflightConnectionPromises.get(to);
1101
- if (!reconnectPromise) {
1102
- const budgetConsumed = this.retryBudget.getBudgetConsumed(to);
1103
- if (!this.retryBudget.hasBudget(to)) {
1104
- const errMsg = `tried to connect to ${to} but retry budget exceeded (more than ${budgetConsumed} attempts in the last ${this.retryBudget.totalBudgetRestoreTime}ms)`;
1105
- log?.warn(errMsg, { clientId: this.clientId, connectedTo: to });
1106
- this.protocolError(ProtocolError.RetriesExceeded, errMsg);
1107
- return false;
1108
- }
1109
- let sleep = Promise.resolve();
1110
- const backoffMs = this.retryBudget.getBackoffMs(to);
1111
- if (backoffMs > 0) {
1112
- sleep = new Promise((resolve) => setTimeout(resolve, backoffMs));
1113
- }
1114
- log?.info(
1115
- `attempting connection to ${to} (${backoffMs}ms backoff)`,
1116
- {
1117
- clientId: this.clientId,
1118
- connectedTo: to
1119
- }
1120
- );
1121
- this.retryBudget.consumeBudget(to);
1122
- reconnectPromise = sleep.then(() => {
1123
- if (!canProceedWithConnection()) {
1124
- throw new Error("transport state is no longer open");
1125
- }
1126
- }).then(() => this.createNewOutgoingConnection(to)).then((conn) => {
1127
- if (!canProceedWithConnection()) {
1128
- log?.info(
1129
- `transport state is no longer open, closing pre-handshake connection to ${to}`,
1130
- {
1131
- clientId: this.clientId,
1132
- connectedTo: to,
1133
- connId: conn.debugId
1134
- }
1135
- );
1136
- conn.close();
1137
- throw new Error("transport state is no longer open");
1138
- }
1139
- return this.sendHandshake(to, conn).then((ok) => {
1140
- if (!ok) {
1141
- conn.close();
1142
- throw new Error("failed to send handshake");
1143
- }
1144
- return conn;
1145
- });
1146
- });
1147
- this.inflightConnectionPromises.set(to, reconnectPromise);
1148
- } else {
1175
+ span.addEvent("connecting");
1176
+ const conn = await this.createNewOutgoingConnection(to);
1177
+ if (!canProceedWithConnection()) {
1149
1178
  log?.info(
1150
- `attempting connection to ${to} (reusing previous attempt)`,
1179
+ `transport state is no longer open, closing pre-handshake connection to ${to}`,
1151
1180
  {
1152
1181
  clientId: this.clientId,
1153
- connectedTo: to
1182
+ connectedTo: to,
1183
+ connId: conn.id
1154
1184
  }
1155
1185
  );
1186
+ conn.close();
1187
+ throw new Error("transport state is no longer open");
1156
1188
  }
1157
- try {
1158
- await reconnectPromise;
1159
- } catch (error) {
1160
- this.inflightConnectionPromises.delete(to);
1161
- const errStr = coerceErrorString(error);
1162
- if (!this.reconnectOnConnectionDrop || !canProceedWithConnection()) {
1163
- log?.warn(`connection to ${to} failed (${errStr})`, {
1164
- clientId: this.clientId,
1165
- connectedTo: to
1166
- });
1167
- } else {
1168
- log?.warn(`connection to ${to} failed (${errStr}), retrying`, {
1169
- clientId: this.clientId,
1170
- connectedTo: to
1171
- });
1172
- return true;
1173
- }
1189
+ span.addEvent("sending handshake");
1190
+ const ok = await this.sendHandshake(to, conn);
1191
+ if (!ok) {
1192
+ conn.close();
1193
+ throw new Error("failed to send handshake");
1174
1194
  }
1175
- } catch (e) {
1176
- if (e instanceof Error) {
1177
- span.recordException(e);
1178
- } else {
1179
- span.recordException(coerceErrorString(e));
1180
- }
1181
- span.setStatus({ code: import_api2.SpanStatusCode.ERROR });
1195
+ return conn;
1196
+ } catch (err) {
1197
+ const errStr = coerceErrorString(err);
1198
+ span.recordException(errStr);
1199
+ span.setStatus({ code: import_api3.SpanStatusCode.ERROR });
1200
+ throw err;
1182
1201
  } finally {
1183
1202
  span.end();
1184
1203
  }
1185
- return false;
1204
+ });
1205
+ this.inflightConnectionPromises.set(to, reconnectPromise);
1206
+ } else {
1207
+ log?.info(`attempting connection to ${to} (reusing previous attempt)`, {
1208
+ clientId: this.clientId,
1209
+ connectedTo: to
1210
+ });
1211
+ }
1212
+ try {
1213
+ await reconnectPromise;
1214
+ } catch (error) {
1215
+ this.inflightConnectionPromises.delete(to);
1216
+ const errStr = coerceErrorString(error);
1217
+ if (!this.reconnectOnConnectionDrop || !canProceedWithConnection()) {
1218
+ log?.warn(`connection to ${to} failed (${errStr})`, {
1219
+ clientId: this.clientId,
1220
+ connectedTo: to
1221
+ });
1222
+ } else {
1223
+ log?.warn(`connection to ${to} failed (${errStr}), retrying`, {
1224
+ clientId: this.clientId,
1225
+ connectedTo: to
1226
+ });
1227
+ return this.connect(to);
1186
1228
  }
1187
- );
1188
- if (retry) {
1189
- return this.connectAttempt(to, attempt + 1);
1190
1229
  }
1191
1230
  }
1192
1231
  deleteSession(session) {
@@ -1194,8 +1233,6 @@ var ClientTransport = class extends Transport {
1194
1233
  super.deleteSession(session);
1195
1234
  }
1196
1235
  async sendHandshake(to, conn) {
1197
- const tracing = { traceparent: "", tracestate: "" };
1198
- import_api2.propagation.inject(import_api2.context.active(), tracing);
1199
1236
  let metadata;
1200
1237
  if (this.options.handshake) {
1201
1238
  metadata = await this.options.handshake.get();
@@ -1209,6 +1246,10 @@ var ClientTransport = class extends Transport {
1209
1246
  ProtocolError.HandshakeFailed,
1210
1247
  "handshake metadata did not match schema"
1211
1248
  );
1249
+ conn.telemetry?.span.setStatus({
1250
+ code: import_api3.SpanStatusCode.ERROR,
1251
+ message: "handshake meta mismatch"
1252
+ });
1212
1253
  return false;
1213
1254
  }
1214
1255
  }
@@ -1218,7 +1259,7 @@ var ClientTransport = class extends Transport {
1218
1259
  to,
1219
1260
  session.id,
1220
1261
  metadata,
1221
- tracing
1262
+ getPropagationContext(session.telemetry.ctx)
1222
1263
  );
1223
1264
  log?.debug(`sending handshake request to ${to}`, {
1224
1265
  clientId: this.clientId,