@replit/river 0.15.1 → 0.15.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 (35) hide show
  1. package/README.md +41 -22
  2. package/dist/{builder-660d3140.d.ts → builder-ebd945c0.d.ts} +1 -1
  3. package/dist/{chunk-O6YQ3JAH.js → chunk-B7VTDQR7.js} +147 -37
  4. package/dist/{chunk-MNWOTQWX.js → chunk-UJHTHOTT.js} +1 -1
  5. package/dist/{chunk-5TX4BKAD.js → chunk-ZRB6IKPV.js} +1 -1
  6. package/dist/{connection-162c0f7b.d.ts → connection-10a24478.d.ts} +1 -1
  7. package/dist/{connection-93daccc3.d.ts → connection-f4492948.d.ts} +1 -1
  8. package/dist/{index-76b801f8.d.ts → index-bbccacef.d.ts} +84 -11
  9. package/dist/router/index.d.cts +3 -3
  10. package/dist/router/index.d.ts +3 -3
  11. package/dist/transport/impls/uds/client.cjs +197 -88
  12. package/dist/transport/impls/uds/client.d.cts +3 -3
  13. package/dist/transport/impls/uds/client.d.ts +3 -3
  14. package/dist/transport/impls/uds/client.js +2 -2
  15. package/dist/transport/impls/uds/server.cjs +66 -69
  16. package/dist/transport/impls/uds/server.d.cts +3 -3
  17. package/dist/transport/impls/uds/server.d.ts +3 -3
  18. package/dist/transport/impls/uds/server.js +2 -2
  19. package/dist/transport/impls/ws/client.cjs +197 -90
  20. package/dist/transport/impls/ws/client.d.cts +3 -3
  21. package/dist/transport/impls/ws/client.d.ts +3 -3
  22. package/dist/transport/impls/ws/client.js +2 -2
  23. package/dist/transport/impls/ws/server.cjs +66 -69
  24. package/dist/transport/impls/ws/server.d.cts +3 -3
  25. package/dist/transport/impls/ws/server.d.ts +3 -3
  26. package/dist/transport/impls/ws/server.js +2 -2
  27. package/dist/transport/index.cjs +197 -90
  28. package/dist/transport/index.d.cts +1 -1
  29. package/dist/transport/index.d.ts +1 -1
  30. package/dist/transport/index.js +1 -1
  31. package/dist/util/testHelpers.cjs +61 -64
  32. package/dist/util/testHelpers.d.cts +10 -4
  33. package/dist/util/testHelpers.d.ts +10 -4
  34. package/dist/util/testHelpers.js +13 -5
  35. package/package.json +1 -1
@@ -165,60 +165,6 @@ var EventDispatcher = class {
165
165
 
166
166
  // transport/session.ts
167
167
  var import_nanoid2 = require("nanoid");
168
-
169
- // codec/json.ts
170
- var encoder = new TextEncoder();
171
- var decoder = new TextDecoder();
172
- function uint8ArrayToBase64(uint8Array) {
173
- let binary = "";
174
- uint8Array.forEach((byte) => {
175
- binary += String.fromCharCode(byte);
176
- });
177
- return btoa(binary);
178
- }
179
- function base64ToUint8Array(base64) {
180
- const binaryString = atob(base64);
181
- const uint8Array = new Uint8Array(binaryString.length);
182
- for (let i = 0; i < binaryString.length; i++) {
183
- uint8Array[i] = binaryString.charCodeAt(i);
184
- }
185
- return uint8Array;
186
- }
187
- var NaiveJsonCodec = {
188
- toBuffer: (obj) => {
189
- return encoder.encode(
190
- JSON.stringify(obj, function replacer(key) {
191
- const val = this[key];
192
- if (val instanceof Uint8Array) {
193
- return { $t: uint8ArrayToBase64(val) };
194
- } else {
195
- return val;
196
- }
197
- })
198
- );
199
- },
200
- fromBuffer: (buff) => {
201
- try {
202
- const parsed = JSON.parse(
203
- decoder.decode(buff),
204
- function reviver(_key, val) {
205
- if (val?.$t) {
206
- return base64ToUint8Array(val.$t);
207
- } else {
208
- return val;
209
- }
210
- }
211
- );
212
- if (typeof parsed === "object")
213
- return parsed;
214
- return null;
215
- } catch {
216
- return null;
217
- }
218
- }
219
- };
220
-
221
- // transport/session.ts
222
168
  var nanoid2 = (0, import_nanoid2.customAlphabet)("1234567890abcdefghijklmnopqrstuvxyz", 6);
223
169
  var unsafeId = () => nanoid2();
224
170
  var Connection = class {
@@ -227,15 +173,6 @@ var Connection = class {
227
173
  this.debugId = `conn-${unsafeId()}`;
228
174
  }
229
175
  };
230
- var HEARTBEAT_INTERVAL_MS = 1e3;
231
- var HEARTBEATS_TILL_DEAD = 2;
232
- var SESSION_DISCONNECT_GRACE_MS = 5e3;
233
- var defaultSessionOptions = {
234
- heartbeatIntervalMs: HEARTBEAT_INTERVAL_MS,
235
- heartbeatsUntilDead: HEARTBEATS_TILL_DEAD,
236
- sessionDisconnectGraceMs: SESSION_DISCONNECT_GRACE_MS,
237
- codec: NaiveJsonCodec
238
- };
239
176
  var Session = class {
240
177
  codec;
241
178
  options;
@@ -430,14 +367,146 @@ function coerceErrorString(err) {
430
367
  return `[coerced to error] ${String(err)}`;
431
368
  }
432
369
 
370
+ // transport/rateLimit.ts
371
+ var LeakyBucketRateLimit = class {
372
+ budgetConsumed;
373
+ intervalHandles;
374
+ options;
375
+ constructor(options) {
376
+ this.options = options;
377
+ this.budgetConsumed = /* @__PURE__ */ new Map();
378
+ this.intervalHandles = /* @__PURE__ */ new Map();
379
+ }
380
+ getBackoffMs(user) {
381
+ if (!this.budgetConsumed.has(user))
382
+ return 0;
383
+ const exponent = Math.max(0, this.getBudgetConsumed(user) - 1);
384
+ const jitter = Math.floor(Math.random() * this.options.maxJitterMs);
385
+ const backoffMs = Math.min(
386
+ this.options.baseIntervalMs * 2 ** exponent,
387
+ this.options.maxBackoffMs
388
+ );
389
+ return backoffMs + jitter;
390
+ }
391
+ get totalBudgetRestoreTime() {
392
+ return this.options.budgetRestoreIntervalMs * this.options.attemptBudgetCapacity;
393
+ }
394
+ consumeBudget(user) {
395
+ this.stopLeak(user);
396
+ this.budgetConsumed.set(user, this.getBudgetConsumed(user) + 1);
397
+ }
398
+ getBudgetConsumed(user) {
399
+ return this.budgetConsumed.get(user) ?? 0;
400
+ }
401
+ hasBudget(user) {
402
+ return this.getBudgetConsumed(user) < this.options.attemptBudgetCapacity;
403
+ }
404
+ startRestoringBudget(user) {
405
+ if (this.intervalHandles.has(user)) {
406
+ return;
407
+ }
408
+ const restoreBudgetForUser = () => {
409
+ const currentBudget = this.budgetConsumed.get(user);
410
+ if (!currentBudget) {
411
+ this.stopLeak(user);
412
+ return;
413
+ }
414
+ const newBudget = currentBudget - 1;
415
+ if (newBudget === 0) {
416
+ this.budgetConsumed.delete(user);
417
+ return;
418
+ }
419
+ this.budgetConsumed.set(user, newBudget);
420
+ };
421
+ restoreBudgetForUser();
422
+ const intervalHandle = setInterval(
423
+ restoreBudgetForUser,
424
+ this.options.budgetRestoreIntervalMs
425
+ );
426
+ this.intervalHandles.set(user, intervalHandle);
427
+ }
428
+ stopLeak(user) {
429
+ if (!this.intervalHandles.has(user)) {
430
+ return;
431
+ }
432
+ clearInterval(this.intervalHandles.get(user));
433
+ this.intervalHandles.delete(user);
434
+ }
435
+ close() {
436
+ for (const user of this.intervalHandles.keys()) {
437
+ this.stopLeak(user);
438
+ }
439
+ }
440
+ };
441
+
442
+ // codec/json.ts
443
+ var encoder = new TextEncoder();
444
+ var decoder = new TextDecoder();
445
+ function uint8ArrayToBase64(uint8Array) {
446
+ let binary = "";
447
+ uint8Array.forEach((byte) => {
448
+ binary += String.fromCharCode(byte);
449
+ });
450
+ return btoa(binary);
451
+ }
452
+ function base64ToUint8Array(base64) {
453
+ const binaryString = atob(base64);
454
+ const uint8Array = new Uint8Array(binaryString.length);
455
+ for (let i = 0; i < binaryString.length; i++) {
456
+ uint8Array[i] = binaryString.charCodeAt(i);
457
+ }
458
+ return uint8Array;
459
+ }
460
+ var NaiveJsonCodec = {
461
+ toBuffer: (obj) => {
462
+ return encoder.encode(
463
+ JSON.stringify(obj, function replacer(key) {
464
+ const val = this[key];
465
+ if (val instanceof Uint8Array) {
466
+ return { $t: uint8ArrayToBase64(val) };
467
+ } else {
468
+ return val;
469
+ }
470
+ })
471
+ );
472
+ },
473
+ fromBuffer: (buff) => {
474
+ try {
475
+ const parsed = JSON.parse(
476
+ decoder.decode(buff),
477
+ function reviver(_key, val) {
478
+ if (val?.$t) {
479
+ return base64ToUint8Array(val.$t);
480
+ } else {
481
+ return val;
482
+ }
483
+ }
484
+ );
485
+ if (typeof parsed === "object")
486
+ return parsed;
487
+ return null;
488
+ } catch {
489
+ return null;
490
+ }
491
+ }
492
+ };
493
+
433
494
  // transport/transport.ts
434
- var RECONNECT_JITTER_MAX_MS = 500;
435
- var RECONNECT_INTERVAL_MS = 250;
436
495
  var defaultTransportOptions = {
437
- retryIntervalMs: RECONNECT_INTERVAL_MS,
438
- retryJitterMs: RECONNECT_JITTER_MAX_MS,
439
- retryAttemptsMax: 5,
440
- ...defaultSessionOptions
496
+ heartbeatIntervalMs: 1e3,
497
+ heartbeatsUntilDead: 2,
498
+ sessionDisconnectGraceMs: 5e3,
499
+ codec: NaiveJsonCodec
500
+ };
501
+ var defaultClientTransportOptions = {
502
+ connectionRetryOptions: {
503
+ baseIntervalMs: 250,
504
+ maxJitterMs: 200,
505
+ maxBackoffMs: 32e3,
506
+ attemptBudgetCapacity: 15,
507
+ budgetRestoreIntervalMs: 200
508
+ },
509
+ ...defaultTransportOptions
441
510
  };
442
511
  var Transport = class {
443
512
  /**
@@ -712,14 +781,26 @@ var Transport = class {
712
781
  }
713
782
  };
714
783
  var ClientTransport = class extends Transport {
784
+ /**
785
+ * The options for this transport.
786
+ */
787
+ options;
715
788
  /**
716
789
  * The map of reconnect promises for each client ID.
717
790
  */
718
791
  inflightConnectionPromises;
792
+ retryBudget;
719
793
  tryReconnecting = true;
720
794
  constructor(clientId, providedOptions) {
721
795
  super(clientId, providedOptions);
796
+ this.options = {
797
+ ...defaultClientTransportOptions,
798
+ ...providedOptions
799
+ };
722
800
  this.inflightConnectionPromises = /* @__PURE__ */ new Map();
801
+ this.retryBudget = new LeakyBucketRateLimit(
802
+ this.options.connectionRetryOptions
803
+ );
723
804
  }
724
805
  handleConnection(conn, to) {
725
806
  if (this.state !== "open")
@@ -750,7 +831,10 @@ var ClientTransport = class extends Transport {
750
831
  log?.info(
751
832
  `${this.clientId} -- connection (id: ${conn.debugId}) to ${to} disconnected`
752
833
  );
753
- void this.connect(to);
834
+ this.inflightConnectionPromises.delete(to);
835
+ if (this.tryReconnecting) {
836
+ void this.connect(to);
837
+ }
754
838
  });
755
839
  conn.addErrorListener((err) => {
756
840
  log?.warn(
@@ -801,41 +885,64 @@ var ClientTransport = class extends Transport {
801
885
  * Manually attempts to connect to a client.
802
886
  * @param to The client ID of the node to connect to.
803
887
  */
804
- async connect(to, attempt = 0) {
805
- if (this.state !== "open" || !this.tryReconnecting) {
888
+ async connect(to) {
889
+ const canProceedWithConnection = () => this.state === "open";
890
+ if (!canProceedWithConnection()) {
806
891
  log?.info(
807
- `${this.clientId} -- transport state is no longer open, not attempting connection`
892
+ `${this.clientId} -- transport state is no longer open, cancelling attempt to connect to ${to}`
808
893
  );
809
894
  return;
810
895
  }
811
896
  let reconnectPromise = this.inflightConnectionPromises.get(to);
812
897
  if (!reconnectPromise) {
813
- reconnectPromise = this.createNewOutgoingConnection(to).then((conn) => {
898
+ log?.info(`${this.clientId} -- attempting connection to ${to}`);
899
+ const budgetConsumed = this.retryBudget.getBudgetConsumed(to);
900
+ if (!this.retryBudget.hasBudget(to)) {
901
+ const errMsg = `not attempting to connect to ${to}, retry budget exceeded (more than ${budgetConsumed} attempts in the last ${this.retryBudget.totalBudgetRestoreTime}ms)`;
902
+ log?.warn(`${this.clientId} -- ${errMsg}`);
903
+ this.protocolError(ProtocolError.RetriesExceeded, errMsg);
904
+ return;
905
+ }
906
+ let sleep = Promise.resolve();
907
+ const backoffMs = this.retryBudget.getBackoffMs(to);
908
+ if (backoffMs > 0) {
909
+ sleep = new Promise((resolve) => setTimeout(resolve, backoffMs));
910
+ }
911
+ this.retryBudget.consumeBudget(to);
912
+ reconnectPromise = sleep.then(() => {
913
+ if (!canProceedWithConnection()) {
914
+ throw new Error("transport state is no longer open");
915
+ }
916
+ }).then(() => this.createNewOutgoingConnection(to)).then((conn) => {
917
+ if (!canProceedWithConnection()) {
918
+ log?.info(
919
+ `${this.clientId} -- transport state is no longer open, closing pre-handshake connection (id: ${conn.debugId}) to ${to}`
920
+ );
921
+ conn.close();
922
+ throw new Error("transport state is no longer open");
923
+ }
924
+ this.retryBudget.startRestoringBudget(to);
814
925
  this.sendHandshake(to, conn);
815
926
  return conn;
816
927
  });
817
928
  this.inflightConnectionPromises.set(to, reconnectPromise);
929
+ } else {
930
+ log?.info(
931
+ `${this.clientId} -- attempting connection to ${to} (reusing previous attempt)`
932
+ );
818
933
  }
819
934
  try {
820
935
  await reconnectPromise;
821
936
  } catch (error) {
822
- const errStr = coerceErrorString(error);
823
937
  this.inflightConnectionPromises.delete(to);
824
- const shouldRetry = this.state === "open" && this.tryReconnecting;
825
- if (!shouldRetry)
826
- return;
827
- if (attempt >= this.options.retryAttemptsMax) {
828
- const errMsg = `connection to ${to} failed after ${attempt} attempts (${errStr}), giving up`;
829
- log?.error(`${this.clientId} -- ${errMsg}`);
830
- this.protocolError(ProtocolError.RetriesExceeded, errMsg);
831
- return;
938
+ const errStr = coerceErrorString(error);
939
+ if (!this.tryReconnecting || !canProceedWithConnection()) {
940
+ log?.warn(`${this.clientId} -- connection to ${to} failed (${errStr})`);
832
941
  } else {
833
- const jitter = Math.floor(Math.random() * this.options.retryJitterMs);
834
- const backoffMs = this.options.retryIntervalMs * 2 ** attempt + jitter;
835
942
  log?.warn(
836
- `${this.clientId} -- connection to ${to} failed (${errStr}), trying again in ${backoffMs}ms`
943
+ `${this.clientId} -- connection to ${to} failed (${errStr}), retrying`
837
944
  );
838
- setTimeout(() => void this.connect(to, attempt + 1), backoffMs);
945
+ return this.connect(to);
839
946
  }
840
947
  }
841
948
  }
@@ -848,9 +955,9 @@ var ClientTransport = class extends Transport {
848
955
  log?.debug(`${this.clientId} -- sending handshake request to ${to}`);
849
956
  conn.send(this.codec.toBuffer(requestMsg));
850
957
  }
851
- onDisconnect(conn, session) {
852
- this.inflightConnectionPromises.delete(session.to);
853
- super.onDisconnect(conn, session);
958
+ close() {
959
+ this.retryBudget.close();
960
+ super.close();
854
961
  }
855
962
  };
856
963
  var ServerTransport = class extends Transport {
@@ -1,3 +1,3 @@
1
- export { a as ClientTransport, C as Connection, l as EventHandler, E as EventMap, k as EventTypes, O as OpaqueTransportMessage, g as OpaqueTransportMessageSchema, m as ProtocolError, n as ProtocolErrorType, S as ServerTransport, d as Session, T as Transport, b as TransportClientId, h as TransportMessage, f as TransportMessageSchema, c as TransportOptions, e as TransportStatus, j as isStreamClose, i as isStreamOpen } from '../index-76b801f8.js';
1
+ export { a as ClientTransport, c as ClientTransportOptions, C as Connection, m as EventHandler, E as EventMap, l as EventTypes, O as OpaqueTransportMessage, h as OpaqueTransportMessageSchema, n as ProtocolError, o as ProtocolErrorType, d as ServerTransporOptions, S as ServerTransport, e as Session, T as Transport, b as TransportClientId, i as TransportMessage, g as TransportMessageSchema, f as TransportStatus, k as isStreamClose, j as isStreamOpen } from '../index-bbccacef.js';
2
2
  import '../types-3e5768ec.js';
3
3
  import '@sinclair/typebox';
@@ -1,3 +1,3 @@
1
- export { a as ClientTransport, C as Connection, l as EventHandler, E as EventMap, k as EventTypes, O as OpaqueTransportMessage, g as OpaqueTransportMessageSchema, m as ProtocolError, n as ProtocolErrorType, S as ServerTransport, d as Session, T as Transport, b as TransportClientId, h as TransportMessage, f as TransportMessageSchema, c as TransportOptions, e as TransportStatus, j as isStreamClose, i as isStreamOpen } from '../index-76b801f8.js';
1
+ export { a as ClientTransport, c as ClientTransportOptions, C as Connection, m as EventHandler, E as EventMap, l as EventTypes, O as OpaqueTransportMessage, h as OpaqueTransportMessageSchema, n as ProtocolError, o as ProtocolErrorType, d as ServerTransporOptions, S as ServerTransport, e as Session, T as Transport, b as TransportClientId, i as TransportMessage, g as TransportMessageSchema, f as TransportStatus, k as isStreamClose, j as isStreamOpen } from '../index-bbccacef.js';
2
2
  import '../types-3e5768ec.js';
3
3
  import '@sinclair/typebox';
@@ -6,7 +6,7 @@ import {
6
6
  ServerTransport,
7
7
  Session,
8
8
  Transport
9
- } from "../chunk-O6YQ3JAH.js";
9
+ } from "../chunk-B7VTDQR7.js";
10
10
  import {
11
11
  OpaqueTransportMessageSchema,
12
12
  TransportMessageSchema
@@ -42,6 +42,7 @@ __export(testHelpers_exports, {
42
42
  onUdsServeReady: () => onUdsServeReady,
43
43
  onWsServerReady: () => onWsServerReady,
44
44
  payloadToTransportMessage: () => payloadToTransportMessage,
45
+ testingSessionOptions: () => testingSessionOptions,
45
46
  waitForMessage: () => waitForMessage
46
47
  });
47
48
  module.exports = __toCommonJS(testHelpers_exports);
@@ -53,71 +54,8 @@ var log;
53
54
 
54
55
  // transport/session.ts
55
56
  var import_nanoid = require("nanoid");
56
-
57
- // codec/json.ts
58
- var encoder = new TextEncoder();
59
- var decoder = new TextDecoder();
60
- function uint8ArrayToBase64(uint8Array) {
61
- let binary = "";
62
- uint8Array.forEach((byte) => {
63
- binary += String.fromCharCode(byte);
64
- });
65
- return btoa(binary);
66
- }
67
- function base64ToUint8Array(base64) {
68
- const binaryString = atob(base64);
69
- const uint8Array = new Uint8Array(binaryString.length);
70
- for (let i = 0; i < binaryString.length; i++) {
71
- uint8Array[i] = binaryString.charCodeAt(i);
72
- }
73
- return uint8Array;
74
- }
75
- var NaiveJsonCodec = {
76
- toBuffer: (obj) => {
77
- return encoder.encode(
78
- JSON.stringify(obj, function replacer(key) {
79
- const val = this[key];
80
- if (val instanceof Uint8Array) {
81
- return { $t: uint8ArrayToBase64(val) };
82
- } else {
83
- return val;
84
- }
85
- })
86
- );
87
- },
88
- fromBuffer: (buff) => {
89
- try {
90
- const parsed = JSON.parse(
91
- decoder.decode(buff),
92
- function reviver(_key, val) {
93
- if (val?.$t) {
94
- return base64ToUint8Array(val.$t);
95
- } else {
96
- return val;
97
- }
98
- }
99
- );
100
- if (typeof parsed === "object")
101
- return parsed;
102
- return null;
103
- } catch {
104
- return null;
105
- }
106
- }
107
- };
108
-
109
- // transport/session.ts
110
57
  var nanoid = (0, import_nanoid.customAlphabet)("1234567890abcdefghijklmnopqrstuvxyz", 6);
111
58
  var unsafeId = () => nanoid();
112
- var HEARTBEAT_INTERVAL_MS = 1e3;
113
- var HEARTBEATS_TILL_DEAD = 2;
114
- var SESSION_DISCONNECT_GRACE_MS = 5e3;
115
- var defaultSessionOptions = {
116
- heartbeatIntervalMs: HEARTBEAT_INTERVAL_MS,
117
- heartbeatsUntilDead: HEARTBEATS_TILL_DEAD,
118
- sessionDisconnectGraceMs: SESSION_DISCONNECT_GRACE_MS,
119
- codec: NaiveJsonCodec
120
- };
121
59
  var Session = class {
122
60
  codec;
123
61
  options;
@@ -309,6 +247,58 @@ function coerceErrorString(err) {
309
247
  return `[coerced to error] ${String(err)}`;
310
248
  }
311
249
 
250
+ // codec/json.ts
251
+ var encoder = new TextEncoder();
252
+ var decoder = new TextDecoder();
253
+ function uint8ArrayToBase64(uint8Array) {
254
+ let binary = "";
255
+ uint8Array.forEach((byte) => {
256
+ binary += String.fromCharCode(byte);
257
+ });
258
+ return btoa(binary);
259
+ }
260
+ function base64ToUint8Array(base64) {
261
+ const binaryString = atob(base64);
262
+ const uint8Array = new Uint8Array(binaryString.length);
263
+ for (let i = 0; i < binaryString.length; i++) {
264
+ uint8Array[i] = binaryString.charCodeAt(i);
265
+ }
266
+ return uint8Array;
267
+ }
268
+ var NaiveJsonCodec = {
269
+ toBuffer: (obj) => {
270
+ return encoder.encode(
271
+ JSON.stringify(obj, function replacer(key) {
272
+ const val = this[key];
273
+ if (val instanceof Uint8Array) {
274
+ return { $t: uint8ArrayToBase64(val) };
275
+ } else {
276
+ return val;
277
+ }
278
+ })
279
+ );
280
+ },
281
+ fromBuffer: (buff) => {
282
+ try {
283
+ const parsed = JSON.parse(
284
+ decoder.decode(buff),
285
+ function reviver(_key, val) {
286
+ if (val?.$t) {
287
+ return base64ToUint8Array(val.$t);
288
+ } else {
289
+ return val;
290
+ }
291
+ }
292
+ );
293
+ if (typeof parsed === "object")
294
+ return parsed;
295
+ return null;
296
+ } catch {
297
+ return null;
298
+ }
299
+ }
300
+ };
301
+
312
302
  // node_modules/p-defer/index.js
313
303
  function pDefer() {
314
304
  const deferred = {};
@@ -673,12 +663,18 @@ function catchProcError(err) {
673
663
  }
674
664
  };
675
665
  }
666
+ var testingSessionOptions = {
667
+ heartbeatIntervalMs: 1e3,
668
+ heartbeatsUntilDead: 2,
669
+ sessionDisconnectGraceMs: 5e3,
670
+ codec: NaiveJsonCodec
671
+ };
676
672
  function dummyCtx(state, extendedContext) {
677
673
  const session = new Session(
678
674
  "client",
679
675
  "SERVER",
680
676
  void 0,
681
- defaultSessionOptions
677
+ testingSessionOptions
682
678
  );
683
679
  return {
684
680
  ...extendedContext,
@@ -750,5 +746,6 @@ var getUnixSocketPath = () => {
750
746
  onUdsServeReady,
751
747
  onWsServerReady,
752
748
  payloadToTransportMessage,
749
+ testingSessionOptions,
753
750
  waitForMessage
754
751
  });
@@ -1,11 +1,11 @@
1
1
  import * as it_pushable from 'it-pushable';
2
+ import { C as Codec } from '../types-3e5768ec.js';
2
3
  import WebSocket from 'isomorphic-ws';
3
4
  import http from 'node:http';
4
- import { P as PartialTransportMessage, T as Transport, C as Connection, O as OpaqueTransportMessage } from '../index-76b801f8.js';
5
- import { P as PayloadType, R as RiverError, a as Procedure, S as ServiceContext, b as Result, c as RiverUncaughtSchema } from '../builder-660d3140.js';
5
+ import { P as PartialTransportMessage, T as Transport, C as Connection, O as OpaqueTransportMessage } from '../index-bbccacef.js';
6
+ import { P as PayloadType, R as RiverError, a as Procedure, S as ServiceContext, b as Result, c as RiverUncaughtSchema } from '../builder-ebd945c0.js';
6
7
  import { Static } from '@sinclair/typebox';
7
8
  import net from 'node:net';
8
- import '../types-3e5768ec.js';
9
9
 
10
10
  /**
11
11
  * Creates a WebSocket server instance using the provided HTTP server.
@@ -48,6 +48,12 @@ declare function createDummyTransportMessage(): PartialTransportMessage<{
48
48
  * @returns A promise that resolves with the payload of the first message that passes the filter.
49
49
  */
50
50
  declare function waitForMessage(t: Transport<Connection>, filter?: (msg: OpaqueTransportMessage) => boolean, rejectMismatch?: boolean): Promise<unknown>;
51
+ declare const testingSessionOptions: {
52
+ heartbeatIntervalMs: number;
53
+ heartbeatsUntilDead: number;
54
+ sessionDisconnectGraceMs: number;
55
+ codec: Codec;
56
+ };
51
57
  declare function asClientRpc<State extends object, I extends PayloadType, O extends PayloadType, E extends RiverError, Init extends PayloadType | null = null>(state: State, proc: Procedure<State, 'rpc', I, O, E, Init>, extendedContext?: Omit<ServiceContext, 'state'>): (msg: Static<I>) => Promise<Result<Static<O>, Static<E> | Static<typeof RiverUncaughtSchema>>>;
52
58
  declare function asClientStream<State extends object, I extends PayloadType, O extends PayloadType, E extends RiverError, Init extends PayloadType | null = null>(state: State, proc: Procedure<State, 'stream', I, O, E, Init>, init?: Init extends PayloadType ? Static<Init> : null, extendedContext?: Omit<ServiceContext, 'state'>): readonly [it_pushable.Pushable<Static<I>, void, unknown>, it_pushable.Pushable<Result<Static<O>, Static<E>>, void, unknown>];
53
59
  declare function asClientSubscription<State extends object, I extends PayloadType, O extends PayloadType, E extends RiverError>(state: State, proc: Procedure<State, 'subscription', I, O, E>, extendedContext?: Omit<ServiceContext, 'state'>): (msg: Static<I>) => it_pushable.Pushable<Result<Static<O>, Static<E>>, void, unknown>;
@@ -60,4 +66,4 @@ declare function asClientUpload<State extends object, I extends PayloadType, O e
60
66
  } | Result<Static<O>, Static<E>>>];
61
67
  declare const getUnixSocketPath: () => string;
62
68
 
63
- export { asClientRpc, asClientStream, asClientSubscription, asClientUpload, createDummyTransportMessage, createLocalWebSocketClient, createWebSocketServer, getUnixSocketPath, iterNext, onUdsServeReady, onWsServerReady, payloadToTransportMessage, waitForMessage };
69
+ export { asClientRpc, asClientStream, asClientSubscription, asClientUpload, createDummyTransportMessage, createLocalWebSocketClient, createWebSocketServer, getUnixSocketPath, iterNext, onUdsServeReady, onWsServerReady, payloadToTransportMessage, testingSessionOptions, waitForMessage };
@@ -1,11 +1,11 @@
1
1
  import * as it_pushable from 'it-pushable';
2
+ import { C as Codec } from '../types-3e5768ec.js';
2
3
  import WebSocket from 'isomorphic-ws';
3
4
  import http from 'node:http';
4
- import { P as PartialTransportMessage, T as Transport, C as Connection, O as OpaqueTransportMessage } from '../index-76b801f8.js';
5
- import { P as PayloadType, R as RiverError, a as Procedure, S as ServiceContext, b as Result, c as RiverUncaughtSchema } from '../builder-660d3140.js';
5
+ import { P as PartialTransportMessage, T as Transport, C as Connection, O as OpaqueTransportMessage } from '../index-bbccacef.js';
6
+ import { P as PayloadType, R as RiverError, a as Procedure, S as ServiceContext, b as Result, c as RiverUncaughtSchema } from '../builder-ebd945c0.js';
6
7
  import { Static } from '@sinclair/typebox';
7
8
  import net from 'node:net';
8
- import '../types-3e5768ec.js';
9
9
 
10
10
  /**
11
11
  * Creates a WebSocket server instance using the provided HTTP server.
@@ -48,6 +48,12 @@ declare function createDummyTransportMessage(): PartialTransportMessage<{
48
48
  * @returns A promise that resolves with the payload of the first message that passes the filter.
49
49
  */
50
50
  declare function waitForMessage(t: Transport<Connection>, filter?: (msg: OpaqueTransportMessage) => boolean, rejectMismatch?: boolean): Promise<unknown>;
51
+ declare const testingSessionOptions: {
52
+ heartbeatIntervalMs: number;
53
+ heartbeatsUntilDead: number;
54
+ sessionDisconnectGraceMs: number;
55
+ codec: Codec;
56
+ };
51
57
  declare function asClientRpc<State extends object, I extends PayloadType, O extends PayloadType, E extends RiverError, Init extends PayloadType | null = null>(state: State, proc: Procedure<State, 'rpc', I, O, E, Init>, extendedContext?: Omit<ServiceContext, 'state'>): (msg: Static<I>) => Promise<Result<Static<O>, Static<E> | Static<typeof RiverUncaughtSchema>>>;
52
58
  declare function asClientStream<State extends object, I extends PayloadType, O extends PayloadType, E extends RiverError, Init extends PayloadType | null = null>(state: State, proc: Procedure<State, 'stream', I, O, E, Init>, init?: Init extends PayloadType ? Static<Init> : null, extendedContext?: Omit<ServiceContext, 'state'>): readonly [it_pushable.Pushable<Static<I>, void, unknown>, it_pushable.Pushable<Result<Static<O>, Static<E>>, void, unknown>];
53
59
  declare function asClientSubscription<State extends object, I extends PayloadType, O extends PayloadType, E extends RiverError>(state: State, proc: Procedure<State, 'subscription', I, O, E>, extendedContext?: Omit<ServiceContext, 'state'>): (msg: Static<I>) => it_pushable.Pushable<Result<Static<O>, Static<E>>, void, unknown>;
@@ -60,4 +66,4 @@ declare function asClientUpload<State extends object, I extends PayloadType, O e
60
66
  } | Result<Static<O>, Static<E>>>];
61
67
  declare const getUnixSocketPath: () => string;
62
68
 
63
- export { asClientRpc, asClientStream, asClientSubscription, asClientUpload, createDummyTransportMessage, createLocalWebSocketClient, createWebSocketServer, getUnixSocketPath, iterNext, onUdsServeReady, onWsServerReady, payloadToTransportMessage, waitForMessage };
69
+ export { asClientRpc, asClientStream, asClientSubscription, asClientUpload, createDummyTransportMessage, createLocalWebSocketClient, createWebSocketServer, getUnixSocketPath, iterNext, onUdsServeReady, onWsServerReady, payloadToTransportMessage, testingSessionOptions, waitForMessage };
@@ -4,14 +4,15 @@ import {
4
4
  } from "../chunk-KWXQLQAF.js";
5
5
  import "../chunk-RPIDSIQG.js";
6
6
  import {
7
- Session,
8
- defaultSessionOptions
9
- } from "../chunk-O6YQ3JAH.js";
7
+ Session
8
+ } from "../chunk-B7VTDQR7.js";
10
9
  import {
11
10
  coerceErrorString
12
11
  } from "../chunk-GFRAOY75.js";
13
12
  import "../chunk-H4BYJELI.js";
14
- import "../chunk-GZ7HCLLM.js";
13
+ import {
14
+ NaiveJsonCodec
15
+ } from "../chunk-GZ7HCLLM.js";
15
16
 
16
17
  // util/testHelpers.ts
17
18
  import WebSocket from "isomorphic-ws";
@@ -85,12 +86,18 @@ function catchProcError(err) {
85
86
  }
86
87
  };
87
88
  }
89
+ var testingSessionOptions = {
90
+ heartbeatIntervalMs: 1e3,
91
+ heartbeatsUntilDead: 2,
92
+ sessionDisconnectGraceMs: 5e3,
93
+ codec: NaiveJsonCodec
94
+ };
88
95
  function dummyCtx(state, extendedContext) {
89
96
  const session = new Session(
90
97
  "client",
91
98
  "SERVER",
92
99
  void 0,
93
- defaultSessionOptions
100
+ testingSessionOptions
94
101
  );
95
102
  return {
96
103
  ...extendedContext,
@@ -161,5 +168,6 @@ export {
161
168
  onUdsServeReady,
162
169
  onWsServerReady,
163
170
  payloadToTransportMessage,
171
+ testingSessionOptions,
164
172
  waitForMessage
165
173
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@replit/river",
3
3
  "description": "It's like tRPC but... with JSON Schema Support, duplex streaming and support for service multiplexing. Transport agnostic!",
4
- "version": "0.15.1",
4
+ "version": "0.15.2",
5
5
  "type": "module",
6
6
  "exports": {
7
7
  ".": {