@replit/river 0.23.16 → 0.24.0

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 (85) hide show
  1. package/README.md +21 -20
  2. package/dist/{chunk-UDXM64QK.js → chunk-AASMR3CQ.js} +24 -18
  3. package/dist/chunk-AASMR3CQ.js.map +1 -0
  4. package/dist/chunk-JA57I7MG.js +653 -0
  5. package/dist/chunk-JA57I7MG.js.map +1 -0
  6. package/dist/chunk-KX5PQRVN.js +382 -0
  7. package/dist/chunk-KX5PQRVN.js.map +1 -0
  8. package/dist/{chunk-LTSLICON.js → chunk-KYYB4DUR.js} +68 -519
  9. package/dist/chunk-KYYB4DUR.js.map +1 -0
  10. package/dist/chunk-NLQPPDOT.js +399 -0
  11. package/dist/chunk-NLQPPDOT.js.map +1 -0
  12. package/dist/{chunk-TXSQRTZB.js → chunk-PJGGC3LV.js} +55 -41
  13. package/dist/chunk-PJGGC3LV.js.map +1 -0
  14. package/dist/chunk-RXJLI2OP.js +50 -0
  15. package/dist/chunk-RXJLI2OP.js.map +1 -0
  16. package/dist/{chunk-6LCL2ZZF.js → chunk-TAH2GVTJ.js} +1 -1
  17. package/dist/chunk-TAH2GVTJ.js.map +1 -0
  18. package/dist/chunk-ZAT3R4CU.js +277 -0
  19. package/dist/chunk-ZAT3R4CU.js.map +1 -0
  20. package/dist/{client-0926d3d6.d.ts → client-ba0d3315.d.ts} +12 -15
  21. package/dist/{connection-99a67d3e.d.ts → connection-c3a96d09.d.ts} +1 -5
  22. package/dist/connection-d33e3246.d.ts +11 -0
  23. package/dist/{handshake-75d0124f.d.ts → handshake-cdead82a.d.ts} +149 -180
  24. package/dist/logging/index.cjs.map +1 -1
  25. package/dist/logging/index.d.cts +1 -1
  26. package/dist/logging/index.d.ts +1 -1
  27. package/dist/logging/index.js +1 -1
  28. package/dist/{index-ea74cdbb.d.ts → message-e6c560fd.d.ts} +2 -2
  29. package/dist/router/index.cjs +107 -530
  30. package/dist/router/index.cjs.map +1 -1
  31. package/dist/router/index.d.cts +12 -50
  32. package/dist/router/index.d.ts +12 -50
  33. package/dist/router/index.js +2 -4
  34. package/dist/server-2ef5e6ec.d.ts +42 -0
  35. package/dist/{services-75e84a9f.d.ts → services-e1417b33.d.ts} +7 -7
  36. package/dist/transport/impls/uds/client.cjs +1242 -1223
  37. package/dist/transport/impls/uds/client.cjs.map +1 -1
  38. package/dist/transport/impls/uds/client.d.cts +4 -4
  39. package/dist/transport/impls/uds/client.d.ts +4 -4
  40. package/dist/transport/impls/uds/client.js +7 -13
  41. package/dist/transport/impls/uds/client.js.map +1 -1
  42. package/dist/transport/impls/uds/server.cjs +1301 -1151
  43. package/dist/transport/impls/uds/server.cjs.map +1 -1
  44. package/dist/transport/impls/uds/server.d.cts +4 -4
  45. package/dist/transport/impls/uds/server.d.ts +4 -4
  46. package/dist/transport/impls/uds/server.js +6 -6
  47. package/dist/transport/impls/ws/client.cjs +980 -969
  48. package/dist/transport/impls/ws/client.cjs.map +1 -1
  49. package/dist/transport/impls/ws/client.d.cts +4 -4
  50. package/dist/transport/impls/ws/client.d.ts +4 -4
  51. package/dist/transport/impls/ws/client.js +6 -7
  52. package/dist/transport/impls/ws/client.js.map +1 -1
  53. package/dist/transport/impls/ws/server.cjs +1182 -1047
  54. package/dist/transport/impls/ws/server.cjs.map +1 -1
  55. package/dist/transport/impls/ws/server.d.cts +4 -4
  56. package/dist/transport/impls/ws/server.d.ts +4 -4
  57. package/dist/transport/impls/ws/server.js +6 -6
  58. package/dist/transport/index.cjs +1434 -1360
  59. package/dist/transport/index.cjs.map +1 -1
  60. package/dist/transport/index.d.cts +4 -4
  61. package/dist/transport/index.d.ts +4 -4
  62. package/dist/transport/index.js +9 -9
  63. package/dist/util/testHelpers.cjs +743 -309
  64. package/dist/util/testHelpers.cjs.map +1 -1
  65. package/dist/util/testHelpers.d.cts +10 -7
  66. package/dist/util/testHelpers.d.ts +10 -7
  67. package/dist/util/testHelpers.js +33 -10
  68. package/dist/util/testHelpers.js.map +1 -1
  69. package/package.json +1 -1
  70. package/dist/chunk-6LCL2ZZF.js.map +0 -1
  71. package/dist/chunk-JA7XGTAL.js +0 -476
  72. package/dist/chunk-JA7XGTAL.js.map +0 -1
  73. package/dist/chunk-LTSLICON.js.map +0 -1
  74. package/dist/chunk-MQCGG6KL.js +0 -335
  75. package/dist/chunk-MQCGG6KL.js.map +0 -1
  76. package/dist/chunk-R47IZD67.js +0 -59
  77. package/dist/chunk-R47IZD67.js.map +0 -1
  78. package/dist/chunk-TXSQRTZB.js.map +0 -1
  79. package/dist/chunk-UDXM64QK.js.map +0 -1
  80. package/dist/chunk-WN77AT67.js +0 -476
  81. package/dist/chunk-WN77AT67.js.map +0 -1
  82. package/dist/chunk-YXDAOVP7.js +0 -347
  83. package/dist/chunk-YXDAOVP7.js.map +0 -1
  84. package/dist/connection-d738cc08.d.ts +0 -17
  85. package/dist/server-3740c5d9.d.ts +0 -24
@@ -31,7 +31,6 @@ __export(router_exports, {
31
31
  createClientHandshakeOptions: () => createClientHandshakeOptions,
32
32
  createServer: () => createServer,
33
33
  createServerHandshakeOptions: () => createServerHandshakeOptions,
34
- diffServerSchema: () => diffServerSchema,
35
34
  serializeSchema: () => serializeSchema
36
35
  });
37
36
  module.exports = __toCommonJS(router_exports);
@@ -174,9 +173,9 @@ var ServiceSchema = class _ServiceSchema {
174
173
  * You probably don't need this, usually the River server will handle this
175
174
  * for you.
176
175
  */
177
- instantiate() {
176
+ instantiate(extendedContext) {
178
177
  return Object.freeze({
179
- state: this.initializeState(),
178
+ state: this.initializeState(extendedContext),
180
179
  procedures: this.procedures
181
180
  });
182
181
  }
@@ -238,468 +237,6 @@ var ServiceScaffold = class {
238
237
  }
239
238
  };
240
239
 
241
- // router/diff.ts
242
- function diffServerSchema(oldServer, newServer, options) {
243
- const allServices = /* @__PURE__ */ new Set([
244
- ...Object.keys(oldServer.services),
245
- ...Object.keys(newServer.services)
246
- ]);
247
- const breakages = {};
248
- for (const serviceName of allServices) {
249
- const oldService = oldServer.services[serviceName];
250
- const newService = newServer.services[serviceName];
251
- const breakage = diffService(oldService, newService, options);
252
- if (breakage) {
253
- breakages[serviceName] = breakage;
254
- }
255
- }
256
- if (Object.keys(breakages).length) {
257
- return { serviceBreakages: breakages };
258
- }
259
- return null;
260
- }
261
- function diffService(oldService, newService, options) {
262
- if (!newService) {
263
- return options?.allowServiceRemoval ? null : { reason: "removed" };
264
- }
265
- if (!oldService) {
266
- return null;
267
- }
268
- const allProcedures = /* @__PURE__ */ new Set([
269
- ...Object.keys(oldService.procedures),
270
- ...Object.keys(newService.procedures)
271
- ]);
272
- const breakages = {};
273
- for (const procedureName of allProcedures) {
274
- const aProcedure = oldService.procedures[procedureName];
275
- const bProcedure = newService.procedures[procedureName];
276
- const breakage = diffProcedure(aProcedure, bProcedure, options);
277
- if (breakage) {
278
- breakages[procedureName] = breakage;
279
- }
280
- }
281
- if (Object.keys(breakages).length) {
282
- return { reason: "modified", procedureBreakages: breakages };
283
- }
284
- return null;
285
- }
286
- function diffProcedure(oldProcedure, newProcedure, options) {
287
- if (!newProcedure) {
288
- return options?.allowProcedureRemoval ? null : { reason: "removed" };
289
- }
290
- if (!oldProcedure) {
291
- return null;
292
- }
293
- if (oldProcedure.type !== newProcedure.type) {
294
- return {
295
- reason: "type-changed",
296
- oldType: oldProcedure.type,
297
- newType: newProcedure.type
298
- };
299
- }
300
- const inputBreakage = diffProcedureField(
301
- oldProcedure.input,
302
- newProcedure.input,
303
- "client"
304
- );
305
- const initBreakage = diffProcedureField(
306
- oldProcedure.init,
307
- newProcedure.init,
308
- "client"
309
- );
310
- const outputBreakage = diffProcedureField(
311
- oldProcedure.output,
312
- newProcedure.output,
313
- "server"
314
- );
315
- if (inputBreakage ?? initBreakage ?? outputBreakage) {
316
- const result = {
317
- reason: "modified"
318
- };
319
- if (inputBreakage) {
320
- result.input = inputBreakage;
321
- }
322
- if (initBreakage) {
323
- result.init = initBreakage;
324
- }
325
- if (outputBreakage) {
326
- result.output = outputBreakage;
327
- }
328
- return result;
329
- }
330
- return null;
331
- }
332
- function diffProcedureField(oldSchema, newSchema, origin) {
333
- if (!oldSchema && !newSchema) {
334
- return null;
335
- }
336
- const diffBreakage = diffRequired(oldSchema, newSchema, origin, false, false);
337
- if (diffBreakage) {
338
- return diffBreakage;
339
- }
340
- if (!oldSchema || !newSchema) {
341
- throw new Error("Appease typescript, this should never happen");
342
- }
343
- return diffJSONSchema(oldSchema, newSchema, origin);
344
- }
345
- function diffRequired(oldSchema, newSchema, origin, oldRequired, newRequired) {
346
- if (!newSchema && !oldSchema) {
347
- throw new Error("Both old and new schema are undefined");
348
- }
349
- if (!newSchema) {
350
- if (!oldRequired && origin == "server") {
351
- return null;
352
- }
353
- return { reason: "removed-required" };
354
- }
355
- if (!oldSchema) {
356
- if (newRequired && origin === "client") {
357
- return { reason: "new-required" };
358
- }
359
- return null;
360
- }
361
- if (origin === "client" && !oldRequired && newRequired) {
362
- return { reason: "new-required" };
363
- }
364
- if (origin === "server" && oldRequired && !newRequired) {
365
- return { reason: "removed-required" };
366
- }
367
- return null;
368
- }
369
- function diffJSONSchema(oldSchema, newSchema, origin) {
370
- if (oldSchema.type !== newSchema.type) {
371
- return {
372
- reason: "type-changed",
373
- oldType: getReportingType(oldSchema),
374
- newType: getReportingType(newSchema)
375
- };
376
- }
377
- if (getReportingType(oldSchema) !== getReportingType(newSchema)) {
378
- return {
379
- reason: "type-changed",
380
- oldType: getReportingType(oldSchema),
381
- newType: getReportingType(newSchema)
382
- };
383
- }
384
- if ("const" in oldSchema && "const" in newSchema && oldSchema.const !== newSchema.const) {
385
- return {
386
- reason: "type-changed",
387
- oldType: `${getReportingType(oldSchema)}-const-${oldSchema.const}`,
388
- newType: `${getReportingType(newSchema)}-const-${newSchema.const}`
389
- };
390
- }
391
- if ("const" in oldSchema && !("const" in newSchema) && origin === "server") {
392
- return {
393
- reason: "type-changed",
394
- oldType: `${getReportingType(oldSchema)}-const-${oldSchema.const}`,
395
- newType: getReportingType(newSchema)
396
- };
397
- }
398
- if ("const" in newSchema && !("const" in oldSchema) && origin === "client") {
399
- return {
400
- reason: "type-changed",
401
- oldType: getReportingType(oldSchema),
402
- newType: `${getReportingType(newSchema)}-const-${newSchema.const}`
403
- };
404
- }
405
- const breakages = {};
406
- if ("$ref" in newSchema) {
407
- if (newSchema.$ref !== oldSchema.$ref) {
408
- return {
409
- reason: "type-changed",
410
- oldType: getReportingType(oldSchema),
411
- newType: getReportingType(newSchema)
412
- };
413
- }
414
- } else if ("not" in newSchema) {
415
- const notBreakage = diffJSONSchema(
416
- oldSchema.not,
417
- newSchema.not,
418
- origin
419
- );
420
- if (notBreakage) {
421
- breakages.not = notBreakage;
422
- }
423
- } else if ("anyOf" in newSchema) {
424
- const oldAnyOfStringified = oldSchema.anyOf.map((el) => JSON.stringify(el)).sort();
425
- const newAnyOfStringified = newSchema.anyOf.map((el) => JSON.stringify(el)).sort();
426
- const anyOfBreakages = {};
427
- for (let i = 0; i < oldAnyOfStringified.length; i++) {
428
- if (newAnyOfStringified.includes(oldAnyOfStringified[i])) {
429
- continue;
430
- }
431
- if (!newAnyOfStringified[i]) {
432
- if (origin === "server") {
433
- continue;
434
- }
435
- anyOfBreakages[`old-${i}`] = { reason: "removed-required" };
436
- } else {
437
- const breakage = diffJSONSchema(
438
- JSON.parse(oldAnyOfStringified[i]),
439
- JSON.parse(newAnyOfStringified[i]),
440
- origin
441
- );
442
- if (breakage) {
443
- anyOfBreakages[`old-${i}`] = breakage;
444
- }
445
- }
446
- }
447
- for (let i = 0; i < newAnyOfStringified.length; i++) {
448
- if (oldAnyOfStringified.includes(newAnyOfStringified[i])) {
449
- continue;
450
- }
451
- if (!oldAnyOfStringified[i]) {
452
- if (origin === "client") {
453
- continue;
454
- }
455
- anyOfBreakages[`new-${i}`] = { reason: "new-required" };
456
- } else {
457
- const breakage = diffJSONSchema(
458
- JSON.parse(oldAnyOfStringified[i]),
459
- JSON.parse(newAnyOfStringified[i]),
460
- origin
461
- );
462
- if (breakage) {
463
- anyOfBreakages[`new-${i}`] = breakage;
464
- }
465
- }
466
- }
467
- if (Object.keys(anyOfBreakages).length > 0) {
468
- breakages.anyOf = {
469
- reason: "field-breakage",
470
- fieldBreakages: anyOfBreakages
471
- };
472
- }
473
- } else if ("oneOf" in newSchema) {
474
- throw new Error("oneOf is not supported, typebox does not emit it");
475
- } else if ("allOf" in newSchema) {
476
- if (newSchema.allOf.length !== oldSchema.allOf.length) {
477
- breakages.allOf = {
478
- reason: "type-changed",
479
- oldType: `${oldSchema.allOf}`,
480
- newType: `${newSchema.allOf}`
481
- };
482
- } else {
483
- for (let i = 0; i < newSchema.allOf.length; i++) {
484
- const breakage = diffJSONSchema(
485
- oldSchema.allOf[i],
486
- newSchema.allOf[i],
487
- origin
488
- );
489
- if (breakage) {
490
- breakages.allOf = breakage;
491
- break;
492
- }
493
- }
494
- }
495
- } else if (newSchema.type === "array") {
496
- const itemsBreakages = diffJSONSchema(
497
- oldSchema.items,
498
- newSchema.items,
499
- origin
500
- );
501
- if (itemsBreakages) {
502
- breakages.items = itemsBreakages;
503
- }
504
- if (oldSchema.minItems < newSchema.minItems) {
505
- if (origin === "client") {
506
- breakages.minItems = {
507
- reason: "type-changed",
508
- oldType: `${oldSchema.minItems}`,
509
- newType: `${newSchema.minItems}`
510
- };
511
- }
512
- } else if (oldSchema.minItems > newSchema.minItems) {
513
- if (origin === "server") {
514
- breakages.minItems = {
515
- reason: "type-changed",
516
- oldType: `${oldSchema.minItems}`,
517
- newType: `${newSchema.minItems}`
518
- };
519
- }
520
- }
521
- if (oldSchema.maxItems < newSchema.maxItems) {
522
- if (origin === "server") {
523
- breakages.maxItems = {
524
- reason: "type-changed",
525
- oldType: `${oldSchema.maxItems}`,
526
- newType: `${newSchema.maxItems}`
527
- };
528
- }
529
- } else if (oldSchema.maxItems > newSchema.maxItems) {
530
- if (origin === "client") {
531
- breakages.maxItems = {
532
- reason: "type-changed",
533
- oldType: `${oldSchema.maxItems}`,
534
- newType: `${newSchema.maxItems}`
535
- };
536
- }
537
- }
538
- if (!oldSchema.uniqueItems && newSchema.uniqueItems && origin === "client") {
539
- breakages.uniqueItems = {
540
- reason: "type-changed",
541
- oldType: `${!!oldSchema.uniqueItems}`,
542
- newType: `${!!newSchema.uniqueItems}`
543
- };
544
- }
545
- if ("contains" in newSchema !== "contains" in oldSchema) {
546
- if ("contains" in newSchema && !("contains" in oldSchema) && origin === "client") {
547
- breakages.contains = {
548
- reason: "type-changed",
549
- oldType: "no-contains",
550
- newType: "contains"
551
- };
552
- }
553
- } else if ("contains" in newSchema) {
554
- const containsBreakage = diffJSONSchema(
555
- oldSchema.contains,
556
- newSchema.contains,
557
- origin
558
- );
559
- if (containsBreakage) {
560
- breakages.contains = containsBreakage;
561
- }
562
- }
563
- if (oldSchema.minContains < newSchema.minContains) {
564
- if (origin === "client") {
565
- breakages.minContains = {
566
- reason: "type-changed",
567
- oldType: `${oldSchema.minContains}`,
568
- newType: `${newSchema.minContains}`
569
- };
570
- }
571
- } else if (oldSchema.minContains > newSchema.minContains) {
572
- if (origin === "server") {
573
- breakages.minContains = {
574
- reason: "type-changed",
575
- oldType: `${oldSchema.minContains}`,
576
- newType: `${newSchema.minContains}`
577
- };
578
- }
579
- }
580
- if (oldSchema.maxContains < newSchema.maxContains) {
581
- if (origin === "server") {
582
- breakages.maxContains = {
583
- reason: "type-changed",
584
- oldType: `${oldSchema.maxContains}`,
585
- newType: `${newSchema.maxContains}`
586
- };
587
- }
588
- } else if (oldSchema.maxContains > newSchema.maxContains) {
589
- if (origin === "client") {
590
- breakages.maxContains = {
591
- reason: "type-changed",
592
- oldType: `${oldSchema.maxContains}`,
593
- newType: `${newSchema.maxContains}`
594
- };
595
- }
596
- }
597
- } else if (newSchema.type === "object") {
598
- if ("properties" in newSchema !== "properties" in oldSchema) {
599
- return {
600
- reason: "type-changed",
601
- oldType: "properties" in oldSchema ? "probably-object" : "probably-record",
602
- newType: "properties" in newSchema ? "probably-object" : "probably-record"
603
- };
604
- }
605
- if ("properties" in newSchema) {
606
- const propertiesBreakages = diffObjectProperties(
607
- oldSchema.properties,
608
- newSchema.properties,
609
- origin,
610
- oldSchema.required,
611
- newSchema.required
612
- );
613
- if (Object.keys(propertiesBreakages).length) {
614
- breakages.properties = {
615
- reason: "field-breakage",
616
- fieldBreakages: propertiesBreakages
617
- };
618
- }
619
- }
620
- if ("patternProperties" in newSchema) {
621
- const patternPropertiesBreakages = diffObjectProperties(
622
- oldSchema.patternProperties,
623
- newSchema.patternProperties,
624
- origin,
625
- oldSchema.required,
626
- newSchema.required
627
- );
628
- if (Object.keys(patternPropertiesBreakages).length) {
629
- breakages.patternProperties = {
630
- reason: "field-breakage",
631
- fieldBreakages: patternPropertiesBreakages
632
- };
633
- }
634
- }
635
- if ("additionalProperties" in newSchema || "additionalProperties" in oldSchema) {
636
- throw new Error("additionalProperties is not supported");
637
- }
638
- if ("minProperties" in newSchema || "minProperties" in oldSchema) {
639
- throw new Error("minProperties is not supported");
640
- }
641
- if ("maxProperties" in newSchema || "maxProperties" in oldSchema) {
642
- throw new Error("maxProperties is not supported");
643
- }
644
- }
645
- if (Object.keys(breakages).length) {
646
- return {
647
- reason: "field-breakage",
648
- fieldBreakages: breakages
649
- };
650
- }
651
- return null;
652
- }
653
- function diffObjectProperties(oldProperties, newProperties, origin, oldRequiredProperties = [], newRequiredProperties = []) {
654
- const allProperties = /* @__PURE__ */ new Set([
655
- ...Object.keys(oldProperties),
656
- ...Object.keys(newProperties)
657
- ]);
658
- const breakages = {};
659
- for (const propertyName of allProperties) {
660
- const requiredBreakage = diffRequired(
661
- oldProperties[propertyName],
662
- newProperties[propertyName],
663
- origin,
664
- oldRequiredProperties.includes(propertyName),
665
- newRequiredProperties.includes(propertyName)
666
- );
667
- if (requiredBreakage) {
668
- breakages[propertyName] = requiredBreakage;
669
- } else if (oldProperties[propertyName] && newProperties[propertyName]) {
670
- const propertyBreakage = diffJSONSchema(
671
- oldProperties[propertyName],
672
- newProperties[propertyName],
673
- origin
674
- );
675
- if (propertyBreakage) {
676
- breakages[propertyName] = propertyBreakage;
677
- }
678
- }
679
- }
680
- return breakages;
681
- }
682
- function getReportingType(schema) {
683
- if ("not" in schema) {
684
- return "not";
685
- }
686
- if ("anyOf" in schema) {
687
- return "anyOf";
688
- }
689
- if ("allOf" in schema) {
690
- return "allOf";
691
- }
692
- if ("$ref" in schema) {
693
- return "$ref";
694
- }
695
- if (schema.type && typeof schema.type === "string") {
696
- return schema.type;
697
- }
698
- throw new Error(
699
- "Subschema not supported, probably a conditional subschema. Check logs."
700
- );
701
- }
702
-
703
240
  // router/procedures.ts
704
241
  var import_typebox2 = require("@sinclair/typebox");
705
242
  function rpc({
@@ -1075,7 +612,15 @@ function _pushable(getNext, options) {
1075
612
 
1076
613
  // transport/message.ts
1077
614
  var import_typebox3 = require("@sinclair/typebox");
615
+
616
+ // transport/id.ts
1078
617
  var import_nanoid = require("nanoid");
618
+ var alphabet = (0, import_nanoid.customAlphabet)(
619
+ "1234567890abcdefghijklmnopqrstuvxyzABCDEFGHIJKLMNOPQRSTUVXYZ"
620
+ );
621
+ var generateId = () => alphabet(12);
622
+
623
+ // transport/message.ts
1079
624
  var TransportMessageSchema = (t) => import_typebox3.Type.Object({
1080
625
  id: import_typebox3.Type.String(),
1081
626
  from: import_typebox3.Type.String(),
@@ -1109,18 +654,29 @@ var ControlMessageHandshakeRequestSchema = import_typebox3.Type.Object({
1109
654
  * used by the server to know whether this is a new or a reestablished connection, and whether it
1110
655
  * is compatible with what it already has.
1111
656
  */
1112
- expectedSessionState: import_typebox3.Type.Optional(
1113
- import_typebox3.Type.Object({
1114
- /**
1115
- * reconnect is set to true if the client explicitly wants to reestablish an existing
1116
- * connection.
1117
- */
1118
- reconnect: import_typebox3.Type.Boolean(),
1119
- nextExpectedSeq: import_typebox3.Type.Integer()
1120
- })
1121
- ),
657
+ expectedSessionState: import_typebox3.Type.Object({
658
+ // what the client expects the server to send next
659
+ nextExpectedSeq: import_typebox3.Type.Integer(),
660
+ // TODO: remove optional once we know all servers
661
+ // are nextSentSeq here
662
+ // what the server expects the client to send next
663
+ nextSentSeq: import_typebox3.Type.Optional(import_typebox3.Type.Integer())
664
+ }),
1122
665
  metadata: import_typebox3.Type.Optional(import_typebox3.Type.Unknown())
1123
666
  });
667
+ var HandshakeErrorRetriableResponseCodes = import_typebox3.Type.Union([
668
+ import_typebox3.Type.Literal("SESSION_STATE_MISMATCH")
669
+ ]);
670
+ var HandshakeErrorFatalResponseCodes = import_typebox3.Type.Union([
671
+ import_typebox3.Type.Literal("MALFORMED_HANDSHAKE_META"),
672
+ import_typebox3.Type.Literal("MALFORMED_HANDSHAKE"),
673
+ import_typebox3.Type.Literal("PROTOCOL_VERSION_MISMATCH"),
674
+ import_typebox3.Type.Literal("REJECTED_BY_CUSTOM_HANDLER")
675
+ ]);
676
+ var HandshakeErrorResponseCodes = import_typebox3.Type.Union([
677
+ HandshakeErrorRetriableResponseCodes,
678
+ HandshakeErrorFatalResponseCodes
679
+ ]);
1124
680
  var ControlMessageHandshakeResponseSchema = import_typebox3.Type.Object({
1125
681
  type: import_typebox3.Type.Literal("HANDSHAKE_RESP"),
1126
682
  status: import_typebox3.Type.Union([
@@ -1130,7 +686,10 @@ var ControlMessageHandshakeResponseSchema = import_typebox3.Type.Object({
1130
686
  }),
1131
687
  import_typebox3.Type.Object({
1132
688
  ok: import_typebox3.Type.Literal(false),
1133
- reason: import_typebox3.Type.String()
689
+ reason: import_typebox3.Type.String(),
690
+ // TODO: remove optional once we know all servers
691
+ // are sending code here
692
+ code: import_typebox3.Type.Optional(HandshakeErrorResponseCodes)
1134
693
  })
1135
694
  ])
1136
695
  });
@@ -1143,6 +702,15 @@ var ControlMessagePayloadSchema = import_typebox3.Type.Union([
1143
702
  var OpaqueTransportMessageSchema = TransportMessageSchema(
1144
703
  import_typebox3.Type.Unknown()
1145
704
  );
705
+ function closeStreamMessage(streamId) {
706
+ return {
707
+ streamId,
708
+ controlFlags: 4 /* StreamClosedBit */,
709
+ payload: {
710
+ type: "CLOSE"
711
+ }
712
+ };
713
+ }
1146
714
  function isStreamOpen(controlFlag) {
1147
715
  return (
1148
716
  /* eslint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison */
@@ -1156,9 +724,6 @@ function isStreamClose(controlFlag) {
1156
724
  );
1157
725
  }
1158
726
 
1159
- // router/client.ts
1160
- var import_nanoid2 = require("nanoid");
1161
-
1162
727
  // router/result.ts
1163
728
  var import_typebox4 = require("@sinclair/typebox");
1164
729
  var UNCAUGHT_ERROR = "UNCAUGHT_ERROR";
@@ -1187,7 +752,7 @@ function Err(error) {
1187
752
  var import_api = require("@opentelemetry/api");
1188
753
 
1189
754
  // package.json
1190
- var version = "0.23.16";
755
+ var version = "0.24.0";
1191
756
 
1192
757
  // tracing/index.ts
1193
758
  function getPropagationContext(ctx) {
@@ -1281,7 +846,7 @@ function createClient(transport, serverId, providedClientOptions = {}) {
1281
846
  }
1282
847
  const options = { ...defaultClientOptions, ...providedClientOptions };
1283
848
  if (options.eagerlyConnect) {
1284
- void transport.connect(serverId);
849
+ transport.connect(serverId);
1285
850
  }
1286
851
  return _createRecursiveProxy(async (opts) => {
1287
852
  const [serviceName, procName, procType] = [...opts.path];
@@ -1291,8 +856,8 @@ function createClient(transport, serverId, providedClientOptions = {}) {
1291
856
  );
1292
857
  }
1293
858
  const [input] = opts.args;
1294
- if (options.connectOnInvoke && !transport.connections.has(serverId)) {
1295
- void transport.connect(serverId);
859
+ if (options.connectOnInvoke && !transport.sessions.has(serverId)) {
860
+ transport.connect(serverId);
1296
861
  }
1297
862
  if (procType === "rpc") {
1298
863
  return handleRpc(transport, serverId, input, serviceName, procName);
@@ -1315,7 +880,7 @@ function createSessionDisconnectHandler(from, cb) {
1315
880
  };
1316
881
  }
1317
882
  function handleRpc(transport, serverId, input, serviceName, procedureName) {
1318
- const streamId = (0, import_nanoid2.nanoid)();
883
+ const streamId = generateId();
1319
884
  const { span, ctx } = createProcTelemetryInfo(
1320
885
  transport,
1321
886
  "rpc",
@@ -1360,7 +925,7 @@ function handleRpc(transport, serverId, input, serviceName, procedureName) {
1360
925
  return responsePromise;
1361
926
  }
1362
927
  function handleStream(transport, serverId, init, serviceName, procedureName) {
1363
- const streamId = (0, import_nanoid2.nanoid)();
928
+ const streamId = generateId();
1364
929
  const { span, ctx } = createProcTelemetryInfo(
1365
930
  transport,
1366
931
  "stream",
@@ -1401,7 +966,7 @@ function handleStream(transport, serverId, init, serviceName, procedureName) {
1401
966
  }
1402
967
  if (!healthyClose)
1403
968
  return;
1404
- transport.sendCloseStream(serverId, streamId);
969
+ transport.send(serverId, closeStreamMessage(streamId));
1405
970
  };
1406
971
  void pipeInputToTransport();
1407
972
  function onMessage(msg) {
@@ -1437,7 +1002,7 @@ function handleStream(transport, serverId, init, serviceName, procedureName) {
1437
1002
  return [inputStream, outputStream, cleanup];
1438
1003
  }
1439
1004
  function handleSubscribe(transport, serverId, input, serviceName, procedureName) {
1440
- const streamId = (0, import_nanoid2.nanoid)();
1005
+ const streamId = generateId();
1441
1006
  const { span, ctx } = createProcTelemetryInfo(
1442
1007
  transport,
1443
1008
  "subscription",
@@ -1476,7 +1041,7 @@ function handleSubscribe(transport, serverId, input, serviceName, procedureName)
1476
1041
  cleanup();
1477
1042
  if (!healthyClose)
1478
1043
  return;
1479
- transport.sendCloseStream(serverId, streamId);
1044
+ transport.send(serverId, closeStreamMessage(streamId));
1480
1045
  };
1481
1046
  const onSessionStatus = createSessionDisconnectHandler(serverId, () => {
1482
1047
  outputStream.push(
@@ -1493,7 +1058,7 @@ function handleSubscribe(transport, serverId, input, serviceName, procedureName)
1493
1058
  return [outputStream, closeHandler];
1494
1059
  }
1495
1060
  function handleUpload(transport, serverId, init, serviceName, procedureName) {
1496
- const streamId = (0, import_nanoid2.nanoid)();
1061
+ const streamId = generateId();
1497
1062
  const { span, ctx } = createProcTelemetryInfo(
1498
1063
  transport,
1499
1064
  "upload",
@@ -1533,7 +1098,7 @@ function handleUpload(transport, serverId, init, serviceName, procedureName) {
1533
1098
  }
1534
1099
  if (!healthyClose)
1535
1100
  return;
1536
- transport.sendCloseStream(serverId, streamId);
1101
+ transport.send(serverId, closeStreamMessage(streamId));
1537
1102
  };
1538
1103
  void pipeInputToTransport();
1539
1104
  const responsePromise = new Promise((resolve) => {
@@ -1584,18 +1149,18 @@ var RiverServer = class {
1584
1149
  transport;
1585
1150
  services;
1586
1151
  contextMap;
1587
- // map of streamId to ProcStream
1588
1152
  streamMap;
1589
- // map of client to their open streams by streamId
1590
- clientStreams;
1591
- disconnectedSessions;
1153
+ sessionToStreamId;
1154
+ // streams that are in the process of being cleaned up
1155
+ // this is to prevent output handlers from sending after the stream is cleaned up
1156
+ sessionsBeingCleanedUp = /* @__PURE__ */ new Set();
1592
1157
  log;
1593
1158
  constructor(transport, services, handshakeOptions, extendedContext) {
1594
1159
  const instances = {};
1595
1160
  this.services = instances;
1596
1161
  this.contextMap = /* @__PURE__ */ new Map();
1597
1162
  for (const [name, service] of Object.entries(services)) {
1598
- const instance = service.instantiate();
1163
+ const instance = service.instantiate(extendedContext ?? {});
1599
1164
  instances[name] = instance;
1600
1165
  this.contextMap.set(instance, {
1601
1166
  ...extendedContext,
@@ -1606,9 +1171,8 @@ var RiverServer = class {
1606
1171
  transport.extendHandshake(handshakeOptions);
1607
1172
  }
1608
1173
  this.transport = transport;
1609
- this.disconnectedSessions = /* @__PURE__ */ new Set();
1610
1174
  this.streamMap = /* @__PURE__ */ new Map();
1611
- this.clientStreams = /* @__PURE__ */ new Map();
1175
+ this.sessionToStreamId = /* @__PURE__ */ new Map();
1612
1176
  this.transport.addEventListener("message", this.onMessage);
1613
1177
  this.transport.addEventListener("sessionStatus", this.onSessionStatus);
1614
1178
  this.log = transport.log;
@@ -1643,24 +1207,35 @@ var RiverServer = class {
1643
1207
  }
1644
1208
  await this.pushToStream(procStream, message, isInitMessage);
1645
1209
  };
1646
- // cleanup streams on session close
1647
1210
  onSessionStatus = async (evt) => {
1648
- if (evt.status !== "disconnect")
1211
+ const streamsFromThisClient = this.sessionToStreamId.get(evt.session.id);
1212
+ const cleanupStreams = async (ids) => {
1213
+ this.sessionsBeingCleanedUp.add(evt.session.id);
1214
+ await Promise.all(Array.from(ids).map(this.cleanupStream));
1215
+ this.sessionToStreamId.delete(evt.session.id);
1216
+ this.sessionsBeingCleanedUp.delete(evt.session.id);
1217
+ };
1218
+ if (evt.status === "connect") {
1219
+ if (streamsFromThisClient) {
1220
+ this.log?.error(
1221
+ `got session connect from ${evt.session.to} but there are still streams open from this session`,
1222
+ {
1223
+ clientId: this.transport.clientId,
1224
+ tags: ["invariant-violation"]
1225
+ }
1226
+ );
1227
+ await cleanupStreams(streamsFromThisClient);
1228
+ }
1229
+ this.sessionToStreamId.set(evt.session.id, /* @__PURE__ */ new Set());
1649
1230
  return;
1650
- const disconnectedClientId = evt.session.to;
1231
+ }
1651
1232
  this.log?.info(
1652
- `got session disconnect from ${disconnectedClientId}, cleaning up streams`,
1233
+ `got session disconnect from ${evt.session.to}, cleaning up streams for session`,
1653
1234
  evt.session.loggingMetadata
1654
1235
  );
1655
- const streamsFromThisClient = this.clientStreams.get(disconnectedClientId);
1656
1236
  if (!streamsFromThisClient)
1657
1237
  return;
1658
- this.disconnectedSessions.add(disconnectedClientId);
1659
- await Promise.all(
1660
- Array.from(streamsFromThisClient).map(this.cleanupStream)
1661
- );
1662
- this.disconnectedSessions.delete(disconnectedClientId);
1663
- this.clientStreams.delete(disconnectedClientId);
1238
+ await cleanupStreams(streamsFromThisClient);
1664
1239
  };
1665
1240
  createNewProcStream(message) {
1666
1241
  if (!isStreamOpen(message.controlFlags)) {
@@ -1711,26 +1286,34 @@ var RiverServer = class {
1711
1286
  });
1712
1287
  return;
1713
1288
  }
1289
+ const {
1290
+ to,
1291
+ id: sessionId,
1292
+ loggingMetadata: sessionLoggingMetadata
1293
+ } = session;
1714
1294
  const procedure = service.procedures[message.procedureName];
1715
1295
  const incoming = pushable({ objectMode: true });
1716
1296
  const outgoing = pushable({ objectMode: true });
1717
1297
  const needsClose = procedure.type === "subscription" || procedure.type === "stream";
1718
1298
  const disposables = [];
1299
+ const wrappedSend = (payload) => {
1300
+ if (!this.sessionsBeingCleanedUp.has(sessionId)) {
1301
+ this.transport.send(to, payload);
1302
+ }
1303
+ };
1719
1304
  const outputHandler = (
1720
1305
  // sending outgoing messages back to client
1721
1306
  needsClose ? (
1722
1307
  // subscription and stream case, we need to send a close bit after the response stream
1723
1308
  (async () => {
1724
1309
  for await (const response of outgoing) {
1725
- this.transport.send(session.to, {
1310
+ wrappedSend({
1726
1311
  streamId: message.streamId,
1727
1312
  controlFlags: 0,
1728
1313
  payload: response
1729
1314
  });
1730
1315
  }
1731
- if (!this.disconnectedSessions.has(message.from)) {
1732
- this.transport.sendCloseStream(session.to, message.streamId);
1733
- }
1316
+ wrappedSend(closeStreamMessage(message.streamId));
1734
1317
  disposables.forEach((d) => d());
1735
1318
  })()
1736
1319
  ) : (
@@ -1738,7 +1321,7 @@ var RiverServer = class {
1738
1321
  (async () => {
1739
1322
  const response = await outgoing.next().then((res) => res.value);
1740
1323
  if (response) {
1741
- this.transport.send(session.to, {
1324
+ wrappedSend({
1742
1325
  streamId: message.streamId,
1743
1326
  controlFlags: 4 /* StreamClosedBit */,
1744
1327
  payload: response
@@ -1752,7 +1335,7 @@ var RiverServer = class {
1752
1335
  const errorMsg = coerceErrorString(err);
1753
1336
  this.log?.error(
1754
1337
  `procedure ${message.serviceName}.${message.procedureName} threw an uncaught error: ${errorMsg}`,
1755
- session.loggingMetadata
1338
+ sessionLoggingMetadata
1756
1339
  );
1757
1340
  span.recordException(err instanceof Error ? err : new Error(errorMsg));
1758
1341
  span.setStatus({ code: import_api2.SpanStatusCode.ERROR });
@@ -1763,10 +1346,10 @@ var RiverServer = class {
1763
1346
  })
1764
1347
  );
1765
1348
  };
1766
- const sessionMeta = this.transport.sessionHandshakeMetadata.get(session);
1349
+ const sessionMeta = this.transport.sessionHandshakeMetadata.get(to);
1767
1350
  if (!sessionMeta) {
1768
1351
  this.log?.error(`session doesn't have handshake metadata`, {
1769
- ...session.loggingMetadata,
1352
+ ...sessionLoggingMetadata,
1770
1353
  tags: ["invariant-violation"]
1771
1354
  });
1772
1355
  return;
@@ -1778,7 +1361,6 @@ var RiverServer = class {
1778
1361
  to: message.to,
1779
1362
  from: message.from,
1780
1363
  streamId: message.streamId,
1781
- session,
1782
1364
  metadata: sessionMeta
1783
1365
  };
1784
1366
  switch (procedure.type) {
@@ -1897,9 +1479,7 @@ var RiverServer = class {
1897
1479
  initMessage.value,
1898
1480
  incoming
1899
1481
  );
1900
- if (!this.disconnectedSessions.has(message.from)) {
1901
- outgoing.push(outputMessage);
1902
- }
1482
+ outgoing.push(outputMessage);
1903
1483
  } catch (err) {
1904
1484
  errorHandler(err, span);
1905
1485
  } finally {
@@ -1917,9 +1497,7 @@ var RiverServer = class {
1917
1497
  serviceContextWithTransportInfo,
1918
1498
  incoming
1919
1499
  );
1920
- if (!this.disconnectedSessions.has(message.from)) {
1921
- outgoing.push(outputMessage);
1922
- }
1500
+ outgoing.push(outputMessage);
1923
1501
  } catch (err) {
1924
1502
  errorHandler(err, span);
1925
1503
  } finally {
@@ -1932,7 +1510,7 @@ var RiverServer = class {
1932
1510
  default:
1933
1511
  this.log?.warn(
1934
1512
  `got request for invalid procedure type ${procedure.type} at ${message.serviceName}.${message.procedureName}`,
1935
- { ...session.loggingMetadata, transportMessage: message }
1513
+ { ...sessionLoggingMetadata, transportMessage: message }
1936
1514
  );
1937
1515
  return;
1938
1516
  }
@@ -1945,9 +1523,9 @@ var RiverServer = class {
1945
1523
  promises: { inputHandler, outputHandler }
1946
1524
  };
1947
1525
  this.streamMap.set(message.streamId, procStream);
1948
- const streamsFromThisClient = this.clientStreams.get(message.from) ?? /* @__PURE__ */ new Set();
1949
- streamsFromThisClient.add(message.streamId);
1950
- this.clientStreams.set(message.from, streamsFromThisClient);
1526
+ const streamsForThisSession = this.sessionToStreamId.get(sessionId) ?? /* @__PURE__ */ new Set();
1527
+ streamsForThisSession.add(message.streamId);
1528
+ this.sessionToStreamId.set(sessionId, streamsForThisSession);
1951
1529
  return procStream;
1952
1530
  }
1953
1531
  async pushToStream(procStream, message, isInit) {
@@ -1983,11 +1561,11 @@ var RiverServer = class {
1983
1561
  }
1984
1562
  if (isStreamClose(message.controlFlags)) {
1985
1563
  await this.cleanupStream(message.streamId);
1986
- const streamsFromThisClient = this.clientStreams.get(message.from);
1564
+ const streamsFromThisClient = this.sessionToStreamId.get(message.from);
1987
1565
  if (streamsFromThisClient) {
1988
1566
  streamsFromThisClient.delete(message.streamId);
1989
1567
  if (streamsFromThisClient.size === 0) {
1990
- this.clientStreams.delete(message.from);
1568
+ this.sessionToStreamId.delete(message.from);
1991
1569
  }
1992
1570
  }
1993
1571
  }
@@ -2045,7 +1623,6 @@ function createServerHandshakeOptions(schema, validate) {
2045
1623
  createClientHandshakeOptions,
2046
1624
  createServer,
2047
1625
  createServerHandshakeOptions,
2048
- diffServerSchema,
2049
1626
  serializeSchema
2050
1627
  });
2051
1628
  //# sourceMappingURL=index.cjs.map