@rotorsoft/act 1.31.20 → 1.31.22

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
@@ -3840,11 +3840,19 @@ var Act = class {
3840
3840
  * It is waited on like any cycle, and deriving from the lanes alone gave
3841
3841
  * it a budget of `0` whenever it was the only thing running — which
3842
3842
  * returned before the wait it was about to be added to.
3843
+ *
3844
+ * A lane configured `leaseMillis: 0` takes the fallback rather than its
3845
+ * own value, which is why this coalesces on falsy and not just on absent
3846
+ * (#1647). A zero-length lease expires the instant it is granted, so it
3847
+ * has no answer to offer for "how long may a handler hold this stream" —
3848
+ * it is the pinned-no-lease case spelled with a number, and #1617 already
3849
+ * settled what that case is worth. Taking it literally derived a budget
3850
+ * of `0` and abandoned the very cycle this had just found running.
3843
3851
  */
3844
3852
  _derive_grace_ms(running, settling) {
3845
3853
  let max = settling ? DEFAULT_SHUTDOWN_GRACE_MS : 0;
3846
3854
  for (const c of running)
3847
- max = Math.max(max, c.lease_millis ?? DEFAULT_SHUTDOWN_GRACE_MS);
3855
+ max = Math.max(max, c.lease_millis || DEFAULT_SHUTDOWN_GRACE_MS);
3848
3856
  return Math.min(max, MAX_SHUTDOWN_GRACE_MS);
3849
3857
  }
3850
3858
  async _await_inflight(grace_ms) {
@@ -4870,6 +4878,25 @@ function register_new_state(state2, states, actions, events) {
4870
4878
  events[name] = { schema: state2.events[name], reactions: /* @__PURE__ */ new Map() };
4871
4879
  }
4872
4880
  }
4881
+ function pick_declared(existing, incoming, what, state_name) {
4882
+ if (existing && incoming && existing !== incoming)
4883
+ throw new Error(`Duplicate ${what} for state "${state_name}"`);
4884
+ return incoming ?? existing;
4885
+ }
4886
+ function autoclose_of(existing, state2) {
4887
+ pick_declared(
4888
+ existing.autoclose,
4889
+ state2.autoclose,
4890
+ "autoclose policy",
4891
+ state2.name
4892
+ );
4893
+ const owner = state2.autoclose ? state2 : existing;
4894
+ return {
4895
+ autoclose: owner.autoclose,
4896
+ autoclose_after_days: owner.autoclose_after_days,
4897
+ autoclose_keep_days: owner.autoclose_keep_days
4898
+ };
4899
+ }
4873
4900
  function merge_into_existing(state2, existing, states, actions, events) {
4874
4901
  for (const name of Object.keys(state2.actions)) {
4875
4902
  if (existing.actions[name] === state2.actions[name]) continue;
@@ -4894,11 +4921,26 @@ function merge_into_existing(state2, existing, states, actions, events) {
4894
4921
  patch: merged_patch,
4895
4922
  on: { ...existing.on, ...state2.on },
4896
4923
  given: { ...existing.given, ...state2.given },
4897
- snap: state2.snap && existing.snap && state2.snap !== existing.snap ? (() => {
4898
- throw new Error(
4899
- `Duplicate snap strategy for state "${state2.name}"`
4900
- );
4901
- })() : state2.snap || existing.snap
4924
+ snap: pick_declared(existing.snap, state2.snap, "snap strategy", state2.name),
4925
+ // Per-action retry policy is keyed by action name, so the two partials'
4926
+ // maps combine. Left `undefined` when neither declared one, so the
4927
+ // orchestrator's `me.options?.[action]` lookup is unchanged.
4928
+ options: existing.options || state2.options ? { ...existing.options, ...state2.options } : void 0,
4929
+ disclose: pick_declared(
4930
+ existing.disclose,
4931
+ state2.disclose,
4932
+ "disclosure predicate",
4933
+ state2.name
4934
+ ),
4935
+ archive: pick_declared(
4936
+ existing.archive,
4937
+ state2.archive,
4938
+ "archiver",
4939
+ state2.name
4940
+ ),
4941
+ // `.autocloses(...)` sets its two day fields alongside the predicate, so
4942
+ // the whole triple travels together from whichever partial declared it.
4943
+ ...autoclose_of(existing, state2)
4902
4944
  };
4903
4945
  states.set(state2.name, merged);
4904
4946
  for (const name of Object.keys(merged.actions)) {