@replit/river 0.11.0 → 0.12.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 (82) hide show
  1. package/README.md +28 -8
  2. package/dist/{builder-1f26296b.d.ts → builder-c593de11.d.ts} +14 -13
  3. package/dist/{chunk-3JGVFWKQ.js → chunk-55XUAPC6.js} +205 -180
  4. package/dist/{chunk-R6H2BIMC.js → chunk-GZ7HCLLM.js} +31 -7
  5. package/dist/{chunk-T7M7OKPE.js → chunk-H4BYJELI.js} +5 -1
  6. package/dist/{chunk-GKPT5YQE.js → chunk-IIBVKYDB.js} +6 -34
  7. package/dist/chunk-M6LY25P2.js +47 -0
  8. package/dist/chunk-QEYN2Z6O.js +726 -0
  9. package/dist/chunk-RDTTKCGV.js +40 -0
  10. package/dist/chunk-TKINU53F.js +44 -0
  11. package/dist/chunk-XFFS4UOD.js +127 -0
  12. package/dist/codec/index.cjs +13 -7
  13. package/dist/codec/index.js +2 -4
  14. package/dist/connection-bf7811aa.d.ts +17 -0
  15. package/dist/connection-d880aa4a.d.ts +18 -0
  16. package/dist/connection-eb10d250.d.ts +15 -0
  17. package/dist/index-0c0a69f6.d.ts +440 -0
  18. package/dist/logging/index.cjs +8 -3
  19. package/dist/logging/index.d.cts +6 -1
  20. package/dist/logging/index.d.ts +6 -1
  21. package/dist/logging/index.js +5 -3
  22. package/dist/messageFraming-b200ef25.d.ts +20 -0
  23. package/dist/router/index.cjs +250 -211
  24. package/dist/router/index.d.cts +6 -7
  25. package/dist/router/index.d.ts +6 -7
  26. package/dist/router/index.js +3 -3
  27. package/dist/transport/impls/stdio/client.cjs +909 -0
  28. package/dist/transport/impls/stdio/client.d.cts +27 -0
  29. package/dist/transport/impls/stdio/client.d.ts +27 -0
  30. package/dist/transport/impls/stdio/client.js +42 -0
  31. package/dist/transport/impls/stdio/server.cjs +883 -0
  32. package/dist/transport/impls/stdio/server.d.cts +25 -0
  33. package/dist/transport/impls/stdio/server.d.ts +25 -0
  34. package/dist/transport/impls/stdio/server.js +33 -0
  35. package/dist/transport/impls/uds/client.cjs +911 -0
  36. package/dist/transport/impls/uds/client.d.cts +16 -0
  37. package/dist/transport/impls/uds/client.d.ts +16 -0
  38. package/dist/transport/impls/uds/client.js +44 -0
  39. package/dist/transport/impls/uds/server.cjs +885 -0
  40. package/dist/transport/impls/uds/server.d.cts +16 -0
  41. package/dist/transport/impls/uds/server.d.ts +16 -0
  42. package/dist/transport/impls/uds/server.js +39 -0
  43. package/dist/transport/impls/ws/client.cjs +612 -249
  44. package/dist/transport/impls/ws/client.d.cts +6 -21
  45. package/dist/transport/impls/ws/client.d.ts +6 -21
  46. package/dist/transport/impls/ws/client.js +83 -7
  47. package/dist/transport/impls/ws/server.cjs +565 -196
  48. package/dist/transport/impls/ws/server.d.cts +6 -10
  49. package/dist/transport/impls/ws/server.d.ts +6 -10
  50. package/dist/transport/impls/ws/server.js +31 -8
  51. package/dist/transport/index.cjs +673 -130
  52. package/dist/transport/index.d.cts +3 -276
  53. package/dist/transport/index.d.ts +3 -276
  54. package/dist/transport/index.js +13 -10
  55. package/dist/util/testHelpers.cjs +40 -602
  56. package/dist/util/testHelpers.d.cts +18 -37
  57. package/dist/util/testHelpers.d.ts +18 -37
  58. package/dist/util/testHelpers.js +27 -47
  59. package/package.json +29 -14
  60. package/dist/chunk-5IC5XMWK.js +0 -140
  61. package/dist/chunk-L7D75G4K.js +0 -29
  62. package/dist/chunk-LQXPKF3A.js +0 -282
  63. package/dist/chunk-PJ2EUO7O.js +0 -63
  64. package/dist/chunk-WVT5QXMZ.js +0 -20
  65. package/dist/chunk-ZE4MX7DF.js +0 -75
  66. package/dist/connection-2529fc14.d.ts +0 -10
  67. package/dist/connection-316d6e3a.d.ts +0 -10
  68. package/dist/connection-8e19874c.d.ts +0 -11
  69. package/dist/connection-f7688cc1.d.ts +0 -11
  70. package/dist/transport/impls/stdio/stdio.cjs +0 -518
  71. package/dist/transport/impls/stdio/stdio.d.cts +0 -26
  72. package/dist/transport/impls/stdio/stdio.d.ts +0 -26
  73. package/dist/transport/impls/stdio/stdio.js +0 -70
  74. package/dist/transport/impls/unixsocket/client.cjs +0 -516
  75. package/dist/transport/impls/unixsocket/client.d.cts +0 -16
  76. package/dist/transport/impls/unixsocket/client.d.ts +0 -16
  77. package/dist/transport/impls/unixsocket/client.js +0 -67
  78. package/dist/transport/impls/unixsocket/server.cjs +0 -520
  79. package/dist/transport/impls/unixsocket/server.d.cts +0 -18
  80. package/dist/transport/impls/unixsocket/server.d.ts +0 -18
  81. package/dist/transport/impls/unixsocket/server.js +0 -73
  82. /package/dist/{chunk-ORAG7IAU.js → chunk-5IZ2UHWV.js} +0 -0
@@ -1,14 +1,12 @@
1
1
  import {
2
2
  ControlMessagePayloadSchema,
3
- closeStream,
3
+ coerceErrorString,
4
4
  isStreamClose,
5
- isStreamOpen,
6
- msg,
7
- reply
8
- } from "./chunk-ZE4MX7DF.js";
5
+ isStreamOpen
6
+ } from "./chunk-XFFS4UOD.js";
9
7
  import {
10
8
  log
11
- } from "./chunk-T7M7OKPE.js";
9
+ } from "./chunk-H4BYJELI.js";
12
10
 
13
11
  // router/builder.ts
14
12
  import { Type } from "@sinclair/typebox";
@@ -475,33 +473,24 @@ var createClient = (transport, serverId = "SERVER") => _createRecursiveProxy(asy
475
473
  throw new Error(`invalid river call, unknown procedure type ${procType}`);
476
474
  }
477
475
  }, []);
478
- var CONNECTION_GRACE_PERIOD_MS = 5e3;
479
- function rejectAfterDisconnectGrace(from, cb) {
480
- let timeout = void 0;
476
+ function createSessionDisconnectHandler(from, cb) {
481
477
  return (evt) => {
482
- if (evt.status === "connect" && evt.conn.connectedTo === from) {
483
- clearTimeout(timeout);
484
- timeout = void 0;
485
- }
486
- if (evt.status === "disconnect" && evt.conn.connectedTo === from) {
487
- timeout = setTimeout(cb, CONNECTION_GRACE_PERIOD_MS);
478
+ if (evt.status === "disconnect" && evt.session.to === from) {
479
+ cb();
488
480
  }
489
481
  };
490
482
  }
491
- function handleRpc(transport, serverId, input, serviceName, procName) {
483
+ function handleRpc(transport, serverId, input, serviceName, procedureName) {
492
484
  const streamId = nanoid();
493
- const m = msg(
494
- transport.clientId,
495
- serverId,
485
+ transport.send(serverId, {
496
486
  streamId,
497
- input,
498
487
  serviceName,
499
- procName
500
- );
501
- m.controlFlags |= 2 /* StreamOpenBit */ | 4 /* StreamClosedBit */;
502
- transport.send(m);
488
+ procedureName,
489
+ payload: input,
490
+ controlFlags: 2 /* StreamOpenBit */ | 4 /* StreamClosedBit */
491
+ });
503
492
  const responsePromise = new Promise((resolve) => {
504
- const onConnectionStatus = rejectAfterDisconnectGrace(serverId, () => {
493
+ const onSessionStatus = createSessionDisconnectHandler(serverId, () => {
505
494
  cleanup();
506
495
  resolve(
507
496
  Err({
@@ -512,172 +501,181 @@ function handleRpc(transport, serverId, input, serviceName, procName) {
512
501
  });
513
502
  function cleanup() {
514
503
  transport.removeEventListener("message", onMessage);
515
- transport.removeEventListener("connectionStatus", onConnectionStatus);
504
+ transport.removeEventListener("sessionStatus", onSessionStatus);
516
505
  }
517
- function onMessage(msg2) {
518
- if (msg2.streamId !== streamId) {
506
+ function onMessage(msg) {
507
+ if (msg.streamId !== streamId) {
519
508
  return;
520
509
  }
521
- if (msg2.to !== transport.clientId) {
510
+ if (msg.to !== transport.clientId) {
522
511
  return;
523
512
  }
524
- if (msg2.streamId === streamId) {
513
+ if (msg.streamId === streamId) {
525
514
  cleanup();
526
- resolve(msg2.payload);
515
+ resolve(msg.payload);
527
516
  }
528
517
  }
529
518
  transport.addEventListener("message", onMessage);
530
- transport.addEventListener("connectionStatus", onConnectionStatus);
519
+ transport.addEventListener("sessionStatus", onSessionStatus);
531
520
  });
532
521
  return responsePromise;
533
522
  }
534
- function handleStream(transport, serverId, init, serviceName, procName) {
523
+ function handleStream(transport, serverId, init, serviceName, procedureName) {
535
524
  const streamId = nanoid();
536
525
  const inputStream = pushable({ objectMode: true });
537
526
  const outputStream = pushable({ objectMode: true });
538
527
  let firstMessage = true;
528
+ let healthyClose = true;
539
529
  if (init) {
540
- const m = msg(
541
- transport.clientId,
542
- serverId,
530
+ transport.send(serverId, {
543
531
  streamId,
544
- init,
545
532
  serviceName,
546
- procName
547
- );
548
- m.controlFlags = 2 /* StreamOpenBit */;
549
- transport.send(m);
533
+ procedureName,
534
+ payload: init,
535
+ controlFlags: 2 /* StreamOpenBit */
536
+ });
550
537
  firstMessage = false;
551
538
  }
552
- (async () => {
539
+ const pipeInputToTransport = async () => {
553
540
  for await (const rawIn of inputStream) {
554
- const m = msg(transport.clientId, serverId, streamId, rawIn);
541
+ const m = {
542
+ streamId,
543
+ payload: rawIn,
544
+ controlFlags: 0
545
+ };
555
546
  if (firstMessage) {
556
547
  m.serviceName = serviceName;
557
- m.procedureName = procName;
548
+ m.procedureName = procedureName;
558
549
  m.controlFlags |= 2 /* StreamOpenBit */;
559
550
  firstMessage = false;
560
551
  }
561
- transport.send(m);
552
+ transport.send(serverId, m);
562
553
  }
563
- transport.send(closeStream(transport.clientId, serverId, streamId));
564
- })();
565
- function onMessage(msg2) {
566
- if (msg2.streamId !== streamId) {
554
+ if (!healthyClose)
555
+ return;
556
+ transport.sendCloseStream(serverId, streamId);
557
+ };
558
+ void pipeInputToTransport();
559
+ function onMessage(msg) {
560
+ if (msg.streamId !== streamId) {
567
561
  return;
568
562
  }
569
- if (msg2.to !== transport.clientId) {
563
+ if (msg.to !== transport.clientId) {
570
564
  return;
571
565
  }
572
- if (isStreamClose(msg2.controlFlags)) {
566
+ if (isStreamClose(msg.controlFlags)) {
573
567
  cleanup();
574
568
  } else {
575
- outputStream.push(msg2.payload);
569
+ outputStream.push(msg.payload);
576
570
  }
577
571
  }
578
572
  function cleanup() {
579
573
  inputStream.end();
580
574
  outputStream.end();
581
575
  transport.removeEventListener("message", onMessage);
582
- transport.removeEventListener("connectionStatus", onConnectionStatus);
576
+ transport.removeEventListener("sessionStatus", onSessionStatus);
583
577
  }
584
- const closeHandler = () => {
585
- cleanup();
586
- transport.send(closeStream(transport.clientId, serverId, streamId));
587
- };
588
- const onConnectionStatus = rejectAfterDisconnectGrace(serverId, () => {
578
+ const onSessionStatus = createSessionDisconnectHandler(serverId, () => {
589
579
  outputStream.push(
590
580
  Err({
591
581
  code: UNEXPECTED_DISCONNECT,
592
582
  message: `${serverId} unexpectedly disconnected`
593
583
  })
594
584
  );
585
+ healthyClose = false;
595
586
  cleanup();
596
587
  });
597
588
  transport.addEventListener("message", onMessage);
598
- transport.addEventListener("connectionStatus", onConnectionStatus);
599
- return [inputStream, outputStream, closeHandler];
589
+ transport.addEventListener("sessionStatus", onSessionStatus);
590
+ return [inputStream, outputStream, cleanup];
600
591
  }
601
- function handleSubscribe(transport, serverId, input, serviceName, procName) {
592
+ function handleSubscribe(transport, serverId, input, serviceName, procedureName) {
602
593
  const streamId = nanoid();
603
- const m = msg(
604
- transport.clientId,
605
- serverId,
594
+ transport.send(serverId, {
606
595
  streamId,
607
- input,
608
596
  serviceName,
609
- procName
610
- );
611
- m.controlFlags |= 2 /* StreamOpenBit */;
612
- transport.send(m);
597
+ procedureName,
598
+ payload: input,
599
+ controlFlags: 2 /* StreamOpenBit */
600
+ });
601
+ let healthyClose = true;
613
602
  const outputStream = pushable({ objectMode: true });
614
- function onMessage(msg2) {
615
- if (msg2.streamId !== streamId) {
603
+ function onMessage(msg) {
604
+ if (msg.streamId !== streamId) {
616
605
  return;
617
606
  }
618
- if (msg2.to !== transport.clientId) {
607
+ if (msg.to !== transport.clientId) {
619
608
  return;
620
609
  }
621
- if (isStreamClose(msg2.controlFlags)) {
610
+ if (isStreamClose(msg.controlFlags)) {
622
611
  cleanup();
623
612
  } else {
624
- outputStream.push(msg2.payload);
613
+ outputStream.push(msg.payload);
625
614
  }
626
615
  }
627
616
  function cleanup() {
628
617
  outputStream.end();
629
618
  transport.removeEventListener("message", onMessage);
630
- transport.removeEventListener("connectionStatus", onConnectionStatus);
619
+ transport.removeEventListener("sessionStatus", onSessionStatus);
631
620
  }
632
621
  const closeHandler = () => {
633
622
  cleanup();
634
- transport.send(closeStream(transport.clientId, serverId, streamId));
623
+ if (!healthyClose)
624
+ return;
625
+ transport.sendCloseStream(serverId, streamId);
635
626
  };
636
- const onConnectionStatus = rejectAfterDisconnectGrace(serverId, () => {
627
+ const onSessionStatus = createSessionDisconnectHandler(serverId, () => {
637
628
  outputStream.push(
638
629
  Err({
639
630
  code: UNEXPECTED_DISCONNECT,
640
631
  message: `${serverId} unexpectedly disconnected`
641
632
  })
642
633
  );
634
+ healthyClose = false;
643
635
  cleanup();
644
636
  });
645
637
  transport.addEventListener("message", onMessage);
646
- transport.addEventListener("connectionStatus", onConnectionStatus);
638
+ transport.addEventListener("sessionStatus", onSessionStatus);
647
639
  return [outputStream, closeHandler];
648
640
  }
649
- function handleUpload(transport, serverId, input, serviceName, procName) {
641
+ function handleUpload(transport, serverId, init, serviceName, procedureName) {
650
642
  const streamId = nanoid();
651
643
  const inputStream = pushable({ objectMode: true });
652
644
  let firstMessage = true;
653
- if (input) {
654
- const m = msg(
655
- transport.clientId,
656
- serverId,
645
+ let healthyClose = true;
646
+ if (init) {
647
+ transport.send(serverId, {
657
648
  streamId,
658
- input,
659
649
  serviceName,
660
- procName
661
- );
662
- m.controlFlags = 2 /* StreamOpenBit */;
663
- transport.send(m);
650
+ procedureName,
651
+ payload: init,
652
+ controlFlags: 2 /* StreamOpenBit */
653
+ });
664
654
  firstMessage = false;
665
655
  }
666
- (async () => {
656
+ const pipeInputToTransport = async () => {
667
657
  for await (const rawIn of inputStream) {
668
- const m = msg(transport.clientId, serverId, streamId, rawIn);
658
+ const m = {
659
+ streamId,
660
+ payload: rawIn,
661
+ controlFlags: 0
662
+ };
669
663
  if (firstMessage) {
670
- m.controlFlags |= 2 /* StreamOpenBit */;
671
664
  m.serviceName = serviceName;
672
- m.procedureName = procName;
665
+ m.procedureName = procedureName;
666
+ m.controlFlags |= 2 /* StreamOpenBit */;
673
667
  firstMessage = false;
674
668
  }
675
- transport.send(m);
669
+ transport.send(serverId, m);
676
670
  }
677
- transport.send(closeStream(transport.clientId, serverId, streamId));
678
- })();
671
+ if (!healthyClose)
672
+ return;
673
+ transport.sendCloseStream(serverId, streamId);
674
+ };
675
+ void pipeInputToTransport();
679
676
  const responsePromise = new Promise((resolve) => {
680
- const onConnectionStatus = rejectAfterDisconnectGrace(serverId, () => {
677
+ const onSessionStatus = createSessionDisconnectHandler(serverId, () => {
678
+ healthyClose = false;
681
679
  cleanup();
682
680
  resolve(
683
681
  Err({
@@ -689,19 +687,19 @@ function handleUpload(transport, serverId, input, serviceName, procName) {
689
687
  function cleanup() {
690
688
  inputStream.end();
691
689
  transport.removeEventListener("message", onMessage);
692
- transport.removeEventListener("connectionStatus", onConnectionStatus);
690
+ transport.removeEventListener("sessionStatus", onSessionStatus);
693
691
  }
694
- function onMessage(msg2) {
695
- if (msg2.to !== transport.clientId) {
692
+ function onMessage(msg) {
693
+ if (msg.to !== transport.clientId) {
696
694
  return;
697
695
  }
698
- if (msg2.streamId === streamId) {
696
+ if (msg.streamId === streamId) {
699
697
  cleanup();
700
- resolve(msg2.payload);
698
+ resolve(msg.payload);
701
699
  }
702
700
  }
703
701
  transport.addEventListener("message", onMessage);
704
- transport.addEventListener("connectionStatus", onConnectionStatus);
702
+ transport.addEventListener("sessionStatus", onSessionStatus);
705
703
  });
706
704
  return [inputStream, responsePromise];
707
705
  }
@@ -716,10 +714,12 @@ var RiverServer = class {
716
714
  streamMap;
717
715
  // map of client to their open streams by streamId
718
716
  clientStreams;
717
+ disconnectedSessions;
719
718
  constructor(transport, services, extendedContext) {
720
719
  this.transport = transport;
721
720
  this.services = services;
722
721
  this.contextMap = /* @__PURE__ */ new Map();
722
+ this.disconnectedSessions = /* @__PURE__ */ new Set();
723
723
  for (const service of Object.values(services)) {
724
724
  this.contextMap.set(service, {
725
725
  ...extendedContext,
@@ -728,13 +728,13 @@ var RiverServer = class {
728
728
  }
729
729
  this.streamMap = /* @__PURE__ */ new Map();
730
730
  this.clientStreams = /* @__PURE__ */ new Map();
731
- this.transport.addEventListener("message", this.handler);
732
- this.transport.addEventListener("connectionStatus", this.onDisconnect);
731
+ this.transport.addEventListener("message", this.onMessage);
732
+ this.transport.addEventListener("sessionStatus", this.onSessionStatus);
733
733
  }
734
734
  get streams() {
735
735
  return this.streamMap;
736
736
  }
737
- handler = async (message) => {
737
+ onMessage = async (message) => {
738
738
  if (message.to !== this.transport.clientId) {
739
739
  log?.info(
740
740
  `${this.transport.clientId} -- got msg with destination that isn't the server, ignoring`
@@ -749,12 +749,12 @@ var RiverServer = class {
749
749
  }
750
750
  await this.pushToStream(procStream, message, isInitMessage);
751
751
  };
752
- // cleanup streams on unexpected disconnections
753
- onDisconnect = async (evt) => {
752
+ // cleanup streams on session close
753
+ onSessionStatus = async (evt) => {
754
754
  if (evt.status !== "disconnect") {
755
755
  return;
756
756
  }
757
- const disconnectedClientId = evt.conn.connectedTo;
757
+ const disconnectedClientId = evt.session.to;
758
758
  log?.info(
759
759
  `${this.transport.clientId} -- got unexpected disconnect from ${disconnectedClientId}, cleaning up streams`
760
760
  );
@@ -762,14 +762,16 @@ var RiverServer = class {
762
762
  if (!streamsFromThisClient) {
763
763
  return;
764
764
  }
765
+ this.disconnectedSessions.add(disconnectedClientId);
765
766
  await Promise.all(
766
767
  Array.from(streamsFromThisClient).map(this.cleanupStream)
767
768
  );
769
+ this.disconnectedSessions.delete(disconnectedClientId);
768
770
  this.clientStreams.delete(disconnectedClientId);
769
771
  };
770
772
  async close() {
771
- this.transport.removeEventListener("message", this.handler);
772
- this.transport.removeEventListener("connectionStatus", this.onDisconnect);
773
+ this.transport.removeEventListener("message", this.onMessage);
774
+ this.transport.removeEventListener("sessionStatus", this.onSessionStatus);
773
775
  await Promise.all([...this.streamMap.keys()].map(this.cleanupStream));
774
776
  }
775
777
  createNewProcStream(message) {
@@ -793,6 +795,13 @@ var RiverServer = class {
793
795
  );
794
796
  return;
795
797
  }
798
+ const session = this.transport.sessions.get(message.from);
799
+ if (!session) {
800
+ log?.warn(
801
+ `${this.transport.clientId} -- couldn't find session for ${message.from}`
802
+ );
803
+ return;
804
+ }
796
805
  const procedure = service.procedures[message.procedureName];
797
806
  const incoming = pushable({ objectMode: true });
798
807
  const outgoing = pushable({ objectMode: true });
@@ -800,21 +809,20 @@ var RiverServer = class {
800
809
  // sending outgoing messages back to client
801
810
  (async () => {
802
811
  for await (const response of outgoing) {
803
- this.transport.send(reply(message, response));
812
+ this.transport.send(session.to, {
813
+ streamId: message.streamId,
814
+ controlFlags: 0,
815
+ payload: response
816
+ });
804
817
  }
805
- if (procedure.type === "subscription" || procedure.type === "stream") {
806
- this.transport.send(
807
- closeStream(
808
- this.transport.clientId,
809
- message.from,
810
- message.streamId
811
- )
812
- );
818
+ const needsClose = procedure.type === "subscription" || procedure.type === "stream";
819
+ if (needsClose && !this.disconnectedSessions.has(message.from)) {
820
+ this.transport.sendCloseStream(session.to, message.streamId);
813
821
  }
814
822
  })()
815
823
  );
816
824
  const errorHandler = (err) => {
817
- const errorMsg = err instanceof Error ? err.message : `[coerced to error] ${err}`;
825
+ const errorMsg = coerceErrorString(err);
818
826
  log?.error(
819
827
  `${this.transport.clientId} -- procedure ${message.serviceName}.${message.procedureName}:${message.streamId} threw an error: ${errorMsg}`
820
828
  );
@@ -827,82 +835,95 @@ var RiverServer = class {
827
835
  };
828
836
  let inputHandler;
829
837
  const procHasInitMessage = "init" in procedure;
830
- if (procedure.type === "stream") {
831
- if (procHasInitMessage) {
832
- inputHandler = (async () => {
833
- const initMessage = await incoming.next();
834
- if (initMessage.done) {
835
- return;
836
- }
837
- return procedure.handler(serviceContext, initMessage.value, incoming, outgoing).catch(errorHandler);
838
- })();
839
- } else {
840
- inputHandler = procedure.handler(serviceContext, incoming, outgoing).catch(errorHandler);
841
- }
842
- } else if (procedure.type === "rpc") {
843
- inputHandler = (async () => {
844
- const inputMessage = await incoming.next();
845
- if (inputMessage.done) {
846
- return;
847
- }
848
- try {
849
- const outputMessage = await procedure.handler(
850
- serviceContext,
851
- inputMessage.value
852
- );
853
- outgoing.push(outputMessage);
854
- } catch (err) {
855
- errorHandler(err);
856
- }
857
- })();
858
- } else if (procedure.type === "subscription") {
859
- inputHandler = (async () => {
860
- const inputMessage = await incoming.next();
861
- if (inputMessage.done) {
862
- return;
863
- }
864
- try {
865
- await procedure.handler(serviceContext, inputMessage.value, outgoing);
866
- } catch (err) {
867
- errorHandler(err);
868
- }
869
- })();
870
- } else if (procedure.type === "upload") {
871
- if (procHasInitMessage) {
838
+ switch (procedure.type) {
839
+ case "rpc":
872
840
  inputHandler = (async () => {
873
- const initMessage = await incoming.next();
874
- if (initMessage.done) {
841
+ const inputMessage = await incoming.next();
842
+ if (inputMessage.done) {
875
843
  return;
876
844
  }
877
845
  try {
878
846
  const outputMessage = await procedure.handler(
879
847
  serviceContext,
880
- initMessage.value,
881
- incoming
848
+ inputMessage.value
882
849
  );
883
850
  outgoing.push(outputMessage);
884
851
  } catch (err) {
885
852
  errorHandler(err);
886
853
  }
887
854
  })();
888
- } else {
855
+ break;
856
+ case "stream":
857
+ if (procHasInitMessage) {
858
+ inputHandler = (async () => {
859
+ const initMessage = await incoming.next();
860
+ if (initMessage.done) {
861
+ return;
862
+ }
863
+ return procedure.handler(serviceContext, initMessage.value, incoming, outgoing).catch(errorHandler);
864
+ })();
865
+ } else {
866
+ inputHandler = procedure.handler(serviceContext, incoming, outgoing).catch(errorHandler);
867
+ }
868
+ break;
869
+ case "subscription":
889
870
  inputHandler = (async () => {
871
+ const inputMessage = await incoming.next();
872
+ if (inputMessage.done) {
873
+ return;
874
+ }
890
875
  try {
891
- const outputMessage = await procedure.handler(
876
+ await procedure.handler(
892
877
  serviceContext,
893
- incoming
878
+ inputMessage.value,
879
+ outgoing
894
880
  );
895
- outgoing.push(outputMessage);
896
881
  } catch (err) {
897
882
  errorHandler(err);
898
883
  }
899
884
  })();
900
- }
901
- } else {
902
- log?.warn(
903
- `${this.transport.clientId} -- got request for invalid procedure type ${procedure.type} at ${message.serviceName}.${message.procedureName}`
904
- );
905
- return;
885
+ break;
886
+ case "upload":
887
+ if (procHasInitMessage) {
888
+ inputHandler = (async () => {
889
+ const initMessage = await incoming.next();
890
+ if (initMessage.done) {
891
+ return;
892
+ }
893
+ try {
894
+ const outputMessage = await procedure.handler(
895
+ serviceContext,
896
+ initMessage.value,
897
+ incoming
898
+ );
899
+ if (!this.disconnectedSessions.has(message.from)) {
900
+ outgoing.push(outputMessage);
901
+ }
902
+ } catch (err) {
903
+ errorHandler(err);
904
+ }
905
+ })();
906
+ } else {
907
+ inputHandler = (async () => {
908
+ try {
909
+ const outputMessage = await procedure.handler(
910
+ serviceContext,
911
+ incoming
912
+ );
913
+ if (!this.disconnectedSessions.has(message.from)) {
914
+ outgoing.push(outputMessage);
915
+ }
916
+ } catch (err) {
917
+ errorHandler(err);
918
+ }
919
+ })();
920
+ }
921
+ break;
922
+ default:
923
+ log?.warn(
924
+ `${this.transport.clientId} -- got request for invalid procedure type ${procedure.type} at ${message.serviceName}.${message.procedureName}`
925
+ );
926
+ return;
906
927
  }
907
928
  const procStream = {
908
929
  id: message.streamId,
@@ -910,7 +931,6 @@ var RiverServer = class {
910
931
  outgoing,
911
932
  serviceName: message.serviceName,
912
933
  procedureName: message.procedureName,
913
- procedure,
914
934
  promises: { inputHandler, outputHandler }
915
935
  };
916
936
  this.streamMap.set(message.streamId, procStream);
@@ -920,13 +940,18 @@ var RiverServer = class {
920
940
  return procStream;
921
941
  }
922
942
  async pushToStream(procStream, message, isInit) {
923
- const procedure = procStream.procedure;
943
+ const { serviceName, procedureName } = procStream;
944
+ const procedure = this.services[serviceName].procedures[procedureName];
924
945
  const procHasInitMessage = "init" in procedure;
925
- if (isInit && procHasInitMessage && Value.Check(procedure.init, message.payload) || Value.Check(procedure.input, message.payload)) {
946
+ if (isInit && procHasInitMessage && Value.Check(procedure.init, message.payload)) {
947
+ procStream.incoming.push(message.payload);
948
+ } else if (Value.Check(procedure.input, message.payload)) {
926
949
  procStream.incoming.push(message.payload);
927
950
  } else if (!Value.Check(ControlMessagePayloadSchema, message.payload)) {
928
951
  log?.error(
929
- `${this.transport.clientId} -- procedure ${procStream.serviceName}.${procStream.procedureName} received invalid payload: ${JSON.stringify(message.payload)}`
952
+ `${this.transport.clientId} -- procedure ${serviceName}.${procedureName} received invalid payload: ${JSON.stringify(
953
+ message.payload
954
+ )}`
930
955
  );
931
956
  }
932
957
  if (isStreamClose(message.controlFlags)) {
@@ -1,3 +1,20 @@
1
+ // codec/binary.ts
2
+ import { decode, encode } from "@msgpack/msgpack";
3
+ var BinaryCodec = {
4
+ toBuffer: encode,
5
+ fromBuffer: (buff) => {
6
+ try {
7
+ const res = decode(buff);
8
+ if (typeof res !== "object") {
9
+ return null;
10
+ }
11
+ return res;
12
+ } catch {
13
+ return null;
14
+ }
15
+ }
16
+ };
17
+
1
18
  // codec/json.ts
2
19
  var encoder = new TextEncoder();
3
20
  var decoder = new TextDecoder();
@@ -20,7 +37,7 @@ var NaiveJsonCodec = {
20
37
  toBuffer: (obj) => {
21
38
  return encoder.encode(
22
39
  JSON.stringify(obj, function replacer(key) {
23
- let val = this[key];
40
+ const val = this[key];
24
41
  if (val instanceof Uint8Array) {
25
42
  return { $t: uint8ArrayToBase64(val) };
26
43
  } else {
@@ -31,13 +48,19 @@ var NaiveJsonCodec = {
31
48
  },
32
49
  fromBuffer: (buff) => {
33
50
  try {
34
- return JSON.parse(decoder.decode(buff), function reviver(_key, val) {
35
- if (val?.$t) {
36
- return base64ToUint8Array(val.$t);
37
- } else {
38
- return val;
51
+ const parsed = JSON.parse(
52
+ decoder.decode(buff),
53
+ function reviver(_key, val) {
54
+ if (val?.$t) {
55
+ return base64ToUint8Array(val.$t);
56
+ } else {
57
+ return val;
58
+ }
39
59
  }
40
- });
60
+ );
61
+ if (typeof parsed === "object")
62
+ return parsed;
63
+ return null;
41
64
  } catch {
42
65
  return null;
43
66
  }
@@ -45,5 +68,6 @@ var NaiveJsonCodec = {
45
68
  };
46
69
 
47
70
  export {
71
+ BinaryCodec,
48
72
  NaiveJsonCodec
49
73
  };