@rotorsoft/act 1.22.3 → 1.22.5

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
@@ -13,13 +13,14 @@ import {
13
13
  dispose,
14
14
  disposeAndExit,
15
15
  extend,
16
+ is_literal_source,
16
17
  log,
17
18
  port,
18
19
  scoped,
19
20
  sleep,
20
21
  store,
21
22
  validate
22
- } from "./chunk-2FN4RFBQ.js";
23
+ } from "./chunk-CWBI4NQD.js";
23
24
  import {
24
25
  ActorSchema,
25
26
  CausationEventSchema,
@@ -1381,13 +1382,22 @@ var CorrelateCycle = class {
1381
1382
  _has_dynamic_resolvers;
1382
1383
  _cd;
1383
1384
  _on_init;
1384
- constructor(registry, static_targets, has_dynamic_resolvers, cd, maxSubscribedStreams, on_init) {
1385
+ /**
1386
+ * Scope runner (#1191). The periodic `start_polling` timer fires
1387
+ * outside any caller frame, so its `correlate()` must be re-wrapped in
1388
+ * the Act's `_scoped` bag or `store()`/`cache()` resolve to the
1389
+ * singleton for a scoped Act. The orchestrator always threads its
1390
+ * `_scoped` (identity for a non-scoped Act), so it's required.
1391
+ */
1392
+ _run_scoped;
1393
+ constructor(registry, static_targets, has_dynamic_resolvers, cd, maxSubscribedStreams, on_init, run_scoped) {
1385
1394
  this._subscribed = new LruSet(maxSubscribedStreams);
1386
1395
  this._registry = registry;
1387
1396
  this._static_targets = static_targets;
1388
1397
  this._has_dynamic_resolvers = has_dynamic_resolvers;
1389
1398
  this._cd = cd;
1390
1399
  this._on_init = on_init;
1400
+ this._run_scoped = run_scoped;
1391
1401
  }
1392
1402
  /** Last correlated event id. */
1393
1403
  get checkpoint() {
@@ -1482,7 +1492,9 @@ var CorrelateCycle = class {
1482
1492
  if (this._timer) return false;
1483
1493
  const limit = query.limit || 100;
1484
1494
  this._timer = setInterval(
1485
- () => this.correlate({ ...query, after: this._checkpoint, limit }).then((result) => {
1495
+ () => this._run_scoped(
1496
+ () => this.correlate({ ...query, after: this._checkpoint, limit })
1497
+ ).then((result) => {
1486
1498
  if (callback && result.subscribed) callback(result.subscribed);
1487
1499
  }).catch((err) => log().error(err)),
1488
1500
  frequency
@@ -1627,8 +1639,10 @@ async function fetch(leased, eventLimit) {
1627
1639
  return Promise.all(
1628
1640
  leased.map(async ({ stream, source, at, lagging }) => {
1629
1641
  const events = [];
1642
+ const stream_exact = source !== void 0 && is_literal_source(source) ? true : void 0;
1630
1643
  await store().query((e) => events.push(e), {
1631
1644
  stream: source,
1645
+ stream_exact,
1632
1646
  after: at,
1633
1647
  limit: eventLimit
1634
1648
  });
@@ -1787,12 +1801,15 @@ async function scan(source, opts = {}, callback) {
1787
1801
  const new_caused_by = id_map.get(caused_by);
1788
1802
  if (new_caused_by !== void 0 && new_caused_by !== caused_by) {
1789
1803
  remapped = {
1790
- ...event,
1804
+ ...migrated,
1791
1805
  meta: {
1792
- ...event.meta,
1806
+ ...migrated.meta,
1793
1807
  causation: {
1794
- ...event.meta.causation,
1795
- event: { ...event.meta.causation.event, id: new_caused_by }
1808
+ ...migrated.meta.causation,
1809
+ event: {
1810
+ ...migrated.meta.causation.event,
1811
+ id: new_caused_by
1812
+ }
1796
1813
  }
1797
1814
  }
1798
1815
  };
@@ -1859,7 +1876,8 @@ async function load(me, target, callback) {
1859
1876
  ...cached ? { after: cached.event_id } : { with_snaps: true, ...asOf }
1860
1877
  }
1861
1878
  );
1862
- if (replayed > 0 && !time_travel && event && !me.pii_aware) {
1879
+ const head_is_tombstone = event?.name === TOMBSTONE_EVENT;
1880
+ if (replayed > 0 && !time_travel && event && !me.pii_aware && !head_is_tombstone) {
1863
1881
  await cache().set(stream, {
1864
1882
  stream,
1865
1883
  state: state2,
@@ -2293,8 +2311,9 @@ var DrainController = class {
2293
2311
  */
2294
2312
  start(cycleMs) {
2295
2313
  if (this._worker || this._stopped) return;
2314
+ const run = this._deps.run_scoped;
2296
2315
  const tick = async () => {
2297
- if (this._armed) await this.drain();
2316
+ if (this._armed) await run(() => this.drain());
2298
2317
  if (this._stopped) return;
2299
2318
  this._worker = setTimeout(tick, cycleMs);
2300
2319
  this._worker.unref();
@@ -2895,6 +2914,9 @@ var Act = class {
2895
2914
  this.emit("closed", result);
2896
2915
  },
2897
2916
  breaker: this._breaker,
2917
+ // Re-scope the per-lane worker's auto-start ticks so their drain
2918
+ // resolves the scoped ports, not the singleton (#1191).
2919
+ run_scoped: this._scoped,
2898
2920
  // Pass lane only when a true per-lane controller is active.
2899
2921
  // The all-lanes (single default) case keeps lane=undefined so
2900
2922
  // adapter SQL collapses to the single-lane shape.
@@ -2941,14 +2963,21 @@ var Act = class {
2941
2963
  options.maxSubscribedStreams ?? DEFAULT_MAX_SUBSCRIBED_STREAMS,
2942
2964
  () => {
2943
2965
  if (this._drain && this._reactive_events.size > 0) this._arm_all();
2944
- }
2966
+ },
2967
+ // Re-scope the background `start_correlations` timer so its
2968
+ // correlate resolves the scoped ports, not the singleton (#1191).
2969
+ this._scoped
2945
2970
  );
2946
2971
  }
2947
2972
  /** Settle loop driving correlate + drain to quiescence. */
2948
2973
  _build_settle(options) {
2949
2974
  return new SettleLoop(
2950
2975
  {
2951
- init: () => this._correlate.init(),
2976
+ // Scope the init like every other store-touching path — a bare
2977
+ // `this._correlate.init()` runs `store().subscribe(...)` against
2978
+ // the singleton for a scoped Act, so static targets never land on
2979
+ // the scoped store and `_initialized` then blocks a retry (#1191).
2980
+ init: () => this._scoped(() => this._correlate.init()),
2952
2981
  checkpoint: () => this._correlate.checkpoint,
2953
2982
  correlate: (q) => this.correlate(q),
2954
2983
  drain: (o) => this.drain(o),
@@ -4560,6 +4589,7 @@ export {
4560
4589
  dispose,
4561
4590
  disposeAndExit,
4562
4591
  extend,
4592
+ is_literal_source,
4563
4593
  log,
4564
4594
  port,
4565
4595
  projection,