@rotorsoft/act 1.23.26 → 1.23.27

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
@@ -1259,9 +1259,7 @@ var InMemoryStore = class {
1259
1259
  }
1260
1260
  return source_matches.some((name) => re.test(name));
1261
1261
  };
1262
- const sorted = [...this._streams.values()].sort(
1263
- (a, b) => a.stream.localeCompare(b.stream)
1264
- );
1262
+ const sorted = [...this._streams.keys()].sort().map((stream) => this._streams.get(stream));
1265
1263
  let count = 0;
1266
1264
  for (const s of sorted) {
1267
1265
  if (after !== void 0 && s.stream <= after) continue;
@@ -1688,7 +1686,10 @@ async function* audit(deps, categories, options = {}) {
1688
1686
  const need_streams = passes.some((p) => p.on_stream !== void 0);
1689
1687
  const need_events = passes.some((p) => p.on_event !== void 0);
1690
1688
  if (need_stats) {
1691
- const stats = await deps.store().query_stats({}, { count: true, names: true });
1689
+ const stats = await deps.store().query_stats(
1690
+ {},
1691
+ { count: true, names: true, exclude: [SNAP_EVENT] }
1692
+ );
1692
1693
  for (const [stream, s] of stats) {
1693
1694
  for (const p of passes) p.on_stat?.(stream, s);
1694
1695
  }
@@ -1828,23 +1829,38 @@ var make_close_candidate_pass = (deps, options) => {
1828
1829
  };
1829
1830
  var make_restart_candidate_pass = (deps, options) => {
1830
1831
  const threshold = options.thresholds?.restart_min ?? DEFAULTS.restart_min;
1832
+ const candidates = [];
1831
1833
  const findings = [];
1832
1834
  return {
1833
1835
  category: "restart-candidate",
1834
- on_stat(stream, { head, count, names }) {
1836
+ on_stat(stream, { head, count }) {
1835
1837
  if (count < threshold) return;
1836
1838
  const head_name = String(head.name);
1837
1839
  if (head_name.startsWith("__")) return;
1838
1840
  if (!restart_is_supported(deps, head_name)) return;
1839
- findings.push({
1840
- category: "restart-candidate",
1841
- stream,
1842
- count,
1843
- // names map is sparse — `__snapshot__` key absent when the
1844
- // stream has never been snapshotted (a common case for the
1845
- // restart-candidate signal).
1846
- snaps: names.__snapshot__ ?? 0
1847
- });
1841
+ candidates.push({ stream, count });
1842
+ },
1843
+ async finalize(deps2) {
1844
+ for (const { stream, count } of candidates) {
1845
+ let snaps = 0;
1846
+ await deps2.store().query(
1847
+ () => {
1848
+ snaps++;
1849
+ },
1850
+ {
1851
+ stream,
1852
+ stream_exact: true,
1853
+ names: [SNAP_EVENT],
1854
+ with_snaps: true
1855
+ }
1856
+ );
1857
+ findings.push({
1858
+ category: "restart-candidate",
1859
+ stream,
1860
+ count,
1861
+ snaps
1862
+ });
1863
+ }
1848
1864
  },
1849
1865
  drain: () => findings
1850
1866
  };
@@ -1899,34 +1915,33 @@ var make_snapshot_drift_pass = (deps, options) => {
1899
1915
  const findings = [];
1900
1916
  return {
1901
1917
  category: "snapshot-drift",
1902
- on_stat(stream, { head, count, names }) {
1918
+ on_stat(stream, { head, count }) {
1903
1919
  if (!restart_is_supported(deps, String(head.name))) return;
1904
1920
  if (count < drift_min) return;
1905
1921
  candidates.push({
1906
1922
  stream,
1907
- total: count,
1908
- snaps: names.__snapshot__ ?? 0
1923
+ total: count
1909
1924
  });
1910
1925
  },
1911
1926
  async finalize(deps2) {
1912
- for (const { stream, total, snaps } of candidates) {
1927
+ for (const { stream, total } of candidates) {
1913
1928
  let events_since_snap = total;
1914
1929
  let snap_at;
1915
- if (snaps > 0) {
1916
- const collected = [];
1917
- await deps2.store().query(
1918
- (e) => {
1919
- collected.push({ id: e.id });
1920
- },
1921
- {
1922
- stream,
1923
- stream_exact: true,
1924
- names: ["__snapshot__"],
1925
- backward: true,
1926
- limit: 1,
1927
- with_snaps: true
1928
- }
1929
- );
1930
+ const collected = [];
1931
+ await deps2.store().query(
1932
+ (e) => {
1933
+ collected.push({ id: e.id });
1934
+ },
1935
+ {
1936
+ stream,
1937
+ stream_exact: true,
1938
+ names: ["__snapshot__"],
1939
+ backward: true,
1940
+ limit: 1,
1941
+ with_snaps: true
1942
+ }
1943
+ );
1944
+ if (collected.length > 0) {
1930
1945
  snap_at = collected[0].id;
1931
1946
  let after = 0;
1932
1947
  await deps2.store().query(
@@ -5868,8 +5883,35 @@ function act() {
5868
5883
  const pending_projections = [];
5869
5884
  const fold_projections = [];
5870
5885
  const batch_handlers = /* @__PURE__ */ new Map();
5886
+ const fold_specs = [];
5871
5887
  const lanes = [];
5872
5888
  let _built = false;
5889
+ const pii_wrap = (original) => async (events, stream) => {
5890
+ const stripped = events.map((e) => {
5891
+ const f = _sf.get(e.name);
5892
+ return f ? pii_strip(e, f) : e;
5893
+ });
5894
+ return original(stripped, stream);
5895
+ };
5896
+ const make_batch_handlers = (patch_fn) => {
5897
+ const handlers = new Map(batch_handlers);
5898
+ for (const spec of fold_specs) {
5899
+ handlers.set(
5900
+ spec.target,
5901
+ pii_wrap(
5902
+ make_fold_handler(
5903
+ spec.merged,
5904
+ spec.flush,
5905
+ spec.config,
5906
+ patch_fn,
5907
+ // Head loads strip sensitive keys like the warm path (#1320).
5908
+ (event_name) => _sf.get(event_name) ?? []
5909
+ )
5910
+ )
5911
+ );
5912
+ }
5913
+ return handlers;
5914
+ };
5873
5915
  const finalize_deprecations = () => {
5874
5916
  const deprecation_summary = [];
5875
5917
  for (const state2 of states.values()) {
@@ -5965,19 +6007,12 @@ function act() {
5965
6007
  throw new Error(
5966
6008
  `State projection "${proj.target}" of "${fold.name}" is missing events ${missing.join(", ")} \u2014 pass every partial of the state to .of()`
5967
6009
  );
5968
- batch_handlers.set(
5969
- proj.target,
5970
- make_fold_handler(
5971
- merged,
5972
- fold.flush,
5973
- fold.config,
5974
- patch_fn,
5975
- // Head loads strip sensitive keys like the warm path (#1320).
5976
- // `_sf` is populated in the events pass below; read lazily at
5977
- // fold time, by when the map is complete.
5978
- (event_name) => _sf.get(event_name) ?? []
5979
- )
5980
- );
6010
+ fold_specs.push({
6011
+ target: proj.target,
6012
+ merged,
6013
+ flush: fold.flush,
6014
+ config: fold.config
6015
+ });
5981
6016
  }
5982
6017
  finalize_deprecations();
5983
6018
  validate_lane_references(registry, lanes);
@@ -6028,14 +6063,7 @@ function act() {
6028
6063
  };
6029
6064
  }
6030
6065
  for (const [target, original] of batch_handlers) {
6031
- const wrapped = async (events, stream) => {
6032
- const stripped = events.map((e) => {
6033
- const f = _sf.get(e.name);
6034
- return f ? pii_strip(e, f) : e;
6035
- });
6036
- return original(stripped, stream);
6037
- };
6038
- batch_handlers.set(target, wrapped);
6066
+ batch_handlers.set(target, pii_wrap(original));
6039
6067
  }
6040
6068
  synthesize_autoclose_reactions(
6041
6069
  registry,
@@ -6050,7 +6078,7 @@ function act() {
6050
6078
  return new Act(
6051
6079
  registry,
6052
6080
  states,
6053
- batch_handlers,
6081
+ make_batch_handlers(patch_fn),
6054
6082
  options,
6055
6083
  lanes,
6056
6084
  patch_fn