@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
@@ -162,11 +162,13 @@ var createLogProxy = (log) => ({
162
162
  var ProtocolError = {
163
163
  RetriesExceeded: "conn_retry_exceeded",
164
164
  HandshakeFailed: "handshake_failed",
165
- UseAfterDestroy: "use_after_destroy",
166
165
  MessageOrderingViolated: "message_ordering_violated"
167
166
  };
168
167
  var EventDispatcher = class {
169
168
  eventListeners = {};
169
+ removeAllListeners() {
170
+ this.eventListeners = {};
171
+ }
170
172
  numberOfListeners(eventType) {
171
173
  return this.eventListeners[eventType]?.size ?? 0;
172
174
  }
@@ -185,7 +187,8 @@ var EventDispatcher = class {
185
187
  dispatchEvent(eventType, event) {
186
188
  const handlers = this.eventListeners[eventType];
187
189
  if (handlers) {
188
- for (const handler of handlers) {
190
+ const copy = [...handlers];
191
+ for (const handler of copy) {
189
192
  handler(event);
190
193
  }
191
194
  }
@@ -199,7 +202,7 @@ var import_nanoid2 = require("nanoid");
199
202
  var import_api = require("@opentelemetry/api");
200
203
 
201
204
  // package.json
202
- var version = "0.23.8";
205
+ var version = "0.23.10";
203
206
 
204
207
  // tracing/index.ts
205
208
  function getPropagationContext(ctx) {
@@ -258,7 +261,7 @@ var Connection = class {
258
261
  get loggingMetadata() {
259
262
  const metadata = { connId: this.id };
260
263
  const spanContext = this.telemetry?.span.spanContext();
261
- if (spanContext) {
264
+ if (this.telemetry?.span.isRecording() && spanContext) {
262
265
  metadata.telemetry = {
263
266
  traceId: spanContext.traceId,
264
267
  spanId: spanContext.spanId
@@ -279,6 +282,11 @@ var Session = class {
279
282
  * The active connection associated with this session
280
283
  */
281
284
  connection;
285
+ /**
286
+ * A connection that is currently undergoing handshaking. Used to distinguish between the active
287
+ * connection, but still be able to close it if needed.
288
+ */
289
+ handshakingConnection;
282
290
  from;
283
291
  to;
284
292
  /**
@@ -458,23 +466,60 @@ var Session = class {
458
466
  this.cancelGrace();
459
467
  this.sendBufferedMessages(newConn);
460
468
  this.connection = newConn;
469
+ this.handshakingConnection = void 0;
470
+ }
471
+ replaceWithNewHandshakingConnection(newConn) {
472
+ this.handshakingConnection = newConn;
461
473
  }
462
474
  beginGrace(cb) {
463
475
  this.log?.info(
464
476
  `starting ${this.options.sessionDisconnectGraceMs}ms grace period until session to ${this.to} is closed`,
465
477
  this.loggingMetadata
466
478
  );
479
+ this.cancelGrace({ keepHeartbeatMisses: true });
467
480
  this.disconnectionGrace = setTimeout(() => {
468
- this.close();
481
+ if (this.connection !== void 0) {
482
+ this.log?.warn(
483
+ `grace period for ${this.to} elapsed while connected. not calling callback`,
484
+ {
485
+ ...this.loggingMetadata,
486
+ connId: this.connection.id,
487
+ tags: ["invariant-violation"]
488
+ }
489
+ );
490
+ return;
491
+ }
492
+ this.log?.info(
493
+ `grace period for ${this.to} elapsed`,
494
+ this.loggingMetadata
495
+ );
469
496
  cb();
470
497
  }, this.options.sessionDisconnectGraceMs);
471
498
  }
472
499
  // called on reconnect of the underlying session
473
- cancelGrace() {
474
- this.heartbeatMisses = 0;
500
+ cancelGrace({ keepHeartbeatMisses } = {
501
+ keepHeartbeatMisses: false
502
+ }) {
503
+ if (!keepHeartbeatMisses) {
504
+ this.heartbeatMisses = 0;
505
+ }
506
+ if (this.disconnectionGrace === void 0)
507
+ return;
475
508
  clearTimeout(this.disconnectionGrace);
476
509
  this.disconnectionGrace = void 0;
477
510
  }
511
+ /**
512
+ * Used to close the handshaking connection, if set.
513
+ */
514
+ closeHandshakingConnection(expectedHandshakingConn) {
515
+ if (this.handshakingConnection === void 0)
516
+ return;
517
+ if (expectedHandshakingConn !== void 0 && this.handshakingConnection === expectedHandshakingConn) {
518
+ return;
519
+ }
520
+ this.handshakingConnection.close();
521
+ this.handshakingConnection = void 0;
522
+ }
478
523
  // closed when we want to discard the whole session
479
524
  // (i.e. shutdown or session disconnect)
480
525
  close() {
@@ -662,10 +707,9 @@ var defaultServerTransportOptions = {
662
707
  };
663
708
  var Transport = class {
664
709
  /**
665
- * A flag indicating whether the transport has been destroyed.
666
- * A destroyed transport will not attempt to reconnect and cannot be used again.
710
+ * The status of the transport.
667
711
  */
668
- state;
712
+ status;
669
713
  /**
670
714
  * The {@link Codec} used to encode and decode messages.
671
715
  */
@@ -707,7 +751,7 @@ var Transport = class {
707
751
  this.sessions = /* @__PURE__ */ new Map();
708
752
  this.codec = this.options.codec;
709
753
  this.clientId = clientId;
710
- this.state = "open";
754
+ this.status = "open";
711
755
  }
712
756
  bindLogger(fn, level) {
713
757
  if (typeof fn === "function") {
@@ -755,7 +799,13 @@ var Transport = class {
755
799
  });
756
800
  return session;
757
801
  }
758
- getOrCreateSession(to, conn, sessionId, propagationCtx) {
802
+ getOrCreateSession({
803
+ to,
804
+ conn,
805
+ handshakingConn,
806
+ sessionId,
807
+ propagationCtx
808
+ }) {
759
809
  let session = this.sessions.get(to);
760
810
  let isReconnect = session !== void 0;
761
811
  if (session?.advertisedSessionId !== void 0 && sessionId !== void 0 && session.advertisedSessionId !== sessionId) {
@@ -763,7 +813,11 @@ var Transport = class {
763
813
  `session for ${to} already exists but has a different session id (expected: ${session.advertisedSessionId}, got: ${sessionId}), creating a new one`,
764
814
  session.loggingMetadata
765
815
  );
766
- this.deleteSession(session);
816
+ this.deleteSession({
817
+ session,
818
+ closeHandshakingConnection: handshakingConn !== void 0,
819
+ handshakingConn
820
+ });
767
821
  isReconnect = false;
768
822
  session = void 0;
769
823
  }
@@ -777,9 +831,19 @@ var Transport = class {
777
831
  if (sessionId !== void 0) {
778
832
  session.advertisedSessionId = sessionId;
779
833
  }
834
+ if (handshakingConn !== void 0) {
835
+ session.replaceWithNewHandshakingConnection(handshakingConn);
836
+ }
780
837
  return { session, isReconnect };
781
838
  }
782
- deleteSession(session) {
839
+ deleteSession({
840
+ session,
841
+ closeHandshakingConnection,
842
+ handshakingConn
843
+ }) {
844
+ if (closeHandshakingConnection) {
845
+ session.closeHandshakingConnection(handshakingConn);
846
+ }
783
847
  session.close();
784
848
  session.telemetry.span.end();
785
849
  this.sessions.delete(session.to);
@@ -806,7 +870,11 @@ var Transport = class {
806
870
  session.connection = void 0;
807
871
  session.beginGrace(() => {
808
872
  session.telemetry.span.addEvent("session grace period expired");
809
- this.deleteSession(session);
873
+ this.deleteSession({
874
+ session,
875
+ closeHandshakingConnection: true,
876
+ handshakingConn: conn
877
+ });
810
878
  });
811
879
  }
812
880
  /**
@@ -845,7 +913,7 @@ var Transport = class {
845
913
  * @param msg The received message.
846
914
  */
847
915
  handleMsg(msg, conn) {
848
- if (this.state !== "open")
916
+ if (this.getStatus() !== "open")
849
917
  return;
850
918
  const session = this.sessions.get(msg.from);
851
919
  if (!session) {
@@ -886,7 +954,7 @@ var Transport = class {
886
954
  code: import_api3.SpanStatusCode.ERROR,
887
955
  message: "message order violated"
888
956
  });
889
- session.close();
957
+ this.deleteSession({ session, closeHandshakingConnection: true });
890
958
  }
891
959
  return;
892
960
  }
@@ -924,23 +992,16 @@ var Transport = class {
924
992
  * @returns The ID of the sent message or undefined if it wasn't sent
925
993
  */
926
994
  send(to, msg) {
927
- if (this.state === "destroyed") {
928
- const err = "transport is destroyed, cant send";
995
+ if (this.getStatus() === "closed") {
996
+ const err = "transport is closed, cant send";
929
997
  this.log?.error(err, {
930
998
  clientId: this.clientId,
931
999
  transportMessage: msg,
932
1000
  tags: ["invariant-violation"]
933
1001
  });
934
- this.protocolError(ProtocolError.UseAfterDestroy, err);
935
- return void 0;
936
- } else if (this.state === "closed") {
937
- this.log?.info(`transport closed when sending, discarding`, {
938
- clientId: this.clientId,
939
- transportMessage: msg
940
- });
941
- return void 0;
1002
+ throw new Error(err);
942
1003
  }
943
- return this.getOrCreateSession(to).session.send(msg);
1004
+ return this.getOrCreateSession({ to }).session.send(msg);
944
1005
  }
945
1006
  // control helpers
946
1007
  sendCloseStream(to, streamId) {
@@ -961,23 +1022,18 @@ var Transport = class {
961
1022
  * Closes the transport. Any messages sent while the transport is closed will be silently discarded.
962
1023
  */
963
1024
  close() {
964
- this.state = "closed";
1025
+ this.status = "closed";
965
1026
  for (const session of this.sessions.values()) {
966
- this.deleteSession(session);
1027
+ this.deleteSession({ session, closeHandshakingConnection: true });
967
1028
  }
1029
+ this.eventDispatcher.dispatchEvent("transportStatus", {
1030
+ status: this.status
1031
+ });
1032
+ this.eventDispatcher.removeAllListeners();
968
1033
  this.log?.info(`manually closed transport`, { clientId: this.clientId });
969
1034
  }
970
- /**
971
- * Default destroy implementation for transports. You should override this in the downstream
972
- * implementation if you need to do any additional cleanup and call super.destroy() at the end.
973
- * Destroys the transport. Any messages sent while the transport is destroyed will throw an error.
974
- */
975
- destroy() {
976
- this.state = "destroyed";
977
- for (const session of this.sessions.values()) {
978
- this.deleteSession(session);
979
- }
980
- this.log?.info(`manually destroyed transport`, { clientId: this.clientId });
1035
+ getStatus() {
1036
+ return this.status;
981
1037
  }
982
1038
  };
983
1039
  var ClientTransport = class extends Transport {
@@ -1014,26 +1070,26 @@ var ClientTransport = class extends Transport {
1014
1070
  this.handshakeExtensions = options;
1015
1071
  }
1016
1072
  handleConnection(conn, to) {
1017
- if (this.state !== "open")
1073
+ if (this.getStatus() !== "open")
1018
1074
  return;
1019
1075
  let session = void 0;
1020
1076
  const handshakeTimeout = setTimeout(() => {
1021
- if (!session) {
1022
- this.log?.warn(
1023
- `connection to ${to} timed out waiting for handshake, closing`,
1024
- { ...conn.loggingMetadata, clientId: this.clientId, connectedTo: to }
1025
- );
1026
- conn.close();
1027
- }
1077
+ if (session)
1078
+ return;
1079
+ this.log?.warn(
1080
+ `connection to ${to} timed out waiting for handshake, closing`,
1081
+ { ...conn.loggingMetadata, clientId: this.clientId, connectedTo: to }
1082
+ );
1083
+ conn.close();
1028
1084
  }, this.options.sessionDisconnectGraceMs);
1029
1085
  const handshakeHandler = (data) => {
1030
1086
  const maybeSession = this.receiveHandshakeResponseMessage(data, conn);
1087
+ clearTimeout(handshakeTimeout);
1031
1088
  if (!maybeSession) {
1032
1089
  conn.close();
1033
1090
  return;
1034
1091
  } else {
1035
1092
  session = maybeSession;
1036
- clearTimeout(handshakeTimeout);
1037
1093
  }
1038
1094
  conn.removeDataListener(handshakeHandler);
1039
1095
  conn.addDataListener((data2) => {
@@ -1140,11 +1196,11 @@ var ClientTransport = class extends Transport {
1140
1196
  connectedTo: parsed.from,
1141
1197
  transportMessage: parsed
1142
1198
  });
1143
- const { session, isReconnect } = this.getOrCreateSession(
1144
- parsed.from,
1199
+ const { session, isReconnect } = this.getOrCreateSession({
1200
+ to: parsed.from,
1145
1201
  conn,
1146
- parsed.payload.status.sessionId
1147
- );
1202
+ sessionId: parsed.payload.status.sessionId
1203
+ });
1148
1204
  this.onConnect(conn, parsed.from, session, isReconnect);
1149
1205
  this.retryBudget.startRestoringBudget(parsed.from);
1150
1206
  return session;
@@ -1154,7 +1210,7 @@ var ClientTransport = class extends Transport {
1154
1210
  * @param to The client ID of the node to connect to.
1155
1211
  */
1156
1212
  async connect(to) {
1157
- const canProceedWithConnection = () => this.state === "open";
1213
+ const canProceedWithConnection = () => this.getStatus() === "open";
1158
1214
  if (!canProceedWithConnection()) {
1159
1215
  this.log?.info(
1160
1216
  `transport state is no longer open, cancelling attempt to connect to ${to}`,
@@ -1250,9 +1306,17 @@ var ClientTransport = class extends Transport {
1250
1306
  }
1251
1307
  }
1252
1308
  }
1253
- deleteSession(session) {
1309
+ deleteSession({
1310
+ session,
1311
+ closeHandshakingConnection,
1312
+ handshakingConn
1313
+ }) {
1254
1314
  this.inflightConnectionPromises.delete(session.to);
1255
- super.deleteSession(session);
1315
+ super.deleteSession({
1316
+ session,
1317
+ closeHandshakingConnection,
1318
+ handshakingConn
1319
+ });
1256
1320
  }
1257
1321
  async sendHandshake(to, conn) {
1258
1322
  let metadata = void 0;
@@ -1279,7 +1343,7 @@ var ClientTransport = class extends Transport {
1279
1343
  return false;
1280
1344
  }
1281
1345
  }
1282
- const { session } = this.getOrCreateSession(to);
1346
+ const { session } = this.getOrCreateSession({ to, handshakingConn: conn });
1283
1347
  const requestMsg = handshakeRequestMessage(
1284
1348
  this.clientId,
1285
1349
  to,
@@ -1391,6 +1455,9 @@ var WebSocketClientTransport = class extends ClientTransport {
1391
1455
  ws.onclose = (evt) => {
1392
1456
  reject(new Error(evt.reason));
1393
1457
  };
1458
+ ws.onerror = (err) => {
1459
+ reject(new Error(err.message));
1460
+ };
1394
1461
  });
1395
1462
  const conn = new WebSocketConnection(ws);
1396
1463
  this.log?.info(`raw websocket to ${to} ok, starting handshake`, {