@orion-js/echoes 4.5.5 → 4.5.7

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.
package/dist/index.js CHANGED
@@ -699,10 +699,14 @@ var EventBus = class {
699
699
  const subscriptions = Object.entries(this.echoes).filter(([, echo2]) => echo2.type === "event").map(([topic, echo2]) => ({
700
700
  topic,
701
701
  attemptsBeforeDeadLetter: echo2.attemptsBeforeDeadLetter,
702
- ordered: echo2.ordered,
703
702
  configVersion: echo2.configVersion,
704
- executionVersion: echo2.executionVersion
703
+ maxConcurrency: echo2.maxConcurrency,
704
+ receiverMode: echo2.receiverMode ?? "single",
705
+ batchSize: echo2.batchSize ?? 1
705
706
  }));
707
+ if (this.consumeFrom.includes("kafka") && subscriptions.some((subscription) => subscription.receiverMode === "batch")) {
708
+ throw new Error("Echoes batch event receivers are supported only by the Pulse transport.");
709
+ }
706
710
  try {
707
711
  for (const name of selected) {
708
712
  const transport = this.transports[name];
@@ -711,7 +715,8 @@ var EventBus = class {
711
715
  consume: this.consumeFrom.includes(name),
712
716
  publish: this.publishTo === name,
713
717
  subscriptions,
714
- onEvent: (event) => this.handleEvent(event)
718
+ onEvent: (event) => this.handleEvent(event),
719
+ onEvents: (events) => this.handleEvents(events)
715
720
  });
716
721
  }
717
722
  this.started = true;
@@ -760,6 +765,15 @@ var EventBus = class {
760
765
  data: event.data
761
766
  });
762
767
  }
768
+ async handleEvents(events) {
769
+ if (events.length === 0) return;
770
+ const echo2 = this.echoes[events[0].topic];
771
+ if ((echo2 == null ? void 0 : echo2.type) === "event" && echo2.onEvents) {
772
+ await echo2.onEvents(events);
773
+ return;
774
+ }
775
+ for (const event of events) await this.handleEvent(event);
776
+ }
763
777
  };
764
778
 
765
779
  // src/events/PulseManager.ts
@@ -789,18 +803,23 @@ var PulseManager = class {
789
803
  this.subscriptions = await Promise.all(
790
804
  options.subscriptions.map(async (definition) => {
791
805
  const subscribeOptions = this.getSubscribeOptions(subscription, definition);
792
- const active = await this.pulse.subscribe(
806
+ if (definition.receiverMode === "batch") {
807
+ if (typeof this.pulse.subscribeBatch !== "function") {
808
+ throw new Error(
809
+ "Echoes batch event receivers require a version of @orion-js/pulse with subscribeBatch support."
810
+ );
811
+ }
812
+ return await this.pulse.subscribeBatch(
813
+ definition.topic,
814
+ (events) => options.onEvents(events.map((event) => this.createReceivedEvent(event))),
815
+ { ...subscribeOptions, batchSize: definition.batchSize }
816
+ );
817
+ }
818
+ return await this.pulse.subscribe(
793
819
  definition.topic,
794
820
  (event) => options.onEvent(this.createReceivedEvent(event)),
795
821
  subscribeOptions
796
822
  );
797
- if (subscribeOptions.executionVersion === 2 && active.executionVersion !== 2) {
798
- await active.unsubscribe();
799
- throw new Error(
800
- "Echoes executionVersion 2 requires a bridge-capable @orion-js/pulse version and a winning configVersion for this listener."
801
- );
802
- }
803
- return active;
804
823
  })
805
824
  );
806
825
  }
@@ -821,10 +840,9 @@ var PulseManager = class {
821
840
  getSubscribeOptions(defaults = {}, definition) {
822
841
  return {
823
842
  ...defaults,
824
- ...definition.ordered === void 0 ? {} : { ordered: definition.ordered },
825
843
  ...definition.configVersion === void 0 ? {} : { configVersion: definition.configVersion },
826
- ...definition.executionVersion === void 0 ? {} : { executionVersion: definition.executionVersion },
827
- ...definition.attemptsBeforeDeadLetter === void 0 ? {} : { maxRetries: definition.attemptsBeforeDeadLetter }
844
+ ...definition.attemptsBeforeDeadLetter === void 0 ? {} : { maxRetries: definition.attemptsBeforeDeadLetter },
845
+ ...definition.maxConcurrency === void 0 ? {} : { maxConcurrency: definition.maxConcurrency }
828
846
  };
829
847
  }
830
848
  createReceivedEvent(event) {
@@ -958,6 +976,18 @@ async function stopService() {
958
976
  }
959
977
 
960
978
  // src/echo/index.ts
979
+ function receivedEventContext(event) {
980
+ return {
981
+ ...event.context || {},
982
+ transport: event.transport,
983
+ eventId: event.id,
984
+ topic: event.topic,
985
+ headers: event.headers,
986
+ createdAt: event.createdAt,
987
+ attempt: event.attempt,
988
+ data: event.data
989
+ };
990
+ }
961
991
  var echo = function createNewEcho(options) {
962
992
  const resolve = async (params, context) => {
963
993
  const cleaned = options.params ? await parseEchoesSchema(options.params, params) : params ?? {};
@@ -968,26 +998,17 @@ var echo = function createNewEcho(options) {
968
998
  return result;
969
999
  };
970
1000
  const onEvent = async (event) => {
971
- const context = {
972
- ...event.context || {},
973
- transport: event.transport,
974
- eventId: event.id,
975
- topic: event.topic,
976
- headers: event.headers,
977
- createdAt: event.createdAt,
978
- attempt: event.attempt,
979
- data: event.data
980
- };
981
- await resolve(event.data.params, context);
1001
+ await resolve(event.data.params, receivedEventContext(event));
982
1002
  };
983
1003
  return {
984
1004
  type: options.type,
985
1005
  params: options.params,
986
1006
  returns: options.returns,
987
1007
  attemptsBeforeDeadLetter: options.type === "event" ? options.attemptsBeforeDeadLetter : void 0,
988
- ordered: options.type === "event" ? options.ordered : void 0,
989
1008
  configVersion: options.type === "event" ? options.configVersion : void 0,
990
- executionVersion: options.type === "event" ? options.executionVersion : void 0,
1009
+ maxConcurrency: options.type === "event" ? options.maxConcurrency : void 0,
1010
+ receiverMode: options.type === "event" ? "single" : void 0,
1011
+ batchSize: options.type === "event" ? 1 : void 0,
991
1012
  resolve,
992
1013
  onEvent,
993
1014
  onMessage: async (messageData) => {
@@ -1025,6 +1046,50 @@ function createEchoRequest(options) {
1025
1046
  function createEchoEvent(options) {
1026
1047
  return echo({ ...options, type: "event" });
1027
1048
  }
1049
+ function createEchoBatchEvent(options) {
1050
+ if (!Number.isInteger(options.batchSize) || options.batchSize <= 0) {
1051
+ throw new Error("batchSize must be a positive integer.");
1052
+ }
1053
+ const resolveBatch = async (events) => {
1054
+ const cleaned = await Promise.all(
1055
+ events.map(async (event) => ({
1056
+ params: options.params ? await parseEchoesSchema(options.params, event.params) : event.params ?? {},
1057
+ context: event.context
1058
+ }))
1059
+ );
1060
+ await options.resolveBatch(cleaned);
1061
+ };
1062
+ const onEvents = async (events) => {
1063
+ await resolveBatch(
1064
+ events.map((event) => ({
1065
+ params: event.data.params,
1066
+ context: receivedEventContext(event)
1067
+ }))
1068
+ );
1069
+ };
1070
+ return {
1071
+ type: "event",
1072
+ params: options.params,
1073
+ attemptsBeforeDeadLetter: options.attemptsBeforeDeadLetter,
1074
+ configVersion: options.configVersion,
1075
+ maxConcurrency: options.maxConcurrency,
1076
+ receiverMode: "batch",
1077
+ batchSize: options.batchSize,
1078
+ resolve: async (params, context) => {
1079
+ await resolveBatch([{ params, context: context ?? {} }]);
1080
+ return void 0;
1081
+ },
1082
+ resolveBatch,
1083
+ onEvent: async (event) => await onEvents([event]),
1084
+ onEvents,
1085
+ onMessage: async () => {
1086
+ throw new Error("Echoes batch event receivers are supported only by the Pulse transport.");
1087
+ },
1088
+ onRequest: async () => {
1089
+ throw new Error("Echoes batch events cannot be invoked as requests.");
1090
+ }
1091
+ };
1092
+ }
1028
1093
 
1029
1094
  // src/schema.ts
1030
1095
  function typedEchoesSchema(schema) {
@@ -1077,6 +1142,28 @@ function EchoEvent(options = {}) {
1077
1142
  return method;
1078
1143
  };
1079
1144
  }
1145
+ function EchoBatchEvent(options) {
1146
+ return (method, context) => {
1147
+ const propertyKey = String(context.name);
1148
+ pendingEchoEntries[propertyKey] = (instance) => {
1149
+ const originalResolveBatch = instance[propertyKey].bind(instance);
1150
+ return createEchoBatchEvent({
1151
+ ...options,
1152
+ resolveBatch: async (events) => {
1153
+ return await runWithEchoesContext(
1154
+ {
1155
+ controllerType: "echo",
1156
+ echoName: propertyKey,
1157
+ params: events.map((event) => event.params)
1158
+ },
1159
+ async () => await originalResolveBatch(events)
1160
+ );
1161
+ }
1162
+ });
1163
+ };
1164
+ return method;
1165
+ };
1166
+ }
1080
1167
  function EchoRequest(options = {}) {
1081
1168
  return (method, context) => {
1082
1169
  const propertyKey = String(context.name);
@@ -1140,6 +1227,7 @@ function getServiceEchoes(target) {
1140
1227
  return echoesMap;
1141
1228
  }
1142
1229
  export {
1230
+ EchoBatchEvent,
1143
1231
  EchoEvent,
1144
1232
  EchoRequest,
1145
1233
  Echoes,
@@ -1147,6 +1235,7 @@ export {
1147
1235
  EchoesValidationError,
1148
1236
  cleanEchoesSchema,
1149
1237
  configureEchoesRuntime,
1238
+ createEchoBatchEvent,
1150
1239
  createEchoEvent,
1151
1240
  createEchoRequest,
1152
1241
  createEchoesUserError,