@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/echo/index.d.ts +2 -1
- package/dist/events/EventBus.d.ts +1 -0
- package/dist/events/EventTransport.d.ts +4 -2
- package/dist/index.cjs +118 -27
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +116 -27
- package/dist/index.js.map +1 -1
- package/dist/service/index.d.ts +3 -2
- package/dist/types.d.ts +23 -13
- package/package.json +3 -3
- package/LICENSE +0 -21
package/dist/echo/index.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import type { EchoesSchema } from '../schema';
|
|
2
|
-
import { EchoConfig, EchoEventConfig, EchoRequestConfig, EchoType } from '../types';
|
|
2
|
+
import { EchoBatchEventConfig, EchoConfig, EchoEventConfig, EchoRequestConfig, EchoType } from '../types';
|
|
3
3
|
/**
|
|
4
4
|
* @deprecated Use createEchoRequest and createEchoEvent instead
|
|
5
5
|
*/
|
|
6
6
|
declare const echo: <TParamsSchema extends EchoesSchema, TReturnsSchema extends EchoesSchema, TEchoType extends 'event' | 'request'>(options: EchoConfig<TParamsSchema, TReturnsSchema, TEchoType>) => EchoType<TParamsSchema, TReturnsSchema, TEchoType>;
|
|
7
7
|
export declare function createEchoRequest<TParamsSchema extends EchoesSchema, TReturnsSchema extends EchoesSchema>(options: EchoRequestConfig<TParamsSchema, TReturnsSchema>): EchoType<TParamsSchema, TReturnsSchema, 'request'>;
|
|
8
8
|
export declare function createEchoEvent<TParamsSchema extends EchoesSchema, TReturnsSchema extends EchoesSchema>(options: EchoEventConfig<TParamsSchema, TReturnsSchema>): EchoType<TParamsSchema, TReturnsSchema, 'event'>;
|
|
9
|
+
export declare function createEchoBatchEvent<TParamsSchema extends EchoesSchema = any>(options: EchoBatchEventConfig<TParamsSchema>): EchoType<TParamsSchema, any, 'event'>;
|
|
9
10
|
export { echo };
|
|
@@ -2,15 +2,17 @@ import type { EchoesEventTransportName, EchoesReceivedEvent, PublishOptions } fr
|
|
|
2
2
|
export interface EventSubscriptionDefinition {
|
|
3
3
|
topic: string;
|
|
4
4
|
attemptsBeforeDeadLetter?: number;
|
|
5
|
-
ordered?: boolean;
|
|
6
5
|
configVersion?: number;
|
|
7
|
-
|
|
6
|
+
maxConcurrency?: number;
|
|
7
|
+
receiverMode: 'single' | 'batch';
|
|
8
|
+
batchSize: number;
|
|
8
9
|
}
|
|
9
10
|
export interface EventTransportStartOptions {
|
|
10
11
|
consume: boolean;
|
|
11
12
|
publish: boolean;
|
|
12
13
|
subscriptions: EventSubscriptionDefinition[];
|
|
13
14
|
onEvent(event: EchoesReceivedEvent): Promise<void>;
|
|
15
|
+
onEvents(events: EchoesReceivedEvent[]): Promise<void>;
|
|
14
16
|
}
|
|
15
17
|
export interface EventTransport {
|
|
16
18
|
readonly name: EchoesEventTransportName;
|
package/dist/index.cjs
CHANGED
|
@@ -29,6 +29,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
29
29
|
// src/index.ts
|
|
30
30
|
var index_exports = {};
|
|
31
31
|
__export(index_exports, {
|
|
32
|
+
EchoBatchEvent: () => EchoBatchEvent,
|
|
32
33
|
EchoEvent: () => EchoEvent,
|
|
33
34
|
EchoRequest: () => EchoRequest,
|
|
34
35
|
Echoes: () => Echoes,
|
|
@@ -36,6 +37,7 @@ __export(index_exports, {
|
|
|
36
37
|
EchoesValidationError: () => EchoesValidationError,
|
|
37
38
|
cleanEchoesSchema: () => cleanEchoesSchema,
|
|
38
39
|
configureEchoesRuntime: () => configureEchoesRuntime,
|
|
40
|
+
createEchoBatchEvent: () => createEchoBatchEvent,
|
|
39
41
|
createEchoEvent: () => createEchoEvent,
|
|
40
42
|
createEchoRequest: () => createEchoRequest,
|
|
41
43
|
createEchoesUserError: () => createEchoesUserError,
|
|
@@ -756,10 +758,14 @@ var EventBus = class {
|
|
|
756
758
|
const subscriptions = Object.entries(this.echoes).filter(([, echo2]) => echo2.type === "event").map(([topic, echo2]) => ({
|
|
757
759
|
topic,
|
|
758
760
|
attemptsBeforeDeadLetter: echo2.attemptsBeforeDeadLetter,
|
|
759
|
-
ordered: echo2.ordered,
|
|
760
761
|
configVersion: echo2.configVersion,
|
|
761
|
-
|
|
762
|
+
maxConcurrency: echo2.maxConcurrency,
|
|
763
|
+
receiverMode: echo2.receiverMode ?? "single",
|
|
764
|
+
batchSize: echo2.batchSize ?? 1
|
|
762
765
|
}));
|
|
766
|
+
if (this.consumeFrom.includes("kafka") && subscriptions.some((subscription) => subscription.receiverMode === "batch")) {
|
|
767
|
+
throw new Error("Echoes batch event receivers are supported only by the Pulse transport.");
|
|
768
|
+
}
|
|
763
769
|
try {
|
|
764
770
|
for (const name of selected) {
|
|
765
771
|
const transport = this.transports[name];
|
|
@@ -768,7 +774,8 @@ var EventBus = class {
|
|
|
768
774
|
consume: this.consumeFrom.includes(name),
|
|
769
775
|
publish: this.publishTo === name,
|
|
770
776
|
subscriptions,
|
|
771
|
-
onEvent: (event) => this.handleEvent(event)
|
|
777
|
+
onEvent: (event) => this.handleEvent(event),
|
|
778
|
+
onEvents: (events) => this.handleEvents(events)
|
|
772
779
|
});
|
|
773
780
|
}
|
|
774
781
|
this.started = true;
|
|
@@ -817,6 +824,15 @@ var EventBus = class {
|
|
|
817
824
|
data: event.data
|
|
818
825
|
});
|
|
819
826
|
}
|
|
827
|
+
async handleEvents(events) {
|
|
828
|
+
if (events.length === 0) return;
|
|
829
|
+
const echo2 = this.echoes[events[0].topic];
|
|
830
|
+
if ((echo2 == null ? void 0 : echo2.type) === "event" && echo2.onEvents) {
|
|
831
|
+
await echo2.onEvents(events);
|
|
832
|
+
return;
|
|
833
|
+
}
|
|
834
|
+
for (const event of events) await this.handleEvent(event);
|
|
835
|
+
}
|
|
820
836
|
};
|
|
821
837
|
|
|
822
838
|
// src/events/PulseManager.ts
|
|
@@ -846,18 +862,23 @@ var PulseManager = class {
|
|
|
846
862
|
this.subscriptions = await Promise.all(
|
|
847
863
|
options.subscriptions.map(async (definition) => {
|
|
848
864
|
const subscribeOptions = this.getSubscribeOptions(subscription, definition);
|
|
849
|
-
|
|
865
|
+
if (definition.receiverMode === "batch") {
|
|
866
|
+
if (typeof this.pulse.subscribeBatch !== "function") {
|
|
867
|
+
throw new Error(
|
|
868
|
+
"Echoes batch event receivers require a version of @orion-js/pulse with subscribeBatch support."
|
|
869
|
+
);
|
|
870
|
+
}
|
|
871
|
+
return await this.pulse.subscribeBatch(
|
|
872
|
+
definition.topic,
|
|
873
|
+
(events) => options.onEvents(events.map((event) => this.createReceivedEvent(event))),
|
|
874
|
+
{ ...subscribeOptions, batchSize: definition.batchSize }
|
|
875
|
+
);
|
|
876
|
+
}
|
|
877
|
+
return await this.pulse.subscribe(
|
|
850
878
|
definition.topic,
|
|
851
879
|
(event) => options.onEvent(this.createReceivedEvent(event)),
|
|
852
880
|
subscribeOptions
|
|
853
881
|
);
|
|
854
|
-
if (subscribeOptions.executionVersion === 2 && active.executionVersion !== 2) {
|
|
855
|
-
await active.unsubscribe();
|
|
856
|
-
throw new Error(
|
|
857
|
-
"Echoes executionVersion 2 requires a bridge-capable @orion-js/pulse version and a winning configVersion for this listener."
|
|
858
|
-
);
|
|
859
|
-
}
|
|
860
|
-
return active;
|
|
861
882
|
})
|
|
862
883
|
);
|
|
863
884
|
}
|
|
@@ -878,10 +899,9 @@ var PulseManager = class {
|
|
|
878
899
|
getSubscribeOptions(defaults = {}, definition) {
|
|
879
900
|
return {
|
|
880
901
|
...defaults,
|
|
881
|
-
...definition.ordered === void 0 ? {} : { ordered: definition.ordered },
|
|
882
902
|
...definition.configVersion === void 0 ? {} : { configVersion: definition.configVersion },
|
|
883
|
-
...definition.
|
|
884
|
-
...definition.
|
|
903
|
+
...definition.attemptsBeforeDeadLetter === void 0 ? {} : { maxRetries: definition.attemptsBeforeDeadLetter },
|
|
904
|
+
...definition.maxConcurrency === void 0 ? {} : { maxConcurrency: definition.maxConcurrency }
|
|
885
905
|
};
|
|
886
906
|
}
|
|
887
907
|
createReceivedEvent(event) {
|
|
@@ -1015,6 +1035,18 @@ async function stopService() {
|
|
|
1015
1035
|
}
|
|
1016
1036
|
|
|
1017
1037
|
// src/echo/index.ts
|
|
1038
|
+
function receivedEventContext(event) {
|
|
1039
|
+
return {
|
|
1040
|
+
...event.context || {},
|
|
1041
|
+
transport: event.transport,
|
|
1042
|
+
eventId: event.id,
|
|
1043
|
+
topic: event.topic,
|
|
1044
|
+
headers: event.headers,
|
|
1045
|
+
createdAt: event.createdAt,
|
|
1046
|
+
attempt: event.attempt,
|
|
1047
|
+
data: event.data
|
|
1048
|
+
};
|
|
1049
|
+
}
|
|
1018
1050
|
var echo = function createNewEcho(options) {
|
|
1019
1051
|
const resolve = async (params, context) => {
|
|
1020
1052
|
const cleaned = options.params ? await parseEchoesSchema(options.params, params) : params ?? {};
|
|
@@ -1025,26 +1057,17 @@ var echo = function createNewEcho(options) {
|
|
|
1025
1057
|
return result;
|
|
1026
1058
|
};
|
|
1027
1059
|
const onEvent = async (event) => {
|
|
1028
|
-
|
|
1029
|
-
...event.context || {},
|
|
1030
|
-
transport: event.transport,
|
|
1031
|
-
eventId: event.id,
|
|
1032
|
-
topic: event.topic,
|
|
1033
|
-
headers: event.headers,
|
|
1034
|
-
createdAt: event.createdAt,
|
|
1035
|
-
attempt: event.attempt,
|
|
1036
|
-
data: event.data
|
|
1037
|
-
};
|
|
1038
|
-
await resolve(event.data.params, context);
|
|
1060
|
+
await resolve(event.data.params, receivedEventContext(event));
|
|
1039
1061
|
};
|
|
1040
1062
|
return {
|
|
1041
1063
|
type: options.type,
|
|
1042
1064
|
params: options.params,
|
|
1043
1065
|
returns: options.returns,
|
|
1044
1066
|
attemptsBeforeDeadLetter: options.type === "event" ? options.attemptsBeforeDeadLetter : void 0,
|
|
1045
|
-
ordered: options.type === "event" ? options.ordered : void 0,
|
|
1046
1067
|
configVersion: options.type === "event" ? options.configVersion : void 0,
|
|
1047
|
-
|
|
1068
|
+
maxConcurrency: options.type === "event" ? options.maxConcurrency : void 0,
|
|
1069
|
+
receiverMode: options.type === "event" ? "single" : void 0,
|
|
1070
|
+
batchSize: options.type === "event" ? 1 : void 0,
|
|
1048
1071
|
resolve,
|
|
1049
1072
|
onEvent,
|
|
1050
1073
|
onMessage: async (messageData) => {
|
|
@@ -1082,6 +1105,50 @@ function createEchoRequest(options) {
|
|
|
1082
1105
|
function createEchoEvent(options) {
|
|
1083
1106
|
return echo({ ...options, type: "event" });
|
|
1084
1107
|
}
|
|
1108
|
+
function createEchoBatchEvent(options) {
|
|
1109
|
+
if (!Number.isInteger(options.batchSize) || options.batchSize <= 0) {
|
|
1110
|
+
throw new Error("batchSize must be a positive integer.");
|
|
1111
|
+
}
|
|
1112
|
+
const resolveBatch = async (events) => {
|
|
1113
|
+
const cleaned = await Promise.all(
|
|
1114
|
+
events.map(async (event) => ({
|
|
1115
|
+
params: options.params ? await parseEchoesSchema(options.params, event.params) : event.params ?? {},
|
|
1116
|
+
context: event.context
|
|
1117
|
+
}))
|
|
1118
|
+
);
|
|
1119
|
+
await options.resolveBatch(cleaned);
|
|
1120
|
+
};
|
|
1121
|
+
const onEvents = async (events) => {
|
|
1122
|
+
await resolveBatch(
|
|
1123
|
+
events.map((event) => ({
|
|
1124
|
+
params: event.data.params,
|
|
1125
|
+
context: receivedEventContext(event)
|
|
1126
|
+
}))
|
|
1127
|
+
);
|
|
1128
|
+
};
|
|
1129
|
+
return {
|
|
1130
|
+
type: "event",
|
|
1131
|
+
params: options.params,
|
|
1132
|
+
attemptsBeforeDeadLetter: options.attemptsBeforeDeadLetter,
|
|
1133
|
+
configVersion: options.configVersion,
|
|
1134
|
+
maxConcurrency: options.maxConcurrency,
|
|
1135
|
+
receiverMode: "batch",
|
|
1136
|
+
batchSize: options.batchSize,
|
|
1137
|
+
resolve: async (params, context) => {
|
|
1138
|
+
await resolveBatch([{ params, context: context ?? {} }]);
|
|
1139
|
+
return void 0;
|
|
1140
|
+
},
|
|
1141
|
+
resolveBatch,
|
|
1142
|
+
onEvent: async (event) => await onEvents([event]),
|
|
1143
|
+
onEvents,
|
|
1144
|
+
onMessage: async () => {
|
|
1145
|
+
throw new Error("Echoes batch event receivers are supported only by the Pulse transport.");
|
|
1146
|
+
},
|
|
1147
|
+
onRequest: async () => {
|
|
1148
|
+
throw new Error("Echoes batch events cannot be invoked as requests.");
|
|
1149
|
+
}
|
|
1150
|
+
};
|
|
1151
|
+
}
|
|
1085
1152
|
|
|
1086
1153
|
// src/schema.ts
|
|
1087
1154
|
function typedEchoesSchema(schema) {
|
|
@@ -1134,6 +1201,28 @@ function EchoEvent(options = {}) {
|
|
|
1134
1201
|
return method;
|
|
1135
1202
|
};
|
|
1136
1203
|
}
|
|
1204
|
+
function EchoBatchEvent(options) {
|
|
1205
|
+
return (method, context) => {
|
|
1206
|
+
const propertyKey = String(context.name);
|
|
1207
|
+
pendingEchoEntries[propertyKey] = (instance) => {
|
|
1208
|
+
const originalResolveBatch = instance[propertyKey].bind(instance);
|
|
1209
|
+
return createEchoBatchEvent({
|
|
1210
|
+
...options,
|
|
1211
|
+
resolveBatch: async (events) => {
|
|
1212
|
+
return await runWithEchoesContext(
|
|
1213
|
+
{
|
|
1214
|
+
controllerType: "echo",
|
|
1215
|
+
echoName: propertyKey,
|
|
1216
|
+
params: events.map((event) => event.params)
|
|
1217
|
+
},
|
|
1218
|
+
async () => await originalResolveBatch(events)
|
|
1219
|
+
);
|
|
1220
|
+
}
|
|
1221
|
+
});
|
|
1222
|
+
};
|
|
1223
|
+
return method;
|
|
1224
|
+
};
|
|
1225
|
+
}
|
|
1137
1226
|
function EchoRequest(options = {}) {
|
|
1138
1227
|
return (method, context) => {
|
|
1139
1228
|
const propertyKey = String(context.name);
|
|
@@ -1198,6 +1287,7 @@ function getServiceEchoes(target) {
|
|
|
1198
1287
|
}
|
|
1199
1288
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1200
1289
|
0 && (module.exports = {
|
|
1290
|
+
EchoBatchEvent,
|
|
1201
1291
|
EchoEvent,
|
|
1202
1292
|
EchoRequest,
|
|
1203
1293
|
Echoes,
|
|
@@ -1205,6 +1295,7 @@ function getServiceEchoes(target) {
|
|
|
1205
1295
|
EchoesValidationError,
|
|
1206
1296
|
cleanEchoesSchema,
|
|
1207
1297
|
configureEchoesRuntime,
|
|
1298
|
+
createEchoBatchEvent,
|
|
1208
1299
|
createEchoEvent,
|
|
1209
1300
|
createEchoRequest,
|
|
1210
1301
|
createEchoesUserError,
|