@statedelta-actions/rules 0.3.0 → 0.5.1

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/CHANGELOG.md ADDED
@@ -0,0 +1,89 @@
1
+ # @statedelta-actions/rules
2
+
3
+ ## 0.5.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 26c579a: Polish published package metadata and READMEs
8
+ - `@statedelta-actions/core` now ships a README (was missing on npm).
9
+ - `@statedelta-actions/analyzer` README: fixed pervasive missing accents.
10
+ - `graph` and `events` READMEs: titles are now the package name (`# @statedelta-actions/graph` / `# @statedelta-actions/events`) instead of a conceptual name.
11
+ - All packages: added `keywords`, `homepage`, `bugs`; package.json keys reordered to a canonical layout.
12
+ - All packages: `CHANGELOG.md` added to `files` so it ships to npm; a `LICENSE` (MIT) file is included in the repo root and in each package.
13
+
14
+ - Updated dependencies [26c579a]
15
+ - Updated dependencies [a3a818b]
16
+ - @statedelta-actions/core@0.5.1
17
+ - @statedelta-actions/actions@0.6.0
18
+
19
+ ## 0.5.0
20
+
21
+ ### Minor Changes
22
+
23
+ - f8c2b4a: Fail-fast register errors, controlled `action-not-found`, atomic registration, and events async/interactive modes
24
+ - **actions** — A missing handler for a directive type now throws at register
25
+ time (was a collected error) — fail-fast for typos and forgotten handlers.
26
+ Invoking an unknown action id returns `aborted: true, abortedBy:
27
+ "action-not-found"` instead of a soft failure. `isActionAsync` is exposed on
28
+ the engine ref handed to handlers (symmetric with `isActionInteractive`).
29
+ - **rules** — `register()` is atomic: it builds a staging set, delegates to the
30
+ ActionEngine, then indexes locally only on success. Structural errors from the
31
+ ActionEngine propagate as a throw with no local state mutated.
32
+ - **events** — `register()`/`defineEvents()` are atomic the same way.
33
+ Async detection is now per-listener transitive via the ActionEngine mini-graph,
34
+ so hybrid engines keep `processEvents`/`processEventsAsync` viable for
35
+ listeners whose subtree is fully sync. New `processEventsInteractive()` returns
36
+ a drainable iterator (sync or async generator) — pauses from `type:"pause"` or
37
+ an interactive handler flow via `yield*` up to the consumer; halt scoping is
38
+ preserved (a pause stops the listeners of that event, following events
39
+ continue). New `isInteractive` getter.
40
+ - **core** — `ActionEngineRef` gains an optional `isActionAsync?` accessor.
41
+ - **sdk** — re-exports the new event types/surface; barrel deps moved to
42
+ `dependencies` (`workspace:^`).
43
+
44
+ ### Patch Changes
45
+
46
+ - Updated dependencies [f8c2b4a]
47
+ - @statedelta-actions/actions@0.5.0
48
+ - @statedelta-actions/core@0.5.0
49
+
50
+ ## 0.3.0
51
+
52
+ ### Minor Changes
53
+
54
+ - Split types em definitions + engine em cada package; novo subpath sdk/definitions
55
+ - core: RegisterWarning movido pra core/types/engine.ts (tipo shared entre packages)
56
+ - actions: types.ts → types/definitions.ts + types/engine.ts
57
+ - rules: types.ts → types/definitions.ts + types/engine.ts
58
+ - events: types.ts → types/definitions.ts + types/engine.ts
59
+ - sdk: novo subpath ./definitions com re-export de definition types puros (zero runtime)
60
+
61
+ ### Patch Changes
62
+
63
+ - Updated dependencies []:
64
+ - @statedelta-actions/core@0.3.0
65
+ - @statedelta-actions/actions@0.3.0
66
+
67
+ ## 0.2.0
68
+
69
+ ### Minor Changes
70
+
71
+ - Sync all packages to 0.2.0 (match SDK version)
72
+
73
+ ### Patch Changes
74
+
75
+ - Updated dependencies []:
76
+ - @statedelta-actions/core@0.2.0
77
+ - @statedelta-actions/actions@0.2.0
78
+
79
+ ## 0.3.0
80
+
81
+ ### Minor Changes
82
+
83
+ - Sync all packages to 0.2.0 (match SDK version)
84
+
85
+ ### Patch Changes
86
+
87
+ - Updated dependencies []:
88
+ - @statedelta-actions/core@0.3.0
89
+ - @statedelta-actions/actions@0.3.0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Anderson D. Rosa
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -22,15 +22,16 @@
22
22
  11. [JIT Compilation](#jit-compilation)
23
23
  12. [Batch Operations](#batch-operations)
24
24
  13. [Async Support](#async-support)
25
- 14. [Error Handling](#error-handling)
26
- 15. [HALT_HANDLER](#halt_handler)
27
- 16. [createInvokerMiddleware](#createinvokermiddleware)
28
- 17. [Full API Reference](#full-api-reference)
29
- 18. [Use Case: RPG Combat Tick](#use-case-rpg-combat-tick)
30
- 19. [Use Case: E-commerce Order Pipeline](#use-case-e-commerce-order-pipeline)
31
- 20. [Use Case: Deployment Approval Workflow](#use-case-deployment-approval-workflow)
32
- 21. [Performance Spectrum](#performance-spectrum)
33
- 22. [Internal Design Notes](#internal-design-notes)
25
+ 14. [Modo Interactive](#modo-interactive)
26
+ 15. [Error Handling](#error-handling)
27
+ 16. [HALT_HANDLER](#halt_handler)
28
+ 17. [createInvokerMiddleware](#createinvokermiddleware)
29
+ 18. [Full API Reference](#full-api-reference)
30
+ 19. [Use Case: RPG Combat Tick](#use-case-rpg-combat-tick)
31
+ 20. [Use Case: E-commerce Order Pipeline](#use-case-e-commerce-order-pipeline)
32
+ 21. [Use Case: Deployment Approval Workflow](#use-case-deployment-approval-workflow)
33
+ 22. [Performance Spectrum](#performance-spectrum)
34
+ 23. [Internal Design Notes](#internal-design-notes)
34
35
 
35
36
 
36
37
  ---
@@ -75,6 +76,8 @@ Middleware enriches the `params` envelope (execution scope), not the domain `ctx
75
76
 
76
77
  The engine never throws to the consumer during `evaluate()`. All runtime errors are collected in `RuleEvaluationResult.errors`. The only exception is a programmer error: calling `evaluate()` when `isAsync === true`.
77
78
 
79
+ `register()` is different — structural errors at boot time (missing handler for a directive type) throw an `Error` and abort the registration atomically. See [Registration](#registration).
80
+
78
81
  ### Feature not used = zero overhead
79
82
 
80
83
  When hooks are not registered, hook code is never executed — not as dead branches, but as absent code paths. The JIT compiler conditionally emits code only for features that are actually configured. Zero middleware means no middleware variables, no pipeline calls, no params allocation.
@@ -289,12 +292,21 @@ const result = ruleEngine.register([rule1, rule2, ...]);
289
292
 
290
293
  ### Registration pipeline
291
294
 
292
- 1. **Validate** each rule (id, priority, when, then/rules)
293
- 2. **Normalize** to hidden action: `rule:{id}`
294
- 3. **Collect sub-rules** recursively with dot-separated IDs
295
- 4. **Index** in internal registries (`_rules` sorted by priority desc)
296
- 5. **Register** hidden actions in ActionEngine
297
- 6. **Return** merged result
295
+ Three phases. Local registries are only mutated after the ActionEngine accepts every hidden action — `register()` is atomic.
296
+
297
+ 1. **Build** — validate each rule (id, priority, when, then/rules), collect sub-rules recursively, build hidden action definitions (`rule:{id}` for top-level, dot-separated for sub-rules). Soft validation errors (duplicate id, missing required field) accumulate in `errors[]`. No local indexing yet.
298
+ 2. **Delegate to ActionEngine** `actionEngine.register(hiddenActions)`. Structural errors propagate as throw (handler missing for a directive type). Soft errors from the ActionEngine are mapped back to rule ids and added to `errors[]`.
299
+ 3. **Index** only reached when phase 2 returns. Insert each rule into `_ruleRegistry` and `_rules` (sorted by priority desc), refresh per-rule `isAsync`/`isInteractive` flags from the mini-graph.
300
+
301
+ ### Throw vs collected errors
302
+
303
+ | Error | Behavior |
304
+ |-------|----------|
305
+ | Missing handler for a directive type in `then` (any depth, including sub-rules and `catch`) | **Throws `Error`** in `register()`. No local state mutated. Consumer wraps in try/catch if needed. |
306
+ | Duplicate rule id, missing `when`, missing `then`/`rules`, invalid priority | Collected in `errors[]`. Other valid rules in the same call still register. |
307
+ | `validate()` from a handler returns invalid or throws | Collected in `errors[]`. |
308
+
309
+ The throw path is reserved for boot-time structural errors that cannot become valid at runtime — typos, forgotten handler registration, refactor leftovers. Soft errors are domain-level and worth surveying.
298
310
 
299
311
  ### RuleRegisterResult
300
312
 
@@ -686,13 +698,31 @@ const result = engine.endBatch();
686
698
 
687
699
  ## Async Support
688
700
 
689
- ### Detection
701
+ ### Detection (per-rule transitivo)
690
702
 
691
703
  ```typescript
692
- const isAsync = ruleHookAnalysis.hasAnyAsync || actionEngine.isAsync;
704
+ const isAsync = ruleHookAnalysis.hasAnyAsync || hasAnyAsyncRuleTransitive;
693
705
  ```
694
706
 
695
- Computed once at construction. Immutable. If any rule hook is async, or if the ActionEngine has async directive hooks, `isAsync === true`.
707
+ Refrescado em `register()` / `unregister()` / `endBatch()` consultando o **mini-graph interno do ActionEngine** (ADR-026 do actions). Cada `StoredRule` cacheia `isAsync`/`isInteractive` per-rule (refletindo `actionEngine.isActionAsync(rule.actionId)`).
708
+
709
+ **Diferença importante:** antes era `actionEngine.isAsync` (global). Agora é per-rule transitivo. Engine híbrido (handler async + handler sync) com rules **100% sync na sub-árvore** permite `evaluate()` regular — só rules transitivamente async forçam `evaluateAsync()`.
710
+
711
+ ```typescript
712
+ // Engine híbrido — handler async existe, mas action `log` (usada em syncRule) é sync
713
+ const engine = createActionEngine({
714
+ handlers: { log, fetchAsync: { async: true, async execute() {...} } },
715
+ });
716
+ const rules = createRuleEngine({ actionEngine: engine });
717
+
718
+ rules.register([
719
+ { id: "syncRule", priority: 1, when: () => true, then: [{ type: "log", message: "x" }] },
720
+ ]);
721
+
722
+ engine.isAsync; // true (engine global async — fetchAsync existe)
723
+ rules.isAsync; // false (rule específica é sync transitivamente)
724
+ rules.evaluate(ctx); // ✅ funciona — não força evaluateAsync
725
+ ```
696
726
 
697
727
  ### Usage
698
728
 
@@ -722,15 +752,141 @@ const ruleEngine = createRuleEngine({
722
752
  },
723
753
  });
724
754
 
755
+
725
756
  // Must use evaluateAsync
726
757
  const result = await ruleEngine.evaluateAsync(ctx);
727
758
  ```
728
759
 
729
760
  ---
730
761
 
762
+ ## Modo Interactive
763
+
764
+ Permite **pausar avaliação de rules** e aguardar input externo via generators — espelhamento do modo interactive do ActionEngine. Ortogonal a sync/async.
765
+
766
+ **Habilitação:** ActionEngine precisa estar em modo interactive (`createActionEngine({ ..., interactive: {} })`). Rules detecta automaticamente quando alguma rule registrada tem ação transitivamente interactive.
767
+
768
+ ### Detection per-rule
769
+
770
+ `StoredRule.isInteractive` cacheia o resultado de `engine.isActionInteractive(rule.actionId)`. Refrescado em register/unregister/endBatch.
771
+
772
+ ```typescript
773
+ rules.isInteractive; // true se qualquer rule é interactive transitivamente
774
+ rules.evaluate(ctx); // throws "use evaluateInteractive"
775
+ rules.evaluateAsync(ctx); // idem
776
+ rules.evaluateInteractive(ctx); // ✅ retorna iterator
777
+ ```
778
+
779
+ ### evaluateInteractive
780
+
781
+ Retorna `InteractiveRuleSession` (sync) ou `AsyncInteractiveRuleSession` (async, quando `rules.isAsync`). Drenagem via `next(value)`:
782
+
783
+ > Handlers são primitivas Lego (ADR-028 do actions). Use `input` (genérico) com payload domain-specific. **Nunca crie `askUser`, `confirmEmail`, etc** — viola o princípio canonical.
784
+
785
+ ```typescript
786
+ const engine = createActionEngine({
787
+ handlers: {
788
+ // Primitiva canonical: yield + schema + retry interno
789
+ input: { interactive: true, *execute(d) {
790
+ const ans = yield { kind: "input", payload: d.payload, schema: d.schema };
791
+ return { ok: true, data: ans };
792
+ } },
793
+ log: { execute: (d, f) => { f.ctx.out.push(d.message); return { ok: true }; } },
794
+ },
795
+ interactive: {},
796
+ });
797
+
798
+ const rules = createRuleEngine({ actionEngine: engine });
799
+ rules.register([
800
+ { id: "wizard", priority: 1, when: () => true, then: [
801
+ { type: "log", message: "before" },
802
+ { type: "pause", message: "Confirmar?", as: "ack" },
803
+ { type: "input", payload: { kind: "text", label: "Nome" }, as: "name" },
804
+ { type: "log", resolve: (_c, s) => ({ message: `${s.name} (${s.ack})` }) },
805
+ ] },
806
+ ]);
807
+
808
+ const ctx = { out: [] };
809
+ const session = rules.evaluateInteractive(ctx);
810
+
811
+ session.next(); // → { source: "pause", payload: { message: "Confirmar?" } }
812
+ // ctx.out: ["before"]
813
+ session.next("yes"); // → { kind: "input", payload: { kind: "text", label: "Nome" } }
814
+ session.next("Anderson"); // → { done: true, value: RuleEvaluationResult }
815
+ // matched: ["wizard"]
816
+ // ctx.out: ["before", "Anderson (yes)"]
817
+ ```
818
+
819
+ ### Mistura sync + interactive (priority order)
820
+
821
+ Rules sync e interactive coexistem na mesma evaluation, respeitando priority. Rules sync rodam direto (sem yield); rules interactive pausam.
822
+
823
+ ```typescript
824
+ rules.register([
825
+ { id: "first", priority: 10, when: () => true, then: [{ type: "log", message: "first" }] },
826
+ { id: "wizard", priority: 5, when: () => true, then: [
827
+ { type: "pause", message: "?" },
828
+ ] },
829
+ { id: "last", priority: 1, when: () => true, then: [{ type: "log", message: "last" }] },
830
+ ]);
831
+
832
+ const session = rules.evaluateInteractive(ctx);
833
+ session.next(); // first roda direto, wizard pausa
834
+ // ctx.out: ["first"]
835
+ session.next("ok"); // wizard completa, last roda
836
+ // ctx.out: ["first", "last"]
837
+ ```
838
+
839
+ ### Async generator (engine async + rule interactive)
840
+
841
+ Quando alguma rule é async transitivamente E alguma é interactive, `evaluateInteractive` retorna `AsyncInteractiveRuleSession`. Drenagem via `await session.next()`:
842
+
843
+ ```typescript
844
+ rules.register([
845
+ { id: "loadData", priority: 10, when: () => true, then: [
846
+ { type: "fetchAsync", as: "v" },
847
+ { type: "log", resolve: (_c, s) => ({ message: `loaded ${s.v}` }) },
848
+ ] },
849
+ { id: "getName", priority: 5, when: () => true, then: [
850
+ { type: "input", payload: { kind: "text", label: "Nome" }, as: "name" },
851
+ ] },
852
+ ]);
853
+
854
+ const session = rules.evaluateInteractive(ctx); // AsyncIterator
855
+
856
+ await session.next(); // loadData rodou (fetch async), getName yieldou
857
+ await session.next("Anderson"); // matched: ["loadData", "getName"]
858
+ ```
859
+
860
+ ### Compilação JIT generator
861
+
862
+ Em `mode: "jit"`, `evaluateInteractive` usa **JIT generator compilado** (Fase R6 — `buildInteractiveRuleExecutor`). 4 wrappers possíveis:
863
+
864
+ | `isAsync` | `isInteractive` | Wrapper |
865
+ |-----------|-----------------|---------|
866
+ | false | false | `function ()` (path original — `evaluate`) |
867
+ | true | false | `async function ()` (`evaluateAsync`) |
868
+ | false | true | `function* ()` (`evaluateInteractive` sync) |
869
+ | true | true | `async function* ()` (`evaluateInteractive` async) |
870
+
871
+ JIT emit branch per-rule no loop:
872
+
873
+ ```javascript
874
+ if (stored.isInteractive) {
875
+ ir = yield* ae.invokeInteractive(stored.actionId, params);
876
+ } else if (stored.isAsync) {
877
+ ir = await ae.invokeAsync(stored.actionId, params);
878
+ } else {
879
+ ir = ae.invoke(stored.actionId, params);
880
+ }
881
+ ```
882
+
883
+ Decisão **per-rule em runtime**, baseada nas flags cached em `StoredRule.isAsync`/`isInteractive`. Em `mode: "interpret"` ou `"auto"` (antes do threshold), usa interpreter generator (mesmo behavior, sem unrolled performance).
884
+
885
+ ---
886
+
731
887
  ## Error Handling
732
888
 
733
- The engine **never throws** during evaluation. All errors are collected:
889
+ The engine **never throws** during evaluation. All runtime errors are collected:
734
890
 
735
891
  | Error source | Behavior |
736
892
  |-------------|----------|
@@ -740,9 +896,12 @@ The engine **never throws** during evaluation. All errors are collected:
740
896
  | `onRulesComplete` throws | Silenced |
741
897
  | Middleware throws | Error collected, invoke skipped, next rule |
742
898
  | ActionEngine invoke errors | Directive errors accumulated in counters |
899
+ | Hidden action id missing at invoke time | Pipeline aborts with `abortedBy: "action-not-found"`, `success: false` |
743
900
  | Sub-rule `when()` throws | Error collected, sub-rule skipped |
744
901
  | `maxSubRuleDepth` exceeded | Error collected, sub-tree skipped (no abort) |
745
902
 
903
+ `register()` follows different rules — see [Registration](#registration). Structural errors at boot (missing handler) throw fail-fast.
904
+
746
905
  ### Inspecting errors
747
906
 
748
907
  ```typescript
package/dist/index.cjs CHANGED
@@ -1,5 +1,9 @@
1
- 'use strict';var core=require('@statedelta-actions/core');function M(r,t,e,i,o,h,b,s,u){if(s>=u)return o.push({ruleIndex:h,error:`maxSubRuleDepth (${u}) exceeded`}),i.errors++,false;for(let c=0;c<r.length;c++){let a=r[c];if(a.definition.when){let d;try{d=a.definition.when(t);}catch(g){o.push({ruleIndex:h,error:String(g)}),i.errors++;continue}if(!d)continue}if(a.actionId){let d=e.invoke(a.actionId,b);if(i.directivesApplied+=d.appliedCount,i.directivesSkipped+=d.skippedCount,i.errors+=d.errors.length,d.aborted)return true}if(a.subRules&&a.subRules.length>0&&M(a.subRules,t,e,i,o,h,b,s+1,u))return true}return false}async function $(r,t,e,i,o,h,b,s,u){if(s>=u)return o.push({ruleIndex:h,error:`maxSubRuleDepth (${u}) exceeded`}),i.errors++,false;for(let c=0;c<r.length;c++){let a=r[c];if(a.definition.when){let d;try{d=a.definition.when(t);}catch(g){o.push({ruleIndex:h,error:String(g)}),i.errors++;continue}if(!d)continue}if(a.actionId){let d=await e.invokeAsync(a.actionId,b);if(i.directivesApplied+=d.appliedCount,i.directivesSkipped+=d.skippedCount,i.errors+=d.errors.length,d.aborted)return true}if(a.subRules&&a.subRules.length>0&&await $(a.subRules,t,e,i,o,h,b,s+1,u))return true}return false}function V(){return r=>({$invoker:{ruleId:r.id,priority:r.priority,tags:r.tags??[]}})}function D(r,t,e,i){let o=i?Object.assign({},i):{};for(let h of r)Object.assign(o,h(t,e,o));return o}function L(){return {rulesEvaluated:0,rulesMatched:0,rulesSkipped:0,directivesApplied:0,directivesSkipped:0,subRunsCreated:0,errors:0}}function H(r,t,e,i,o,h,b,s,u,c){return {success:r,aborted:t,abortedBy:e,matched:i,skipped:o,notMatched:h,errors:b,processedCount:s,totalCount:u,counters:c}}function W(r,t){let e=r.filledNames.has("beforeRule"),i=r.filledNames.has("afterRule"),o=r.filledNames.has("onRulesComplete"),h=e||i;return function(s,u,c,a,d){let g=s.length,m=[],n=[],A=[],v=[],p=L(),T=a.length>0,C=true,x=false,_,y=g;c.setContext(u);let k=h?{ctx:u,counters:p}:void 0;for(let f=0;f<g;f++){let R=s[f],E=R.definition.id;if(p.rulesEvaluated++,e)try{let l=d.beforeRule(R.definition,k);if(l==="skip"){n.push(E),p.rulesSkipped++;continue}if(l==="abort"){C=!1,x=!0,_="beforeRule",y=f+1;break}}catch(l){v.push({ruleIndex:f,error:`beforeRule: ${l}`}),p.errors++;}let w;try{w=R.definition.when(u);}catch(l){v.push({ruleIndex:f,error:String(l)}),A.push(E),p.errors++;continue}if(!w){A.push(E);continue}m.push(E),p.rulesMatched++;let S;if(T)try{S=D(a,R.definition,u);}catch(l){v.push({ruleIndex:f,error:`Middleware: ${l}`}),p.errors++;continue}if(R.actionId){let l=c.invoke(R.actionId,S);if(p.directivesApplied+=l.appliedCount,p.directivesSkipped+=l.skippedCount,p.errors+=l.errors.length,i)try{if(d.afterRule(R.definition,l,k)==="abort"){C=!1,x=!0,_="afterRule",y=f+1;break}}catch{}if(l.aborted){C=l.abortedBy==="halt",x=true,_=l.abortedBy,y=f+1;break}}if(R.subRules&&R.subRules.length>0&&M(R.subRules,u,c,p,v,f,S,0,t)){C=false,x=true,_="sub-rule",y=f+1;break}}let I=H(C,x,_,m,n,A,v,y,g,p);if(o)try{d.onRulesComplete(I);}catch{}return I}}function J(r,t){let e=r.filledNames.has("beforeRule"),i=r.filledNames.has("afterRule"),o=r.filledNames.has("onRulesComplete"),h=e||i;return async function(s,u,c,a,d){let g=s.length,m=[],n=[],A=[],v=[],p=L(),T=a.length>0,C=true,x=false,_,y=g;c.setContext(u);let k=h?{ctx:u,counters:p}:void 0;for(let f=0;f<g;f++){let R=s[f],E=R.definition.id;if(p.rulesEvaluated++,e)try{let l=await d.beforeRule(R.definition,k);if(l==="skip"){n.push(E),p.rulesSkipped++;continue}if(l==="abort"){C=!1,x=!0,_="beforeRule",y=f+1;break}}catch(l){v.push({ruleIndex:f,error:`beforeRule: ${l}`}),p.errors++;}let w;try{w=R.definition.when(u);}catch(l){v.push({ruleIndex:f,error:String(l)}),A.push(E),p.errors++;continue}if(!w){A.push(E);continue}m.push(E),p.rulesMatched++;let S;if(T)try{S=D(a,R.definition,u);}catch(l){v.push({ruleIndex:f,error:`Middleware: ${l}`}),p.errors++;continue}if(R.actionId){let l=await c.invokeAsync(R.actionId,S);if(p.directivesApplied+=l.appliedCount,p.directivesSkipped+=l.skippedCount,p.errors+=l.errors.length,i)try{if(await d.afterRule(R.definition,l,k)==="abort"){C=!1,x=!0,_="afterRule",y=f+1;break}}catch{}if(l.aborted){C=l.abortedBy==="halt",x=true,_=l.abortedBy,y=f+1;break}}if(R.subRules&&R.subRules.length>0&&await $(R.subRules,u,c,p,v,f,S,0,t)){C=false,x=true,_="sub-rule",y=f+1;break}}let I=H(C,x,_,m,n,A,v,y,g,p);if(o)try{await d.onRulesComplete(I);}catch{}return I}}function O(r,t,e){return t?J(r,e):W(r,e)}function B(r,t,e,i,o,h,b){r.push(`{const _er={success:${t},aborted:true,abortedBy:${e},matched,skipped,notMatched,errors,processedCount:${i},totalCount:${o},counters};`),h&&r.push(`try{${b}_hookOnComplete(_er);}catch(_e){}`),r.push("return _er;}");}function j(r,t,e,i){let{filledNames:o,asyncNames:h}=r,b=y=>o.has(y),s=y=>h.has(y)?"await ":"",u=b("beforeRule"),c=b("afterRule"),a=b("onRulesComplete"),d=s("beforeRule"),g=s("afterRule"),m=s("onRulesComplete"),n=[];n.push("const len=rules.length;"),n.push("const matched=[];const skipped=[];const notMatched=[];"),n.push("const errors=[];"),n.push("const counters={rulesEvaluated:0,rulesMatched:0,rulesSkipped:0,directivesApplied:0,directivesSkipped:0,subRunsCreated:0,errors:0};"),n.push("ae.setContext(ctx);"),(u||c)&&n.push("const evalCtx={ctx,counters};"),u&&n.push("const _hookBefore=hooks.beforeRule;"),c&&n.push("const _hookAfter=hooks.afterRule;"),a&&n.push("const _hookOnComplete=hooks.onRulesComplete;"),n.push("for(let i=0;i<len;i++){"),n.push("const stored=rules[i];"),n.push("const _rid=stored.definition.id;"),n.push("counters.rulesEvaluated++;"),u&&(n.push("try{"),n.push(`const _bd=${d}_hookBefore(stored.definition,evalCtx);`),n.push('if(_bd==="skip"){skipped.push(_rid);counters.rulesSkipped++;continue;}'),n.push('if(_bd==="abort")'),B(n,"false",'"beforeRule"',"i+1","len",a,m),n.push('}catch(_e){errors.push({ruleIndex:i,error:"beforeRule: "+_e});counters.errors++;}')),n.push("let ev;"),n.push("try{ev=stored.definition.when(ctx);}catch(_e){errors.push({ruleIndex:i,error:String(_e)});notMatched.push(_rid);counters.errors++;continue;}"),n.push("if(!ev){notMatched.push(_rid);continue;}"),n.push("matched.push(_rid);counters.rulesMatched++;"),t&&(n.push("let params;"),n.push('try{params=$.runMw(mw,stored.definition,ctx);}catch(_e){errors.push({ruleIndex:i,error:"Middleware: "+_e});counters.errors++;continue;}'));let A=t?",params":"",v=e?`await ae.invokeAsync(stored.actionId${A})`:`ae.invoke(stored.actionId${A})`;n.push("if(stored.actionId){"),n.push(`const ir=${v};`),n.push("counters.directivesApplied+=ir.appliedCount;counters.directivesSkipped+=ir.skippedCount;counters.errors+=ir.errors.length;"),c&&(n.push("try{"),n.push(`const _ad=${g}_hookAfter(stored.definition,ir,evalCtx);`),n.push('if(_ad==="abort")'),B(n,"false",'"afterRule"',"i+1","len",a,m),n.push("}catch(_e){}")),n.push("if(ir.aborted)"),B(n,'ir.abortedBy==="halt"',"ir.abortedBy","i+1","len",a,m),n.push("}");let p=t?"params":"undefined";n.push("if(stored.subRules&&stored.subRules.length>0){"),n.push(`if(${e?"await ":""}$.evalSub(stored.subRules,ctx,ae,counters,errors,i,${p},0,$.maxDepth))`),B(n,"false",'"sub-rule"',"i+1","len",a,m),n.push("}"),n.push("}"),n.push("const _r={success:true,aborted:false,abortedBy:undefined,matched,skipped,notMatched,errors,processedCount:len,totalCount:len,counters};"),a&&n.push(`try{${m}_hookOnComplete(_r);}catch(_e){}`),n.push("return _r;");let T=n.join(`
2
- `),C=e?"async ":"",x=new Function("rules","ctx","ae","mw","hooks","$",`"use strict";
3
- return(${C}()=>{
4
- ${T}
5
- })();`),_={maxDepth:i};return _.evalSub=e?$:M,t&&(_.runMw=D),function(k,I,f,R,E){return x(k,I,f,R,E,_)}}function P(r){if(!r.id||typeof r.id!="string")return {ruleId:r.id??"(missing)",code:"INVALID_RULE",message:"rule must have a string id"};if(typeof r.priority!="number")return {ruleId:r.id,code:"INVALID_RULE",message:"rule must have a numeric priority"};if(typeof r.when!="function")return {ruleId:r.id,code:"INVALID_RULE",message:"rule must have a when function"};let t=Array.isArray(r.then)&&r.then.length>0,e=Array.isArray(r.rules)&&r.rules.length>0;return !t&&!e?{ruleId:r.id,code:"INVALID_RULE",message:"rule must have then or sub-rules (or both)"}:null}function U(r,t){let e=`${t}.${r.id??"(missing)"}`;if(!r.id||typeof r.id!="string")return {ruleId:e,code:"INVALID_RULE",message:"sub-rule must have a string id"};let i=Array.isArray(r.then)&&r.then.length>0,o=Array.isArray(r.rules)&&r.rules.length>0;return !i&&!o?{ruleId:e,code:"INVALID_RULE",message:"sub-rule must have then or sub-rules (or both)"}:null}var N=()=>{},F=class{_actionEngine;_middleware;_ruleHooks;_isAsync;_maxSubRuleDepth;_requestedMode;_ruleHookAnalysis;_ruleEvaluator;_mode;_maybeAutoPromote;_ruleRegistry=new Map;_rules=[];_batch=null;constructor(t){if(this._actionEngine=t.actionEngine,this._middleware=t.middleware??[],this._ruleHooks=t.ruleHooks??{},this._maxSubRuleDepth=t.maxSubRuleDepth??10,this._requestedMode=t.mode??"auto",this._ruleHookAnalysis=core.analyzeSlots(this._ruleHooks,core.RULE_SLOT_NAMES),this._isAsync=this._ruleHookAnalysis.hasAnyAsync||this._actionEngine.isAsync,this._requestedMode==="jit")this._ruleEvaluator=this._buildJitRule(),this._mode="jit",this._maybeAutoPromote=N;else if(this._ruleEvaluator=O(this._ruleHookAnalysis,this._isAsync,this._maxSubRuleDepth),this._mode="interpret",this._requestedMode==="auto"){let e=0,i=t.autoJitThreshold??8;this._maybeAutoPromote=()=>{++e>=i&&this._promote();};}else this._maybeAutoPromote=N;}get actionEngine(){return this._actionEngine}get isAsync(){return this._isAsync}get compilationMode(){return this._mode}get size(){return this._rules.length}has(t){return this._ruleRegistry.has(t)}register(t){let e=[],i=[],o=[];for(let s of t){let u=P(s);if(u){i.push(u);continue}if(this._ruleRegistry.has(s.id)){i.push({ruleId:s.id,code:"DUPLICATE_ID",message:`rule "${s.id}" is already registered`});continue}let c=`rule:${s.id}`,a=Array.isArray(s.then)&&s.then.length>0,d=a?c:"",g=Array.isArray(s.rules)&&s.rules.length>0?this._collectSubRules(c,s.rules,i,o):void 0,m={definition:s,actionId:d,priority:s.priority,subRules:g?.length?g:void 0};if(this._ruleRegistry.set(s.id,m),Q(this._rules,m),a){let n=["rule"];s.tags&&n.push(...s.tags),o.push({id:d,tags:n,directives:s.then,declarations:s.declarations});}e.push(s.id);}let h=[];if(o.length>0){let s=this._actionEngine.register(o);for(let u of s.errors){let c=this._actionIdToRuleId(u.actionId);i.push({ruleId:c??u.actionId,code:u.code??"ACTION_ERROR",message:u.error});}h=s.warnings;}let b={registered:e,errors:i,warnings:h};return this._batch&&(this._batch.registered.push(...e),this._batch.errors.push(...i),this._batch.warnings.push(...h)),b}unregister(t){let e=this._ruleRegistry.get(t);return e?(this._ruleRegistry.delete(t),X(this._rules,e),e.actionId&&this._actionEngine.unregister(e.actionId),e.subRules&&this._unregisterSubRules(e.subRules),true):false}beginBatch(){this._batch||(this._batch={depth:0,registered:[],errors:[],warnings:[]}),this._batch.depth++,this._actionEngine.beginBatch();}endBatch(){if(!this._batch||this._batch.depth<=0)throw new Error("endBatch() called without matching beginBatch()");this._batch.depth--;let t=this._actionEngine.endBatch();if(this._batch.depth>0)return {registered:[],errors:[],warnings:[]};let e=this._batch;for(let o of t.errors){let h=this._actionIdToRuleId(o.actionId);e.errors.push({ruleId:h??o.actionId,code:o.code??"ACTION_ERROR",message:o.error});}e.warnings.push(...t.warnings);let i={registered:e.registered,errors:e.errors,warnings:e.warnings};return this._batch=null,i}batch(t){this.beginBatch();try{return t(this),this.endBatch()}catch(e){try{this.endBatch();}catch{}throw e}}evaluate(t){if(this._isAsync)throw new Error("Cannot call evaluate() with async hooks. Use evaluateAsync() instead.");let e=this._ruleEvaluator(this._rules,t,this._actionEngine,this._middleware,this._ruleHooks);return this._maybeAutoPromote(),e}async evaluateAsync(t){let e=await this._ruleEvaluator(this._rules,t,this._actionEngine,this._middleware,this._ruleHooks);return this._maybeAutoPromote(),e}compile(){this._requestedMode!=="interpret"&&this._mode!=="jit"&&this._promote();}_collectSubRules(t,e,i,o){let h=[],b=this._actionIdToRuleId(t);for(let s of e){let u=U(s,b);if(u){i.push(u);continue}let c=`${t}.${s.id}`,a=`${b}.${s.id}`,d=Array.isArray(s.then)&&s.then.length>0,g=Array.isArray(s.rules)&&s.rules.length>0?this._collectSubRules(c,s.rules,i,o):void 0,m={definition:s,actionId:d?c:"",subRules:g?.length?g:void 0};if(d){let n=["rule"];s.tags&&n.push(...s.tags),o.push({id:c,tags:n,directives:s.then,declarations:s.declarations});}this._ruleRegistry.set(a,m),h.push(m);}return h}_unregisterSubRules(t){for(let e of t){if(e.actionId){let i=this._actionIdToRuleId(e.actionId);i&&this._ruleRegistry.delete(i),this._actionEngine.unregister(e.actionId);}e.subRules&&this._unregisterSubRules(e.subRules);}}_actionIdToRuleId(t){return t.startsWith("rule:")?t.slice(5):null}_promote(){this._ruleEvaluator=this._buildJitRule(),this._mode="jit",this._maybeAutoPromote=N;}_buildJitRule(){return j(this._ruleHookAnalysis,this._middleware.length>0,this._isAsync,this._maxSubRuleDepth)}};function K(r){return new F(r)}function Q(r,t){let e=0,i=r.length;for(;e<i;){let o=e+i>>>1;r[o].priority>=t.priority?e=o+1:i=o;}r.splice(e,0,t);}function X(r,t){let e=r.indexOf(t);return e===-1?false:(r.splice(e,1),true)}var Y={analyze:()=>({capabilities:["halt"],dependencies:[]}),execute:()=>({ok:true,halt:true})};exports.HALT_HANDLER=Y;exports.createInvokerMiddleware=V;exports.createRuleEngine=K;
1
+ 'use strict';var core=require('@statedelta-actions/core');function B(n,r,t,o,c,d,b,R,a){if(R>=a)return c.push({ruleIndex:d,error:`maxSubRuleDepth (${a}) exceeded`}),o.errors++,false;for(let u=0;u<n.length;u++){let s=n[u];if(s.definition.when){let l;try{l=s.definition.when(r);}catch(v){c.push({ruleIndex:d,error:String(v)}),o.errors++;continue}if(!l)continue}if(s.actionId){let l=t.invoke(s.actionId,b);if(o.directivesApplied+=l.appliedCount,o.directivesSkipped+=l.skippedCount,o.errors+=l.errors.length,l.aborted)return true}if(s.subRules&&s.subRules.length>0&&B(s.subRules,r,t,o,c,d,b,R+1,a))return true}return false}async function F(n,r,t,o,c,d,b,R,a){if(R>=a)return c.push({ruleIndex:d,error:`maxSubRuleDepth (${a}) exceeded`}),o.errors++,false;for(let u=0;u<n.length;u++){let s=n[u];if(s.definition.when){let l;try{l=s.definition.when(r);}catch(v){c.push({ruleIndex:d,error:String(v)}),o.errors++;continue}if(!l)continue}if(s.actionId){let l=await t.invokeAsync(s.actionId,b);if(o.directivesApplied+=l.appliedCount,o.directivesSkipped+=l.skippedCount,o.errors+=l.errors.length,l.aborted)return true}if(s.subRules&&s.subRules.length>0&&await F(s.subRules,r,t,o,c,d,b,R+1,a))return true}return false}function Q(){return n=>({$invoker:{ruleId:n.id,priority:n.priority,tags:n.tags??[]}})}function $(n,r,t,o){let c=o?Object.assign({},o):{};for(let d of n)Object.assign(c,d(r,t,c));return c}function q(){return {rulesEvaluated:0,rulesMatched:0,rulesSkipped:0,directivesApplied:0,directivesSkipped:0,subRunsCreated:0,errors:0}}function U(n,r,t,o,c,d,b,R,a,u){return {success:n,aborted:r,abortedBy:t,matched:o,skipped:c,notMatched:d,errors:b,processedCount:R,totalCount:a,counters:u}}function X(n,r){let t=n.filledNames.has("beforeRule"),o=n.filledNames.has("afterRule"),c=n.filledNames.has("onRulesComplete"),d=t||o;return function(R,a,u,s,l){let v=R.length,_=[],e=[],A=[],y=[],h=q(),S=s.length>0,I=true,C=false,g,m=v;u.setContext(a);let E=d?{ctx:a,counters:h}:void 0;for(let f=0;f<v;f++){let p=R[f],k=p.definition.id;if(h.rulesEvaluated++,t)try{let i=l.beforeRule(p.definition,E);if(i==="skip"){e.push(k),h.rulesSkipped++;continue}if(i==="abort"){I=!1,C=!0,g="beforeRule",m=f+1;break}}catch(i){y.push({ruleIndex:f,error:`beforeRule: ${i}`}),h.errors++;}let T;try{T=p.definition.when(a);}catch(i){y.push({ruleIndex:f,error:String(i)}),A.push(k),h.errors++;continue}if(!T){A.push(k);continue}_.push(k),h.rulesMatched++;let x;if(S)try{x=$(s,p.definition,a);}catch(i){y.push({ruleIndex:f,error:`Middleware: ${i}`}),h.errors++;continue}if(p.actionId){let i=u.invoke(p.actionId,x);if(h.directivesApplied+=i.appliedCount,h.directivesSkipped+=i.skippedCount,h.errors+=i.errors.length,o)try{if(l.afterRule(p.definition,i,E)==="abort"){I=!1,C=!0,g="afterRule",m=f+1;break}}catch{}if(i.aborted){I=i.abortedBy==="halt",C=true,g=i.abortedBy,m=f+1;break}}if(p.subRules&&p.subRules.length>0&&B(p.subRules,a,u,h,y,f,x,0,r)){I=false,C=true,g="sub-rule",m=f+1;break}}let w=U(I,C,g,_,e,A,y,m,v,h);if(c)try{l.onRulesComplete(w);}catch{}return w}}function Y(n,r){let t=n.filledNames.has("beforeRule"),o=n.filledNames.has("afterRule"),c=n.filledNames.has("onRulesComplete"),d=t||o;return async function(R,a,u,s,l){let v=R.length,_=[],e=[],A=[],y=[],h=q(),S=s.length>0,I=true,C=false,g,m=v;u.setContext(a);let E=d?{ctx:a,counters:h}:void 0;for(let f=0;f<v;f++){let p=R[f],k=p.definition.id;if(h.rulesEvaluated++,t)try{let i=await l.beforeRule(p.definition,E);if(i==="skip"){e.push(k),h.rulesSkipped++;continue}if(i==="abort"){I=!1,C=!0,g="beforeRule",m=f+1;break}}catch(i){y.push({ruleIndex:f,error:`beforeRule: ${i}`}),h.errors++;}let T;try{T=p.definition.when(a);}catch(i){y.push({ruleIndex:f,error:String(i)}),A.push(k),h.errors++;continue}if(!T){A.push(k);continue}_.push(k),h.rulesMatched++;let x;if(S)try{x=$(s,p.definition,a);}catch(i){y.push({ruleIndex:f,error:`Middleware: ${i}`}),h.errors++;continue}if(p.actionId){let i=await u.invokeAsync(p.actionId,x);if(h.directivesApplied+=i.appliedCount,h.directivesSkipped+=i.skippedCount,h.errors+=i.errors.length,o)try{if(await l.afterRule(p.definition,i,E)==="abort"){I=!1,C=!0,g="afterRule",m=f+1;break}}catch{}if(i.aborted){I=i.abortedBy==="halt",C=true,g=i.abortedBy,m=f+1;break}}if(p.subRules&&p.subRules.length>0&&await F(p.subRules,a,u,h,y,f,x,0,r)){I=false,C=true,g="sub-rule",m=f+1;break}}let w=U(I,C,g,_,e,A,y,m,v,h);if(c)try{await l.onRulesComplete(w);}catch{}return w}}function O(n,r,t){return r?Y(n,t):X(n,t)}function G(){return {rulesEvaluated:0,rulesMatched:0,rulesSkipped:0,directivesApplied:0,directivesSkipped:0,subRunsCreated:0,errors:0}}function V(n,r,t,o,c,d,b,R,a,u){return {success:n,aborted:r,abortedBy:t,matched:o,skipped:c,notMatched:d,errors:b,processedCount:R,totalCount:a,counters:u}}function Z(n){let r=n.filledNames.has("beforeRule"),t=n.filledNames.has("afterRule"),o=n.filledNames.has("onRulesComplete"),c=r||t;return function*(b,R,a,u,s,l){let v=b.length,_=[],e=[],A=[],y=[],h=G(),S=u.length>0,I=true,C=false,g,m=v;a.setContext(R);let E=c?{ctx:R,counters:h}:void 0;for(let f=0;f<v;f++){let p=b[f],k=p.definition.id;if(h.rulesEvaluated++,r)try{let i=s.beforeRule(p.definition,E);if(i==="skip"){e.push(k),h.rulesSkipped++;continue}if(i==="abort"){I=!1,C=!0,g="beforeRule",m=f+1;break}}catch(i){y.push({ruleIndex:f,error:`beforeRule: ${i}`}),h.errors++;}let T;try{T=p.definition.when(R);}catch(i){y.push({ruleIndex:f,error:String(i)}),A.push(k),h.errors++;continue}if(!T){A.push(k);continue}_.push(k),h.rulesMatched++;let x;if(S)try{x=$(u,p.definition,R);}catch(i){y.push({ruleIndex:f,error:`Middleware: ${i}`}),h.errors++;continue}if(p.actionId){let i;if(p.isInteractive?i=yield*a.invokeInteractive(p.actionId,x):i=a.invoke(p.actionId,x),h.directivesApplied+=i.appliedCount,h.directivesSkipped+=i.skippedCount,h.errors+=i.errors.length,t)try{if(s.afterRule(p.definition,i,E)==="abort"){I=!1,C=!0,g="afterRule",m=f+1;break}}catch{}if(i.aborted){I=i.abortedBy==="halt",C=true,g=i.abortedBy,m=f+1;break}}if(p.subRules&&p.subRules.length>0&&(yield*D(p.subRules,R,a,h,y,f,x,0,l))){I=false,C=true,g="sub-rule",m=f+1;break}}let w=V(I,C,g,_,e,A,y,m,v,h);if(o)try{s.onRulesComplete(w);}catch{}return w}}function ee(n){let r=n.filledNames.has("beforeRule"),t=n.filledNames.has("afterRule"),o=n.filledNames.has("onRulesComplete"),c=r||t;return async function*(b,R,a,u,s,l){let v=b.length,_=[],e=[],A=[],y=[],h=G(),S=u.length>0,I=true,C=false,g,m=v;a.setContext(R);let E=c?{ctx:R,counters:h}:void 0;for(let f=0;f<v;f++){let p=b[f],k=p.definition.id;if(h.rulesEvaluated++,r)try{let i=await s.beforeRule(p.definition,E);if(i==="skip"){e.push(k),h.rulesSkipped++;continue}if(i==="abort"){I=!1,C=!0,g="beforeRule",m=f+1;break}}catch(i){y.push({ruleIndex:f,error:`beforeRule: ${i}`}),h.errors++;}let T;try{T=p.definition.when(R);}catch(i){y.push({ruleIndex:f,error:String(i)}),A.push(k),h.errors++;continue}if(!T){A.push(k);continue}_.push(k),h.rulesMatched++;let x;if(S)try{x=$(u,p.definition,R);}catch(i){y.push({ruleIndex:f,error:`Middleware: ${i}`}),h.errors++;continue}if(p.actionId){let i;if(p.isInteractive?i=yield*a.invokeInteractive(p.actionId,x):p.isAsync?i=await a.invokeAsync(p.actionId,x):i=a.invoke(p.actionId,x),h.directivesApplied+=i.appliedCount,h.directivesSkipped+=i.skippedCount,h.errors+=i.errors.length,t)try{if(await s.afterRule(p.definition,i,E)==="abort"){I=!1,C=!0,g="afterRule",m=f+1;break}}catch{}if(i.aborted){I=i.abortedBy==="halt",C=true,g=i.abortedBy,m=f+1;break}}if(p.subRules&&p.subRules.length>0&&(yield*N(p.subRules,R,a,h,y,f,x,0,l))){I=false,C=true,g="sub-rule",m=f+1;break}}let w=V(I,C,g,_,e,A,y,m,v,h);if(o)try{await s.onRulesComplete(w);}catch{}return w}}function*D(n,r,t,o,c,d,b,R,a){if(R>=a)return c.push({ruleIndex:d,error:`maxSubRuleDepth (${a}) exceeded`}),o.errors++,false;for(let u=0;u<n.length;u++){let s=n[u];if(s.definition.when){let l;try{l=s.definition.when(r);}catch(v){c.push({ruleIndex:d,error:String(v)}),o.errors++;continue}if(!l)continue}if(s.actionId){let l;if(s.isInteractive?l=yield*t.invokeInteractive(s.actionId,b):l=t.invoke(s.actionId,b),o.directivesApplied+=l.appliedCount,o.directivesSkipped+=l.skippedCount,o.errors+=l.errors.length,l.aborted)return true}if(s.subRules&&s.subRules.length>0&&(yield*D(s.subRules,r,t,o,c,d,b,R+1,a)))return true}return false}async function*N(n,r,t,o,c,d,b,R,a){if(R>=a)return c.push({ruleIndex:d,error:`maxSubRuleDepth (${a}) exceeded`}),o.errors++,false;for(let u=0;u<n.length;u++){let s=n[u];if(s.definition.when){let l;try{l=s.definition.when(r);}catch(v){c.push({ruleIndex:d,error:String(v)}),o.errors++;continue}if(!l)continue}if(s.actionId){let l;if(s.isInteractive?l=yield*t.invokeInteractive(s.actionId,b):s.isAsync?l=await t.invokeAsync(s.actionId,b):l=t.invoke(s.actionId,b),o.directivesApplied+=l.appliedCount,o.directivesSkipped+=l.skippedCount,o.errors+=l.errors.length,l.aborted)return true}if(s.subRules&&s.subRules.length>0&&(yield*N(s.subRules,r,t,o,c,d,b,R+1,a)))return true}return false}function W(n,r){return r?ee(n):Z(n)}function M(n,r,t,o,c,d,b){n.push(`{const _er={success:${r},aborted:true,abortedBy:${t},matched,skipped,notMatched,errors,processedCount:${o},totalCount:${c},counters};`),d&&n.push(`try{${b}_hookOnComplete(_er);}catch(_e){}`),n.push("return _er;}");}function J(n,r,t,o){let{filledNames:c,asyncNames:d}=n,b=m=>c.has(m),R=m=>d.has(m)?"await ":"",a=b("beforeRule"),u=b("afterRule"),s=b("onRulesComplete"),l=R("beforeRule"),v=R("afterRule"),_=R("onRulesComplete"),e=[];e.push("const len=rules.length;"),e.push("const matched=[];const skipped=[];const notMatched=[];"),e.push("const errors=[];"),e.push("const counters={rulesEvaluated:0,rulesMatched:0,rulesSkipped:0,directivesApplied:0,directivesSkipped:0,subRunsCreated:0,errors:0};"),e.push("ae.setContext(ctx);"),(a||u)&&e.push("const evalCtx={ctx,counters};"),a&&e.push("const _hookBefore=hooks.beforeRule;"),u&&e.push("const _hookAfter=hooks.afterRule;"),s&&e.push("const _hookOnComplete=hooks.onRulesComplete;"),e.push("for(let i=0;i<len;i++){"),e.push("const stored=rules[i];"),e.push("const _rid=stored.definition.id;"),e.push("counters.rulesEvaluated++;"),a&&(e.push("try{"),e.push(`const _bd=${l}_hookBefore(stored.definition,evalCtx);`),e.push('if(_bd==="skip"){skipped.push(_rid);counters.rulesSkipped++;continue;}'),e.push('if(_bd==="abort")'),M(e,"false",'"beforeRule"',"i+1","len",s,_),e.push('}catch(_e){errors.push({ruleIndex:i,error:"beforeRule: "+_e});counters.errors++;}')),e.push("let ev;"),e.push("try{ev=stored.definition.when(ctx);}catch(_e){errors.push({ruleIndex:i,error:String(_e)});notMatched.push(_rid);counters.errors++;continue;}"),e.push("if(!ev){notMatched.push(_rid);continue;}"),e.push("matched.push(_rid);counters.rulesMatched++;"),r&&(e.push("let params;"),e.push('try{params=$.runMw(mw,stored.definition,ctx);}catch(_e){errors.push({ruleIndex:i,error:"Middleware: "+_e});counters.errors++;continue;}'));let A=r?",params":"",y=t?`await ae.invokeAsync(stored.actionId${A})`:`ae.invoke(stored.actionId${A})`;e.push("if(stored.actionId){"),e.push(`const ir=${y};`),e.push("counters.directivesApplied+=ir.appliedCount;counters.directivesSkipped+=ir.skippedCount;counters.errors+=ir.errors.length;"),u&&(e.push("try{"),e.push(`const _ad=${v}_hookAfter(stored.definition,ir,evalCtx);`),e.push('if(_ad==="abort")'),M(e,"false",'"afterRule"',"i+1","len",s,_),e.push("}catch(_e){}")),e.push("if(ir.aborted)"),M(e,'ir.abortedBy==="halt"',"ir.abortedBy","i+1","len",s,_),e.push("}");let h=r?"params":"undefined";e.push("if(stored.subRules&&stored.subRules.length>0){"),e.push(`if(${t?"await ":""}$.evalSub(stored.subRules,ctx,ae,counters,errors,i,${h},0,$.maxDepth))`),M(e,"false",'"sub-rule"',"i+1","len",s,_),e.push("}"),e.push("}"),e.push("const _r={success:true,aborted:false,abortedBy:undefined,matched,skipped,notMatched,errors,processedCount:len,totalCount:len,counters};"),s&&e.push(`try{${_}_hookOnComplete(_r);}catch(_e){}`),e.push("return _r;");let S=e.join(`
2
+ `),I=t?"async ":"",C=new Function("rules","ctx","ae","mw","hooks","$",`"use strict";
3
+ return(${I}()=>{
4
+ ${S}
5
+ })();`),g={maxDepth:o};return g.evalSub=t?F:B,r&&(g.runMw=$),function(E,w,f,p,k){return C(E,w,f,p,k,g)}}function P(n,r,t,o){let{filledNames:c,asyncNames:d}=n,b=g=>c.has(g),R=g=>d.has(g)?"await ":"",a=b("beforeRule"),u=b("afterRule"),s=b("onRulesComplete"),l=R("beforeRule"),v=R("afterRule"),_=R("onRulesComplete"),e=[];e.push("const len=rules.length;"),e.push("const matched=[];const skipped=[];const notMatched=[];"),e.push("const errors=[];"),e.push("const counters={rulesEvaluated:0,rulesMatched:0,rulesSkipped:0,directivesApplied:0,directivesSkipped:0,subRunsCreated:0,errors:0};"),e.push("ae.setContext(ctx);"),(a||u)&&e.push("const evalCtx={ctx,counters};"),a&&e.push("const _hookBefore=hooks.beforeRule;"),u&&e.push("const _hookAfter=hooks.afterRule;"),s&&e.push("const _hookOnComplete=hooks.onRulesComplete;"),e.push("for(let i=0;i<len;i++){"),e.push("const stored=rules[i];"),e.push("const _rid=stored.definition.id;"),e.push("counters.rulesEvaluated++;"),a&&(e.push("try{"),e.push(`const _bd=${l}_hookBefore(stored.definition,evalCtx);`),e.push('if(_bd==="skip"){skipped.push(_rid);counters.rulesSkipped++;continue;}'),e.push('if(_bd==="abort")'),M(e,"false",'"beforeRule"',"i+1","len",s,_),e.push('}catch(_e){errors.push({ruleIndex:i,error:"beforeRule: "+_e});counters.errors++;}')),e.push("let ev;"),e.push("try{ev=stored.definition.when(ctx);}catch(_e){errors.push({ruleIndex:i,error:String(_e)});notMatched.push(_rid);counters.errors++;continue;}"),e.push("if(!ev){notMatched.push(_rid);continue;}"),e.push("matched.push(_rid);counters.rulesMatched++;"),r&&(e.push("let params;"),e.push('try{params=$.runMw(mw,stored.definition,ctx);}catch(_e){errors.push({ruleIndex:i,error:"Middleware: "+_e});counters.errors++;continue;}'));let A=r?",params":"";e.push("if(stored.actionId){"),e.push("let ir;"),e.push("if(stored.isInteractive){"),e.push(`ir=yield* ae.invokeInteractive(stored.actionId${A});`),e.push("}else "),t?(e.push("if(stored.isAsync){"),e.push(`ir=await ae.invokeAsync(stored.actionId${A});`),e.push("}else{")):e.push("{"),e.push(`ir=ae.invoke(stored.actionId${A});`),e.push("}"),e.push("counters.directivesApplied+=ir.appliedCount;counters.directivesSkipped+=ir.skippedCount;counters.errors+=ir.errors.length;"),u&&(e.push("try{"),e.push(`const _ad=${v}_hookAfter(stored.definition,ir,evalCtx);`),e.push('if(_ad==="abort")'),M(e,"false",'"afterRule"',"i+1","len",s,_),e.push("}catch(_e){}")),e.push("if(ir.aborted)"),M(e,'ir.abortedBy==="halt"',"ir.abortedBy","i+1","len",s,_),e.push("}");let y=r?"params":"undefined";e.push("if(stored.subRules&&stored.subRules.length>0){"),e.push(`if(yield* $.evalSubInt(stored.subRules,ctx,ae,counters,errors,i,${y},0,$.maxDepth))`),M(e,"false",'"sub-rule"',"i+1","len",s,_),e.push("}"),e.push("}"),e.push("const _r={success:true,aborted:false,abortedBy:undefined,matched,skipped,notMatched,errors,processedCount:len,totalCount:len,counters};"),s&&e.push(`try{${_}_hookOnComplete(_r);}catch(_e){}`),e.push("return _r;");let h=e.join(`
6
+ `),S=t?"async function*()":"function*()",I=new Function("rules","ctx","ae","mw","hooks","$",`"use strict";
7
+ return(${S}{
8
+ ${h}
9
+ })();`),C={maxDepth:o};return C.evalSubInt=t?N:D,r&&(C.runMw=$),function(m,E,w,f,p){return I(m,E,w,f,p,C)}}function z(n){if(!n.id||typeof n.id!="string")return {ruleId:n.id??"(missing)",code:"INVALID_RULE",message:"rule must have a string id"};if(typeof n.priority!="number")return {ruleId:n.id,code:"INVALID_RULE",message:"rule must have a numeric priority"};if(typeof n.when!="function")return {ruleId:n.id,code:"INVALID_RULE",message:"rule must have a when function"};let r=Array.isArray(n.then)&&n.then.length>0,t=Array.isArray(n.rules)&&n.rules.length>0;return !r&&!t?{ruleId:n.id,code:"INVALID_RULE",message:"rule must have then or sub-rules (or both)"}:null}function K(n,r){let t=`${r}.${n.id??"(missing)"}`;if(!n.id||typeof n.id!="string")return {ruleId:t,code:"INVALID_RULE",message:"sub-rule must have a string id"};let o=Array.isArray(n.then)&&n.then.length>0,c=Array.isArray(n.rules)&&n.rules.length>0;return !o&&!c?{ruleId:t,code:"INVALID_RULE",message:"sub-rule must have then or sub-rules (or both)"}:null}var L=()=>{},j=class{_actionEngine;_middleware;_ruleHooks;_maxSubRuleDepth;_requestedMode;_ruleHookAnalysis;_hasAnyInteractiveRule=false;_isAsync;_ruleEvaluator;_mode;_maybeAutoPromote;_interactiveEvaluator=null;_interactiveEvaluatorIsAsync=false;_ruleRegistry=new Map;_rules=[];_batch=null;constructor(r){if(this._actionEngine=r.actionEngine,this._middleware=r.middleware??[],this._ruleHooks=r.ruleHooks??{},this._maxSubRuleDepth=r.maxSubRuleDepth??10,this._requestedMode=r.mode??"auto",this._ruleHookAnalysis=core.analyzeSlots(this._ruleHooks,core.RULE_SLOT_NAMES),this._isAsync=this._ruleHookAnalysis.hasAnyAsync,this._requestedMode==="jit")this._ruleEvaluator=this._buildJitRule(),this._mode="jit",this._maybeAutoPromote=L;else if(this._ruleEvaluator=O(this._ruleHookAnalysis,this._isAsync,this._maxSubRuleDepth),this._mode="interpret",this._requestedMode==="auto"){let t=0,o=r.autoJitThreshold??8;this._maybeAutoPromote=()=>{++t>=o&&this._promote();};}else this._maybeAutoPromote=L;}get actionEngine(){return this._actionEngine}get isAsync(){return this._isAsync}get isInteractive(){return this._hasAnyInteractiveRule}get compilationMode(){return this._mode}get size(){return this._rules.length}has(r){return this._ruleRegistry.has(r)}register(r){let t=[],o=[],c=[],d=[];for(let u of r){let s=z(u);if(s){t.push(s);continue}if(this._ruleRegistry.has(u.id)||c.some(y=>y.id===u.id)){t.push({ruleId:u.id,code:"DUPLICATE_ID",message:`rule "${u.id}" is already registered`});continue}let l=`rule:${u.id}`,v=Array.isArray(u.then)&&u.then.length>0,_=v?l:"",e=Array.isArray(u.rules)&&u.rules.length>0?this._collectSubRules(l,u.rules,t,o,d):void 0,A={definition:u,actionId:_,priority:u.priority,subRules:e?.length?e:void 0,isAsync:false,isInteractive:false};if(v){let y=["rule"];u.tags&&y.push(...u.tags),o.push({id:_,tags:y,directives:u.then,declarations:u.declarations});}c.push({id:u.id,stored:A});}let b=[];if(o.length>0){let u=this._actionEngine.register(o);for(let s of u.errors){let l=this._actionIdToRuleId(s.actionId);t.push({ruleId:l??s.actionId,code:s.code??"ACTION_ERROR",message:s.error});}b=u.warnings;}let R=[];for(let{id:u,stored:s}of c)this._ruleRegistry.set(u,s),se(this._rules,s),R.push(u);for(let{qualifiedId:u,stored:s}of d)this._ruleRegistry.set(u,s);let a={registered:R,errors:t,warnings:b};return this._batch?(this._batch.registered.push(...R),this._batch.errors.push(...t),this._batch.warnings.push(...b)):R.length>0&&this._refreshRuleFlags(),a}unregister(r){let t=this._ruleRegistry.get(r);return t?(this._ruleRegistry.delete(r),ie(this._rules,t),t.actionId&&this._actionEngine.unregister(t.actionId),t.subRules&&this._unregisterSubRules(t.subRules),this._refreshRuleFlags(),true):false}beginBatch(){this._batch||(this._batch={depth:0,registered:[],errors:[],warnings:[]}),this._batch.depth++,this._actionEngine.beginBatch();}endBatch(){if(!this._batch||this._batch.depth<=0)throw new Error("endBatch() called without matching beginBatch()");this._batch.depth--;let r=this._actionEngine.endBatch();if(this._batch.depth>0)return {registered:[],errors:[],warnings:[]};let t=this._batch;for(let c of r.errors){let d=this._actionIdToRuleId(c.actionId);t.errors.push({ruleId:d??c.actionId,code:c.code??"ACTION_ERROR",message:c.error});}t.warnings.push(...r.warnings);let o={registered:t.registered,errors:t.errors,warnings:t.warnings};return this._batch=null,this._refreshRuleFlags(),o}batch(r){this.beginBatch();try{return r(this),this.endBatch()}catch(t){try{this.endBatch();}catch{}throw t}}evaluate(r){if(this._hasAnyInteractiveRule)throw new Error("Cannot call evaluate() \u2014 at least one rule is interactive (transitively). Use evaluateInteractive() instead.");if(this._isAsync)throw new Error("Cannot call evaluate() with async hooks or async rules. Use evaluateAsync() instead.");let t=this._ruleEvaluator(this._rules,r,this._actionEngine,this._middleware,this._ruleHooks);return this._maybeAutoPromote(),t}async evaluateAsync(r){if(this._hasAnyInteractiveRule)throw new Error("Cannot call evaluateAsync() \u2014 at least one rule is interactive (transitively). Use evaluateInteractive() instead.");let t=await this._ruleEvaluator(this._rules,r,this._actionEngine,this._middleware,this._ruleHooks);return this._maybeAutoPromote(),t}evaluateInteractive(r){if(!this._hasAnyInteractiveRule)throw new Error("Cannot call evaluateInteractive() \u2014 no registered rule is interactive (transitively). Use evaluate() or evaluateAsync() instead.");return (this._interactiveEvaluator===null||this._interactiveEvaluatorIsAsync!==this._isAsync)&&(this._interactiveEvaluator=this._mode==="jit"?P(this._ruleHookAnalysis,this._middleware.length>0,this._isAsync,this._maxSubRuleDepth):W(this._ruleHookAnalysis,this._isAsync),this._interactiveEvaluatorIsAsync=this._isAsync),this._interactiveEvaluator(this._rules,r,this._actionEngine,this._middleware,this._ruleHooks,this._maxSubRuleDepth)}compile(){this._requestedMode!=="interpret"&&this._mode!=="jit"&&this._promote();}_collectSubRules(r,t,o,c,d){let b=[],R=this._actionIdToRuleId(r);for(let a of t){let u=K(a,R);if(u){o.push(u);continue}let s=`${r}.${a.id}`,l=`${R}.${a.id}`,v=Array.isArray(a.then)&&a.then.length>0,_=Array.isArray(a.rules)&&a.rules.length>0?this._collectSubRules(s,a.rules,o,c,d):void 0,e={definition:a,actionId:v?s:"",subRules:_?.length?_:void 0,isAsync:false,isInteractive:false};if(v){let A=["rule"];a.tags&&A.push(...a.tags),c.push({id:s,tags:A,directives:a.then,declarations:a.declarations});}d.push({qualifiedId:l,stored:e}),b.push(e);}return b}_unregisterSubRules(r){for(let t of r){if(t.actionId){let o=this._actionIdToRuleId(t.actionId);o&&this._ruleRegistry.delete(o),this._actionEngine.unregister(t.actionId);}t.subRules&&this._unregisterSubRules(t.subRules);}}_actionIdToRuleId(r){return r.startsWith("rule:")?r.slice(5):null}_refreshRuleFlags(){let r=false,t=false,o=d=>{if(d.actionId?(d.isAsync=this._actionEngine.isActionAsync(d.actionId)??false,d.isInteractive=this._actionEngine.isActionInteractive(d.actionId)??false,d.isAsync&&(r=true),d.isInteractive&&(t=true)):(d.isAsync=false,d.isInteractive=false),d.subRules)for(let b of d.subRules)o(b);};for(let d of this._rules)o(d);this._hasAnyInteractiveRule=t;let c=this._ruleHookAnalysis.hasAnyAsync||r;c!==this._isAsync?(this._isAsync=c,this._rebuildEvaluator()):this._isAsync=c;}_rebuildEvaluator(){this._mode==="jit"?this._ruleEvaluator=this._buildJitRule():this._ruleEvaluator=O(this._ruleHookAnalysis,this._isAsync,this._maxSubRuleDepth);}_promote(){this._ruleEvaluator=this._buildJitRule(),this._mode="jit",this._maybeAutoPromote=L;}_buildJitRule(){return J(this._ruleHookAnalysis,this._middleware.length>0,this._isAsync,this._maxSubRuleDepth)}};function ne(n){return new j(n)}function se(n,r){let t=0,o=n.length;for(;t<o;){let c=t+o>>>1;n[c].priority>=r.priority?t=c+1:o=c;}n.splice(t,0,r);}function ie(n,r){let t=n.indexOf(r);return t===-1?false:(n.splice(t,1),true)}var oe={analyze:()=>({capabilities:["halt"],dependencies:[]}),execute:()=>({ok:true,halt:true})};exports.HALT_HANDLER=oe;exports.createInvokerMiddleware=Q;exports.createRuleEngine=ne;
package/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { Directive, RegisterWarning, RuleError, FrameCounters, HookFn, DirectiveResult } from '@statedelta-actions/core';
1
+ import { Directive, RuleError, FrameCounters, RegisterWarning, HookFn, DirectiveResult } from '@statedelta-actions/core';
2
2
  import { IActionEngine } from '@statedelta-actions/actions';
3
3
 
4
4
  interface SubRuleDefinition<TCtx = unknown> {
@@ -69,11 +69,37 @@ interface RuleEngineConfig<TCtx = unknown> {
69
69
  /** Threshold de evaluate() calls para auto-promote em modo "auto". Default: 8. */
70
70
  autoJitThreshold?: number;
71
71
  }
72
+ /**
73
+ * Sessão de avaliação de rules em modo interactive — retornada por
74
+ * `evaluateInteractive(ctx)`. Drena via `next()` igual a `InteractiveSession`
75
+ * do actions, mas o `done.value` final é `RuleEvaluationResult`.
76
+ */
77
+ interface InteractiveRuleSession extends Iterator<unknown, RuleEvaluationResult, unknown> {
78
+ next(value?: unknown): IteratorResult<unknown, RuleEvaluationResult>;
79
+ return(): IteratorResult<unknown, RuleEvaluationResult>;
80
+ throw(err?: unknown): IteratorResult<unknown, RuleEvaluationResult>;
81
+ [Symbol.iterator](): InteractiveRuleSession;
82
+ }
83
+ interface AsyncInteractiveRuleSession extends AsyncIterator<unknown, RuleEvaluationResult, unknown> {
84
+ next(value?: unknown): Promise<IteratorResult<unknown, RuleEvaluationResult>>;
85
+ return(): Promise<IteratorResult<unknown, RuleEvaluationResult>>;
86
+ throw(err?: unknown): Promise<IteratorResult<unknown, RuleEvaluationResult>>;
87
+ [Symbol.asyncIterator](): AsyncInteractiveRuleSession;
88
+ }
72
89
  interface IRuleEngine<TCtx = unknown> {
73
90
  register(rules: readonly RuleDefinition<TCtx>[]): RuleRegisterResult;
74
91
  unregister(id: string): boolean;
75
92
  evaluate(ctx: TCtx): RuleEvaluationResult;
76
93
  evaluateAsync(ctx: TCtx): Promise<RuleEvaluationResult>;
94
+ /**
95
+ * Avalia rules em modo interactive — retorna iterator drenável.
96
+ * Lança se nenhuma rule registrada é interactive transitivamente, ou se
97
+ * actionEngine não tem `interactive` configurado.
98
+ *
99
+ * Variante async (AsyncInteractiveRuleSession) é retornada quando alguma
100
+ * rule é async transitivamente OU algum hook é async.
101
+ */
102
+ evaluateInteractive(ctx: TCtx): InteractiveRuleSession | AsyncInteractiveRuleSession;
77
103
  beginBatch(): void;
78
104
  endBatch(): RuleRegisterResult;
79
105
  /** Executa fn dentro de um batch, com endBatch() garantido (inclusive em throw). */
@@ -84,6 +110,8 @@ interface IRuleEngine<TCtx = unknown> {
84
110
  has(id: string): boolean;
85
111
  readonly actionEngine: IActionEngine<TCtx>;
86
112
  readonly isAsync: boolean;
113
+ /** Alguma rule registrada é interactive transitivamente? Cached. */
114
+ readonly isInteractive: boolean;
87
115
  readonly compilationMode: "interpret" | "jit";
88
116
  /** Número de rules top-level registradas. */
89
117
  readonly size: number;
@@ -115,4 +143,4 @@ declare const HALT_HANDLER: {
115
143
 
116
144
  declare function createInvokerMiddleware<TCtx>(): RuleMiddleware<TCtx>;
117
145
 
118
- export { HALT_HANDLER, type IRuleEngine, type RuleDefinition, type RuleEngineConfig, type RuleEvaluationContext, type RuleEvaluationResult, type RuleHooks, type RuleMiddleware, type RuleRegisterError, type RuleRegisterResult, type SubRuleDefinition, createInvokerMiddleware, createRuleEngine };
146
+ export { type AsyncInteractiveRuleSession, HALT_HANDLER, type IRuleEngine, type InteractiveRuleSession, type RuleDefinition, type RuleEngineConfig, type RuleEvaluationContext, type RuleEvaluationResult, type RuleHooks, type RuleMiddleware, type RuleRegisterError, type RuleRegisterResult, type SubRuleDefinition, createInvokerMiddleware, createRuleEngine };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Directive, RegisterWarning, RuleError, FrameCounters, HookFn, DirectiveResult } from '@statedelta-actions/core';
1
+ import { Directive, RuleError, FrameCounters, RegisterWarning, HookFn, DirectiveResult } from '@statedelta-actions/core';
2
2
  import { IActionEngine } from '@statedelta-actions/actions';
3
3
 
4
4
  interface SubRuleDefinition<TCtx = unknown> {
@@ -69,11 +69,37 @@ interface RuleEngineConfig<TCtx = unknown> {
69
69
  /** Threshold de evaluate() calls para auto-promote em modo "auto". Default: 8. */
70
70
  autoJitThreshold?: number;
71
71
  }
72
+ /**
73
+ * Sessão de avaliação de rules em modo interactive — retornada por
74
+ * `evaluateInteractive(ctx)`. Drena via `next()` igual a `InteractiveSession`
75
+ * do actions, mas o `done.value` final é `RuleEvaluationResult`.
76
+ */
77
+ interface InteractiveRuleSession extends Iterator<unknown, RuleEvaluationResult, unknown> {
78
+ next(value?: unknown): IteratorResult<unknown, RuleEvaluationResult>;
79
+ return(): IteratorResult<unknown, RuleEvaluationResult>;
80
+ throw(err?: unknown): IteratorResult<unknown, RuleEvaluationResult>;
81
+ [Symbol.iterator](): InteractiveRuleSession;
82
+ }
83
+ interface AsyncInteractiveRuleSession extends AsyncIterator<unknown, RuleEvaluationResult, unknown> {
84
+ next(value?: unknown): Promise<IteratorResult<unknown, RuleEvaluationResult>>;
85
+ return(): Promise<IteratorResult<unknown, RuleEvaluationResult>>;
86
+ throw(err?: unknown): Promise<IteratorResult<unknown, RuleEvaluationResult>>;
87
+ [Symbol.asyncIterator](): AsyncInteractiveRuleSession;
88
+ }
72
89
  interface IRuleEngine<TCtx = unknown> {
73
90
  register(rules: readonly RuleDefinition<TCtx>[]): RuleRegisterResult;
74
91
  unregister(id: string): boolean;
75
92
  evaluate(ctx: TCtx): RuleEvaluationResult;
76
93
  evaluateAsync(ctx: TCtx): Promise<RuleEvaluationResult>;
94
+ /**
95
+ * Avalia rules em modo interactive — retorna iterator drenável.
96
+ * Lança se nenhuma rule registrada é interactive transitivamente, ou se
97
+ * actionEngine não tem `interactive` configurado.
98
+ *
99
+ * Variante async (AsyncInteractiveRuleSession) é retornada quando alguma
100
+ * rule é async transitivamente OU algum hook é async.
101
+ */
102
+ evaluateInteractive(ctx: TCtx): InteractiveRuleSession | AsyncInteractiveRuleSession;
77
103
  beginBatch(): void;
78
104
  endBatch(): RuleRegisterResult;
79
105
  /** Executa fn dentro de um batch, com endBatch() garantido (inclusive em throw). */
@@ -84,6 +110,8 @@ interface IRuleEngine<TCtx = unknown> {
84
110
  has(id: string): boolean;
85
111
  readonly actionEngine: IActionEngine<TCtx>;
86
112
  readonly isAsync: boolean;
113
+ /** Alguma rule registrada é interactive transitivamente? Cached. */
114
+ readonly isInteractive: boolean;
87
115
  readonly compilationMode: "interpret" | "jit";
88
116
  /** Número de rules top-level registradas. */
89
117
  readonly size: number;
@@ -115,4 +143,4 @@ declare const HALT_HANDLER: {
115
143
 
116
144
  declare function createInvokerMiddleware<TCtx>(): RuleMiddleware<TCtx>;
117
145
 
118
- export { HALT_HANDLER, type IRuleEngine, type RuleDefinition, type RuleEngineConfig, type RuleEvaluationContext, type RuleEvaluationResult, type RuleHooks, type RuleMiddleware, type RuleRegisterError, type RuleRegisterResult, type SubRuleDefinition, createInvokerMiddleware, createRuleEngine };
146
+ export { type AsyncInteractiveRuleSession, HALT_HANDLER, type IRuleEngine, type InteractiveRuleSession, type RuleDefinition, type RuleEngineConfig, type RuleEvaluationContext, type RuleEvaluationResult, type RuleHooks, type RuleMiddleware, type RuleRegisterError, type RuleRegisterResult, type SubRuleDefinition, createInvokerMiddleware, createRuleEngine };
package/dist/index.js CHANGED
@@ -1,5 +1,9 @@
1
- import {analyzeSlots,RULE_SLOT_NAMES}from'@statedelta-actions/core';function M(r,t,e,i,o,h,b,s,u){if(s>=u)return o.push({ruleIndex:h,error:`maxSubRuleDepth (${u}) exceeded`}),i.errors++,false;for(let c=0;c<r.length;c++){let a=r[c];if(a.definition.when){let d;try{d=a.definition.when(t);}catch(g){o.push({ruleIndex:h,error:String(g)}),i.errors++;continue}if(!d)continue}if(a.actionId){let d=e.invoke(a.actionId,b);if(i.directivesApplied+=d.appliedCount,i.directivesSkipped+=d.skippedCount,i.errors+=d.errors.length,d.aborted)return true}if(a.subRules&&a.subRules.length>0&&M(a.subRules,t,e,i,o,h,b,s+1,u))return true}return false}async function $(r,t,e,i,o,h,b,s,u){if(s>=u)return o.push({ruleIndex:h,error:`maxSubRuleDepth (${u}) exceeded`}),i.errors++,false;for(let c=0;c<r.length;c++){let a=r[c];if(a.definition.when){let d;try{d=a.definition.when(t);}catch(g){o.push({ruleIndex:h,error:String(g)}),i.errors++;continue}if(!d)continue}if(a.actionId){let d=await e.invokeAsync(a.actionId,b);if(i.directivesApplied+=d.appliedCount,i.directivesSkipped+=d.skippedCount,i.errors+=d.errors.length,d.aborted)return true}if(a.subRules&&a.subRules.length>0&&await $(a.subRules,t,e,i,o,h,b,s+1,u))return true}return false}function V(){return r=>({$invoker:{ruleId:r.id,priority:r.priority,tags:r.tags??[]}})}function D(r,t,e,i){let o=i?Object.assign({},i):{};for(let h of r)Object.assign(o,h(t,e,o));return o}function L(){return {rulesEvaluated:0,rulesMatched:0,rulesSkipped:0,directivesApplied:0,directivesSkipped:0,subRunsCreated:0,errors:0}}function H(r,t,e,i,o,h,b,s,u,c){return {success:r,aborted:t,abortedBy:e,matched:i,skipped:o,notMatched:h,errors:b,processedCount:s,totalCount:u,counters:c}}function W(r,t){let e=r.filledNames.has("beforeRule"),i=r.filledNames.has("afterRule"),o=r.filledNames.has("onRulesComplete"),h=e||i;return function(s,u,c,a,d){let g=s.length,m=[],n=[],A=[],v=[],p=L(),T=a.length>0,C=true,x=false,_,y=g;c.setContext(u);let k=h?{ctx:u,counters:p}:void 0;for(let f=0;f<g;f++){let R=s[f],E=R.definition.id;if(p.rulesEvaluated++,e)try{let l=d.beforeRule(R.definition,k);if(l==="skip"){n.push(E),p.rulesSkipped++;continue}if(l==="abort"){C=!1,x=!0,_="beforeRule",y=f+1;break}}catch(l){v.push({ruleIndex:f,error:`beforeRule: ${l}`}),p.errors++;}let w;try{w=R.definition.when(u);}catch(l){v.push({ruleIndex:f,error:String(l)}),A.push(E),p.errors++;continue}if(!w){A.push(E);continue}m.push(E),p.rulesMatched++;let S;if(T)try{S=D(a,R.definition,u);}catch(l){v.push({ruleIndex:f,error:`Middleware: ${l}`}),p.errors++;continue}if(R.actionId){let l=c.invoke(R.actionId,S);if(p.directivesApplied+=l.appliedCount,p.directivesSkipped+=l.skippedCount,p.errors+=l.errors.length,i)try{if(d.afterRule(R.definition,l,k)==="abort"){C=!1,x=!0,_="afterRule",y=f+1;break}}catch{}if(l.aborted){C=l.abortedBy==="halt",x=true,_=l.abortedBy,y=f+1;break}}if(R.subRules&&R.subRules.length>0&&M(R.subRules,u,c,p,v,f,S,0,t)){C=false,x=true,_="sub-rule",y=f+1;break}}let I=H(C,x,_,m,n,A,v,y,g,p);if(o)try{d.onRulesComplete(I);}catch{}return I}}function J(r,t){let e=r.filledNames.has("beforeRule"),i=r.filledNames.has("afterRule"),o=r.filledNames.has("onRulesComplete"),h=e||i;return async function(s,u,c,a,d){let g=s.length,m=[],n=[],A=[],v=[],p=L(),T=a.length>0,C=true,x=false,_,y=g;c.setContext(u);let k=h?{ctx:u,counters:p}:void 0;for(let f=0;f<g;f++){let R=s[f],E=R.definition.id;if(p.rulesEvaluated++,e)try{let l=await d.beforeRule(R.definition,k);if(l==="skip"){n.push(E),p.rulesSkipped++;continue}if(l==="abort"){C=!1,x=!0,_="beforeRule",y=f+1;break}}catch(l){v.push({ruleIndex:f,error:`beforeRule: ${l}`}),p.errors++;}let w;try{w=R.definition.when(u);}catch(l){v.push({ruleIndex:f,error:String(l)}),A.push(E),p.errors++;continue}if(!w){A.push(E);continue}m.push(E),p.rulesMatched++;let S;if(T)try{S=D(a,R.definition,u);}catch(l){v.push({ruleIndex:f,error:`Middleware: ${l}`}),p.errors++;continue}if(R.actionId){let l=await c.invokeAsync(R.actionId,S);if(p.directivesApplied+=l.appliedCount,p.directivesSkipped+=l.skippedCount,p.errors+=l.errors.length,i)try{if(await d.afterRule(R.definition,l,k)==="abort"){C=!1,x=!0,_="afterRule",y=f+1;break}}catch{}if(l.aborted){C=l.abortedBy==="halt",x=true,_=l.abortedBy,y=f+1;break}}if(R.subRules&&R.subRules.length>0&&await $(R.subRules,u,c,p,v,f,S,0,t)){C=false,x=true,_="sub-rule",y=f+1;break}}let I=H(C,x,_,m,n,A,v,y,g,p);if(o)try{await d.onRulesComplete(I);}catch{}return I}}function O(r,t,e){return t?J(r,e):W(r,e)}function B(r,t,e,i,o,h,b){r.push(`{const _er={success:${t},aborted:true,abortedBy:${e},matched,skipped,notMatched,errors,processedCount:${i},totalCount:${o},counters};`),h&&r.push(`try{${b}_hookOnComplete(_er);}catch(_e){}`),r.push("return _er;}");}function j(r,t,e,i){let{filledNames:o,asyncNames:h}=r,b=y=>o.has(y),s=y=>h.has(y)?"await ":"",u=b("beforeRule"),c=b("afterRule"),a=b("onRulesComplete"),d=s("beforeRule"),g=s("afterRule"),m=s("onRulesComplete"),n=[];n.push("const len=rules.length;"),n.push("const matched=[];const skipped=[];const notMatched=[];"),n.push("const errors=[];"),n.push("const counters={rulesEvaluated:0,rulesMatched:0,rulesSkipped:0,directivesApplied:0,directivesSkipped:0,subRunsCreated:0,errors:0};"),n.push("ae.setContext(ctx);"),(u||c)&&n.push("const evalCtx={ctx,counters};"),u&&n.push("const _hookBefore=hooks.beforeRule;"),c&&n.push("const _hookAfter=hooks.afterRule;"),a&&n.push("const _hookOnComplete=hooks.onRulesComplete;"),n.push("for(let i=0;i<len;i++){"),n.push("const stored=rules[i];"),n.push("const _rid=stored.definition.id;"),n.push("counters.rulesEvaluated++;"),u&&(n.push("try{"),n.push(`const _bd=${d}_hookBefore(stored.definition,evalCtx);`),n.push('if(_bd==="skip"){skipped.push(_rid);counters.rulesSkipped++;continue;}'),n.push('if(_bd==="abort")'),B(n,"false",'"beforeRule"',"i+1","len",a,m),n.push('}catch(_e){errors.push({ruleIndex:i,error:"beforeRule: "+_e});counters.errors++;}')),n.push("let ev;"),n.push("try{ev=stored.definition.when(ctx);}catch(_e){errors.push({ruleIndex:i,error:String(_e)});notMatched.push(_rid);counters.errors++;continue;}"),n.push("if(!ev){notMatched.push(_rid);continue;}"),n.push("matched.push(_rid);counters.rulesMatched++;"),t&&(n.push("let params;"),n.push('try{params=$.runMw(mw,stored.definition,ctx);}catch(_e){errors.push({ruleIndex:i,error:"Middleware: "+_e});counters.errors++;continue;}'));let A=t?",params":"",v=e?`await ae.invokeAsync(stored.actionId${A})`:`ae.invoke(stored.actionId${A})`;n.push("if(stored.actionId){"),n.push(`const ir=${v};`),n.push("counters.directivesApplied+=ir.appliedCount;counters.directivesSkipped+=ir.skippedCount;counters.errors+=ir.errors.length;"),c&&(n.push("try{"),n.push(`const _ad=${g}_hookAfter(stored.definition,ir,evalCtx);`),n.push('if(_ad==="abort")'),B(n,"false",'"afterRule"',"i+1","len",a,m),n.push("}catch(_e){}")),n.push("if(ir.aborted)"),B(n,'ir.abortedBy==="halt"',"ir.abortedBy","i+1","len",a,m),n.push("}");let p=t?"params":"undefined";n.push("if(stored.subRules&&stored.subRules.length>0){"),n.push(`if(${e?"await ":""}$.evalSub(stored.subRules,ctx,ae,counters,errors,i,${p},0,$.maxDepth))`),B(n,"false",'"sub-rule"',"i+1","len",a,m),n.push("}"),n.push("}"),n.push("const _r={success:true,aborted:false,abortedBy:undefined,matched,skipped,notMatched,errors,processedCount:len,totalCount:len,counters};"),a&&n.push(`try{${m}_hookOnComplete(_r);}catch(_e){}`),n.push("return _r;");let T=n.join(`
2
- `),C=e?"async ":"",x=new Function("rules","ctx","ae","mw","hooks","$",`"use strict";
3
- return(${C}()=>{
4
- ${T}
5
- })();`),_={maxDepth:i};return _.evalSub=e?$:M,t&&(_.runMw=D),function(k,I,f,R,E){return x(k,I,f,R,E,_)}}function P(r){if(!r.id||typeof r.id!="string")return {ruleId:r.id??"(missing)",code:"INVALID_RULE",message:"rule must have a string id"};if(typeof r.priority!="number")return {ruleId:r.id,code:"INVALID_RULE",message:"rule must have a numeric priority"};if(typeof r.when!="function")return {ruleId:r.id,code:"INVALID_RULE",message:"rule must have a when function"};let t=Array.isArray(r.then)&&r.then.length>0,e=Array.isArray(r.rules)&&r.rules.length>0;return !t&&!e?{ruleId:r.id,code:"INVALID_RULE",message:"rule must have then or sub-rules (or both)"}:null}function U(r,t){let e=`${t}.${r.id??"(missing)"}`;if(!r.id||typeof r.id!="string")return {ruleId:e,code:"INVALID_RULE",message:"sub-rule must have a string id"};let i=Array.isArray(r.then)&&r.then.length>0,o=Array.isArray(r.rules)&&r.rules.length>0;return !i&&!o?{ruleId:e,code:"INVALID_RULE",message:"sub-rule must have then or sub-rules (or both)"}:null}var N=()=>{},F=class{_actionEngine;_middleware;_ruleHooks;_isAsync;_maxSubRuleDepth;_requestedMode;_ruleHookAnalysis;_ruleEvaluator;_mode;_maybeAutoPromote;_ruleRegistry=new Map;_rules=[];_batch=null;constructor(t){if(this._actionEngine=t.actionEngine,this._middleware=t.middleware??[],this._ruleHooks=t.ruleHooks??{},this._maxSubRuleDepth=t.maxSubRuleDepth??10,this._requestedMode=t.mode??"auto",this._ruleHookAnalysis=analyzeSlots(this._ruleHooks,RULE_SLOT_NAMES),this._isAsync=this._ruleHookAnalysis.hasAnyAsync||this._actionEngine.isAsync,this._requestedMode==="jit")this._ruleEvaluator=this._buildJitRule(),this._mode="jit",this._maybeAutoPromote=N;else if(this._ruleEvaluator=O(this._ruleHookAnalysis,this._isAsync,this._maxSubRuleDepth),this._mode="interpret",this._requestedMode==="auto"){let e=0,i=t.autoJitThreshold??8;this._maybeAutoPromote=()=>{++e>=i&&this._promote();};}else this._maybeAutoPromote=N;}get actionEngine(){return this._actionEngine}get isAsync(){return this._isAsync}get compilationMode(){return this._mode}get size(){return this._rules.length}has(t){return this._ruleRegistry.has(t)}register(t){let e=[],i=[],o=[];for(let s of t){let u=P(s);if(u){i.push(u);continue}if(this._ruleRegistry.has(s.id)){i.push({ruleId:s.id,code:"DUPLICATE_ID",message:`rule "${s.id}" is already registered`});continue}let c=`rule:${s.id}`,a=Array.isArray(s.then)&&s.then.length>0,d=a?c:"",g=Array.isArray(s.rules)&&s.rules.length>0?this._collectSubRules(c,s.rules,i,o):void 0,m={definition:s,actionId:d,priority:s.priority,subRules:g?.length?g:void 0};if(this._ruleRegistry.set(s.id,m),Q(this._rules,m),a){let n=["rule"];s.tags&&n.push(...s.tags),o.push({id:d,tags:n,directives:s.then,declarations:s.declarations});}e.push(s.id);}let h=[];if(o.length>0){let s=this._actionEngine.register(o);for(let u of s.errors){let c=this._actionIdToRuleId(u.actionId);i.push({ruleId:c??u.actionId,code:u.code??"ACTION_ERROR",message:u.error});}h=s.warnings;}let b={registered:e,errors:i,warnings:h};return this._batch&&(this._batch.registered.push(...e),this._batch.errors.push(...i),this._batch.warnings.push(...h)),b}unregister(t){let e=this._ruleRegistry.get(t);return e?(this._ruleRegistry.delete(t),X(this._rules,e),e.actionId&&this._actionEngine.unregister(e.actionId),e.subRules&&this._unregisterSubRules(e.subRules),true):false}beginBatch(){this._batch||(this._batch={depth:0,registered:[],errors:[],warnings:[]}),this._batch.depth++,this._actionEngine.beginBatch();}endBatch(){if(!this._batch||this._batch.depth<=0)throw new Error("endBatch() called without matching beginBatch()");this._batch.depth--;let t=this._actionEngine.endBatch();if(this._batch.depth>0)return {registered:[],errors:[],warnings:[]};let e=this._batch;for(let o of t.errors){let h=this._actionIdToRuleId(o.actionId);e.errors.push({ruleId:h??o.actionId,code:o.code??"ACTION_ERROR",message:o.error});}e.warnings.push(...t.warnings);let i={registered:e.registered,errors:e.errors,warnings:e.warnings};return this._batch=null,i}batch(t){this.beginBatch();try{return t(this),this.endBatch()}catch(e){try{this.endBatch();}catch{}throw e}}evaluate(t){if(this._isAsync)throw new Error("Cannot call evaluate() with async hooks. Use evaluateAsync() instead.");let e=this._ruleEvaluator(this._rules,t,this._actionEngine,this._middleware,this._ruleHooks);return this._maybeAutoPromote(),e}async evaluateAsync(t){let e=await this._ruleEvaluator(this._rules,t,this._actionEngine,this._middleware,this._ruleHooks);return this._maybeAutoPromote(),e}compile(){this._requestedMode!=="interpret"&&this._mode!=="jit"&&this._promote();}_collectSubRules(t,e,i,o){let h=[],b=this._actionIdToRuleId(t);for(let s of e){let u=U(s,b);if(u){i.push(u);continue}let c=`${t}.${s.id}`,a=`${b}.${s.id}`,d=Array.isArray(s.then)&&s.then.length>0,g=Array.isArray(s.rules)&&s.rules.length>0?this._collectSubRules(c,s.rules,i,o):void 0,m={definition:s,actionId:d?c:"",subRules:g?.length?g:void 0};if(d){let n=["rule"];s.tags&&n.push(...s.tags),o.push({id:c,tags:n,directives:s.then,declarations:s.declarations});}this._ruleRegistry.set(a,m),h.push(m);}return h}_unregisterSubRules(t){for(let e of t){if(e.actionId){let i=this._actionIdToRuleId(e.actionId);i&&this._ruleRegistry.delete(i),this._actionEngine.unregister(e.actionId);}e.subRules&&this._unregisterSubRules(e.subRules);}}_actionIdToRuleId(t){return t.startsWith("rule:")?t.slice(5):null}_promote(){this._ruleEvaluator=this._buildJitRule(),this._mode="jit",this._maybeAutoPromote=N;}_buildJitRule(){return j(this._ruleHookAnalysis,this._middleware.length>0,this._isAsync,this._maxSubRuleDepth)}};function K(r){return new F(r)}function Q(r,t){let e=0,i=r.length;for(;e<i;){let o=e+i>>>1;r[o].priority>=t.priority?e=o+1:i=o;}r.splice(e,0,t);}function X(r,t){let e=r.indexOf(t);return e===-1?false:(r.splice(e,1),true)}var Y={analyze:()=>({capabilities:["halt"],dependencies:[]}),execute:()=>({ok:true,halt:true})};export{Y as HALT_HANDLER,V as createInvokerMiddleware,K as createRuleEngine};
1
+ import {analyzeSlots,RULE_SLOT_NAMES}from'@statedelta-actions/core';function B(n,r,t,o,c,d,b,R,a){if(R>=a)return c.push({ruleIndex:d,error:`maxSubRuleDepth (${a}) exceeded`}),o.errors++,false;for(let u=0;u<n.length;u++){let s=n[u];if(s.definition.when){let l;try{l=s.definition.when(r);}catch(v){c.push({ruleIndex:d,error:String(v)}),o.errors++;continue}if(!l)continue}if(s.actionId){let l=t.invoke(s.actionId,b);if(o.directivesApplied+=l.appliedCount,o.directivesSkipped+=l.skippedCount,o.errors+=l.errors.length,l.aborted)return true}if(s.subRules&&s.subRules.length>0&&B(s.subRules,r,t,o,c,d,b,R+1,a))return true}return false}async function F(n,r,t,o,c,d,b,R,a){if(R>=a)return c.push({ruleIndex:d,error:`maxSubRuleDepth (${a}) exceeded`}),o.errors++,false;for(let u=0;u<n.length;u++){let s=n[u];if(s.definition.when){let l;try{l=s.definition.when(r);}catch(v){c.push({ruleIndex:d,error:String(v)}),o.errors++;continue}if(!l)continue}if(s.actionId){let l=await t.invokeAsync(s.actionId,b);if(o.directivesApplied+=l.appliedCount,o.directivesSkipped+=l.skippedCount,o.errors+=l.errors.length,l.aborted)return true}if(s.subRules&&s.subRules.length>0&&await F(s.subRules,r,t,o,c,d,b,R+1,a))return true}return false}function Q(){return n=>({$invoker:{ruleId:n.id,priority:n.priority,tags:n.tags??[]}})}function $(n,r,t,o){let c=o?Object.assign({},o):{};for(let d of n)Object.assign(c,d(r,t,c));return c}function q(){return {rulesEvaluated:0,rulesMatched:0,rulesSkipped:0,directivesApplied:0,directivesSkipped:0,subRunsCreated:0,errors:0}}function U(n,r,t,o,c,d,b,R,a,u){return {success:n,aborted:r,abortedBy:t,matched:o,skipped:c,notMatched:d,errors:b,processedCount:R,totalCount:a,counters:u}}function X(n,r){let t=n.filledNames.has("beforeRule"),o=n.filledNames.has("afterRule"),c=n.filledNames.has("onRulesComplete"),d=t||o;return function(R,a,u,s,l){let v=R.length,_=[],e=[],A=[],y=[],h=q(),S=s.length>0,I=true,C=false,g,m=v;u.setContext(a);let E=d?{ctx:a,counters:h}:void 0;for(let f=0;f<v;f++){let p=R[f],k=p.definition.id;if(h.rulesEvaluated++,t)try{let i=l.beforeRule(p.definition,E);if(i==="skip"){e.push(k),h.rulesSkipped++;continue}if(i==="abort"){I=!1,C=!0,g="beforeRule",m=f+1;break}}catch(i){y.push({ruleIndex:f,error:`beforeRule: ${i}`}),h.errors++;}let T;try{T=p.definition.when(a);}catch(i){y.push({ruleIndex:f,error:String(i)}),A.push(k),h.errors++;continue}if(!T){A.push(k);continue}_.push(k),h.rulesMatched++;let x;if(S)try{x=$(s,p.definition,a);}catch(i){y.push({ruleIndex:f,error:`Middleware: ${i}`}),h.errors++;continue}if(p.actionId){let i=u.invoke(p.actionId,x);if(h.directivesApplied+=i.appliedCount,h.directivesSkipped+=i.skippedCount,h.errors+=i.errors.length,o)try{if(l.afterRule(p.definition,i,E)==="abort"){I=!1,C=!0,g="afterRule",m=f+1;break}}catch{}if(i.aborted){I=i.abortedBy==="halt",C=true,g=i.abortedBy,m=f+1;break}}if(p.subRules&&p.subRules.length>0&&B(p.subRules,a,u,h,y,f,x,0,r)){I=false,C=true,g="sub-rule",m=f+1;break}}let w=U(I,C,g,_,e,A,y,m,v,h);if(c)try{l.onRulesComplete(w);}catch{}return w}}function Y(n,r){let t=n.filledNames.has("beforeRule"),o=n.filledNames.has("afterRule"),c=n.filledNames.has("onRulesComplete"),d=t||o;return async function(R,a,u,s,l){let v=R.length,_=[],e=[],A=[],y=[],h=q(),S=s.length>0,I=true,C=false,g,m=v;u.setContext(a);let E=d?{ctx:a,counters:h}:void 0;for(let f=0;f<v;f++){let p=R[f],k=p.definition.id;if(h.rulesEvaluated++,t)try{let i=await l.beforeRule(p.definition,E);if(i==="skip"){e.push(k),h.rulesSkipped++;continue}if(i==="abort"){I=!1,C=!0,g="beforeRule",m=f+1;break}}catch(i){y.push({ruleIndex:f,error:`beforeRule: ${i}`}),h.errors++;}let T;try{T=p.definition.when(a);}catch(i){y.push({ruleIndex:f,error:String(i)}),A.push(k),h.errors++;continue}if(!T){A.push(k);continue}_.push(k),h.rulesMatched++;let x;if(S)try{x=$(s,p.definition,a);}catch(i){y.push({ruleIndex:f,error:`Middleware: ${i}`}),h.errors++;continue}if(p.actionId){let i=await u.invokeAsync(p.actionId,x);if(h.directivesApplied+=i.appliedCount,h.directivesSkipped+=i.skippedCount,h.errors+=i.errors.length,o)try{if(await l.afterRule(p.definition,i,E)==="abort"){I=!1,C=!0,g="afterRule",m=f+1;break}}catch{}if(i.aborted){I=i.abortedBy==="halt",C=true,g=i.abortedBy,m=f+1;break}}if(p.subRules&&p.subRules.length>0&&await F(p.subRules,a,u,h,y,f,x,0,r)){I=false,C=true,g="sub-rule",m=f+1;break}}let w=U(I,C,g,_,e,A,y,m,v,h);if(c)try{await l.onRulesComplete(w);}catch{}return w}}function O(n,r,t){return r?Y(n,t):X(n,t)}function G(){return {rulesEvaluated:0,rulesMatched:0,rulesSkipped:0,directivesApplied:0,directivesSkipped:0,subRunsCreated:0,errors:0}}function V(n,r,t,o,c,d,b,R,a,u){return {success:n,aborted:r,abortedBy:t,matched:o,skipped:c,notMatched:d,errors:b,processedCount:R,totalCount:a,counters:u}}function Z(n){let r=n.filledNames.has("beforeRule"),t=n.filledNames.has("afterRule"),o=n.filledNames.has("onRulesComplete"),c=r||t;return function*(b,R,a,u,s,l){let v=b.length,_=[],e=[],A=[],y=[],h=G(),S=u.length>0,I=true,C=false,g,m=v;a.setContext(R);let E=c?{ctx:R,counters:h}:void 0;for(let f=0;f<v;f++){let p=b[f],k=p.definition.id;if(h.rulesEvaluated++,r)try{let i=s.beforeRule(p.definition,E);if(i==="skip"){e.push(k),h.rulesSkipped++;continue}if(i==="abort"){I=!1,C=!0,g="beforeRule",m=f+1;break}}catch(i){y.push({ruleIndex:f,error:`beforeRule: ${i}`}),h.errors++;}let T;try{T=p.definition.when(R);}catch(i){y.push({ruleIndex:f,error:String(i)}),A.push(k),h.errors++;continue}if(!T){A.push(k);continue}_.push(k),h.rulesMatched++;let x;if(S)try{x=$(u,p.definition,R);}catch(i){y.push({ruleIndex:f,error:`Middleware: ${i}`}),h.errors++;continue}if(p.actionId){let i;if(p.isInteractive?i=yield*a.invokeInteractive(p.actionId,x):i=a.invoke(p.actionId,x),h.directivesApplied+=i.appliedCount,h.directivesSkipped+=i.skippedCount,h.errors+=i.errors.length,t)try{if(s.afterRule(p.definition,i,E)==="abort"){I=!1,C=!0,g="afterRule",m=f+1;break}}catch{}if(i.aborted){I=i.abortedBy==="halt",C=true,g=i.abortedBy,m=f+1;break}}if(p.subRules&&p.subRules.length>0&&(yield*D(p.subRules,R,a,h,y,f,x,0,l))){I=false,C=true,g="sub-rule",m=f+1;break}}let w=V(I,C,g,_,e,A,y,m,v,h);if(o)try{s.onRulesComplete(w);}catch{}return w}}function ee(n){let r=n.filledNames.has("beforeRule"),t=n.filledNames.has("afterRule"),o=n.filledNames.has("onRulesComplete"),c=r||t;return async function*(b,R,a,u,s,l){let v=b.length,_=[],e=[],A=[],y=[],h=G(),S=u.length>0,I=true,C=false,g,m=v;a.setContext(R);let E=c?{ctx:R,counters:h}:void 0;for(let f=0;f<v;f++){let p=b[f],k=p.definition.id;if(h.rulesEvaluated++,r)try{let i=await s.beforeRule(p.definition,E);if(i==="skip"){e.push(k),h.rulesSkipped++;continue}if(i==="abort"){I=!1,C=!0,g="beforeRule",m=f+1;break}}catch(i){y.push({ruleIndex:f,error:`beforeRule: ${i}`}),h.errors++;}let T;try{T=p.definition.when(R);}catch(i){y.push({ruleIndex:f,error:String(i)}),A.push(k),h.errors++;continue}if(!T){A.push(k);continue}_.push(k),h.rulesMatched++;let x;if(S)try{x=$(u,p.definition,R);}catch(i){y.push({ruleIndex:f,error:`Middleware: ${i}`}),h.errors++;continue}if(p.actionId){let i;if(p.isInteractive?i=yield*a.invokeInteractive(p.actionId,x):p.isAsync?i=await a.invokeAsync(p.actionId,x):i=a.invoke(p.actionId,x),h.directivesApplied+=i.appliedCount,h.directivesSkipped+=i.skippedCount,h.errors+=i.errors.length,t)try{if(await s.afterRule(p.definition,i,E)==="abort"){I=!1,C=!0,g="afterRule",m=f+1;break}}catch{}if(i.aborted){I=i.abortedBy==="halt",C=true,g=i.abortedBy,m=f+1;break}}if(p.subRules&&p.subRules.length>0&&(yield*N(p.subRules,R,a,h,y,f,x,0,l))){I=false,C=true,g="sub-rule",m=f+1;break}}let w=V(I,C,g,_,e,A,y,m,v,h);if(o)try{await s.onRulesComplete(w);}catch{}return w}}function*D(n,r,t,o,c,d,b,R,a){if(R>=a)return c.push({ruleIndex:d,error:`maxSubRuleDepth (${a}) exceeded`}),o.errors++,false;for(let u=0;u<n.length;u++){let s=n[u];if(s.definition.when){let l;try{l=s.definition.when(r);}catch(v){c.push({ruleIndex:d,error:String(v)}),o.errors++;continue}if(!l)continue}if(s.actionId){let l;if(s.isInteractive?l=yield*t.invokeInteractive(s.actionId,b):l=t.invoke(s.actionId,b),o.directivesApplied+=l.appliedCount,o.directivesSkipped+=l.skippedCount,o.errors+=l.errors.length,l.aborted)return true}if(s.subRules&&s.subRules.length>0&&(yield*D(s.subRules,r,t,o,c,d,b,R+1,a)))return true}return false}async function*N(n,r,t,o,c,d,b,R,a){if(R>=a)return c.push({ruleIndex:d,error:`maxSubRuleDepth (${a}) exceeded`}),o.errors++,false;for(let u=0;u<n.length;u++){let s=n[u];if(s.definition.when){let l;try{l=s.definition.when(r);}catch(v){c.push({ruleIndex:d,error:String(v)}),o.errors++;continue}if(!l)continue}if(s.actionId){let l;if(s.isInteractive?l=yield*t.invokeInteractive(s.actionId,b):s.isAsync?l=await t.invokeAsync(s.actionId,b):l=t.invoke(s.actionId,b),o.directivesApplied+=l.appliedCount,o.directivesSkipped+=l.skippedCount,o.errors+=l.errors.length,l.aborted)return true}if(s.subRules&&s.subRules.length>0&&(yield*N(s.subRules,r,t,o,c,d,b,R+1,a)))return true}return false}function W(n,r){return r?ee(n):Z(n)}function M(n,r,t,o,c,d,b){n.push(`{const _er={success:${r},aborted:true,abortedBy:${t},matched,skipped,notMatched,errors,processedCount:${o},totalCount:${c},counters};`),d&&n.push(`try{${b}_hookOnComplete(_er);}catch(_e){}`),n.push("return _er;}");}function J(n,r,t,o){let{filledNames:c,asyncNames:d}=n,b=m=>c.has(m),R=m=>d.has(m)?"await ":"",a=b("beforeRule"),u=b("afterRule"),s=b("onRulesComplete"),l=R("beforeRule"),v=R("afterRule"),_=R("onRulesComplete"),e=[];e.push("const len=rules.length;"),e.push("const matched=[];const skipped=[];const notMatched=[];"),e.push("const errors=[];"),e.push("const counters={rulesEvaluated:0,rulesMatched:0,rulesSkipped:0,directivesApplied:0,directivesSkipped:0,subRunsCreated:0,errors:0};"),e.push("ae.setContext(ctx);"),(a||u)&&e.push("const evalCtx={ctx,counters};"),a&&e.push("const _hookBefore=hooks.beforeRule;"),u&&e.push("const _hookAfter=hooks.afterRule;"),s&&e.push("const _hookOnComplete=hooks.onRulesComplete;"),e.push("for(let i=0;i<len;i++){"),e.push("const stored=rules[i];"),e.push("const _rid=stored.definition.id;"),e.push("counters.rulesEvaluated++;"),a&&(e.push("try{"),e.push(`const _bd=${l}_hookBefore(stored.definition,evalCtx);`),e.push('if(_bd==="skip"){skipped.push(_rid);counters.rulesSkipped++;continue;}'),e.push('if(_bd==="abort")'),M(e,"false",'"beforeRule"',"i+1","len",s,_),e.push('}catch(_e){errors.push({ruleIndex:i,error:"beforeRule: "+_e});counters.errors++;}')),e.push("let ev;"),e.push("try{ev=stored.definition.when(ctx);}catch(_e){errors.push({ruleIndex:i,error:String(_e)});notMatched.push(_rid);counters.errors++;continue;}"),e.push("if(!ev){notMatched.push(_rid);continue;}"),e.push("matched.push(_rid);counters.rulesMatched++;"),r&&(e.push("let params;"),e.push('try{params=$.runMw(mw,stored.definition,ctx);}catch(_e){errors.push({ruleIndex:i,error:"Middleware: "+_e});counters.errors++;continue;}'));let A=r?",params":"",y=t?`await ae.invokeAsync(stored.actionId${A})`:`ae.invoke(stored.actionId${A})`;e.push("if(stored.actionId){"),e.push(`const ir=${y};`),e.push("counters.directivesApplied+=ir.appliedCount;counters.directivesSkipped+=ir.skippedCount;counters.errors+=ir.errors.length;"),u&&(e.push("try{"),e.push(`const _ad=${v}_hookAfter(stored.definition,ir,evalCtx);`),e.push('if(_ad==="abort")'),M(e,"false",'"afterRule"',"i+1","len",s,_),e.push("}catch(_e){}")),e.push("if(ir.aborted)"),M(e,'ir.abortedBy==="halt"',"ir.abortedBy","i+1","len",s,_),e.push("}");let h=r?"params":"undefined";e.push("if(stored.subRules&&stored.subRules.length>0){"),e.push(`if(${t?"await ":""}$.evalSub(stored.subRules,ctx,ae,counters,errors,i,${h},0,$.maxDepth))`),M(e,"false",'"sub-rule"',"i+1","len",s,_),e.push("}"),e.push("}"),e.push("const _r={success:true,aborted:false,abortedBy:undefined,matched,skipped,notMatched,errors,processedCount:len,totalCount:len,counters};"),s&&e.push(`try{${_}_hookOnComplete(_r);}catch(_e){}`),e.push("return _r;");let S=e.join(`
2
+ `),I=t?"async ":"",C=new Function("rules","ctx","ae","mw","hooks","$",`"use strict";
3
+ return(${I}()=>{
4
+ ${S}
5
+ })();`),g={maxDepth:o};return g.evalSub=t?F:B,r&&(g.runMw=$),function(E,w,f,p,k){return C(E,w,f,p,k,g)}}function P(n,r,t,o){let{filledNames:c,asyncNames:d}=n,b=g=>c.has(g),R=g=>d.has(g)?"await ":"",a=b("beforeRule"),u=b("afterRule"),s=b("onRulesComplete"),l=R("beforeRule"),v=R("afterRule"),_=R("onRulesComplete"),e=[];e.push("const len=rules.length;"),e.push("const matched=[];const skipped=[];const notMatched=[];"),e.push("const errors=[];"),e.push("const counters={rulesEvaluated:0,rulesMatched:0,rulesSkipped:0,directivesApplied:0,directivesSkipped:0,subRunsCreated:0,errors:0};"),e.push("ae.setContext(ctx);"),(a||u)&&e.push("const evalCtx={ctx,counters};"),a&&e.push("const _hookBefore=hooks.beforeRule;"),u&&e.push("const _hookAfter=hooks.afterRule;"),s&&e.push("const _hookOnComplete=hooks.onRulesComplete;"),e.push("for(let i=0;i<len;i++){"),e.push("const stored=rules[i];"),e.push("const _rid=stored.definition.id;"),e.push("counters.rulesEvaluated++;"),a&&(e.push("try{"),e.push(`const _bd=${l}_hookBefore(stored.definition,evalCtx);`),e.push('if(_bd==="skip"){skipped.push(_rid);counters.rulesSkipped++;continue;}'),e.push('if(_bd==="abort")'),M(e,"false",'"beforeRule"',"i+1","len",s,_),e.push('}catch(_e){errors.push({ruleIndex:i,error:"beforeRule: "+_e});counters.errors++;}')),e.push("let ev;"),e.push("try{ev=stored.definition.when(ctx);}catch(_e){errors.push({ruleIndex:i,error:String(_e)});notMatched.push(_rid);counters.errors++;continue;}"),e.push("if(!ev){notMatched.push(_rid);continue;}"),e.push("matched.push(_rid);counters.rulesMatched++;"),r&&(e.push("let params;"),e.push('try{params=$.runMw(mw,stored.definition,ctx);}catch(_e){errors.push({ruleIndex:i,error:"Middleware: "+_e});counters.errors++;continue;}'));let A=r?",params":"";e.push("if(stored.actionId){"),e.push("let ir;"),e.push("if(stored.isInteractive){"),e.push(`ir=yield* ae.invokeInteractive(stored.actionId${A});`),e.push("}else "),t?(e.push("if(stored.isAsync){"),e.push(`ir=await ae.invokeAsync(stored.actionId${A});`),e.push("}else{")):e.push("{"),e.push(`ir=ae.invoke(stored.actionId${A});`),e.push("}"),e.push("counters.directivesApplied+=ir.appliedCount;counters.directivesSkipped+=ir.skippedCount;counters.errors+=ir.errors.length;"),u&&(e.push("try{"),e.push(`const _ad=${v}_hookAfter(stored.definition,ir,evalCtx);`),e.push('if(_ad==="abort")'),M(e,"false",'"afterRule"',"i+1","len",s,_),e.push("}catch(_e){}")),e.push("if(ir.aborted)"),M(e,'ir.abortedBy==="halt"',"ir.abortedBy","i+1","len",s,_),e.push("}");let y=r?"params":"undefined";e.push("if(stored.subRules&&stored.subRules.length>0){"),e.push(`if(yield* $.evalSubInt(stored.subRules,ctx,ae,counters,errors,i,${y},0,$.maxDepth))`),M(e,"false",'"sub-rule"',"i+1","len",s,_),e.push("}"),e.push("}"),e.push("const _r={success:true,aborted:false,abortedBy:undefined,matched,skipped,notMatched,errors,processedCount:len,totalCount:len,counters};"),s&&e.push(`try{${_}_hookOnComplete(_r);}catch(_e){}`),e.push("return _r;");let h=e.join(`
6
+ `),S=t?"async function*()":"function*()",I=new Function("rules","ctx","ae","mw","hooks","$",`"use strict";
7
+ return(${S}{
8
+ ${h}
9
+ })();`),C={maxDepth:o};return C.evalSubInt=t?N:D,r&&(C.runMw=$),function(m,E,w,f,p){return I(m,E,w,f,p,C)}}function z(n){if(!n.id||typeof n.id!="string")return {ruleId:n.id??"(missing)",code:"INVALID_RULE",message:"rule must have a string id"};if(typeof n.priority!="number")return {ruleId:n.id,code:"INVALID_RULE",message:"rule must have a numeric priority"};if(typeof n.when!="function")return {ruleId:n.id,code:"INVALID_RULE",message:"rule must have a when function"};let r=Array.isArray(n.then)&&n.then.length>0,t=Array.isArray(n.rules)&&n.rules.length>0;return !r&&!t?{ruleId:n.id,code:"INVALID_RULE",message:"rule must have then or sub-rules (or both)"}:null}function K(n,r){let t=`${r}.${n.id??"(missing)"}`;if(!n.id||typeof n.id!="string")return {ruleId:t,code:"INVALID_RULE",message:"sub-rule must have a string id"};let o=Array.isArray(n.then)&&n.then.length>0,c=Array.isArray(n.rules)&&n.rules.length>0;return !o&&!c?{ruleId:t,code:"INVALID_RULE",message:"sub-rule must have then or sub-rules (or both)"}:null}var L=()=>{},j=class{_actionEngine;_middleware;_ruleHooks;_maxSubRuleDepth;_requestedMode;_ruleHookAnalysis;_hasAnyInteractiveRule=false;_isAsync;_ruleEvaluator;_mode;_maybeAutoPromote;_interactiveEvaluator=null;_interactiveEvaluatorIsAsync=false;_ruleRegistry=new Map;_rules=[];_batch=null;constructor(r){if(this._actionEngine=r.actionEngine,this._middleware=r.middleware??[],this._ruleHooks=r.ruleHooks??{},this._maxSubRuleDepth=r.maxSubRuleDepth??10,this._requestedMode=r.mode??"auto",this._ruleHookAnalysis=analyzeSlots(this._ruleHooks,RULE_SLOT_NAMES),this._isAsync=this._ruleHookAnalysis.hasAnyAsync,this._requestedMode==="jit")this._ruleEvaluator=this._buildJitRule(),this._mode="jit",this._maybeAutoPromote=L;else if(this._ruleEvaluator=O(this._ruleHookAnalysis,this._isAsync,this._maxSubRuleDepth),this._mode="interpret",this._requestedMode==="auto"){let t=0,o=r.autoJitThreshold??8;this._maybeAutoPromote=()=>{++t>=o&&this._promote();};}else this._maybeAutoPromote=L;}get actionEngine(){return this._actionEngine}get isAsync(){return this._isAsync}get isInteractive(){return this._hasAnyInteractiveRule}get compilationMode(){return this._mode}get size(){return this._rules.length}has(r){return this._ruleRegistry.has(r)}register(r){let t=[],o=[],c=[],d=[];for(let u of r){let s=z(u);if(s){t.push(s);continue}if(this._ruleRegistry.has(u.id)||c.some(y=>y.id===u.id)){t.push({ruleId:u.id,code:"DUPLICATE_ID",message:`rule "${u.id}" is already registered`});continue}let l=`rule:${u.id}`,v=Array.isArray(u.then)&&u.then.length>0,_=v?l:"",e=Array.isArray(u.rules)&&u.rules.length>0?this._collectSubRules(l,u.rules,t,o,d):void 0,A={definition:u,actionId:_,priority:u.priority,subRules:e?.length?e:void 0,isAsync:false,isInteractive:false};if(v){let y=["rule"];u.tags&&y.push(...u.tags),o.push({id:_,tags:y,directives:u.then,declarations:u.declarations});}c.push({id:u.id,stored:A});}let b=[];if(o.length>0){let u=this._actionEngine.register(o);for(let s of u.errors){let l=this._actionIdToRuleId(s.actionId);t.push({ruleId:l??s.actionId,code:s.code??"ACTION_ERROR",message:s.error});}b=u.warnings;}let R=[];for(let{id:u,stored:s}of c)this._ruleRegistry.set(u,s),se(this._rules,s),R.push(u);for(let{qualifiedId:u,stored:s}of d)this._ruleRegistry.set(u,s);let a={registered:R,errors:t,warnings:b};return this._batch?(this._batch.registered.push(...R),this._batch.errors.push(...t),this._batch.warnings.push(...b)):R.length>0&&this._refreshRuleFlags(),a}unregister(r){let t=this._ruleRegistry.get(r);return t?(this._ruleRegistry.delete(r),ie(this._rules,t),t.actionId&&this._actionEngine.unregister(t.actionId),t.subRules&&this._unregisterSubRules(t.subRules),this._refreshRuleFlags(),true):false}beginBatch(){this._batch||(this._batch={depth:0,registered:[],errors:[],warnings:[]}),this._batch.depth++,this._actionEngine.beginBatch();}endBatch(){if(!this._batch||this._batch.depth<=0)throw new Error("endBatch() called without matching beginBatch()");this._batch.depth--;let r=this._actionEngine.endBatch();if(this._batch.depth>0)return {registered:[],errors:[],warnings:[]};let t=this._batch;for(let c of r.errors){let d=this._actionIdToRuleId(c.actionId);t.errors.push({ruleId:d??c.actionId,code:c.code??"ACTION_ERROR",message:c.error});}t.warnings.push(...r.warnings);let o={registered:t.registered,errors:t.errors,warnings:t.warnings};return this._batch=null,this._refreshRuleFlags(),o}batch(r){this.beginBatch();try{return r(this),this.endBatch()}catch(t){try{this.endBatch();}catch{}throw t}}evaluate(r){if(this._hasAnyInteractiveRule)throw new Error("Cannot call evaluate() \u2014 at least one rule is interactive (transitively). Use evaluateInteractive() instead.");if(this._isAsync)throw new Error("Cannot call evaluate() with async hooks or async rules. Use evaluateAsync() instead.");let t=this._ruleEvaluator(this._rules,r,this._actionEngine,this._middleware,this._ruleHooks);return this._maybeAutoPromote(),t}async evaluateAsync(r){if(this._hasAnyInteractiveRule)throw new Error("Cannot call evaluateAsync() \u2014 at least one rule is interactive (transitively). Use evaluateInteractive() instead.");let t=await this._ruleEvaluator(this._rules,r,this._actionEngine,this._middleware,this._ruleHooks);return this._maybeAutoPromote(),t}evaluateInteractive(r){if(!this._hasAnyInteractiveRule)throw new Error("Cannot call evaluateInteractive() \u2014 no registered rule is interactive (transitively). Use evaluate() or evaluateAsync() instead.");return (this._interactiveEvaluator===null||this._interactiveEvaluatorIsAsync!==this._isAsync)&&(this._interactiveEvaluator=this._mode==="jit"?P(this._ruleHookAnalysis,this._middleware.length>0,this._isAsync,this._maxSubRuleDepth):W(this._ruleHookAnalysis,this._isAsync),this._interactiveEvaluatorIsAsync=this._isAsync),this._interactiveEvaluator(this._rules,r,this._actionEngine,this._middleware,this._ruleHooks,this._maxSubRuleDepth)}compile(){this._requestedMode!=="interpret"&&this._mode!=="jit"&&this._promote();}_collectSubRules(r,t,o,c,d){let b=[],R=this._actionIdToRuleId(r);for(let a of t){let u=K(a,R);if(u){o.push(u);continue}let s=`${r}.${a.id}`,l=`${R}.${a.id}`,v=Array.isArray(a.then)&&a.then.length>0,_=Array.isArray(a.rules)&&a.rules.length>0?this._collectSubRules(s,a.rules,o,c,d):void 0,e={definition:a,actionId:v?s:"",subRules:_?.length?_:void 0,isAsync:false,isInteractive:false};if(v){let A=["rule"];a.tags&&A.push(...a.tags),c.push({id:s,tags:A,directives:a.then,declarations:a.declarations});}d.push({qualifiedId:l,stored:e}),b.push(e);}return b}_unregisterSubRules(r){for(let t of r){if(t.actionId){let o=this._actionIdToRuleId(t.actionId);o&&this._ruleRegistry.delete(o),this._actionEngine.unregister(t.actionId);}t.subRules&&this._unregisterSubRules(t.subRules);}}_actionIdToRuleId(r){return r.startsWith("rule:")?r.slice(5):null}_refreshRuleFlags(){let r=false,t=false,o=d=>{if(d.actionId?(d.isAsync=this._actionEngine.isActionAsync(d.actionId)??false,d.isInteractive=this._actionEngine.isActionInteractive(d.actionId)??false,d.isAsync&&(r=true),d.isInteractive&&(t=true)):(d.isAsync=false,d.isInteractive=false),d.subRules)for(let b of d.subRules)o(b);};for(let d of this._rules)o(d);this._hasAnyInteractiveRule=t;let c=this._ruleHookAnalysis.hasAnyAsync||r;c!==this._isAsync?(this._isAsync=c,this._rebuildEvaluator()):this._isAsync=c;}_rebuildEvaluator(){this._mode==="jit"?this._ruleEvaluator=this._buildJitRule():this._ruleEvaluator=O(this._ruleHookAnalysis,this._isAsync,this._maxSubRuleDepth);}_promote(){this._ruleEvaluator=this._buildJitRule(),this._mode="jit",this._maybeAutoPromote=L;}_buildJitRule(){return J(this._ruleHookAnalysis,this._middleware.length>0,this._isAsync,this._maxSubRuleDepth)}};function ne(n){return new j(n)}function se(n,r){let t=0,o=n.length;for(;t<o;){let c=t+o>>>1;n[c].priority>=r.priority?t=c+1:o=c;}n.splice(t,0,r);}function ie(n,r){let t=n.indexOf(r);return t===-1?false:(n.splice(t,1),true)}var oe={analyze:()=>({capabilities:["halt"],dependencies:[]}),execute:()=>({ok:true,halt:true})};export{oe as HALT_HANDLER,Q as createInvokerMiddleware,ne as createRuleEngine};
package/package.json CHANGED
@@ -1,7 +1,14 @@
1
1
  {
2
2
  "name": "@statedelta-actions/rules",
3
- "version": "0.3.0",
3
+ "version": "0.5.1",
4
4
  "description": "Rule evaluation engine with JIT-optimized sequential evaluation and sub-rules",
5
+ "keywords": [
6
+ "statedelta",
7
+ "rule-engine",
8
+ "jit",
9
+ "conditional-evaluation",
10
+ "sub-rules"
11
+ ],
5
12
  "type": "module",
6
13
  "main": "./dist/index.cjs",
7
14
  "module": "./dist/index.js",
@@ -15,11 +22,12 @@
15
22
  },
16
23
  "files": [
17
24
  "dist",
18
- "README.md"
25
+ "README.md",
26
+ "CHANGELOG.md"
19
27
  ],
20
28
  "dependencies": {
21
- "@statedelta-actions/core": "0.3.0",
22
- "@statedelta-actions/actions": "0.3.0"
29
+ "@statedelta-actions/actions": "0.6.0",
30
+ "@statedelta-actions/core": "0.5.1"
23
31
  },
24
32
  "devDependencies": {
25
33
  "apex-store": "0.4.0"
@@ -31,6 +39,10 @@
31
39
  "url": "https://github.com/andersondrosa/statedelta-actions.git",
32
40
  "directory": "packages/rules"
33
41
  },
42
+ "homepage": "https://github.com/andersondrosa/statedelta-actions/tree/main/packages/rules#readme",
43
+ "bugs": {
44
+ "url": "https://github.com/andersondrosa/statedelta-actions/issues"
45
+ },
34
46
  "sideEffects": false,
35
47
  "engines": {
36
48
  "node": ">=18"