@event-driven-io/emmett 0.43.0-beta.24 → 0.43.0-beta.26
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.cjs +82 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +49 -7
- package/dist/index.d.ts +49 -7
- package/dist/index.js +80 -12
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -997,7 +997,13 @@ const getInMemoryDatabase = () => {
|
|
|
997
997
|
|
|
998
998
|
//#endregion
|
|
999
999
|
//#region src/processors/checkpoints.ts
|
|
1000
|
-
const ProcessorCheckpoint = (checkpoint) => checkpoint
|
|
1000
|
+
const ProcessorCheckpoint = Object.assign((checkpoint) => checkpoint, {
|
|
1001
|
+
END: "END",
|
|
1002
|
+
BEGINNING: "BEGINNING",
|
|
1003
|
+
isBeginning: (checkpoint) => checkpoint === void 0 || checkpoint === "BEGINNING",
|
|
1004
|
+
isEnd: (checkpoint) => checkpoint === "END",
|
|
1005
|
+
compare: (a, b) => a > b ? 1 : -1
|
|
1006
|
+
});
|
|
1001
1007
|
const bigIntProcessorCheckpoint = (value) => bigInt.toNormalizedString(value);
|
|
1002
1008
|
const parseBigIntProcessorCheckpoint = (value) => BigInt(value);
|
|
1003
1009
|
const getCheckpoint = (message) => {
|
|
@@ -1187,6 +1193,20 @@ const processorCollector = (observability) => {
|
|
|
1187
1193
|
|
|
1188
1194
|
//#endregion
|
|
1189
1195
|
//#region src/processors/processors.ts
|
|
1196
|
+
const CurrentMessageProcessorPosition = {
|
|
1197
|
+
compare: (a, b, compareCheckpoints = (chkA, chkB) => chkA > chkB ? 1 : chkA < chkB ? -1 : 0) => {
|
|
1198
|
+
if (a === b) return 0;
|
|
1199
|
+
if (a === "BEGINNING") return -1;
|
|
1200
|
+
if (b === "BEGINNING") return 1;
|
|
1201
|
+
if (a === "END") return 1;
|
|
1202
|
+
if (b === "END") return -1;
|
|
1203
|
+
return compareCheckpoints(a.lastCheckpoint, b.lastCheckpoint);
|
|
1204
|
+
},
|
|
1205
|
+
zip: (checkpoints, compareCheckpoints) => {
|
|
1206
|
+
if (checkpoints.length === 0) return "BEGINNING";
|
|
1207
|
+
return checkpoints.map((pos) => pos === void 0 ? "BEGINNING" : pos).sort((a, b) => CurrentMessageProcessorPosition.compare(a, b, compareCheckpoints))[0] ?? "BEGINNING";
|
|
1208
|
+
}
|
|
1209
|
+
};
|
|
1190
1210
|
const wasMessageHandled = (message, checkpoint) => {
|
|
1191
1211
|
const messageCheckpoint = getCheckpoint(message);
|
|
1192
1212
|
return messageCheckpoint !== null && messageCheckpoint !== void 0 && checkpoint !== null && checkpoint !== void 0 && messageCheckpoint <= checkpoint;
|
|
@@ -1216,6 +1236,7 @@ const getProjectorId = (options) => `emt:processor:projector:${options.projectio
|
|
|
1216
1236
|
const { info, error } = _event_driven_io_almanac.LogEvent;
|
|
1217
1237
|
const reactor = (options) => {
|
|
1218
1238
|
const { checkpoints, processorId, processorInstanceId: instanceId = getProcessorInstanceId(processorId), type = MessageProcessorType.REACTOR, version = 1, partition = defaultProcessorPartition, hooks = {}, processingScope = defaultProcessingMessageProcessingScope, startFrom, canHandle, stopAfter } = options;
|
|
1239
|
+
const checkpointer = checkpoints === "DISABLED" ? inMemoryCheckpointer() : checkpoints;
|
|
1219
1240
|
const collector = processorCollector(processorObservability(options));
|
|
1220
1241
|
const isCustomBatch = "eachBatch" in options && !!options.eachBatch;
|
|
1221
1242
|
const eachBatch = isCustomBatch ? options.eachBatch : async (messages, context) => {
|
|
@@ -1317,11 +1338,12 @@ const reactor = (options) => {
|
|
|
1317
1338
|
log(info(`Executing onStart hook for processor ${processorId} with instance id ${instanceId}`));
|
|
1318
1339
|
await hooks.onStart(context);
|
|
1319
1340
|
}
|
|
1320
|
-
if (startFrom && startFrom !== "CURRENT") {
|
|
1341
|
+
if (startFrom !== void 0 && startFrom !== "CURRENT") {
|
|
1342
|
+
if (typeof startFrom !== "string") lastCheckpoint = startFrom.lastCheckpoint;
|
|
1321
1343
|
log(info(`Processor ${processorId} with instance id ${instanceId} starting from: ${JSONSerializer.serialize(startFrom)}`));
|
|
1322
1344
|
return startFrom;
|
|
1323
1345
|
}
|
|
1324
|
-
if (
|
|
1346
|
+
if (checkpointer) lastCheckpoint = (await checkpointer.read({
|
|
1325
1347
|
processorId,
|
|
1326
1348
|
partition
|
|
1327
1349
|
}, {
|
|
@@ -1370,8 +1392,8 @@ const reactor = (options) => {
|
|
|
1370
1392
|
} : batchResult;
|
|
1371
1393
|
const isStop = messageProcessingResult && messageProcessingResult.type === "STOP";
|
|
1372
1394
|
const checkpointMessage = messageProcessingResult?.type === "STOP" ? messageProcessingResult.lastSuccessfulMessage : messagesAboveCheckpoint[messagesAboveCheckpoint.length - 1];
|
|
1373
|
-
if (checkpointMessage &&
|
|
1374
|
-
const storeCheckpointResult = await
|
|
1395
|
+
if (checkpointMessage && checkpointer) {
|
|
1396
|
+
const storeCheckpointResult = await checkpointer.store({
|
|
1375
1397
|
processorId,
|
|
1376
1398
|
version,
|
|
1377
1399
|
message: checkpointMessage,
|
|
@@ -1425,14 +1447,14 @@ const projector = (options) => {
|
|
|
1425
1447
|
//#endregion
|
|
1426
1448
|
//#region src/processors/inMemoryProcessors.ts
|
|
1427
1449
|
const inMemoryCheckpointer = () => {
|
|
1450
|
+
let fallbackDatabase;
|
|
1451
|
+
const resolveDatabase = (context) => context?.database ?? (fallbackDatabase ??= getInMemoryDatabase());
|
|
1428
1452
|
return {
|
|
1429
|
-
read: async ({ processorId },
|
|
1430
|
-
|
|
1431
|
-
return Promise.resolve({ lastCheckpoint: checkpoint?.lastCheckpoint ?? null });
|
|
1453
|
+
read: async ({ processorId }, context) => {
|
|
1454
|
+
return { lastCheckpoint: (await resolveDatabase(context).collection("emt_processor_checkpoints").findOne((d) => d._id === processorId))?.lastCheckpoint ?? null };
|
|
1432
1455
|
},
|
|
1433
|
-
store: async (
|
|
1434
|
-
const
|
|
1435
|
-
const checkpoints = database.collection("emt_processor_checkpoints");
|
|
1456
|
+
store: async ({ message, processorId, lastCheckpoint }, context) => {
|
|
1457
|
+
const checkpoints = resolveDatabase(context).collection("emt_processor_checkpoints");
|
|
1436
1458
|
const currentPosition = (await checkpoints.findOne((d) => d._id === processorId))?.lastCheckpoint ?? null;
|
|
1437
1459
|
const newCheckpoint = getCheckpoint(message);
|
|
1438
1460
|
if (currentPosition && (currentPosition === newCheckpoint || currentPosition !== lastCheckpoint)) return {
|
|
@@ -1502,6 +1524,49 @@ const inMemoryReactor = (options) => {
|
|
|
1502
1524
|
return Object.assign(processor, { database });
|
|
1503
1525
|
};
|
|
1504
1526
|
|
|
1527
|
+
//#endregion
|
|
1528
|
+
//#region src/processors/processorStartPositions.ts
|
|
1529
|
+
const ProcessorStartPositions = (options) => {
|
|
1530
|
+
const positions = /* @__PURE__ */ new Map();
|
|
1531
|
+
return {
|
|
1532
|
+
set: (processorId, position) => {
|
|
1533
|
+
positions.set(processorId, position);
|
|
1534
|
+
},
|
|
1535
|
+
with: (expected) => [...positions.entries()].filter(([, position]) => position === expected).map((p) => p[0]),
|
|
1536
|
+
zip: () => CurrentMessageProcessorPosition.zip([...positions.values()], options?.compareCheckpoints),
|
|
1537
|
+
afterStartPosition: (processorId, messages) => {
|
|
1538
|
+
const position = positions.get(processorId);
|
|
1539
|
+
if (position === void 0 || position === "BEGINNING" || position === "END") return messages;
|
|
1540
|
+
const { lastCheckpoint } = position;
|
|
1541
|
+
return messages.filter((message) => {
|
|
1542
|
+
const checkpoint = getCheckpoint(message);
|
|
1543
|
+
return checkpoint !== null && checkpoint > lastCheckpoint;
|
|
1544
|
+
});
|
|
1545
|
+
}
|
|
1546
|
+
};
|
|
1547
|
+
};
|
|
1548
|
+
const ConsumerStartPositions = { resolve: async ({ processors, handlerContext: handlerOptions, readLastMessageCheckpoint, compareCheckpoints }) => {
|
|
1549
|
+
const positions = ProcessorStartPositions({ compareCheckpoints });
|
|
1550
|
+
await Promise.all(processors.map(async (o) => {
|
|
1551
|
+
try {
|
|
1552
|
+
const position = await o.start(handlerOptions);
|
|
1553
|
+
positions.set(o.id, position);
|
|
1554
|
+
} catch (error) {
|
|
1555
|
+
console.log(`Error during processor start position retrieval for processor: ${o.id}. Stopping it.`, error);
|
|
1556
|
+
throw error;
|
|
1557
|
+
}
|
|
1558
|
+
}));
|
|
1559
|
+
const endProcessorIds = positions.with("END");
|
|
1560
|
+
if (endProcessorIds.length > 0) {
|
|
1561
|
+
const lastCheckpoint = await readLastMessageCheckpoint(handlerOptions);
|
|
1562
|
+
for (const processorId of endProcessorIds) positions.set(processorId, lastCheckpoint ? { lastCheckpoint } : "BEGINNING");
|
|
1563
|
+
}
|
|
1564
|
+
return {
|
|
1565
|
+
earliestPosition: positions.zip(),
|
|
1566
|
+
afterStartPosition: (processorId, messages) => positions.afterStartPosition(processorId, messages)
|
|
1567
|
+
};
|
|
1568
|
+
} };
|
|
1569
|
+
|
|
1505
1570
|
//#endregion
|
|
1506
1571
|
//#region src/eventStore/projections/inMemory/inMemoryProjection.ts
|
|
1507
1572
|
const DATABASE_REQUIRED_ERROR_MESSAGE = "Database is required in context for InMemory projections";
|
|
@@ -2856,6 +2921,8 @@ var src_exports = /* @__PURE__ */ require_plugins.__exportAll({
|
|
|
2856
2921
|
CommandHandlerStreamVersionConflictRetryOptions: () => CommandHandlerStreamVersionConflictRetryOptions,
|
|
2857
2922
|
ConcurrencyError: () => require_plugins.ConcurrencyError,
|
|
2858
2923
|
ConcurrencyInMemoryDatabaseError: () => require_plugins.ConcurrencyInMemoryDatabaseError,
|
|
2924
|
+
ConsumerStartPositions: () => ConsumerStartPositions,
|
|
2925
|
+
CurrentMessageProcessorPosition: () => CurrentMessageProcessorPosition,
|
|
2859
2926
|
DATABASE_REQUIRED_ERROR_MESSAGE: () => DATABASE_REQUIRED_ERROR_MESSAGE,
|
|
2860
2927
|
DeciderCommandHandler: () => DeciderCommandHandler,
|
|
2861
2928
|
DeciderSpecification: () => DeciderSpecification,
|
|
@@ -2881,6 +2948,7 @@ var src_exports = /* @__PURE__ */ require_plugins.__exportAll({
|
|
|
2881
2948
|
NoRetries: () => NoRetries,
|
|
2882
2949
|
NotFoundError: () => require_plugins.NotFoundError,
|
|
2883
2950
|
ProcessorCheckpoint: () => ProcessorCheckpoint,
|
|
2951
|
+
ProcessorStartPositions: () => ProcessorStartPositions,
|
|
2884
2952
|
STREAM_DOES_NOT_EXIST: () => STREAM_DOES_NOT_EXIST,
|
|
2885
2953
|
STREAM_EXISTS: () => STREAM_EXISTS,
|
|
2886
2954
|
ScopeTypes: () => ScopeTypes,
|
|
@@ -3021,6 +3089,8 @@ exports.CommandHandler = CommandHandler;
|
|
|
3021
3089
|
exports.CommandHandlerStreamVersionConflictRetryOptions = CommandHandlerStreamVersionConflictRetryOptions;
|
|
3022
3090
|
exports.ConcurrencyError = require_plugins.ConcurrencyError;
|
|
3023
3091
|
exports.ConcurrencyInMemoryDatabaseError = require_plugins.ConcurrencyInMemoryDatabaseError;
|
|
3092
|
+
exports.ConsumerStartPositions = ConsumerStartPositions;
|
|
3093
|
+
exports.CurrentMessageProcessorPosition = CurrentMessageProcessorPosition;
|
|
3024
3094
|
exports.DATABASE_REQUIRED_ERROR_MESSAGE = DATABASE_REQUIRED_ERROR_MESSAGE;
|
|
3025
3095
|
exports.DeciderCommandHandler = DeciderCommandHandler;
|
|
3026
3096
|
exports.DeciderSpecification = DeciderSpecification;
|
|
@@ -3046,6 +3116,7 @@ exports.NO_CONCURRENCY_CHECK = NO_CONCURRENCY_CHECK;
|
|
|
3046
3116
|
exports.NoRetries = NoRetries;
|
|
3047
3117
|
exports.NotFoundError = require_plugins.NotFoundError;
|
|
3048
3118
|
exports.ProcessorCheckpoint = ProcessorCheckpoint;
|
|
3119
|
+
exports.ProcessorStartPositions = ProcessorStartPositions;
|
|
3049
3120
|
exports.STREAM_DOES_NOT_EXIST = STREAM_DOES_NOT_EXIST;
|
|
3050
3121
|
exports.STREAM_EXISTS = STREAM_EXISTS;
|
|
3051
3122
|
exports.ScopeTypes = ScopeTypes;
|