@event-driven-io/emmett 0.43.0-beta.23 → 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 CHANGED
@@ -619,6 +619,11 @@ const bigIntReplacer = (_key, value) => {
619
619
  const dateReplacer = (_key, value) => {
620
620
  return value instanceof Date ? value.toISOString() : value;
621
621
  };
622
+ const errorReplacer = (_key, value) => value instanceof Error ? {
623
+ type: value.constructor.name || "error",
624
+ message: value.message,
625
+ stack: value.stack
626
+ } : value;
622
627
  const isFirstLetterNumeric = (str) => {
623
628
  const c = str.charCodeAt(0);
624
629
  return c >= 48 && c <= 57;
@@ -660,11 +665,12 @@ const composeJSONRevivers = (...revivers) => {
660
665
  if (filteredRevivers.length === 0) return void 0;
661
666
  return (key, value, context) => filteredRevivers.reduce((accValue, reviver) => reviver(key, accValue, context), value);
662
667
  };
663
- const JSONReplacer = (opts) => composeJSONReplacers(opts?.replacer, opts?.failOnBigIntSerialization !== true ? JSONReplacers.bigInt : void 0, opts?.useDefaultDateSerialization !== true ? JSONReplacers.date : void 0);
668
+ const JSONReplacer = (opts) => composeJSONReplacers(opts?.replacer, opts?.failOnBigIntSerialization !== true ? JSONReplacers.bigInt : void 0, opts?.useDefaultDateSerialization !== true ? JSONReplacers.date : void 0, opts?.skipErrorSerialization !== true ? JSONReplacers.error : void 0);
664
669
  const JSONReviver = (opts) => composeJSONRevivers(opts?.reviver, opts?.parseBigInts === true ? JSONRevivers.bigInt : void 0, opts?.parseDates === true ? JSONRevivers.date : void 0);
665
670
  const JSONReplacers = {
666
671
  bigInt: bigIntReplacer,
667
- date: dateReplacer
672
+ date: dateReplacer,
673
+ error: errorReplacer
668
674
  };
669
675
  const JSONRevivers = {
670
676
  bigInt: bigIntReviver,
@@ -673,8 +679,19 @@ const JSONRevivers = {
673
679
  const jsonSerializer = (options) => {
674
680
  const defaultReplacer = JSONReplacer(options);
675
681
  const defaultReviver = JSONReviver(options);
682
+ const defaultFormat = options?.format ?? "compact";
683
+ const defaultSafe = options?.safe ?? false;
676
684
  return {
677
- serialize: (object, serializerOptions) => JSON.stringify(object, serializerOptions ? JSONReplacer(serializerOptions) : defaultReplacer),
685
+ serialize: (object, serializerOptions) => {
686
+ const replacer = serializerOptions ? JSONReplacer(serializerOptions) : defaultReplacer;
687
+ const indent = (serializerOptions?.format ?? defaultFormat) === "pretty" ? 2 : void 0;
688
+ if (serializerOptions?.safe ?? defaultSafe) try {
689
+ return JSON.stringify(object, replacer, indent);
690
+ } catch (e) {
691
+ return `{"__serializationError":${JSON.stringify(String(e))}}`;
692
+ }
693
+ return JSON.stringify(object, replacer, indent);
694
+ },
678
695
  deserialize: (payload, deserializerOptions) => JSON.parse(payload, deserializerOptions ? JSONReviver(deserializerOptions) : defaultReviver)
679
696
  };
680
697
  };
@@ -978,6 +995,21 @@ const getInMemoryDatabase = () => {
978
995
  } };
979
996
  };
980
997
 
998
+ //#endregion
999
+ //#region src/processors/checkpoints.ts
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
+ });
1007
+ const bigIntProcessorCheckpoint = (value) => bigInt.toNormalizedString(value);
1008
+ const parseBigIntProcessorCheckpoint = (value) => BigInt(value);
1009
+ const getCheckpoint = (message) => {
1010
+ return message.metadata.checkpoint;
1011
+ };
1012
+
981
1013
  //#endregion
982
1014
  //#region src/observability/attributes.ts
983
1015
  const EmmettAttributes = {
@@ -1065,281 +1097,21 @@ const MessagingSystemName = "emmett";
1065
1097
 
1066
1098
  //#endregion
1067
1099
  //#region src/observability/options.ts
1068
- const resolveConsumerObservability = (options, parent) => ({
1069
- tracer: options?.observability?.tracer ?? parent?.observability?.tracer ?? (0, _event_driven_io_almanac.noopTracer)(),
1070
- meter: options?.observability?.meter ?? parent?.observability?.meter ?? (0, _event_driven_io_almanac.noopMeter)(),
1071
- pollTracing: options?.observability?.pollTracing ?? parent?.observability?.pollTracing ?? "off",
1072
- attributeTarget: options?.observability?.attributeTarget ?? parent?.observability?.attributeTarget ?? "both"
1073
- });
1074
- const resolveWorkflowObservability = (options, parent) => ({
1075
- tracer: options?.observability?.tracer ?? parent?.observability?.tracer ?? (0, _event_driven_io_almanac.noopTracer)(),
1076
- meter: options?.observability?.meter ?? parent?.observability?.meter ?? (0, _event_driven_io_almanac.noopMeter)(),
1077
- propagation: options?.observability?.propagation ?? parent?.observability?.propagation ?? "links",
1078
- attributeTarget: options?.observability?.attributeTarget ?? parent?.observability?.attributeTarget ?? "both",
1079
- includeMessagePayloads: options?.observability?.includeMessagePayloads ?? parent?.observability?.includeMessagePayloads ?? false
1080
- });
1081
-
1082
- //#endregion
1083
- //#region src/observability/tracer.ts
1084
- const tracer = () => {};
1085
- const LogLevel = {
1086
- DISABLED: "DISABLED",
1087
- INFO: "INFO",
1088
- LOG: "LOG",
1089
- WARN: "WARN",
1090
- ERROR: "ERROR"
1091
- };
1092
- const LogStyle = {
1093
- RAW: "RAW",
1094
- PRETTY: "PRETTY"
1095
- };
1096
- const getEnvVariable = (name) => {
1097
- try {
1098
- if (typeof process !== "undefined" && process.env) return process.env[name];
1099
- return;
1100
- } catch {
1101
- return;
1102
- }
1103
- };
1104
- const shouldLog = (logLevel) => {
1105
- const definedLogLevel = getEnvVariable("DUMBO_LOG_LEVEL") ?? LogLevel.ERROR;
1106
- if (definedLogLevel === LogLevel.ERROR && logLevel === LogLevel.ERROR) return true;
1107
- if (definedLogLevel === LogLevel.WARN && [LogLevel.ERROR, LogLevel.WARN].includes(logLevel)) return true;
1108
- if (definedLogLevel === LogLevel.LOG && [
1109
- LogLevel.ERROR,
1110
- LogLevel.WARN,
1111
- LogLevel.LOG
1112
- ].includes(logLevel)) return true;
1113
- if (definedLogLevel === LogLevel.INFO && [
1114
- LogLevel.ERROR,
1115
- LogLevel.WARN,
1116
- LogLevel.LOG,
1117
- LogLevel.INFO
1118
- ].includes(logLevel)) return true;
1119
- return false;
1120
- };
1121
- const nulloTraceEventRecorder = () => {};
1122
- const getTraceEventFormatter = (logStyle, serializer) => (event) => {
1123
- serializer = serializer ?? JSONSerializer.from();
1124
- switch (logStyle) {
1125
- case "RAW": return serializer.serialize(event);
1126
- case "PRETTY": return serializer.serialize(event);
1127
- }
1128
- };
1129
- const getTraceEventRecorder = (logLevel, logStyle) => {
1130
- const format = getTraceEventFormatter(logStyle);
1131
- switch (logLevel) {
1132
- case "DISABLED": return nulloTraceEventRecorder;
1133
- case "INFO": return (event) => console.info(format(event));
1134
- case "LOG": return (event) => console.log(format(event));
1135
- case "WARN": return (event) => console.warn(format(event));
1136
- case "ERROR": return (event) => console.error(format(event));
1137
- }
1138
- };
1139
- const recordTraceEvent = (logLevel, eventName, attributes) => {
1140
- if (!shouldLog(LogLevel.LOG)) return;
1141
- const event = {
1142
- name: eventName,
1143
- timestamp: (/* @__PURE__ */ new Date()).getTime(),
1144
- ...attributes
1145
- };
1146
- getTraceEventRecorder(logLevel, getEnvVariable("DUMBO_LOG_STYLE") ?? "RAW")(event);
1147
- };
1148
- tracer.info = (eventName, attributes) => recordTraceEvent(LogLevel.INFO, eventName, attributes);
1149
- tracer.warn = (eventName, attributes) => recordTraceEvent(LogLevel.WARN, eventName, attributes);
1150
- tracer.log = (eventName, attributes) => recordTraceEvent(LogLevel.LOG, eventName, attributes);
1151
- tracer.error = (eventName, attributes) => recordTraceEvent(LogLevel.ERROR, eventName, attributes);
1152
-
1153
- //#endregion
1154
- //#region src/eventStore/observability/eventStoreCollector.ts
1155
- const resolveEventStoreObservability = (options, parent) => ({
1156
- tracer: options?.observability?.tracer ?? parent?.observability?.tracer ?? (0, _event_driven_io_almanac.noopTracer)(),
1157
- meter: options?.observability?.meter ?? parent?.observability?.meter ?? (0, _event_driven_io_almanac.noopMeter)(),
1158
- attributeTarget: options?.observability?.attributeTarget ?? parent?.observability?.attributeTarget ?? "both"
1159
- });
1160
- const eventStoreCollector = (observability) => {
1161
- const A = EmmettAttributes;
1162
- const M = _event_driven_io_almanac.MessagingAttributes;
1163
- const streamReadingDuration = observability.meter.histogram(EmmettMetrics.stream.readingDuration);
1164
- const streamReadingSize = observability.meter.histogram(EmmettMetrics.stream.readingSize);
1165
- const eventReadingCount = observability.meter.counter(EmmettMetrics.event.readingCount);
1166
- const streamAppendingDuration = observability.meter.histogram(EmmettMetrics.stream.appendingDuration);
1167
- const streamAppendingSize = observability.meter.histogram(EmmettMetrics.stream.appendingSize);
1168
- const eventAppendingCount = observability.meter.counter(EmmettMetrics.event.appendingCount);
1169
- return {
1170
- instrumentRead: (streamName, fn) => {
1171
- const start = Date.now();
1172
- return observability.tracer.startSpan("eventStore.readStream", async (span) => {
1173
- span.setAttributes({
1174
- [A.eventStore.operation]: "readStream",
1175
- [A.stream.name]: streamName,
1176
- [M.operation.type]: "receive",
1177
- [M.destination.name]: streamName,
1178
- [M.system]: MessagingSystemName
1179
- });
1180
- let status = "success";
1181
- try {
1182
- const result = await fn();
1183
- const events = result.events;
1184
- span.setAttributes({
1185
- [A.eventStore.read.status]: status,
1186
- [A.eventStore.read.eventCount]: events.length,
1187
- [A.eventStore.read.eventTypes]: [...new Set(events.map((e) => e.type))]
1188
- });
1189
- streamReadingSize.record(events.length, { [A.eventStore.read.status]: status });
1190
- for (const event of events) eventReadingCount.add(1, { [A.event.type]: event.type });
1191
- return result;
1192
- } catch (err) {
1193
- status = "failure";
1194
- span.setAttributes({ [A.eventStore.read.status]: status });
1195
- throw err;
1196
- } finally {
1197
- streamReadingDuration.record(Date.now() - start, { [A.eventStore.read.status]: status });
1198
- }
1199
- });
1200
- },
1201
- instrumentAppend: (streamName, events, fn) => {
1202
- const start = Date.now();
1203
- return observability.tracer.startSpan("eventStore.appendToStream", async (span) => {
1204
- span.setAttributes({
1205
- [A.eventStore.operation]: "appendToStream",
1206
- [A.stream.name]: streamName,
1207
- [A.eventStore.append.batchSize]: events.length,
1208
- [M.operation.type]: "send",
1209
- [M.batch.messageCount]: events.length,
1210
- [M.destination.name]: streamName,
1211
- [M.system]: MessagingSystemName
1212
- });
1213
- let status = "success";
1214
- try {
1215
- const result = await fn();
1216
- span.setAttributes({
1217
- [A.eventStore.append.status]: status,
1218
- [A.stream.versionAfter]: Number(result.nextExpectedStreamVersion)
1219
- });
1220
- streamAppendingSize.record(events.length, { [A.eventStore.append.status]: status });
1221
- for (const event of events) eventAppendingCount.add(1, { [A.event.type]: event.type });
1222
- return result;
1223
- } catch (err) {
1224
- status = "failure";
1225
- span.setAttributes({ [A.eventStore.append.status]: status });
1226
- throw err;
1227
- } finally {
1228
- streamAppendingDuration.record(Date.now() - start, { [A.eventStore.append.status]: status });
1229
- }
1230
- });
1231
- }
1232
- };
1233
- };
1234
-
1235
- //#endregion
1236
- //#region src/observability/collectors/consumerCollector.ts
1237
- const consumerCollector = (observability) => {
1238
- const { startScope } = (0, _event_driven_io_almanac.ObservabilityScope)({
1239
- ...observability,
1240
- attributePrefix: "emmett"
1241
- });
1242
- const A = EmmettAttributes;
1243
- const M = _event_driven_io_almanac.MessagingAttributes;
1244
- const pollDuration = observability.meter.histogram(EmmettMetrics.consumer.pollDuration);
1245
- const deliveryDuration = observability.meter.histogram(EmmettMetrics.consumer.deliveryDuration);
1246
- return {
1247
- tracePoll: (context, fn) => {
1248
- if (observability.pollTracing === "off" || observability.pollTracing === "active" && context.batchSize === 0) return fn(_event_driven_io_almanac.noopScope);
1249
- return startScope("consumer.poll", async (scope) => {
1250
- scope.setAttributes({
1251
- [A.scope.type]: ScopeTypes.consumer,
1252
- [A.consumer.batchSize]: context.batchSize,
1253
- [A.consumer.processorCount]: context.processorCount,
1254
- [M.system]: MessagingSystemName,
1255
- [M.operation.type]: "receive",
1256
- ...context.empty ? { "emmett.consumer.poll.empty": true } : {},
1257
- ...context.waitMs != null ? { "emmett.consumer.poll.wait_ms": context.waitMs } : {}
1258
- });
1259
- return fn(scope);
1260
- });
1261
- },
1262
- recordPollMetrics: (durationMs, attrs) => {
1263
- pollDuration.record(durationMs, attrs);
1264
- },
1265
- traceDelivery: (scope, processorId, fn) => {
1266
- const start = Date.now();
1267
- return scope.scope(`consumer.deliver.${processorId}`, async (child) => {
1268
- try {
1269
- return await fn();
1270
- } catch (error) {
1271
- if (error instanceof Error) child.recordException(error);
1272
- throw error;
1273
- } finally {
1274
- deliveryDuration.record(Date.now() - start, { [A.consumer.delivery.processorId]: processorId });
1275
- }
1276
- }, { attributes: { [A.consumer.delivery.processorId]: processorId } });
1277
- }
1100
+ const mergeObservabilityOptions = (options, defaults) => {
1101
+ const observability = defaults === void 0 ? options.observability : options.observability === void 0 ? defaults : {
1102
+ ...defaults,
1103
+ ...options.observability
1278
1104
  };
1279
- };
1280
-
1281
- //#endregion
1282
- //#region src/observability/collectors/workflowCollector.ts
1283
- const workflowCollector = (observability) => {
1284
- const { startScope } = (0, _event_driven_io_almanac.ObservabilityScope)({
1285
- ...observability,
1286
- attributePrefix: "emmett"
1287
- });
1288
- const A = EmmettAttributes;
1289
- const M = _event_driven_io_almanac.MessagingAttributes;
1290
- const processingDuration = observability.meter.histogram(EmmettMetrics.workflow.processingDuration);
1105
+ if (observability === options.observability) return options;
1291
1106
  return {
1292
- startScope: (context, fn) => {
1293
- const start = Date.now();
1294
- return startScope("workflow.handle", async (scope) => {
1295
- scope.setAttributes({
1296
- [A.scope.type]: ScopeTypes.workflow,
1297
- [A.workflow.id]: context.workflowId,
1298
- [A.workflow.type]: context.workflowType,
1299
- [A.workflow.inputType]: context.inputType,
1300
- [M.system]: MessagingSystemName
1301
- });
1302
- let status = "success";
1303
- try {
1304
- return await fn(scope);
1305
- } catch (err) {
1306
- status = "failure";
1307
- throw err;
1308
- } finally {
1309
- processingDuration.record(Date.now() - start, {
1310
- [A.workflow.type]: context.workflowType,
1311
- status
1312
- });
1313
- }
1314
- }, { attributes: {
1315
- [A.scope.type]: ScopeTypes.workflow,
1316
- [A.workflow.type]: context.workflowType
1317
- } });
1318
- },
1319
- recordOutputs: (scope, outputs) => {
1320
- scope.setAttributes({
1321
- [A.workflow.outputs]: outputs.map((o) => o.type),
1322
- [A.workflow.outputsCount]: outputs.length
1323
- });
1324
- },
1325
- recordStateRebuild: (scope, eventCount) => {
1326
- scope.setAttributes({ [A.workflow.stateRebuildEventCount]: eventCount });
1327
- }
1107
+ ...options,
1108
+ observability
1328
1109
  };
1329
1110
  };
1330
1111
 
1331
- //#endregion
1332
- //#region src/processors/checkpoints.ts
1333
- const ProcessorCheckpoint = (checkpoint) => checkpoint;
1334
- const bigIntProcessorCheckpoint = (value) => bigInt.toNormalizedString(value);
1335
- const parseBigIntProcessorCheckpoint = (value) => BigInt(value);
1336
- const getCheckpoint = (message) => {
1337
- return message.metadata.checkpoint;
1338
- };
1339
-
1340
1112
  //#endregion
1341
1113
  //#region src/processors/observability/processorCollector.ts
1342
- const resolveProcessorObservability = (options, parent) => ({
1114
+ const processorObservability = (options, parent) => ({
1343
1115
  tracer: options?.observability?.tracer ?? parent?.observability?.tracer ?? (0, _event_driven_io_almanac.noopTracer)(),
1344
1116
  meter: options?.observability?.meter ?? parent?.observability?.meter ?? (0, _event_driven_io_almanac.noopMeter)(),
1345
1117
  propagation: options?.observability?.propagation ?? parent?.observability?.propagation ?? "links",
@@ -1421,6 +1193,20 @@ const processorCollector = (observability) => {
1421
1193
 
1422
1194
  //#endregion
1423
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
+ };
1424
1210
  const wasMessageHandled = (message, checkpoint) => {
1425
1211
  const messageCheckpoint = getCheckpoint(message);
1426
1212
  return messageCheckpoint !== null && messageCheckpoint !== void 0 && checkpoint !== null && checkpoint !== void 0 && messageCheckpoint <= checkpoint;
@@ -1447,9 +1233,11 @@ const defaultProcessorVersion = 1;
1447
1233
  const defaultProcessorPartition = defaultTag;
1448
1234
  const getProcessorInstanceId = (processorId) => `${processorId}:${(0, uuid.v7)()}`;
1449
1235
  const getProjectorId = (options) => `emt:processor:projector:${options.projectionName}`;
1236
+ const { info, error } = _event_driven_io_almanac.LogEvent;
1450
1237
  const reactor = (options) => {
1451
1238
  const { checkpoints, processorId, processorInstanceId: instanceId = getProcessorInstanceId(processorId), type = MessageProcessorType.REACTOR, version = 1, partition = defaultProcessorPartition, hooks = {}, processingScope = defaultProcessingMessageProcessingScope, startFrom, canHandle, stopAfter } = options;
1452
- const collector = processorCollector(resolveProcessorObservability(options));
1239
+ const checkpointer = checkpoints === "DISABLED" ? inMemoryCheckpointer() : checkpoints;
1240
+ const collector = processorCollector(processorObservability(options));
1453
1241
  const isCustomBatch = "eachBatch" in options && !!options.eachBatch;
1454
1242
  const eachBatch = isCustomBatch ? options.eachBatch : async (messages, context) => {
1455
1243
  const batchCtx = context.observabilityScope.spanContext();
@@ -1531,28 +1319,31 @@ const reactor = (options) => {
1531
1319
  ...partialOptions,
1532
1320
  observabilityScope: ("observabilityScope" in partialOptions ? partialOptions.observabilityScope ?? _event_driven_io_almanac.noopScope : _event_driven_io_almanac.noopScope) ?? _event_driven_io_almanac.noopScope
1533
1321
  };
1322
+ const log = startOptions.observabilityScope.log;
1534
1323
  if (isActive) {
1535
- console.log(`Processor ${processorId} with instance id ${instanceId} is already active. Start request ignored.`);
1324
+ log(info(`Processor ${processorId} with instance id ${instanceId} is already active. Start request ignored.`));
1536
1325
  return;
1537
1326
  }
1538
- console.log(`Starting processor ${processorId} with instance id ${instanceId}`);
1327
+ log(info(`Starting processor ${processorId} with instance id ${instanceId}`));
1539
1328
  await init(startOptions);
1540
1329
  isActive = true;
1541
1330
  closeSignal = onShutdown(() => close(startOptions));
1542
1331
  if (lastCheckpoint !== null) {
1543
- console.log(`Processor ${processorId} started with instance id ${instanceId}, checkpoint: ${JSONSerializer.serialize(lastCheckpoint)}`);
1332
+ log(info(`Processor ${processorId} started with instance id ${instanceId}, checkpoint: ${JSONSerializer.serialize(lastCheckpoint)}`));
1544
1333
  return { lastCheckpoint };
1545
1334
  }
1546
1335
  return await processingScope(async (context) => {
1336
+ const log = context.observabilityScope.log;
1547
1337
  if (hooks.onStart) {
1548
- console.log(`Executing onStart hook for processor ${processorId} with instance id ${instanceId}`);
1338
+ log(info(`Executing onStart hook for processor ${processorId} with instance id ${instanceId}`));
1549
1339
  await hooks.onStart(context);
1550
1340
  }
1551
- if (startFrom && startFrom !== "CURRENT") {
1552
- console.log(`Processor ${processorId} with instance id ${instanceId} starting from: ${JSONSerializer.serialize(startFrom)}`);
1341
+ if (startFrom !== void 0 && startFrom !== "CURRENT") {
1342
+ if (typeof startFrom !== "string") lastCheckpoint = startFrom.lastCheckpoint;
1343
+ log(info(`Processor ${processorId} with instance id ${instanceId} starting from: ${JSONSerializer.serialize(startFrom)}`));
1553
1344
  return startFrom;
1554
1345
  }
1555
- if (checkpoints) lastCheckpoint = (await checkpoints?.read({
1346
+ if (checkpointer) lastCheckpoint = (await checkpointer.read({
1556
1347
  processorId,
1557
1348
  partition
1558
1349
  }, {
@@ -1560,10 +1351,10 @@ const reactor = (options) => {
1560
1351
  ...context
1561
1352
  })).lastCheckpoint;
1562
1353
  if (lastCheckpoint === null) {
1563
- console.log(`Processor ${processorId} with instance id ${instanceId} starting from: BEGINNING`);
1354
+ log(info(`Processor ${processorId} with instance id ${instanceId} starting from: BEGINNING`));
1564
1355
  return "BEGINNING";
1565
1356
  }
1566
- console.log(`Checkpoint read for processor ${processorId} with instance id ${instanceId}: ${JSONSerializer.serialize(lastCheckpoint)}`);
1357
+ log(info(`Checkpoint read for processor ${processorId} with instance id ${instanceId}: ${JSONSerializer.serialize(lastCheckpoint)}`));
1567
1358
  return { lastCheckpoint };
1568
1359
  }, startOptions);
1569
1360
  },
@@ -1601,8 +1392,8 @@ const reactor = (options) => {
1601
1392
  } : batchResult;
1602
1393
  const isStop = messageProcessingResult && messageProcessingResult.type === "STOP";
1603
1394
  const checkpointMessage = messageProcessingResult?.type === "STOP" ? messageProcessingResult.lastSuccessfulMessage : messagesAboveCheckpoint[messagesAboveCheckpoint.length - 1];
1604
- if (checkpointMessage && checkpoints) {
1605
- const storeCheckpointResult = await checkpoints.store({
1395
+ if (checkpointMessage && checkpointer) {
1396
+ const storeCheckpointResult = await checkpointer.store({
1606
1397
  processorId,
1607
1398
  version,
1608
1399
  message: checkpointMessage,
@@ -1620,12 +1411,12 @@ const reactor = (options) => {
1620
1411
  ...partialContext,
1621
1412
  observabilityScope: scope
1622
1413
  });
1623
- } catch (error) {
1624
- console.log(`Error during message processing for processor ${processorId} with instance id ${instanceId}. Stopping the processor.`, error);
1414
+ } catch (err) {
1415
+ scope.log(error({ err }, `Error during message processing for processor ${processorId} with instance id ${instanceId}. Stopping the processor.`));
1625
1416
  isActive = false;
1626
1417
  return {
1627
1418
  type: "STOP",
1628
- error,
1419
+ error: err,
1629
1420
  reason: "Error during message processing"
1630
1421
  };
1631
1422
  }
@@ -1656,14 +1447,14 @@ const projector = (options) => {
1656
1447
  //#endregion
1657
1448
  //#region src/processors/inMemoryProcessors.ts
1658
1449
  const inMemoryCheckpointer = () => {
1450
+ let fallbackDatabase;
1451
+ const resolveDatabase = (context) => context?.database ?? (fallbackDatabase ??= getInMemoryDatabase());
1659
1452
  return {
1660
- read: async ({ processorId }, { database }) => {
1661
- const checkpoint = await database.collection("emt_processor_checkpoints").findOne((d) => d._id === processorId);
1662
- 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 };
1663
1455
  },
1664
- store: async (context, { database }) => {
1665
- const { message, processorId, lastCheckpoint } = context;
1666
- const checkpoints = database.collection("emt_processor_checkpoints");
1456
+ store: async ({ message, processorId, lastCheckpoint }, context) => {
1457
+ const checkpoints = resolveDatabase(context).collection("emt_processor_checkpoints");
1667
1458
  const currentPosition = (await checkpoints.findOne((d) => d._id === processorId))?.lastCheckpoint ?? null;
1668
1459
  const newCheckpoint = getCheckpoint(message);
1669
1460
  if (currentPosition && (currentPosition === newCheckpoint || currentPosition !== lastCheckpoint)) return {
@@ -1733,6 +1524,49 @@ const inMemoryReactor = (options) => {
1733
1524
  return Object.assign(processor, { database });
1734
1525
  };
1735
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
+
1736
1570
  //#endregion
1737
1571
  //#region src/eventStore/projections/inMemory/inMemoryProjection.ts
1738
1572
  const DATABASE_REQUIRED_ERROR_MESSAGE = "Database is required in context for InMemory projections";
@@ -2198,7 +2032,7 @@ const InMemoryProjectionSpec = { for: (options) => {
2198
2032
  return Promise.resolve(false);
2199
2033
  }
2200
2034
  },
2201
- observability: resolveEventStoreObservability(void 0)
2035
+ observability: eventStoreObservability(void 0)
2202
2036
  });
2203
2037
  };
2204
2038
  return {
@@ -2303,6 +2137,88 @@ const upcastRecordedMessages = (recordedMessages, options) => {
2303
2137
  return recordedMessages.map((recordedMessage) => upcastRecordedMessage(recordedMessage, options));
2304
2138
  };
2305
2139
 
2140
+ //#endregion
2141
+ //#region src/eventStore/observability/eventStoreCollector.ts
2142
+ const eventStoreObservability = (options, parent) => ({
2143
+ tracer: options?.observability?.tracer ?? parent?.observability?.tracer ?? (0, _event_driven_io_almanac.noopTracer)(),
2144
+ meter: options?.observability?.meter ?? parent?.observability?.meter ?? (0, _event_driven_io_almanac.noopMeter)(),
2145
+ attributeTarget: options?.observability?.attributeTarget ?? parent?.observability?.attributeTarget ?? "both"
2146
+ });
2147
+ const eventStoreCollector = (observability) => {
2148
+ const A = EmmettAttributes;
2149
+ const M = _event_driven_io_almanac.MessagingAttributes;
2150
+ const streamReadingDuration = observability.meter.histogram(EmmettMetrics.stream.readingDuration);
2151
+ const streamReadingSize = observability.meter.histogram(EmmettMetrics.stream.readingSize);
2152
+ const eventReadingCount = observability.meter.counter(EmmettMetrics.event.readingCount);
2153
+ const streamAppendingDuration = observability.meter.histogram(EmmettMetrics.stream.appendingDuration);
2154
+ const streamAppendingSize = observability.meter.histogram(EmmettMetrics.stream.appendingSize);
2155
+ const eventAppendingCount = observability.meter.counter(EmmettMetrics.event.appendingCount);
2156
+ return {
2157
+ instrumentRead: (streamName, fn) => {
2158
+ const start = Date.now();
2159
+ return observability.tracer.startSpan("eventStore.readStream", async (span) => {
2160
+ span.setAttributes({
2161
+ [A.eventStore.operation]: "readStream",
2162
+ [A.stream.name]: streamName,
2163
+ [M.operation.type]: "receive",
2164
+ [M.destination.name]: streamName,
2165
+ [M.system]: MessagingSystemName
2166
+ });
2167
+ let status = "success";
2168
+ try {
2169
+ const result = await fn();
2170
+ const events = result.events;
2171
+ span.setAttributes({
2172
+ [A.eventStore.read.status]: status,
2173
+ [A.eventStore.read.eventCount]: events.length,
2174
+ [A.eventStore.read.eventTypes]: [...new Set(events.map((e) => e.type))]
2175
+ });
2176
+ streamReadingSize.record(events.length, { [A.eventStore.read.status]: status });
2177
+ for (const event of events) eventReadingCount.add(1, { [A.event.type]: event.type });
2178
+ return result;
2179
+ } catch (err) {
2180
+ status = "failure";
2181
+ span.setAttributes({ [A.eventStore.read.status]: status });
2182
+ throw err;
2183
+ } finally {
2184
+ streamReadingDuration.record(Date.now() - start, { [A.eventStore.read.status]: status });
2185
+ }
2186
+ });
2187
+ },
2188
+ instrumentAppend: (streamName, events, fn) => {
2189
+ const start = Date.now();
2190
+ return observability.tracer.startSpan("eventStore.appendToStream", async (span) => {
2191
+ span.setAttributes({
2192
+ [A.eventStore.operation]: "appendToStream",
2193
+ [A.stream.name]: streamName,
2194
+ [A.eventStore.append.batchSize]: events.length,
2195
+ [M.operation.type]: "send",
2196
+ [M.batch.messageCount]: events.length,
2197
+ [M.destination.name]: streamName,
2198
+ [M.system]: MessagingSystemName
2199
+ });
2200
+ let status = "success";
2201
+ try {
2202
+ const result = await fn();
2203
+ span.setAttributes({
2204
+ [A.eventStore.append.status]: status,
2205
+ [A.stream.versionAfter]: Number(result.nextExpectedStreamVersion)
2206
+ });
2207
+ streamAppendingSize.record(events.length, { [A.eventStore.append.status]: status });
2208
+ for (const event of events) eventAppendingCount.add(1, { [A.event.type]: event.type });
2209
+ return result;
2210
+ } catch (err) {
2211
+ status = "failure";
2212
+ span.setAttributes({ [A.eventStore.append.status]: status });
2213
+ throw err;
2214
+ } finally {
2215
+ streamAppendingDuration.record(Date.now() - start, { [A.eventStore.append.status]: status });
2216
+ }
2217
+ });
2218
+ }
2219
+ };
2220
+ };
2221
+
2306
2222
  //#endregion
2307
2223
  //#region src/eventStore/inMemoryEventStore.ts
2308
2224
  const InMemoryEventStoreDefaultStreamVersion = 0n;
@@ -2313,7 +2229,7 @@ const getInMemoryEventStore = (eventStoreOptions) => {
2313
2229
  };
2314
2230
  const database = eventStoreOptions?.database || getInMemoryDatabase();
2315
2231
  const inlineProjections = (eventStoreOptions?.projections ?? []).filter(({ type }) => type === "inline").map(({ projection }) => projection);
2316
- const observability = resolveEventStoreObservability(eventStoreOptions);
2232
+ const observability = eventStoreObservability(eventStoreOptions);
2317
2233
  const collector = eventStoreCollector(observability);
2318
2234
  const eventStore = {
2319
2235
  database,
@@ -2395,7 +2311,7 @@ const getInMemoryEventStore = (eventStoreOptions) => {
2395
2311
 
2396
2312
  //#endregion
2397
2313
  //#region src/commandHandling/observability/commandHandlerCollector.ts
2398
- const resolveCommandObservability = (options, parent) => ({
2314
+ const commandObservability = (options, parent) => ({
2399
2315
  tracer: options?.observability?.tracer ?? parent?.observability?.tracer ?? (0, _event_driven_io_almanac.noopTracer)(),
2400
2316
  meter: options?.observability?.meter ?? parent?.observability?.meter ?? (0, _event_driven_io_almanac.noopMeter)(),
2401
2317
  attributeTarget: options?.observability?.attributeTarget ?? parent?.observability?.attributeTarget ?? "both",
@@ -2439,7 +2355,7 @@ const commandHandlerCollector = (observability) => {
2439
2355
  "exception.message": err instanceof Error ? err.message : String(err),
2440
2356
  "exception.type": err instanceof Error ? err.constructor.name : "unknown"
2441
2357
  });
2442
- scope.recordException(err instanceof Error ? err : new Error(String(err)));
2358
+ scope.log(_event_driven_io_almanac.LogEvent.error(err instanceof Error ? err : new Error(String(err))));
2443
2359
  throw err;
2444
2360
  } finally {
2445
2361
  commandHandlingDuration.record(Date.now() - start, {
@@ -2488,7 +2404,7 @@ const CommandHandlerStreamVersionConflictRetryOptions = {
2488
2404
  shouldRetryError: isExpectedVersionConflictError
2489
2405
  };
2490
2406
  const CommandHandler = (options) => async (store, id, handle, handleOptions) => {
2491
- const collector = commandHandlerCollector(resolveCommandObservability(options));
2407
+ const collector = commandHandlerCollector(commandObservability(options));
2492
2408
  const streamName = (options.mapToStreamId ?? ((id) => id))(id);
2493
2409
  const commandType = handleOptions?.commandType ?? options.commandType ?? options.name ?? handlerNames(handle);
2494
2410
  const correlationId = handleOptions?.observability?.correlationId ?? (0, uuid.v7)();
@@ -2587,6 +2503,61 @@ const DeciderCommandHandler = (options) => async (eventStore, id, commands, hand
2587
2503
  });
2588
2504
  };
2589
2505
 
2506
+ //#endregion
2507
+ //#region src/consumers/observability/consumerCollector.ts
2508
+ const consumerObservability = (options, parent) => {
2509
+ const observability = mergeObservabilityOptions({ observability: options?.observability }, parent?.observability).observability;
2510
+ return {
2511
+ tracer: observability?.tracer ?? (0, _event_driven_io_almanac.noopTracer)(),
2512
+ meter: observability?.meter ?? (0, _event_driven_io_almanac.noopMeter)(),
2513
+ pollTracing: observability?.pollTracing ?? "off",
2514
+ attributeTarget: observability?.attributeTarget ?? "both"
2515
+ };
2516
+ };
2517
+ const consumerCollector = (observability) => {
2518
+ const { startScope } = (0, _event_driven_io_almanac.ObservabilityScope)({
2519
+ ...observability,
2520
+ attributePrefix: "emmett"
2521
+ });
2522
+ const A = EmmettAttributes;
2523
+ const M = _event_driven_io_almanac.MessagingAttributes;
2524
+ const pollDuration = observability.meter.histogram(EmmettMetrics.consumer.pollDuration);
2525
+ const deliveryDuration = observability.meter.histogram(EmmettMetrics.consumer.deliveryDuration);
2526
+ return {
2527
+ tracePoll: (context, fn) => {
2528
+ if (observability.pollTracing === "off" || observability.pollTracing === "active" && context.batchSize === 0) return fn(_event_driven_io_almanac.noopScope);
2529
+ return startScope("consumer.poll", async (scope) => {
2530
+ scope.setAttributes({
2531
+ [A.scope.type]: ScopeTypes.consumer,
2532
+ [A.consumer.batchSize]: context.batchSize,
2533
+ [A.consumer.processorCount]: context.processorCount,
2534
+ [M.system]: MessagingSystemName,
2535
+ [M.operation.type]: "receive",
2536
+ ...context.empty ? { "emmett.consumer.poll.empty": true } : {},
2537
+ ...context.waitMs != null ? { "emmett.consumer.poll.wait_ms": context.waitMs } : {}
2538
+ });
2539
+ return fn(scope);
2540
+ });
2541
+ },
2542
+ recordPollMetrics: (durationMs, attrs) => {
2543
+ pollDuration.record(durationMs, attrs);
2544
+ },
2545
+ traceDelivery: (scope, processorId, fn) => {
2546
+ const start = Date.now();
2547
+ return scope.scope(`consumer.deliver.${processorId}`, async (child) => {
2548
+ try {
2549
+ return await fn();
2550
+ } catch (error) {
2551
+ if (error instanceof Error) child.log(_event_driven_io_almanac.LogEvent.error(error));
2552
+ throw error;
2553
+ } finally {
2554
+ deliveryDuration.record(Date.now() - start, { [A.consumer.delivery.processorId]: processorId });
2555
+ }
2556
+ }, { attributes: { [A.consumer.delivery.processorId]: processorId } });
2557
+ }
2558
+ };
2559
+ };
2560
+
2590
2561
  //#endregion
2591
2562
  //#region src/messageBus/index.ts
2592
2563
  const getInMemoryMessageBus = () => {
@@ -2653,6 +2624,66 @@ const projections = {
2653
2624
  async: asyncProjections
2654
2625
  };
2655
2626
 
2627
+ //#endregion
2628
+ //#region src/workflows/observability/workflowCollector.ts
2629
+ const workflowObservability = (options, parent) => {
2630
+ const observability = mergeObservabilityOptions({ observability: options?.observability }, parent?.observability).observability;
2631
+ return {
2632
+ tracer: observability?.tracer ?? (0, _event_driven_io_almanac.noopTracer)(),
2633
+ meter: observability?.meter ?? (0, _event_driven_io_almanac.noopMeter)(),
2634
+ propagation: observability?.propagation ?? "links",
2635
+ attributeTarget: observability?.attributeTarget ?? "both",
2636
+ includeMessagePayloads: observability?.includeMessagePayloads ?? false
2637
+ };
2638
+ };
2639
+ const workflowCollector = (observability) => {
2640
+ const { startScope } = (0, _event_driven_io_almanac.ObservabilityScope)({
2641
+ ...observability,
2642
+ attributePrefix: "emmett"
2643
+ });
2644
+ const A = EmmettAttributes;
2645
+ const M = _event_driven_io_almanac.MessagingAttributes;
2646
+ const processingDuration = observability.meter.histogram(EmmettMetrics.workflow.processingDuration);
2647
+ return {
2648
+ startScope: (context, fn) => {
2649
+ const start = Date.now();
2650
+ return startScope("workflow.handle", async (scope) => {
2651
+ scope.setAttributes({
2652
+ [A.scope.type]: ScopeTypes.workflow,
2653
+ [A.workflow.id]: context.workflowId,
2654
+ [A.workflow.type]: context.workflowType,
2655
+ [A.workflow.inputType]: context.inputType,
2656
+ [M.system]: MessagingSystemName
2657
+ });
2658
+ let status = "success";
2659
+ try {
2660
+ return await fn(scope);
2661
+ } catch (err) {
2662
+ status = "failure";
2663
+ throw err;
2664
+ } finally {
2665
+ processingDuration.record(Date.now() - start, {
2666
+ [A.workflow.type]: context.workflowType,
2667
+ status
2668
+ });
2669
+ }
2670
+ }, { attributes: {
2671
+ [A.scope.type]: ScopeTypes.workflow,
2672
+ [A.workflow.type]: context.workflowType
2673
+ } });
2674
+ },
2675
+ recordOutputs: (scope, outputs) => {
2676
+ scope.setAttributes({
2677
+ [A.workflow.outputs]: outputs.map((o) => o.type),
2678
+ [A.workflow.outputsCount]: outputs.length
2679
+ });
2680
+ },
2681
+ recordStateRebuild: (scope, eventCount) => {
2682
+ scope.setAttributes({ [A.workflow.stateRebuildEventCount]: eventCount });
2683
+ }
2684
+ };
2685
+ };
2686
+
2656
2687
  //#endregion
2657
2688
  //#region src/workflows/handleWorkflow.ts
2658
2689
  const WorkflowHandlerStreamVersionConflictRetryOptions = {
@@ -2722,7 +2753,7 @@ const createWrappedEvolve = (evolve, workflowName, separateInputInboxFromProcess
2722
2753
  };
2723
2754
  const workflowStreamName = ({ workflowName, workflowId }) => `emt:workflow:${workflowName}:${workflowId}`;
2724
2755
  const WorkflowHandler = (options) => async (store, message, handleOptions) => {
2725
- const collector = workflowCollector(resolveWorkflowObservability(options));
2756
+ const collector = workflowCollector(workflowObservability(options));
2726
2757
  const workflowType = options.workflow.name;
2727
2758
  const inputType = message.type;
2728
2759
  const workflowId = options.getWorkflowId(message) ?? "";
@@ -2890,6 +2921,8 @@ var src_exports = /* @__PURE__ */ require_plugins.__exportAll({
2890
2921
  CommandHandlerStreamVersionConflictRetryOptions: () => CommandHandlerStreamVersionConflictRetryOptions,
2891
2922
  ConcurrencyError: () => require_plugins.ConcurrencyError,
2892
2923
  ConcurrencyInMemoryDatabaseError: () => require_plugins.ConcurrencyInMemoryDatabaseError,
2924
+ ConsumerStartPositions: () => ConsumerStartPositions,
2925
+ CurrentMessageProcessorPosition: () => CurrentMessageProcessorPosition,
2893
2926
  DATABASE_REQUIRED_ERROR_MESSAGE: () => DATABASE_REQUIRED_ERROR_MESSAGE,
2894
2927
  DeciderCommandHandler: () => DeciderCommandHandler,
2895
2928
  DeciderSpecification: () => DeciderSpecification,
@@ -2908,8 +2941,6 @@ var src_exports = /* @__PURE__ */ require_plugins.__exportAll({
2908
2941
  JSONReviver: () => JSONReviver,
2909
2942
  JSONRevivers: () => JSONRevivers,
2910
2943
  JSONSerializer: () => JSONSerializer,
2911
- LogLevel: () => LogLevel,
2912
- LogStyle: () => LogStyle,
2913
2944
  MessageProcessor: () => MessageProcessor,
2914
2945
  MessageProcessorType: () => MessageProcessorType,
2915
2946
  MessagingSystemName: () => MessagingSystemName,
@@ -2917,6 +2948,7 @@ var src_exports = /* @__PURE__ */ require_plugins.__exportAll({
2917
2948
  NoRetries: () => NoRetries,
2918
2949
  NotFoundError: () => require_plugins.NotFoundError,
2919
2950
  ProcessorCheckpoint: () => ProcessorCheckpoint,
2951
+ ProcessorStartPositions: () => ProcessorStartPositions,
2920
2952
  STREAM_DOES_NOT_EXIST: () => STREAM_DOES_NOT_EXIST,
2921
2953
  STREAM_EXISTS: () => STREAM_EXISTS,
2922
2954
  ScopeTypes: () => ScopeTypes,
@@ -2965,6 +2997,7 @@ var src_exports = /* @__PURE__ */ require_plugins.__exportAll({
2965
2997
  composeJSONReplacers: () => composeJSONReplacers,
2966
2998
  composeJSONRevivers: () => composeJSONRevivers,
2967
2999
  consumerCollector: () => consumerCollector,
3000
+ consumerObservability: () => consumerObservability,
2968
3001
  deepEquals: () => deepEquals,
2969
3002
  defaultProcessingMessageProcessingScope: () => defaultProcessingMessageProcessingScope,
2970
3003
  defaultProcessorPartition: () => defaultProcessorPartition,
@@ -2975,9 +3008,11 @@ var src_exports = /* @__PURE__ */ require_plugins.__exportAll({
2975
3008
  downcastRecordedMessage: () => downcastRecordedMessage,
2976
3009
  downcastRecordedMessages: () => downcastRecordedMessages,
2977
3010
  emmettPrefix: () => "emt",
3011
+ errorReplacer: () => errorReplacer,
2978
3012
  event: () => event,
2979
3013
  eventInStream: () => eventInStream,
2980
3014
  eventStoreCollector: () => eventStoreCollector,
3015
+ eventStoreObservability: () => eventStoreObservability,
2981
3016
  eventsInStream: () => eventsInStream,
2982
3017
  expectInMemoryDocuments: () => expectInMemoryDocuments,
2983
3018
  filterProjections: () => filterProjections,
@@ -3019,6 +3054,7 @@ var src_exports = /* @__PURE__ */ require_plugins.__exportAll({
3019
3054
  jsonSerializer: () => jsonSerializer,
3020
3055
  matchesExpectedVersion: () => matchesExpectedVersion,
3021
3056
  merge: () => merge,
3057
+ mergeObservabilityOptions: () => mergeObservabilityOptions,
3022
3058
  message: () => message,
3023
3059
  newEventsInStream: () => newEventsInStream,
3024
3060
  nulloSessionFactory: () => nulloSessionFactory,
@@ -3026,18 +3062,14 @@ var src_exports = /* @__PURE__ */ require_plugins.__exportAll({
3026
3062
  parseBigIntProcessorCheckpoint: () => parseBigIntProcessorCheckpoint,
3027
3063
  parseDateFromUtcYYYYMMDD: () => require_plugins.parseDateFromUtcYYYYMMDD,
3028
3064
  processorCollector: () => processorCollector,
3065
+ processorObservability: () => processorObservability,
3029
3066
  projection: () => projection,
3030
3067
  projections: () => projections,
3031
3068
  projector: () => projector,
3032
3069
  reactor: () => reactor,
3033
3070
  reduceAsync: () => reduceAsync,
3034
- resolveConsumerObservability: () => resolveConsumerObservability,
3035
- resolveEventStoreObservability: () => resolveEventStoreObservability,
3036
- resolveProcessorObservability: () => resolveProcessorObservability,
3037
- resolveWorkflowObservability: () => resolveWorkflowObservability,
3038
3071
  sum: () => sum,
3039
3072
  toNormalizedString: () => toNormalizedString,
3040
- tracer: () => tracer,
3041
3073
  tryPublishMessagesAfterCommit: () => tryPublishMessagesAfterCommit,
3042
3074
  unknownTag: () => unknownTag,
3043
3075
  upcastRecordedMessage: () => upcastRecordedMessage,
@@ -3045,6 +3077,7 @@ var src_exports = /* @__PURE__ */ require_plugins.__exportAll({
3045
3077
  verifyThat: () => verifyThat,
3046
3078
  wasMessageHandled: () => wasMessageHandled,
3047
3079
  workflowCollector: () => workflowCollector,
3080
+ workflowObservability: () => workflowObservability,
3048
3081
  workflowOutputHandler: () => workflowOutputHandler,
3049
3082
  workflowProcessor: () => workflowProcessor,
3050
3083
  workflowStreamName: () => workflowStreamName
@@ -3056,6 +3089,8 @@ exports.CommandHandler = CommandHandler;
3056
3089
  exports.CommandHandlerStreamVersionConflictRetryOptions = CommandHandlerStreamVersionConflictRetryOptions;
3057
3090
  exports.ConcurrencyError = require_plugins.ConcurrencyError;
3058
3091
  exports.ConcurrencyInMemoryDatabaseError = require_plugins.ConcurrencyInMemoryDatabaseError;
3092
+ exports.ConsumerStartPositions = ConsumerStartPositions;
3093
+ exports.CurrentMessageProcessorPosition = CurrentMessageProcessorPosition;
3059
3094
  exports.DATABASE_REQUIRED_ERROR_MESSAGE = DATABASE_REQUIRED_ERROR_MESSAGE;
3060
3095
  exports.DeciderCommandHandler = DeciderCommandHandler;
3061
3096
  exports.DeciderSpecification = DeciderSpecification;
@@ -3074,8 +3109,6 @@ exports.JSONReplacers = JSONReplacers;
3074
3109
  exports.JSONReviver = JSONReviver;
3075
3110
  exports.JSONRevivers = JSONRevivers;
3076
3111
  exports.JSONSerializer = JSONSerializer;
3077
- exports.LogLevel = LogLevel;
3078
- exports.LogStyle = LogStyle;
3079
3112
  exports.MessageProcessor = MessageProcessor;
3080
3113
  exports.MessageProcessorType = MessageProcessorType;
3081
3114
  exports.MessagingSystemName = MessagingSystemName;
@@ -3083,6 +3116,7 @@ exports.NO_CONCURRENCY_CHECK = NO_CONCURRENCY_CHECK;
3083
3116
  exports.NoRetries = NoRetries;
3084
3117
  exports.NotFoundError = require_plugins.NotFoundError;
3085
3118
  exports.ProcessorCheckpoint = ProcessorCheckpoint;
3119
+ exports.ProcessorStartPositions = ProcessorStartPositions;
3086
3120
  exports.STREAM_DOES_NOT_EXIST = STREAM_DOES_NOT_EXIST;
3087
3121
  exports.STREAM_EXISTS = STREAM_EXISTS;
3088
3122
  exports.ScopeTypes = ScopeTypes;
@@ -3131,6 +3165,7 @@ exports.command = command;
3131
3165
  exports.composeJSONReplacers = composeJSONReplacers;
3132
3166
  exports.composeJSONRevivers = composeJSONRevivers;
3133
3167
  exports.consumerCollector = consumerCollector;
3168
+ exports.consumerObservability = consumerObservability;
3134
3169
  exports.deepEquals = deepEquals;
3135
3170
  exports.defaultProcessingMessageProcessingScope = defaultProcessingMessageProcessingScope;
3136
3171
  exports.defaultProcessorPartition = defaultProcessorPartition;
@@ -3141,9 +3176,11 @@ exports.documentExists = documentExists;
3141
3176
  exports.downcastRecordedMessage = downcastRecordedMessage;
3142
3177
  exports.downcastRecordedMessages = downcastRecordedMessages;
3143
3178
  exports.emmettPrefix = emmettPrefix;
3179
+ exports.errorReplacer = errorReplacer;
3144
3180
  exports.event = event;
3145
3181
  exports.eventInStream = eventInStream;
3146
3182
  exports.eventStoreCollector = eventStoreCollector;
3183
+ exports.eventStoreObservability = eventStoreObservability;
3147
3184
  exports.eventsInStream = eventsInStream;
3148
3185
  exports.expectInMemoryDocuments = expectInMemoryDocuments;
3149
3186
  exports.filterProjections = filterProjections;
@@ -3185,6 +3222,7 @@ exports.isValidYYYYMMDD = require_plugins.isValidYYYYMMDD;
3185
3222
  exports.jsonSerializer = jsonSerializer;
3186
3223
  exports.matchesExpectedVersion = matchesExpectedVersion;
3187
3224
  exports.merge = merge;
3225
+ exports.mergeObservabilityOptions = mergeObservabilityOptions;
3188
3226
  exports.message = message;
3189
3227
  exports.newEventsInStream = newEventsInStream;
3190
3228
  exports.nulloSessionFactory = nulloSessionFactory;
@@ -3192,18 +3230,14 @@ exports.onShutdown = onShutdown;
3192
3230
  exports.parseBigIntProcessorCheckpoint = parseBigIntProcessorCheckpoint;
3193
3231
  exports.parseDateFromUtcYYYYMMDD = require_plugins.parseDateFromUtcYYYYMMDD;
3194
3232
  exports.processorCollector = processorCollector;
3233
+ exports.processorObservability = processorObservability;
3195
3234
  exports.projection = projection;
3196
3235
  exports.projections = projections;
3197
3236
  exports.projector = projector;
3198
3237
  exports.reactor = reactor;
3199
3238
  exports.reduceAsync = reduceAsync;
3200
- exports.resolveConsumerObservability = resolveConsumerObservability;
3201
- exports.resolveEventStoreObservability = resolveEventStoreObservability;
3202
- exports.resolveProcessorObservability = resolveProcessorObservability;
3203
- exports.resolveWorkflowObservability = resolveWorkflowObservability;
3204
3239
  exports.sum = sum;
3205
3240
  exports.toNormalizedString = toNormalizedString;
3206
- exports.tracer = tracer;
3207
3241
  exports.tryPublishMessagesAfterCommit = tryPublishMessagesAfterCommit;
3208
3242
  exports.unknownTag = unknownTag;
3209
3243
  exports.upcastRecordedMessage = upcastRecordedMessage;
@@ -3211,6 +3245,7 @@ exports.upcastRecordedMessages = upcastRecordedMessages;
3211
3245
  exports.verifyThat = verifyThat;
3212
3246
  exports.wasMessageHandled = wasMessageHandled;
3213
3247
  exports.workflowCollector = workflowCollector;
3248
+ exports.workflowObservability = workflowObservability;
3214
3249
  exports.workflowOutputHandler = workflowOutputHandler;
3215
3250
  exports.workflowProcessor = workflowProcessor;
3216
3251
  exports.workflowStreamName = workflowStreamName;