@event-driven-io/emmett-esdb 0.43.0-beta.12 → 0.43.0-beta.13

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
@@ -719,7 +719,40 @@ var reactor = (options) => {
719
719
  canHandle,
720
720
  stopAfter
721
721
  } = options;
722
- const eachMessage = "eachMessage" in options && options.eachMessage ? options.eachMessage : () => Promise.resolve();
722
+ const isCustomBatch = "eachBatch" in options && !!options.eachBatch;
723
+ const eachBatch = isCustomBatch ? options.eachBatch : async (messages, context) => {
724
+ let result = void 0;
725
+ for (let i = 0; i < messages.length; i++) {
726
+ const message2 = messages[i];
727
+ const messageProcessingResult = await options.eachMessage(
728
+ message2,
729
+ context
730
+ );
731
+ if (messageProcessingResult && messageProcessingResult.type === "STOP") {
732
+ result = {
733
+ ...messageProcessingResult,
734
+ lastSuccessfulMessage: messageProcessingResult.error ? messages[i - 1] : message2
735
+ };
736
+ break;
737
+ }
738
+ if (stopAfter && stopAfter(message2)) {
739
+ result = {
740
+ type: "STOP",
741
+ reason: "Stop condition reached",
742
+ lastSuccessfulMessage: message2
743
+ };
744
+ break;
745
+ }
746
+ if (messageProcessingResult && messageProcessingResult.type === "SKIP") {
747
+ result = {
748
+ ...messageProcessingResult,
749
+ lastSuccessfulMessage: message2
750
+ };
751
+ continue;
752
+ }
753
+ }
754
+ return result;
755
+ };
723
756
  let isInitiated = false;
724
757
  let isActive = false;
725
758
  let lastCheckpoint = null;
@@ -757,10 +790,11 @@ var reactor = (options) => {
757
790
  await init(startOptions);
758
791
  isActive = true;
759
792
  closeSignal = onShutdown(() => close(startOptions));
760
- if (lastCheckpoint !== null)
793
+ if (lastCheckpoint !== null) {
761
794
  return {
762
795
  lastCheckpoint
763
796
  };
797
+ }
764
798
  return await processingScope(async (context) => {
765
799
  if (hooks.onStart) {
766
800
  await hooks.onStart(context);
@@ -789,46 +823,48 @@ var reactor = (options) => {
789
823
  handle: async (messages, partialContext) => {
790
824
  if (!isActive) return Promise.resolve();
791
825
  return await processingScope(async (context) => {
792
- let result = void 0;
793
- for (const message2 of messages) {
794
- if (wasMessageHandled(message2, lastCheckpoint)) continue;
795
- const upcasted = upcastRecordedMessage(
826
+ const messagesAboveCheckpoint = messages.filter(
827
+ (message2) => !wasMessageHandled(message2, lastCheckpoint)
828
+ );
829
+ const upcastedMessages = messagesAboveCheckpoint.map(
830
+ (message2) => upcastRecordedMessage(
796
831
  // TODO: Make it smarter
797
832
  message2,
798
833
  _optionalChain([options, 'access', _32 => _32.messageOptions, 'optionalAccess', _33 => _33.schema, 'optionalAccess', _34 => _34.versioning])
834
+ )
835
+ ).filter(
836
+ (upcasted) => !canHandle || canHandle.includes(upcasted.type)
837
+ );
838
+ const stopMessageIndex = isCustomBatch && stopAfter ? upcastedMessages.findIndex(stopAfter) : -1;
839
+ const unhandledMessages = stopMessageIndex !== -1 ? upcastedMessages.slice(0, stopMessageIndex + 1) : upcastedMessages;
840
+ const batchResult = await eachBatch(unhandledMessages, context);
841
+ const messageProcessingResult = _optionalChain([batchResult, 'optionalAccess', _35 => _35.type]) === "STOP" ? batchResult : stopMessageIndex !== -1 ? {
842
+ type: "STOP",
843
+ reason: "Stop condition reached",
844
+ lastSuccessfulMessage: unhandledMessages[stopMessageIndex]
845
+ } : batchResult;
846
+ const isStop = messageProcessingResult && messageProcessingResult.type === "STOP";
847
+ const checkpointMessage = _optionalChain([messageProcessingResult, 'optionalAccess', _36 => _36.type]) === "STOP" ? messageProcessingResult.lastSuccessfulMessage : messagesAboveCheckpoint[messagesAboveCheckpoint.length - 1];
848
+ if (checkpointMessage && checkpoints) {
849
+ const storeCheckpointResult = await checkpoints.store(
850
+ {
851
+ processorId,
852
+ version,
853
+ message: checkpointMessage,
854
+ lastCheckpoint,
855
+ partition
856
+ },
857
+ context
799
858
  );
800
- if (canHandle !== void 0 && !canHandle.includes(upcasted.type))
801
- continue;
802
- const messageProcessingResult = await eachMessage(upcasted, context);
803
- if (checkpoints) {
804
- const storeCheckpointResult = await checkpoints.store(
805
- {
806
- processorId,
807
- version,
808
- message: upcasted,
809
- lastCheckpoint,
810
- partition
811
- },
812
- context
813
- );
814
- if (storeCheckpointResult.success) {
815
- lastCheckpoint = storeCheckpointResult.newCheckpoint;
816
- }
817
- }
818
- if (messageProcessingResult && messageProcessingResult.type === "STOP") {
819
- isActive = false;
820
- result = messageProcessingResult;
821
- break;
859
+ if (storeCheckpointResult.success) {
860
+ lastCheckpoint = storeCheckpointResult.newCheckpoint;
822
861
  }
823
- if (stopAfter && stopAfter(upcasted)) {
824
- isActive = false;
825
- result = { type: "STOP", reason: "Stop condition reached" };
826
- break;
827
- }
828
- if (messageProcessingResult && messageProcessingResult.type === "SKIP")
829
- continue;
830
862
  }
831
- return result;
863
+ if (isStop) {
864
+ isActive = false;
865
+ return messageProcessingResult;
866
+ }
867
+ return void 0;
832
868
  }, partialContext);
833
869
  }
834
870
  };
@@ -848,15 +884,15 @@ var projector = (options) => {
848
884
  processorId,
849
885
  messageOptions: options.projection.eventsOptions,
850
886
  hooks: {
851
- onInit: _optionalChain([options, 'access', _35 => _35.hooks, 'optionalAccess', _36 => _36.onInit]),
852
- onStart: options.truncateOnStart && options.projection.truncate || _optionalChain([options, 'access', _37 => _37.hooks, 'optionalAccess', _38 => _38.onStart]) ? async (context) => {
887
+ onInit: _optionalChain([options, 'access', _37 => _37.hooks, 'optionalAccess', _38 => _38.onInit]),
888
+ onStart: options.truncateOnStart && options.projection.truncate || _optionalChain([options, 'access', _39 => _39.hooks, 'optionalAccess', _40 => _40.onStart]) ? async (context) => {
853
889
  if (options.truncateOnStart && options.projection.truncate)
854
890
  await options.projection.truncate(context);
855
- if (_optionalChain([options, 'access', _39 => _39.hooks, 'optionalAccess', _40 => _40.onStart])) await _optionalChain([options, 'access', _41 => _41.hooks, 'optionalAccess', _42 => _42.onStart, 'call', _43 => _43(context)]);
891
+ if (_optionalChain([options, 'access', _41 => _41.hooks, 'optionalAccess', _42 => _42.onStart])) await _optionalChain([options, 'access', _43 => _43.hooks, 'optionalAccess', _44 => _44.onStart, 'call', _45 => _45(context)]);
856
892
  } : void 0,
857
- onClose: _optionalChain([options, 'access', _44 => _44.hooks, 'optionalAccess', _45 => _45.onClose])
893
+ onClose: _optionalChain([options, 'access', _46 => _46.hooks, 'optionalAccess', _47 => _47.onClose])
858
894
  },
859
- eachMessage: async (event2, context) => projection2.handle([event2], context)
895
+ eachBatch: async (events, context) => projection2.handle(events, context)
860
896
  });
861
897
  };
862
898
  var inMemoryCheckpointer = () => {
@@ -864,7 +900,7 @@ var inMemoryCheckpointer = () => {
864
900
  read: async ({ processorId }, { database }) => {
865
901
  const checkpoint = await database.collection("emt_processor_checkpoints").findOne((d) => d._id === processorId);
866
902
  return Promise.resolve({
867
- lastCheckpoint: _nullishCoalesce(_optionalChain([checkpoint, 'optionalAccess', _46 => _46.lastCheckpoint]), () => ( null))
903
+ lastCheckpoint: _nullishCoalesce(_optionalChain([checkpoint, 'optionalAccess', _48 => _48.lastCheckpoint]), () => ( null))
868
904
  });
869
905
  },
870
906
  store: async (context, { database }) => {
@@ -875,7 +911,7 @@ var inMemoryCheckpointer = () => {
875
911
  const checkpoint = await checkpoints.findOne(
876
912
  (d) => d._id === processorId
877
913
  );
878
- const currentPosition = _nullishCoalesce(_optionalChain([checkpoint, 'optionalAccess', _47 => _47.lastCheckpoint]), () => ( null));
914
+ const currentPosition = _nullishCoalesce(_optionalChain([checkpoint, 'optionalAccess', _49 => _49.lastCheckpoint]), () => ( null));
879
915
  const newCheckpoint = getCheckpoint(message2);
880
916
  if (currentPosition && (currentPosition === newCheckpoint || currentPosition !== lastCheckpoint)) {
881
917
  return {
@@ -895,7 +931,7 @@ var inMemoryCheckpointer = () => {
895
931
  var inMemoryProcessingScope = (options) => {
896
932
  const processorDatabase = options.database;
897
933
  const processingScope = (handler, partialContext) => {
898
- const database = _nullishCoalesce(processorDatabase, () => ( _optionalChain([partialContext, 'optionalAccess', _48 => _48.database])));
934
+ const database = _nullishCoalesce(processorDatabase, () => ( _optionalChain([partialContext, 'optionalAccess', _50 => _50.database])));
899
935
  if (!database)
900
936
  throw new EmmettError(
901
937
  `InMemory processor '${options.processorId}' is missing database. Ensure that you passed it through options`
@@ -905,12 +941,12 @@ var inMemoryProcessingScope = (options) => {
905
941
  return processingScope;
906
942
  };
907
943
  var inMemoryProjector = (options) => {
908
- const database = _nullishCoalesce(_optionalChain([options, 'access', _49 => _49.connectionOptions, 'optionalAccess', _50 => _50.database]), () => ( getInMemoryDatabase()));
944
+ const database = _nullishCoalesce(_optionalChain([options, 'access', _51 => _51.connectionOptions, 'optionalAccess', _52 => _52.database]), () => ( getInMemoryDatabase()));
909
945
  const hooks = {
910
- onInit: _optionalChain([options, 'access', _51 => _51.hooks, 'optionalAccess', _52 => _52.onInit]),
911
- onStart: _optionalChain([options, 'access', _53 => _53.hooks, 'optionalAccess', _54 => _54.onStart]),
912
- onClose: _optionalChain([options, 'access', _55 => _55.hooks, 'optionalAccess', _56 => _56.onClose]) ? async (context) => {
913
- if (_optionalChain([options, 'access', _57 => _57.hooks, 'optionalAccess', _58 => _58.onClose])) await _optionalChain([options, 'access', _59 => _59.hooks, 'optionalAccess', _60 => _60.onClose, 'call', _61 => _61(context)]);
946
+ onInit: _optionalChain([options, 'access', _53 => _53.hooks, 'optionalAccess', _54 => _54.onInit]),
947
+ onStart: _optionalChain([options, 'access', _55 => _55.hooks, 'optionalAccess', _56 => _56.onStart]),
948
+ onClose: _optionalChain([options, 'access', _57 => _57.hooks, 'optionalAccess', _58 => _58.onClose]) ? async (context) => {
949
+ if (_optionalChain([options, 'access', _59 => _59.hooks, 'optionalAccess', _60 => _60.onClose])) await _optionalChain([options, 'access', _61 => _61.hooks, 'optionalAccess', _62 => _62.onClose, 'call', _63 => _63(context)]);
914
950
  } : void 0
915
951
  };
916
952
  const processor = projector({
@@ -925,11 +961,11 @@ var inMemoryProjector = (options) => {
925
961
  return Object.assign(processor, { database });
926
962
  };
927
963
  var inMemoryReactor = (options) => {
928
- const database = _nullishCoalesce(_optionalChain([options, 'access', _62 => _62.connectionOptions, 'optionalAccess', _63 => _63.database]), () => ( getInMemoryDatabase()));
964
+ const database = _nullishCoalesce(_optionalChain([options, 'access', _64 => _64.connectionOptions, 'optionalAccess', _65 => _65.database]), () => ( getInMemoryDatabase()));
929
965
  const hooks = {
930
- onInit: _optionalChain([options, 'access', _64 => _64.hooks, 'optionalAccess', _65 => _65.onInit]),
931
- onStart: _optionalChain([options, 'access', _66 => _66.hooks, 'optionalAccess', _67 => _67.onStart]),
932
- onClose: _optionalChain([options, 'access', _68 => _68.hooks, 'optionalAccess', _69 => _69.onClose])
966
+ onInit: _optionalChain([options, 'access', _66 => _66.hooks, 'optionalAccess', _67 => _67.onInit]),
967
+ onStart: _optionalChain([options, 'access', _68 => _68.hooks, 'optionalAccess', _69 => _69.onStart]),
968
+ onClose: _optionalChain([options, 'access', _70 => _70.hooks, 'optionalAccess', _71 => _71.onClose])
933
969
  };
934
970
  const processor = reactor({
935
971
  ...options,
@@ -943,7 +979,7 @@ var inMemoryReactor = (options) => {
943
979
  return Object.assign(processor, { database });
944
980
  };
945
981
  var downcastRecordedMessage = (recordedMessage, options) => {
946
- if (!_optionalChain([options, 'optionalAccess', _70 => _70.downcast]))
982
+ if (!_optionalChain([options, 'optionalAccess', _72 => _72.downcast]))
947
983
  return recordedMessage;
948
984
  const downcasted = options.downcast(
949
985
  recordedMessage
@@ -961,14 +997,14 @@ var downcastRecordedMessage = (recordedMessage, options) => {
961
997
  };
962
998
  };
963
999
  var downcastRecordedMessages = (recordedMessages, options) => {
964
- if (!_optionalChain([options, 'optionalAccess', _71 => _71.downcast]))
1000
+ if (!_optionalChain([options, 'optionalAccess', _73 => _73.downcast]))
965
1001
  return recordedMessages;
966
1002
  return recordedMessages.map(
967
1003
  (recordedMessage) => downcastRecordedMessage(recordedMessage, options)
968
1004
  );
969
1005
  };
970
1006
  var upcastRecordedMessage = (recordedMessage, options) => {
971
- if (!_optionalChain([options, 'optionalAccess', _72 => _72.upcast]))
1007
+ if (!_optionalChain([options, 'optionalAccess', _74 => _74.upcast]))
972
1008
  return recordedMessage;
973
1009
  const upcasted = options.upcast(
974
1010
  recordedMessage
@@ -1020,7 +1056,7 @@ var getEventStoreDBEventStore = (eventStore) => {
1020
1056
  return {
1021
1057
  async aggregateStream(streamName, options) {
1022
1058
  const { evolve, initialState, read } = options;
1023
- const expectedStreamVersion = _optionalChain([read, 'optionalAccess', _73 => _73.expectedStreamVersion]);
1059
+ const expectedStreamVersion = _optionalChain([read, 'optionalAccess', _75 => _75.expectedStreamVersion]);
1024
1060
  let state = initialState();
1025
1061
  let currentStreamVersion = EventStoreDBEventStoreDefaultStreamVersion;
1026
1062
  let lastEventGlobalPosition = void 0;
@@ -1035,11 +1071,11 @@ var getEventStoreDBEventStore = (eventStore) => {
1035
1071
  state,
1036
1072
  upcastRecordedMessage(
1037
1073
  mapFromESDBEvent(resolvedEvent),
1038
- _optionalChain([options, 'optionalAccess', _74 => _74.read, 'optionalAccess', _75 => _75.schema, 'optionalAccess', _76 => _76.versioning])
1074
+ _optionalChain([options, 'optionalAccess', _76 => _76.read, 'optionalAccess', _77 => _77.schema, 'optionalAccess', _78 => _78.versioning])
1039
1075
  )
1040
1076
  );
1041
1077
  currentStreamVersion = event.revision;
1042
- lastEventGlobalPosition = _optionalChain([event, 'access', _77 => _77.position, 'optionalAccess', _78 => _78.commit]);
1078
+ lastEventGlobalPosition = _optionalChain([event, 'access', _79 => _79.position, 'optionalAccess', _80 => _80.commit]);
1043
1079
  }
1044
1080
  assertExpectedVersionMatchesCurrent(
1045
1081
  currentStreamVersion,
@@ -1080,7 +1116,7 @@ var getEventStoreDBEventStore = (eventStore) => {
1080
1116
  events.push(
1081
1117
  upcastRecordedMessage(
1082
1118
  mapFromESDBEvent(resolvedEvent),
1083
- _optionalChain([options, 'optionalAccess', _79 => _79.schema, 'optionalAccess', _80 => _80.versioning])
1119
+ _optionalChain([options, 'optionalAccess', _81 => _81.schema, 'optionalAccess', _82 => _82.versioning])
1084
1120
  )
1085
1121
  );
1086
1122
  currentStreamVersion = event.revision;
@@ -1105,11 +1141,11 @@ var getEventStoreDBEventStore = (eventStore) => {
1105
1141
  try {
1106
1142
  const eventsToStore = downcastRecordedMessages(
1107
1143
  events,
1108
- _optionalChain([options, 'optionalAccess', _81 => _81.schema, 'optionalAccess', _82 => _82.versioning])
1144
+ _optionalChain([options, 'optionalAccess', _83 => _83.schema, 'optionalAccess', _84 => _84.versioning])
1109
1145
  );
1110
1146
  const serializedEvents = eventsToStore.map(_dbclient.jsonEvent);
1111
1147
  const expectedRevision = toExpectedRevision(
1112
- _optionalChain([options, 'optionalAccess', _83 => _83.expectedStreamVersion])
1148
+ _optionalChain([options, 'optionalAccess', _85 => _85.expectedStreamVersion])
1113
1149
  );
1114
1150
  const appendResult = await eventStore.appendToStream(
1115
1151
  streamName,
@@ -1156,7 +1192,7 @@ var getEventStoreDBEventStore = (eventStore) => {
1156
1192
  };
1157
1193
  };
1158
1194
  var getESDBCheckpoint = (resolvedEvent, from) => {
1159
- return !from || _optionalChain([from, 'optionalAccess', _84 => _84.stream]) === $all ? _nullishCoalesce(_optionalChain([resolvedEvent, 'access', _85 => _85.link, 'optionalAccess', _86 => _86.position, 'optionalAccess', _87 => _87.commit]), () => ( _optionalChain([resolvedEvent, 'access', _88 => _88.event, 'optionalAccess', _89 => _89.position, 'optionalAccess', _90 => _90.commit]))) : _nullishCoalesce(_optionalChain([resolvedEvent, 'access', _91 => _91.link, 'optionalAccess', _92 => _92.revision]), () => ( resolvedEvent.event.revision));
1195
+ return !from || _optionalChain([from, 'optionalAccess', _86 => _86.stream]) === $all ? _nullishCoalesce(_optionalChain([resolvedEvent, 'access', _87 => _87.link, 'optionalAccess', _88 => _88.position, 'optionalAccess', _89 => _89.commit]), () => ( _optionalChain([resolvedEvent, 'access', _90 => _90.event, 'optionalAccess', _91 => _91.position, 'optionalAccess', _92 => _92.commit]))) : _nullishCoalesce(_optionalChain([resolvedEvent, 'access', _93 => _93.link, 'optionalAccess', _94 => _94.revision]), () => ( resolvedEvent.event.revision));
1160
1196
  };
1161
1197
  var mapFromESDBEvent = (resolvedEvent, from) => {
1162
1198
  const event = resolvedEvent.event;
@@ -1199,7 +1235,7 @@ var toGlobalPosition = (startFrom) => startFrom === "BEGINNING" ? _dbclient.STAR
1199
1235
  };
1200
1236
  var toStreamPosition = (startFrom) => startFrom === "BEGINNING" ? _dbclient.START : startFrom === "END" ? _dbclient.END : parseBigIntProcessorCheckpoint(startFrom.lastCheckpoint);
1201
1237
  var subscribe = (client, from, options) => from == void 0 || from.stream == $all ? client.subscribeToAll({
1202
- ..._nullishCoalesce(_optionalChain([from, 'optionalAccess', _93 => _93.options]), () => ( {})),
1238
+ ..._nullishCoalesce(_optionalChain([from, 'optionalAccess', _95 => _95.options]), () => ( {})),
1203
1239
  fromPosition: toGlobalPosition(options.startFrom),
1204
1240
  filter: _dbclient.excludeSystemEvents.call(void 0, )
1205
1241
  }) : client.subscribeToStream(from.stream, {
@@ -1258,7 +1294,7 @@ var eventStoreDBSubscription = ({
1258
1294
  let start;
1259
1295
  let processor;
1260
1296
  let subscription;
1261
- const resubscribeOptions = _nullishCoalesce(_optionalChain([resilience, 'optionalAccess', _94 => _94.resubscribeOptions]), () => ( {
1297
+ const resubscribeOptions = _nullishCoalesce(_optionalChain([resilience, 'optionalAccess', _96 => _96.resubscribeOptions]), () => ( {
1262
1298
  ...EventStoreDBResubscribeDefaultOptions,
1263
1299
  shouldRetryResult: () => isRunning,
1264
1300
  shouldRetryError: (error) => isRunning && EventStoreDBResubscribeDefaultOptions.shouldRetryError(error)
@@ -1381,9 +1417,9 @@ var eventStoreDBEventStoreConsumer = (options) => {
1381
1417
  return await s.handle(messagesBatch, { client });
1382
1418
  })
1383
1419
  );
1384
- const error = _optionalChain([result, 'access', _95 => _95.find, 'call', _96 => _96((r) => r.status === "rejected"), 'optionalAccess', _97 => _97.reason]);
1420
+ const error = _optionalChain([result, 'access', _97 => _97.find, 'call', _98 => _98((r) => r.status === "rejected"), 'optionalAccess', _99 => _99.reason]);
1385
1421
  return result.some(
1386
- (r) => r.status === "fulfilled" && _optionalChain([r, 'access', _98 => _98.value, 'optionalAccess', _99 => _99.type]) !== "STOP"
1422
+ (r) => r.status === "fulfilled" && _optionalChain([r, 'access', _100 => _100.value, 'optionalAccess', _101 => _101.type]) !== "STOP"
1387
1423
  ) ? void 0 : {
1388
1424
  type: "STOP",
1389
1425
  error: error ? EmmettError.mapFrom(error) : void 0
@@ -1393,7 +1429,7 @@ var eventStoreDBEventStoreConsumer = (options) => {
1393
1429
  client,
1394
1430
  from: options.from,
1395
1431
  eachBatch,
1396
- batchSize: _nullishCoalesce(_optionalChain([pulling, 'optionalAccess', _100 => _100.batchSize]), () => ( DefaultEventStoreDBEventStoreProcessorBatchSize)),
1432
+ batchSize: _nullishCoalesce(_optionalChain([pulling, 'optionalAccess', _102 => _102.batchSize]), () => ( DefaultEventStoreDBEventStoreProcessorBatchSize)),
1397
1433
  resilience: options.resilience
1398
1434
  });
1399
1435
  const stop = async () => {