@replit/river 0.18.5 → 0.19.2

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 (48) hide show
  1. package/dist/{chunk-VH3NGOXQ.js → chunk-D5PVGZPQ.js} +5 -3
  2. package/dist/{chunk-K7CUSLWL.js → chunk-JH275HID.js} +1 -1
  3. package/dist/{chunk-WER2DWCP.js → chunk-NBE3D667.js} +0 -4
  4. package/dist/{chunk-6Q3MSICL.js → chunk-SR4DBLJ6.js} +11 -3
  5. package/dist/{chunk-UABIFWM7.js → chunk-YFPVQTWL.js} +220 -105
  6. package/dist/{chunk-PUX3U2SZ.js → chunk-ZWPEZS27.js} +1 -1
  7. package/dist/{connection-893bd769.d.ts → connection-aa0ea000.d.ts} +1 -1
  8. package/dist/{connection-89918b74.d.ts → connection-cfec12e6.d.ts} +1 -1
  9. package/dist/index-e2513701.d.ts +342 -0
  10. package/dist/logging/index.cjs +0 -4
  11. package/dist/logging/index.d.cts +2 -1
  12. package/dist/logging/index.d.ts +2 -1
  13. package/dist/logging/index.js +1 -1
  14. package/dist/router/index.cjs +11 -2
  15. package/dist/router/index.d.cts +7 -383
  16. package/dist/router/index.d.ts +7 -383
  17. package/dist/router/index.js +3 -3
  18. package/dist/services-4bba42d8.d.ts +736 -0
  19. package/dist/services-5fc5712d.d.ts +736 -0
  20. package/dist/transport/impls/uds/client.cjs +80 -53
  21. package/dist/transport/impls/uds/client.d.cts +5 -5
  22. package/dist/transport/impls/uds/client.d.ts +5 -5
  23. package/dist/transport/impls/uds/client.js +4 -4
  24. package/dist/transport/impls/uds/server.cjs +151 -62
  25. package/dist/transport/impls/uds/server.d.cts +4 -4
  26. package/dist/transport/impls/uds/server.d.ts +4 -4
  27. package/dist/transport/impls/uds/server.js +4 -4
  28. package/dist/transport/impls/ws/client.cjs +80 -53
  29. package/dist/transport/impls/ws/client.d.cts +3 -3
  30. package/dist/transport/impls/ws/client.d.ts +3 -3
  31. package/dist/transport/impls/ws/client.js +4 -4
  32. package/dist/transport/impls/ws/server.cjs +151 -62
  33. package/dist/transport/impls/ws/server.d.cts +4 -4
  34. package/dist/transport/impls/ws/server.d.ts +4 -4
  35. package/dist/transport/impls/ws/server.js +4 -4
  36. package/dist/transport/index.cjs +188 -71
  37. package/dist/transport/index.d.cts +295 -3
  38. package/dist/transport/index.d.ts +295 -3
  39. package/dist/transport/index.js +3 -4
  40. package/dist/util/testHelpers.cjs +410 -401
  41. package/dist/util/testHelpers.d.cts +3 -3
  42. package/dist/util/testHelpers.d.ts +3 -3
  43. package/dist/util/testHelpers.js +4 -5
  44. package/package.json +1 -1
  45. package/dist/chunk-RPIDSIQG.js +0 -0
  46. package/dist/index-46ed19d8.d.ts +0 -111
  47. package/dist/index-d412ca83.d.ts +0 -420
  48. package/dist/procedures-bfffcb0b.d.ts +0 -324
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  WebSocketConnection
3
- } from "../../../chunk-K7CUSLWL.js";
3
+ } from "../../../chunk-JH275HID.js";
4
4
  import {
5
5
  ServerTransport
6
- } from "../../../chunk-UABIFWM7.js";
7
- import "../../../chunk-VH3NGOXQ.js";
8
- import "../../../chunk-WER2DWCP.js";
6
+ } from "../../../chunk-YFPVQTWL.js";
7
+ import "../../../chunk-D5PVGZPQ.js";
8
+ import "../../../chunk-NBE3D667.js";
9
9
  import "../../../chunk-GZ7HCLLM.js";
10
10
 
11
11
  // transport/impls/ws/server.ts
@@ -59,7 +59,8 @@ var PROTOCOL_VERSION = "v1.1";
59
59
  var ControlMessageHandshakeRequestSchema = import_typebox.Type.Object({
60
60
  type: import_typebox.Type.Literal("HANDSHAKE_REQ"),
61
61
  protocolVersion: import_typebox.Type.String(),
62
- sessionId: import_typebox.Type.String()
62
+ sessionId: import_typebox.Type.String(),
63
+ metadata: import_typebox.Type.Optional(import_typebox.Type.Unknown())
63
64
  });
64
65
  var ControlMessageHandshakeResponseSchema = import_typebox.Type.Object({
65
66
  type: import_typebox.Type.Literal("HANDSHAKE_RESP"),
@@ -83,7 +84,7 @@ var ControlMessagePayloadSchema = import_typebox.Type.Union([
83
84
  var OpaqueTransportMessageSchema = TransportMessageSchema(
84
85
  import_typebox.Type.Unknown()
85
86
  );
86
- function handshakeRequestMessage(from, to, sessionId) {
87
+ function handshakeRequestMessage(from, to, sessionId, metadata) {
87
88
  return {
88
89
  id: (0, import_nanoid.nanoid)(),
89
90
  from,
@@ -95,7 +96,8 @@ function handshakeRequestMessage(from, to, sessionId) {
95
96
  payload: {
96
97
  type: "HANDSHAKE_REQ",
97
98
  protocolVersion: PROTOCOL_VERSION,
98
- sessionId
99
+ sessionId,
100
+ metadata
99
101
  }
100
102
  };
101
103
  }
@@ -187,6 +189,12 @@ var Session = class {
187
189
  * for this session.
188
190
  */
189
191
  advertisedSessionId;
192
+ /**
193
+ * The metadata for this session, as parsed from the handshake.
194
+ *
195
+ * Will only ever be populated on the server side.
196
+ */
197
+ metadata;
190
198
  /**
191
199
  * Number of messages we've sent along this session (excluding handshake and acks)
192
200
  */
@@ -289,27 +297,24 @@ var Session = class {
289
297
  this.seq = 0;
290
298
  this.ack = 0;
291
299
  }
292
- sendBufferedMessages() {
293
- if (!this.connection) {
294
- const msg = `tried sending buffered messages without a connection (if you hit this code path something is seriously wrong)`;
295
- log?.error(msg, this.loggingMetadata);
296
- throw new Error(msg);
297
- }
298
- log?.info(
299
- `resending ${this.sendBuffer.length} buffered messages`,
300
- this.loggingMetadata
301
- );
300
+ sendBufferedMessages(conn) {
301
+ log?.info(`resending ${this.sendBuffer.length} buffered messages`, {
302
+ ...this.loggingMetadata,
303
+ connId: conn.debugId
304
+ });
302
305
  for (const msg of this.sendBuffer) {
303
306
  log?.debug(`resending msg`, {
304
307
  ...this.loggingMetadata,
305
- fullTransportMessage: msg
308
+ fullTransportMessage: msg,
309
+ connId: conn.debugId
306
310
  });
307
- const ok = this.connection.send(this.codec.toBuffer(msg));
311
+ const ok = conn.send(this.codec.toBuffer(msg));
308
312
  if (!ok) {
309
- const errMsg = `failed to send buffered message to ${this.to} (if you hit this code path something is seriously wrong)`;
313
+ const errMsg = `failed to send buffered message to ${this.to} (sus, this is a fresh connection)`;
310
314
  log?.error(errMsg, {
311
315
  ...this.loggingMetadata,
312
- fullTransportMessage: msg
316
+ fullTransportMessage: msg,
317
+ connId: conn.debugId
313
318
  });
314
319
  throw new Error(errMsg);
315
320
  }
@@ -340,6 +345,7 @@ var Session = class {
340
345
  this.closeStaleConnection(newConn);
341
346
  this.cancelGrace();
342
347
  this.connection = newConn;
348
+ this.sendBufferedMessages(newConn);
343
349
  }
344
350
  beginGrace(cb) {
345
351
  log?.info(
@@ -538,6 +544,9 @@ var defaultClientTransportOptions = {
538
544
  ...defaultTransportOptions,
539
545
  ...defaultConnectionRetryOptions
540
546
  };
547
+ var defaultServerTransportOptions = {
548
+ ...defaultTransportOptions
549
+ };
541
550
  var Transport = class {
542
551
  /**
543
552
  * A flag indicating whether the transport has been destroyed.
@@ -591,37 +600,15 @@ var Transport = class {
591
600
  * and we know the identity of the connected client.
592
601
  * @param conn The connection object.
593
602
  */
594
- onConnect(conn, connectedTo, advertisedSessionId) {
603
+ onConnect(conn, connectedTo, session, isReconnect) {
595
604
  this.eventDispatcher.dispatchEvent("connectionStatus", {
596
605
  status: "connect",
597
606
  conn
598
607
  });
599
- let oldSession = this.sessions.get(connectedTo);
600
- if (oldSession?.advertisedSessionId && oldSession.advertisedSessionId !== advertisedSessionId) {
601
- log?.warn(
602
- `connection from ${connectedTo} is a different session (id: ${advertisedSessionId}, last connected to: ${oldSession.advertisedSessionId}), killing old session and starting a new one`,
603
- oldSession.loggingMetadata
604
- );
605
- this.deleteSession(oldSession);
606
- oldSession = void 0;
608
+ if (isReconnect) {
609
+ session.replaceWithNewConnection(conn);
610
+ log?.info(`reconnected to ${connectedTo}`, session.loggingMetadata);
607
611
  }
608
- if (oldSession === void 0) {
609
- const newSession = this.createSession(connectedTo, conn);
610
- newSession.advertisedSessionId = advertisedSessionId;
611
- log?.info(
612
- `new connection for new session to ${connectedTo}`,
613
- newSession.loggingMetadata
614
- );
615
- return newSession;
616
- }
617
- oldSession.replaceWithNewConnection(conn);
618
- oldSession.sendBufferedMessages();
619
- oldSession.advertisedSessionId = advertisedSessionId;
620
- log?.info(
621
- `new connection for existing session to ${connectedTo}`,
622
- oldSession.loggingMetadata
623
- );
624
- return oldSession;
625
612
  }
626
613
  createSession(to, conn) {
627
614
  const session = new Session(
@@ -637,8 +624,18 @@ var Transport = class {
637
624
  });
638
625
  return session;
639
626
  }
640
- getOrCreateSession(to, conn) {
627
+ getOrCreateSession(to, conn, sessionId) {
641
628
  let session = this.sessions.get(to);
629
+ let isReconnect = session !== void 0;
630
+ if (session?.advertisedSessionId !== void 0 && sessionId !== void 0 && session.advertisedSessionId !== sessionId) {
631
+ log?.warn(
632
+ `session for ${to} already exists but has a different session id (expected: ${session.advertisedSessionId}, got: ${sessionId}), creating a new one`,
633
+ session.loggingMetadata
634
+ );
635
+ this.deleteSession(session);
636
+ isReconnect = false;
637
+ session = void 0;
638
+ }
642
639
  if (!session) {
643
640
  session = this.createSession(to, conn);
644
641
  log?.info(
@@ -646,7 +643,10 @@ var Transport = class {
646
643
  session.loggingMetadata
647
644
  );
648
645
  }
649
- return session;
646
+ if (sessionId !== void 0) {
647
+ session.advertisedSessionId = sessionId;
648
+ }
649
+ return { session, isReconnect };
650
650
  }
651
651
  deleteSession(session) {
652
652
  session.close();
@@ -781,7 +781,7 @@ var Transport = class {
781
781
  });
782
782
  return void 0;
783
783
  }
784
- return this.getOrCreateSession(to).send(msg);
784
+ return this.getOrCreateSession(to).session.send(msg);
785
785
  }
786
786
  // control helpers
787
787
  sendCloseStream(to, streamId) {
@@ -940,11 +940,12 @@ var ClientTransport = class extends Transport {
940
940
  connectedTo: parsed.from,
941
941
  fullTransportMessage: parsed
942
942
  });
943
- const session = this.onConnect(
944
- conn,
943
+ const { session, isReconnect } = this.getOrCreateSession(
945
944
  parsed.from,
945
+ conn,
946
946
  parsed.payload.status.sessionId
947
947
  );
948
+ this.onConnect(conn, parsed.from, session, isReconnect);
948
949
  this.retryBudget.startRestoringBudget(parsed.from);
949
950
  return session;
950
951
  }
@@ -997,8 +998,13 @@ var ClientTransport = class extends Transport {
997
998
  conn.close();
998
999
  throw new Error("transport state is no longer open");
999
1000
  }
1000
- this.sendHandshake(to, conn);
1001
- return conn;
1001
+ return this.sendHandshake(to, conn).then((ok) => {
1002
+ if (!ok) {
1003
+ conn.close();
1004
+ throw new Error("failed to send handshake");
1005
+ }
1006
+ return conn;
1007
+ });
1002
1008
  });
1003
1009
  this.inflightConnectionPromises.set(to, reconnectPromise);
1004
1010
  } else {
@@ -1030,14 +1036,35 @@ var ClientTransport = class extends Transport {
1030
1036
  this.inflightConnectionPromises.delete(session.to);
1031
1037
  super.deleteSession(session);
1032
1038
  }
1033
- sendHandshake(to, conn) {
1034
- const session = this.getOrCreateSession(to, conn);
1035
- const requestMsg = handshakeRequestMessage(this.clientId, to, session.id);
1039
+ async sendHandshake(to, conn) {
1040
+ let metadata;
1041
+ if (this.options.handshake) {
1042
+ metadata = await this.options.handshake.get();
1043
+ if (!import_value.Value.Check(this.options.handshake.schema, metadata)) {
1044
+ log?.error(`handshake metadata did not match schema`, {
1045
+ clientId: this.clientId,
1046
+ connectedTo: to
1047
+ });
1048
+ this.protocolError(
1049
+ ProtocolError.HandshakeFailed,
1050
+ "handshake metadata did not match schema"
1051
+ );
1052
+ return false;
1053
+ }
1054
+ }
1055
+ const { session } = this.getOrCreateSession(to, conn);
1056
+ const requestMsg = handshakeRequestMessage(
1057
+ this.clientId,
1058
+ to,
1059
+ session.id,
1060
+ metadata
1061
+ );
1036
1062
  log?.debug(`sending handshake request to ${to}`, {
1037
1063
  clientId: this.clientId,
1038
1064
  connectedTo: to
1039
1065
  });
1040
1066
  conn.send(this.codec.toBuffer(requestMsg));
1067
+ return true;
1041
1068
  }
1042
1069
  close() {
1043
1070
  this.retryBudget.close();
@@ -1045,8 +1072,16 @@ var ClientTransport = class extends Transport {
1045
1072
  }
1046
1073
  };
1047
1074
  var ServerTransport = class extends Transport {
1075
+ /**
1076
+ * The options for this transport.
1077
+ */
1078
+ options;
1048
1079
  constructor(clientId, providedOptions) {
1049
1080
  super(clientId, providedOptions);
1081
+ this.options = {
1082
+ ...defaultServerTransportOptions,
1083
+ ...providedOptions
1084
+ };
1050
1085
  log?.info(`initiated server transport`, {
1051
1086
  clientId: this.clientId,
1052
1087
  protocolVersion: PROTOCOL_VERSION
@@ -1074,24 +1109,38 @@ var ServerTransport = class extends Transport {
1074
1109
  conn.close();
1075
1110
  }
1076
1111
  }, this.options.sessionDisconnectGraceMs);
1112
+ const buffer = [];
1113
+ let receivedHandshakeMessage = false;
1077
1114
  const handshakeHandler = (data) => {
1078
- const maybeSession = this.receiveHandshakeRequestMessage(data, conn);
1079
- if (!maybeSession) {
1080
- conn.close();
1115
+ if (receivedHandshakeMessage) {
1116
+ buffer.push(data);
1081
1117
  return;
1082
- } else {
1083
- session = maybeSession;
1084
- clearTimeout(handshakeTimeout);
1085
1118
  }
1086
- conn.removeDataListener(handshakeHandler);
1087
- conn.addDataListener((data2) => {
1088
- const parsed = this.parseMsg(data2);
1089
- if (!parsed) {
1090
- conn.close();
1091
- return;
1119
+ receivedHandshakeMessage = true;
1120
+ clearTimeout(handshakeTimeout);
1121
+ void this.receiveHandshakeRequestMessage(data, conn).then(
1122
+ (maybeSession) => {
1123
+ if (!maybeSession) {
1124
+ conn.close();
1125
+ return;
1126
+ }
1127
+ session = maybeSession;
1128
+ const dataHandler = (data2) => {
1129
+ const parsed = this.parseMsg(data2);
1130
+ if (!parsed) {
1131
+ conn.close();
1132
+ return;
1133
+ }
1134
+ this.handleMsg(parsed);
1135
+ };
1136
+ conn.removeDataListener(handshakeHandler);
1137
+ conn.addDataListener(dataHandler);
1138
+ for (const data2 of buffer) {
1139
+ dataHandler(data2);
1140
+ }
1141
+ buffer.length = 0;
1092
1142
  }
1093
- this.handleMsg(parsed);
1094
- });
1143
+ );
1095
1144
  };
1096
1145
  conn.addDataListener(handshakeHandler);
1097
1146
  conn.addCloseListener(() => {
@@ -1112,7 +1161,7 @@ var ServerTransport = class extends Transport {
1112
1161
  );
1113
1162
  });
1114
1163
  }
1115
- receiveHandshakeRequestMessage(data, conn) {
1164
+ async receiveHandshakeRequestMessage(data, conn) {
1116
1165
  const parsed = this.parseMsg(data);
1117
1166
  if (!parsed) {
1118
1167
  this.protocolError(
@@ -1128,7 +1177,8 @@ var ServerTransport = class extends Transport {
1128
1177
  reason
1129
1178
  });
1130
1179
  conn.send(this.codec.toBuffer(responseMsg2));
1131
- log?.warn(`${reason}: ${JSON.stringify(parsed)}`, {
1180
+ const logData = typeof parsed.payload === "object" ? { ...parsed, payload: { ...parsed.payload, metadata: "redacted" } } : { ...parsed };
1181
+ log?.warn(`${reason}: ${JSON.stringify(logData)}`, {
1132
1182
  clientId: this.clientId,
1133
1183
  connId: conn.debugId
1134
1184
  });
@@ -1153,7 +1203,73 @@ var ServerTransport = class extends Transport {
1153
1203
  this.protocolError(ProtocolError.HandshakeFailed, reason);
1154
1204
  return false;
1155
1205
  }
1156
- const session = this.getOrCreateSession(parsed.from, conn);
1206
+ const { session, isReconnect } = this.getOrCreateSession(
1207
+ parsed.from,
1208
+ conn,
1209
+ parsed.payload.sessionId
1210
+ );
1211
+ let handshakeMetadata;
1212
+ if (this.options.handshake) {
1213
+ if (!import_value.Value.Check(
1214
+ this.options.handshake.requestSchema,
1215
+ parsed.payload.metadata
1216
+ )) {
1217
+ const reason = "received malformed handshake metadata";
1218
+ const responseMsg2 = handshakeResponseMessage(
1219
+ this.clientId,
1220
+ parsed.from,
1221
+ { ok: false, reason }
1222
+ );
1223
+ conn.send(this.codec.toBuffer(responseMsg2));
1224
+ log?.warn(`received malformed handshake metadata from ${parsed.from}`, {
1225
+ clientId: this.clientId,
1226
+ connId: conn.debugId
1227
+ });
1228
+ this.protocolError(ProtocolError.HandshakeFailed, reason);
1229
+ this.deleteSession(session);
1230
+ return false;
1231
+ }
1232
+ const parsedMetadata = await this.options.handshake.parse(
1233
+ parsed.payload.metadata,
1234
+ session,
1235
+ isReconnect
1236
+ );
1237
+ if (parsedMetadata === false) {
1238
+ const reason = "rejected by server";
1239
+ const responseMsg2 = handshakeResponseMessage(
1240
+ this.clientId,
1241
+ parsed.from,
1242
+ { ok: false, reason }
1243
+ );
1244
+ conn.send(this.codec.toBuffer(responseMsg2));
1245
+ log?.warn(`rejected handshake from ${parsed.from}`, {
1246
+ clientId: this.clientId,
1247
+ connId: conn.debugId
1248
+ });
1249
+ this.protocolError(ProtocolError.HandshakeFailed, reason);
1250
+ this.deleteSession(session);
1251
+ return false;
1252
+ }
1253
+ if (!import_value.Value.Check(this.options.handshake.parsedSchema, parsedMetadata)) {
1254
+ const reason = "failed to parse handshake metadata";
1255
+ const responseMsg2 = handshakeResponseMessage(
1256
+ this.clientId,
1257
+ parsed.from,
1258
+ { ok: false, reason }
1259
+ );
1260
+ conn.send(this.codec.toBuffer(responseMsg2));
1261
+ log?.error(`failed to parse handshake metadata`, {
1262
+ clientId: this.clientId,
1263
+ connId: conn.debugId
1264
+ });
1265
+ this.protocolError(ProtocolError.HandshakeFailed, reason);
1266
+ this.deleteSession(session);
1267
+ return false;
1268
+ }
1269
+ handshakeMetadata = parsedMetadata;
1270
+ }
1271
+ handshakeMetadata ??= {};
1272
+ session.metadata = handshakeMetadata;
1157
1273
  log?.debug(
1158
1274
  `handshake from ${parsed.from} ok, responding with handshake success`,
1159
1275
  { clientId: this.clientId, connId: conn.debugId }
@@ -1163,7 +1279,8 @@ var ServerTransport = class extends Transport {
1163
1279
  sessionId: session.id
1164
1280
  });
1165
1281
  conn.send(this.codec.toBuffer(responseMsg));
1166
- return this.onConnect(conn, parsed.from, parsed.payload.sessionId);
1282
+ this.onConnect(conn, parsed.from, session, isReconnect);
1283
+ return session;
1167
1284
  }
1168
1285
  };
1169
1286
  // Annotate the CommonJS export names for ESM import in node: