@statedelta-actions/actions 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Motor de execução de diretivas com validação em register-time e compilação JIT.
4
4
 
5
- Defina ações como objetos JS declarativos. Registre. O engine valida estrutura, normaliza diretivas pra forma canônica, compila executores otimizados. Em runtime, invoke é O(1) lookup + execução — zero validação, zero análise.
5
+ Defina ações como objetos JS declarativos. Registre. O engine valida estrutura, compila executores otimizados. Em runtime, invoke é O(1) lookup + execução — zero validação, zero análise.
6
6
 
7
7
  ## Filosofia
8
8
 
@@ -14,6 +14,8 @@ Ações são **declarativas**. Uma action é um ID mais uma lista ordenada de di
14
14
 
15
15
  **Handlers têm fases.** Um handler não é só um executor. Ele pode validar estrutura da diretiva em register-time, contribuir código JIT, e executar em runtime. Cada fase é opcional — uma função simples funciona como handler (compat V1). Uma definição completa desbloqueia todo o pipeline. A fase `analyze` existe na interface mas é consumida pelo `ActionAnalyzer`, não pelo engine.
16
16
 
17
+ **Sem sugar no runtime.** Diretivas devem ser passadas em **forma canônica** — toda diretiva tem campo `type`. Sugar forms (shorthands de autoria) são concern do compilador JSON DSL, que normaliza antes de entregar pro engine. O engine não interpreta nem converte sugar.
18
+
17
19
  ## Instalação
18
20
 
19
21
  ```bash
@@ -73,10 +75,9 @@ const result = engine.register([
73
75
  // result.errors → []
74
76
  // result.warnings → []
75
77
 
76
- // 4. Defina contexto e invoque
77
- engine.setContext({ state: {}, events: [] });
78
-
79
- const r = engine.invoke("heal");
78
+ // 4. Invoque com contexto
79
+ const ctx = { state: {}, events: [] };
80
+ const r = engine.invoke("heal", undefined, ctx);
80
81
  // r.success → true
81
82
  // r.appliedCount → 2
82
83
  ```
@@ -146,16 +147,11 @@ engine.register([{
146
147
 
147
148
  ### Categorias de Diretiva
148
149
 
149
- Três categorias. Todas têm campo `type` na forma canônica. O consumer pode usar a forma sugar (shorthand) — o engine normaliza em register-time.
150
+ Três categorias. **Toda diretiva tem campo `type`** (forma canônica). O engine opera exclusivamente sobre forma canônica.
150
151
 
151
152
  **Binding** — escrita no scope de execução:
152
153
 
153
154
  ```typescript
154
- // Sugar (authoring)
155
- { const: "tax", value: 0.1 }
156
- { let: "total", value: "$", resolve: (ctx, scope) => ({ value: scope.subtotal * 1.1 }) }
157
-
158
- // Forma canônica (após normalização no register)
159
155
  { type: "const", name: "tax", value: 0.1 }
160
156
  { type: "let", name: "total", value: "$", resolve: (ctx, scope) => ({ value: scope.subtotal * 1.1 }) }
161
157
  ```
@@ -163,12 +159,7 @@ Três categorias. Todas têm campo `type` na forma canônica. O consumer pode us
163
159
  **Control** — saída antecipada:
164
160
 
165
161
  ```typescript
166
- // Sugar (authoring)
167
- { return: "done" }
168
- { throw: "saldo insuficiente" }
169
-
170
- // Forma canônica (após normalização no register)
171
- { type: "return", value: "done" } // success: true, data: "done"
162
+ { type: "return", value: "done" } // success: true, data: "done"
172
163
  { type: "throw", message: "saldo insuficiente" } // success: false
173
164
  ```
174
165
 
@@ -179,7 +170,7 @@ Três categorias. Todas têm campo `type` na forma canônica. O consumer pode us
179
170
  { type: "action", id: "heal", catch: [{ type: "emit", event: "heal:failed" }] }
180
171
  ```
181
172
 
182
- Após normalização, **toda diretiva tem `type`**. O interpreter e JIT operam sobre formato uniforme — um único dispatch via `type` field, sem branching de categorias.
173
+ O interpreter e JIT operam sobre formato uniforme — um único dispatch via `type` field, sem branching de categorias.
183
174
 
184
175
  Os nomes `const`, `let`, `return`, `throw` são **tipos reservados** — o engine rejeita handlers com esses nomes.
185
176
 
@@ -197,11 +188,10 @@ const result = engine.register(actions);
197
188
 
198
189
  O pipeline de registro:
199
190
 
200
- 1. **Validate** — valida estrutura via `handler.validate()` (rejeita diretivas malformadas)
201
- 2. **Normalize** — converte sugar forms (`{ const: ... }`, `{ return: ... }`) pra forma canônica (`{ type: "const", ... }`)
202
- 3. **Store** — armazena no registry com diretivas normalizadas
203
- 4. **Compile** — compila executor (interpret/JIT) sobre formato canônico
204
- 5. **Emit** — emite evento `register` via lifecycle events
191
+ 1. **Validate** — valida estrutura via `handler.validate()` (rejeita diretivas malformadas). Diretivas reservadas (`const`, `let`, `return`, `throw`) são reconhecidas pelo `type` e não precisam de handler.
192
+ 2. **Store** — armazena no registry
193
+ 3. **Compile** — compila executor (interpret/JIT)
194
+ 4. **Emit** — emite evento `register` via lifecycle events
205
195
 
206
196
  Retorna `RegisterResult`:
207
197
 
@@ -236,21 +226,34 @@ Suporta aninhamento — `endBatch()` interno é no-op. Processamento acontece na
236
226
  ## Invocação
237
227
 
238
228
  ```typescript
239
- // Defina contexto primeiro
229
+ // Passe ctx direto na invocação (recomendado)
230
+ const result = engine.invoke("heal", undefined, ctx);
231
+ const result = engine.invoke("heal", { amount: 50 }, ctx);
232
+
233
+ // Ou defina ctx global e invoque sem passar ctx
240
234
  engine.setContext(ctx);
241
235
  const result = engine.invoke("heal");
242
- const result = engine.invoke("heal", { amount: 50 });
243
236
 
244
- // Ou contexto com escopo
237
+ // Ou ctx temporário com escopo (múltiplas invocações)
245
238
  engine.context(ctx, () => {
246
239
  engine.invoke("heal");
247
240
  engine.invoke("combat");
248
241
  });
249
242
 
250
243
  // Async (obrigatório se algum hook for async)
251
- const result = await engine.invokeAsync("heal");
244
+ const result = await engine.invokeAsync("heal", undefined, ctx);
252
245
  ```
253
246
 
247
+ Três formas de fornecer ctx, em ordem de preferência:
248
+
249
+ | Forma | Quando usar |
250
+ |-------|-------------|
251
+ | `invoke(id, params, ctx)` | Invocação única, ctx por chamada — mais direto |
252
+ | `context(ctx, fn)` | Múltiplas invocações com mesmo ctx temporário |
253
+ | `setContext(ctx)` | Ctx global estável entre múltiplas invocações |
254
+
255
+ Se `ctx` for passado no `invoke`/`invokeAsync`, tem precedência sobre `setContext`/`context`. Se omitido, fallback pro ctx global (erro se nenhum definido).
256
+
254
257
  Retorna `DirectiveResult`:
255
258
 
256
259
  ```typescript
@@ -395,6 +398,60 @@ Hooks podem ser sync ou async. Hooks async tornam o engine async (`engine.isAsyn
395
398
 
396
399
  **Custo zero quando ausente.** A compilação JIT não emite código de hook para hooks não registrados.
397
400
 
401
+ ## Action Hooks
402
+
403
+ Hooks no nível de **action** — interceptam antes e depois de executar todas as diretivas de uma action. Diferente de `directiveHooks` que operam por diretiva individual.
404
+
405
+ ```typescript
406
+ createActionEngine({
407
+ handlers,
408
+ actionHooks: {
409
+ beforeAction(id, params, frame) {
410
+ // Antes de executar qualquer diretiva da action.
411
+ // Retorne void pra prosseguir normalmente.
412
+ // Retorne { skip: true, data? } pra skip total (zero diretivas processadas).
413
+ },
414
+ afterAction(id, params, result, frame) {
415
+ // Após execução completa. NÃO dispara se beforeAction skipou.
416
+ // Retorne void pra manter resultado original.
417
+ // Retorne DirectiveResult pra substituir.
418
+ },
419
+ },
420
+ });
421
+ ```
422
+
423
+ **Use cases:** memoização, profiling, auditoria, mock/dry-run, governance.
424
+
425
+ ### Memoização via beforeAction
426
+
427
+ O engine não sabe o que é memo. O consumer implementa a lógica via closure (ADR-017):
428
+
429
+ ```typescript
430
+ const cache = new Map<string, { data: unknown }>();
431
+
432
+ const engine = createActionEngine({
433
+ handlers,
434
+ actionHooks: {
435
+ beforeAction(id) {
436
+ const cached = cache.get(id);
437
+ if (cached) return { skip: true, data: cached.data };
438
+ },
439
+ afterAction(id, _params, result) {
440
+ cache.set(id, { data: result.data });
441
+ },
442
+ },
443
+ });
444
+ ```
445
+
446
+ ### Comportamento
447
+
448
+ - **Frame:** O hook recebe o `childFrame` (scope filho, depth incrementado), não o frame do caller.
449
+ - **Skip e auto-promote:** Skip não incrementa `invokeCount` — não conta pro threshold de auto-promote.
450
+ - **Skip e afterAction:** Se `beforeAction` skipar, `afterAction` **não** dispara.
451
+ - **Sub-actions:** Hooks disparam pra cada action na cadeia de invocação (parent e child).
452
+ - **Sem hooks:** Custo zero — um null check por invoke.
453
+ - **JIT:** Zero impacto. Hooks vivem no caller (`_invokeInternal`), não no código gerado.
454
+
398
455
  ## Handler Permissions
399
456
 
400
457
  Controle declarativo de quais diretivas uma instância do engine pode usar. Útil pra governança (sandbox parent→child) e arquitetura (query actions não devem mutar estado).
@@ -506,8 +563,14 @@ import type {
506
563
  DirectivePermissionEntry,
507
564
  } from "@statedelta-actions/actions";
508
565
 
566
+ // Action Hooks
567
+ import type {
568
+ ActionHooks,
569
+ ActionInterceptResult,
570
+ } from "@statedelta-actions/actions";
571
+
509
572
  // Register Pipeline
510
- import { normalizeDirectives, RESERVED_TYPES } from "@statedelta-actions/actions";
573
+ import { RESERVED_TYPES } from "@statedelta-actions/actions";
511
574
 
512
575
  // Emitter
513
576
  import { SimpleEmitter } from "@statedelta-actions/actions";
package/dist/index.cjs CHANGED
@@ -1,9 +1,9 @@
1
- 'use strict';var core=require('@statedelta-actions/core');var F=class{_listeners=new Map;on(e,i){let n=this._listeners.get(e);n||(n=new Set,this._listeners.set(e,n)),n.add(i);let s=false;return ()=>{s||(s=true,n.delete(i),n.size===0&&this._listeners.delete(e));}}once(e,i){let n=this.on(e,s=>{n(),i(s);});return n}emit(e,i){let n=this._listeners.get(e);if(!n||n.size===0)return;let s=[...n];for(let r=0;r<s.length;r++)try{s[r](i);}catch(c){console.error(`[SimpleEmitter] Listener error on "${e}":`,c);}}listenerCount(e){return this._listeners.get(e)?.size??0}hasListeners(e){let i=this._listeners.get(e);return i!==void 0&&i.size>0}off(e){this._listeners.delete(e);}removeAllListeners(){this._listeners.clear();}};var S=new Set(["const","let","return","throw"]);function W(t,e,i,n){let s=[];for(let r=0;r<t.directives.length;r++){let c=t.directives[r];if("const"in c||"let"in c||"return"in c||"throw"in c)continue;let h=c[n];if(!h){s.push(`directive[${r}]: missing type field "${n}"`);continue}if(!e[h]){s.push(`directive[${r}]: no handler for type "${h}"`);continue}let x=i.get(h);if(x?.validate)try{let D=x.validate(c);D&&!D.valid&&s.push(`directive[${r}]: ${D.error??"validation failed"}`);}catch(D){s.push(`directive[${r}]: validate threw: ${D}`);}let m=c.catch;if(m&&Array.isArray(m))for(let D=0;D<m.length;D++){let R=m[D];if("const"in R||"let"in R||"return"in R||"throw"in R)continue;let v=R[n];v&&!e[v]&&s.push(`directive[${r}].catch[${D}]: no handler for type "${v}"`);}}return s}function H(t,e){let i=t.length,n=new Array(i);for(let s=0;s<i;s++){let r=t[s];if("const"in r)n[s]=q(r,"const");else if("let"in r)n[s]=q(r,"let");else if("return"in r)n[s]=te(r);else if("throw"in r)n[s]=re(r);else {let c=r.catch;Array.isArray(c)&&c.length>0?n[s]={...r,catch:H(c)}:n[s]=r;}}return n}function q(t,e){let{[e]:i,...n}=t;return {...n,type:e,name:i}}function te(t){let{return:e,...i}=t;return {...i,type:"return",value:e}}function re(t){let{throw:e,...i}=t;return {...i,type:"throw",message:e}}function M(t,e,i,n,s,r,c){return {success:false,aborted:true,abortedBy:t,appliedCount:e,skippedCount:i,errors:n,processedCount:s,totalCount:r,counters:c}}function ie(t){let e=t.filledNames.has("beforeDirective"),i=t.filledNames.has("afterDirective"),n=t.filledNames.has("onDirectivesComplete");return function(r,c,h,x,m,D,R){let v=Math.min(r.length,R),l=[],f=0,_=0,{counters:u,scope:C}=c,A=c.ctx;for(let a=0;a<v;a++){let p=r[a],$=p[m];if($==="const"||$==="let"){let o=p.name;if(typeof p.resolve=="function")try{C[o]=p.resolve(A,C).value;}catch(d){l.push({directiveIndex:a,error:`Binding resolve: ${d}`}),u.errors++;}else C[o]=p.value;continue}if($==="return"){let o=a+1;if(typeof p.resolve=="function")try{let d=p.resolve(A,C),b="value"in d?d.value:"return"in d?d.return:p.value;return {success:!0,aborted:!1,appliedCount:f,skippedCount:_,errors:l,processedCount:o,totalCount:v,counters:u,data:b}}catch(d){l.push({directiveIndex:a,error:`Control resolve: ${d}`}),u.errors++;}else return {success:true,aborted:false,appliedCount:f,skippedCount:_,errors:l,processedCount:o,totalCount:v,counters:u,data:p.value};continue}if($==="throw"){let o=a+1;if(typeof p.resolve=="function")try{let d=p.resolve(A,C),b="message"in d?d.message:"throw"in d?d.throw:p.message;return {success:!1,aborted:!0,abortedBy:"throw",appliedCount:f,skippedCount:_,errors:l,processedCount:o,totalCount:v,counters:u,data:b}}catch(d){l.push({directiveIndex:a,error:`Control resolve: ${d}`}),u.errors++;}else return {success:false,aborted:true,abortedBy:"throw",appliedCount:f,skippedCount:_,errors:l,processedCount:o,totalCount:v,counters:u,data:p.message};continue}let y=p,E=c;if(e)try{let o=core.processIntercept(x.beforeDirective(y,c),"beforeDirective");if(o.action===core.Intercept.SKIP){_++,u.directivesSkipped++;continue}if(o.action===core.Intercept.ABORT)return M(o.abortReason,f,_,l,a,v,u);o.ctx!==void 0&&(E=c.withCtx(o.ctx)),o.directive!==void 0&&(y=o.directive);}catch(o){l.push({directiveIndex:a,error:`Hook beforeDirective: ${o}`}),u.errors++;}if(typeof y.resolve=="function")try{let o=y.resolve(E.ctx,E.scope);y={...y,...o};}catch(o){l.push({directiveIndex:a,error:`Directive resolve: ${o}`}),u.errors++;continue}let w=y[m],I=w?h[w]:void 0;if(!I){l.push({directiveIndex:a,error:`No handler for directive type: ${w??"undefined"}`}),u.errors++;continue}let g;try{g=I(y,E,D);}catch(o){g={ok:false,error:String(o)};}let T=a+1;if(g.ok){if(f++,u.directivesApplied++,typeof y.as=="string"&&(C[y.as]=g.data),g.halt)return {success:true,aborted:true,abortedBy:"halt",appliedCount:f,skippedCount:_,errors:l,processedCount:T,totalCount:v,counters:u,data:g.data}}else {if(g.halt)return {success:false,aborted:true,abortedBy:"halt",appliedCount:f,skippedCount:_,errors:l,processedCount:T,totalCount:v,counters:u,data:g.data};let o=y.catch;if(Array.isArray(o)&&o.length>0){C.$exception=g.error??"handler failed";let d=D.runDirectives(o,E);f+=d.appliedCount;for(let b=0;b<d.errors.length;b++)l.push(d.errors[b]);if(d.aborted)return {success:d.success,aborted:true,abortedBy:d.abortedBy,appliedCount:f,skippedCount:_,errors:l,processedCount:T,totalCount:v,counters:u,data:d.data}}else l.push({directiveIndex:a,error:g.error??"handler failed"}),u.errors++;}if(i)try{if(x.afterDirective(y,g,E)==="abort")return M("afterDirective",f,_,l,T,v,u)}catch(o){l.push({directiveIndex:a,error:`Hook afterDirective: ${o}`}),u.errors++;}}let k={success:true,aborted:false,appliedCount:f,skippedCount:_,errors:l,processedCount:v,totalCount:v,counters:u};if(n)try{x.onDirectivesComplete(k);}catch{}return k}}function ne(t){let e=t.filledNames.has("beforeDirective"),i=t.filledNames.has("afterDirective"),n=t.filledNames.has("onDirectivesComplete");return async function(r,c,h,x,m,D,R){let v=Math.min(r.length,R),l=[],f=0,_=0,{counters:u,scope:C}=c,A=c.ctx;for(let a=0;a<v;a++){let p=r[a],$=p[m];if($==="const"||$==="let"){let o=p.name;if(typeof p.resolve=="function")try{C[o]=p.resolve(A,C).value;}catch(d){l.push({directiveIndex:a,error:`Binding resolve: ${d}`}),u.errors++;}else C[o]=p.value;continue}if($==="return"){let o=a+1;if(typeof p.resolve=="function")try{let d=p.resolve(A,C),b="value"in d?d.value:"return"in d?d.return:p.value;return {success:!0,aborted:!1,appliedCount:f,skippedCount:_,errors:l,processedCount:o,totalCount:v,counters:u,data:b}}catch(d){l.push({directiveIndex:a,error:`Control resolve: ${d}`}),u.errors++;}else return {success:true,aborted:false,appliedCount:f,skippedCount:_,errors:l,processedCount:o,totalCount:v,counters:u,data:p.value};continue}if($==="throw"){let o=a+1;if(typeof p.resolve=="function")try{let d=p.resolve(A,C),b="message"in d?d.message:"throw"in d?d.throw:p.message;return {success:!1,aborted:!0,abortedBy:"throw",appliedCount:f,skippedCount:_,errors:l,processedCount:o,totalCount:v,counters:u,data:b}}catch(d){l.push({directiveIndex:a,error:`Control resolve: ${d}`}),u.errors++;}else return {success:false,aborted:true,abortedBy:"throw",appliedCount:f,skippedCount:_,errors:l,processedCount:o,totalCount:v,counters:u,data:p.message};continue}let y=p,E=c;if(e)try{let o=core.processIntercept(await x.beforeDirective(y,c),"beforeDirective");if(o.action===core.Intercept.SKIP){_++,u.directivesSkipped++;continue}if(o.action===core.Intercept.ABORT)return M(o.abortReason,f,_,l,a,v,u);o.ctx!==void 0&&(E=c.withCtx(o.ctx)),o.directive!==void 0&&(y=o.directive);}catch(o){l.push({directiveIndex:a,error:`Hook beforeDirective: ${o}`}),u.errors++;}if(typeof y.resolve=="function")try{let o=y.resolve(E.ctx,E.scope);y={...y,...o};}catch(o){l.push({directiveIndex:a,error:`Directive resolve: ${o}`}),u.errors++;continue}let w=y[m],I=w?h[w]:void 0;if(!I){l.push({directiveIndex:a,error:`No handler for directive type: ${w??"undefined"}`}),u.errors++;continue}let g;try{g=I(y,E,D);}catch(o){g={ok:false,error:String(o)};}let T=a+1;if(g.ok){if(f++,u.directivesApplied++,typeof y.as=="string"&&(C[y.as]=g.data),g.halt)return {success:true,aborted:true,abortedBy:"halt",appliedCount:f,skippedCount:_,errors:l,processedCount:T,totalCount:v,counters:u,data:g.data}}else {if(g.halt)return {success:false,aborted:true,abortedBy:"halt",appliedCount:f,skippedCount:_,errors:l,processedCount:T,totalCount:v,counters:u,data:g.data};let o=y.catch;if(Array.isArray(o)&&o.length>0){C.$exception=g.error??"handler failed";let d=await D.runDirectivesAsync(o,E);f+=d.appliedCount;for(let b=0;b<d.errors.length;b++)l.push(d.errors[b]);if(d.aborted)return {success:d.success,aborted:true,abortedBy:d.abortedBy,appliedCount:f,skippedCount:_,errors:l,processedCount:T,totalCount:v,counters:u,data:d.data}}else l.push({directiveIndex:a,error:g.error??"handler failed"}),u.errors++;}if(i)try{if(await x.afterDirective(y,g,E)==="abort")return M("afterDirective",f,_,l,T,v,u)}catch(o){l.push({directiveIndex:a,error:`Hook afterDirective: ${o}`}),u.errors++;}}let k={success:true,aborted:false,appliedCount:f,skippedCount:_,errors:l,processedCount:v,totalCount:v,counters:u};if(n)try{await x.onDirectivesComplete(k);}catch{}return k}}function B(t,e){return e?ne(t):ie(t)}function j(t){let{filledNames:e,hasAnyAsync:i}=t,n=m=>e.has(m),s=m=>t.asyncNames.has(m)?"await ":"",r=[];for(let m of e)r.push(`const ${m} = directiveHooks.${m};`);r.push("const len = Math.min(directives.length, maxDirectives);"),r.push("const errors = []; let appliedCount = 0; let skippedCount = 0;"),r.push("const counters = frame.counters;"),r.push("for (let i = 0; i < len; i++) {"),r.push(" let directive = directives[i];"),n("beforeDirective")?(r.push(" let _df = frame;"),r.push(" try {"),r.push(` const _bd = ${s("beforeDirective")}beforeDirective(directive, frame);`),r.push(' if (_bd === "skip") { skippedCount++; counters.directivesSkipped++; continue; }'),r.push(' if (_bd === "abort") return { success: false, aborted: true, abortedBy: "beforeDirective", appliedCount, skippedCount, errors, processedCount: i, totalCount: len, counters };'),r.push(' if (typeof _bd === "object" && _bd !== null) {'),r.push(' if ("abort" in _bd) return { success: false, aborted: true, abortedBy: _bd.abort, appliedCount, skippedCount, errors, processedCount: i, totalCount: len, counters };'),r.push(' if ("ctx" in _bd) _df = frame.withCtx(_bd.ctx);'),r.push(' if ("directive" in _bd) directive = _bd.directive;'),r.push(" }"),r.push(' } catch (_e) { errors.push({ directiveIndex: i, error: "Hook beforeDirective: " + _e }); counters.errors++; }')):r.push(" const _df = frame;"),r.push(' if (typeof directive.resolve === "function") {'),r.push(" try { const _r = directive.resolve(_df.ctx); directive = Object.assign({}, directive, _r); }"),r.push(' catch (_e) { errors.push({ directiveIndex: i, error: "Directive resolve: " + _e }); counters.errors++; continue; }'),r.push(" }"),r.push(" const _type = directive[typeField];"),r.push(" const _handler = _type ? handlers[_type] : undefined;"),r.push(' if (!_handler) { errors.push({ directiveIndex: i, error: "No handler for directive type: " + (_type || "undefined") }); counters.errors++; continue; }'),r.push(" let _result;"),r.push(" try { _result = _handler(directive, _df, engine); } catch (_e) { errors.push({ directiveIndex: i, error: String(_e) }); counters.errors++; continue; }"),r.push(" if (_result.ok) { appliedCount++; counters.directivesApplied++; }"),r.push(' else { errors.push({ directiveIndex: i, error: _result.error || "handler failed" }); counters.errors++; }'),n("afterDirective")&&(r.push(" try {"),r.push(` const _ad = ${s("afterDirective")}afterDirective(directive, _result, _df);`),r.push(' if (_ad === "abort") return { success: false, aborted: true, abortedBy: "afterDirective", appliedCount, skippedCount, errors, processedCount: i + 1, totalCount: len, counters };'),r.push(' } catch (_e) { errors.push({ directiveIndex: i, error: "Hook afterDirective: " + _e }); counters.errors++; }')),r.push("}"),r.push("const _finalResult = { success: true, aborted: false, appliedCount, skippedCount, errors, processedCount: len, totalCount: len, counters };"),n("onDirectivesComplete")&&r.push(`try { ${s("onDirectivesComplete")}onDirectivesComplete(_finalResult); } catch (_e) {}`),r.push("return _finalResult;");let c=r.join(`
2
- `),h=i?"async ":"";return {fn:new Function("directives","frame","handlers","directiveHooks","typeField","engine","maxDirectives",`"use strict";
3
- return (${h}() => {
1
+ 'use strict';var core=require('@statedelta-actions/core');var H=class{_listeners=new Map;on(e,i){let s=this._listeners.get(e);s||(s=new Set,this._listeners.set(e,s)),s.add(i);let n=false;return ()=>{n||(n=true,s.delete(i),s.size===0&&this._listeners.delete(e));}}once(e,i){let s=this.on(e,n=>{s(),i(n);});return s}emit(e,i){let s=this._listeners.get(e);if(!s||s.size===0)return;let n=[...s];for(let r=0;r<n.length;r++)try{n[r](i);}catch(c){console.error(`[SimpleEmitter] Listener error on "${e}":`,c);}}listenerCount(e){return this._listeners.get(e)?.size??0}hasListeners(e){let i=this._listeners.get(e);return i!==void 0&&i.size>0}off(e){this._listeners.delete(e);}removeAllListeners(){this._listeners.clear();}};var I=new Set(["const","let","return","throw"]);function W(t,e,i,s){let n=[];for(let r=0;r<t.directives.length;r++){let c=t.directives[r],f=c[s];if(!f){n.push(`directive[${r}]: missing type field "${s}"`);continue}if(I.has(f))continue;if(!e[f]){n.push(`directive[${r}]: no handler for type "${f}"`);continue}let _=i.get(f);if(_?.validate)try{let C=_.validate(c);C&&!C.valid&&n.push(`directive[${r}]: ${C.error??"validation failed"}`);}catch(C){n.push(`directive[${r}]: validate threw: ${C}`);}let h=c.catch;if(h&&Array.isArray(h))for(let C=0;C<h.length;C++){let v=h[C][s];v&&I.has(v)||v&&!e[v]&&n.push(`directive[${r}].catch[${C}]: no handler for type "${v}"`);}}return n}function S(t,e){let i=t.length,s=new Array(i);for(let n=0;n<i;n++){let r=t[n],c=r.catch;Array.isArray(c)&&c.length>0?s[n]={...r,catch:S(c)}:s[n]=r;}return s}function P(t,e,i,s,n,r,c){return {success:false,aborted:true,abortedBy:t,appliedCount:e,skippedCount:i,errors:s,processedCount:n,totalCount:r,counters:c}}function te(t){let e=t.filledNames.has("beforeDirective"),i=t.filledNames.has("afterDirective"),s=t.filledNames.has("onDirectivesComplete");return function(r,c,f,_,h,C,T){let v=Math.min(r.length,T),l=[],m=0,x=0,{counters:u,scope:D}=c,R=c.ctx;for(let a=0;a<v;a++){let p=r[a],E=p[h];if(E==="const"||E==="let"){let o=p.name;if(typeof p.resolve=="function")try{D[o]=p.resolve(R,D).value;}catch(d){l.push({directiveIndex:a,error:`Binding resolve: ${d}`}),u.errors++;}else D[o]=p.value;continue}if(E==="return"){let o=a+1;if(typeof p.resolve=="function")try{let d=p.resolve(R,D),b="value"in d?d.value:"return"in d?d.return:p.value;return {success:!0,aborted:!1,appliedCount:m,skippedCount:x,errors:l,processedCount:o,totalCount:v,counters:u,data:b}}catch(d){l.push({directiveIndex:a,error:`Control resolve: ${d}`}),u.errors++;}else return {success:true,aborted:false,appliedCount:m,skippedCount:x,errors:l,processedCount:o,totalCount:v,counters:u,data:p.value};continue}if(E==="throw"){let o=a+1;if(typeof p.resolve=="function")try{let d=p.resolve(R,D),b="message"in d?d.message:"throw"in d?d.throw:p.message;return {success:!1,aborted:!0,abortedBy:"throw",appliedCount:m,skippedCount:x,errors:l,processedCount:o,totalCount:v,counters:u,data:b}}catch(d){l.push({directiveIndex:a,error:`Control resolve: ${d}`}),u.errors++;}else return {success:false,aborted:true,abortedBy:"throw",appliedCount:m,skippedCount:x,errors:l,processedCount:o,totalCount:v,counters:u,data:p.message};continue}let y=p,A=c;if(e)try{let o=core.processIntercept(_.beforeDirective(y,c),"beforeDirective");if(o.action===core.Intercept.SKIP){x++,u.directivesSkipped++;continue}if(o.action===core.Intercept.ABORT)return P(o.abortReason,m,x,l,a,v,u);o.ctx!==void 0&&(A=c.withCtx(o.ctx)),o.directive!==void 0&&(y=o.directive);}catch(o){l.push({directiveIndex:a,error:`Hook beforeDirective: ${o}`}),u.errors++;}if(typeof y.resolve=="function")try{let o=y.resolve(A.ctx,A.scope);y={...y,...o};}catch(o){l.push({directiveIndex:a,error:`Directive resolve: ${o}`}),u.errors++;continue}let w=y[h],F=w?f[w]:void 0;if(!F){l.push({directiveIndex:a,error:`No handler for directive type: ${w??"undefined"}`}),u.errors++;continue}let g;try{g=F(y,A,C);}catch(o){g={ok:false,error:String(o)};}let $=a+1;if(g.ok){if(m++,u.directivesApplied++,typeof y.as=="string"&&(D[y.as]=g.data),g.halt)return {success:true,aborted:true,abortedBy:"halt",appliedCount:m,skippedCount:x,errors:l,processedCount:$,totalCount:v,counters:u,data:g.data}}else {if(g.halt)return {success:false,aborted:true,abortedBy:"halt",appliedCount:m,skippedCount:x,errors:l,processedCount:$,totalCount:v,counters:u,data:g.data};let o=y.catch;if(Array.isArray(o)&&o.length>0){D.$exception=g.error??"handler failed";let d=C.runDirectives(o,A);m+=d.appliedCount;for(let b=0;b<d.errors.length;b++)l.push(d.errors[b]);if(d.aborted)return {success:d.success,aborted:true,abortedBy:d.abortedBy,appliedCount:m,skippedCount:x,errors:l,processedCount:$,totalCount:v,counters:u,data:d.data}}else l.push({directiveIndex:a,error:g.error??"handler failed"}),u.errors++;}if(i)try{if(_.afterDirective(y,g,A)==="abort")return P("afterDirective",m,x,l,$,v,u)}catch(o){l.push({directiveIndex:a,error:`Hook afterDirective: ${o}`}),u.errors++;}}let k={success:true,aborted:false,appliedCount:m,skippedCount:x,errors:l,processedCount:v,totalCount:v,counters:u};if(s)try{_.onDirectivesComplete(k);}catch{}return k}}function re(t){let e=t.filledNames.has("beforeDirective"),i=t.filledNames.has("afterDirective"),s=t.filledNames.has("onDirectivesComplete");return async function(r,c,f,_,h,C,T){let v=Math.min(r.length,T),l=[],m=0,x=0,{counters:u,scope:D}=c,R=c.ctx;for(let a=0;a<v;a++){let p=r[a],E=p[h];if(E==="const"||E==="let"){let o=p.name;if(typeof p.resolve=="function")try{D[o]=p.resolve(R,D).value;}catch(d){l.push({directiveIndex:a,error:`Binding resolve: ${d}`}),u.errors++;}else D[o]=p.value;continue}if(E==="return"){let o=a+1;if(typeof p.resolve=="function")try{let d=p.resolve(R,D),b="value"in d?d.value:"return"in d?d.return:p.value;return {success:!0,aborted:!1,appliedCount:m,skippedCount:x,errors:l,processedCount:o,totalCount:v,counters:u,data:b}}catch(d){l.push({directiveIndex:a,error:`Control resolve: ${d}`}),u.errors++;}else return {success:true,aborted:false,appliedCount:m,skippedCount:x,errors:l,processedCount:o,totalCount:v,counters:u,data:p.value};continue}if(E==="throw"){let o=a+1;if(typeof p.resolve=="function")try{let d=p.resolve(R,D),b="message"in d?d.message:"throw"in d?d.throw:p.message;return {success:!1,aborted:!0,abortedBy:"throw",appliedCount:m,skippedCount:x,errors:l,processedCount:o,totalCount:v,counters:u,data:b}}catch(d){l.push({directiveIndex:a,error:`Control resolve: ${d}`}),u.errors++;}else return {success:false,aborted:true,abortedBy:"throw",appliedCount:m,skippedCount:x,errors:l,processedCount:o,totalCount:v,counters:u,data:p.message};continue}let y=p,A=c;if(e)try{let o=core.processIntercept(await _.beforeDirective(y,c),"beforeDirective");if(o.action===core.Intercept.SKIP){x++,u.directivesSkipped++;continue}if(o.action===core.Intercept.ABORT)return P(o.abortReason,m,x,l,a,v,u);o.ctx!==void 0&&(A=c.withCtx(o.ctx)),o.directive!==void 0&&(y=o.directive);}catch(o){l.push({directiveIndex:a,error:`Hook beforeDirective: ${o}`}),u.errors++;}if(typeof y.resolve=="function")try{let o=y.resolve(A.ctx,A.scope);y={...y,...o};}catch(o){l.push({directiveIndex:a,error:`Directive resolve: ${o}`}),u.errors++;continue}let w=y[h],F=w?f[w]:void 0;if(!F){l.push({directiveIndex:a,error:`No handler for directive type: ${w??"undefined"}`}),u.errors++;continue}let g;try{g=F(y,A,C);}catch(o){g={ok:false,error:String(o)};}let $=a+1;if(g.ok){if(m++,u.directivesApplied++,typeof y.as=="string"&&(D[y.as]=g.data),g.halt)return {success:true,aborted:true,abortedBy:"halt",appliedCount:m,skippedCount:x,errors:l,processedCount:$,totalCount:v,counters:u,data:g.data}}else {if(g.halt)return {success:false,aborted:true,abortedBy:"halt",appliedCount:m,skippedCount:x,errors:l,processedCount:$,totalCount:v,counters:u,data:g.data};let o=y.catch;if(Array.isArray(o)&&o.length>0){D.$exception=g.error??"handler failed";let d=await C.runDirectivesAsync(o,A);m+=d.appliedCount;for(let b=0;b<d.errors.length;b++)l.push(d.errors[b]);if(d.aborted)return {success:d.success,aborted:true,abortedBy:d.abortedBy,appliedCount:m,skippedCount:x,errors:l,processedCount:$,totalCount:v,counters:u,data:d.data}}else l.push({directiveIndex:a,error:g.error??"handler failed"}),u.errors++;}if(i)try{if(await _.afterDirective(y,g,A)==="abort")return P("afterDirective",m,x,l,$,v,u)}catch(o){l.push({directiveIndex:a,error:`Hook afterDirective: ${o}`}),u.errors++;}}let k={success:true,aborted:false,appliedCount:m,skippedCount:x,errors:l,processedCount:v,totalCount:v,counters:u};if(s)try{await _.onDirectivesComplete(k);}catch{}return k}}function B(t,e){return e?re(t):te(t)}function j(t){let{filledNames:e,hasAnyAsync:i}=t,s=h=>e.has(h),n=h=>t.asyncNames.has(h)?"await ":"",r=[];for(let h of e)r.push(`const ${h} = directiveHooks.${h};`);r.push("const len = Math.min(directives.length, maxDirectives);"),r.push("const errors = []; let appliedCount = 0; let skippedCount = 0;"),r.push("const counters = frame.counters;"),r.push("for (let i = 0; i < len; i++) {"),r.push(" let directive = directives[i];"),s("beforeDirective")?(r.push(" let _df = frame;"),r.push(" try {"),r.push(` const _bd = ${n("beforeDirective")}beforeDirective(directive, frame);`),r.push(' if (_bd === "skip") { skippedCount++; counters.directivesSkipped++; continue; }'),r.push(' if (_bd === "abort") return { success: false, aborted: true, abortedBy: "beforeDirective", appliedCount, skippedCount, errors, processedCount: i, totalCount: len, counters };'),r.push(' if (typeof _bd === "object" && _bd !== null) {'),r.push(' if ("abort" in _bd) return { success: false, aborted: true, abortedBy: _bd.abort, appliedCount, skippedCount, errors, processedCount: i, totalCount: len, counters };'),r.push(' if ("ctx" in _bd) _df = frame.withCtx(_bd.ctx);'),r.push(' if ("directive" in _bd) directive = _bd.directive;'),r.push(" }"),r.push(' } catch (_e) { errors.push({ directiveIndex: i, error: "Hook beforeDirective: " + _e }); counters.errors++; }')):r.push(" const _df = frame;"),r.push(' if (typeof directive.resolve === "function") {'),r.push(" try { const _r = directive.resolve(_df.ctx); directive = Object.assign({}, directive, _r); }"),r.push(' catch (_e) { errors.push({ directiveIndex: i, error: "Directive resolve: " + _e }); counters.errors++; continue; }'),r.push(" }"),r.push(" const _type = directive[typeField];"),r.push(" const _handler = _type ? handlers[_type] : undefined;"),r.push(' if (!_handler) { errors.push({ directiveIndex: i, error: "No handler for directive type: " + (_type || "undefined") }); counters.errors++; continue; }'),r.push(" let _result;"),r.push(" try { _result = _handler(directive, _df, engine); } catch (_e) { errors.push({ directiveIndex: i, error: String(_e) }); counters.errors++; continue; }"),r.push(" if (_result.ok) { appliedCount++; counters.directivesApplied++; }"),r.push(' else { errors.push({ directiveIndex: i, error: _result.error || "handler failed" }); counters.errors++; }'),s("afterDirective")&&(r.push(" try {"),r.push(` const _ad = ${n("afterDirective")}afterDirective(directive, _result, _df);`),r.push(' if (_ad === "abort") return { success: false, aborted: true, abortedBy: "afterDirective", appliedCount, skippedCount, errors, processedCount: i + 1, totalCount: len, counters };'),r.push(' } catch (_e) { errors.push({ directiveIndex: i, error: "Hook afterDirective: " + _e }); counters.errors++; }')),r.push("}"),r.push("const _finalResult = { success: true, aborted: false, appliedCount, skippedCount, errors, processedCount: len, totalCount: len, counters };"),s("onDirectivesComplete")&&r.push(`try { ${n("onDirectivesComplete")}onDirectivesComplete(_finalResult); } catch (_e) {}`),r.push("return _finalResult;");let c=r.join(`
2
+ `),f=i?"async ":"";return {fn:new Function("directives","frame","handlers","directiveHooks","typeField","engine","maxDirectives",`"use strict";
3
+ return (${f}() => {
4
4
  ${c}
5
- })();`),isAsync:i}}function N(t,e,i){return `return{success:false,aborted:true,abortedBy:${t},appliedCount,skippedCount,errors,processedCount:${e},totalCount:${i},counters};`}function se(t,e){return `return{success:true,aborted:true,abortedBy:"halt",appliedCount,skippedCount,errors,processedCount:${t},totalCount:${e},counters,data:_result.data};`}function oe(t,e){return `return{success:false,aborted:true,abortedBy:"halt",appliedCount,skippedCount,errors,processedCount:${t},totalCount:${e},counters,data:_result.data};`}function ce(t,e,i){let n=JSON.stringify(e.name);typeof e.resolve=="function"?(t.push("try{"),t.push(`scope[${n}]=$.d[${i}].resolve(ctx,scope).value;`),t.push(`}catch(_e){errors.push({directiveIndex:${i},error:"Binding resolve: "+_e});counters.errors++;}`)):t.push(`scope[${n}]=$.d[${i}].value;`);}function ae(t,e,i,n){let s=typeof e.resolve=="function",r=i+1;s?(t.push("try{"),t.push(`const _rv=$.d[${i}].resolve(ctx,scope);`),t.push(`return{success:true,aborted:false,appliedCount,skippedCount,errors,processedCount:${r},totalCount:${n},counters,data:"value" in _rv?_rv.value:"return" in _rv?_rv.return:$.d[${i}].value};`),t.push(`}catch(_e){errors.push({directiveIndex:${i},error:"Control resolve: "+_e});counters.errors++;}`)):t.push(`return{success:true,aborted:false,appliedCount,skippedCount,errors,processedCount:${r},totalCount:${n},counters,data:$.d[${i}].value};`);}function ue(t,e,i,n){let s=typeof e.resolve=="function",r=i+1;s?(t.push("try{"),t.push(`const _rv=$.d[${i}].resolve(ctx,scope);`),t.push(`return{success:false,aborted:true,abortedBy:"throw",appliedCount,skippedCount,errors,processedCount:${r},totalCount:${n},counters,data:"message" in _rv?_rv.message:"throw" in _rv?_rv.throw:$.d[${i}].message};`),t.push(`}catch(_e){errors.push({directiveIndex:${i},error:"Control resolve: "+_e});counters.errors++;}`)):t.push(`return{success:false,aborted:true,abortedBy:"throw",appliedCount,skippedCount,errors,processedCount:${r},totalCount:${n},counters,data:$.d[${i}].message};`);}function de(t,e,i,n,s,r,c,h,x,m){let D=e[s],R=r.get(D),v=typeof e.resolve=="function",l=typeof e.as=="string",f=Array.isArray(e.catch)&&e.catch.length>0,_=l?JSON.stringify(e.as):"",u=i+1;t.push(`_b${i}:{`);let C=c||v,A=c;C&&t.push(`let _dir=$.d[${i}];`),A&&t.push("let _df=frame;"),c&&(t.push("try{"),t.push(`const _bd=${x}_hookBefore($.d[${i}],frame);`),t.push(`if(_bd==="skip"){skippedCount++;counters.directivesSkipped++;break _b${i};}`),t.push(`if(_bd==="abort")${N('"beforeDirective"',i,n)}`),t.push('if(typeof _bd==="object"&&_bd!==null){'),t.push(`if("abort" in _bd)${N("_bd.abort",i,n)}`),t.push('if("ctx" in _bd)_df=frame.withCtx(_bd.ctx);'),t.push('if("directive" in _bd)_dir=_bd.directive;'),t.push("}"),t.push(`}catch(_e){errors.push({directiveIndex:${i},error:"Hook beforeDirective: "+_e});counters.errors++;}`)),c?(t.push('if(typeof _dir.resolve==="function"){'),t.push("try{const _r=_dir.resolve(_df.ctx,scope);_dir=Object.assign({},_dir,_r);}"),t.push(`catch(_e){errors.push({directiveIndex:${i},error:"Directive resolve: "+_e});counters.errors++;break _b${i};}}`)):v&&(t.push(`try{const _r=$.d[${i}].resolve(ctx,scope);_dir=Object.assign({},$.d[${i}],_r);}`),t.push(`catch(_e){errors.push({directiveIndex:${i},error:"Directive resolve: "+_e});counters.errors++;break _b${i};}`));let k=C?"_dir":`$.d[${i}]`,a=A?"_df":"frame";t.push("let _result;"),t.push(`try{_result=${R}(${k},${a},$.engine);}`),t.push("catch(_e){_result={ok:false,error:String(_e)};}"),t.push("if(_result.ok){"),t.push("appliedCount++;counters.directivesApplied++;"),l&&t.push(`scope[${_}]=_result.data;`),t.push(`if(_result.halt)${se(u,n)}`),t.push("}else{"),t.push(`if(_result.halt)${oe(u,n)}`),f?(t.push('scope.$exception=_result.error||"handler failed";'),t.push(`const _cr=$.runner($.d[${i}].catch,${a});`),t.push("appliedCount+=_cr.appliedCount;"),t.push("for(let _j=0;_j<_cr.errors.length;_j++)errors.push(_cr.errors[_j]);"),t.push(`if(_cr.aborted)return{success:_cr.success,aborted:true,abortedBy:_cr.abortedBy,appliedCount,skippedCount,errors,processedCount:${u},totalCount:${n},counters,data:_cr.data};`)):t.push(`errors.push({directiveIndex:${i},error:_result.error||"handler failed"});counters.errors++;`),t.push("}"),h&&(t.push("try{"),t.push(`const _ad=${m}_hookAfter(${k},_result,${a});`),t.push(`if(_ad==="abort")${N('"afterDirective"',u,n)}`),t.push(`}catch(_e){errors.push({directiveIndex:${i},error:"Hook afterDirective: "+_e});counters.errors++;}`)),t.push("}");}function O(t,e,i){let n=[],s=t.length,{filledNames:r,hasAnyAsync:c,asyncNames:h}=e,x=r.has("beforeDirective"),m=r.has("afterDirective"),D=r.has("onDirectivesComplete"),R=h.has("beforeDirective")?"await ":"",v=h.has("afterDirective")?"await ":"",l=h.has("onDirectivesComplete")?"await ":"",f=new Set;for(let a of t){let p=a[i];p&&!S.has(p)&&f.add(p);}let _=new Map,u=0;for(let a of f)_.set(a,`_h${u++}`);n.push("const counters=frame.counters;"),n.push("const ctx=frame.ctx;"),n.push("const errors=[];"),n.push("let appliedCount=0;"),n.push("let skippedCount=0;");for(let[a,p]of _)n.push(`const ${p}=$.h[${JSON.stringify(a)}];`);x&&n.push("const _hookBefore=$.hooks.beforeDirective;"),m&&n.push("const _hookAfter=$.hooks.afterDirective;");for(let a=0;a<t.length;a++){let p=t[a];switch(p[i]){case "const":case "let":ce(n,p,a);break;case "return":ae(n,p,a,s);break;case "throw":ue(n,p,a,s);break;default:de(n,p,a,s,i,_,x,m,R,v);break}}n.push(`const _finalResult={success:true,aborted:false,appliedCount,skippedCount,errors,processedCount:${s},totalCount:${s},counters};`),D&&n.push(`try{${l}$.hooks.onDirectivesComplete(_finalResult);}catch(_e){}`),n.push("return _finalResult;");let C=n.join(`
6
- `),A=c?"async ":"";return {fn:new Function("frame","scope","$",`"use strict";
7
- return(${A}()=>{
8
- ${C}
9
- })();`),isAsync:c}}function K(t,e,i){return {success:false,aborted:false,appliedCount:0,skippedCount:0,processedCount:0,totalCount:0,errors:[{directiveIndex:-1,error:e}],counters:t,...i}}function U(t,e){return K(e,`Action not found: "${t}"`)}function G(t,e,i){return K(i,`Max depth ${e} exceeded invoking "${t}"`,{aborted:true,abortedBy:"maxDepth"})}function Y(t,e){return K(e,`Action "${t}" is private (sub-action). Can only be invoked from within its parent scope.`)}function le(t){return typeof t=="object"&&t!==null&&"execute"in t}function Q(t){let e=Object.create(null),i=new Map;for(let n of Object.keys(t)){let s=t[n];le(s)?(e[n]=s.execute,i.set(n,s)):(e[n]=s,i.set(n,{execute:s}));}return {handlers:e,definitions:i}}function X(t,e){if(t==="*")return true;if(!t.includes("*"))return t===e;let i=t.replace(/[.+^${}()|[\]\\]/g,"\\$&");return new RegExp("^"+i.replace(/\*/g,".*")+"$").test(e)}function Z(t){return typeof t=="string"?{pattern:t}:t}function L(t,e,i){let n=new Map;if(!e&&!i){for(let s of t)n.set(s,{status:"available"});return n}if(e){let s=e.map(Z);for(let r of t){let c=s.some(h=>X(h.pattern,r));n.set(r,{status:c?"available":"denied"});}}else {let s=i.map(Z);for(let r of t){let c=s.find(h=>X(h.pattern,r));c?n.set(r,{status:"denied",reason:c.reason,source:c.source}):n.set(r,{status:"available"});}}return n}var ve=8,fe="type",z={maxDepth:10,maxRules:1e4,maxDirectives:1e5},V=class{_directiveExecutor;_mode;_ctx;_requestedMode;_threshold;_limits;_typeField;_handlers;_definitions;_directiveHooks;_directiveAnalysis;_isAsync;_directivePermissions;_registry=new Map;_emitter=new F;_batchDepth=0;_batchErrors=[];_batchWarnings=[];_batchActions=[];_batchRegistered=[];_registeredIds=new Set;_directiveRunner;_engineRef;constructor(e){this._requestedMode=e.mode??"auto",this._threshold=e.autoJitThreshold??ve,this._typeField=e.typeField??fe,this._limits={maxDepth:e.limits?.maxDepth??z.maxDepth,maxRules:e.limits?.maxRules??z.maxRules,maxDirectives:e.limits?.maxDirectives??z.maxDirectives};let{handlers:i,definitions:n}=Q(e.handlers);for(let s of Object.keys(e.handlers))if(S.has(s))throw new Error(`Handler type "${s}" is reserved for engine-internal directives`);if(e.allowedDirectives&&e.blockedDirectives)throw new Error("allowedDirectives and blockedDirectives are mutually exclusive. Provide one or neither.");this._handlers=i,this._definitions=n,this._directivePermissions=L(Object.keys(i),e.allowedDirectives,e.blockedDirectives),this._directiveHooks=e.directiveHooks??{},this._directiveAnalysis=core.analyzeSlots(this._directiveHooks,core.DIRECTIVE_SLOT_NAMES),this._isAsync=this._directiveAnalysis.hasAnyAsync,this._engineRef={runDirectives:(s,r)=>this._executeDirectives(s,r),runDirectivesAsync:(s,r)=>this._executeDirectivesAsync(s,r),invoke:(s,r,c)=>this._invokeInternal(s,r,c),invokeAsync:(s,r,c)=>this._invokeInternalAsync(s,r,c),evaluateRules:()=>{throw new Error("evaluateRules() not available in ActionEngine context. Use createRuleEngine().")},evaluateRulesAsync:()=>{throw new Error("evaluateRulesAsync() not available in ActionEngine context. Use createRuleEngine().")}},this._directiveRunner=(s,r)=>this._directiveExecutor(s,r,this._handlers,this._directiveHooks,this._typeField,this._engineRef,this._limits.maxDirectives),this._requestedMode==="jit"?(this._directiveExecutor=this._buildJitDirectiveExecutor(),this._mode="jit"):(this._directiveExecutor=B(this._directiveAnalysis,this._isAsync),this._mode="interpret");}register(e){let i=[],n=[],s=[],r=[];for(let h of e){if(!h.id){n.push({actionId:"",error:"Action must have an id"});continue}let x=W(h,this._handlers,this._definitions,this._typeField);if(x.length>0){for(let m of x)n.push({actionId:h.id,error:m});continue}r.push(h);}for(let h of r){let x=H(h.directives,this._typeField),m={definition:h,directives:x,compiled:null,invokeCount:0};this._requestedMode==="jit"&&(m.compiled=this._compileAction(x)),this._registry.set(h.id,m),this._registeredIds.add(h.id),i.push(h.id);}if(this._batchDepth>0){this._batchErrors.push(...n),this._batchWarnings.push(...s);for(let h of r)this._batchActions.push(h);return this._batchRegistered.push(...i),{registered:i,errors:n,warnings:s}}let c={registered:i,errors:n,warnings:s};return i.length>0&&this._emitter.emit("register",{actions:r,result:c,registered:i}),c}unregister(e){let i=this._registry.delete(e);i&&this._registeredIds.delete(e);let n=e+"/",s=[];for(let r of this._registry.keys())r.startsWith(n)&&(this._registry.delete(r),this._registeredIds.delete(r),s.push(r));return i&&this._emitter.emit("unregister",{id:e,cascaded:s}),i}invoke(e,i){if(this._isAsync)throw new Error("Cannot call invoke() with async hooks. Use invokeAsync() instead.");let n=this._requireCtx(),s=core.createRootFrame(n,this._limits);return this._invokeInternal(e,i,s)}async invokeAsync(e,i){let n=this._requireCtx(),s=core.createRootFrame(n,this._limits);return this._invokeInternalAsync(e,i,s)}setContext(e){this._ctx=e;}context(e,i){let n=this._ctx;this._ctx=e;try{return i()}finally{this._ctx=n;}}beginBatch(){this._batchDepth++,this._batchDepth===1&&(this._batchErrors=[],this._batchWarnings=[],this._batchActions=[],this._batchRegistered=[]);}endBatch(){if(this._batchDepth<=0)throw new Error("endBatch() called without matching beginBatch()");if(this._batchDepth--,this._batchDepth>0)return {registered:[],errors:[],warnings:[]};let e={registered:this._batchRegistered,errors:this._batchErrors,warnings:this._batchWarnings};return this._batchRegistered.length>0&&this._emitter.emit("register",{actions:this._batchActions,result:e,registered:this._batchRegistered}),e}on(e,i){return this._emitter.on(e,i)}get handlerDefinitions(){return this._definitions}get registeredIds(){return this._registeredIds}getActionDefinition(e){return this._registry.get(e)?.definition}get typeField(){return this._typeField}get directivePermissions(){return this._directivePermissions}get isAsync(){return this._isAsync}get compilationMode(){return this._mode}get directiveHookSlots(){return this._directiveAnalysis.filledNames}get asyncSlots(){return this._directiveAnalysis.asyncNames}compile(){if(this._requestedMode!=="interpret"){this._mode!=="jit"&&this._promote();for(let e of this._registry.values())e.compiled||(e.compiled=this._compileAction(e.directives));}}_invokeInternal(e,i,n){let s=this._prepareInvoke(e,i,n);if("success"in s)return s;let{stored:r,childFrame:c,childScope:h}=s;if(r.compiled)return r.compiled.fn(c,h,r.compiled.$);let x=this._directiveRunner(r.directives,c);return this._maybeAutoPromote(r),x}async _invokeInternalAsync(e,i,n){let s=this._prepareInvoke(e,i,n);if("success"in s)return s;let{stored:r,childFrame:c,childScope:h}=s;if(r.compiled)return r.compiled.fn(c,h,r.compiled.$);let x=this._directiveRunner(r.directives,c);return this._maybeAutoPromote(r),x}_prepareInvoke(e,i,n){let s=this._registry.get(e);if(!s)return U(e,n.counters);if(e.includes("/")&&!this._isAccessible(e,n))return Y(e,n.counters);if(n.depth>=n.limits.maxDepth)return G(e,n.limits.maxDepth,n.counters);let r=Object.create(n.scope);i&&Object.assign(r,i);let c=n.child("action:"+e,0,e).withScope(r);return {stored:s,childFrame:c,childScope:r}}_maybeAutoPromote(e){this._requestedMode==="auto"&&++e.invokeCount>=this._threshold&&(e.compiled=this._compileAction(e.directives),this._mode!=="jit"&&this._promote());}_executeDirectives(e,i){return this._directiveExecutor(e,i,this._handlers,this._directiveHooks,this._typeField,this._engineRef,this._limits.maxDirectives)}async _executeDirectivesAsync(e,i){return this._directiveExecutor(e,i,this._handlers,this._directiveHooks,this._typeField,this._engineRef,this._limits.maxDirectives)}_compileAction(e){let{fn:i}=O(e,this._directiveAnalysis,this._typeField),n={d:e,h:this._handlers,hooks:this._directiveHooks,engine:this._engineRef,runner:this._directiveRunner};return {fn:i,$:n}}_isAccessible(e,i){let s="action:"+e.slice(0,e.lastIndexOf("/"));return i.path.includes(s)}_requireCtx(){if(this._ctx===void 0)throw new Error("No context set. Call setContext(ctx) or use context(ctx, fn) before invoke.");return this._ctx}_promote(){this._directiveExecutor=this._buildJitDirectiveExecutor(),this._mode="jit";}_buildJitDirectiveExecutor(){let{fn:e}=j(this._directiveAnalysis);return e}};function _e(t){return new V(t)}exports.RESERVED_TYPES=S;exports.SimpleEmitter=F;exports.buildActionExecutor=O;exports.buildDirectiveExecutor=j;exports.createActionEngine=_e;exports.createDirectiveInterpreter=B;exports.normalizeDirectives=H;
5
+ })();`),isAsync:i}}function N(t,e,i){return `return{success:false,aborted:true,abortedBy:${t},appliedCount,skippedCount,errors,processedCount:${e},totalCount:${i},counters};`}function ie(t,e){return `return{success:true,aborted:true,abortedBy:"halt",appliedCount,skippedCount,errors,processedCount:${t},totalCount:${e},counters,data:_result.data};`}function se(t,e){return `return{success:false,aborted:true,abortedBy:"halt",appliedCount,skippedCount,errors,processedCount:${t},totalCount:${e},counters,data:_result.data};`}function ne(t,e,i){let s=JSON.stringify(e.name);typeof e.resolve=="function"?(t.push("try{"),t.push(`scope[${s}]=$.d[${i}].resolve(ctx,scope).value;`),t.push(`}catch(_e){errors.push({directiveIndex:${i},error:"Binding resolve: "+_e});counters.errors++;}`)):t.push(`scope[${s}]=$.d[${i}].value;`);}function oe(t,e,i,s){let n=typeof e.resolve=="function",r=i+1;n?(t.push("try{"),t.push(`const _rv=$.d[${i}].resolve(ctx,scope);`),t.push(`return{success:true,aborted:false,appliedCount,skippedCount,errors,processedCount:${r},totalCount:${s},counters,data:"value" in _rv?_rv.value:"return" in _rv?_rv.return:$.d[${i}].value};`),t.push(`}catch(_e){errors.push({directiveIndex:${i},error:"Control resolve: "+_e});counters.errors++;}`)):t.push(`return{success:true,aborted:false,appliedCount,skippedCount,errors,processedCount:${r},totalCount:${s},counters,data:$.d[${i}].value};`);}function ce(t,e,i,s){let n=typeof e.resolve=="function",r=i+1;n?(t.push("try{"),t.push(`const _rv=$.d[${i}].resolve(ctx,scope);`),t.push(`return{success:false,aborted:true,abortedBy:"throw",appliedCount,skippedCount,errors,processedCount:${r},totalCount:${s},counters,data:"message" in _rv?_rv.message:"throw" in _rv?_rv.throw:$.d[${i}].message};`),t.push(`}catch(_e){errors.push({directiveIndex:${i},error:"Control resolve: "+_e});counters.errors++;}`)):t.push(`return{success:false,aborted:true,abortedBy:"throw",appliedCount,skippedCount,errors,processedCount:${r},totalCount:${s},counters,data:$.d[${i}].message};`);}function ae(t,e,i,s,n,r,c,f,_,h){let C=e[n],T=r.get(C),v=typeof e.resolve=="function",l=typeof e.as=="string",m=Array.isArray(e.catch)&&e.catch.length>0,x=l?JSON.stringify(e.as):"",u=i+1;t.push(`_b${i}:{`);let D=c||v,R=c;D&&t.push(`let _dir=$.d[${i}];`),R&&t.push("let _df=frame;"),c&&(t.push("try{"),t.push(`const _bd=${_}_hookBefore($.d[${i}],frame);`),t.push(`if(_bd==="skip"){skippedCount++;counters.directivesSkipped++;break _b${i};}`),t.push(`if(_bd==="abort")${N('"beforeDirective"',i,s)}`),t.push('if(typeof _bd==="object"&&_bd!==null){'),t.push(`if("abort" in _bd)${N("_bd.abort",i,s)}`),t.push('if("ctx" in _bd)_df=frame.withCtx(_bd.ctx);'),t.push('if("directive" in _bd)_dir=_bd.directive;'),t.push("}"),t.push(`}catch(_e){errors.push({directiveIndex:${i},error:"Hook beforeDirective: "+_e});counters.errors++;}`)),c?(t.push('if(typeof _dir.resolve==="function"){'),t.push("try{const _r=_dir.resolve(_df.ctx,scope);_dir=Object.assign({},_dir,_r);}"),t.push(`catch(_e){errors.push({directiveIndex:${i},error:"Directive resolve: "+_e});counters.errors++;break _b${i};}}`)):v&&(t.push(`try{const _r=$.d[${i}].resolve(ctx,scope);_dir=Object.assign({},$.d[${i}],_r);}`),t.push(`catch(_e){errors.push({directiveIndex:${i},error:"Directive resolve: "+_e});counters.errors++;break _b${i};}`));let k=D?"_dir":`$.d[${i}]`,a=R?"_df":"frame";t.push("let _result;"),t.push(`try{_result=${T}(${k},${a},$.engine);}`),t.push("catch(_e){_result={ok:false,error:String(_e)};}"),t.push("if(_result.ok){"),t.push("appliedCount++;counters.directivesApplied++;"),l&&t.push(`scope[${x}]=_result.data;`),t.push(`if(_result.halt)${ie(u,s)}`),t.push("}else{"),t.push(`if(_result.halt)${se(u,s)}`),m?(t.push('scope.$exception=_result.error||"handler failed";'),t.push(`const _cr=$.runner($.d[${i}].catch,${a});`),t.push("appliedCount+=_cr.appliedCount;"),t.push("for(let _j=0;_j<_cr.errors.length;_j++)errors.push(_cr.errors[_j]);"),t.push(`if(_cr.aborted)return{success:_cr.success,aborted:true,abortedBy:_cr.abortedBy,appliedCount,skippedCount,errors,processedCount:${u},totalCount:${s},counters,data:_cr.data};`)):t.push(`errors.push({directiveIndex:${i},error:_result.error||"handler failed"});counters.errors++;`),t.push("}"),f&&(t.push("try{"),t.push(`const _ad=${h}_hookAfter(${k},_result,${a});`),t.push(`if(_ad==="abort")${N('"afterDirective"',u,s)}`),t.push(`}catch(_e){errors.push({directiveIndex:${i},error:"Hook afterDirective: "+_e});counters.errors++;}`)),t.push("}");}function O(t,e,i){let s=[],n=t.length,{filledNames:r,hasAnyAsync:c,asyncNames:f}=e,_=r.has("beforeDirective"),h=r.has("afterDirective"),C=r.has("onDirectivesComplete"),T=f.has("beforeDirective")?"await ":"",v=f.has("afterDirective")?"await ":"",l=f.has("onDirectivesComplete")?"await ":"",m=new Set;for(let a of t){let p=a[i];p&&!I.has(p)&&m.add(p);}let x=new Map,u=0;for(let a of m)x.set(a,`_h${u++}`);s.push("const counters=frame.counters;"),s.push("const ctx=frame.ctx;"),s.push("const errors=[];"),s.push("let appliedCount=0;"),s.push("let skippedCount=0;");for(let[a,p]of x)s.push(`const ${p}=$.h[${JSON.stringify(a)}];`);_&&s.push("const _hookBefore=$.hooks.beforeDirective;"),h&&s.push("const _hookAfter=$.hooks.afterDirective;");for(let a=0;a<t.length;a++){let p=t[a];switch(p[i]){case "const":case "let":ne(s,p,a);break;case "return":oe(s,p,a,n);break;case "throw":ce(s,p,a,n);break;default:ae(s,p,a,n,i,x,_,h,T,v);break}}s.push(`const _finalResult={success:true,aborted:false,appliedCount,skippedCount,errors,processedCount:${n},totalCount:${n},counters};`),C&&s.push(`try{${l}$.hooks.onDirectivesComplete(_finalResult);}catch(_e){}`),s.push("return _finalResult;");let D=s.join(`
6
+ `),R=c?"async ":"";return {fn:new Function("frame","scope","$",`"use strict";
7
+ return(${R}()=>{
8
+ ${D}
9
+ })();`),isAsync:c}}function K(t,e,i){return {success:false,aborted:false,appliedCount:0,skippedCount:0,processedCount:0,totalCount:0,errors:[{directiveIndex:-1,error:e}],counters:t,...i}}function U(t,e){return K(e,`Action not found: "${t}"`)}function G(t,e,i){return K(i,`Max depth ${e} exceeded invoking "${t}"`,{aborted:true,abortedBy:"maxDepth"})}function Y(t,e){return K(e,`Action "${t}" is private (sub-action). Can only be invoked from within its parent scope.`)}function z(t,e){return {success:true,aborted:false,appliedCount:0,skippedCount:0,processedCount:0,totalCount:0,errors:[],data:t,counters:e}}function ue(t){return typeof t=="object"&&t!==null&&"execute"in t}function Q(t){let e=Object.create(null),i=new Map;for(let s of Object.keys(t)){let n=t[s];ue(n)?(e[s]=n.execute,i.set(s,n)):(e[s]=n,i.set(s,{execute:n}));}return {handlers:e,definitions:i}}function X(t,e){if(t==="*")return true;if(!t.includes("*"))return t===e;let i=t.replace(/[.+^${}()|[\]\\]/g,"\\$&");return new RegExp("^"+i.replace(/\*/g,".*")+"$").test(e)}function Z(t){return typeof t=="string"?{pattern:t}:t}function L(t,e,i){let s=new Map;if(!e&&!i){for(let n of t)s.set(n,{status:"available"});return s}if(e){let n=e.map(Z);for(let r of t){let c=n.some(f=>X(f.pattern,r));s.set(r,{status:c?"available":"denied"});}}else {let n=i.map(Z);for(let r of t){let c=n.find(f=>X(f.pattern,r));c?s.set(r,{status:"denied",reason:c.reason,source:c.source}):s.set(r,{status:"available"});}}return s}var pe=8,he="type",V={maxDepth:10,maxRules:1e4,maxDirectives:1e5},q=class{_directiveExecutor;_mode;_ctx;_requestedMode;_threshold;_limits;_typeField;_handlers;_definitions;_directiveHooks;_directiveAnalysis;_isAsync;_directivePermissions;_beforeAction;_afterAction;_registry=new Map;_emitter=new H;_batchDepth=0;_batchErrors=[];_batchWarnings=[];_batchActions=[];_batchRegistered=[];_registeredIds=new Set;_directiveRunner;_engineRef;constructor(e){this._requestedMode=e.mode??"auto",this._threshold=e.autoJitThreshold??pe,this._typeField=e.typeField??he,this._limits={maxDepth:e.limits?.maxDepth??V.maxDepth,maxRules:e.limits?.maxRules??V.maxRules,maxDirectives:e.limits?.maxDirectives??V.maxDirectives};let{handlers:i,definitions:s}=Q(e.handlers);for(let n of Object.keys(e.handlers))if(I.has(n))throw new Error(`Handler type "${n}" is reserved for engine-internal directives`);if(e.allowedDirectives&&e.blockedDirectives)throw new Error("allowedDirectives and blockedDirectives are mutually exclusive. Provide one or neither.");this._handlers=i,this._definitions=s,this._directivePermissions=L(Object.keys(i),e.allowedDirectives,e.blockedDirectives),this._directiveHooks=e.directiveHooks??{},this._beforeAction=e.actionHooks?.beforeAction??null,this._afterAction=e.actionHooks?.afterAction??null,this._directiveAnalysis=core.analyzeSlots(this._directiveHooks,core.DIRECTIVE_SLOT_NAMES),this._isAsync=this._directiveAnalysis.hasAnyAsync,this._engineRef={runDirectives:(n,r)=>this._executeDirectives(n,r),runDirectivesAsync:(n,r)=>this._executeDirectivesAsync(n,r),invoke:(n,r,c)=>this._invokeInternal(n,r,c),invokeAsync:(n,r,c)=>this._invokeInternalAsync(n,r,c),evaluateRules:()=>{throw new Error("evaluateRules() not available in ActionEngine context. Use createRuleEngine().")},evaluateRulesAsync:()=>{throw new Error("evaluateRulesAsync() not available in ActionEngine context. Use createRuleEngine().")}},this._directiveRunner=(n,r)=>this._directiveExecutor(n,r,this._handlers,this._directiveHooks,this._typeField,this._engineRef,this._limits.maxDirectives),this._requestedMode==="jit"?(this._directiveExecutor=this._buildJitDirectiveExecutor(),this._mode="jit"):(this._directiveExecutor=B(this._directiveAnalysis,this._isAsync),this._mode="interpret");}register(e){let i=[],s=[],n=[],r=[];for(let f of e){if(!f.id){s.push({actionId:"",error:"Action must have an id"});continue}let _=W(f,this._handlers,this._definitions,this._typeField);if(_.length>0){for(let h of _)s.push({actionId:f.id,error:h});continue}r.push(f);}for(let f of r){let _=S(f.directives,this._typeField),h={definition:f,directives:_,compiled:null,invokeCount:0};this._requestedMode==="jit"&&(h.compiled=this._compileAction(_)),this._registry.set(f.id,h),this._registeredIds.add(f.id),i.push(f.id);}if(this._batchDepth>0){this._batchErrors.push(...s),this._batchWarnings.push(...n);for(let f of r)this._batchActions.push(f);return this._batchRegistered.push(...i),{registered:i,errors:s,warnings:n}}let c={registered:i,errors:s,warnings:n};return i.length>0&&this._emitter.emit("register",{actions:r,result:c,registered:i}),c}unregister(e){let i=this._registry.delete(e);i&&this._registeredIds.delete(e);let s=e+"/",n=[];for(let r of this._registry.keys())r.startsWith(s)&&(this._registry.delete(r),this._registeredIds.delete(r),n.push(r));return i&&this._emitter.emit("unregister",{id:e,cascaded:n}),i}invoke(e,i,s){if(this._isAsync)throw new Error("Cannot call invoke() with async hooks. Use invokeAsync() instead.");let n=s!==void 0?s:this._requireCtx(),r=core.createRootFrame(n,this._limits);return this._invokeInternal(e,i,r)}async invokeAsync(e,i,s){let n=s!==void 0?s:this._requireCtx(),r=core.createRootFrame(n,this._limits);return this._invokeInternalAsync(e,i,r)}setContext(e){this._ctx=e;}context(e,i){let s=this._ctx;this._ctx=e;try{return i()}finally{this._ctx=s;}}beginBatch(){this._batchDepth++,this._batchDepth===1&&(this._batchErrors=[],this._batchWarnings=[],this._batchActions=[],this._batchRegistered=[]);}endBatch(){if(this._batchDepth<=0)throw new Error("endBatch() called without matching beginBatch()");if(this._batchDepth--,this._batchDepth>0)return {registered:[],errors:[],warnings:[]};let e={registered:this._batchRegistered,errors:this._batchErrors,warnings:this._batchWarnings};return this._batchRegistered.length>0&&this._emitter.emit("register",{actions:this._batchActions,result:e,registered:this._batchRegistered}),e}on(e,i){return this._emitter.on(e,i)}get handlerDefinitions(){return this._definitions}get registeredIds(){return this._registeredIds}getActionDefinition(e){return this._registry.get(e)?.definition}get typeField(){return this._typeField}get directivePermissions(){return this._directivePermissions}get isAsync(){return this._isAsync}get compilationMode(){return this._mode}get directiveHookSlots(){return this._directiveAnalysis.filledNames}get asyncSlots(){return this._directiveAnalysis.asyncNames}compile(){if(this._requestedMode!=="interpret"){this._mode!=="jit"&&this._promote();for(let e of this._registry.values())e.compiled||(e.compiled=this._compileAction(e.directives));}}_invokeInternal(e,i,s){let n=this._prepareInvoke(e,i,s);if("success"in n)return n;let{stored:r,childFrame:c,childScope:f}=n;if(this._beforeAction!==null){let h=this._beforeAction(e,i,c);if(h?.skip)return z(h.data,c.counters)}let _;if(r.compiled?_=r.compiled.fn(c,f,r.compiled.$):(_=this._directiveRunner(r.directives,c),this._maybeAutoPromote(r)),this._afterAction!==null){let h=this._afterAction(e,i,_,c);h!==void 0&&(_=h);}return _}async _invokeInternalAsync(e,i,s){let n=this._prepareInvoke(e,i,s);if("success"in n)return n;let{stored:r,childFrame:c,childScope:f}=n;if(this._beforeAction!==null){let h=this._beforeAction(e,i,c);if(h?.skip)return z(h.data,c.counters)}let _;if(r.compiled?_=await r.compiled.fn(c,f,r.compiled.$):(_=await this._directiveRunner(r.directives,c),this._maybeAutoPromote(r)),this._afterAction!==null){let h=this._afterAction(e,i,_,c);h!==void 0&&(_=h);}return _}_prepareInvoke(e,i,s){let n=this._registry.get(e);if(!n)return U(e,s.counters);if(e.includes("/")&&!this._isAccessible(e,s))return Y(e,s.counters);if(s.depth>=s.limits.maxDepth)return G(e,s.limits.maxDepth,s.counters);let r=Object.create(s.scope);i&&Object.assign(r,i);let c=s.child("action:"+e,0,e).withScope(r);return {stored:n,childFrame:c,childScope:r}}_maybeAutoPromote(e){this._requestedMode==="auto"&&++e.invokeCount>=this._threshold&&(e.compiled=this._compileAction(e.directives),this._mode!=="jit"&&this._promote());}_executeDirectives(e,i){return this._directiveExecutor(e,i,this._handlers,this._directiveHooks,this._typeField,this._engineRef,this._limits.maxDirectives)}async _executeDirectivesAsync(e,i){return this._directiveExecutor(e,i,this._handlers,this._directiveHooks,this._typeField,this._engineRef,this._limits.maxDirectives)}_compileAction(e){let{fn:i}=O(e,this._directiveAnalysis,this._typeField),s={d:e,h:this._handlers,hooks:this._directiveHooks,engine:this._engineRef,runner:this._directiveRunner};return {fn:i,$:s}}_isAccessible(e,i){let n="action:"+e.slice(0,e.lastIndexOf("/"));return i.path.includes(n)}_requireCtx(){if(this._ctx===void 0)throw new Error("No context set. Pass ctx to invoke(id, params, ctx), call setContext(ctx), or use context(ctx, fn).");return this._ctx}_promote(){this._directiveExecutor=this._buildJitDirectiveExecutor(),this._mode="jit";}_buildJitDirectiveExecutor(){let{fn:e}=j(this._directiveAnalysis);return e}};function fe(t){return new q(t)}exports.RESERVED_TYPES=I;exports.SimpleEmitter=H;exports.buildActionExecutor=O;exports.buildDirectiveExecutor=j;exports.createActionEngine=fe;exports.createDirectiveInterpreter=B;exports.normalizeDirectives=S;
package/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { Directive, ExecutionFrame, RuleEngineRef, ApplyResult, HookFn, InterceptResult, AbortDecision, DirectiveResult, ActionEngineRef, FrameLimits, SlotAnalysis } from '@statedelta-actions/core';
1
+ import { Directive, ExecutionFrame, DirectiveResult, RuleEngineRef, ApplyResult, HookFn, InterceptResult, AbortDecision, ActionEngineRef, FrameLimits, SlotAnalysis } from '@statedelta-actions/core';
2
2
 
3
3
  type DirectiveHandler<TCtx> = (directive: Directive, frame: ExecutionFrame<TCtx>, engine: RuleEngineRef<TCtx>) => ApplyResult;
4
4
  type DirectiveHandlerMap<TCtx> = Record<string, DirectiveHandler<TCtx>>;
@@ -138,13 +138,47 @@ interface DirectivePermissionConfig {
138
138
  * String pura é equivalente a `{ pattern: string }`.
139
139
  */
140
140
  type DirectivePermissionEntry = string | DirectivePermissionConfig;
141
+ /** Resultado de interceptação do beforeAction — skip total da execução. */
142
+ interface ActionInterceptResult {
143
+ readonly data?: unknown;
144
+ readonly skip: true;
145
+ }
146
+ /**
147
+ * Hooks no nível de action — interceptam antes/depois de executar
148
+ * todas as diretivas de uma action. Diferente de DirectiveHooks que
149
+ * operam dentro da execução (por diretiva).
150
+ *
151
+ * Sync na v0. Async como evolução futura.
152
+ */
153
+ interface ActionHooks<TCtx> {
154
+ /**
155
+ * Chamado antes de executar as diretivas de uma action.
156
+ * O frame recebido é o childFrame (scope filho, path com action:{id}).
157
+ *
158
+ * - void/undefined → executa normalmente
159
+ * - { skip: true, data? } → skip total, retorna DirectiveResult fabricado
160
+ *
161
+ * Se skip, afterAction NÃO dispara e invokeCount NÃO incrementa.
162
+ */
163
+ beforeAction?: (id: string, params: Record<string, unknown> | undefined, frame: ExecutionFrame<TCtx>) => ActionInterceptResult | void;
164
+ /**
165
+ * Chamado após a execução completa de uma action.
166
+ * NÃO dispara se beforeAction retornou skip.
167
+ *
168
+ * - void/undefined → resultado original mantido
169
+ * - DirectiveResult → substitui o resultado
170
+ */
171
+ afterAction?: (id: string, params: Record<string, unknown> | undefined, result: DirectiveResult, frame: ExecutionFrame<TCtx>) => DirectiveResult | void;
172
+ }
141
173
  interface IActionEngineConfig<TCtx> {
142
174
  /** Handlers com fases (V2) ou funções simples (V1 compat). */
143
175
  handlers: HandlerInputMap<TCtx>;
144
176
  /** Campo de tipo pra dispatch (default: "type"). */
145
177
  typeField?: string;
146
- /** Hooks de directive. */
178
+ /** Hooks de directive (nível de diretiva individual). */
147
179
  directiveHooks?: DirectiveHooks<TCtx>;
180
+ /** Hooks de action (nível de action inteira — antes/depois de todas as diretivas). */
181
+ actionHooks?: ActionHooks<TCtx>;
148
182
  /** Limites de execução. */
149
183
  limits?: Partial<FrameLimits>;
150
184
  /** Modo de compilação. */
@@ -175,10 +209,10 @@ interface IActionEngine<TCtx> {
175
209
  beginBatch(): void;
176
210
  /** Finaliza batch. Executa análise, typecheck, indexação. */
177
211
  endBatch(): RegisterResult;
178
- /** Invoca action por ID. Lookup O(1). */
179
- invoke(id: string, params?: Record<string, unknown>): DirectiveResult;
180
- /** Invoca action async. */
181
- invokeAsync(id: string, params?: Record<string, unknown>): Promise<DirectiveResult>;
212
+ /** Invoca action por ID. Lookup O(1). ctx opcional — se omitido, usa setContext/context. */
213
+ invoke(id: string, params?: Record<string, unknown>, ctx?: TCtx): DirectiveResult;
214
+ /** Invoca action async. ctx opcional — se omitido, usa setContext/context. */
215
+ invokeAsync(id: string, params?: Record<string, unknown>, ctx?: TCtx): Promise<DirectiveResult>;
182
216
  /** Seta ctx global. */
183
217
  setContext(ctx: TCtx): void;
184
218
  /** Override temporário de ctx dentro do callback. */
@@ -254,7 +288,7 @@ declare class SimpleEmitter<TEvents = Record<string, unknown>> {
254
288
  }
255
289
 
256
290
  declare const RESERVED_TYPES: Set<string>;
257
- declare function normalizeDirectives<TCtx>(directives: readonly Directive<TCtx>[], typeField: string): Directive<TCtx>[];
291
+ declare function normalizeDirectives<TCtx>(directives: readonly Directive<TCtx>[], _typeField: string): Directive<TCtx>[];
258
292
 
259
293
  declare function createDirectiveInterpreter<TCtx>(analysis: SlotAnalysis, isAsync: boolean): DirectiveExecutorFn<TCtx>;
260
294
 
@@ -274,4 +308,4 @@ interface GeneratedActionExecutor {
274
308
  }
275
309
  declare function buildActionExecutor(directives: readonly Directive[], analysis: SlotAnalysis, typeField: string): GeneratedActionExecutor;
276
310
 
277
- export { type ActionDefinition, type DirectiveExecutorFn, type DirectiveHandler, type DirectiveHandlerMap, type DirectiveHooks, type DirectivePermission, type DirectivePermissionConfig, type DirectivePermissionEntry, type DirectivePermissionStatus, type DirectiveRunnerFn, type EngineEventMap, type EngineEventName, type GeneratedActionExecutor, type GeneratedDirectiveExecutor, type HandlerAnalysis, type HandlerDefinition, type HandlerInput, type HandlerInputMap, type IActionEngine, type IActionEngineConfig, type Listener, RESERVED_TYPES, type RegisterError, type RegisterEvent, type RegisterResult, type RegisterWarning, SimpleEmitter, type UnregisterEvent, type ValidationResult, buildActionExecutor, buildDirectiveExecutor, createActionEngine, createDirectiveInterpreter, normalizeDirectives };
311
+ export { type ActionDefinition, type ActionHooks, type ActionInterceptResult, type DirectiveExecutorFn, type DirectiveHandler, type DirectiveHandlerMap, type DirectiveHooks, type DirectivePermission, type DirectivePermissionConfig, type DirectivePermissionEntry, type DirectivePermissionStatus, type DirectiveRunnerFn, type EngineEventMap, type EngineEventName, type GeneratedActionExecutor, type GeneratedDirectiveExecutor, type HandlerAnalysis, type HandlerDefinition, type HandlerInput, type HandlerInputMap, type IActionEngine, type IActionEngineConfig, type Listener, RESERVED_TYPES, type RegisterError, type RegisterEvent, type RegisterResult, type RegisterWarning, SimpleEmitter, type UnregisterEvent, type ValidationResult, buildActionExecutor, buildDirectiveExecutor, createActionEngine, createDirectiveInterpreter, normalizeDirectives };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Directive, ExecutionFrame, RuleEngineRef, ApplyResult, HookFn, InterceptResult, AbortDecision, DirectiveResult, ActionEngineRef, FrameLimits, SlotAnalysis } from '@statedelta-actions/core';
1
+ import { Directive, ExecutionFrame, DirectiveResult, RuleEngineRef, ApplyResult, HookFn, InterceptResult, AbortDecision, ActionEngineRef, FrameLimits, SlotAnalysis } from '@statedelta-actions/core';
2
2
 
3
3
  type DirectiveHandler<TCtx> = (directive: Directive, frame: ExecutionFrame<TCtx>, engine: RuleEngineRef<TCtx>) => ApplyResult;
4
4
  type DirectiveHandlerMap<TCtx> = Record<string, DirectiveHandler<TCtx>>;
@@ -138,13 +138,47 @@ interface DirectivePermissionConfig {
138
138
  * String pura é equivalente a `{ pattern: string }`.
139
139
  */
140
140
  type DirectivePermissionEntry = string | DirectivePermissionConfig;
141
+ /** Resultado de interceptação do beforeAction — skip total da execução. */
142
+ interface ActionInterceptResult {
143
+ readonly data?: unknown;
144
+ readonly skip: true;
145
+ }
146
+ /**
147
+ * Hooks no nível de action — interceptam antes/depois de executar
148
+ * todas as diretivas de uma action. Diferente de DirectiveHooks que
149
+ * operam dentro da execução (por diretiva).
150
+ *
151
+ * Sync na v0. Async como evolução futura.
152
+ */
153
+ interface ActionHooks<TCtx> {
154
+ /**
155
+ * Chamado antes de executar as diretivas de uma action.
156
+ * O frame recebido é o childFrame (scope filho, path com action:{id}).
157
+ *
158
+ * - void/undefined → executa normalmente
159
+ * - { skip: true, data? } → skip total, retorna DirectiveResult fabricado
160
+ *
161
+ * Se skip, afterAction NÃO dispara e invokeCount NÃO incrementa.
162
+ */
163
+ beforeAction?: (id: string, params: Record<string, unknown> | undefined, frame: ExecutionFrame<TCtx>) => ActionInterceptResult | void;
164
+ /**
165
+ * Chamado após a execução completa de uma action.
166
+ * NÃO dispara se beforeAction retornou skip.
167
+ *
168
+ * - void/undefined → resultado original mantido
169
+ * - DirectiveResult → substitui o resultado
170
+ */
171
+ afterAction?: (id: string, params: Record<string, unknown> | undefined, result: DirectiveResult, frame: ExecutionFrame<TCtx>) => DirectiveResult | void;
172
+ }
141
173
  interface IActionEngineConfig<TCtx> {
142
174
  /** Handlers com fases (V2) ou funções simples (V1 compat). */
143
175
  handlers: HandlerInputMap<TCtx>;
144
176
  /** Campo de tipo pra dispatch (default: "type"). */
145
177
  typeField?: string;
146
- /** Hooks de directive. */
178
+ /** Hooks de directive (nível de diretiva individual). */
147
179
  directiveHooks?: DirectiveHooks<TCtx>;
180
+ /** Hooks de action (nível de action inteira — antes/depois de todas as diretivas). */
181
+ actionHooks?: ActionHooks<TCtx>;
148
182
  /** Limites de execução. */
149
183
  limits?: Partial<FrameLimits>;
150
184
  /** Modo de compilação. */
@@ -175,10 +209,10 @@ interface IActionEngine<TCtx> {
175
209
  beginBatch(): void;
176
210
  /** Finaliza batch. Executa análise, typecheck, indexação. */
177
211
  endBatch(): RegisterResult;
178
- /** Invoca action por ID. Lookup O(1). */
179
- invoke(id: string, params?: Record<string, unknown>): DirectiveResult;
180
- /** Invoca action async. */
181
- invokeAsync(id: string, params?: Record<string, unknown>): Promise<DirectiveResult>;
212
+ /** Invoca action por ID. Lookup O(1). ctx opcional — se omitido, usa setContext/context. */
213
+ invoke(id: string, params?: Record<string, unknown>, ctx?: TCtx): DirectiveResult;
214
+ /** Invoca action async. ctx opcional — se omitido, usa setContext/context. */
215
+ invokeAsync(id: string, params?: Record<string, unknown>, ctx?: TCtx): Promise<DirectiveResult>;
182
216
  /** Seta ctx global. */
183
217
  setContext(ctx: TCtx): void;
184
218
  /** Override temporário de ctx dentro do callback. */
@@ -254,7 +288,7 @@ declare class SimpleEmitter<TEvents = Record<string, unknown>> {
254
288
  }
255
289
 
256
290
  declare const RESERVED_TYPES: Set<string>;
257
- declare function normalizeDirectives<TCtx>(directives: readonly Directive<TCtx>[], typeField: string): Directive<TCtx>[];
291
+ declare function normalizeDirectives<TCtx>(directives: readonly Directive<TCtx>[], _typeField: string): Directive<TCtx>[];
258
292
 
259
293
  declare function createDirectiveInterpreter<TCtx>(analysis: SlotAnalysis, isAsync: boolean): DirectiveExecutorFn<TCtx>;
260
294
 
@@ -274,4 +308,4 @@ interface GeneratedActionExecutor {
274
308
  }
275
309
  declare function buildActionExecutor(directives: readonly Directive[], analysis: SlotAnalysis, typeField: string): GeneratedActionExecutor;
276
310
 
277
- export { type ActionDefinition, type DirectiveExecutorFn, type DirectiveHandler, type DirectiveHandlerMap, type DirectiveHooks, type DirectivePermission, type DirectivePermissionConfig, type DirectivePermissionEntry, type DirectivePermissionStatus, type DirectiveRunnerFn, type EngineEventMap, type EngineEventName, type GeneratedActionExecutor, type GeneratedDirectiveExecutor, type HandlerAnalysis, type HandlerDefinition, type HandlerInput, type HandlerInputMap, type IActionEngine, type IActionEngineConfig, type Listener, RESERVED_TYPES, type RegisterError, type RegisterEvent, type RegisterResult, type RegisterWarning, SimpleEmitter, type UnregisterEvent, type ValidationResult, buildActionExecutor, buildDirectiveExecutor, createActionEngine, createDirectiveInterpreter, normalizeDirectives };
311
+ export { type ActionDefinition, type ActionHooks, type ActionInterceptResult, type DirectiveExecutorFn, type DirectiveHandler, type DirectiveHandlerMap, type DirectiveHooks, type DirectivePermission, type DirectivePermissionConfig, type DirectivePermissionEntry, type DirectivePermissionStatus, type DirectiveRunnerFn, type EngineEventMap, type EngineEventName, type GeneratedActionExecutor, type GeneratedDirectiveExecutor, type HandlerAnalysis, type HandlerDefinition, type HandlerInput, type HandlerInputMap, type IActionEngine, type IActionEngineConfig, type Listener, RESERVED_TYPES, type RegisterError, type RegisterEvent, type RegisterResult, type RegisterWarning, SimpleEmitter, type UnregisterEvent, type ValidationResult, buildActionExecutor, buildDirectiveExecutor, createActionEngine, createDirectiveInterpreter, normalizeDirectives };
package/dist/index.js CHANGED
@@ -1,9 +1,9 @@
1
- import {processIntercept,Intercept,analyzeSlots,DIRECTIVE_SLOT_NAMES,createRootFrame}from'@statedelta-actions/core';var F=class{_listeners=new Map;on(e,i){let n=this._listeners.get(e);n||(n=new Set,this._listeners.set(e,n)),n.add(i);let s=false;return ()=>{s||(s=true,n.delete(i),n.size===0&&this._listeners.delete(e));}}once(e,i){let n=this.on(e,s=>{n(),i(s);});return n}emit(e,i){let n=this._listeners.get(e);if(!n||n.size===0)return;let s=[...n];for(let r=0;r<s.length;r++)try{s[r](i);}catch(c){console.error(`[SimpleEmitter] Listener error on "${e}":`,c);}}listenerCount(e){return this._listeners.get(e)?.size??0}hasListeners(e){let i=this._listeners.get(e);return i!==void 0&&i.size>0}off(e){this._listeners.delete(e);}removeAllListeners(){this._listeners.clear();}};var S=new Set(["const","let","return","throw"]);function W(t,e,i,n){let s=[];for(let r=0;r<t.directives.length;r++){let c=t.directives[r];if("const"in c||"let"in c||"return"in c||"throw"in c)continue;let h=c[n];if(!h){s.push(`directive[${r}]: missing type field "${n}"`);continue}if(!e[h]){s.push(`directive[${r}]: no handler for type "${h}"`);continue}let x=i.get(h);if(x?.validate)try{let D=x.validate(c);D&&!D.valid&&s.push(`directive[${r}]: ${D.error??"validation failed"}`);}catch(D){s.push(`directive[${r}]: validate threw: ${D}`);}let m=c.catch;if(m&&Array.isArray(m))for(let D=0;D<m.length;D++){let R=m[D];if("const"in R||"let"in R||"return"in R||"throw"in R)continue;let v=R[n];v&&!e[v]&&s.push(`directive[${r}].catch[${D}]: no handler for type "${v}"`);}}return s}function H(t,e){let i=t.length,n=new Array(i);for(let s=0;s<i;s++){let r=t[s];if("const"in r)n[s]=q(r,"const");else if("let"in r)n[s]=q(r,"let");else if("return"in r)n[s]=te(r);else if("throw"in r)n[s]=re(r);else {let c=r.catch;Array.isArray(c)&&c.length>0?n[s]={...r,catch:H(c)}:n[s]=r;}}return n}function q(t,e){let{[e]:i,...n}=t;return {...n,type:e,name:i}}function te(t){let{return:e,...i}=t;return {...i,type:"return",value:e}}function re(t){let{throw:e,...i}=t;return {...i,type:"throw",message:e}}function M(t,e,i,n,s,r,c){return {success:false,aborted:true,abortedBy:t,appliedCount:e,skippedCount:i,errors:n,processedCount:s,totalCount:r,counters:c}}function ie(t){let e=t.filledNames.has("beforeDirective"),i=t.filledNames.has("afterDirective"),n=t.filledNames.has("onDirectivesComplete");return function(r,c,h,x,m,D,R){let v=Math.min(r.length,R),l=[],f=0,_=0,{counters:u,scope:C}=c,A=c.ctx;for(let a=0;a<v;a++){let p=r[a],$=p[m];if($==="const"||$==="let"){let o=p.name;if(typeof p.resolve=="function")try{C[o]=p.resolve(A,C).value;}catch(d){l.push({directiveIndex:a,error:`Binding resolve: ${d}`}),u.errors++;}else C[o]=p.value;continue}if($==="return"){let o=a+1;if(typeof p.resolve=="function")try{let d=p.resolve(A,C),b="value"in d?d.value:"return"in d?d.return:p.value;return {success:!0,aborted:!1,appliedCount:f,skippedCount:_,errors:l,processedCount:o,totalCount:v,counters:u,data:b}}catch(d){l.push({directiveIndex:a,error:`Control resolve: ${d}`}),u.errors++;}else return {success:true,aborted:false,appliedCount:f,skippedCount:_,errors:l,processedCount:o,totalCount:v,counters:u,data:p.value};continue}if($==="throw"){let o=a+1;if(typeof p.resolve=="function")try{let d=p.resolve(A,C),b="message"in d?d.message:"throw"in d?d.throw:p.message;return {success:!1,aborted:!0,abortedBy:"throw",appliedCount:f,skippedCount:_,errors:l,processedCount:o,totalCount:v,counters:u,data:b}}catch(d){l.push({directiveIndex:a,error:`Control resolve: ${d}`}),u.errors++;}else return {success:false,aborted:true,abortedBy:"throw",appliedCount:f,skippedCount:_,errors:l,processedCount:o,totalCount:v,counters:u,data:p.message};continue}let y=p,E=c;if(e)try{let o=processIntercept(x.beforeDirective(y,c),"beforeDirective");if(o.action===Intercept.SKIP){_++,u.directivesSkipped++;continue}if(o.action===Intercept.ABORT)return M(o.abortReason,f,_,l,a,v,u);o.ctx!==void 0&&(E=c.withCtx(o.ctx)),o.directive!==void 0&&(y=o.directive);}catch(o){l.push({directiveIndex:a,error:`Hook beforeDirective: ${o}`}),u.errors++;}if(typeof y.resolve=="function")try{let o=y.resolve(E.ctx,E.scope);y={...y,...o};}catch(o){l.push({directiveIndex:a,error:`Directive resolve: ${o}`}),u.errors++;continue}let w=y[m],I=w?h[w]:void 0;if(!I){l.push({directiveIndex:a,error:`No handler for directive type: ${w??"undefined"}`}),u.errors++;continue}let g;try{g=I(y,E,D);}catch(o){g={ok:false,error:String(o)};}let T=a+1;if(g.ok){if(f++,u.directivesApplied++,typeof y.as=="string"&&(C[y.as]=g.data),g.halt)return {success:true,aborted:true,abortedBy:"halt",appliedCount:f,skippedCount:_,errors:l,processedCount:T,totalCount:v,counters:u,data:g.data}}else {if(g.halt)return {success:false,aborted:true,abortedBy:"halt",appliedCount:f,skippedCount:_,errors:l,processedCount:T,totalCount:v,counters:u,data:g.data};let o=y.catch;if(Array.isArray(o)&&o.length>0){C.$exception=g.error??"handler failed";let d=D.runDirectives(o,E);f+=d.appliedCount;for(let b=0;b<d.errors.length;b++)l.push(d.errors[b]);if(d.aborted)return {success:d.success,aborted:true,abortedBy:d.abortedBy,appliedCount:f,skippedCount:_,errors:l,processedCount:T,totalCount:v,counters:u,data:d.data}}else l.push({directiveIndex:a,error:g.error??"handler failed"}),u.errors++;}if(i)try{if(x.afterDirective(y,g,E)==="abort")return M("afterDirective",f,_,l,T,v,u)}catch(o){l.push({directiveIndex:a,error:`Hook afterDirective: ${o}`}),u.errors++;}}let k={success:true,aborted:false,appliedCount:f,skippedCount:_,errors:l,processedCount:v,totalCount:v,counters:u};if(n)try{x.onDirectivesComplete(k);}catch{}return k}}function ne(t){let e=t.filledNames.has("beforeDirective"),i=t.filledNames.has("afterDirective"),n=t.filledNames.has("onDirectivesComplete");return async function(r,c,h,x,m,D,R){let v=Math.min(r.length,R),l=[],f=0,_=0,{counters:u,scope:C}=c,A=c.ctx;for(let a=0;a<v;a++){let p=r[a],$=p[m];if($==="const"||$==="let"){let o=p.name;if(typeof p.resolve=="function")try{C[o]=p.resolve(A,C).value;}catch(d){l.push({directiveIndex:a,error:`Binding resolve: ${d}`}),u.errors++;}else C[o]=p.value;continue}if($==="return"){let o=a+1;if(typeof p.resolve=="function")try{let d=p.resolve(A,C),b="value"in d?d.value:"return"in d?d.return:p.value;return {success:!0,aborted:!1,appliedCount:f,skippedCount:_,errors:l,processedCount:o,totalCount:v,counters:u,data:b}}catch(d){l.push({directiveIndex:a,error:`Control resolve: ${d}`}),u.errors++;}else return {success:true,aborted:false,appliedCount:f,skippedCount:_,errors:l,processedCount:o,totalCount:v,counters:u,data:p.value};continue}if($==="throw"){let o=a+1;if(typeof p.resolve=="function")try{let d=p.resolve(A,C),b="message"in d?d.message:"throw"in d?d.throw:p.message;return {success:!1,aborted:!0,abortedBy:"throw",appliedCount:f,skippedCount:_,errors:l,processedCount:o,totalCount:v,counters:u,data:b}}catch(d){l.push({directiveIndex:a,error:`Control resolve: ${d}`}),u.errors++;}else return {success:false,aborted:true,abortedBy:"throw",appliedCount:f,skippedCount:_,errors:l,processedCount:o,totalCount:v,counters:u,data:p.message};continue}let y=p,E=c;if(e)try{let o=processIntercept(await x.beforeDirective(y,c),"beforeDirective");if(o.action===Intercept.SKIP){_++,u.directivesSkipped++;continue}if(o.action===Intercept.ABORT)return M(o.abortReason,f,_,l,a,v,u);o.ctx!==void 0&&(E=c.withCtx(o.ctx)),o.directive!==void 0&&(y=o.directive);}catch(o){l.push({directiveIndex:a,error:`Hook beforeDirective: ${o}`}),u.errors++;}if(typeof y.resolve=="function")try{let o=y.resolve(E.ctx,E.scope);y={...y,...o};}catch(o){l.push({directiveIndex:a,error:`Directive resolve: ${o}`}),u.errors++;continue}let w=y[m],I=w?h[w]:void 0;if(!I){l.push({directiveIndex:a,error:`No handler for directive type: ${w??"undefined"}`}),u.errors++;continue}let g;try{g=I(y,E,D);}catch(o){g={ok:false,error:String(o)};}let T=a+1;if(g.ok){if(f++,u.directivesApplied++,typeof y.as=="string"&&(C[y.as]=g.data),g.halt)return {success:true,aborted:true,abortedBy:"halt",appliedCount:f,skippedCount:_,errors:l,processedCount:T,totalCount:v,counters:u,data:g.data}}else {if(g.halt)return {success:false,aborted:true,abortedBy:"halt",appliedCount:f,skippedCount:_,errors:l,processedCount:T,totalCount:v,counters:u,data:g.data};let o=y.catch;if(Array.isArray(o)&&o.length>0){C.$exception=g.error??"handler failed";let d=await D.runDirectivesAsync(o,E);f+=d.appliedCount;for(let b=0;b<d.errors.length;b++)l.push(d.errors[b]);if(d.aborted)return {success:d.success,aborted:true,abortedBy:d.abortedBy,appliedCount:f,skippedCount:_,errors:l,processedCount:T,totalCount:v,counters:u,data:d.data}}else l.push({directiveIndex:a,error:g.error??"handler failed"}),u.errors++;}if(i)try{if(await x.afterDirective(y,g,E)==="abort")return M("afterDirective",f,_,l,T,v,u)}catch(o){l.push({directiveIndex:a,error:`Hook afterDirective: ${o}`}),u.errors++;}}let k={success:true,aborted:false,appliedCount:f,skippedCount:_,errors:l,processedCount:v,totalCount:v,counters:u};if(n)try{await x.onDirectivesComplete(k);}catch{}return k}}function B(t,e){return e?ne(t):ie(t)}function j(t){let{filledNames:e,hasAnyAsync:i}=t,n=m=>e.has(m),s=m=>t.asyncNames.has(m)?"await ":"",r=[];for(let m of e)r.push(`const ${m} = directiveHooks.${m};`);r.push("const len = Math.min(directives.length, maxDirectives);"),r.push("const errors = []; let appliedCount = 0; let skippedCount = 0;"),r.push("const counters = frame.counters;"),r.push("for (let i = 0; i < len; i++) {"),r.push(" let directive = directives[i];"),n("beforeDirective")?(r.push(" let _df = frame;"),r.push(" try {"),r.push(` const _bd = ${s("beforeDirective")}beforeDirective(directive, frame);`),r.push(' if (_bd === "skip") { skippedCount++; counters.directivesSkipped++; continue; }'),r.push(' if (_bd === "abort") return { success: false, aborted: true, abortedBy: "beforeDirective", appliedCount, skippedCount, errors, processedCount: i, totalCount: len, counters };'),r.push(' if (typeof _bd === "object" && _bd !== null) {'),r.push(' if ("abort" in _bd) return { success: false, aborted: true, abortedBy: _bd.abort, appliedCount, skippedCount, errors, processedCount: i, totalCount: len, counters };'),r.push(' if ("ctx" in _bd) _df = frame.withCtx(_bd.ctx);'),r.push(' if ("directive" in _bd) directive = _bd.directive;'),r.push(" }"),r.push(' } catch (_e) { errors.push({ directiveIndex: i, error: "Hook beforeDirective: " + _e }); counters.errors++; }')):r.push(" const _df = frame;"),r.push(' if (typeof directive.resolve === "function") {'),r.push(" try { const _r = directive.resolve(_df.ctx); directive = Object.assign({}, directive, _r); }"),r.push(' catch (_e) { errors.push({ directiveIndex: i, error: "Directive resolve: " + _e }); counters.errors++; continue; }'),r.push(" }"),r.push(" const _type = directive[typeField];"),r.push(" const _handler = _type ? handlers[_type] : undefined;"),r.push(' if (!_handler) { errors.push({ directiveIndex: i, error: "No handler for directive type: " + (_type || "undefined") }); counters.errors++; continue; }'),r.push(" let _result;"),r.push(" try { _result = _handler(directive, _df, engine); } catch (_e) { errors.push({ directiveIndex: i, error: String(_e) }); counters.errors++; continue; }"),r.push(" if (_result.ok) { appliedCount++; counters.directivesApplied++; }"),r.push(' else { errors.push({ directiveIndex: i, error: _result.error || "handler failed" }); counters.errors++; }'),n("afterDirective")&&(r.push(" try {"),r.push(` const _ad = ${s("afterDirective")}afterDirective(directive, _result, _df);`),r.push(' if (_ad === "abort") return { success: false, aborted: true, abortedBy: "afterDirective", appliedCount, skippedCount, errors, processedCount: i + 1, totalCount: len, counters };'),r.push(' } catch (_e) { errors.push({ directiveIndex: i, error: "Hook afterDirective: " + _e }); counters.errors++; }')),r.push("}"),r.push("const _finalResult = { success: true, aborted: false, appliedCount, skippedCount, errors, processedCount: len, totalCount: len, counters };"),n("onDirectivesComplete")&&r.push(`try { ${s("onDirectivesComplete")}onDirectivesComplete(_finalResult); } catch (_e) {}`),r.push("return _finalResult;");let c=r.join(`
2
- `),h=i?"async ":"";return {fn:new Function("directives","frame","handlers","directiveHooks","typeField","engine","maxDirectives",`"use strict";
3
- return (${h}() => {
1
+ import {processIntercept,Intercept,analyzeSlots,DIRECTIVE_SLOT_NAMES,createRootFrame}from'@statedelta-actions/core';var H=class{_listeners=new Map;on(e,i){let s=this._listeners.get(e);s||(s=new Set,this._listeners.set(e,s)),s.add(i);let n=false;return ()=>{n||(n=true,s.delete(i),s.size===0&&this._listeners.delete(e));}}once(e,i){let s=this.on(e,n=>{s(),i(n);});return s}emit(e,i){let s=this._listeners.get(e);if(!s||s.size===0)return;let n=[...s];for(let r=0;r<n.length;r++)try{n[r](i);}catch(c){console.error(`[SimpleEmitter] Listener error on "${e}":`,c);}}listenerCount(e){return this._listeners.get(e)?.size??0}hasListeners(e){let i=this._listeners.get(e);return i!==void 0&&i.size>0}off(e){this._listeners.delete(e);}removeAllListeners(){this._listeners.clear();}};var I=new Set(["const","let","return","throw"]);function W(t,e,i,s){let n=[];for(let r=0;r<t.directives.length;r++){let c=t.directives[r],f=c[s];if(!f){n.push(`directive[${r}]: missing type field "${s}"`);continue}if(I.has(f))continue;if(!e[f]){n.push(`directive[${r}]: no handler for type "${f}"`);continue}let _=i.get(f);if(_?.validate)try{let C=_.validate(c);C&&!C.valid&&n.push(`directive[${r}]: ${C.error??"validation failed"}`);}catch(C){n.push(`directive[${r}]: validate threw: ${C}`);}let h=c.catch;if(h&&Array.isArray(h))for(let C=0;C<h.length;C++){let v=h[C][s];v&&I.has(v)||v&&!e[v]&&n.push(`directive[${r}].catch[${C}]: no handler for type "${v}"`);}}return n}function S(t,e){let i=t.length,s=new Array(i);for(let n=0;n<i;n++){let r=t[n],c=r.catch;Array.isArray(c)&&c.length>0?s[n]={...r,catch:S(c)}:s[n]=r;}return s}function P(t,e,i,s,n,r,c){return {success:false,aborted:true,abortedBy:t,appliedCount:e,skippedCount:i,errors:s,processedCount:n,totalCount:r,counters:c}}function te(t){let e=t.filledNames.has("beforeDirective"),i=t.filledNames.has("afterDirective"),s=t.filledNames.has("onDirectivesComplete");return function(r,c,f,_,h,C,T){let v=Math.min(r.length,T),l=[],m=0,x=0,{counters:u,scope:D}=c,R=c.ctx;for(let a=0;a<v;a++){let p=r[a],E=p[h];if(E==="const"||E==="let"){let o=p.name;if(typeof p.resolve=="function")try{D[o]=p.resolve(R,D).value;}catch(d){l.push({directiveIndex:a,error:`Binding resolve: ${d}`}),u.errors++;}else D[o]=p.value;continue}if(E==="return"){let o=a+1;if(typeof p.resolve=="function")try{let d=p.resolve(R,D),b="value"in d?d.value:"return"in d?d.return:p.value;return {success:!0,aborted:!1,appliedCount:m,skippedCount:x,errors:l,processedCount:o,totalCount:v,counters:u,data:b}}catch(d){l.push({directiveIndex:a,error:`Control resolve: ${d}`}),u.errors++;}else return {success:true,aborted:false,appliedCount:m,skippedCount:x,errors:l,processedCount:o,totalCount:v,counters:u,data:p.value};continue}if(E==="throw"){let o=a+1;if(typeof p.resolve=="function")try{let d=p.resolve(R,D),b="message"in d?d.message:"throw"in d?d.throw:p.message;return {success:!1,aborted:!0,abortedBy:"throw",appliedCount:m,skippedCount:x,errors:l,processedCount:o,totalCount:v,counters:u,data:b}}catch(d){l.push({directiveIndex:a,error:`Control resolve: ${d}`}),u.errors++;}else return {success:false,aborted:true,abortedBy:"throw",appliedCount:m,skippedCount:x,errors:l,processedCount:o,totalCount:v,counters:u,data:p.message};continue}let y=p,A=c;if(e)try{let o=processIntercept(_.beforeDirective(y,c),"beforeDirective");if(o.action===Intercept.SKIP){x++,u.directivesSkipped++;continue}if(o.action===Intercept.ABORT)return P(o.abortReason,m,x,l,a,v,u);o.ctx!==void 0&&(A=c.withCtx(o.ctx)),o.directive!==void 0&&(y=o.directive);}catch(o){l.push({directiveIndex:a,error:`Hook beforeDirective: ${o}`}),u.errors++;}if(typeof y.resolve=="function")try{let o=y.resolve(A.ctx,A.scope);y={...y,...o};}catch(o){l.push({directiveIndex:a,error:`Directive resolve: ${o}`}),u.errors++;continue}let w=y[h],F=w?f[w]:void 0;if(!F){l.push({directiveIndex:a,error:`No handler for directive type: ${w??"undefined"}`}),u.errors++;continue}let g;try{g=F(y,A,C);}catch(o){g={ok:false,error:String(o)};}let $=a+1;if(g.ok){if(m++,u.directivesApplied++,typeof y.as=="string"&&(D[y.as]=g.data),g.halt)return {success:true,aborted:true,abortedBy:"halt",appliedCount:m,skippedCount:x,errors:l,processedCount:$,totalCount:v,counters:u,data:g.data}}else {if(g.halt)return {success:false,aborted:true,abortedBy:"halt",appliedCount:m,skippedCount:x,errors:l,processedCount:$,totalCount:v,counters:u,data:g.data};let o=y.catch;if(Array.isArray(o)&&o.length>0){D.$exception=g.error??"handler failed";let d=C.runDirectives(o,A);m+=d.appliedCount;for(let b=0;b<d.errors.length;b++)l.push(d.errors[b]);if(d.aborted)return {success:d.success,aborted:true,abortedBy:d.abortedBy,appliedCount:m,skippedCount:x,errors:l,processedCount:$,totalCount:v,counters:u,data:d.data}}else l.push({directiveIndex:a,error:g.error??"handler failed"}),u.errors++;}if(i)try{if(_.afterDirective(y,g,A)==="abort")return P("afterDirective",m,x,l,$,v,u)}catch(o){l.push({directiveIndex:a,error:`Hook afterDirective: ${o}`}),u.errors++;}}let k={success:true,aborted:false,appliedCount:m,skippedCount:x,errors:l,processedCount:v,totalCount:v,counters:u};if(s)try{_.onDirectivesComplete(k);}catch{}return k}}function re(t){let e=t.filledNames.has("beforeDirective"),i=t.filledNames.has("afterDirective"),s=t.filledNames.has("onDirectivesComplete");return async function(r,c,f,_,h,C,T){let v=Math.min(r.length,T),l=[],m=0,x=0,{counters:u,scope:D}=c,R=c.ctx;for(let a=0;a<v;a++){let p=r[a],E=p[h];if(E==="const"||E==="let"){let o=p.name;if(typeof p.resolve=="function")try{D[o]=p.resolve(R,D).value;}catch(d){l.push({directiveIndex:a,error:`Binding resolve: ${d}`}),u.errors++;}else D[o]=p.value;continue}if(E==="return"){let o=a+1;if(typeof p.resolve=="function")try{let d=p.resolve(R,D),b="value"in d?d.value:"return"in d?d.return:p.value;return {success:!0,aborted:!1,appliedCount:m,skippedCount:x,errors:l,processedCount:o,totalCount:v,counters:u,data:b}}catch(d){l.push({directiveIndex:a,error:`Control resolve: ${d}`}),u.errors++;}else return {success:true,aborted:false,appliedCount:m,skippedCount:x,errors:l,processedCount:o,totalCount:v,counters:u,data:p.value};continue}if(E==="throw"){let o=a+1;if(typeof p.resolve=="function")try{let d=p.resolve(R,D),b="message"in d?d.message:"throw"in d?d.throw:p.message;return {success:!1,aborted:!0,abortedBy:"throw",appliedCount:m,skippedCount:x,errors:l,processedCount:o,totalCount:v,counters:u,data:b}}catch(d){l.push({directiveIndex:a,error:`Control resolve: ${d}`}),u.errors++;}else return {success:false,aborted:true,abortedBy:"throw",appliedCount:m,skippedCount:x,errors:l,processedCount:o,totalCount:v,counters:u,data:p.message};continue}let y=p,A=c;if(e)try{let o=processIntercept(await _.beforeDirective(y,c),"beforeDirective");if(o.action===Intercept.SKIP){x++,u.directivesSkipped++;continue}if(o.action===Intercept.ABORT)return P(o.abortReason,m,x,l,a,v,u);o.ctx!==void 0&&(A=c.withCtx(o.ctx)),o.directive!==void 0&&(y=o.directive);}catch(o){l.push({directiveIndex:a,error:`Hook beforeDirective: ${o}`}),u.errors++;}if(typeof y.resolve=="function")try{let o=y.resolve(A.ctx,A.scope);y={...y,...o};}catch(o){l.push({directiveIndex:a,error:`Directive resolve: ${o}`}),u.errors++;continue}let w=y[h],F=w?f[w]:void 0;if(!F){l.push({directiveIndex:a,error:`No handler for directive type: ${w??"undefined"}`}),u.errors++;continue}let g;try{g=F(y,A,C);}catch(o){g={ok:false,error:String(o)};}let $=a+1;if(g.ok){if(m++,u.directivesApplied++,typeof y.as=="string"&&(D[y.as]=g.data),g.halt)return {success:true,aborted:true,abortedBy:"halt",appliedCount:m,skippedCount:x,errors:l,processedCount:$,totalCount:v,counters:u,data:g.data}}else {if(g.halt)return {success:false,aborted:true,abortedBy:"halt",appliedCount:m,skippedCount:x,errors:l,processedCount:$,totalCount:v,counters:u,data:g.data};let o=y.catch;if(Array.isArray(o)&&o.length>0){D.$exception=g.error??"handler failed";let d=await C.runDirectivesAsync(o,A);m+=d.appliedCount;for(let b=0;b<d.errors.length;b++)l.push(d.errors[b]);if(d.aborted)return {success:d.success,aborted:true,abortedBy:d.abortedBy,appliedCount:m,skippedCount:x,errors:l,processedCount:$,totalCount:v,counters:u,data:d.data}}else l.push({directiveIndex:a,error:g.error??"handler failed"}),u.errors++;}if(i)try{if(await _.afterDirective(y,g,A)==="abort")return P("afterDirective",m,x,l,$,v,u)}catch(o){l.push({directiveIndex:a,error:`Hook afterDirective: ${o}`}),u.errors++;}}let k={success:true,aborted:false,appliedCount:m,skippedCount:x,errors:l,processedCount:v,totalCount:v,counters:u};if(s)try{await _.onDirectivesComplete(k);}catch{}return k}}function B(t,e){return e?re(t):te(t)}function j(t){let{filledNames:e,hasAnyAsync:i}=t,s=h=>e.has(h),n=h=>t.asyncNames.has(h)?"await ":"",r=[];for(let h of e)r.push(`const ${h} = directiveHooks.${h};`);r.push("const len = Math.min(directives.length, maxDirectives);"),r.push("const errors = []; let appliedCount = 0; let skippedCount = 0;"),r.push("const counters = frame.counters;"),r.push("for (let i = 0; i < len; i++) {"),r.push(" let directive = directives[i];"),s("beforeDirective")?(r.push(" let _df = frame;"),r.push(" try {"),r.push(` const _bd = ${n("beforeDirective")}beforeDirective(directive, frame);`),r.push(' if (_bd === "skip") { skippedCount++; counters.directivesSkipped++; continue; }'),r.push(' if (_bd === "abort") return { success: false, aborted: true, abortedBy: "beforeDirective", appliedCount, skippedCount, errors, processedCount: i, totalCount: len, counters };'),r.push(' if (typeof _bd === "object" && _bd !== null) {'),r.push(' if ("abort" in _bd) return { success: false, aborted: true, abortedBy: _bd.abort, appliedCount, skippedCount, errors, processedCount: i, totalCount: len, counters };'),r.push(' if ("ctx" in _bd) _df = frame.withCtx(_bd.ctx);'),r.push(' if ("directive" in _bd) directive = _bd.directive;'),r.push(" }"),r.push(' } catch (_e) { errors.push({ directiveIndex: i, error: "Hook beforeDirective: " + _e }); counters.errors++; }')):r.push(" const _df = frame;"),r.push(' if (typeof directive.resolve === "function") {'),r.push(" try { const _r = directive.resolve(_df.ctx); directive = Object.assign({}, directive, _r); }"),r.push(' catch (_e) { errors.push({ directiveIndex: i, error: "Directive resolve: " + _e }); counters.errors++; continue; }'),r.push(" }"),r.push(" const _type = directive[typeField];"),r.push(" const _handler = _type ? handlers[_type] : undefined;"),r.push(' if (!_handler) { errors.push({ directiveIndex: i, error: "No handler for directive type: " + (_type || "undefined") }); counters.errors++; continue; }'),r.push(" let _result;"),r.push(" try { _result = _handler(directive, _df, engine); } catch (_e) { errors.push({ directiveIndex: i, error: String(_e) }); counters.errors++; continue; }"),r.push(" if (_result.ok) { appliedCount++; counters.directivesApplied++; }"),r.push(' else { errors.push({ directiveIndex: i, error: _result.error || "handler failed" }); counters.errors++; }'),s("afterDirective")&&(r.push(" try {"),r.push(` const _ad = ${n("afterDirective")}afterDirective(directive, _result, _df);`),r.push(' if (_ad === "abort") return { success: false, aborted: true, abortedBy: "afterDirective", appliedCount, skippedCount, errors, processedCount: i + 1, totalCount: len, counters };'),r.push(' } catch (_e) { errors.push({ directiveIndex: i, error: "Hook afterDirective: " + _e }); counters.errors++; }')),r.push("}"),r.push("const _finalResult = { success: true, aborted: false, appliedCount, skippedCount, errors, processedCount: len, totalCount: len, counters };"),s("onDirectivesComplete")&&r.push(`try { ${n("onDirectivesComplete")}onDirectivesComplete(_finalResult); } catch (_e) {}`),r.push("return _finalResult;");let c=r.join(`
2
+ `),f=i?"async ":"";return {fn:new Function("directives","frame","handlers","directiveHooks","typeField","engine","maxDirectives",`"use strict";
3
+ return (${f}() => {
4
4
  ${c}
5
- })();`),isAsync:i}}function N(t,e,i){return `return{success:false,aborted:true,abortedBy:${t},appliedCount,skippedCount,errors,processedCount:${e},totalCount:${i},counters};`}function se(t,e){return `return{success:true,aborted:true,abortedBy:"halt",appliedCount,skippedCount,errors,processedCount:${t},totalCount:${e},counters,data:_result.data};`}function oe(t,e){return `return{success:false,aborted:true,abortedBy:"halt",appliedCount,skippedCount,errors,processedCount:${t},totalCount:${e},counters,data:_result.data};`}function ce(t,e,i){let n=JSON.stringify(e.name);typeof e.resolve=="function"?(t.push("try{"),t.push(`scope[${n}]=$.d[${i}].resolve(ctx,scope).value;`),t.push(`}catch(_e){errors.push({directiveIndex:${i},error:"Binding resolve: "+_e});counters.errors++;}`)):t.push(`scope[${n}]=$.d[${i}].value;`);}function ae(t,e,i,n){let s=typeof e.resolve=="function",r=i+1;s?(t.push("try{"),t.push(`const _rv=$.d[${i}].resolve(ctx,scope);`),t.push(`return{success:true,aborted:false,appliedCount,skippedCount,errors,processedCount:${r},totalCount:${n},counters,data:"value" in _rv?_rv.value:"return" in _rv?_rv.return:$.d[${i}].value};`),t.push(`}catch(_e){errors.push({directiveIndex:${i},error:"Control resolve: "+_e});counters.errors++;}`)):t.push(`return{success:true,aborted:false,appliedCount,skippedCount,errors,processedCount:${r},totalCount:${n},counters,data:$.d[${i}].value};`);}function ue(t,e,i,n){let s=typeof e.resolve=="function",r=i+1;s?(t.push("try{"),t.push(`const _rv=$.d[${i}].resolve(ctx,scope);`),t.push(`return{success:false,aborted:true,abortedBy:"throw",appliedCount,skippedCount,errors,processedCount:${r},totalCount:${n},counters,data:"message" in _rv?_rv.message:"throw" in _rv?_rv.throw:$.d[${i}].message};`),t.push(`}catch(_e){errors.push({directiveIndex:${i},error:"Control resolve: "+_e});counters.errors++;}`)):t.push(`return{success:false,aborted:true,abortedBy:"throw",appliedCount,skippedCount,errors,processedCount:${r},totalCount:${n},counters,data:$.d[${i}].message};`);}function de(t,e,i,n,s,r,c,h,x,m){let D=e[s],R=r.get(D),v=typeof e.resolve=="function",l=typeof e.as=="string",f=Array.isArray(e.catch)&&e.catch.length>0,_=l?JSON.stringify(e.as):"",u=i+1;t.push(`_b${i}:{`);let C=c||v,A=c;C&&t.push(`let _dir=$.d[${i}];`),A&&t.push("let _df=frame;"),c&&(t.push("try{"),t.push(`const _bd=${x}_hookBefore($.d[${i}],frame);`),t.push(`if(_bd==="skip"){skippedCount++;counters.directivesSkipped++;break _b${i};}`),t.push(`if(_bd==="abort")${N('"beforeDirective"',i,n)}`),t.push('if(typeof _bd==="object"&&_bd!==null){'),t.push(`if("abort" in _bd)${N("_bd.abort",i,n)}`),t.push('if("ctx" in _bd)_df=frame.withCtx(_bd.ctx);'),t.push('if("directive" in _bd)_dir=_bd.directive;'),t.push("}"),t.push(`}catch(_e){errors.push({directiveIndex:${i},error:"Hook beforeDirective: "+_e});counters.errors++;}`)),c?(t.push('if(typeof _dir.resolve==="function"){'),t.push("try{const _r=_dir.resolve(_df.ctx,scope);_dir=Object.assign({},_dir,_r);}"),t.push(`catch(_e){errors.push({directiveIndex:${i},error:"Directive resolve: "+_e});counters.errors++;break _b${i};}}`)):v&&(t.push(`try{const _r=$.d[${i}].resolve(ctx,scope);_dir=Object.assign({},$.d[${i}],_r);}`),t.push(`catch(_e){errors.push({directiveIndex:${i},error:"Directive resolve: "+_e});counters.errors++;break _b${i};}`));let k=C?"_dir":`$.d[${i}]`,a=A?"_df":"frame";t.push("let _result;"),t.push(`try{_result=${R}(${k},${a},$.engine);}`),t.push("catch(_e){_result={ok:false,error:String(_e)};}"),t.push("if(_result.ok){"),t.push("appliedCount++;counters.directivesApplied++;"),l&&t.push(`scope[${_}]=_result.data;`),t.push(`if(_result.halt)${se(u,n)}`),t.push("}else{"),t.push(`if(_result.halt)${oe(u,n)}`),f?(t.push('scope.$exception=_result.error||"handler failed";'),t.push(`const _cr=$.runner($.d[${i}].catch,${a});`),t.push("appliedCount+=_cr.appliedCount;"),t.push("for(let _j=0;_j<_cr.errors.length;_j++)errors.push(_cr.errors[_j]);"),t.push(`if(_cr.aborted)return{success:_cr.success,aborted:true,abortedBy:_cr.abortedBy,appliedCount,skippedCount,errors,processedCount:${u},totalCount:${n},counters,data:_cr.data};`)):t.push(`errors.push({directiveIndex:${i},error:_result.error||"handler failed"});counters.errors++;`),t.push("}"),h&&(t.push("try{"),t.push(`const _ad=${m}_hookAfter(${k},_result,${a});`),t.push(`if(_ad==="abort")${N('"afterDirective"',u,n)}`),t.push(`}catch(_e){errors.push({directiveIndex:${i},error:"Hook afterDirective: "+_e});counters.errors++;}`)),t.push("}");}function O(t,e,i){let n=[],s=t.length,{filledNames:r,hasAnyAsync:c,asyncNames:h}=e,x=r.has("beforeDirective"),m=r.has("afterDirective"),D=r.has("onDirectivesComplete"),R=h.has("beforeDirective")?"await ":"",v=h.has("afterDirective")?"await ":"",l=h.has("onDirectivesComplete")?"await ":"",f=new Set;for(let a of t){let p=a[i];p&&!S.has(p)&&f.add(p);}let _=new Map,u=0;for(let a of f)_.set(a,`_h${u++}`);n.push("const counters=frame.counters;"),n.push("const ctx=frame.ctx;"),n.push("const errors=[];"),n.push("let appliedCount=0;"),n.push("let skippedCount=0;");for(let[a,p]of _)n.push(`const ${p}=$.h[${JSON.stringify(a)}];`);x&&n.push("const _hookBefore=$.hooks.beforeDirective;"),m&&n.push("const _hookAfter=$.hooks.afterDirective;");for(let a=0;a<t.length;a++){let p=t[a];switch(p[i]){case "const":case "let":ce(n,p,a);break;case "return":ae(n,p,a,s);break;case "throw":ue(n,p,a,s);break;default:de(n,p,a,s,i,_,x,m,R,v);break}}n.push(`const _finalResult={success:true,aborted:false,appliedCount,skippedCount,errors,processedCount:${s},totalCount:${s},counters};`),D&&n.push(`try{${l}$.hooks.onDirectivesComplete(_finalResult);}catch(_e){}`),n.push("return _finalResult;");let C=n.join(`
6
- `),A=c?"async ":"";return {fn:new Function("frame","scope","$",`"use strict";
7
- return(${A}()=>{
8
- ${C}
9
- })();`),isAsync:c}}function K(t,e,i){return {success:false,aborted:false,appliedCount:0,skippedCount:0,processedCount:0,totalCount:0,errors:[{directiveIndex:-1,error:e}],counters:t,...i}}function U(t,e){return K(e,`Action not found: "${t}"`)}function G(t,e,i){return K(i,`Max depth ${e} exceeded invoking "${t}"`,{aborted:true,abortedBy:"maxDepth"})}function Y(t,e){return K(e,`Action "${t}" is private (sub-action). Can only be invoked from within its parent scope.`)}function le(t){return typeof t=="object"&&t!==null&&"execute"in t}function Q(t){let e=Object.create(null),i=new Map;for(let n of Object.keys(t)){let s=t[n];le(s)?(e[n]=s.execute,i.set(n,s)):(e[n]=s,i.set(n,{execute:s}));}return {handlers:e,definitions:i}}function X(t,e){if(t==="*")return true;if(!t.includes("*"))return t===e;let i=t.replace(/[.+^${}()|[\]\\]/g,"\\$&");return new RegExp("^"+i.replace(/\*/g,".*")+"$").test(e)}function Z(t){return typeof t=="string"?{pattern:t}:t}function L(t,e,i){let n=new Map;if(!e&&!i){for(let s of t)n.set(s,{status:"available"});return n}if(e){let s=e.map(Z);for(let r of t){let c=s.some(h=>X(h.pattern,r));n.set(r,{status:c?"available":"denied"});}}else {let s=i.map(Z);for(let r of t){let c=s.find(h=>X(h.pattern,r));c?n.set(r,{status:"denied",reason:c.reason,source:c.source}):n.set(r,{status:"available"});}}return n}var ve=8,fe="type",z={maxDepth:10,maxRules:1e4,maxDirectives:1e5},V=class{_directiveExecutor;_mode;_ctx;_requestedMode;_threshold;_limits;_typeField;_handlers;_definitions;_directiveHooks;_directiveAnalysis;_isAsync;_directivePermissions;_registry=new Map;_emitter=new F;_batchDepth=0;_batchErrors=[];_batchWarnings=[];_batchActions=[];_batchRegistered=[];_registeredIds=new Set;_directiveRunner;_engineRef;constructor(e){this._requestedMode=e.mode??"auto",this._threshold=e.autoJitThreshold??ve,this._typeField=e.typeField??fe,this._limits={maxDepth:e.limits?.maxDepth??z.maxDepth,maxRules:e.limits?.maxRules??z.maxRules,maxDirectives:e.limits?.maxDirectives??z.maxDirectives};let{handlers:i,definitions:n}=Q(e.handlers);for(let s of Object.keys(e.handlers))if(S.has(s))throw new Error(`Handler type "${s}" is reserved for engine-internal directives`);if(e.allowedDirectives&&e.blockedDirectives)throw new Error("allowedDirectives and blockedDirectives are mutually exclusive. Provide one or neither.");this._handlers=i,this._definitions=n,this._directivePermissions=L(Object.keys(i),e.allowedDirectives,e.blockedDirectives),this._directiveHooks=e.directiveHooks??{},this._directiveAnalysis=analyzeSlots(this._directiveHooks,DIRECTIVE_SLOT_NAMES),this._isAsync=this._directiveAnalysis.hasAnyAsync,this._engineRef={runDirectives:(s,r)=>this._executeDirectives(s,r),runDirectivesAsync:(s,r)=>this._executeDirectivesAsync(s,r),invoke:(s,r,c)=>this._invokeInternal(s,r,c),invokeAsync:(s,r,c)=>this._invokeInternalAsync(s,r,c),evaluateRules:()=>{throw new Error("evaluateRules() not available in ActionEngine context. Use createRuleEngine().")},evaluateRulesAsync:()=>{throw new Error("evaluateRulesAsync() not available in ActionEngine context. Use createRuleEngine().")}},this._directiveRunner=(s,r)=>this._directiveExecutor(s,r,this._handlers,this._directiveHooks,this._typeField,this._engineRef,this._limits.maxDirectives),this._requestedMode==="jit"?(this._directiveExecutor=this._buildJitDirectiveExecutor(),this._mode="jit"):(this._directiveExecutor=B(this._directiveAnalysis,this._isAsync),this._mode="interpret");}register(e){let i=[],n=[],s=[],r=[];for(let h of e){if(!h.id){n.push({actionId:"",error:"Action must have an id"});continue}let x=W(h,this._handlers,this._definitions,this._typeField);if(x.length>0){for(let m of x)n.push({actionId:h.id,error:m});continue}r.push(h);}for(let h of r){let x=H(h.directives,this._typeField),m={definition:h,directives:x,compiled:null,invokeCount:0};this._requestedMode==="jit"&&(m.compiled=this._compileAction(x)),this._registry.set(h.id,m),this._registeredIds.add(h.id),i.push(h.id);}if(this._batchDepth>0){this._batchErrors.push(...n),this._batchWarnings.push(...s);for(let h of r)this._batchActions.push(h);return this._batchRegistered.push(...i),{registered:i,errors:n,warnings:s}}let c={registered:i,errors:n,warnings:s};return i.length>0&&this._emitter.emit("register",{actions:r,result:c,registered:i}),c}unregister(e){let i=this._registry.delete(e);i&&this._registeredIds.delete(e);let n=e+"/",s=[];for(let r of this._registry.keys())r.startsWith(n)&&(this._registry.delete(r),this._registeredIds.delete(r),s.push(r));return i&&this._emitter.emit("unregister",{id:e,cascaded:s}),i}invoke(e,i){if(this._isAsync)throw new Error("Cannot call invoke() with async hooks. Use invokeAsync() instead.");let n=this._requireCtx(),s=createRootFrame(n,this._limits);return this._invokeInternal(e,i,s)}async invokeAsync(e,i){let n=this._requireCtx(),s=createRootFrame(n,this._limits);return this._invokeInternalAsync(e,i,s)}setContext(e){this._ctx=e;}context(e,i){let n=this._ctx;this._ctx=e;try{return i()}finally{this._ctx=n;}}beginBatch(){this._batchDepth++,this._batchDepth===1&&(this._batchErrors=[],this._batchWarnings=[],this._batchActions=[],this._batchRegistered=[]);}endBatch(){if(this._batchDepth<=0)throw new Error("endBatch() called without matching beginBatch()");if(this._batchDepth--,this._batchDepth>0)return {registered:[],errors:[],warnings:[]};let e={registered:this._batchRegistered,errors:this._batchErrors,warnings:this._batchWarnings};return this._batchRegistered.length>0&&this._emitter.emit("register",{actions:this._batchActions,result:e,registered:this._batchRegistered}),e}on(e,i){return this._emitter.on(e,i)}get handlerDefinitions(){return this._definitions}get registeredIds(){return this._registeredIds}getActionDefinition(e){return this._registry.get(e)?.definition}get typeField(){return this._typeField}get directivePermissions(){return this._directivePermissions}get isAsync(){return this._isAsync}get compilationMode(){return this._mode}get directiveHookSlots(){return this._directiveAnalysis.filledNames}get asyncSlots(){return this._directiveAnalysis.asyncNames}compile(){if(this._requestedMode!=="interpret"){this._mode!=="jit"&&this._promote();for(let e of this._registry.values())e.compiled||(e.compiled=this._compileAction(e.directives));}}_invokeInternal(e,i,n){let s=this._prepareInvoke(e,i,n);if("success"in s)return s;let{stored:r,childFrame:c,childScope:h}=s;if(r.compiled)return r.compiled.fn(c,h,r.compiled.$);let x=this._directiveRunner(r.directives,c);return this._maybeAutoPromote(r),x}async _invokeInternalAsync(e,i,n){let s=this._prepareInvoke(e,i,n);if("success"in s)return s;let{stored:r,childFrame:c,childScope:h}=s;if(r.compiled)return r.compiled.fn(c,h,r.compiled.$);let x=this._directiveRunner(r.directives,c);return this._maybeAutoPromote(r),x}_prepareInvoke(e,i,n){let s=this._registry.get(e);if(!s)return U(e,n.counters);if(e.includes("/")&&!this._isAccessible(e,n))return Y(e,n.counters);if(n.depth>=n.limits.maxDepth)return G(e,n.limits.maxDepth,n.counters);let r=Object.create(n.scope);i&&Object.assign(r,i);let c=n.child("action:"+e,0,e).withScope(r);return {stored:s,childFrame:c,childScope:r}}_maybeAutoPromote(e){this._requestedMode==="auto"&&++e.invokeCount>=this._threshold&&(e.compiled=this._compileAction(e.directives),this._mode!=="jit"&&this._promote());}_executeDirectives(e,i){return this._directiveExecutor(e,i,this._handlers,this._directiveHooks,this._typeField,this._engineRef,this._limits.maxDirectives)}async _executeDirectivesAsync(e,i){return this._directiveExecutor(e,i,this._handlers,this._directiveHooks,this._typeField,this._engineRef,this._limits.maxDirectives)}_compileAction(e){let{fn:i}=O(e,this._directiveAnalysis,this._typeField),n={d:e,h:this._handlers,hooks:this._directiveHooks,engine:this._engineRef,runner:this._directiveRunner};return {fn:i,$:n}}_isAccessible(e,i){let s="action:"+e.slice(0,e.lastIndexOf("/"));return i.path.includes(s)}_requireCtx(){if(this._ctx===void 0)throw new Error("No context set. Call setContext(ctx) or use context(ctx, fn) before invoke.");return this._ctx}_promote(){this._directiveExecutor=this._buildJitDirectiveExecutor(),this._mode="jit";}_buildJitDirectiveExecutor(){let{fn:e}=j(this._directiveAnalysis);return e}};function _e(t){return new V(t)}export{S as RESERVED_TYPES,F as SimpleEmitter,O as buildActionExecutor,j as buildDirectiveExecutor,_e as createActionEngine,B as createDirectiveInterpreter,H as normalizeDirectives};
5
+ })();`),isAsync:i}}function N(t,e,i){return `return{success:false,aborted:true,abortedBy:${t},appliedCount,skippedCount,errors,processedCount:${e},totalCount:${i},counters};`}function ie(t,e){return `return{success:true,aborted:true,abortedBy:"halt",appliedCount,skippedCount,errors,processedCount:${t},totalCount:${e},counters,data:_result.data};`}function se(t,e){return `return{success:false,aborted:true,abortedBy:"halt",appliedCount,skippedCount,errors,processedCount:${t},totalCount:${e},counters,data:_result.data};`}function ne(t,e,i){let s=JSON.stringify(e.name);typeof e.resolve=="function"?(t.push("try{"),t.push(`scope[${s}]=$.d[${i}].resolve(ctx,scope).value;`),t.push(`}catch(_e){errors.push({directiveIndex:${i},error:"Binding resolve: "+_e});counters.errors++;}`)):t.push(`scope[${s}]=$.d[${i}].value;`);}function oe(t,e,i,s){let n=typeof e.resolve=="function",r=i+1;n?(t.push("try{"),t.push(`const _rv=$.d[${i}].resolve(ctx,scope);`),t.push(`return{success:true,aborted:false,appliedCount,skippedCount,errors,processedCount:${r},totalCount:${s},counters,data:"value" in _rv?_rv.value:"return" in _rv?_rv.return:$.d[${i}].value};`),t.push(`}catch(_e){errors.push({directiveIndex:${i},error:"Control resolve: "+_e});counters.errors++;}`)):t.push(`return{success:true,aborted:false,appliedCount,skippedCount,errors,processedCount:${r},totalCount:${s},counters,data:$.d[${i}].value};`);}function ce(t,e,i,s){let n=typeof e.resolve=="function",r=i+1;n?(t.push("try{"),t.push(`const _rv=$.d[${i}].resolve(ctx,scope);`),t.push(`return{success:false,aborted:true,abortedBy:"throw",appliedCount,skippedCount,errors,processedCount:${r},totalCount:${s},counters,data:"message" in _rv?_rv.message:"throw" in _rv?_rv.throw:$.d[${i}].message};`),t.push(`}catch(_e){errors.push({directiveIndex:${i},error:"Control resolve: "+_e});counters.errors++;}`)):t.push(`return{success:false,aborted:true,abortedBy:"throw",appliedCount,skippedCount,errors,processedCount:${r},totalCount:${s},counters,data:$.d[${i}].message};`);}function ae(t,e,i,s,n,r,c,f,_,h){let C=e[n],T=r.get(C),v=typeof e.resolve=="function",l=typeof e.as=="string",m=Array.isArray(e.catch)&&e.catch.length>0,x=l?JSON.stringify(e.as):"",u=i+1;t.push(`_b${i}:{`);let D=c||v,R=c;D&&t.push(`let _dir=$.d[${i}];`),R&&t.push("let _df=frame;"),c&&(t.push("try{"),t.push(`const _bd=${_}_hookBefore($.d[${i}],frame);`),t.push(`if(_bd==="skip"){skippedCount++;counters.directivesSkipped++;break _b${i};}`),t.push(`if(_bd==="abort")${N('"beforeDirective"',i,s)}`),t.push('if(typeof _bd==="object"&&_bd!==null){'),t.push(`if("abort" in _bd)${N("_bd.abort",i,s)}`),t.push('if("ctx" in _bd)_df=frame.withCtx(_bd.ctx);'),t.push('if("directive" in _bd)_dir=_bd.directive;'),t.push("}"),t.push(`}catch(_e){errors.push({directiveIndex:${i},error:"Hook beforeDirective: "+_e});counters.errors++;}`)),c?(t.push('if(typeof _dir.resolve==="function"){'),t.push("try{const _r=_dir.resolve(_df.ctx,scope);_dir=Object.assign({},_dir,_r);}"),t.push(`catch(_e){errors.push({directiveIndex:${i},error:"Directive resolve: "+_e});counters.errors++;break _b${i};}}`)):v&&(t.push(`try{const _r=$.d[${i}].resolve(ctx,scope);_dir=Object.assign({},$.d[${i}],_r);}`),t.push(`catch(_e){errors.push({directiveIndex:${i},error:"Directive resolve: "+_e});counters.errors++;break _b${i};}`));let k=D?"_dir":`$.d[${i}]`,a=R?"_df":"frame";t.push("let _result;"),t.push(`try{_result=${T}(${k},${a},$.engine);}`),t.push("catch(_e){_result={ok:false,error:String(_e)};}"),t.push("if(_result.ok){"),t.push("appliedCount++;counters.directivesApplied++;"),l&&t.push(`scope[${x}]=_result.data;`),t.push(`if(_result.halt)${ie(u,s)}`),t.push("}else{"),t.push(`if(_result.halt)${se(u,s)}`),m?(t.push('scope.$exception=_result.error||"handler failed";'),t.push(`const _cr=$.runner($.d[${i}].catch,${a});`),t.push("appliedCount+=_cr.appliedCount;"),t.push("for(let _j=0;_j<_cr.errors.length;_j++)errors.push(_cr.errors[_j]);"),t.push(`if(_cr.aborted)return{success:_cr.success,aborted:true,abortedBy:_cr.abortedBy,appliedCount,skippedCount,errors,processedCount:${u},totalCount:${s},counters,data:_cr.data};`)):t.push(`errors.push({directiveIndex:${i},error:_result.error||"handler failed"});counters.errors++;`),t.push("}"),f&&(t.push("try{"),t.push(`const _ad=${h}_hookAfter(${k},_result,${a});`),t.push(`if(_ad==="abort")${N('"afterDirective"',u,s)}`),t.push(`}catch(_e){errors.push({directiveIndex:${i},error:"Hook afterDirective: "+_e});counters.errors++;}`)),t.push("}");}function O(t,e,i){let s=[],n=t.length,{filledNames:r,hasAnyAsync:c,asyncNames:f}=e,_=r.has("beforeDirective"),h=r.has("afterDirective"),C=r.has("onDirectivesComplete"),T=f.has("beforeDirective")?"await ":"",v=f.has("afterDirective")?"await ":"",l=f.has("onDirectivesComplete")?"await ":"",m=new Set;for(let a of t){let p=a[i];p&&!I.has(p)&&m.add(p);}let x=new Map,u=0;for(let a of m)x.set(a,`_h${u++}`);s.push("const counters=frame.counters;"),s.push("const ctx=frame.ctx;"),s.push("const errors=[];"),s.push("let appliedCount=0;"),s.push("let skippedCount=0;");for(let[a,p]of x)s.push(`const ${p}=$.h[${JSON.stringify(a)}];`);_&&s.push("const _hookBefore=$.hooks.beforeDirective;"),h&&s.push("const _hookAfter=$.hooks.afterDirective;");for(let a=0;a<t.length;a++){let p=t[a];switch(p[i]){case "const":case "let":ne(s,p,a);break;case "return":oe(s,p,a,n);break;case "throw":ce(s,p,a,n);break;default:ae(s,p,a,n,i,x,_,h,T,v);break}}s.push(`const _finalResult={success:true,aborted:false,appliedCount,skippedCount,errors,processedCount:${n},totalCount:${n},counters};`),C&&s.push(`try{${l}$.hooks.onDirectivesComplete(_finalResult);}catch(_e){}`),s.push("return _finalResult;");let D=s.join(`
6
+ `),R=c?"async ":"";return {fn:new Function("frame","scope","$",`"use strict";
7
+ return(${R}()=>{
8
+ ${D}
9
+ })();`),isAsync:c}}function K(t,e,i){return {success:false,aborted:false,appliedCount:0,skippedCount:0,processedCount:0,totalCount:0,errors:[{directiveIndex:-1,error:e}],counters:t,...i}}function U(t,e){return K(e,`Action not found: "${t}"`)}function G(t,e,i){return K(i,`Max depth ${e} exceeded invoking "${t}"`,{aborted:true,abortedBy:"maxDepth"})}function Y(t,e){return K(e,`Action "${t}" is private (sub-action). Can only be invoked from within its parent scope.`)}function z(t,e){return {success:true,aborted:false,appliedCount:0,skippedCount:0,processedCount:0,totalCount:0,errors:[],data:t,counters:e}}function ue(t){return typeof t=="object"&&t!==null&&"execute"in t}function Q(t){let e=Object.create(null),i=new Map;for(let s of Object.keys(t)){let n=t[s];ue(n)?(e[s]=n.execute,i.set(s,n)):(e[s]=n,i.set(s,{execute:n}));}return {handlers:e,definitions:i}}function X(t,e){if(t==="*")return true;if(!t.includes("*"))return t===e;let i=t.replace(/[.+^${}()|[\]\\]/g,"\\$&");return new RegExp("^"+i.replace(/\*/g,".*")+"$").test(e)}function Z(t){return typeof t=="string"?{pattern:t}:t}function L(t,e,i){let s=new Map;if(!e&&!i){for(let n of t)s.set(n,{status:"available"});return s}if(e){let n=e.map(Z);for(let r of t){let c=n.some(f=>X(f.pattern,r));s.set(r,{status:c?"available":"denied"});}}else {let n=i.map(Z);for(let r of t){let c=n.find(f=>X(f.pattern,r));c?s.set(r,{status:"denied",reason:c.reason,source:c.source}):s.set(r,{status:"available"});}}return s}var pe=8,he="type",V={maxDepth:10,maxRules:1e4,maxDirectives:1e5},q=class{_directiveExecutor;_mode;_ctx;_requestedMode;_threshold;_limits;_typeField;_handlers;_definitions;_directiveHooks;_directiveAnalysis;_isAsync;_directivePermissions;_beforeAction;_afterAction;_registry=new Map;_emitter=new H;_batchDepth=0;_batchErrors=[];_batchWarnings=[];_batchActions=[];_batchRegistered=[];_registeredIds=new Set;_directiveRunner;_engineRef;constructor(e){this._requestedMode=e.mode??"auto",this._threshold=e.autoJitThreshold??pe,this._typeField=e.typeField??he,this._limits={maxDepth:e.limits?.maxDepth??V.maxDepth,maxRules:e.limits?.maxRules??V.maxRules,maxDirectives:e.limits?.maxDirectives??V.maxDirectives};let{handlers:i,definitions:s}=Q(e.handlers);for(let n of Object.keys(e.handlers))if(I.has(n))throw new Error(`Handler type "${n}" is reserved for engine-internal directives`);if(e.allowedDirectives&&e.blockedDirectives)throw new Error("allowedDirectives and blockedDirectives are mutually exclusive. Provide one or neither.");this._handlers=i,this._definitions=s,this._directivePermissions=L(Object.keys(i),e.allowedDirectives,e.blockedDirectives),this._directiveHooks=e.directiveHooks??{},this._beforeAction=e.actionHooks?.beforeAction??null,this._afterAction=e.actionHooks?.afterAction??null,this._directiveAnalysis=analyzeSlots(this._directiveHooks,DIRECTIVE_SLOT_NAMES),this._isAsync=this._directiveAnalysis.hasAnyAsync,this._engineRef={runDirectives:(n,r)=>this._executeDirectives(n,r),runDirectivesAsync:(n,r)=>this._executeDirectivesAsync(n,r),invoke:(n,r,c)=>this._invokeInternal(n,r,c),invokeAsync:(n,r,c)=>this._invokeInternalAsync(n,r,c),evaluateRules:()=>{throw new Error("evaluateRules() not available in ActionEngine context. Use createRuleEngine().")},evaluateRulesAsync:()=>{throw new Error("evaluateRulesAsync() not available in ActionEngine context. Use createRuleEngine().")}},this._directiveRunner=(n,r)=>this._directiveExecutor(n,r,this._handlers,this._directiveHooks,this._typeField,this._engineRef,this._limits.maxDirectives),this._requestedMode==="jit"?(this._directiveExecutor=this._buildJitDirectiveExecutor(),this._mode="jit"):(this._directiveExecutor=B(this._directiveAnalysis,this._isAsync),this._mode="interpret");}register(e){let i=[],s=[],n=[],r=[];for(let f of e){if(!f.id){s.push({actionId:"",error:"Action must have an id"});continue}let _=W(f,this._handlers,this._definitions,this._typeField);if(_.length>0){for(let h of _)s.push({actionId:f.id,error:h});continue}r.push(f);}for(let f of r){let _=S(f.directives,this._typeField),h={definition:f,directives:_,compiled:null,invokeCount:0};this._requestedMode==="jit"&&(h.compiled=this._compileAction(_)),this._registry.set(f.id,h),this._registeredIds.add(f.id),i.push(f.id);}if(this._batchDepth>0){this._batchErrors.push(...s),this._batchWarnings.push(...n);for(let f of r)this._batchActions.push(f);return this._batchRegistered.push(...i),{registered:i,errors:s,warnings:n}}let c={registered:i,errors:s,warnings:n};return i.length>0&&this._emitter.emit("register",{actions:r,result:c,registered:i}),c}unregister(e){let i=this._registry.delete(e);i&&this._registeredIds.delete(e);let s=e+"/",n=[];for(let r of this._registry.keys())r.startsWith(s)&&(this._registry.delete(r),this._registeredIds.delete(r),n.push(r));return i&&this._emitter.emit("unregister",{id:e,cascaded:n}),i}invoke(e,i,s){if(this._isAsync)throw new Error("Cannot call invoke() with async hooks. Use invokeAsync() instead.");let n=s!==void 0?s:this._requireCtx(),r=createRootFrame(n,this._limits);return this._invokeInternal(e,i,r)}async invokeAsync(e,i,s){let n=s!==void 0?s:this._requireCtx(),r=createRootFrame(n,this._limits);return this._invokeInternalAsync(e,i,r)}setContext(e){this._ctx=e;}context(e,i){let s=this._ctx;this._ctx=e;try{return i()}finally{this._ctx=s;}}beginBatch(){this._batchDepth++,this._batchDepth===1&&(this._batchErrors=[],this._batchWarnings=[],this._batchActions=[],this._batchRegistered=[]);}endBatch(){if(this._batchDepth<=0)throw new Error("endBatch() called without matching beginBatch()");if(this._batchDepth--,this._batchDepth>0)return {registered:[],errors:[],warnings:[]};let e={registered:this._batchRegistered,errors:this._batchErrors,warnings:this._batchWarnings};return this._batchRegistered.length>0&&this._emitter.emit("register",{actions:this._batchActions,result:e,registered:this._batchRegistered}),e}on(e,i){return this._emitter.on(e,i)}get handlerDefinitions(){return this._definitions}get registeredIds(){return this._registeredIds}getActionDefinition(e){return this._registry.get(e)?.definition}get typeField(){return this._typeField}get directivePermissions(){return this._directivePermissions}get isAsync(){return this._isAsync}get compilationMode(){return this._mode}get directiveHookSlots(){return this._directiveAnalysis.filledNames}get asyncSlots(){return this._directiveAnalysis.asyncNames}compile(){if(this._requestedMode!=="interpret"){this._mode!=="jit"&&this._promote();for(let e of this._registry.values())e.compiled||(e.compiled=this._compileAction(e.directives));}}_invokeInternal(e,i,s){let n=this._prepareInvoke(e,i,s);if("success"in n)return n;let{stored:r,childFrame:c,childScope:f}=n;if(this._beforeAction!==null){let h=this._beforeAction(e,i,c);if(h?.skip)return z(h.data,c.counters)}let _;if(r.compiled?_=r.compiled.fn(c,f,r.compiled.$):(_=this._directiveRunner(r.directives,c),this._maybeAutoPromote(r)),this._afterAction!==null){let h=this._afterAction(e,i,_,c);h!==void 0&&(_=h);}return _}async _invokeInternalAsync(e,i,s){let n=this._prepareInvoke(e,i,s);if("success"in n)return n;let{stored:r,childFrame:c,childScope:f}=n;if(this._beforeAction!==null){let h=this._beforeAction(e,i,c);if(h?.skip)return z(h.data,c.counters)}let _;if(r.compiled?_=await r.compiled.fn(c,f,r.compiled.$):(_=await this._directiveRunner(r.directives,c),this._maybeAutoPromote(r)),this._afterAction!==null){let h=this._afterAction(e,i,_,c);h!==void 0&&(_=h);}return _}_prepareInvoke(e,i,s){let n=this._registry.get(e);if(!n)return U(e,s.counters);if(e.includes("/")&&!this._isAccessible(e,s))return Y(e,s.counters);if(s.depth>=s.limits.maxDepth)return G(e,s.limits.maxDepth,s.counters);let r=Object.create(s.scope);i&&Object.assign(r,i);let c=s.child("action:"+e,0,e).withScope(r);return {stored:n,childFrame:c,childScope:r}}_maybeAutoPromote(e){this._requestedMode==="auto"&&++e.invokeCount>=this._threshold&&(e.compiled=this._compileAction(e.directives),this._mode!=="jit"&&this._promote());}_executeDirectives(e,i){return this._directiveExecutor(e,i,this._handlers,this._directiveHooks,this._typeField,this._engineRef,this._limits.maxDirectives)}async _executeDirectivesAsync(e,i){return this._directiveExecutor(e,i,this._handlers,this._directiveHooks,this._typeField,this._engineRef,this._limits.maxDirectives)}_compileAction(e){let{fn:i}=O(e,this._directiveAnalysis,this._typeField),s={d:e,h:this._handlers,hooks:this._directiveHooks,engine:this._engineRef,runner:this._directiveRunner};return {fn:i,$:s}}_isAccessible(e,i){let n="action:"+e.slice(0,e.lastIndexOf("/"));return i.path.includes(n)}_requireCtx(){if(this._ctx===void 0)throw new Error("No context set. Pass ctx to invoke(id, params, ctx), call setContext(ctx), or use context(ctx, fn).");return this._ctx}_promote(){this._directiveExecutor=this._buildJitDirectiveExecutor(),this._mode="jit";}_buildJitDirectiveExecutor(){let{fn:e}=j(this._directiveAnalysis);return e}};function fe(t){return new q(t)}export{I as RESERVED_TYPES,H as SimpleEmitter,O as buildActionExecutor,j as buildDirectiveExecutor,fe as createActionEngine,B as createDirectiveInterpreter,S as normalizeDirectives};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@statedelta-actions/actions",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Directive execution engine with JIT compilation and BailHook interception",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -18,7 +18,7 @@
18
18
  "README.md"
19
19
  ],
20
20
  "dependencies": {
21
- "@statedelta-actions/core": "0.1.0"
21
+ "@statedelta-actions/core": "0.2.0"
22
22
  },
23
23
  "author": "Anderson D. Rosa <andersondrosa@outlook.com>",
24
24
  "license": "MIT",