@rotorsoft/act 1.32.25 → 1.32.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.
Files changed (49) hide show
  1. package/README.md +2 -3
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/@types/act.d.ts +5 -151
  4. package/dist/@types/act.d.ts.map +1 -1
  5. package/dist/@types/adapters/in-memory-store.d.ts +0 -21
  6. package/dist/@types/adapters/in-memory-store.d.ts.map +1 -1
  7. package/dist/@types/builders/act-builder.d.ts +0 -25
  8. package/dist/@types/builders/act-builder.d.ts.map +1 -1
  9. package/dist/@types/builders/build-classify.d.ts +4 -4
  10. package/dist/@types/builders/build-classify.d.ts.map +1 -1
  11. package/dist/@types/builders/projection-builder.d.ts.map +1 -1
  12. package/dist/@types/builders/slice-builder.d.ts +1 -12
  13. package/dist/@types/builders/slice-builder.d.ts.map +1 -1
  14. package/dist/@types/builders/state-builder.d.ts +0 -189
  15. package/dist/@types/builders/state-builder.d.ts.map +1 -1
  16. package/dist/@types/config.d.ts +0 -27
  17. package/dist/@types/config.d.ts.map +1 -1
  18. package/dist/@types/internal/close-cycle.d.ts +2 -1
  19. package/dist/@types/internal/close-cycle.d.ts.map +1 -1
  20. package/dist/@types/internal/correlate-cycle.d.ts.map +1 -1
  21. package/dist/@types/internal/drain-cycle.d.ts.map +1 -1
  22. package/dist/@types/ports.d.ts +0 -7
  23. package/dist/@types/ports.d.ts.map +1 -1
  24. package/dist/@types/test/sandbox.d.ts +0 -14
  25. package/dist/@types/test/sandbox.d.ts.map +1 -1
  26. package/dist/@types/types/action.d.ts +0 -27
  27. package/dist/@types/types/action.d.ts.map +1 -1
  28. package/dist/@types/types/errors.d.ts +1 -92
  29. package/dist/@types/types/errors.d.ts.map +1 -1
  30. package/dist/@types/types/ports.d.ts +0 -70
  31. package/dist/@types/types/ports.d.ts.map +1 -1
  32. package/dist/@types/types/reaction.d.ts +0 -33
  33. package/dist/@types/types/reaction.d.ts.map +1 -1
  34. package/dist/{chunk-QXW3JV2H.js → chunk-5FXT63KF.js} +2 -2
  35. package/dist/chunk-5FXT63KF.js.map +1 -0
  36. package/dist/{chunk-XSG2NW4J.js → chunk-F7K7SIG6.js} +1 -1
  37. package/dist/chunk-F7K7SIG6.js.map +1 -0
  38. package/dist/index.cjs +79 -165
  39. package/dist/index.cjs.map +1 -1
  40. package/dist/index.js +81 -167
  41. package/dist/index.js.map +1 -1
  42. package/dist/test/index.cjs.map +1 -1
  43. package/dist/test/index.js +2 -2
  44. package/dist/test/index.js.map +1 -1
  45. package/dist/types/index.cjs.map +1 -1
  46. package/dist/types/index.js +1 -1
  47. package/package.json +1 -4
  48. package/dist/chunk-QXW3JV2H.js.map +0 -1
  49. package/dist/chunk-XSG2NW4J.js.map +0 -1
package/dist/index.js CHANGED
@@ -26,7 +26,7 @@ import {
26
26
  sleep,
27
27
  store,
28
28
  validate
29
- } from "./chunk-QXW3JV2H.js";
29
+ } from "./chunk-5FXT63KF.js";
30
30
  import {
31
31
  ActorSchema,
32
32
  CausationEventSchema,
@@ -53,7 +53,7 @@ import {
53
53
  pii_split,
54
54
  pii_strip,
55
55
  sensitive
56
- } from "./chunk-XSG2NW4J.js";
56
+ } from "./chunk-F7K7SIG6.js";
57
57
 
58
58
  // src/signals.ts
59
59
  process.once("SIGINT", async (arg) => {
@@ -81,10 +81,8 @@ var ALL_LANES = /* @__PURE__ */ Symbol("act-1103/all-lanes");
81
81
  function classify_registry(registry, states) {
82
82
  const statics = /* @__PURE__ */ new Map();
83
83
  const target_lanes = /* @__PURE__ */ new Map();
84
- const reactive_events = /* @__PURE__ */ new Set();
85
84
  const event_to_lanes = /* @__PURE__ */ new Map();
86
85
  for (const [name, register] of Object.entries(registry.events)) {
87
- if (register.reactions.size > 0) reactive_events.add(name);
88
86
  for (const reaction of register.reactions.values()) {
89
87
  if (typeof reaction.resolver === "function") {
90
88
  event_to_lanes.set(name, ALL_LANES);
@@ -122,7 +120,6 @@ function classify_registry(registry, states) {
122
120
  }
123
121
  return {
124
122
  static_targets: [...statics.values()],
125
- reactive_events,
126
123
  event_to_state,
127
124
  event_to_lanes
128
125
  };
@@ -1279,7 +1276,7 @@ async function run_full_closes(full, target_map, deps, skipped) {
1279
1276
  }
1280
1277
  const safe = await partition_by_safety(
1281
1278
  stream_info,
1282
- deps.reactive_events_size,
1279
+ deps.reactive,
1283
1280
  skipped,
1284
1281
  deps.probe_page_size ?? SAFETY_PROBE_PAGE_SIZE,
1285
1282
  deps.catch_up_correlation
@@ -1316,8 +1313,8 @@ async function run_full_closes(full, target_map, deps, skipped) {
1316
1313
  );
1317
1314
  }
1318
1315
  async function run_windowed_closes(windowed, deps, skipped) {
1319
- const checkpoint = deps.reactive_events_size > 0 ? await deps.catch_up_correlation(Number.MAX_SAFE_INTEGER) : -1;
1320
- const min_at = deps.reactive_events_size > 0 ? await probe_min_watermarks(
1316
+ const checkpoint = deps.reactive ? await deps.catch_up_correlation(Number.MAX_SAFE_INTEGER) : -1;
1317
+ const min_at = deps.reactive ? await probe_min_watermarks(
1321
1318
  windowed.map((t) => t.stream),
1322
1319
  deps.probe_page_size ?? SAFETY_PROBE_PAGE_SIZE,
1323
1320
  checkpoint
@@ -1405,8 +1402,8 @@ async function scan_stream_heads(streams) {
1405
1402
  }
1406
1403
  return out;
1407
1404
  }
1408
- async function partition_by_safety(stream_info, reactive_events_size, skipped, page_size, catch_up_correlation2) {
1409
- if (reactive_events_size === 0) return [...stream_info.keys()];
1405
+ async function partition_by_safety(stream_info, reactive, skipped, page_size, catch_up_correlation2) {
1406
+ if (!reactive) return [...stream_info.keys()];
1410
1407
  let needed = -1;
1411
1408
  for (const info of stream_info.values())
1412
1409
  needed = Math.max(needed, info.max_id);
@@ -1692,13 +1689,25 @@ var CorrelateCycle = class {
1692
1689
  const after = Math.max(this._checkpoint, query.after || -1);
1693
1690
  const correlated = /* @__PURE__ */ new Map();
1694
1691
  let last_id = after;
1692
+ let stopped = false;
1695
1693
  const found = await store().query(
1696
1694
  (event) => {
1697
- last_id = event.id;
1695
+ if (stopped) return;
1698
1696
  const register = this._registry.events[event.name];
1699
1697
  if (register) {
1700
1698
  for (const reaction of register.reactions.values()) {
1701
- const resolved = typeof reaction.resolver === "function" ? reaction.resolver(event) : reaction.resolver;
1699
+ let resolved;
1700
+ try {
1701
+ resolved = typeof reaction.resolver === "function" ? reaction.resolver(event) : reaction.resolver;
1702
+ } catch (error) {
1703
+ stopped = true;
1704
+ report_once(
1705
+ this._reported,
1706
+ `resolver|${reaction.handler.name}|${event.id}`,
1707
+ `Resolver of reaction "${reaction.handler.name}" threw on ${String(event.name)} #${event.id} (stream "${event.stream}"): ${String(error)}. Correlation stops before this event until the resolver stops throwing; work already found keeps draining.`
1708
+ );
1709
+ return;
1710
+ }
1702
1711
  if (!resolved) continue;
1703
1712
  let lane = resolved.lane;
1704
1713
  if (lane !== void 0 && !this._declared_lanes.has(lane)) {
@@ -1747,6 +1756,7 @@ var CorrelateCycle = class {
1747
1756
  correlated.set(resolved.target, entry);
1748
1757
  }
1749
1758
  }
1759
+ last_id = event.id;
1750
1760
  },
1751
1761
  // Resolvers see `pii: null`: correlate runs actor-less, and one
1752
1762
  // undecryptable row would otherwise stop every stream's reactions.
@@ -1788,7 +1798,7 @@ var CorrelateCycle = class {
1788
1798
  return { subscribed, last_id, marked, scanned: true };
1789
1799
  }
1790
1800
  this._checkpoint = last_id;
1791
- this._armed = found === query.limit;
1801
+ this._armed = stopped || found === query.limit;
1792
1802
  return { subscribed: 0, last_id, marked: 0, scanned: true };
1793
1803
  }
1794
1804
  /**
@@ -2672,6 +2682,22 @@ function fetch_failure_policy(registry) {
2672
2682
  }
2673
2683
  return { blockOnError, maxRetries };
2674
2684
  }
2685
+ function resolver_failed(lease, { error, options }) {
2686
+ log().error(error);
2687
+ const block2 = options.blockOnError && lease.retry >= options.maxRetries;
2688
+ return {
2689
+ lease,
2690
+ handled: 0,
2691
+ acked_at: lease.at,
2692
+ error,
2693
+ ...block2 ? { block: true } : {
2694
+ next_attempt_at: Date.now() + compute_backoff_delay(
2695
+ lease.retry,
2696
+ options.backoff ?? DEFAULT_BACKOFF
2697
+ )
2698
+ }
2699
+ };
2700
+ }
2675
2701
  function warn_misrouted(seen, stream, handler, event) {
2676
2702
  report_once(
2677
2703
  seen,
@@ -2705,13 +2731,23 @@ async function run_drain_cycle(deps, cycle) {
2705
2731
  );
2706
2732
  for (const f of fetched) {
2707
2733
  const { stream, events } = f;
2734
+ let failed;
2708
2735
  const payloads = events.flatMap((event) => {
2709
2736
  const register = registry.events[event.name];
2710
2737
  if (!register) return [];
2711
2738
  return [...register.reactions.values()].filter((reaction) => {
2712
2739
  const resolver = reaction.resolver;
2713
2740
  const dynamic = typeof resolver === "function";
2714
- const resolved = dynamic ? resolver(event) : resolver;
2741
+ let resolved;
2742
+ try {
2743
+ resolved = dynamic ? resolver(event) : resolver;
2744
+ } catch (error) {
2745
+ failed ??= {
2746
+ error: `Resolver of reaction "${reaction.handler.name}" threw on ${String(event.name)} #${event.id} (stream "${event.stream}"): ${String(error)}`,
2747
+ options: reaction.options
2748
+ };
2749
+ return false;
2750
+ }
2715
2751
  if (!resolved || resolved.target !== stream) return false;
2716
2752
  if (!dynamic || !batch_handlers.has(stream)) return true;
2717
2753
  warn_misrouted(
@@ -2723,7 +2759,7 @@ async function run_drain_cycle(deps, cycle) {
2723
2759
  return false;
2724
2760
  }).map((reaction) => ({ ...reaction, event }));
2725
2761
  });
2726
- fetch_map.set(stream, { fetch: f, payloads });
2762
+ fetch_map.set(stream, { fetch: f, payloads, failed });
2727
2763
  }
2728
2764
  const handled = await Promise.all(
2729
2765
  leased.map((lease) => {
@@ -2744,6 +2780,8 @@ async function run_drain_cycle(deps, cycle) {
2744
2780
  };
2745
2781
  return Promise.resolve(failed);
2746
2782
  }
2783
+ if (entry.failed)
2784
+ return Promise.resolve(resolver_failed(lease, entry.failed));
2747
2785
  const at = entry.fetch.events.at(-1)?.id || fetch_window_at;
2748
2786
  const { payloads } = entry;
2749
2787
  const exhausted = budget_exhausted(
@@ -3223,7 +3261,8 @@ var Act = class {
3223
3261
  _breaker;
3224
3262
  _listen;
3225
3263
  _drain;
3226
- _reactive_events;
3264
+ /** Whether any event has a reaction; nothing arms without one. */
3265
+ _reactive;
3227
3266
  _drain_controllers;
3228
3267
  _correlate;
3229
3268
  _settle;
@@ -3353,7 +3392,7 @@ var Act = class {
3353
3392
  });
3354
3393
  this._handle_batch = build_handle_batch(this._logger);
3355
3394
  const classification = classify_registry(this.registry, this._states);
3356
- this._reactive_events = classification.reactive_events;
3395
+ this._reactive = classification.event_to_lanes.size > 0;
3357
3396
  this._event_to_state = classification.event_to_state;
3358
3397
  this._event_to_lanes = classification.event_to_lanes;
3359
3398
  this._listen = options.listen !== false;
@@ -3400,8 +3439,18 @@ var Act = class {
3400
3439
  on_acked: (acked) => this.emit("acked", acked),
3401
3440
  on_blocked: (blocked) => this.emit("blocked", blocked),
3402
3441
  // Reaction-requested close: the same machinery as `app.close`.
3442
+ // A store failure reaches the breaker; anything else (the archive
3443
+ // callback is app code) is logged here, never counted.
3403
3444
  on_close: async (targets) => {
3404
- await this._run_close(targets);
3445
+ try {
3446
+ await this._run_close(targets);
3447
+ } catch (error) {
3448
+ if (error instanceof StoreError) throw error;
3449
+ this._logger.error(
3450
+ error,
3451
+ `Reaction-requested close of ${targets.map((t) => `"${t.stream}"`).join(", ")} failed and was not retried; close it with app.close(...) once the cause is fixed.`
3452
+ );
3453
+ }
3405
3454
  },
3406
3455
  breaker: this._breaker,
3407
3456
  run_scoped: this._scoped,
@@ -3450,9 +3499,8 @@ var Act = class {
3450
3499
  declared_lanes: new Set(this._declared_lanes),
3451
3500
  // Built after the controllers, so their keys are the active lanes.
3452
3501
  shard: this._drain_controllers.size < this._declared_lanes.length ? [...this._drain_controllers.keys()] : void 0,
3453
- on_init: () => {
3454
- if (this._drain && this._reactive_events.size > 0) this._arm_all();
3455
- },
3502
+ // Only reached on a draining app: writer-only ones never correlate.
3503
+ on_init: () => this._arm_all(),
3456
3504
  on_init_async: this._drain ? () => this._seed_persisted_defers() : void 0
3457
3505
  });
3458
3506
  }
@@ -3549,7 +3597,7 @@ var Act = class {
3549
3597
  }
3550
3598
  /** Failures are logged, never thrown: `notify` is a hint. */
3551
3599
  async _wire_notify(s) {
3552
- if (this._reactive_events.size === 0) return void 0;
3600
+ if (!this._reactive) return void 0;
3553
3601
  if (!s.notify) return void 0;
3554
3602
  if (!this._listen) return void 0;
3555
3603
  try {
@@ -3609,46 +3657,6 @@ var Act = class {
3609
3657
  * console.log(snapshots[0].state.count); // Current count after increment
3610
3658
  * ```
3611
3659
  *
3612
- * @example With error handling
3613
- * ```typescript
3614
- * try {
3615
- * await app.do(
3616
- * "withdraw",
3617
- * { stream: "account-123", actor: { id: "user1", name: "Alice" } },
3618
- * { amount: 1000 }
3619
- * );
3620
- * } catch (error) {
3621
- * if (error instanceof InvariantError) {
3622
- * console.error("Business rule violated:", error.description);
3623
- * } else if (error instanceof ConcurrencyError) {
3624
- * console.error("Concurrent modification detected, retry...");
3625
- * } else if (error instanceof ValidationError) {
3626
- * console.error("Invalid payload:", error.details);
3627
- * }
3628
- * }
3629
- * ```
3630
- *
3631
- * @example Reaction triggering another action (reactingTo auto-injected)
3632
- * ```typescript
3633
- * const app = act()
3634
- * .withState(Order)
3635
- * .withState(Inventory)
3636
- * .on("OrderPlaced")
3637
- * .do(async function reduceInventory(event, _stream, app) {
3638
- * // Inside reaction handlers, reactingTo is auto-injected when omitted.
3639
- * // The triggering event is used by default, maintaining the correlation chain.
3640
- * await app.do(
3641
- * "reduceStock",
3642
- * { stream: "inventory-1", actor: { id: "sys", name: "system" } },
3643
- * { amount: event.data.items.length }
3644
- * );
3645
- * // To use a different correlation, pass reactingTo explicitly:
3646
- * // await app.do("reduceStock", target, payload, { reactingTo: customEvent });
3647
- * })
3648
- * .to("inventory-1")
3649
- * .build();
3650
- * ```
3651
- *
3652
3660
  * @see {@link Target} for target structure
3653
3661
  * @see {@link Snapshot} for return value structure
3654
3662
  * @see {@link ValidationError}, {@link InvariantError}, {@link ConcurrencyError}
@@ -3664,10 +3672,9 @@ var Act = class {
3664
3672
  payload,
3665
3673
  do_options
3666
3674
  );
3667
- if (this._reactive_events.size > 0)
3668
- this._arm_for_event_names(
3669
- snapshots.map((s) => s.event.name)
3670
- );
3675
+ this._arm_for_event_names(
3676
+ snapshots.map((s) => s.event.name)
3677
+ );
3671
3678
  this.emit("committed", snapshots);
3672
3679
  return snapshots;
3673
3680
  });
@@ -3714,26 +3721,6 @@ var Act = class {
3714
3721
  * console.log(`Found ${count} events from ${first?.id} to ${last?.id}`);
3715
3722
  * ```
3716
3723
  *
3717
- * @example Query specific event types
3718
- * ```typescript
3719
- * const { count } = await app.query(
3720
- * { name: "UserCreated", limit: 100 },
3721
- * (event) => {
3722
- * console.log("User created:", event.data.email);
3723
- * }
3724
- * );
3725
- * ```
3726
- *
3727
- * @example Query events in time range
3728
- * ```typescript
3729
- * const yesterday = new Date(Date.now() - 24 * 60 * 60 * 1000);
3730
- * const { count } = await app.query({
3731
- * created_after: yesterday,
3732
- * stream: "user-123"
3733
- * });
3734
- * console.log(`User had ${count} events in last 24 hours`);
3735
- * ```
3736
- *
3737
3724
  * @see {@link query_array} for loading events into memory
3738
3725
  */
3739
3726
  async query(query, callback) {
@@ -3765,14 +3752,6 @@ var Act = class {
3765
3752
  * events.forEach(event => console.log(event.name, event.data));
3766
3753
  * ```
3767
3754
  *
3768
- * @example Get recent events
3769
- * ```typescript
3770
- * const recent = await app.query_array({
3771
- * stream: "user-123",
3772
- * limit: 10
3773
- * });
3774
- * ```
3775
- *
3776
3755
  * @see {@link query} for large result sets
3777
3756
  */
3778
3757
  async query_array(query) {
@@ -3843,12 +3822,6 @@ var Act = class {
3843
3822
  * await app.drain();
3844
3823
  * ```
3845
3824
  *
3846
- * @example In production, prefer settle()
3847
- * ```typescript
3848
- * await app.do("CreateItem", target, input);
3849
- * app.settle(); // debounced correlate→drain, emits "settled"
3850
- * ```
3851
- *
3852
3825
  * @see {@link settle} for debounced correlate→drain with lifecycle events
3853
3826
  * @see {@link correlate} for dynamic stream discovery
3854
3827
  * @see {@link start_correlations} for automatic correlation
@@ -3860,6 +3833,7 @@ var Act = class {
3860
3833
  return this._scoped(() => this._drain_all(options));
3861
3834
  }
3862
3835
  _arm_all() {
3836
+ if (!this._reactive) return;
3863
3837
  this._correlate.arm();
3864
3838
  for (const c of this._drain_controllers.values()) c.arm();
3865
3839
  }
@@ -3915,37 +3889,20 @@ var Act = class {
3915
3889
  * on reaction resolvers. It then registers these streams so they'll be picked up by
3916
3890
  * the next drain cycle.
3917
3891
  *
3918
- * @param query - Query filter to scan for new correlations
3919
3892
  * @param query - Scan filter — see {@link Query} for fields (typically
3920
3893
  * `{ after: <event-id>, limit: <count> }`)
3921
- * @returns Object with newly leased streams and last scanned event ID
3894
+ * @returns The number of newly subscribed streams and the last scanned event id
3922
3895
  *
3923
3896
  * @example Manual correlation
3924
3897
  * ```typescript
3925
3898
  * // Scan for new streams
3926
- * const { leased, last_id } = await app.correlate({ after: 0, limit: 100 });
3927
- * console.log(`Found ${leased.length} new streams`);
3899
+ * const { subscribed, last_id } = await app.correlate({ after: 0, limit: 100 });
3900
+ * console.log(`Subscribed ${subscribed} new streams`);
3928
3901
  *
3929
3902
  * // Save last_id for next scan
3930
3903
  * await saveCheckpoint(last_id);
3931
3904
  * ```
3932
3905
  *
3933
- * @example Dynamic stream creation
3934
- * ```typescript
3935
- * const app = act()
3936
- * .withState(User)
3937
- * .withState(UserStats)
3938
- * .on("UserLoggedIn")
3939
- * .do(async (event) => ["incrementLoginCount", {}])
3940
- * .to((event) => ({
3941
- * target: `stats-${event.stream}` // Dynamic target per user
3942
- * }))
3943
- * .build();
3944
- *
3945
- * // Discover stats streams as users log in
3946
- * await app.correlate();
3947
- * ```
3948
- *
3949
3906
  * @see {@link start_correlations} for automatic periodic correlation
3950
3907
  * @see {@link stop_correlations} to stop automatic correlation
3951
3908
  */
@@ -3958,8 +3915,7 @@ var Act = class {
3958
3915
  if (!this._drain) return { subscribed: 0, last_id: -1, scanned: false };
3959
3916
  return this._scoped(async () => {
3960
3917
  const { subscribed, last_id, marked, scanned } = await this._correlate.correlate(query, lease);
3961
- if ((subscribed > 0 || marked > 0) && this._reactive_events.size > 0)
3962
- this._arm_all();
3918
+ if (subscribed > 0 || marked > 0) this._arm_all();
3963
3919
  if (subscribed > 0) this._on_discovered?.(subscribed);
3964
3920
  return { subscribed, last_id, scanned };
3965
3921
  });
@@ -4051,12 +4007,6 @@ var Act = class {
4051
4007
  * app.settle({ eventLimit: 1000 }); // emits "settled" when fully replayed
4052
4008
  * ```
4053
4009
  *
4054
- * @example Rebuild a projection (tests / scripts)
4055
- * ```typescript
4056
- * await app.reset(["my-projection"]);
4057
- * await app.drain({ eventLimit: 1000 }); // small streams: one pass is enough
4058
- * ```
4059
- *
4060
4010
  * @see {@link Store.reset} for the underlying store primitive
4061
4011
  * @see {@link settle} for the debounced full-catch-up loop
4062
4012
  */
@@ -4065,7 +4015,7 @@ var Act = class {
4065
4015
  const count = await store().reset(input);
4066
4016
  for (const handler of this._batch_handlers.values())
4067
4017
  handler[FOLD_RESET]?.();
4068
- if (count > 0 && this._reactive_events.size > 0) this._arm_all();
4018
+ if (count > 0) this._arm_all();
4069
4019
  return count;
4070
4020
  });
4071
4021
  }
@@ -4099,7 +4049,7 @@ var Act = class {
4099
4049
  async unblock(input) {
4100
4050
  return this._scoped(async () => {
4101
4051
  const count = await store().unblock(input);
4102
- if (count > 0 && this._reactive_events.size > 0) this._arm_all();
4052
+ if (count > 0) this._arm_all();
4103
4053
  return count;
4104
4054
  });
4105
4055
  }
@@ -4135,11 +4085,6 @@ var Act = class {
4135
4085
  * await cache().clear(); // operator's responsibility
4136
4086
  * ```
4137
4087
  *
4138
- * @example Copy one store into another
4139
- * ```typescript
4140
- * await app.restore(pg, {}, sqlite);
4141
- * ```
4142
- *
4143
4088
  * @see {@link Store.restore} for the underlying driver-pattern primitive.
4144
4089
  */
4145
4090
  async restore(source, opts = {}, sink) {
@@ -4278,16 +4223,6 @@ var Act = class {
4278
4223
  * await app.prioritize({ stream: "^proj-orders$", stream_exact: false }, 10);
4279
4224
  * ```
4280
4225
  *
4281
- * @example Drop all audit projections to background
4282
- * ```typescript
4283
- * await app.prioritize({ source: "^audit-" }, -5);
4284
- * ```
4285
- *
4286
- * @example Reset everyone to default
4287
- * ```typescript
4288
- * await app.prioritize({}, 0);
4289
- * ```
4290
- *
4291
4226
  * @see {@link Store.prioritize} for the underlying primitive
4292
4227
  * @see {@link claim} for how priority biases scheduling
4293
4228
  */
@@ -4298,7 +4233,7 @@ var Act = class {
4298
4233
  async _run_close(targets) {
4299
4234
  const close_actor = { id: "$close", name: "close" };
4300
4235
  const result = await run_close_cycle(targets, {
4301
- reactive_events_size: this._reactive_events.size,
4236
+ reactive: this._reactive,
4302
4237
  catch_up_correlation: (until) => catch_up_correlation(
4303
4238
  this._correlate,
4304
4239
  (limit) => this.correlate({ limit }),
@@ -4351,27 +4286,6 @@ var Act = class {
4351
4286
  * { stream: "order-456" },
4352
4287
  * ]);
4353
4288
  * ```
4354
- *
4355
- * @example Close with restart (state loaded automatically after guard)
4356
- * ```typescript
4357
- * await app.close([
4358
- * { stream: "counter-1", restart: true },
4359
- * { stream: "counter-2" }, // tombstoned
4360
- * ]);
4361
- * ```
4362
- *
4363
- * @example Windowed close — keep the last 180 days of real events
4364
- * ```typescript
4365
- * const cutoff = new Date();
4366
- * cutoff.setDate(cutoff.getDate() - 180);
4367
- * await app.close([
4368
- * {
4369
- * stream: "ledger-acme",
4370
- * before: cutoff,
4371
- * archive: async () => { await archiveToS3("ledger-acme", cutoff); },
4372
- * },
4373
- * ]);
4374
- * ```
4375
4289
  */
4376
4290
  async close(targets) {
4377
4291
  if (!targets.length) return { truncated: /* @__PURE__ */ new Map(), skipped: [] };