@rotorsoft/act 1.32.17 → 1.32.19

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 (32) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/@types/builders/builder-base.d.ts +1 -1
  3. package/dist/@types/builders/builder-base.d.ts.map +1 -1
  4. package/dist/@types/builders/reaction-builder.d.ts.map +1 -1
  5. package/dist/@types/internal/autoclose-reaction.d.ts +0 -8
  6. package/dist/@types/internal/autoclose-reaction.d.ts.map +1 -1
  7. package/dist/@types/internal/config.d.ts +6 -6
  8. package/dist/@types/internal/config.d.ts.map +1 -1
  9. package/dist/@types/internal/defer-timer.d.ts +6 -12
  10. package/dist/@types/internal/defer-timer.d.ts.map +1 -1
  11. package/dist/@types/internal/drain-cycle.d.ts +6 -44
  12. package/dist/@types/internal/drain-cycle.d.ts.map +1 -1
  13. package/dist/@types/internal/event-sourcing.d.ts +2 -1
  14. package/dist/@types/internal/event-sourcing.d.ts.map +1 -1
  15. package/dist/@types/internal/index.d.ts +1 -1
  16. package/dist/@types/internal/index.d.ts.map +1 -1
  17. package/dist/@types/internal/sensitive.d.ts +0 -21
  18. package/dist/@types/internal/sensitive.d.ts.map +1 -1
  19. package/dist/@types/types/reaction.d.ts +3 -3
  20. package/dist/{chunk-PZP5ZEZ4.js → chunk-QOSQI3CA.js} +2 -2
  21. package/dist/{chunk-JRTZGWVS.js → chunk-XSG2NW4J.js} +1 -1
  22. package/dist/{chunk-JRTZGWVS.js.map → chunk-XSG2NW4J.js.map} +1 -1
  23. package/dist/index.cjs +19 -19
  24. package/dist/index.cjs.map +1 -1
  25. package/dist/index.js +21 -21
  26. package/dist/index.js.map +1 -1
  27. package/dist/test/index.cjs.map +1 -1
  28. package/dist/test/index.js +2 -2
  29. package/dist/types/index.cjs.map +1 -1
  30. package/dist/types/index.js +1 -1
  31. package/package.json +1 -1
  32. /package/dist/{chunk-PZP5ZEZ4.js.map → chunk-QOSQI3CA.js.map} +0 -0
package/dist/index.cjs CHANGED
@@ -2494,6 +2494,10 @@ var BackoffOptionsSchema = import_zod6.z.object({
2494
2494
  maxMs: import_zod6.z.number().gt(0).optional(),
2495
2495
  jitter: import_zod6.z.boolean().optional()
2496
2496
  });
2497
+ var DEFAULT_BACKOFF = {
2498
+ strategy: "fixed",
2499
+ baseMs: 1e4
2500
+ };
2497
2501
  var DEFAULT_MAX_RETRIES = 3;
2498
2502
  var DEFAULT_BLOCK_ON_ERROR = true;
2499
2503
  var ReactionOptionsSchema = import_zod6.z.object({
@@ -3698,9 +3702,8 @@ var DeferTimer = class {
3698
3702
  _on_wake;
3699
3703
  /**
3700
3704
  * @param on_wake - invoked once each time the earliest due-time elapses,
3701
- * after the come-due entries have been removed. Consumers use it to
3702
- * re-arm their loop (the drain sets its `armed` flag; autoclose runs a
3703
- * tick).
3705
+ * after the come-due entries have been removed. The consumer re-schedules
3706
+ * for whatever is still parked.
3704
3707
  */
3705
3708
  constructor(on_wake) {
3706
3709
  this._on_wake = on_wake;
@@ -3753,14 +3756,9 @@ var DeferTimer = class {
3753
3756
  this._timer = setTimeout(() => {
3754
3757
  this._timer = void 0;
3755
3758
  const now = Date.now();
3756
- let came_due = false;
3757
3759
  for (const [stream, at] of this._due)
3758
- if (at <= now) {
3759
- this._due.delete(stream);
3760
- came_due = true;
3761
- }
3760
+ if (at <= now) this._due.delete(stream);
3762
3761
  this._on_wake();
3763
- if (!came_due && this._due.size > 0) this.schedule();
3764
3762
  }, delay);
3765
3763
  this._timer.unref();
3766
3764
  }
@@ -4477,7 +4475,7 @@ async function run_drain_cycle(deps, cycle) {
4477
4475
  handled: 0,
4478
4476
  acked_at: lease.at,
4479
4477
  error,
4480
- ...block2 ? { block: true } : {}
4478
+ ...block2 ? { block: true } : { next_attempt_at: Date.now() + DEFAULT_BACKOFF.baseMs }
4481
4479
  };
4482
4480
  return Promise.resolve(failed);
4483
4481
  }
@@ -4525,11 +4523,15 @@ var DrainController = class {
4525
4523
  _ratio = 0.5;
4526
4524
  /**
4527
4525
  * Local wake for streams this worker parked (backoff or defer). The
4528
- * schedule itself is persisted in the store; this only re-arms the drain
4529
- * at the earliest pending visit.
4526
+ * schedule itself is persisted in the store; this runs the drain at the
4527
+ * earliest pending visit. A parked stream already carries its mark, so
4528
+ * the drain alone finds it, and on an idle app nothing else would.
4529
+ * `stop()` cancels the timer and a stopped drain never re-schedules it,
4530
+ * so a wake never runs after a stop.
4530
4531
  */
4531
4532
  _defer = new DeferTimer(() => {
4532
4533
  this._armed = true;
4534
+ void this._deps.run_scoped(() => this.drain());
4533
4535
  });
4534
4536
  /** Worker timer. Set when `start()` is active, undefined otherwise. */
4535
4537
  _worker;
@@ -4617,13 +4619,13 @@ var DrainController = class {
4617
4619
  async drain(options = {}) {
4618
4620
  if (!this._armed) return EMPTY_DRAIN;
4619
4621
  if (this._locked) return EMPTY_DRAIN;
4620
- if (this._deps.breaker.state(Date.now()) === "open")
4621
- return EMPTY_DRAIN;
4622
4622
  const d = this._deps.defaults ?? {};
4623
4623
  const streamLimit = d.streamLimit ?? options.streamLimit ?? DEFAULT_STREAM_LIMIT;
4624
4624
  const eventLimit = d.eventLimit ?? options.eventLimit ?? DEFAULT_EVENT_LIMIT;
4625
4625
  const leaseMillis = d.leaseMillis ?? options.leaseMillis ?? DEFAULT_LEASE_MILLIS;
4626
4626
  try {
4627
+ if (this._deps.breaker.state(Date.now()) === "open")
4628
+ return EMPTY_DRAIN;
4627
4629
  this._locked = true;
4628
4630
  this._inflight = new Promise((done) => {
4629
4631
  this._inflight_done = done;
@@ -4641,7 +4643,6 @@ var DrainController = class {
4641
4643
  if (!cycle) {
4642
4644
  this._deps.breaker.passed();
4643
4645
  this._armed = false;
4644
- if (this._defer.size > 0) this._defer.schedule();
4645
4646
  return EMPTY_DRAIN;
4646
4647
  }
4647
4648
  const { leased, fetched, handled, acked, blocked, closeable } = cycle;
@@ -4650,11 +4651,9 @@ var DrainController = class {
4650
4651
  for (const lease of acked) this._defer.delete(lease.stream);
4651
4652
  for (const lease of blocked) this._defer.delete(lease.stream);
4652
4653
  for (const h of handled) {
4653
- const retry_at = h.error && !h.block ? h.next_attempt_at ?? Date.now() + leaseMillis : void 0;
4654
- const next = h.defer ?? retry_at;
4654
+ const next = h.defer ?? h.next_attempt_at;
4655
4655
  if (next !== void 0) this._defer.set(h.lease.stream, next);
4656
4656
  }
4657
- if (this._defer.size > 0) this._defer.schedule();
4658
4657
  if (acked.length) this._deps.on_acked(acked);
4659
4658
  if (closeable.length) await this._deps.on_close(closeable);
4660
4659
  this._deps.breaker.passed();
@@ -4665,6 +4664,7 @@ var DrainController = class {
4665
4664
  this._deps.breaker.failed(Date.now(), error);
4666
4665
  return EMPTY_DRAIN;
4667
4666
  } finally {
4667
+ if (!this._stopped) this._defer.schedule();
4668
4668
  this._locked = false;
4669
4669
  this._inflight = void 0;
4670
4670
  this._inflight_done?.();
@@ -4870,7 +4870,7 @@ function finalize(lease, handled, at, error, options, logger, failed_at) {
4870
4870
  logger.error(
4871
4871
  non_retryable ? `Blocking ${lease.stream} on non-retryable error.` : `Blocking ${lease.stream} after ${lease.retry} retries.`
4872
4872
  );
4873
- const next_attempt_at = !block2 && options.backoff ? Date.now() + compute_backoff_delay(lease.retry, options.backoff) : void 0;
4873
+ const next_attempt_at = block2 ? void 0 : Date.now() + compute_backoff_delay(lease.retry, options.backoff ?? DEFAULT_BACKOFF);
4874
4874
  return {
4875
4875
  lease,
4876
4876
  handled,