@replit/river 0.16.2 → 0.17.1

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 (38) hide show
  1. package/dist/{chunk-HZWCU4ZI.js → chunk-4A7FDC2C.js} +1 -1
  2. package/dist/{chunk-SKH3JYHN.js → chunk-7IQO434V.js} +1 -1
  3. package/dist/{chunk-CJGD7CNG.js → chunk-F6KWMEPR.js} +87 -88
  4. package/dist/{chunk-HKVP6XEL.js → chunk-MSAS5CVJ.js} +1 -1
  5. package/dist/{chunk-GFRAOY75.js → chunk-VH3NGOXQ.js} +8 -17
  6. package/dist/{connection-2db95d74.d.ts → connection-0767dc6b.d.ts} +1 -1
  7. package/dist/{connection-c97da681.d.ts → connection-f31edbcd.d.ts} +1 -1
  8. package/dist/{index-c9e9977f.d.ts → index-8df0bdfb.d.ts} +14 -21
  9. package/dist/{procedures-d295c1a5.d.ts → procedures-b5ddb54d.d.ts} +1 -1
  10. package/dist/router/index.cjs +2 -2
  11. package/dist/router/index.d.cts +3 -3
  12. package/dist/router/index.d.ts +3 -3
  13. package/dist/router/index.js +2 -2
  14. package/dist/transport/impls/uds/client.cjs +66 -60
  15. package/dist/transport/impls/uds/client.d.cts +2 -2
  16. package/dist/transport/impls/uds/client.d.ts +2 -2
  17. package/dist/transport/impls/uds/client.js +3 -3
  18. package/dist/transport/impls/uds/server.cjs +78 -91
  19. package/dist/transport/impls/uds/server.d.cts +2 -2
  20. package/dist/transport/impls/uds/server.d.ts +2 -2
  21. package/dist/transport/impls/uds/server.js +3 -3
  22. package/dist/transport/impls/ws/client.cjs +66 -60
  23. package/dist/transport/impls/ws/client.d.cts +2 -2
  24. package/dist/transport/impls/ws/client.d.ts +2 -2
  25. package/dist/transport/impls/ws/client.js +3 -3
  26. package/dist/transport/impls/ws/server.cjs +78 -91
  27. package/dist/transport/impls/ws/server.d.cts +2 -2
  28. package/dist/transport/impls/ws/server.d.ts +2 -2
  29. package/dist/transport/impls/ws/server.js +3 -3
  30. package/dist/transport/index.cjs +93 -106
  31. package/dist/transport/index.d.cts +1 -1
  32. package/dist/transport/index.d.ts +1 -1
  33. package/dist/transport/index.js +2 -2
  34. package/dist/util/testHelpers.cjs +46 -19
  35. package/dist/util/testHelpers.d.cts +4 -9
  36. package/dist/util/testHelpers.d.ts +4 -9
  37. package/dist/util/testHelpers.js +8 -14
  38. package/package.json +1 -1
@@ -48,18 +48,18 @@ var ControlMessageAckSchema = import_typebox.Type.Object({
48
48
  var ControlMessageCloseSchema = import_typebox.Type.Object({
49
49
  type: import_typebox.Type.Literal("CLOSE")
50
50
  });
51
- var PROTOCOL_VERSION = "v1";
51
+ var PROTOCOL_VERSION = "v1.1";
52
52
  var ControlMessageHandshakeRequestSchema = import_typebox.Type.Object({
53
53
  type: import_typebox.Type.Literal("HANDSHAKE_REQ"),
54
54
  protocolVersion: import_typebox.Type.String(),
55
- instanceId: import_typebox.Type.String()
55
+ sessionId: import_typebox.Type.String()
56
56
  });
57
57
  var ControlMessageHandshakeResponseSchema = import_typebox.Type.Object({
58
58
  type: import_typebox.Type.Literal("HANDSHAKE_RESP"),
59
59
  status: import_typebox.Type.Union([
60
60
  import_typebox.Type.Object({
61
61
  ok: import_typebox.Type.Literal(true),
62
- instanceId: import_typebox.Type.String()
62
+ sessionId: import_typebox.Type.String()
63
63
  }),
64
64
  import_typebox.Type.Object({
65
65
  ok: import_typebox.Type.Literal(false),
@@ -76,7 +76,7 @@ var ControlMessagePayloadSchema = import_typebox.Type.Union([
76
76
  var OpaqueTransportMessageSchema = TransportMessageSchema(
77
77
  import_typebox.Type.Unknown()
78
78
  );
79
- function handshakeResponseMessage(from, instanceId, to, ok, reason) {
79
+ function handshakeResponseMessage(from, to, status) {
80
80
  return {
81
81
  id: (0, import_nanoid.nanoid)(),
82
82
  from,
@@ -85,18 +85,9 @@ function handshakeResponseMessage(from, instanceId, to, ok, reason) {
85
85
  ack: 0,
86
86
  streamId: (0, import_nanoid.nanoid)(),
87
87
  controlFlags: 0,
88
- payload: ok ? {
88
+ payload: {
89
89
  type: "HANDSHAKE_RESP",
90
- status: {
91
- ok: true,
92
- instanceId
93
- }
94
- } : {
95
- type: "HANDSHAKE_RESP",
96
- status: {
97
- ok: false,
98
- reason: reason ?? "Unknown reason"
99
- }
90
+ status
100
91
  }
101
92
  };
102
93
  }
@@ -167,7 +158,12 @@ var Session = class {
167
158
  /**
168
159
  * The unique ID of this session.
169
160
  */
170
- debugId;
161
+ id;
162
+ /**
163
+ * What the other side advertised as their session ID
164
+ * for this session.
165
+ */
166
+ advertisedSessionId;
171
167
  /**
172
168
  * Number of messages we've sent along this session (excluding handshake and acks)
173
169
  */
@@ -189,11 +185,11 @@ var Session = class {
189
185
  * The interval for sending heartbeats.
190
186
  */
191
187
  heartbeat;
192
- constructor(from, connectedTo, conn, options) {
188
+ constructor(conn, from, to, options) {
189
+ this.id = `session-${nanoid2(12)}`;
193
190
  this.options = options;
194
- this.debugId = `sess-${unsafeId()}`;
195
191
  this.from = from;
196
- this.to = connectedTo;
192
+ this.to = to;
197
193
  this.connection = conn;
198
194
  this.codec = options.codec;
199
195
  this.heartbeatMisses = 0;
@@ -233,7 +229,7 @@ var Session = class {
233
229
  log?.info(
234
230
  `${this.from} -- closing connection (id: ${this.connection.debugId}) to ${this.to} due to inactivity`
235
231
  );
236
- this.closeStaleConnection(this.connection);
232
+ this.closeStaleConnection();
237
233
  }
238
234
  return;
239
235
  }
@@ -264,33 +260,37 @@ var Session = class {
264
260
  log?.debug(`${this.from} -- resending ${msg.id} (seq: ${msg.seq})`);
265
261
  const ok = this.connection.send(this.codec.toBuffer(msg));
266
262
  if (!ok) {
267
- const msg2 = `${this.from} -- failed to send buffered message to ${this.to} in session (id: ${this.debugId}) (if you hit this code path something is seriously wrong)`;
263
+ const msg2 = `${this.from} -- failed to send buffered message to ${this.to} in session (id: ${this.id}) (if you hit this code path something is seriously wrong)`;
268
264
  log?.error(msg2);
269
265
  throw new Error(msg2);
270
266
  }
271
267
  }
272
268
  }
273
269
  updateBookkeeping(ack, seq) {
274
- this.sendBuffer = this.sendBuffer.filter((unacked) => unacked.seq > ack);
270
+ if (seq + 1 < this.ack) {
271
+ log?.error(`${this.from} -- received stale seq ${seq} + 1 < ${this.ack}`);
272
+ return;
273
+ }
274
+ this.sendBuffer = this.sendBuffer.filter((unacked) => unacked.seq >= ack);
275
275
  this.ack = seq + 1;
276
276
  }
277
277
  closeStaleConnection(conn) {
278
- if (!this.connection || this.connection !== conn)
278
+ if (this.connection === void 0 || this.connection === conn)
279
279
  return;
280
280
  log?.info(
281
- `${this.from} -- closing old inner connection (id: ${this.connection.debugId}) from session (id: ${this.debugId}) to ${this.to}`
281
+ `${this.from} -- closing old inner connection (id: ${this.connection.debugId}) from session (id: ${this.id}) to ${this.to}`
282
282
  );
283
283
  this.connection.close();
284
284
  this.connection = void 0;
285
285
  }
286
286
  replaceWithNewConnection(newConn) {
287
- this.closeStaleConnection(this.connection);
287
+ this.closeStaleConnection(newConn);
288
288
  this.cancelGrace();
289
289
  this.connection = newConn;
290
290
  }
291
291
  beginGrace(cb) {
292
292
  log?.info(
293
- `${this.from} -- starting ${this.options.sessionDisconnectGraceMs}ms grace period until session (id: ${this.debugId}) to ${this.to} is closed`
293
+ `${this.from} -- starting ${this.options.sessionDisconnectGraceMs}ms grace period until session (id: ${this.id}) to ${this.to} is closed`
294
294
  );
295
295
  this.disconnectionGrace = setTimeout(() => {
296
296
  this.close();
@@ -301,11 +301,12 @@ var Session = class {
301
301
  cancelGrace() {
302
302
  this.heartbeatMisses = 0;
303
303
  clearTimeout(this.disconnectionGrace);
304
+ this.disconnectionGrace = void 0;
304
305
  }
305
306
  // closed when we want to discard the whole session
306
307
  // (i.e. shutdown or session disconnect)
307
308
  close() {
308
- this.closeStaleConnection(this.connection);
309
+ this.closeStaleConnection();
309
310
  this.cancelGrace();
310
311
  this.resetBufferedMessages();
311
312
  clearInterval(this.heartbeat);
@@ -334,9 +335,6 @@ var Session = class {
334
335
  }
335
336
  };
336
337
 
337
- // transport/transport.ts
338
- var import_nanoid3 = require("nanoid");
339
-
340
338
  // util/stringify.ts
341
339
  function coerceErrorString(err) {
342
340
  if (err instanceof Error) {
@@ -416,13 +414,6 @@ var defaultClientTransportOptions = {
416
414
  ...defaultConnectionRetryOptions
417
415
  };
418
416
  var Transport = class {
419
- /**
420
- * Unique per instance of the transport.
421
- * This allows us to distinguish reconnects to different
422
- * transports.
423
- */
424
- instanceId = (0, import_nanoid3.nanoid)();
425
- connectedInstanceIds = /* @__PURE__ */ new Map();
426
417
  /**
427
418
  * A flag indicating whether the transport has been destroyed.
428
419
  * A destroyed transport will not attempt to reconnect and cannot be used again.
@@ -475,41 +466,41 @@ var Transport = class {
475
466
  * and we know the identity of the connected client.
476
467
  * @param conn The connection object.
477
468
  */
478
- onConnect(conn, connectedTo, instanceId) {
469
+ onConnect(conn, connectedTo, advertisedSessionId) {
479
470
  this.eventDispatcher.dispatchEvent("connectionStatus", {
480
471
  status: "connect",
481
472
  conn
482
473
  });
483
474
  let oldSession = this.sessions.get(connectedTo);
484
- const lastInstanceId = this.connectedInstanceIds.get(connectedTo);
485
- if (oldSession && lastInstanceId !== void 0 && lastInstanceId !== instanceId) {
475
+ if (oldSession?.advertisedSessionId && oldSession.advertisedSessionId !== advertisedSessionId) {
486
476
  log?.warn(
487
- `${this.clientId} -- connection from ${connectedTo} is a different instance (got: ${instanceId}, last connected to: ${lastInstanceId}), starting a new session`
477
+ `${this.clientId} -- connection from ${connectedTo} is a different session (id: ${advertisedSessionId}, last connected to: ${oldSession.advertisedSessionId}), starting a new session`
488
478
  );
489
479
  oldSession.close();
490
480
  this.deleteSession(oldSession);
491
481
  oldSession = void 0;
492
482
  }
493
- this.connectedInstanceIds.set(connectedTo, instanceId);
494
483
  if (oldSession === void 0) {
495
484
  const newSession = this.createSession(connectedTo, conn);
485
+ newSession.advertisedSessionId = advertisedSessionId;
496
486
  log?.info(
497
- `${this.clientId} -- new connection (id: ${conn.debugId}) for new session (id: ${newSession.debugId}) to ${connectedTo}`
487
+ `${this.clientId} -- new connection (id: ${conn.debugId}) for new session (id: ${newSession.id}) to ${connectedTo}`
498
488
  );
499
489
  return newSession;
500
490
  }
501
491
  log?.info(
502
- `${this.clientId} -- new connection (id: ${conn.debugId}) for existing session (id: ${oldSession.debugId}) to ${connectedTo}`
492
+ `${this.clientId} -- new connection (id: ${conn.debugId}) for existing session (id: ${oldSession.id}) to ${connectedTo}`
503
493
  );
504
494
  oldSession.replaceWithNewConnection(conn);
505
495
  oldSession.sendBufferedMessages();
496
+ oldSession.advertisedSessionId = advertisedSessionId;
506
497
  return oldSession;
507
498
  }
508
- createSession(connectedTo, conn) {
499
+ createSession(to, conn) {
509
500
  const session = new Session(
510
- this.clientId,
511
- connectedTo,
512
501
  conn,
502
+ this.clientId,
503
+ to,
513
504
  this.options
514
505
  );
515
506
  this.sessions.set(session.to, session);
@@ -519,10 +510,20 @@ var Transport = class {
519
510
  });
520
511
  return session;
521
512
  }
513
+ getOrCreateSession(to, conn) {
514
+ let session = this.sessions.get(to);
515
+ if (!session) {
516
+ session = this.createSession(to, conn);
517
+ log?.info(
518
+ `${this.clientId} -- no session for ${to}, created a new one (id: ${session.id})`
519
+ );
520
+ }
521
+ return session;
522
+ }
522
523
  deleteSession(session) {
523
524
  this.sessions.delete(session.to);
524
525
  log?.info(
525
- `${this.clientId} -- session ${session.debugId} disconnect from ${session.to}`
526
+ `${this.clientId} -- session ${session.id} disconnect from ${session.to}`
526
527
  );
527
528
  this.eventDispatcher.dispatchEvent("sessionStatus", {
528
529
  status: "disconnect",
@@ -592,9 +593,12 @@ var Transport = class {
592
593
  } else {
593
594
  const errMsg = `received out-of-order msg (got seq: ${msg.seq}, wanted seq: ${session.nextExpectedSeq})`;
594
595
  log?.error(
595
- `${this.clientId} -- ${errMsg}, marking connection as dead: ${JSON.stringify(msg)}`
596
+ `${this.clientId} -- fatal: ${errMsg}, marking connection as dead: ${JSON.stringify(
597
+ msg
598
+ )}`
596
599
  );
597
600
  this.protocolError(ProtocolError.MessageOrderingViolated, errMsg);
601
+ session.close();
598
602
  }
599
603
  return;
600
604
  }
@@ -641,14 +645,7 @@ var Transport = class {
641
645
  );
642
646
  return void 0;
643
647
  }
644
- let session = this.sessions.get(to);
645
- if (!session) {
646
- session = this.createSession(to, void 0);
647
- log?.info(
648
- `${this.clientId} -- no session for ${to}, created a new one (id: ${session.debugId})`
649
- );
650
- }
651
- return session.send(msg);
648
+ return this.getOrCreateSession(to).send(msg);
652
649
  }
653
650
  // control helpers
654
651
  sendCloseStream(to, streamId) {
@@ -694,7 +691,7 @@ var ServerTransport = class extends Transport {
694
691
  constructor(clientId, providedOptions) {
695
692
  super(clientId, providedOptions);
696
693
  log?.info(
697
- `${this.clientId} -- initiated server transport (instance id: ${this.instanceId}, protocol: ${PROTOCOL_VERSION})`
694
+ `${this.clientId} -- initiated server transport (protocol: ${PROTOCOL_VERSION})`
698
695
  );
699
696
  }
700
697
  handleConnection(conn) {
@@ -706,12 +703,13 @@ var ServerTransport = class extends Transport {
706
703
  let session = void 0;
707
704
  const client = () => session?.to ?? "unknown";
708
705
  const handshakeHandler = (data) => {
709
- const handshake = this.receiveHandshakeRequestMessage(data, conn);
710
- if (!handshake) {
706
+ const maybeSession = this.receiveHandshakeRequestMessage(data, conn);
707
+ if (!maybeSession) {
711
708
  conn.close();
712
709
  return;
710
+ } else {
711
+ session = maybeSession;
713
712
  }
714
- session = this.onConnect(conn, handshake.from, handshake.instanceId);
715
713
  conn.removeDataListener(handshakeHandler);
716
714
  conn.addDataListener((data2) => {
717
715
  const parsed = this.parseMsg(data2);
@@ -749,18 +747,13 @@ var ServerTransport = class extends Transport {
749
747
  return false;
750
748
  }
751
749
  if (!import_value.Value.Check(ControlMessageHandshakeRequestSchema, parsed.payload)) {
752
- const responseMsg2 = handshakeResponseMessage(
753
- this.clientId,
754
- this.instanceId,
755
- parsed.from,
756
- false
757
- );
750
+ const reason = "received invalid handshake msg";
751
+ const responseMsg2 = handshakeResponseMessage(this.clientId, parsed.from, {
752
+ ok: false,
753
+ reason
754
+ });
758
755
  conn.send(this.codec.toBuffer(responseMsg2));
759
- log?.warn(
760
- `${this.clientId} -- received invalid handshake msg: ${JSON.stringify(
761
- parsed
762
- )}`
763
- );
756
+ log?.warn(`${this.clientId} -- ${reason}: ${JSON.stringify(parsed)}`);
764
757
  this.protocolError(
765
758
  ProtocolError.HandshakeFailed,
766
759
  "invalid handshake request"
@@ -769,34 +762,28 @@ var ServerTransport = class extends Transport {
769
762
  }
770
763
  const gotVersion = parsed.payload.protocolVersion;
771
764
  if (gotVersion !== PROTOCOL_VERSION) {
772
- const responseMsg2 = handshakeResponseMessage(
773
- this.clientId,
774
- this.instanceId,
775
- parsed.from,
776
- false
777
- );
765
+ const reason = `incorrect version (got: ${gotVersion} wanted ${PROTOCOL_VERSION})`;
766
+ const responseMsg2 = handshakeResponseMessage(this.clientId, parsed.from, {
767
+ ok: false,
768
+ reason
769
+ });
778
770
  conn.send(this.codec.toBuffer(responseMsg2));
779
771
  log?.warn(
780
772
  `${this.clientId} -- received handshake msg with incompatible protocol version (got: ${gotVersion}, expected: ${PROTOCOL_VERSION})`
781
773
  );
782
- this.protocolError(
783
- ProtocolError.HandshakeFailed,
784
- `incorrect version (got: ${gotVersion} wanted ${PROTOCOL_VERSION})`
785
- );
774
+ this.protocolError(ProtocolError.HandshakeFailed, reason);
786
775
  return false;
787
776
  }
788
- const instanceId = parsed.payload.instanceId;
777
+ const session = this.getOrCreateSession(parsed.from, conn);
789
778
  log?.debug(
790
- `${this.clientId} -- handshake from ${parsed.from} ok (instance id: ${instanceId}), responding with handshake success`
791
- );
792
- const responseMsg = handshakeResponseMessage(
793
- this.clientId,
794
- this.instanceId,
795
- parsed.from,
796
- true
779
+ `${this.clientId} -- handshake from ${parsed.from} ok, responding with handshake success`
797
780
  );
781
+ const responseMsg = handshakeResponseMessage(this.clientId, parsed.from, {
782
+ ok: true,
783
+ sessionId: session.id
784
+ });
798
785
  conn.send(this.codec.toBuffer(responseMsg));
799
- return { instanceId, from: parsed.from };
786
+ return this.onConnect(conn, parsed.from, parsed.payload.sessionId);
800
787
  }
801
788
  };
802
789
 
@@ -1,7 +1,7 @@
1
- import { S as ServerTransport, b as TransportClientId, d as ProvidedTransportOptions } from '../../../index-c9e9977f.js';
1
+ import { d as ServerTransport, b as TransportClientId, e as ProvidedTransportOptions } from '../../../index-8df0bdfb.js';
2
2
  import { WebSocketServer } from 'ws';
3
3
  import { WebSocket } from 'isomorphic-ws';
4
- import { W as WebSocketConnection } from '../../../connection-c97da681.js';
4
+ import { W as WebSocketConnection } from '../../../connection-f31edbcd.js';
5
5
  import '../../../types-3e5768ec.js';
6
6
  import '@sinclair/typebox';
7
7
 
@@ -1,7 +1,7 @@
1
- import { S as ServerTransport, b as TransportClientId, d as ProvidedTransportOptions } from '../../../index-c9e9977f.js';
1
+ import { d as ServerTransport, b as TransportClientId, e as ProvidedTransportOptions } from '../../../index-8df0bdfb.js';
2
2
  import { WebSocketServer } from 'ws';
3
3
  import { WebSocket } from 'isomorphic-ws';
4
- import { W as WebSocketConnection } from '../../../connection-c97da681.js';
4
+ import { W as WebSocketConnection } from '../../../connection-f31edbcd.js';
5
5
  import '../../../types-3e5768ec.js';
6
6
  import '@sinclair/typebox';
7
7
 
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  WebSocketConnection
3
- } from "../../../chunk-HKVP6XEL.js";
3
+ } from "../../../chunk-MSAS5CVJ.js";
4
4
  import {
5
5
  ServerTransport
6
- } from "../../../chunk-CJGD7CNG.js";
7
- import "../../../chunk-GFRAOY75.js";
6
+ } from "../../../chunk-F6KWMEPR.js";
7
+ import "../../../chunk-VH3NGOXQ.js";
8
8
  import "../../../chunk-H4BYJELI.js";
9
9
  import "../../../chunk-GZ7HCLLM.js";
10
10