@rotorsoft/act 1.3.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -868,51 +868,7 @@ var subscribe = (streams) => store().subscribe(streams);
868
868
 
869
869
  // src/internal/event-sourcing.ts
870
870
  import { patch } from "@rotorsoft/act-patch";
871
- async function* iterate(source, filter) {
872
- const state2 = {
873
- slot: null,
874
- onProduce: null,
875
- onConsume: null,
876
- done: false,
877
- error: void 0
878
- };
879
- const wakeProduce = () => {
880
- const fn = state2.onProduce;
881
- state2.onProduce = null;
882
- if (fn) fn();
883
- };
884
- void source.query((event) => {
885
- state2.slot = event;
886
- wakeProduce();
887
- return new Promise((resolve) => {
888
- state2.onConsume = () => resolve();
889
- });
890
- }, filter).then(
891
- () => {
892
- state2.done = true;
893
- wakeProduce();
894
- },
895
- (err) => {
896
- state2.error = err;
897
- state2.done = true;
898
- wakeProduce();
899
- }
900
- );
901
- while (true) {
902
- if (state2.slot === null && !state2.done)
903
- await new Promise((resolve) => {
904
- state2.onProduce = resolve;
905
- });
906
- if (state2.error) throw state2.error;
907
- if (state2.slot === null) return;
908
- const event = state2.slot;
909
- state2.slot = null;
910
- const fn = state2.onConsume;
911
- state2.onConsume = null;
912
- fn();
913
- yield event;
914
- }
915
- }
871
+ var DEFAULT_BATCH = 500;
916
872
  async function snap(snapshot) {
917
873
  try {
918
874
  const { id, stream, name, meta, version } = snapshot.event;
@@ -944,7 +900,7 @@ async function tombstone(stream, expectedVersion, correlation) {
944
900
  throw error;
945
901
  }
946
902
  }
947
- function isValid(event) {
903
+ function is_valid(event) {
948
904
  if (event.version < 0) return false;
949
905
  if (!(event.created instanceof Date) || Number.isNaN(event.created.getTime()))
950
906
  return false;
@@ -952,48 +908,70 @@ function isValid(event) {
952
908
  }
953
909
  async function scan(source, opts = {}, callback) {
954
910
  const { drop_snapshots = false, on_progress } = opts;
955
- const idMap = /* @__PURE__ */ new Map();
911
+ const limit = opts.batch_size ?? DEFAULT_BATCH;
912
+ const id_map = /* @__PURE__ */ new Map();
956
913
  let kept = 0;
957
- let droppedSnapshots = 0;
914
+ let dropped_snaps = 0;
958
915
  let processed = 0;
959
- for await (const event of iterate(source)) {
960
- processed++;
961
- if (!isValid(event)) throw new Error(`Invalid event at index ${processed}`);
962
- if (on_progress) on_progress({ processed });
963
- if (drop_snapshots && event.name === SNAP_EVENT) {
964
- droppedSnapshots++;
965
- continue;
966
- }
967
- if (!callback) {
968
- kept++;
969
- continue;
970
- }
971
- let remapped = event;
972
- const causedBy = event.meta.causation.event?.id;
973
- if (causedBy !== void 0) {
974
- const newCausedBy = idMap.get(causedBy);
975
- if (newCausedBy !== void 0 && newCausedBy !== causedBy) {
976
- remapped = {
977
- ...event,
978
- meta: {
979
- ...event.meta,
980
- causation: {
981
- ...event.meta.causation,
982
- event: { ...event.meta.causation.event, id: newCausedBy }
983
- }
916
+ let at;
917
+ let max_id;
918
+ const probed = await source.query(
919
+ (e) => {
920
+ max_id = e.id;
921
+ },
922
+ { backward: true, limit: 1 }
923
+ );
924
+ if (probed !== 1) max_id = void 0;
925
+ while (true) {
926
+ let got = 0;
927
+ let id;
928
+ await source.query(
929
+ async (event) => {
930
+ got++;
931
+ id = event.id;
932
+ processed++;
933
+ if (!is_valid(event))
934
+ throw new Error(`Invalid event at index ${processed}`);
935
+ if (on_progress) on_progress({ processed, id: event.id, max_id });
936
+ if (drop_snapshots && event.name === SNAP_EVENT) {
937
+ dropped_snaps++;
938
+ return;
939
+ }
940
+ if (!callback) {
941
+ kept++;
942
+ return;
943
+ }
944
+ let remapped = event;
945
+ const caused_by = event.meta.causation.event?.id;
946
+ if (caused_by !== void 0) {
947
+ const new_caused_by = id_map.get(caused_by);
948
+ if (new_caused_by !== void 0 && new_caused_by !== caused_by) {
949
+ remapped = {
950
+ ...event,
951
+ meta: {
952
+ ...event.meta,
953
+ causation: {
954
+ ...event.meta.causation,
955
+ event: { ...event.meta.causation.event, id: new_caused_by }
956
+ }
957
+ }
958
+ };
984
959
  }
985
- };
986
- }
987
- }
988
- const newId = await callback(remapped);
989
- idMap.set(event.id, newId);
990
- kept++;
960
+ }
961
+ const new_id = await callback(remapped);
962
+ id_map.set(event.id, new_id);
963
+ kept++;
964
+ },
965
+ { after: at, limit }
966
+ );
967
+ if (got !== limit) break;
968
+ at = id;
991
969
  }
992
970
  return {
993
971
  kept,
994
972
  dropped: {
995
973
  closed_streams: 0,
996
- snapshots: droppedSnapshots,
974
+ snapshots: dropped_snaps,
997
975
  empty_streams: 0
998
976
  }
999
977
  };