@replit/river 0.23.13 → 0.23.15

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 (62) hide show
  1. package/dist/{chunk-2FNLANTJ.js → chunk-5HK7ZQYH.js} +10 -2
  2. package/dist/{chunk-2FNLANTJ.js.map → chunk-5HK7ZQYH.js.map} +1 -1
  3. package/dist/{chunk-KFTGQ3QC.js → chunk-AEY7BBOZ.js} +2 -2
  4. package/dist/{chunk-S4DUN7KK.js → chunk-IJTGEBLG.js} +41 -20
  5. package/dist/chunk-IJTGEBLG.js.map +1 -0
  6. package/dist/{chunk-ZUKDZY54.js → chunk-JMVKSGND.js} +89 -25
  7. package/dist/chunk-JMVKSGND.js.map +1 -0
  8. package/dist/{chunk-XM656KMN.js → chunk-MD4S7GO2.js} +71 -3
  9. package/dist/chunk-MD4S7GO2.js.map +1 -0
  10. package/dist/{chunk-ES4XO2XD.js → chunk-OXVWMLID.js} +33 -4
  11. package/dist/chunk-OXVWMLID.js.map +1 -0
  12. package/dist/{chunk-SX6HI63Q.js → chunk-RQQZUQGE.js} +2 -2
  13. package/dist/{chunk-4QZOW4DH.js → chunk-XYEOXPZQ.js} +2 -2
  14. package/dist/{client-dd5c9dd0.d.ts → client-e13979ac.d.ts} +1 -1
  15. package/dist/{connection-39816c00.d.ts → connection-5d0978ce.d.ts} +1 -1
  16. package/dist/{connection-40318f22.d.ts → connection-e57e98ea.d.ts} +1 -1
  17. package/dist/{handshake-e428d1c8.d.ts → handshake-5665ffd3.d.ts} +13 -0
  18. package/dist/router/index.cjs +16 -1
  19. package/dist/router/index.cjs.map +1 -1
  20. package/dist/router/index.d.cts +7 -7
  21. package/dist/router/index.d.ts +7 -7
  22. package/dist/router/index.js +2 -2
  23. package/dist/{server-ebf80863.d.ts → server-1cfc88d1.d.ts} +1 -1
  24. package/dist/{services-f406b3aa.d.ts → services-86c4d10d.d.ts} +2 -2
  25. package/dist/transport/impls/uds/client.cjs +138 -18
  26. package/dist/transport/impls/uds/client.cjs.map +1 -1
  27. package/dist/transport/impls/uds/client.d.cts +3 -3
  28. package/dist/transport/impls/uds/client.d.ts +3 -3
  29. package/dist/transport/impls/uds/client.js +5 -5
  30. package/dist/transport/impls/uds/server.cjs +182 -23
  31. package/dist/transport/impls/uds/server.cjs.map +1 -1
  32. package/dist/transport/impls/uds/server.d.cts +3 -3
  33. package/dist/transport/impls/uds/server.d.ts +3 -3
  34. package/dist/transport/impls/uds/server.js +5 -5
  35. package/dist/transport/impls/ws/client.cjs +138 -18
  36. package/dist/transport/impls/ws/client.cjs.map +1 -1
  37. package/dist/transport/impls/ws/client.d.cts +3 -3
  38. package/dist/transport/impls/ws/client.d.ts +3 -3
  39. package/dist/transport/impls/ws/client.js +5 -5
  40. package/dist/transport/impls/ws/server.cjs +182 -23
  41. package/dist/transport/impls/ws/server.cjs.map +1 -1
  42. package/dist/transport/impls/ws/server.d.cts +3 -3
  43. package/dist/transport/impls/ws/server.d.ts +3 -3
  44. package/dist/transport/impls/ws/server.js +5 -5
  45. package/dist/transport/index.cjs +227 -40
  46. package/dist/transport/index.cjs.map +1 -1
  47. package/dist/transport/index.d.cts +3 -3
  48. package/dist/transport/index.d.ts +3 -3
  49. package/dist/transport/index.js +5 -5
  50. package/dist/util/testHelpers.cjs +9 -1
  51. package/dist/util/testHelpers.cjs.map +1 -1
  52. package/dist/util/testHelpers.d.cts +3 -3
  53. package/dist/util/testHelpers.d.ts +3 -3
  54. package/dist/util/testHelpers.js +3 -3
  55. package/package.json +13 -14
  56. package/dist/chunk-ES4XO2XD.js.map +0 -1
  57. package/dist/chunk-S4DUN7KK.js.map +0 -1
  58. package/dist/chunk-XM656KMN.js.map +0 -1
  59. package/dist/chunk-ZUKDZY54.js.map +0 -1
  60. /package/dist/{chunk-KFTGQ3QC.js.map → chunk-AEY7BBOZ.js.map} +0 -0
  61. /package/dist/{chunk-SX6HI63Q.js.map → chunk-RQQZUQGE.js.map} +0 -0
  62. /package/dist/{chunk-4QZOW4DH.js.map → chunk-XYEOXPZQ.js.map} +0 -0
@@ -59,6 +59,21 @@ var ControlMessageHandshakeRequestSchema = import_typebox.Type.Object({
59
59
  type: import_typebox.Type.Literal("HANDSHAKE_REQ"),
60
60
  protocolVersion: import_typebox.Type.String(),
61
61
  sessionId: import_typebox.Type.String(),
62
+ /**
63
+ * Specifies what the server's expected session state (from the pov of the client). This can be
64
+ * used by the server to know whether this is a new or a reestablished connection, and whether it
65
+ * is compatible with what it already has.
66
+ */
67
+ expectedSessionState: import_typebox.Type.Optional(
68
+ import_typebox.Type.Object({
69
+ /**
70
+ * reconnect is set to true if the client explicitly wants to reestablish an existing
71
+ * connection.
72
+ */
73
+ reconnect: import_typebox.Type.Boolean(),
74
+ nextExpectedSeq: import_typebox.Type.Integer()
75
+ })
76
+ ),
62
77
  metadata: import_typebox.Type.Optional(import_typebox.Type.Unknown())
63
78
  });
64
79
  var ControlMessageHandshakeResponseSchema = import_typebox.Type.Object({
@@ -83,7 +98,14 @@ var ControlMessagePayloadSchema = import_typebox.Type.Union([
83
98
  var OpaqueTransportMessageSchema = TransportMessageSchema(
84
99
  import_typebox.Type.Unknown()
85
100
  );
86
- function handshakeRequestMessage(from, to, sessionId, metadata, tracing) {
101
+ function handshakeRequestMessage({
102
+ from,
103
+ to,
104
+ sessionId,
105
+ expectedSessionState,
106
+ metadata,
107
+ tracing
108
+ }) {
87
109
  return {
88
110
  id: (0, import_nanoid.nanoid)(),
89
111
  from,
@@ -97,10 +119,12 @@ function handshakeRequestMessage(from, to, sessionId, metadata, tracing) {
97
119
  type: "HANDSHAKE_REQ",
98
120
  protocolVersion: PROTOCOL_VERSION,
99
121
  sessionId,
122
+ expectedSessionState,
100
123
  metadata
101
124
  }
102
125
  };
103
126
  }
127
+ var SESSION_STATE_MISMATCH = "session state mismatch";
104
128
  function isAck(controlFlag) {
105
129
  return (controlFlag & 1 /* AckBit */) === 1 /* AckBit */;
106
130
  }
@@ -350,7 +374,7 @@ var import_nanoid2 = require("nanoid");
350
374
  var import_api = require("@opentelemetry/api");
351
375
 
352
376
  // package.json
353
- var version = "0.23.13";
377
+ var version = "0.23.15";
354
378
 
355
379
  // tracing/index.ts
356
380
  function getPropagationContext(ctx) {
@@ -664,9 +688,17 @@ var Session = class {
664
688
  get connected() {
665
689
  return this.connection !== void 0;
666
690
  }
691
+ get nextExpectedAck() {
692
+ return this.seq;
693
+ }
667
694
  get nextExpectedSeq() {
668
695
  return this.ack;
669
696
  }
697
+ // This is only used in tests to make the session misbehave.
698
+ /* @internal */
699
+ advanceAckForTesting(by) {
700
+ this.ack += by;
701
+ }
670
702
  constructMsg(partialMsg) {
671
703
  const msg = {
672
704
  ...partialMsg,
@@ -770,6 +802,20 @@ var Transport = class {
770
802
  if (this.log) {
771
803
  session.bindLogger(this.log);
772
804
  }
805
+ const currentSession = this.sessions.get(session.to);
806
+ if (currentSession) {
807
+ this.log?.warn(
808
+ `session ${session.id} from ${session.to} surreptitiously replacing ${currentSession.id}`,
809
+ {
810
+ ...currentSession.loggingMetadata,
811
+ tags: ["invariant-violation"]
812
+ }
813
+ );
814
+ this.deleteSession({
815
+ session: currentSession,
816
+ closeHandshakingConnection: false
817
+ });
818
+ }
773
819
  this.sessions.set(session.to, session);
774
820
  this.eventDispatcher.dispatchEvent("sessionStatus", {
775
821
  status: "connect",
@@ -777,6 +823,49 @@ var Transport = class {
777
823
  });
778
824
  return session;
779
825
  }
826
+ createNewSession({
827
+ to,
828
+ conn,
829
+ sessionId,
830
+ propagationCtx
831
+ }) {
832
+ let session = this.sessions.get(to);
833
+ if (session !== void 0) {
834
+ this.log?.info(
835
+ `session for ${to} already exists, replacing it with a new session as requested`,
836
+ session.loggingMetadata
837
+ );
838
+ this.deleteSession({
839
+ session,
840
+ closeHandshakingConnection: false
841
+ });
842
+ session = void 0;
843
+ }
844
+ session = this.createSession(to, conn, propagationCtx);
845
+ session.advertisedSessionId = sessionId;
846
+ this.log?.info(`created new session for ${to}`, session.loggingMetadata);
847
+ return session;
848
+ }
849
+ getExistingSession({
850
+ to,
851
+ sessionId,
852
+ nextExpectedSeq
853
+ }) {
854
+ const session = this.sessions.get(to);
855
+ if (
856
+ // reject this request if there was no previous session to replace
857
+ session === void 0 || // or if both parties do not agree about the next expected sequence number
858
+ session.nextExpectedAck < nextExpectedSeq || // or if both parties do not agree on the advertised session id
859
+ session.advertisedSessionId !== sessionId
860
+ ) {
861
+ return false;
862
+ }
863
+ this.log?.info(
864
+ `reused existing session for ${to}`,
865
+ session.loggingMetadata
866
+ );
867
+ return session;
868
+ }
780
869
  getOrCreateSession({
781
870
  to,
782
871
  conn,
@@ -825,6 +914,17 @@ var Transport = class {
825
914
  }
826
915
  session.close();
827
916
  session.telemetry.span.end();
917
+ const currentSession = this.sessions.get(session.to);
918
+ if (currentSession && currentSession.id !== session.id) {
919
+ this.log?.warn(
920
+ `session ${session.id} disconnect from ${session.to}, mismatch with ${currentSession.id}`,
921
+ {
922
+ ...session.loggingMetadata,
923
+ tags: ["invariant-violation"]
924
+ }
925
+ );
926
+ return;
927
+ }
828
928
  this.sessions.delete(session.to);
829
929
  this.log?.info(
830
930
  `session ${session.id} disconnect from ${session.to}`,
@@ -1187,24 +1287,40 @@ var ClientTransport = class extends Transport {
1187
1287
  );
1188
1288
  return false;
1189
1289
  }
1290
+ const previousSession = this.sessions.get(parsed.from);
1190
1291
  if (!parsed.payload.status.ok) {
1191
- conn.telemetry?.span.setStatus({
1192
- code: import_api4.SpanStatusCode.ERROR,
1193
- message: "handshake rejected"
1194
- });
1195
- this.log?.warn(`received handshake rejection`, {
1196
- ...conn.loggingMetadata,
1197
- clientId: this.clientId,
1198
- connectedTo: parsed.from,
1199
- transportMessage: parsed
1200
- });
1292
+ if (parsed.payload.status.reason === SESSION_STATE_MISMATCH) {
1293
+ if (previousSession) {
1294
+ this.deleteSession({
1295
+ session: previousSession,
1296
+ closeHandshakingConnection: true
1297
+ });
1298
+ }
1299
+ conn.telemetry?.span.setStatus({
1300
+ code: import_api4.SpanStatusCode.ERROR,
1301
+ message: parsed.payload.status.reason
1302
+ });
1303
+ } else {
1304
+ conn.telemetry?.span.setStatus({
1305
+ code: import_api4.SpanStatusCode.ERROR,
1306
+ message: "handshake rejected"
1307
+ });
1308
+ }
1309
+ this.log?.warn(
1310
+ `received handshake rejection: ${parsed.payload.status.reason}`,
1311
+ {
1312
+ ...conn.loggingMetadata,
1313
+ clientId: this.clientId,
1314
+ connectedTo: parsed.from,
1315
+ transportMessage: parsed
1316
+ }
1317
+ );
1201
1318
  this.protocolError(
1202
1319
  ProtocolError.HandshakeFailed,
1203
1320
  parsed.payload.status.reason
1204
1321
  );
1205
1322
  return false;
1206
1323
  }
1207
- const previousSession = this.sessions.get(parsed.from);
1208
1324
  if (previousSession?.advertisedSessionId && previousSession.advertisedSessionId !== parsed.payload.status.sessionId) {
1209
1325
  this.deleteSession({
1210
1326
  session: previousSession,
@@ -1384,13 +1500,17 @@ var ClientTransport = class extends Transport {
1384
1500
  }
1385
1501
  }
1386
1502
  const { session } = this.getOrCreateSession({ to, handshakingConn: conn });
1387
- const requestMsg = handshakeRequestMessage(
1388
- this.clientId,
1503
+ const requestMsg = handshakeRequestMessage({
1504
+ from: this.clientId,
1389
1505
  to,
1390
- session.id,
1506
+ sessionId: session.id,
1507
+ expectedSessionState: {
1508
+ reconnect: session.advertisedSessionId !== void 0,
1509
+ nextExpectedSeq: session.nextExpectedSeq
1510
+ },
1391
1511
  metadata,
1392
- getPropagationContext(session.telemetry.ctx)
1393
- );
1512
+ tracing: getPropagationContext(session.telemetry.ctx)
1513
+ });
1394
1514
  this.log?.debug(`sending handshake request to ${to}`, {
1395
1515
  ...conn.loggingMetadata,
1396
1516
  clientId: this.clientId,