@statedelta-actions/events 0.3.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +89 -0
- package/LICENSE +21 -0
- package/README.md +31 -6
- package/dist/index.cjs +8 -4
- package/dist/index.d.cts +29 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.js +8 -4
- package/package.json +18 -6
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# @statedelta-actions/events
|
|
2
|
+
|
|
3
|
+
## 0.5.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 26c579a: Polish published package metadata and READMEs
|
|
8
|
+
- `@statedelta-actions/core` now ships a README (was missing on npm).
|
|
9
|
+
- `@statedelta-actions/analyzer` README: fixed pervasive missing accents.
|
|
10
|
+
- `graph` and `events` READMEs: titles are now the package name (`# @statedelta-actions/graph` / `# @statedelta-actions/events`) instead of a conceptual name.
|
|
11
|
+
- All packages: added `keywords`, `homepage`, `bugs`; package.json keys reordered to a canonical layout.
|
|
12
|
+
- All packages: `CHANGELOG.md` added to `files` so it ships to npm; a `LICENSE` (MIT) file is included in the repo root and in each package.
|
|
13
|
+
|
|
14
|
+
- Updated dependencies [26c579a]
|
|
15
|
+
- Updated dependencies [a3a818b]
|
|
16
|
+
- @statedelta-actions/core@0.5.1
|
|
17
|
+
- @statedelta-actions/actions@0.6.0
|
|
18
|
+
|
|
19
|
+
## 0.5.0
|
|
20
|
+
|
|
21
|
+
### Minor Changes
|
|
22
|
+
|
|
23
|
+
- f8c2b4a: Fail-fast register errors, controlled `action-not-found`, atomic registration, and events async/interactive modes
|
|
24
|
+
- **actions** — A missing handler for a directive type now throws at register
|
|
25
|
+
time (was a collected error) — fail-fast for typos and forgotten handlers.
|
|
26
|
+
Invoking an unknown action id returns `aborted: true, abortedBy:
|
|
27
|
+
"action-not-found"` instead of a soft failure. `isActionAsync` is exposed on
|
|
28
|
+
the engine ref handed to handlers (symmetric with `isActionInteractive`).
|
|
29
|
+
- **rules** — `register()` is atomic: it builds a staging set, delegates to the
|
|
30
|
+
ActionEngine, then indexes locally only on success. Structural errors from the
|
|
31
|
+
ActionEngine propagate as a throw with no local state mutated.
|
|
32
|
+
- **events** — `register()`/`defineEvents()` are atomic the same way.
|
|
33
|
+
Async detection is now per-listener transitive via the ActionEngine mini-graph,
|
|
34
|
+
so hybrid engines keep `processEvents`/`processEventsAsync` viable for
|
|
35
|
+
listeners whose subtree is fully sync. New `processEventsInteractive()` returns
|
|
36
|
+
a drainable iterator (sync or async generator) — pauses from `type:"pause"` or
|
|
37
|
+
an interactive handler flow via `yield*` up to the consumer; halt scoping is
|
|
38
|
+
preserved (a pause stops the listeners of that event, following events
|
|
39
|
+
continue). New `isInteractive` getter.
|
|
40
|
+
- **core** — `ActionEngineRef` gains an optional `isActionAsync?` accessor.
|
|
41
|
+
- **sdk** — re-exports the new event types/surface; barrel deps moved to
|
|
42
|
+
`dependencies` (`workspace:^`).
|
|
43
|
+
|
|
44
|
+
### Patch Changes
|
|
45
|
+
|
|
46
|
+
- Updated dependencies [f8c2b4a]
|
|
47
|
+
- @statedelta-actions/actions@0.5.0
|
|
48
|
+
- @statedelta-actions/core@0.5.0
|
|
49
|
+
|
|
50
|
+
## 0.3.0
|
|
51
|
+
|
|
52
|
+
### Minor Changes
|
|
53
|
+
|
|
54
|
+
- Split types em definitions + engine em cada package; novo subpath sdk/definitions
|
|
55
|
+
- core: RegisterWarning movido pra core/types/engine.ts (tipo shared entre packages)
|
|
56
|
+
- actions: types.ts → types/definitions.ts + types/engine.ts
|
|
57
|
+
- rules: types.ts → types/definitions.ts + types/engine.ts
|
|
58
|
+
- events: types.ts → types/definitions.ts + types/engine.ts
|
|
59
|
+
- sdk: novo subpath ./definitions com re-export de definition types puros (zero runtime)
|
|
60
|
+
|
|
61
|
+
### Patch Changes
|
|
62
|
+
|
|
63
|
+
- Updated dependencies []:
|
|
64
|
+
- @statedelta-actions/core@0.3.0
|
|
65
|
+
- @statedelta-actions/actions@0.3.0
|
|
66
|
+
|
|
67
|
+
## 0.2.0
|
|
68
|
+
|
|
69
|
+
### Minor Changes
|
|
70
|
+
|
|
71
|
+
- Sync all packages to 0.2.0 (match SDK version)
|
|
72
|
+
|
|
73
|
+
### Patch Changes
|
|
74
|
+
|
|
75
|
+
- Updated dependencies []:
|
|
76
|
+
- @statedelta-actions/core@0.2.0
|
|
77
|
+
- @statedelta-actions/actions@0.2.0
|
|
78
|
+
|
|
79
|
+
## 0.3.0
|
|
80
|
+
|
|
81
|
+
### Minor Changes
|
|
82
|
+
|
|
83
|
+
- Sync all packages to 0.2.0 (match SDK version)
|
|
84
|
+
|
|
85
|
+
### Patch Changes
|
|
86
|
+
|
|
87
|
+
- Updated dependencies []:
|
|
88
|
+
- @statedelta-actions/core@0.3.0
|
|
89
|
+
- @statedelta-actions/actions@0.3.0
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Anderson D. Rosa
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @statedelta-actions/events
|
|
2
2
|
|
|
3
|
-
> **
|
|
4
|
-
> **Escopo:** Dispatcher de listeners sobre o ActionEngine. Listeners reagem a eventos nomeados, executando diretivas via hidden actions.
|
|
3
|
+
> **EventProcessor** — eventos como actions deferidas. Dispatcher de listeners sobre o ActionEngine: listeners reagem a eventos nomeados, executando diretivas via hidden actions.
|
|
5
4
|
> **Dependências:** `core/` (tipos, slot analysis), `actions/` (IActionEngine). Zero dependência de `rules/`.
|
|
6
5
|
>
|
|
7
6
|
> Para arquitetura interna, pipelines e fluxos, ver [`docs/ARCHITECTURE.md`](./docs/ARCHITECTURE.md).
|
|
@@ -90,22 +89,45 @@ const result = ep.register([
|
|
|
90
89
|
ep.unregister("on-save"); // true se existia, false se não
|
|
91
90
|
```
|
|
92
91
|
|
|
92
|
+
#### Throw vs collected errors
|
|
93
|
+
|
|
94
|
+
`register` e `defineEvents` são atômicos: o registro local só é aplicado depois que o ActionEngine aceita todas as hidden actions. Comportamento por tipo de erro:
|
|
95
|
+
|
|
96
|
+
| Erro | Comportamento |
|
|
97
|
+
|------|---------------|
|
|
98
|
+
| Handler ausente para um tipo de diretiva em `then` (qualquer profundidade, inclusive `catch`) | **Lança `Error`** propagado do `actionEngine.register`. Estado local intocado. |
|
|
99
|
+
| Listener/event duplicado, missing required field, tier violation contra `EventDefinition` | Coletado em `errors[]`. Outros itens válidos no mesmo call ainda registram. |
|
|
100
|
+
| `validate()` de handler retorna invalid ou lança | Coletado em `errors[]`. |
|
|
101
|
+
|
|
102
|
+
Throw é reservado pra erros estruturais que não viram válidos em runtime — typo, handler esquecido, refactor incompleto. Soft errors são domain-level e merecem inspeção pelo consumer.
|
|
103
|
+
|
|
93
104
|
### Processing
|
|
94
105
|
|
|
95
106
|
```typescript
|
|
96
|
-
// Sync (throws se
|
|
107
|
+
// Sync (throws se algum listener é async ou interactive transitivamente)
|
|
97
108
|
const result = ep.processEvents(
|
|
98
109
|
[{ event: "save" }, { event: "damage", data: { amount: 10 } }],
|
|
99
110
|
ctx,
|
|
100
111
|
);
|
|
101
112
|
|
|
102
|
-
// Async (
|
|
113
|
+
// Async (throws se algum listener é interactive transitivamente)
|
|
103
114
|
const result = await ep.processEventsAsync(
|
|
104
115
|
[{ event: "save" }],
|
|
105
116
|
ctx,
|
|
106
117
|
);
|
|
118
|
+
|
|
119
|
+
// Interactive — retorna iterator drenável (sync ou async generator)
|
|
120
|
+
const session = ep.processEventsInteractive([{ event: "save" }], ctx);
|
|
121
|
+
let step = session.next();
|
|
122
|
+
while (!step.done) {
|
|
123
|
+
// step.value = payload do yield (PauseEvent ou payload de handler interactive)
|
|
124
|
+
step = session.next(/* resposta do consumer */);
|
|
125
|
+
}
|
|
126
|
+
// step.value = EventProcessingResult
|
|
107
127
|
```
|
|
108
128
|
|
|
129
|
+
`processEventsInteractive` lança se nenhum listener registrado é interactive transitivamente. Pausas fluem via `yield*` em 3 níveis (consumer → events generator → `actionEngine.invokeInteractive`). Halt scoping preservado: pause/halt num listener para os listeners daquele evento; próximos eventos na fila continuam.
|
|
130
|
+
|
|
109
131
|
### Batch
|
|
110
132
|
|
|
111
133
|
```typescript
|
|
@@ -124,9 +146,12 @@ ep.compile();
|
|
|
124
146
|
|
|
125
147
|
// Consultar modo atual
|
|
126
148
|
ep.compilationMode; // "interpret" | "jit"
|
|
127
|
-
ep.isAsync; // true se hooks
|
|
149
|
+
ep.isAsync; // true se hooks são async OU se algum listener é async transitivamente
|
|
150
|
+
ep.isInteractive; // true se algum listener é interactive transitivamente
|
|
128
151
|
```
|
|
129
152
|
|
|
153
|
+
`isAsync` e `isInteractive` são per-listener transitivos. Engine híbrido (handler async + listener cuja sub-árvore é 100% sync) mantém `processEvents` (sync) viável — só listeners que invocam handler async transitivamente forçam `processEventsAsync`, só listeners interactive transitivamente forçam `processEventsInteractive`. Detecção via mini-graph do ActionEngine, refrescada em register/unregister/endBatch. O dispatcher interactive é lazy — só construído na primeira chamada de `processEventsInteractive` (custo zero pra engines sem nada interactive).
|
|
154
|
+
|
|
130
155
|
---
|
|
131
156
|
|
|
132
157
|
## Hooks — EventHooks
|
package/dist/index.cjs
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
'use strict';var core=require('@statedelta-actions/core');function
|
|
2
|
-
`),p=r?"async ":"",
|
|
1
|
+
'use strict';var core=require('@statedelta-actions/core');function N(){return {rulesEvaluated:0,rulesMatched:0,rulesSkipped:0,directivesApplied:0,directivesSkipped:0,subRunsCreated:0,errors:0}}function O(t,n){t.rulesEvaluated+=n.rulesEvaluated,t.rulesMatched+=n.rulesMatched,t.rulesSkipped+=n.rulesSkipped,t.directivesApplied+=n.directivesApplied,t.directivesSkipped+=n.directivesSkipped,t.subRunsCreated+=n.subRunsCreated,t.errors+=n.errors;}function M(t,n,r,o){let a=o?Object.assign({},o):{};for(let d of t)Object.assign(a,d(n,r,a));return a}function J(t){let n=t.filledNames.has("beforeEvent"),r=t.filledNames.has("afterEvent"),o=t.filledNames.has("onEventsComplete");return function(d,f,g,s,c,l){let E=[],y=[],e=[],k=N(),R=c.length>0;s.setContext(g);for(let p of f){let _=d.get(p.event);if(!_||_.length===0){y.push(p.event);continue}let b=[],A=[],S=[],C=[],i=N(),w=false,T,D={ctx:g,counters:i,event:p.event},L={$event:{type:p.event,data:p.data}};for(let h=0;h<_.length;h++){let m=_[h];if(i.rulesEvaluated++,n)try{let v=l.beforeEvent(m.definition,D);if(v==="skip"){A.push(h),i.rulesSkipped++;continue}if(v==="abort")break}catch(v){C.push({ruleIndex:h,error:`beforeEvent: ${v}`}),i.errors++;}b.push(h),i.rulesMatched++;let x;if(R)try{x=M(c,m.definition,g,L);}catch(v){C.push({ruleIndex:h,error:`Middleware: ${v}`}),i.errors++;continue}else x=L;let u=s.invoke(m.actionId,x);if(i.directivesApplied+=u.appliedCount,i.directivesSkipped+=u.skippedCount,i.errors+=u.errors.length,r)try{if(l.afterEvent(m.definition,u,D)==="abort")break}catch{}if(u.aborted){w=true,T=u.abortedBy;break}}e.push(...C),O(k,i),E.push({event:p.event,matched:b,skipped:A,notMatched:S,errors:C,halted:w,haltedBy:T,counters:i});}let I={eventResults:E,unprocessedEvents:y,errors:e,counters:k,totalEvents:f.length,processedEvents:E.length};if(o)try{l.onEventsComplete(I);}catch{}return I}}function z(t){let n=t.filledNames.has("beforeEvent"),r=t.filledNames.has("afterEvent"),o=t.filledNames.has("onEventsComplete");return async function(d,f,g,s,c,l){let E=[],y=[],e=[],k=N(),R=c.length>0;s.setContext(g);for(let p of f){let _=d.get(p.event);if(!_||_.length===0){y.push(p.event);continue}let b=[],A=[],S=[],C=[],i=N(),w=false,T,D={ctx:g,counters:i,event:p.event},L={$event:{type:p.event,data:p.data}};for(let h=0;h<_.length;h++){let m=_[h];if(i.rulesEvaluated++,n)try{let v=await l.beforeEvent(m.definition,D);if(v==="skip"){A.push(h),i.rulesSkipped++;continue}if(v==="abort")break}catch(v){C.push({ruleIndex:h,error:`beforeEvent: ${v}`}),i.errors++;}b.push(h),i.rulesMatched++;let x;if(R)try{x=M(c,m.definition,g,L);}catch(v){C.push({ruleIndex:h,error:`Middleware: ${v}`}),i.errors++;continue}else x=L;let u=await s.invokeAsync(m.actionId,x);if(i.directivesApplied+=u.appliedCount,i.directivesSkipped+=u.skippedCount,i.errors+=u.errors.length,r)try{if(await l.afterEvent(m.definition,u,D)==="abort")break}catch{}if(u.aborted){w=true,T=u.abortedBy;break}}e.push(...C),O(k,i),E.push({event:p.event,matched:b,skipped:A,notMatched:S,errors:C,halted:w,haltedBy:T,counters:i});}let I={eventResults:E,unprocessedEvents:y,errors:e,counters:k,totalEvents:f.length,processedEvents:E.length};if(o)try{await l.onEventsComplete(I);}catch{}return I}}function $(t,n){return n?z(t):J(t)}function P(){return {rulesEvaluated:0,rulesMatched:0,rulesSkipped:0,directivesApplied:0,directivesSkipped:0,subRunsCreated:0,errors:0}}function j(t,n){t.rulesEvaluated+=n.rulesEvaluated,t.rulesMatched+=n.rulesMatched,t.rulesSkipped+=n.rulesSkipped,t.directivesApplied+=n.directivesApplied,t.directivesSkipped+=n.directivesSkipped,t.subRunsCreated+=n.subRunsCreated,t.errors+=n.errors;}function K(t){let n=t.filledNames.has("beforeEvent"),r=t.filledNames.has("afterEvent"),o=t.filledNames.has("onEventsComplete");return function*(d,f,g,s,c,l){let E=[],y=[],e=[],k=P(),R=c.length>0;s.setContext(g);for(let p of f){let _=d.get(p.event);if(!_||_.length===0){y.push(p.event);continue}let b=[],A=[],S=[],C=[],i=P(),w=false,T,D={ctx:g,counters:i,event:p.event},L={$event:{type:p.event,data:p.data}};for(let h=0;h<_.length;h++){let m=_[h];if(i.rulesEvaluated++,n)try{let v=l.beforeEvent(m.definition,D);if(v==="skip"){A.push(h),i.rulesSkipped++;continue}if(v==="abort")break}catch(v){C.push({ruleIndex:h,error:`beforeEvent: ${v}`}),i.errors++;}b.push(h),i.rulesMatched++;let x;if(R)try{x=M(c,m.definition,g,L);}catch(v){C.push({ruleIndex:h,error:`Middleware: ${v}`}),i.errors++;continue}else x=L;let u;if(m.isInteractive?u=yield*s.invokeInteractive(m.actionId,x):u=s.invoke(m.actionId,x),i.directivesApplied+=u.appliedCount,i.directivesSkipped+=u.skippedCount,i.errors+=u.errors.length,r)try{if(l.afterEvent(m.definition,u,D)==="abort")break}catch{}if(u.aborted){w=true,T=u.abortedBy;break}}e.push(...C),j(k,i),E.push({event:p.event,matched:b,skipped:A,notMatched:S,errors:C,halted:w,haltedBy:T,counters:i});}let I={eventResults:E,unprocessedEvents:y,errors:e,counters:k,totalEvents:f.length,processedEvents:E.length};if(o)try{l.onEventsComplete(I);}catch{}return I}}function X(t){let n=t.filledNames.has("beforeEvent"),r=t.filledNames.has("afterEvent"),o=t.filledNames.has("onEventsComplete");return async function*(d,f,g,s,c,l){let E=[],y=[],e=[],k=P(),R=c.length>0;s.setContext(g);for(let p of f){let _=d.get(p.event);if(!_||_.length===0){y.push(p.event);continue}let b=[],A=[],S=[],C=[],i=P(),w=false,T,D={ctx:g,counters:i,event:p.event},L={$event:{type:p.event,data:p.data}};for(let h=0;h<_.length;h++){let m=_[h];if(i.rulesEvaluated++,n)try{let v=await l.beforeEvent(m.definition,D);if(v==="skip"){A.push(h),i.rulesSkipped++;continue}if(v==="abort")break}catch(v){C.push({ruleIndex:h,error:`beforeEvent: ${v}`}),i.errors++;}b.push(h),i.rulesMatched++;let x;if(R)try{x=M(c,m.definition,g,L);}catch(v){C.push({ruleIndex:h,error:`Middleware: ${v}`}),i.errors++;continue}else x=L;let u;if(m.isInteractive?u=yield*s.invokeInteractive(m.actionId,x):m.isAsync?u=await s.invokeAsync(m.actionId,x):u=s.invoke(m.actionId,x),i.directivesApplied+=u.appliedCount,i.directivesSkipped+=u.skippedCount,i.errors+=u.errors.length,r)try{if(await l.afterEvent(m.definition,u,D)==="abort")break}catch{}if(u.aborted){w=true,T=u.abortedBy;break}}e.push(...C),j(k,i),E.push({event:p.event,matched:b,skipped:A,notMatched:S,errors:C,halted:w,haltedBy:T,counters:i});}let I={eventResults:E,unprocessedEvents:y,errors:e,counters:k,totalEvents:f.length,processedEvents:E.length};if(o)try{await l.onEventsComplete(I);}catch{}return I}}function V(t,n){return n?X(t):K(t)}function H(t,n,r){let{filledNames:o,asyncNames:a}=t,d=A=>o.has(A),f=A=>a.has(A)?"await ":"",g=d("beforeEvent"),s=d("afterEvent"),c=d("onEventsComplete"),l=f("beforeEvent"),E=f("afterEvent"),y=f("onEventsComplete"),e=[];e.push("const eventResults=[];"),e.push("const unprocessedEvents=[];"),e.push("const aggErrors=[];"),e.push("const aggCounters={rulesEvaluated:0,rulesMatched:0,rulesSkipped:0,directivesApplied:0,directivesSkipped:0,subRunsCreated:0,errors:0};"),e.push("ae.setContext(ctx);"),c&&e.push("const _hookOnComplete=hooks.onEventsComplete;"),e.push("for(let _ei=0;_ei<events.length;_ei++){"),e.push("const ev=events[_ei];"),e.push("const _evListeners=listenerIndex.get(ev.event);"),e.push("if(!_evListeners||_evListeners.length===0){unprocessedEvents.push(ev.event);continue;}"),e.push("const matched=[];const skipped=[];const notMatched=[];"),e.push("const errors=[];"),e.push("const counters={rulesEvaluated:0,rulesMatched:0,rulesSkipped:0,directivesApplied:0,directivesSkipped:0,subRunsCreated:0,errors:0};"),e.push("let halted=false;let haltedBy;"),(g||s)&&e.push("const evalCtx={ctx,counters,event:ev.event};"),g&&e.push("const _hookBefore=hooks.beforeEvent;"),s&&e.push("const _hookAfter=hooks.afterEvent;"),e.push("const _ep={$event:{type:ev.event,data:ev.data}};"),e.push("for(let _ri=0;_ri<_evListeners.length;_ri++){"),e.push("const stored=_evListeners[_ri];"),e.push("counters.rulesEvaluated++;"),g&&(e.push("try{"),e.push(`const _bd=${l}_hookBefore(stored.definition,evalCtx);`),e.push('if(_bd==="skip"){skipped.push(_ri);counters.rulesSkipped++;continue;}'),e.push('if(_bd==="abort"){break;}'),e.push('}catch(_e){errors.push({ruleIndex:_ri,error:"beforeEvent: "+_e});counters.errors++;}')),e.push("matched.push(_ri);counters.rulesMatched++;"),n&&(e.push("let params;"),e.push('try{params=$.runMw(mw,stored.definition,ctx,_ep);}catch(_e){errors.push({ruleIndex:_ri,error:"Middleware: "+_e});counters.errors++;continue;}'));let k=n?"params":"_ep",R=r?`await ae.invokeAsync(stored.actionId,${k})`:`ae.invoke(stored.actionId,${k})`;e.push(`const ir=${R};`),e.push("counters.directivesApplied+=ir.appliedCount;counters.directivesSkipped+=ir.skippedCount;counters.errors+=ir.errors.length;"),s&&(e.push("try{"),e.push(`const _ad=${E}_hookAfter(stored.definition,ir,evalCtx);`),e.push('if(_ad==="abort"){break;}'),e.push("}catch(_e){}")),e.push("if(ir.aborted){halted=true;haltedBy=ir.abortedBy;break;}"),e.push("}"),e.push("aggCounters.rulesEvaluated+=counters.rulesEvaluated;"),e.push("aggCounters.rulesMatched+=counters.rulesMatched;"),e.push("aggCounters.rulesSkipped+=counters.rulesSkipped;"),e.push("aggCounters.directivesApplied+=counters.directivesApplied;"),e.push("aggCounters.directivesSkipped+=counters.directivesSkipped;"),e.push("aggCounters.subRunsCreated+=counters.subRunsCreated;"),e.push("aggCounters.errors+=counters.errors;"),e.push("for(let _k=0;_k<errors.length;_k++)aggErrors.push(errors[_k]);"),e.push("eventResults.push({event:ev.event,matched,skipped,notMatched,errors,halted,haltedBy,counters});"),e.push("}"),e.push("const _r={eventResults,unprocessedEvents,errors:aggErrors,counters:aggCounters,totalEvents:events.length,processedEvents:eventResults.length};"),c&&e.push(`try{${y}_hookOnComplete(_r);}catch(_e){}`),e.push("return _r;");let I=e.join(`
|
|
2
|
+
`),p=r?"async ":"",_=new Function("listenerIndex","events","ctx","ae","mw","hooks","$",`"use strict";
|
|
3
3
|
return(${p}()=>{
|
|
4
|
-
${
|
|
5
|
-
})();`),
|
|
4
|
+
${I}
|
|
5
|
+
})();`),b={};return n&&(b.runMw=M),function(S,C,i,w,T,D){return _(S,C,i,w,T,D,b)}}function Q(t,n,r){let{filledNames:o,asyncNames:a}=t,d=b=>o.has(b),f=b=>a.has(b)?"await ":"",g=d("beforeEvent"),s=d("afterEvent"),c=d("onEventsComplete"),l=f("beforeEvent"),E=f("afterEvent"),y=f("onEventsComplete"),e=[];e.push("const eventResults=[];"),e.push("const unprocessedEvents=[];"),e.push("const aggErrors=[];"),e.push("const aggCounters={rulesEvaluated:0,rulesMatched:0,rulesSkipped:0,directivesApplied:0,directivesSkipped:0,subRunsCreated:0,errors:0};"),e.push("ae.setContext(ctx);"),c&&e.push("const _hookOnComplete=hooks.onEventsComplete;"),e.push("for(let _ei=0;_ei<events.length;_ei++){"),e.push("const ev=events[_ei];"),e.push("const _evListeners=listenerIndex.get(ev.event);"),e.push("if(!_evListeners||_evListeners.length===0){unprocessedEvents.push(ev.event);continue;}"),e.push("const matched=[];const skipped=[];const notMatched=[];"),e.push("const errors=[];"),e.push("const counters={rulesEvaluated:0,rulesMatched:0,rulesSkipped:0,directivesApplied:0,directivesSkipped:0,subRunsCreated:0,errors:0};"),e.push("let halted=false;let haltedBy;"),(g||s)&&e.push("const evalCtx={ctx,counters,event:ev.event};"),g&&e.push("const _hookBefore=hooks.beforeEvent;"),s&&e.push("const _hookAfter=hooks.afterEvent;"),e.push("const _ep={$event:{type:ev.event,data:ev.data}};"),e.push("for(let _ri=0;_ri<_evListeners.length;_ri++){"),e.push("const stored=_evListeners[_ri];"),e.push("counters.rulesEvaluated++;"),g&&(e.push("try{"),e.push(`const _bd=${l}_hookBefore(stored.definition,evalCtx);`),e.push('if(_bd==="skip"){skipped.push(_ri);counters.rulesSkipped++;continue;}'),e.push('if(_bd==="abort"){break;}'),e.push('}catch(_e){errors.push({ruleIndex:_ri,error:"beforeEvent: "+_e});counters.errors++;}')),e.push("matched.push(_ri);counters.rulesMatched++;"),n&&(e.push("let params;"),e.push('try{params=$.runMw(mw,stored.definition,ctx,_ep);}catch(_e){errors.push({ruleIndex:_ri,error:"Middleware: "+_e});counters.errors++;continue;}'));let k=n?"params":"_ep";e.push("let ir;"),e.push("if(stored.isInteractive){"),e.push(`ir=yield* ae.invokeInteractive(stored.actionId,${k});`),r&&(e.push("}else if(stored.isAsync){"),e.push(`ir=await ae.invokeAsync(stored.actionId,${k});`)),e.push("}else{"),e.push(`ir=ae.invoke(stored.actionId,${k});`),e.push("}"),e.push("counters.directivesApplied+=ir.appliedCount;counters.directivesSkipped+=ir.skippedCount;counters.errors+=ir.errors.length;"),s&&(e.push("try{"),e.push(`const _ad=${E}_hookAfter(stored.definition,ir,evalCtx);`),e.push('if(_ad==="abort"){break;}'),e.push("}catch(_e){}")),e.push("if(ir.aborted){halted=true;haltedBy=ir.abortedBy;break;}"),e.push("}"),e.push("aggCounters.rulesEvaluated+=counters.rulesEvaluated;"),e.push("aggCounters.rulesMatched+=counters.rulesMatched;"),e.push("aggCounters.rulesSkipped+=counters.rulesSkipped;"),e.push("aggCounters.directivesApplied+=counters.directivesApplied;"),e.push("aggCounters.directivesSkipped+=counters.directivesSkipped;"),e.push("aggCounters.subRunsCreated+=counters.subRunsCreated;"),e.push("aggCounters.errors+=counters.errors;"),e.push("for(let _k=0;_k<errors.length;_k++)aggErrors.push(errors[_k]);"),e.push("eventResults.push({event:ev.event,matched,skipped,notMatched,errors,halted,haltedBy,counters});"),e.push("}"),e.push("const _r={eventResults,unprocessedEvents,errors:aggErrors,counters:aggCounters,totalEvents:events.length,processedEvents:eventResults.length};"),c&&e.push(`try{${y}_hookOnComplete(_r);}catch(_e){}`),e.push("return _r;");let R=e.join(`
|
|
6
|
+
`),I=r?"async function* ":"function* ",p=new Function("listenerIndex","events","ctx","ae","mw","hooks","$",`"use strict";
|
|
7
|
+
return(${I}(){
|
|
8
|
+
${R}
|
|
9
|
+
})();`),_={};return n&&(_.runMw=M),function(A,S,C,i,w,T){return p(A,S,C,i,w,T,_)}}function W(t){return !t.event||typeof t.event!="string"?{event:t.event??"(missing)",code:"INVALID_DEFINITION",message:"event definition must have a non-empty string event name"}:t.tags!==void 0&&!Array.isArray(t.tags)?{event:t.event,code:"INVALID_DEFINITION",message:"event definition tags must be an array of strings"}:t.tier!==void 0&&typeof t.tier!="number"?{event:t.event,code:"INVALID_DEFINITION",message:"event definition tier must be a number"}:null}function G(t){if(!t.id||typeof t.id!="string")return {listenerId:t.id??"(missing)",code:"INVALID_LISTENER",message:"listener must have a string id"};if(typeof t.priority!="number")return {listenerId:t.id,code:"INVALID_LISTENER",message:"listener must have a numeric priority"};if(typeof t.on=="string"){if(!t.on)return {listenerId:t.id,code:"INVALID_LISTENER",message:"listener.on must be a non-empty string or string[]"}}else if(Array.isArray(t.on)){if(t.on.length===0||t.on.some(n=>typeof n!="string"||!n))return {listenerId:t.id,code:"INVALID_LISTENER",message:"listener.on must be a non-empty string or string[] of non-empty strings"}}else return {listenerId:t.id,code:"INVALID_LISTENER",message:"listener.on must be a string or string[]"};return !Array.isArray(t.then)||t.then.length===0?{listenerId:t.id,code:"INVALID_LISTENER",message:"listener must have a non-empty then array"}:null}function q(t,n){let r=0,o=t.length;for(;r<o;){let a=r+o>>>1;t[a].priority>=n.priority?r=a+1:o=a;}t.splice(r,0,n);}function U(t,n){let r=t.indexOf(n);return r===-1?false:(t.splice(r,1),true)}var F=()=>{},B=class{_actionEngine;_middleware;_eventHooks;_requestedMode;_hookAnalysis;_isAsync;_hasAnyInteractiveListener=false;_dispatcher;_mode;_maybeAutoPromote;_interactiveDispatcher=null;_interactiveDispatcherIsAsync=false;_eventDefinitions=new Map;_listenerRegistry=new Map;_listenerIndex=new Map;_batch=null;constructor(n){if(this._actionEngine=n.actionEngine,this._middleware=n.middleware??[],this._eventHooks=n.eventHooks??{},this._requestedMode=n.mode??"auto",this._hookAnalysis=core.analyzeSlots(this._eventHooks,core.EVENT_SLOT_NAMES),this._isAsync=this._hookAnalysis.hasAnyAsync,this._requestedMode==="jit")this._dispatcher=this._buildJit(),this._mode="jit",this._maybeAutoPromote=F;else if(this._dispatcher=$(this._hookAnalysis,this._isAsync),this._mode="interpret",this._requestedMode==="auto"){let r=0,o=n.autoJitThreshold??8;this._maybeAutoPromote=()=>{++r>=o&&this._promote();};}else this._maybeAutoPromote=F;}get actionEngine(){return this._actionEngine}get isAsync(){return this._isAsync}get isInteractive(){return this._hasAnyInteractiveListener}get compilationMode(){return this._mode}get eventDefinitions(){return this._eventDefinitions}getEventDefinition(n){return this._eventDefinitions.get(n)}defineEvents(n){let r=[],o=[],a=[];for(let s of n){let c=W(s);if(c){r.push(c);continue}if(this._eventDefinitions.has(s.event)||a.some(E=>E.name===s.event)){r.push({event:s.event,code:"DUPLICATE_EVENT",message:`event definition "${s.event}" is already registered`});continue}let l=["eventdef"];s.tags&&l.push(...s.tags),o.push({id:`eventdef:${s.event}`,directives:[],tags:l,declarations:s.declarations,tier:s.tier,metadata:{...s.schema!==void 0&&{schema:s.schema},...s.description!==void 0&&{description:s.description}}}),a.push({name:s.event,def:s});}let d=[];if(o.length>0){let s=this._actionEngine.register(o);for(let c of s.errors){let l=this._actionIdToEventName(c.actionId);r.push({event:l??c.actionId,code:c.code??"ACTION_ERROR",message:c.error});}d=s.warnings;}let f=[];for(let{name:s,def:c}of a)this._eventDefinitions.set(s,c),f.push(s);let g={defined:f,errors:r,warnings:d};return this._batch&&(this._batch.definedEvents.push(...f),this._batch.defineErrors.push(...r),this._batch.warnings.push(...d)),g}register(n){let r=[],o=[],a=[],d=[];for(let s of n){let c=G(s);if(c){r.push(c);continue}if(this._listenerRegistry.has(s.id)||d.some(R=>R.id===s.id)){r.push({listenerId:s.id,code:"DUPLICATE_ID",message:`listener "${s.id}" is already registered`});continue}let l=typeof s.on=="string"?[s.on]:s.on,E=false;for(let R of l){let I=this._eventDefinitions.get(R);if(!I){o.push({actionId:`event:${s.id}`,code:"NO_EVENT_DEFINITION",message:`listener "${s.id}" listens to "${R}" but no event definition is registered for it`});continue}I.tier!==void 0&&s.declarations?.tier!==void 0&&s.declarations.tier<I.tier&&(r.push({listenerId:s.id,code:"TIER_VIOLATION",message:`listener "${s.id}" declares tier ${s.declarations.tier} but event "${R}" requires tier >= ${I.tier}`}),E=true);}if(E)continue;let y=`event:${s.id}`,e={definition:s,actionId:y,priority:s.priority,isAsync:false,isInteractive:false},k=["event"];s.tags&&k.push(...s.tags),a.push({id:y,tags:k,directives:s.then,declarations:s.declarations}),d.push({id:s.id,stored:e,eventNames:l});}if(a.length>0){let s=this._actionEngine.register(a);for(let c of s.errors){let l=this._actionIdToListenerId(c.actionId);r.push({listenerId:l??c.actionId,code:c.code??"ACTION_ERROR",message:c.error});}o.push(...s.warnings);}let f=[];for(let{id:s,stored:c,eventNames:l}of d){this._listenerRegistry.set(s,c);for(let E of l){let y=this._listenerIndex.get(E);y||(y=[],this._listenerIndex.set(E,y)),q(y,c);}f.push(s);}let g={registered:f,errors:r,warnings:o};return this._batch?(this._batch.registered.push(...f),this._batch.errors.push(...r),this._batch.warnings.push(...o)):f.length>0&&this._refreshListenerFlags(),g}unregister(n){let r=this._listenerRegistry.get(n);if(!r)return false;this._listenerRegistry.delete(n);let o=typeof r.definition.on=="string"?[r.definition.on]:r.definition.on;for(let a of o){let d=this._listenerIndex.get(a);d&&(U(d,r),d.length===0&&this._listenerIndex.delete(a));}return this._actionEngine.unregister(r.actionId),this._refreshListenerFlags(),true}processEvents(n,r){if(this._hasAnyInteractiveListener)throw new Error("Cannot call processEvents() \u2014 at least one listener is interactive (transitively). Use processEventsInteractive() instead.");if(this._isAsync)throw new Error("Cannot call processEvents() with async hooks or async listeners. Use processEventsAsync() instead.");let o=this._dispatcher(this._listenerIndex,n,r,this._actionEngine,this._middleware,this._eventHooks);return this._maybeAutoPromote(),o}async processEventsAsync(n,r){if(this._hasAnyInteractiveListener)throw new Error("Cannot call processEventsAsync() \u2014 at least one listener is interactive (transitively). Use processEventsInteractive() instead.");let o=await this._dispatcher(this._listenerIndex,n,r,this._actionEngine,this._middleware,this._eventHooks);return this._maybeAutoPromote(),o}processEventsInteractive(n,r){if(!this._hasAnyInteractiveListener)throw new Error("Cannot call processEventsInteractive() \u2014 no registered listener is interactive (transitively). Use processEvents() or processEventsAsync() instead.");return (this._interactiveDispatcher===null||this._interactiveDispatcherIsAsync!==this._isAsync)&&(this._interactiveDispatcher=this._mode==="jit"?Q(this._hookAnalysis,this._middleware.length>0,this._isAsync):V(this._hookAnalysis,this._isAsync),this._interactiveDispatcherIsAsync=this._isAsync),this._interactiveDispatcher(this._listenerIndex,n,r,this._actionEngine,this._middleware,this._eventHooks)}beginBatch(){this._batch||(this._batch={depth:0,registered:[],errors:[],warnings:[],definedEvents:[],defineErrors:[]}),this._batch.depth++,this._actionEngine.beginBatch();}endBatch(){if(!this._batch||this._batch.depth<=0)throw new Error("endBatch() called without matching beginBatch()");this._batch.depth--;let n=this._actionEngine.endBatch();if(this._batch.depth>0)return {registered:[],errors:[],warnings:[]};let r=this._batch;for(let a of n.errors){let d=this._actionIdToListenerId(a.actionId);r.errors.push({listenerId:d??a.actionId,code:a.code??"ACTION_ERROR",message:a.error});}r.warnings.push(...n.warnings);let o={registered:r.registered,errors:r.errors,warnings:r.warnings};return this._batch=null,this._refreshListenerFlags(),o}compile(){this._requestedMode!=="interpret"&&this._mode!=="jit"&&this._promote();}_promote(){this._dispatcher=this._buildJit(),this._mode="jit",this._maybeAutoPromote=F,this._interactiveDispatcher=null;}_buildJit(){return H(this._hookAnalysis,this._middleware.length>0,this._isAsync)}_refreshListenerFlags(){let n=false,r=false;for(let a of this._listenerRegistry.values())a.isAsync=this._actionEngine.isActionAsync(a.actionId)??false,a.isInteractive=this._actionEngine.isActionInteractive?.(a.actionId)??false,a.isAsync&&(n=true),a.isInteractive&&(r=true);this._hasAnyInteractiveListener=r;let o=this._hookAnalysis.hasAnyAsync||n;o!==this._isAsync&&(this._isAsync=o,this._rebuildDispatcher());}_rebuildDispatcher(){this._dispatcher=this._mode==="jit"?this._buildJit():$(this._hookAnalysis,this._isAsync);}_actionIdToListenerId(n){return n.startsWith("event:")?n.slice(6):null}_actionIdToEventName(n){return n.startsWith("eventdef:")?n.slice(9):null}};function ee(t){return new B(t)}function he(t="event"){return n=>{let r=n[t],o=typeof r=="string"&&r?[`eventdef:${r}`]:[];return {capabilities:["emit"],dependencies:o}}}exports.createEmitAnalyzer=he;exports.createEventProcessor=ee;
|
package/dist/index.d.cts
CHANGED
|
@@ -92,6 +92,24 @@ interface EventProcessorConfig<TCtx = unknown> {
|
|
|
92
92
|
mode?: "interpret" | "jit" | "auto";
|
|
93
93
|
autoJitThreshold?: number;
|
|
94
94
|
}
|
|
95
|
+
/**
|
|
96
|
+
* Sessão de processamento de events em modo interactive — retornada por
|
|
97
|
+
* `processEventsInteractive(events, ctx)`. Drena via `next()`. O `done.value`
|
|
98
|
+
* final é `EventProcessingResult`. Halt scoping: pause em listener para os
|
|
99
|
+
* listeners daquele evento; próximos eventos na fila continuam normalmente.
|
|
100
|
+
*/
|
|
101
|
+
interface InteractiveEventSession extends Iterator<unknown, EventProcessingResult, unknown> {
|
|
102
|
+
next(value?: unknown): IteratorResult<unknown, EventProcessingResult>;
|
|
103
|
+
return(): IteratorResult<unknown, EventProcessingResult>;
|
|
104
|
+
throw(err?: unknown): IteratorResult<unknown, EventProcessingResult>;
|
|
105
|
+
[Symbol.iterator](): InteractiveEventSession;
|
|
106
|
+
}
|
|
107
|
+
interface AsyncInteractiveEventSession extends AsyncIterator<unknown, EventProcessingResult, unknown> {
|
|
108
|
+
next(value?: unknown): Promise<IteratorResult<unknown, EventProcessingResult>>;
|
|
109
|
+
return(): Promise<IteratorResult<unknown, EventProcessingResult>>;
|
|
110
|
+
throw(err?: unknown): Promise<IteratorResult<unknown, EventProcessingResult>>;
|
|
111
|
+
[Symbol.asyncIterator](): AsyncInteractiveEventSession;
|
|
112
|
+
}
|
|
95
113
|
interface IEventProcessor<TCtx = unknown> {
|
|
96
114
|
defineEvents(definitions: readonly EventDefinition[]): EventDefineResult;
|
|
97
115
|
getEventDefinition(event: string): EventDefinition | undefined;
|
|
@@ -100,11 +118,22 @@ interface IEventProcessor<TCtx = unknown> {
|
|
|
100
118
|
unregister(id: string): boolean;
|
|
101
119
|
processEvents(events: readonly QueuedEvent[], ctx: TCtx): EventProcessingResult;
|
|
102
120
|
processEventsAsync(events: readonly QueuedEvent[], ctx: TCtx): Promise<EventProcessingResult>;
|
|
121
|
+
/**
|
|
122
|
+
* Processa events em modo interactive — retorna iterator drenável.
|
|
123
|
+
* Lança se nenhum listener registrado é interactive transitivamente, ou se
|
|
124
|
+
* actionEngine não tem `interactive` configurado.
|
|
125
|
+
*
|
|
126
|
+
* Variante async (AsyncInteractiveEventSession) é retornada quando algum
|
|
127
|
+
* listener é async transitivamente OU algum hook é async.
|
|
128
|
+
*/
|
|
129
|
+
processEventsInteractive(events: readonly QueuedEvent[], ctx: TCtx): InteractiveEventSession | AsyncInteractiveEventSession;
|
|
103
130
|
beginBatch(): void;
|
|
104
131
|
endBatch(): EventRegisterResult;
|
|
105
132
|
compile(): void;
|
|
106
133
|
readonly actionEngine: IActionEngine<TCtx>;
|
|
107
134
|
readonly isAsync: boolean;
|
|
135
|
+
/** Algum listener registrado é interactive transitivamente? Cached. */
|
|
136
|
+
readonly isInteractive: boolean;
|
|
108
137
|
readonly compilationMode: "interpret" | "jit";
|
|
109
138
|
}
|
|
110
139
|
|
package/dist/index.d.ts
CHANGED
|
@@ -92,6 +92,24 @@ interface EventProcessorConfig<TCtx = unknown> {
|
|
|
92
92
|
mode?: "interpret" | "jit" | "auto";
|
|
93
93
|
autoJitThreshold?: number;
|
|
94
94
|
}
|
|
95
|
+
/**
|
|
96
|
+
* Sessão de processamento de events em modo interactive — retornada por
|
|
97
|
+
* `processEventsInteractive(events, ctx)`. Drena via `next()`. O `done.value`
|
|
98
|
+
* final é `EventProcessingResult`. Halt scoping: pause em listener para os
|
|
99
|
+
* listeners daquele evento; próximos eventos na fila continuam normalmente.
|
|
100
|
+
*/
|
|
101
|
+
interface InteractiveEventSession extends Iterator<unknown, EventProcessingResult, unknown> {
|
|
102
|
+
next(value?: unknown): IteratorResult<unknown, EventProcessingResult>;
|
|
103
|
+
return(): IteratorResult<unknown, EventProcessingResult>;
|
|
104
|
+
throw(err?: unknown): IteratorResult<unknown, EventProcessingResult>;
|
|
105
|
+
[Symbol.iterator](): InteractiveEventSession;
|
|
106
|
+
}
|
|
107
|
+
interface AsyncInteractiveEventSession extends AsyncIterator<unknown, EventProcessingResult, unknown> {
|
|
108
|
+
next(value?: unknown): Promise<IteratorResult<unknown, EventProcessingResult>>;
|
|
109
|
+
return(): Promise<IteratorResult<unknown, EventProcessingResult>>;
|
|
110
|
+
throw(err?: unknown): Promise<IteratorResult<unknown, EventProcessingResult>>;
|
|
111
|
+
[Symbol.asyncIterator](): AsyncInteractiveEventSession;
|
|
112
|
+
}
|
|
95
113
|
interface IEventProcessor<TCtx = unknown> {
|
|
96
114
|
defineEvents(definitions: readonly EventDefinition[]): EventDefineResult;
|
|
97
115
|
getEventDefinition(event: string): EventDefinition | undefined;
|
|
@@ -100,11 +118,22 @@ interface IEventProcessor<TCtx = unknown> {
|
|
|
100
118
|
unregister(id: string): boolean;
|
|
101
119
|
processEvents(events: readonly QueuedEvent[], ctx: TCtx): EventProcessingResult;
|
|
102
120
|
processEventsAsync(events: readonly QueuedEvent[], ctx: TCtx): Promise<EventProcessingResult>;
|
|
121
|
+
/**
|
|
122
|
+
* Processa events em modo interactive — retorna iterator drenável.
|
|
123
|
+
* Lança se nenhum listener registrado é interactive transitivamente, ou se
|
|
124
|
+
* actionEngine não tem `interactive` configurado.
|
|
125
|
+
*
|
|
126
|
+
* Variante async (AsyncInteractiveEventSession) é retornada quando algum
|
|
127
|
+
* listener é async transitivamente OU algum hook é async.
|
|
128
|
+
*/
|
|
129
|
+
processEventsInteractive(events: readonly QueuedEvent[], ctx: TCtx): InteractiveEventSession | AsyncInteractiveEventSession;
|
|
103
130
|
beginBatch(): void;
|
|
104
131
|
endBatch(): EventRegisterResult;
|
|
105
132
|
compile(): void;
|
|
106
133
|
readonly actionEngine: IActionEngine<TCtx>;
|
|
107
134
|
readonly isAsync: boolean;
|
|
135
|
+
/** Algum listener registrado é interactive transitivamente? Cached. */
|
|
136
|
+
readonly isInteractive: boolean;
|
|
108
137
|
readonly compilationMode: "interpret" | "jit";
|
|
109
138
|
}
|
|
110
139
|
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
import {analyzeSlots,EVENT_SLOT_NAMES}from'@statedelta-actions/core';function
|
|
2
|
-
`),p=r?"async ":"",
|
|
1
|
+
import {analyzeSlots,EVENT_SLOT_NAMES}from'@statedelta-actions/core';function N(){return {rulesEvaluated:0,rulesMatched:0,rulesSkipped:0,directivesApplied:0,directivesSkipped:0,subRunsCreated:0,errors:0}}function O(t,n){t.rulesEvaluated+=n.rulesEvaluated,t.rulesMatched+=n.rulesMatched,t.rulesSkipped+=n.rulesSkipped,t.directivesApplied+=n.directivesApplied,t.directivesSkipped+=n.directivesSkipped,t.subRunsCreated+=n.subRunsCreated,t.errors+=n.errors;}function M(t,n,r,o){let a=o?Object.assign({},o):{};for(let d of t)Object.assign(a,d(n,r,a));return a}function J(t){let n=t.filledNames.has("beforeEvent"),r=t.filledNames.has("afterEvent"),o=t.filledNames.has("onEventsComplete");return function(d,f,g,s,c,l){let E=[],y=[],e=[],k=N(),R=c.length>0;s.setContext(g);for(let p of f){let _=d.get(p.event);if(!_||_.length===0){y.push(p.event);continue}let b=[],A=[],S=[],C=[],i=N(),w=false,T,D={ctx:g,counters:i,event:p.event},L={$event:{type:p.event,data:p.data}};for(let h=0;h<_.length;h++){let m=_[h];if(i.rulesEvaluated++,n)try{let v=l.beforeEvent(m.definition,D);if(v==="skip"){A.push(h),i.rulesSkipped++;continue}if(v==="abort")break}catch(v){C.push({ruleIndex:h,error:`beforeEvent: ${v}`}),i.errors++;}b.push(h),i.rulesMatched++;let x;if(R)try{x=M(c,m.definition,g,L);}catch(v){C.push({ruleIndex:h,error:`Middleware: ${v}`}),i.errors++;continue}else x=L;let u=s.invoke(m.actionId,x);if(i.directivesApplied+=u.appliedCount,i.directivesSkipped+=u.skippedCount,i.errors+=u.errors.length,r)try{if(l.afterEvent(m.definition,u,D)==="abort")break}catch{}if(u.aborted){w=true,T=u.abortedBy;break}}e.push(...C),O(k,i),E.push({event:p.event,matched:b,skipped:A,notMatched:S,errors:C,halted:w,haltedBy:T,counters:i});}let I={eventResults:E,unprocessedEvents:y,errors:e,counters:k,totalEvents:f.length,processedEvents:E.length};if(o)try{l.onEventsComplete(I);}catch{}return I}}function z(t){let n=t.filledNames.has("beforeEvent"),r=t.filledNames.has("afterEvent"),o=t.filledNames.has("onEventsComplete");return async function(d,f,g,s,c,l){let E=[],y=[],e=[],k=N(),R=c.length>0;s.setContext(g);for(let p of f){let _=d.get(p.event);if(!_||_.length===0){y.push(p.event);continue}let b=[],A=[],S=[],C=[],i=N(),w=false,T,D={ctx:g,counters:i,event:p.event},L={$event:{type:p.event,data:p.data}};for(let h=0;h<_.length;h++){let m=_[h];if(i.rulesEvaluated++,n)try{let v=await l.beforeEvent(m.definition,D);if(v==="skip"){A.push(h),i.rulesSkipped++;continue}if(v==="abort")break}catch(v){C.push({ruleIndex:h,error:`beforeEvent: ${v}`}),i.errors++;}b.push(h),i.rulesMatched++;let x;if(R)try{x=M(c,m.definition,g,L);}catch(v){C.push({ruleIndex:h,error:`Middleware: ${v}`}),i.errors++;continue}else x=L;let u=await s.invokeAsync(m.actionId,x);if(i.directivesApplied+=u.appliedCount,i.directivesSkipped+=u.skippedCount,i.errors+=u.errors.length,r)try{if(await l.afterEvent(m.definition,u,D)==="abort")break}catch{}if(u.aborted){w=true,T=u.abortedBy;break}}e.push(...C),O(k,i),E.push({event:p.event,matched:b,skipped:A,notMatched:S,errors:C,halted:w,haltedBy:T,counters:i});}let I={eventResults:E,unprocessedEvents:y,errors:e,counters:k,totalEvents:f.length,processedEvents:E.length};if(o)try{await l.onEventsComplete(I);}catch{}return I}}function $(t,n){return n?z(t):J(t)}function P(){return {rulesEvaluated:0,rulesMatched:0,rulesSkipped:0,directivesApplied:0,directivesSkipped:0,subRunsCreated:0,errors:0}}function j(t,n){t.rulesEvaluated+=n.rulesEvaluated,t.rulesMatched+=n.rulesMatched,t.rulesSkipped+=n.rulesSkipped,t.directivesApplied+=n.directivesApplied,t.directivesSkipped+=n.directivesSkipped,t.subRunsCreated+=n.subRunsCreated,t.errors+=n.errors;}function K(t){let n=t.filledNames.has("beforeEvent"),r=t.filledNames.has("afterEvent"),o=t.filledNames.has("onEventsComplete");return function*(d,f,g,s,c,l){let E=[],y=[],e=[],k=P(),R=c.length>0;s.setContext(g);for(let p of f){let _=d.get(p.event);if(!_||_.length===0){y.push(p.event);continue}let b=[],A=[],S=[],C=[],i=P(),w=false,T,D={ctx:g,counters:i,event:p.event},L={$event:{type:p.event,data:p.data}};for(let h=0;h<_.length;h++){let m=_[h];if(i.rulesEvaluated++,n)try{let v=l.beforeEvent(m.definition,D);if(v==="skip"){A.push(h),i.rulesSkipped++;continue}if(v==="abort")break}catch(v){C.push({ruleIndex:h,error:`beforeEvent: ${v}`}),i.errors++;}b.push(h),i.rulesMatched++;let x;if(R)try{x=M(c,m.definition,g,L);}catch(v){C.push({ruleIndex:h,error:`Middleware: ${v}`}),i.errors++;continue}else x=L;let u;if(m.isInteractive?u=yield*s.invokeInteractive(m.actionId,x):u=s.invoke(m.actionId,x),i.directivesApplied+=u.appliedCount,i.directivesSkipped+=u.skippedCount,i.errors+=u.errors.length,r)try{if(l.afterEvent(m.definition,u,D)==="abort")break}catch{}if(u.aborted){w=true,T=u.abortedBy;break}}e.push(...C),j(k,i),E.push({event:p.event,matched:b,skipped:A,notMatched:S,errors:C,halted:w,haltedBy:T,counters:i});}let I={eventResults:E,unprocessedEvents:y,errors:e,counters:k,totalEvents:f.length,processedEvents:E.length};if(o)try{l.onEventsComplete(I);}catch{}return I}}function X(t){let n=t.filledNames.has("beforeEvent"),r=t.filledNames.has("afterEvent"),o=t.filledNames.has("onEventsComplete");return async function*(d,f,g,s,c,l){let E=[],y=[],e=[],k=P(),R=c.length>0;s.setContext(g);for(let p of f){let _=d.get(p.event);if(!_||_.length===0){y.push(p.event);continue}let b=[],A=[],S=[],C=[],i=P(),w=false,T,D={ctx:g,counters:i,event:p.event},L={$event:{type:p.event,data:p.data}};for(let h=0;h<_.length;h++){let m=_[h];if(i.rulesEvaluated++,n)try{let v=await l.beforeEvent(m.definition,D);if(v==="skip"){A.push(h),i.rulesSkipped++;continue}if(v==="abort")break}catch(v){C.push({ruleIndex:h,error:`beforeEvent: ${v}`}),i.errors++;}b.push(h),i.rulesMatched++;let x;if(R)try{x=M(c,m.definition,g,L);}catch(v){C.push({ruleIndex:h,error:`Middleware: ${v}`}),i.errors++;continue}else x=L;let u;if(m.isInteractive?u=yield*s.invokeInteractive(m.actionId,x):m.isAsync?u=await s.invokeAsync(m.actionId,x):u=s.invoke(m.actionId,x),i.directivesApplied+=u.appliedCount,i.directivesSkipped+=u.skippedCount,i.errors+=u.errors.length,r)try{if(await l.afterEvent(m.definition,u,D)==="abort")break}catch{}if(u.aborted){w=true,T=u.abortedBy;break}}e.push(...C),j(k,i),E.push({event:p.event,matched:b,skipped:A,notMatched:S,errors:C,halted:w,haltedBy:T,counters:i});}let I={eventResults:E,unprocessedEvents:y,errors:e,counters:k,totalEvents:f.length,processedEvents:E.length};if(o)try{await l.onEventsComplete(I);}catch{}return I}}function V(t,n){return n?X(t):K(t)}function H(t,n,r){let{filledNames:o,asyncNames:a}=t,d=A=>o.has(A),f=A=>a.has(A)?"await ":"",g=d("beforeEvent"),s=d("afterEvent"),c=d("onEventsComplete"),l=f("beforeEvent"),E=f("afterEvent"),y=f("onEventsComplete"),e=[];e.push("const eventResults=[];"),e.push("const unprocessedEvents=[];"),e.push("const aggErrors=[];"),e.push("const aggCounters={rulesEvaluated:0,rulesMatched:0,rulesSkipped:0,directivesApplied:0,directivesSkipped:0,subRunsCreated:0,errors:0};"),e.push("ae.setContext(ctx);"),c&&e.push("const _hookOnComplete=hooks.onEventsComplete;"),e.push("for(let _ei=0;_ei<events.length;_ei++){"),e.push("const ev=events[_ei];"),e.push("const _evListeners=listenerIndex.get(ev.event);"),e.push("if(!_evListeners||_evListeners.length===0){unprocessedEvents.push(ev.event);continue;}"),e.push("const matched=[];const skipped=[];const notMatched=[];"),e.push("const errors=[];"),e.push("const counters={rulesEvaluated:0,rulesMatched:0,rulesSkipped:0,directivesApplied:0,directivesSkipped:0,subRunsCreated:0,errors:0};"),e.push("let halted=false;let haltedBy;"),(g||s)&&e.push("const evalCtx={ctx,counters,event:ev.event};"),g&&e.push("const _hookBefore=hooks.beforeEvent;"),s&&e.push("const _hookAfter=hooks.afterEvent;"),e.push("const _ep={$event:{type:ev.event,data:ev.data}};"),e.push("for(let _ri=0;_ri<_evListeners.length;_ri++){"),e.push("const stored=_evListeners[_ri];"),e.push("counters.rulesEvaluated++;"),g&&(e.push("try{"),e.push(`const _bd=${l}_hookBefore(stored.definition,evalCtx);`),e.push('if(_bd==="skip"){skipped.push(_ri);counters.rulesSkipped++;continue;}'),e.push('if(_bd==="abort"){break;}'),e.push('}catch(_e){errors.push({ruleIndex:_ri,error:"beforeEvent: "+_e});counters.errors++;}')),e.push("matched.push(_ri);counters.rulesMatched++;"),n&&(e.push("let params;"),e.push('try{params=$.runMw(mw,stored.definition,ctx,_ep);}catch(_e){errors.push({ruleIndex:_ri,error:"Middleware: "+_e});counters.errors++;continue;}'));let k=n?"params":"_ep",R=r?`await ae.invokeAsync(stored.actionId,${k})`:`ae.invoke(stored.actionId,${k})`;e.push(`const ir=${R};`),e.push("counters.directivesApplied+=ir.appliedCount;counters.directivesSkipped+=ir.skippedCount;counters.errors+=ir.errors.length;"),s&&(e.push("try{"),e.push(`const _ad=${E}_hookAfter(stored.definition,ir,evalCtx);`),e.push('if(_ad==="abort"){break;}'),e.push("}catch(_e){}")),e.push("if(ir.aborted){halted=true;haltedBy=ir.abortedBy;break;}"),e.push("}"),e.push("aggCounters.rulesEvaluated+=counters.rulesEvaluated;"),e.push("aggCounters.rulesMatched+=counters.rulesMatched;"),e.push("aggCounters.rulesSkipped+=counters.rulesSkipped;"),e.push("aggCounters.directivesApplied+=counters.directivesApplied;"),e.push("aggCounters.directivesSkipped+=counters.directivesSkipped;"),e.push("aggCounters.subRunsCreated+=counters.subRunsCreated;"),e.push("aggCounters.errors+=counters.errors;"),e.push("for(let _k=0;_k<errors.length;_k++)aggErrors.push(errors[_k]);"),e.push("eventResults.push({event:ev.event,matched,skipped,notMatched,errors,halted,haltedBy,counters});"),e.push("}"),e.push("const _r={eventResults,unprocessedEvents,errors:aggErrors,counters:aggCounters,totalEvents:events.length,processedEvents:eventResults.length};"),c&&e.push(`try{${y}_hookOnComplete(_r);}catch(_e){}`),e.push("return _r;");let I=e.join(`
|
|
2
|
+
`),p=r?"async ":"",_=new Function("listenerIndex","events","ctx","ae","mw","hooks","$",`"use strict";
|
|
3
3
|
return(${p}()=>{
|
|
4
|
-
${
|
|
5
|
-
})();`),
|
|
4
|
+
${I}
|
|
5
|
+
})();`),b={};return n&&(b.runMw=M),function(S,C,i,w,T,D){return _(S,C,i,w,T,D,b)}}function Q(t,n,r){let{filledNames:o,asyncNames:a}=t,d=b=>o.has(b),f=b=>a.has(b)?"await ":"",g=d("beforeEvent"),s=d("afterEvent"),c=d("onEventsComplete"),l=f("beforeEvent"),E=f("afterEvent"),y=f("onEventsComplete"),e=[];e.push("const eventResults=[];"),e.push("const unprocessedEvents=[];"),e.push("const aggErrors=[];"),e.push("const aggCounters={rulesEvaluated:0,rulesMatched:0,rulesSkipped:0,directivesApplied:0,directivesSkipped:0,subRunsCreated:0,errors:0};"),e.push("ae.setContext(ctx);"),c&&e.push("const _hookOnComplete=hooks.onEventsComplete;"),e.push("for(let _ei=0;_ei<events.length;_ei++){"),e.push("const ev=events[_ei];"),e.push("const _evListeners=listenerIndex.get(ev.event);"),e.push("if(!_evListeners||_evListeners.length===0){unprocessedEvents.push(ev.event);continue;}"),e.push("const matched=[];const skipped=[];const notMatched=[];"),e.push("const errors=[];"),e.push("const counters={rulesEvaluated:0,rulesMatched:0,rulesSkipped:0,directivesApplied:0,directivesSkipped:0,subRunsCreated:0,errors:0};"),e.push("let halted=false;let haltedBy;"),(g||s)&&e.push("const evalCtx={ctx,counters,event:ev.event};"),g&&e.push("const _hookBefore=hooks.beforeEvent;"),s&&e.push("const _hookAfter=hooks.afterEvent;"),e.push("const _ep={$event:{type:ev.event,data:ev.data}};"),e.push("for(let _ri=0;_ri<_evListeners.length;_ri++){"),e.push("const stored=_evListeners[_ri];"),e.push("counters.rulesEvaluated++;"),g&&(e.push("try{"),e.push(`const _bd=${l}_hookBefore(stored.definition,evalCtx);`),e.push('if(_bd==="skip"){skipped.push(_ri);counters.rulesSkipped++;continue;}'),e.push('if(_bd==="abort"){break;}'),e.push('}catch(_e){errors.push({ruleIndex:_ri,error:"beforeEvent: "+_e});counters.errors++;}')),e.push("matched.push(_ri);counters.rulesMatched++;"),n&&(e.push("let params;"),e.push('try{params=$.runMw(mw,stored.definition,ctx,_ep);}catch(_e){errors.push({ruleIndex:_ri,error:"Middleware: "+_e});counters.errors++;continue;}'));let k=n?"params":"_ep";e.push("let ir;"),e.push("if(stored.isInteractive){"),e.push(`ir=yield* ae.invokeInteractive(stored.actionId,${k});`),r&&(e.push("}else if(stored.isAsync){"),e.push(`ir=await ae.invokeAsync(stored.actionId,${k});`)),e.push("}else{"),e.push(`ir=ae.invoke(stored.actionId,${k});`),e.push("}"),e.push("counters.directivesApplied+=ir.appliedCount;counters.directivesSkipped+=ir.skippedCount;counters.errors+=ir.errors.length;"),s&&(e.push("try{"),e.push(`const _ad=${E}_hookAfter(stored.definition,ir,evalCtx);`),e.push('if(_ad==="abort"){break;}'),e.push("}catch(_e){}")),e.push("if(ir.aborted){halted=true;haltedBy=ir.abortedBy;break;}"),e.push("}"),e.push("aggCounters.rulesEvaluated+=counters.rulesEvaluated;"),e.push("aggCounters.rulesMatched+=counters.rulesMatched;"),e.push("aggCounters.rulesSkipped+=counters.rulesSkipped;"),e.push("aggCounters.directivesApplied+=counters.directivesApplied;"),e.push("aggCounters.directivesSkipped+=counters.directivesSkipped;"),e.push("aggCounters.subRunsCreated+=counters.subRunsCreated;"),e.push("aggCounters.errors+=counters.errors;"),e.push("for(let _k=0;_k<errors.length;_k++)aggErrors.push(errors[_k]);"),e.push("eventResults.push({event:ev.event,matched,skipped,notMatched,errors,halted,haltedBy,counters});"),e.push("}"),e.push("const _r={eventResults,unprocessedEvents,errors:aggErrors,counters:aggCounters,totalEvents:events.length,processedEvents:eventResults.length};"),c&&e.push(`try{${y}_hookOnComplete(_r);}catch(_e){}`),e.push("return _r;");let R=e.join(`
|
|
6
|
+
`),I=r?"async function* ":"function* ",p=new Function("listenerIndex","events","ctx","ae","mw","hooks","$",`"use strict";
|
|
7
|
+
return(${I}(){
|
|
8
|
+
${R}
|
|
9
|
+
})();`),_={};return n&&(_.runMw=M),function(A,S,C,i,w,T){return p(A,S,C,i,w,T,_)}}function W(t){return !t.event||typeof t.event!="string"?{event:t.event??"(missing)",code:"INVALID_DEFINITION",message:"event definition must have a non-empty string event name"}:t.tags!==void 0&&!Array.isArray(t.tags)?{event:t.event,code:"INVALID_DEFINITION",message:"event definition tags must be an array of strings"}:t.tier!==void 0&&typeof t.tier!="number"?{event:t.event,code:"INVALID_DEFINITION",message:"event definition tier must be a number"}:null}function G(t){if(!t.id||typeof t.id!="string")return {listenerId:t.id??"(missing)",code:"INVALID_LISTENER",message:"listener must have a string id"};if(typeof t.priority!="number")return {listenerId:t.id,code:"INVALID_LISTENER",message:"listener must have a numeric priority"};if(typeof t.on=="string"){if(!t.on)return {listenerId:t.id,code:"INVALID_LISTENER",message:"listener.on must be a non-empty string or string[]"}}else if(Array.isArray(t.on)){if(t.on.length===0||t.on.some(n=>typeof n!="string"||!n))return {listenerId:t.id,code:"INVALID_LISTENER",message:"listener.on must be a non-empty string or string[] of non-empty strings"}}else return {listenerId:t.id,code:"INVALID_LISTENER",message:"listener.on must be a string or string[]"};return !Array.isArray(t.then)||t.then.length===0?{listenerId:t.id,code:"INVALID_LISTENER",message:"listener must have a non-empty then array"}:null}function q(t,n){let r=0,o=t.length;for(;r<o;){let a=r+o>>>1;t[a].priority>=n.priority?r=a+1:o=a;}t.splice(r,0,n);}function U(t,n){let r=t.indexOf(n);return r===-1?false:(t.splice(r,1),true)}var F=()=>{},B=class{_actionEngine;_middleware;_eventHooks;_requestedMode;_hookAnalysis;_isAsync;_hasAnyInteractiveListener=false;_dispatcher;_mode;_maybeAutoPromote;_interactiveDispatcher=null;_interactiveDispatcherIsAsync=false;_eventDefinitions=new Map;_listenerRegistry=new Map;_listenerIndex=new Map;_batch=null;constructor(n){if(this._actionEngine=n.actionEngine,this._middleware=n.middleware??[],this._eventHooks=n.eventHooks??{},this._requestedMode=n.mode??"auto",this._hookAnalysis=analyzeSlots(this._eventHooks,EVENT_SLOT_NAMES),this._isAsync=this._hookAnalysis.hasAnyAsync,this._requestedMode==="jit")this._dispatcher=this._buildJit(),this._mode="jit",this._maybeAutoPromote=F;else if(this._dispatcher=$(this._hookAnalysis,this._isAsync),this._mode="interpret",this._requestedMode==="auto"){let r=0,o=n.autoJitThreshold??8;this._maybeAutoPromote=()=>{++r>=o&&this._promote();};}else this._maybeAutoPromote=F;}get actionEngine(){return this._actionEngine}get isAsync(){return this._isAsync}get isInteractive(){return this._hasAnyInteractiveListener}get compilationMode(){return this._mode}get eventDefinitions(){return this._eventDefinitions}getEventDefinition(n){return this._eventDefinitions.get(n)}defineEvents(n){let r=[],o=[],a=[];for(let s of n){let c=W(s);if(c){r.push(c);continue}if(this._eventDefinitions.has(s.event)||a.some(E=>E.name===s.event)){r.push({event:s.event,code:"DUPLICATE_EVENT",message:`event definition "${s.event}" is already registered`});continue}let l=["eventdef"];s.tags&&l.push(...s.tags),o.push({id:`eventdef:${s.event}`,directives:[],tags:l,declarations:s.declarations,tier:s.tier,metadata:{...s.schema!==void 0&&{schema:s.schema},...s.description!==void 0&&{description:s.description}}}),a.push({name:s.event,def:s});}let d=[];if(o.length>0){let s=this._actionEngine.register(o);for(let c of s.errors){let l=this._actionIdToEventName(c.actionId);r.push({event:l??c.actionId,code:c.code??"ACTION_ERROR",message:c.error});}d=s.warnings;}let f=[];for(let{name:s,def:c}of a)this._eventDefinitions.set(s,c),f.push(s);let g={defined:f,errors:r,warnings:d};return this._batch&&(this._batch.definedEvents.push(...f),this._batch.defineErrors.push(...r),this._batch.warnings.push(...d)),g}register(n){let r=[],o=[],a=[],d=[];for(let s of n){let c=G(s);if(c){r.push(c);continue}if(this._listenerRegistry.has(s.id)||d.some(R=>R.id===s.id)){r.push({listenerId:s.id,code:"DUPLICATE_ID",message:`listener "${s.id}" is already registered`});continue}let l=typeof s.on=="string"?[s.on]:s.on,E=false;for(let R of l){let I=this._eventDefinitions.get(R);if(!I){o.push({actionId:`event:${s.id}`,code:"NO_EVENT_DEFINITION",message:`listener "${s.id}" listens to "${R}" but no event definition is registered for it`});continue}I.tier!==void 0&&s.declarations?.tier!==void 0&&s.declarations.tier<I.tier&&(r.push({listenerId:s.id,code:"TIER_VIOLATION",message:`listener "${s.id}" declares tier ${s.declarations.tier} but event "${R}" requires tier >= ${I.tier}`}),E=true);}if(E)continue;let y=`event:${s.id}`,e={definition:s,actionId:y,priority:s.priority,isAsync:false,isInteractive:false},k=["event"];s.tags&&k.push(...s.tags),a.push({id:y,tags:k,directives:s.then,declarations:s.declarations}),d.push({id:s.id,stored:e,eventNames:l});}if(a.length>0){let s=this._actionEngine.register(a);for(let c of s.errors){let l=this._actionIdToListenerId(c.actionId);r.push({listenerId:l??c.actionId,code:c.code??"ACTION_ERROR",message:c.error});}o.push(...s.warnings);}let f=[];for(let{id:s,stored:c,eventNames:l}of d){this._listenerRegistry.set(s,c);for(let E of l){let y=this._listenerIndex.get(E);y||(y=[],this._listenerIndex.set(E,y)),q(y,c);}f.push(s);}let g={registered:f,errors:r,warnings:o};return this._batch?(this._batch.registered.push(...f),this._batch.errors.push(...r),this._batch.warnings.push(...o)):f.length>0&&this._refreshListenerFlags(),g}unregister(n){let r=this._listenerRegistry.get(n);if(!r)return false;this._listenerRegistry.delete(n);let o=typeof r.definition.on=="string"?[r.definition.on]:r.definition.on;for(let a of o){let d=this._listenerIndex.get(a);d&&(U(d,r),d.length===0&&this._listenerIndex.delete(a));}return this._actionEngine.unregister(r.actionId),this._refreshListenerFlags(),true}processEvents(n,r){if(this._hasAnyInteractiveListener)throw new Error("Cannot call processEvents() \u2014 at least one listener is interactive (transitively). Use processEventsInteractive() instead.");if(this._isAsync)throw new Error("Cannot call processEvents() with async hooks or async listeners. Use processEventsAsync() instead.");let o=this._dispatcher(this._listenerIndex,n,r,this._actionEngine,this._middleware,this._eventHooks);return this._maybeAutoPromote(),o}async processEventsAsync(n,r){if(this._hasAnyInteractiveListener)throw new Error("Cannot call processEventsAsync() \u2014 at least one listener is interactive (transitively). Use processEventsInteractive() instead.");let o=await this._dispatcher(this._listenerIndex,n,r,this._actionEngine,this._middleware,this._eventHooks);return this._maybeAutoPromote(),o}processEventsInteractive(n,r){if(!this._hasAnyInteractiveListener)throw new Error("Cannot call processEventsInteractive() \u2014 no registered listener is interactive (transitively). Use processEvents() or processEventsAsync() instead.");return (this._interactiveDispatcher===null||this._interactiveDispatcherIsAsync!==this._isAsync)&&(this._interactiveDispatcher=this._mode==="jit"?Q(this._hookAnalysis,this._middleware.length>0,this._isAsync):V(this._hookAnalysis,this._isAsync),this._interactiveDispatcherIsAsync=this._isAsync),this._interactiveDispatcher(this._listenerIndex,n,r,this._actionEngine,this._middleware,this._eventHooks)}beginBatch(){this._batch||(this._batch={depth:0,registered:[],errors:[],warnings:[],definedEvents:[],defineErrors:[]}),this._batch.depth++,this._actionEngine.beginBatch();}endBatch(){if(!this._batch||this._batch.depth<=0)throw new Error("endBatch() called without matching beginBatch()");this._batch.depth--;let n=this._actionEngine.endBatch();if(this._batch.depth>0)return {registered:[],errors:[],warnings:[]};let r=this._batch;for(let a of n.errors){let d=this._actionIdToListenerId(a.actionId);r.errors.push({listenerId:d??a.actionId,code:a.code??"ACTION_ERROR",message:a.error});}r.warnings.push(...n.warnings);let o={registered:r.registered,errors:r.errors,warnings:r.warnings};return this._batch=null,this._refreshListenerFlags(),o}compile(){this._requestedMode!=="interpret"&&this._mode!=="jit"&&this._promote();}_promote(){this._dispatcher=this._buildJit(),this._mode="jit",this._maybeAutoPromote=F,this._interactiveDispatcher=null;}_buildJit(){return H(this._hookAnalysis,this._middleware.length>0,this._isAsync)}_refreshListenerFlags(){let n=false,r=false;for(let a of this._listenerRegistry.values())a.isAsync=this._actionEngine.isActionAsync(a.actionId)??false,a.isInteractive=this._actionEngine.isActionInteractive?.(a.actionId)??false,a.isAsync&&(n=true),a.isInteractive&&(r=true);this._hasAnyInteractiveListener=r;let o=this._hookAnalysis.hasAnyAsync||n;o!==this._isAsync&&(this._isAsync=o,this._rebuildDispatcher());}_rebuildDispatcher(){this._dispatcher=this._mode==="jit"?this._buildJit():$(this._hookAnalysis,this._isAsync);}_actionIdToListenerId(n){return n.startsWith("event:")?n.slice(6):null}_actionIdToEventName(n){return n.startsWith("eventdef:")?n.slice(9):null}};function ee(t){return new B(t)}function he(t="event"){return n=>{let r=n[t],o=typeof r=="string"&&r?[`eventdef:${r}`]:[];return {capabilities:["emit"],dependencies:o}}}export{he as createEmitAnalyzer,ee as createEventProcessor};
|
package/package.json
CHANGED
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@statedelta-actions/events",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"description": "Event processing engine with listener dispatch and JIT optimization",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"statedelta",
|
|
7
|
+
"event-processing",
|
|
8
|
+
"listeners",
|
|
9
|
+
"jit",
|
|
10
|
+
"event-driven"
|
|
11
|
+
],
|
|
5
12
|
"type": "module",
|
|
6
13
|
"main": "./dist/index.cjs",
|
|
7
14
|
"module": "./dist/index.js",
|
|
@@ -15,15 +22,16 @@
|
|
|
15
22
|
},
|
|
16
23
|
"files": [
|
|
17
24
|
"dist",
|
|
18
|
-
"README.md"
|
|
25
|
+
"README.md",
|
|
26
|
+
"CHANGELOG.md"
|
|
19
27
|
],
|
|
20
28
|
"dependencies": {
|
|
21
|
-
"@statedelta-actions/
|
|
22
|
-
"@statedelta-actions/
|
|
29
|
+
"@statedelta-actions/actions": "0.6.0",
|
|
30
|
+
"@statedelta-actions/core": "0.5.1"
|
|
23
31
|
},
|
|
24
32
|
"devDependencies": {
|
|
25
|
-
"@statedelta-actions/
|
|
26
|
-
"@statedelta-actions/
|
|
33
|
+
"@statedelta-actions/graph": "0.4.2",
|
|
34
|
+
"@statedelta-actions/analyzer": "0.4.2"
|
|
27
35
|
},
|
|
28
36
|
"author": "Anderson D. Rosa <andersondrosa@outlook.com>",
|
|
29
37
|
"license": "MIT",
|
|
@@ -32,6 +40,10 @@
|
|
|
32
40
|
"url": "https://github.com/andersondrosa/statedelta-actions.git",
|
|
33
41
|
"directory": "packages/events"
|
|
34
42
|
},
|
|
43
|
+
"homepage": "https://github.com/andersondrosa/statedelta-actions/tree/main/packages/events#readme",
|
|
44
|
+
"bugs": {
|
|
45
|
+
"url": "https://github.com/andersondrosa/statedelta-actions/issues"
|
|
46
|
+
},
|
|
35
47
|
"sideEffects": false,
|
|
36
48
|
"engines": {
|
|
37
49
|
"node": ">=18"
|