@rotorsoft/act 1.33.19 → 1.34.0

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 (34) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/@types/act.d.ts +2 -2
  3. package/dist/@types/builders/merge.d.ts.map +1 -1
  4. package/dist/@types/builders/state-builder.d.ts +1 -1
  5. package/dist/@types/builders/state-builder.d.ts.map +1 -1
  6. package/dist/@types/internal/drain-cycle.d.ts.map +1 -1
  7. package/dist/@types/internal/event-sourcing.d.ts.map +1 -1
  8. package/dist/@types/internal/settle.d.ts +2 -3
  9. package/dist/@types/internal/settle.d.ts.map +1 -1
  10. package/dist/@types/types/action.d.ts +28 -0
  11. package/dist/@types/types/action.d.ts.map +1 -1
  12. package/dist/@types/types/builders.d.ts +113 -25
  13. package/dist/@types/types/builders.d.ts.map +1 -1
  14. package/dist/@types/types/errors.d.ts +13 -6
  15. package/dist/@types/types/errors.d.ts.map +1 -1
  16. package/dist/{chunk-5Z53Y7SG.js → chunk-5F2TQ4PT.js} +2 -2
  17. package/dist/{chunk-HEHGZHHA.js → chunk-BKCNU6FF.js} +10 -5
  18. package/dist/chunk-BKCNU6FF.js.map +1 -0
  19. package/dist/{chunk-GEUBNZ3B.cjs → chunk-BTLM7SW4.cjs} +13 -13
  20. package/dist/{chunk-GEUBNZ3B.cjs.map → chunk-BTLM7SW4.cjs.map} +1 -1
  21. package/dist/{chunk-DVYTKZD5.cjs → chunk-RF5MV72K.cjs} +10 -5
  22. package/dist/chunk-RF5MV72K.cjs.map +1 -0
  23. package/dist/index.cjs +168 -151
  24. package/dist/index.cjs.map +1 -1
  25. package/dist/index.js +29 -12
  26. package/dist/index.js.map +1 -1
  27. package/dist/test/index.cjs +4 -4
  28. package/dist/test/index.js +2 -2
  29. package/dist/types/index.cjs +2 -2
  30. package/dist/types/index.js +1 -1
  31. package/package.json +1 -1
  32. package/dist/chunk-DVYTKZD5.cjs.map +0 -1
  33. package/dist/chunk-HEHGZHHA.js.map +0 -1
  34. /package/dist/{chunk-5Z53Y7SG.js.map → chunk-5F2TQ4PT.js.map} +0 -0
package/dist/index.js CHANGED
@@ -40,7 +40,7 @@ import {
40
40
  sleep,
41
41
  store,
42
42
  validate
43
- } from "./chunk-5Z53Y7SG.js";
43
+ } from "./chunk-5F2TQ4PT.js";
44
44
  import {
45
45
  ActorSchema,
46
46
  CausationEventSchema,
@@ -70,7 +70,7 @@ import {
70
70
  pii_fields,
71
71
  pii_schemas,
72
72
  sensitive
73
- } from "./chunk-HEHGZHHA.js";
73
+ } from "./chunk-BKCNU6FF.js";
74
74
 
75
75
  // src/signals.ts
76
76
  process.once("SIGINT", async (arg) => {
@@ -1924,6 +1924,19 @@ async function action(me, action2, target, payload, options, patch_fn = bare_pat
1924
1924
  );
1925
1925
  });
1926
1926
  }
1927
+ if (me.requires) {
1928
+ const preconditions = me.requires[action2] || [];
1929
+ for (const { holds, description } of preconditions)
1930
+ if (!holds(validated, snapshot.state, actor))
1931
+ throw new InvariantError(
1932
+ action2,
1933
+ validated,
1934
+ target,
1935
+ snapshot,
1936
+ description,
1937
+ "precondition"
1938
+ );
1939
+ }
1927
1940
  const result = me.on[action2](validated, snapshot, target);
1928
1941
  if (!result) return [snapshot];
1929
1942
  if (Array.isArray(result) && result.length === 0) {
@@ -2343,15 +2356,14 @@ async function run_drain_cycle(deps, cycle) {
2343
2356
  return handle({ ...lease, at }, payloads);
2344
2357
  })
2345
2358
  );
2346
- const blocked = await ops.block(
2347
- handled.filter(({ block: block2 }) => block2).map(({ lease, error }) => ({ ...lease, error }))
2348
- );
2359
+ const to_block = handled.filter(({ block: block2 }) => block2).map(({ lease, error }) => ({ ...lease, error }));
2360
+ const blocked = to_block.length ? await ops.block(to_block) : [];
2349
2361
  if (blocked.length) deps.on_blocked(blocked);
2350
2362
  const submitted = handled.flatMap((h, i) => {
2351
2363
  const advance = h.handled > 0 ? h.acked_at : leased[i].at;
2352
2364
  return h.defer !== void 0 ? { ...h.lease, at: advance, due: h.defer, retry: -1 } : h.next_attempt_at !== void 0 ? { ...h.lease, at: advance, due: h.next_attempt_at } : h.handled > 0 || !h.error ? { ...h.lease, at: h.acked_at } : [];
2353
2365
  });
2354
- const acked = await ops.ack(submitted);
2366
+ const acked = submitted.length ? await ops.ack(submitted) : [];
2355
2367
  const expected = submitted.filter((l) => l.due === void 0).length;
2356
2368
  if (acked.length < expected)
2357
2369
  log().warn(
@@ -2854,9 +2866,8 @@ var SettleLoop = class {
2854
2866
  * `debounceMs` brings it forward), and a call during a running cycle
2855
2867
  * queues one more pass after it. Callers pass options, which the next
2856
2868
  * pass uses; internal wake-ups pass none, so they never discard a
2857
- * caller's. The cycle runs correlate→drain in a
2858
- * loop until a pass makes no progress (it read no events and leased no
2859
- * streams) or `maxPasses` is reached, then emits the
2869
+ * caller's. The cycle runs correlate→drain passes until one makes no
2870
+ * progress (see {@link SettleOptions.maxPasses}), then emits the
2860
2871
  * `"settled"` lifecycle event via {@link SettleDeps.on_settled}.
2861
2872
  */
2862
2873
  schedule(options) {
@@ -3906,8 +3917,8 @@ var Act = class {
3906
3917
  * `unblock()`, `restore()`) schedules this on its own unless the app
3907
3918
  * sets `autoSettle: false`. Call it at startup, to run what was pending
3908
3919
  * before a restart, or with options for the next pass; the scheduling
3909
- * rule is in the event-sourcing docs (§ settle). Runs correlate→drain in a loop until a pass makes no
3910
- * progress — it read no events and leased no streams —
3920
+ * rule is in the event-sourcing docs (§ settle). Runs correlate→drain
3921
+ * passes until one makes no progress (see {@link SettleOptions.maxPasses}),
3911
3922
  * then emits the `"settled"` lifecycle event, so one call fully catches
3912
3923
  * up paginated streams without forcing callers to loop.
3913
3924
  *
@@ -4241,6 +4252,7 @@ function merge_into_existing(state2, existing, states, actions, events) {
4241
4252
  patch: merged_patch,
4242
4253
  on: { ...existing.on, ...state2.on },
4243
4254
  given: { ...existing.given, ...state2.given },
4255
+ requires: { ...existing.requires, ...state2.requires },
4244
4256
  snap: pick_declared(existing.snap, state2.snap, "snap strategy", state2.name),
4245
4257
  // Per-action retry policy is keyed by action name, so the two partials'
4246
4258
  // maps combine. Left `undefined` when neither declared one, so the
@@ -5008,6 +5020,11 @@ function action_builder(state2) {
5008
5020
  function given(rules) {
5009
5021
  internal.given ??= {};
5010
5022
  internal.given[action2] = rules;
5023
+ return { requires, emit };
5024
+ }
5025
+ function requires(rules) {
5026
+ internal.requires ??= {};
5027
+ internal.requires[action2] = rules;
5011
5028
  return { emit };
5012
5029
  }
5013
5030
  function emit(handler) {
@@ -5025,7 +5042,7 @@ function action_builder(state2) {
5025
5042
  }
5026
5043
  return builder;
5027
5044
  }
5028
- return { given, emit };
5045
+ return { given, requires, emit };
5029
5046
  },
5030
5047
  snap(snap2) {
5031
5048
  internal.snap = snap2;