@replit/river 0.23.13 → 0.23.14

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-SX6HI63Q.js → chunk-BEALFLCB.js} +2 -2
  2. package/dist/{chunk-S4DUN7KK.js → chunk-D2DHRRBN.js} +41 -20
  3. package/dist/chunk-D2DHRRBN.js.map +1 -0
  4. package/dist/{chunk-ES4XO2XD.js → chunk-GCCRVSMR.js} +33 -4
  5. package/dist/chunk-GCCRVSMR.js.map +1 -0
  6. package/dist/{chunk-KFTGQ3QC.js → chunk-GN4YEXT7.js} +2 -2
  7. package/dist/{chunk-2FNLANTJ.js → chunk-O2AVDJCQ.js} +10 -2
  8. package/dist/{chunk-2FNLANTJ.js.map → chunk-O2AVDJCQ.js.map} +1 -1
  9. package/dist/{chunk-XM656KMN.js → chunk-OTVTKAN6.js} +46 -3
  10. package/dist/chunk-OTVTKAN6.js.map +1 -0
  11. package/dist/{chunk-ZUKDZY54.js → chunk-WUL63FR6.js} +89 -25
  12. package/dist/chunk-WUL63FR6.js.map +1 -0
  13. package/dist/{chunk-4QZOW4DH.js → chunk-YCLZWES2.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 +113 -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 +157 -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 +113 -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 +157 -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 +202 -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-SX6HI63Q.js.map → chunk-BEALFLCB.js.map} +0 -0
  61. /package/dist/{chunk-KFTGQ3QC.js.map → chunk-GN4YEXT7.js.map} +0 -0
  62. /package/dist/{chunk-4QZOW4DH.js.map → chunk-YCLZWES2.js.map} +0 -0
@@ -66,6 +66,21 @@ var ControlMessageHandshakeRequestSchema = import_typebox.Type.Object({
66
66
  type: import_typebox.Type.Literal("HANDSHAKE_REQ"),
67
67
  protocolVersion: import_typebox.Type.String(),
68
68
  sessionId: import_typebox.Type.String(),
69
+ /**
70
+ * Specifies what the server's expected session state (from the pov of the client). This can be
71
+ * used by the server to know whether this is a new or a reestablished connection, and whether it
72
+ * is compatible with what it already has.
73
+ */
74
+ expectedSessionState: import_typebox.Type.Optional(
75
+ import_typebox.Type.Object({
76
+ /**
77
+ * reconnect is set to true if the client explicitly wants to reestablish an existing
78
+ * connection.
79
+ */
80
+ reconnect: import_typebox.Type.Boolean(),
81
+ nextExpectedSeq: import_typebox.Type.Integer()
82
+ })
83
+ ),
69
84
  metadata: import_typebox.Type.Optional(import_typebox.Type.Unknown())
70
85
  });
71
86
  var ControlMessageHandshakeResponseSchema = import_typebox.Type.Object({
@@ -90,7 +105,14 @@ var ControlMessagePayloadSchema = import_typebox.Type.Union([
90
105
  var OpaqueTransportMessageSchema = TransportMessageSchema(
91
106
  import_typebox.Type.Unknown()
92
107
  );
93
- function handshakeRequestMessage(from, to, sessionId, metadata, tracing) {
108
+ function handshakeRequestMessage({
109
+ from,
110
+ to,
111
+ sessionId,
112
+ expectedSessionState,
113
+ metadata,
114
+ tracing
115
+ }) {
94
116
  return {
95
117
  id: (0, import_nanoid.nanoid)(),
96
118
  from,
@@ -104,11 +126,17 @@ function handshakeRequestMessage(from, to, sessionId, metadata, tracing) {
104
126
  type: "HANDSHAKE_REQ",
105
127
  protocolVersion: PROTOCOL_VERSION,
106
128
  sessionId,
129
+ expectedSessionState,
107
130
  metadata
108
131
  }
109
132
  };
110
133
  }
111
- function handshakeResponseMessage(from, to, status) {
134
+ var SESSION_STATE_MISMATCH = "session state mismatch";
135
+ function handshakeResponseMessage({
136
+ from,
137
+ to,
138
+ status
139
+ }) {
112
140
  return {
113
141
  id: (0, import_nanoid.nanoid)(),
114
142
  from,
@@ -224,7 +252,7 @@ var import_nanoid2 = require("nanoid");
224
252
  var import_api = require("@opentelemetry/api");
225
253
 
226
254
  // package.json
227
- var version = "0.23.13";
255
+ var version = "0.23.14";
228
256
 
229
257
  // tracing/index.ts
230
258
  function getPropagationContext(ctx) {
@@ -538,9 +566,17 @@ var Session = class {
538
566
  get connected() {
539
567
  return this.connection !== void 0;
540
568
  }
569
+ get nextExpectedAck() {
570
+ return this.seq;
571
+ }
541
572
  get nextExpectedSeq() {
542
573
  return this.ack;
543
574
  }
575
+ // This is only used in tests to make the session misbehave.
576
+ /* @internal */
577
+ advanceAckForTesting(by) {
578
+ this.ack += by;
579
+ }
544
580
  constructMsg(partialMsg) {
545
581
  const msg = {
546
582
  ...partialMsg,
@@ -727,6 +763,49 @@ var Transport = class {
727
763
  });
728
764
  return session;
729
765
  }
766
+ createNewSession({
767
+ to,
768
+ conn,
769
+ sessionId,
770
+ propagationCtx
771
+ }) {
772
+ let session = this.sessions.get(to);
773
+ if (session !== void 0) {
774
+ this.log?.info(
775
+ `session for ${to} already exists, replacing it with a new session as requested`,
776
+ session.loggingMetadata
777
+ );
778
+ this.deleteSession({
779
+ session,
780
+ closeHandshakingConnection: false
781
+ });
782
+ session = void 0;
783
+ }
784
+ session = this.createSession(to, conn, propagationCtx);
785
+ session.advertisedSessionId = sessionId;
786
+ this.log?.info(`created new session for ${to}`, session.loggingMetadata);
787
+ return session;
788
+ }
789
+ getExistingSession({
790
+ to,
791
+ sessionId,
792
+ nextExpectedSeq
793
+ }) {
794
+ const session = this.sessions.get(to);
795
+ if (
796
+ // reject this request if there was no previous session to replace
797
+ session === void 0 || // or if both parties do not agree about the next expected sequence number
798
+ session.nextExpectedAck < nextExpectedSeq || // or if both parties do not agree on the advertised session id
799
+ session.advertisedSessionId !== sessionId
800
+ ) {
801
+ return false;
802
+ }
803
+ this.log?.info(
804
+ `reused existing session for ${to}`,
805
+ session.loggingMetadata
806
+ );
807
+ return session;
808
+ }
730
809
  getOrCreateSession({
731
810
  to,
732
811
  conn,
@@ -1211,24 +1290,40 @@ var ClientTransport = class extends Transport {
1211
1290
  );
1212
1291
  return false;
1213
1292
  }
1293
+ const previousSession = this.sessions.get(parsed.from);
1214
1294
  if (!parsed.payload.status.ok) {
1215
- conn.telemetry?.span.setStatus({
1216
- code: import_api4.SpanStatusCode.ERROR,
1217
- message: "handshake rejected"
1218
- });
1219
- this.log?.warn(`received handshake rejection`, {
1220
- ...conn.loggingMetadata,
1221
- clientId: this.clientId,
1222
- connectedTo: parsed.from,
1223
- transportMessage: parsed
1224
- });
1295
+ if (parsed.payload.status.reason === SESSION_STATE_MISMATCH) {
1296
+ if (previousSession) {
1297
+ this.deleteSession({
1298
+ session: previousSession,
1299
+ closeHandshakingConnection: true
1300
+ });
1301
+ }
1302
+ conn.telemetry?.span.setStatus({
1303
+ code: import_api4.SpanStatusCode.ERROR,
1304
+ message: parsed.payload.status.reason
1305
+ });
1306
+ } else {
1307
+ conn.telemetry?.span.setStatus({
1308
+ code: import_api4.SpanStatusCode.ERROR,
1309
+ message: "handshake rejected"
1310
+ });
1311
+ }
1312
+ this.log?.warn(
1313
+ `received handshake rejection: ${parsed.payload.status.reason}`,
1314
+ {
1315
+ ...conn.loggingMetadata,
1316
+ clientId: this.clientId,
1317
+ connectedTo: parsed.from,
1318
+ transportMessage: parsed
1319
+ }
1320
+ );
1225
1321
  this.protocolError(
1226
1322
  ProtocolError.HandshakeFailed,
1227
1323
  parsed.payload.status.reason
1228
1324
  );
1229
1325
  return false;
1230
1326
  }
1231
- const previousSession = this.sessions.get(parsed.from);
1232
1327
  if (previousSession?.advertisedSessionId && previousSession.advertisedSessionId !== parsed.payload.status.sessionId) {
1233
1328
  this.deleteSession({
1234
1329
  session: previousSession,
@@ -1408,13 +1503,17 @@ var ClientTransport = class extends Transport {
1408
1503
  }
1409
1504
  }
1410
1505
  const { session } = this.getOrCreateSession({ to, handshakingConn: conn });
1411
- const requestMsg = handshakeRequestMessage(
1412
- this.clientId,
1506
+ const requestMsg = handshakeRequestMessage({
1507
+ from: this.clientId,
1413
1508
  to,
1414
- session.id,
1509
+ sessionId: session.id,
1510
+ expectedSessionState: {
1511
+ reconnect: session.advertisedSessionId !== void 0,
1512
+ nextExpectedSeq: session.nextExpectedSeq
1513
+ },
1415
1514
  metadata,
1416
- getPropagationContext(session.telemetry.ctx)
1417
- );
1515
+ tracing: getPropagationContext(session.telemetry.ctx)
1516
+ });
1418
1517
  this.log?.debug(`sending handshake request to ${to}`, {
1419
1518
  ...conn.loggingMetadata,
1420
1519
  clientId: this.clientId,
@@ -1552,9 +1651,13 @@ var ServerTransport = class extends Transport {
1552
1651
  message: "malformed handshake meta"
1553
1652
  });
1554
1653
  const reason = "received malformed handshake metadata";
1555
- const responseMsg = handshakeResponseMessage(this.clientId, from, {
1556
- ok: false,
1557
- reason
1654
+ const responseMsg = handshakeResponseMessage({
1655
+ from: this.clientId,
1656
+ to: from,
1657
+ status: {
1658
+ ok: false,
1659
+ reason
1660
+ }
1558
1661
  });
1559
1662
  conn.send(this.codec.toBuffer(responseMsg));
1560
1663
  this.log?.warn(`received malformed handshake metadata from ${from}`, {
@@ -1578,9 +1681,13 @@ var ServerTransport = class extends Transport {
1578
1681
  code: import_api5.SpanStatusCode.ERROR,
1579
1682
  message: reason
1580
1683
  });
1581
- const responseMsg = handshakeResponseMessage(this.clientId, from, {
1582
- ok: false,
1583
- reason
1684
+ const responseMsg = handshakeResponseMessage({
1685
+ from: this.clientId,
1686
+ to: from,
1687
+ status: {
1688
+ ok: false,
1689
+ reason
1690
+ }
1584
1691
  });
1585
1692
  conn.send(this.codec.toBuffer(responseMsg));
1586
1693
  this.log?.warn(`rejected handshake from ${from}`, {
@@ -1612,9 +1719,13 @@ var ServerTransport = class extends Transport {
1612
1719
  message: "invalid handshake request"
1613
1720
  });
1614
1721
  const reason = "received invalid handshake msg";
1615
- const responseMsg2 = handshakeResponseMessage(this.clientId, parsed.from, {
1616
- ok: false,
1617
- reason
1722
+ const responseMsg2 = handshakeResponseMessage({
1723
+ from: this.clientId,
1724
+ to: parsed.from,
1725
+ status: {
1726
+ ok: false,
1727
+ reason
1728
+ }
1618
1729
  });
1619
1730
  conn.send(this.codec.toBuffer(responseMsg2));
1620
1731
  this.log?.warn(reason, {
@@ -1640,9 +1751,13 @@ var ServerTransport = class extends Transport {
1640
1751
  message: "incorrect protocol version"
1641
1752
  });
1642
1753
  const reason = `incorrect version (got: ${gotVersion} wanted ${PROTOCOL_VERSION})`;
1643
- const responseMsg2 = handshakeResponseMessage(this.clientId, parsed.from, {
1644
- ok: false,
1645
- reason
1754
+ const responseMsg2 = handshakeResponseMessage({
1755
+ from: this.clientId,
1756
+ to: parsed.from,
1757
+ status: {
1758
+ ok: false,
1759
+ reason
1760
+ }
1646
1761
  });
1647
1762
  conn.send(this.codec.toBuffer(responseMsg2));
1648
1763
  this.log?.warn(
@@ -1662,20 +1777,67 @@ var ServerTransport = class extends Transport {
1662
1777
  if (parsedMetadata === false) {
1663
1778
  return false;
1664
1779
  }
1665
- const { session, isTransparentReconnect } = this.getOrCreateSession({
1666
- to: parsed.from,
1667
- conn,
1668
- sessionId: parsed.payload.sessionId,
1669
- propagationCtx: parsed.tracing
1670
- });
1780
+ let session;
1781
+ let isTransparentReconnect;
1782
+ if (!parsed.payload.expectedSessionState) {
1783
+ ({ session, isTransparentReconnect } = this.getOrCreateSession({
1784
+ to: parsed.from,
1785
+ conn,
1786
+ sessionId: parsed.payload.sessionId,
1787
+ propagationCtx: parsed.tracing
1788
+ }));
1789
+ } else if (parsed.payload.expectedSessionState.reconnect) {
1790
+ const existingSession = this.getExistingSession({
1791
+ to: parsed.from,
1792
+ sessionId: parsed.payload.sessionId,
1793
+ nextExpectedSeq: parsed.payload.expectedSessionState.nextExpectedSeq
1794
+ });
1795
+ if (existingSession === false) {
1796
+ conn.telemetry?.span.setStatus({
1797
+ code: import_api5.SpanStatusCode.ERROR,
1798
+ message: SESSION_STATE_MISMATCH
1799
+ });
1800
+ const reason = SESSION_STATE_MISMATCH;
1801
+ const responseMsg2 = handshakeResponseMessage({
1802
+ from: this.clientId,
1803
+ to: parsed.from,
1804
+ status: {
1805
+ ok: false,
1806
+ reason
1807
+ }
1808
+ });
1809
+ conn.send(this.codec.toBuffer(responseMsg2));
1810
+ this.log?.warn(
1811
+ `'received handshake msg with incompatible existing session state: ${parsed.payload.sessionId}`,
1812
+ { ...conn.loggingMetadata, clientId: this.clientId }
1813
+ );
1814
+ this.protocolError(ProtocolError.HandshakeFailed, reason);
1815
+ return false;
1816
+ }
1817
+ session = existingSession;
1818
+ isTransparentReconnect = false;
1819
+ } else {
1820
+ const createdSession = this.createNewSession({
1821
+ to: parsed.from,
1822
+ conn,
1823
+ sessionId: parsed.payload.sessionId,
1824
+ propagationCtx: parsed.tracing
1825
+ });
1826
+ session = createdSession;
1827
+ isTransparentReconnect = false;
1828
+ }
1671
1829
  this.sessionHandshakeMetadata.set(session, parsedMetadata);
1672
1830
  this.log?.debug(
1673
1831
  `handshake from ${parsed.from} ok, responding with handshake success`,
1674
1832
  conn.loggingMetadata
1675
1833
  );
1676
- const responseMsg = handshakeResponseMessage(this.clientId, parsed.from, {
1677
- ok: true,
1678
- sessionId: session.id
1834
+ const responseMsg = handshakeResponseMessage({
1835
+ from: this.clientId,
1836
+ to: parsed.from,
1837
+ status: {
1838
+ ok: true,
1839
+ sessionId: session.id
1840
+ }
1679
1841
  });
1680
1842
  conn.send(this.codec.toBuffer(responseMsg));
1681
1843
  this.onConnect(conn, session, isTransparentReconnect);