@statedelta-actions/actions 0.2.0 → 0.5.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 +260 -5
- package/dist/index.cjs +9 -9
- package/dist/index.d.cts +283 -26
- package/dist/index.d.ts +283 -26
- package/dist/index.js +9 -9
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -1,21 +1,8 @@
|
|
|
1
|
-
import { Directive, ExecutionFrame,
|
|
1
|
+
import { Directive, ExecutionFrame, RuleEngineRef, ApplyResult, RegisterWarning, ActionEngineRef, DirectiveResult, HookFn, InterceptResult, AbortDecision, FrameLimits, SlotAnalysis } from '@statedelta-actions/core';
|
|
2
|
+
export { RegisterWarning } from '@statedelta-actions/core';
|
|
2
3
|
|
|
3
|
-
type DirectiveHandler<TCtx> = (directive: Directive, frame: ExecutionFrame<TCtx>, engine: RuleEngineRef<TCtx>) => ApplyResult
|
|
4
|
+
type DirectiveHandler<TCtx> = (directive: Directive, frame: ExecutionFrame<TCtx>, engine: RuleEngineRef<TCtx>) => ApplyResult | Promise<ApplyResult>;
|
|
4
5
|
type DirectiveHandlerMap<TCtx> = Record<string, DirectiveHandler<TCtx>>;
|
|
5
|
-
interface DirectiveHooks<TCtx> {
|
|
6
|
-
beforeDirective?: HookFn<[
|
|
7
|
-
directive: Directive,
|
|
8
|
-
frame: ExecutionFrame<TCtx>
|
|
9
|
-
], InterceptResult<TCtx>>;
|
|
10
|
-
afterDirective?: HookFn<[
|
|
11
|
-
directive: Directive,
|
|
12
|
-
result: ApplyResult,
|
|
13
|
-
frame: ExecutionFrame<TCtx>
|
|
14
|
-
], AbortDecision>;
|
|
15
|
-
onDirectivesComplete?: HookFn<[result: DirectiveResult], void>;
|
|
16
|
-
}
|
|
17
|
-
type DirectiveExecutorFn<TCtx> = (directives: readonly Directive[], frame: ExecutionFrame<TCtx>, handlers: DirectiveHandlerMap<TCtx>, directiveHooks: DirectiveHooks<TCtx>, typeField: string, engine: RuleEngineRef<TCtx>, maxDirectives: number) => DirectiveResult | Promise<DirectiveResult>;
|
|
18
|
-
type DirectiveRunnerFn<TCtx> = (directives: readonly Directive[], frame: ExecutionFrame<TCtx>) => DirectiveResult | Promise<DirectiveResult>;
|
|
19
6
|
interface HandlerAnalysis {
|
|
20
7
|
capabilities: string[];
|
|
21
8
|
dependencies: string[];
|
|
@@ -32,8 +19,44 @@ interface HandlerDefinition<TCtx> {
|
|
|
32
19
|
validate?: (directive: Directive) => ValidationResult | void;
|
|
33
20
|
/** JIT-time: contribui código inline per-action (Fase 2c). */
|
|
34
21
|
compile?: (directive: Directive, compiler: unknown) => string | void;
|
|
22
|
+
/**
|
|
23
|
+
* Marca o handler como assíncrono (opt-in explícito).
|
|
24
|
+
*
|
|
25
|
+
* Quando true (ou quando `execute` é uma `async function`), o engine:
|
|
26
|
+
* - inclui este handler no async handler set;
|
|
27
|
+
* - força `isAsync = true` no engine inteiro;
|
|
28
|
+
* - emite `await` ao invocar este handler no interpreter async e nos JITs.
|
|
29
|
+
*
|
|
30
|
+
* Auto-detecção via `isAsyncFunction(execute)` cobre `async function`.
|
|
31
|
+
* Use a flag para wrappers que retornam `Promise<ApplyResult>` sem
|
|
32
|
+
* serem `async function` (ex: factory que retorna função normal que
|
|
33
|
+
* delega pra um await internamente via `.then`).
|
|
34
|
+
*
|
|
35
|
+
* Sem flag e sem `async function`: handler é tratado como sync.
|
|
36
|
+
*/
|
|
37
|
+
async?: boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Marca o handler como interativo (opt-in explícito).
|
|
40
|
+
*
|
|
41
|
+
* Quando true (ou quando `execute` é uma `function*` / `async function*`),
|
|
42
|
+
* o engine:
|
|
43
|
+
* - inclui este handler no interactive handler set;
|
|
44
|
+
* - propaga transitividade `_interactiveActions` no mini-graph;
|
|
45
|
+
* - emite `yield* handler(...)` ao invocar nas actions interactive;
|
|
46
|
+
* - exige `engine.invokeInteractive()` em actions cuja sub-árvore use o handler.
|
|
47
|
+
*
|
|
48
|
+
* Auto-detecção via `isGeneratorFunction(execute)` cobre `function*` e
|
|
49
|
+
* `async function*`. Use a flag para wrappers que retornam iterator sem
|
|
50
|
+
* serem generator function.
|
|
51
|
+
*
|
|
52
|
+
* Handler com `interactive: true` em engine sem `interactive` config →
|
|
53
|
+
* erro no constructor (fail-fast).
|
|
54
|
+
*
|
|
55
|
+
* Sem flag e sem generator function: handler é tratado como regular.
|
|
56
|
+
*/
|
|
57
|
+
interactive?: boolean;
|
|
35
58
|
/** Runtime: executa a directive (obrigatório). */
|
|
36
|
-
execute: (directive: Directive, frame: ExecutionFrame<TCtx>, engine: ActionEngineRef<TCtx>) => ApplyResult
|
|
59
|
+
execute: (directive: Directive, frame: ExecutionFrame<TCtx>, engine: ActionEngineRef<TCtx>) => ApplyResult | Promise<ApplyResult>;
|
|
37
60
|
}
|
|
38
61
|
/**
|
|
39
62
|
* Aceita handler V1 (função) ou V2 (objeto com fases).
|
|
@@ -67,6 +90,20 @@ interface ActionDefinition<TCtx = unknown> {
|
|
|
67
90
|
* Requer tierPropagator habilitado no grafo.
|
|
68
91
|
*/
|
|
69
92
|
tier?: number;
|
|
93
|
+
/**
|
|
94
|
+
* Interactive — declaração explícita de que a action é interativa.
|
|
95
|
+
*
|
|
96
|
+
* Quando true, força `actionIsInteractive(id) === true` no mini-graph
|
|
97
|
+
* mesmo que a inferência local não detecte (ex: handler `action`
|
|
98
|
+
* dinâmico que pode invocar interactive em runtime).
|
|
99
|
+
*
|
|
100
|
+
* Pode ser inferida (sub-árvore usa handler interactive ou type:"pause").
|
|
101
|
+
* Quando declarada, o analyzer (opt-in) valida contra a inferência:
|
|
102
|
+
* declared !== inferred → DECLARATION_CONFLICT.
|
|
103
|
+
*
|
|
104
|
+
* Engine respeita declaração na propagação any_true.
|
|
105
|
+
*/
|
|
106
|
+
interactive?: boolean;
|
|
70
107
|
/**
|
|
71
108
|
* Declarações — contratos públicos (trust boundaries).
|
|
72
109
|
* Cada key = nome de um propagator registrado no grafo.
|
|
@@ -103,11 +140,7 @@ interface RegisterError {
|
|
|
103
140
|
error: string;
|
|
104
141
|
code?: string;
|
|
105
142
|
}
|
|
106
|
-
|
|
107
|
-
actionId: string;
|
|
108
|
-
code: string;
|
|
109
|
-
message: string;
|
|
110
|
-
}
|
|
143
|
+
|
|
111
144
|
interface RegisterResult {
|
|
112
145
|
registered: readonly string[];
|
|
113
146
|
errors: readonly RegisterError[];
|
|
@@ -138,6 +171,90 @@ interface DirectivePermissionConfig {
|
|
|
138
171
|
* String pura é equivalente a `{ pattern: string }`.
|
|
139
172
|
*/
|
|
140
173
|
type DirectivePermissionEntry = string | DirectivePermissionConfig;
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Configuração do modo interactive.
|
|
177
|
+
*
|
|
178
|
+
* v0: estrutura mínima — habilita o modo. Controller dinâmico
|
|
179
|
+
* (`shouldPause`) pra debug arbitrário fica reservado pra evolução
|
|
180
|
+
* futura.
|
|
181
|
+
*
|
|
182
|
+
* Habilitar `interactive: {}` ativa:
|
|
183
|
+
* - mini-graph propaga `_interactiveActions` transitivo
|
|
184
|
+
* - actions cuja sub-árvore tem handler interactive ou `type:"pause"`
|
|
185
|
+
* compilam como generator (na fase JIT correspondente)
|
|
186
|
+
* - `engine.invoke()` lança per-action transitivamente
|
|
187
|
+
* - `engine.invokeInteractive()` retorna iterator
|
|
188
|
+
*
|
|
189
|
+
* Sem `interactive` configurado:
|
|
190
|
+
* - handler com `interactive: true` → erro no constructor
|
|
191
|
+
* - diretiva `type: "pause"` → erro no register
|
|
192
|
+
*/
|
|
193
|
+
interface InteractiveConfig {
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Evento yieldado durante execução de uma action interactive.
|
|
197
|
+
*
|
|
198
|
+
* - `source: "handler"` — handler interactive yieldou. `payload` é
|
|
199
|
+
* opaco (handler controla o protocol).
|
|
200
|
+
* - `source: "pause"` — diretiva `type:"pause"` engine-level. `payload`
|
|
201
|
+
* contém `{ message?: unknown }` extraído da diretiva.
|
|
202
|
+
*/
|
|
203
|
+
interface PauseEvent {
|
|
204
|
+
readonly source: "handler" | "pause";
|
|
205
|
+
readonly directive: Directive;
|
|
206
|
+
readonly frame: ExecutionFrame<unknown>;
|
|
207
|
+
readonly index: number;
|
|
208
|
+
readonly payload?: unknown;
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Sessão interativa retornada por `engine.invokeInteractive()` em
|
|
212
|
+
* actions sync (sem handler async na sub-árvore).
|
|
213
|
+
*
|
|
214
|
+
* Drena via `next()`/`return()`/`throw()` ou `for...of`.
|
|
215
|
+
*/
|
|
216
|
+
interface InteractiveSession extends Iterator<PauseEvent, DirectiveResult, unknown> {
|
|
217
|
+
next(value?: unknown): IteratorResult<PauseEvent, DirectiveResult>;
|
|
218
|
+
return(): IteratorResult<PauseEvent, DirectiveResult>;
|
|
219
|
+
throw(err?: unknown): IteratorResult<PauseEvent, DirectiveResult>;
|
|
220
|
+
[Symbol.iterator](): InteractiveSession;
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Sessão interativa async — engine async (handler async transitivo)
|
|
224
|
+
* combinado com interactive.
|
|
225
|
+
*
|
|
226
|
+
* Drena via `await session.next()` / `for await...of`.
|
|
227
|
+
*/
|
|
228
|
+
interface AsyncInteractiveSession extends AsyncIterator<PauseEvent, DirectiveResult, unknown> {
|
|
229
|
+
next(value?: unknown): Promise<IteratorResult<PauseEvent, DirectiveResult>>;
|
|
230
|
+
return(): Promise<IteratorResult<PauseEvent, DirectiveResult>>;
|
|
231
|
+
throw(err?: unknown): Promise<IteratorResult<PauseEvent, DirectiveResult>>;
|
|
232
|
+
[Symbol.asyncIterator](): AsyncInteractiveSession;
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Forma alternativa de `ApplyResult` que um handler `action` pode
|
|
236
|
+
* retornar quando o target é interactive — engine detecta `iterator`
|
|
237
|
+
* e emite `yield* iterator` no JIT.
|
|
238
|
+
*/
|
|
239
|
+
interface InteractiveApplyResult {
|
|
240
|
+
readonly ok: true;
|
|
241
|
+
readonly iterator: Iterator<PauseEvent, ApplyResult, unknown> | AsyncIterator<PauseEvent, ApplyResult, unknown>;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
interface DirectiveHooks<TCtx> {
|
|
245
|
+
beforeDirective?: HookFn<[
|
|
246
|
+
directive: Directive,
|
|
247
|
+
frame: ExecutionFrame<TCtx>
|
|
248
|
+
], InterceptResult<TCtx>>;
|
|
249
|
+
afterDirective?: HookFn<[
|
|
250
|
+
directive: Directive,
|
|
251
|
+
result: ApplyResult,
|
|
252
|
+
frame: ExecutionFrame<TCtx>
|
|
253
|
+
], AbortDecision>;
|
|
254
|
+
onDirectivesComplete?: HookFn<[result: DirectiveResult], void>;
|
|
255
|
+
}
|
|
256
|
+
type DirectiveExecutorFn<TCtx> = (directives: readonly Directive[], frame: ExecutionFrame<TCtx>, handlers: DirectiveHandlerMap<TCtx>, directiveHooks: DirectiveHooks<TCtx>, typeField: string, engine: RuleEngineRef<TCtx>, maxDirectives: number) => DirectiveResult | Promise<DirectiveResult>;
|
|
257
|
+
type DirectiveRunnerFn<TCtx> = (directives: readonly Directive[], frame: ExecutionFrame<TCtx>) => DirectiveResult | Promise<DirectiveResult>;
|
|
141
258
|
/** Resultado de interceptação do beforeAction — skip total da execução. */
|
|
142
259
|
interface ActionInterceptResult {
|
|
143
260
|
readonly data?: unknown;
|
|
@@ -199,6 +316,20 @@ interface IActionEngineConfig<TCtx> {
|
|
|
199
316
|
* Diretivas estáticas (const/let/return/throw) são sempre permitidas.
|
|
200
317
|
*/
|
|
201
318
|
blockedDirectives?: readonly DirectivePermissionEntry[];
|
|
319
|
+
/**
|
|
320
|
+
* Habilita modo interactive (generator-based pause/resume).
|
|
321
|
+
*
|
|
322
|
+
* Sem essa config:
|
|
323
|
+
* - handler com `interactive: true` → erro no constructor
|
|
324
|
+
* - diretiva `type: "pause"` em alguma action → erro no register
|
|
325
|
+
* - `engine.invokeInteractive()` lança
|
|
326
|
+
*
|
|
327
|
+
* Com `interactive: {}` ativo:
|
|
328
|
+
* - mini-graph propaga `_interactiveActions` transitivo
|
|
329
|
+
* - `engine.invoke()` lança per-action transitivo
|
|
330
|
+
* - `engine.invokeInteractive()` retorna iterator
|
|
331
|
+
*/
|
|
332
|
+
interactive?: InteractiveConfig;
|
|
202
333
|
}
|
|
203
334
|
interface IActionEngine<TCtx> {
|
|
204
335
|
/** Registra actions. Valida, analisa, indexa no grafo, compila. */
|
|
@@ -237,12 +368,98 @@ interface IActionEngine<TCtx> {
|
|
|
237
368
|
*/
|
|
238
369
|
readonly directivePermissions: ReadonlyMap<string, DirectivePermission>;
|
|
239
370
|
readonly isAsync: boolean;
|
|
371
|
+
readonly isInteractive: boolean;
|
|
240
372
|
readonly compilationMode: "interpret" | "jit";
|
|
241
373
|
compile(): void;
|
|
242
374
|
readonly directiveHookSlots: ReadonlySet<string>;
|
|
243
375
|
readonly asyncSlots: ReadonlySet<string>;
|
|
376
|
+
/**
|
|
377
|
+
* Action é async transitivamente?
|
|
378
|
+
* Consulta closure `_asyncActions` do mini-graph.
|
|
379
|
+
* `undefined` se id não está registrado.
|
|
380
|
+
*/
|
|
381
|
+
isActionAsync(id: string): boolean | undefined;
|
|
382
|
+
/**
|
|
383
|
+
* Action é interactive transitivamente?
|
|
384
|
+
* Consulta closure `_interactiveActions` do mini-graph.
|
|
385
|
+
* `undefined` se id não está registrado.
|
|
386
|
+
*/
|
|
387
|
+
isActionInteractive(id: string): boolean | undefined;
|
|
388
|
+
/**
|
|
389
|
+
* Invoca action em modo interactive — retorna iterator drenável.
|
|
390
|
+
* Lança se a action não é interactive ou se engine não tem
|
|
391
|
+
* `interactive` configurado.
|
|
392
|
+
*
|
|
393
|
+
* Variante async (AsyncInteractiveSession) é retornada quando a
|
|
394
|
+
* action é async transitivamente.
|
|
395
|
+
*/
|
|
396
|
+
invokeInteractive(id: string, params?: Record<string, unknown>, ctx?: TCtx): InteractiveSession | AsyncInteractiveSession;
|
|
244
397
|
}
|
|
245
398
|
|
|
399
|
+
/**
|
|
400
|
+
* Helpers opcionais pra drenar `InteractiveSession` / `AsyncInteractiveSession`.
|
|
401
|
+
*
|
|
402
|
+
* `engine.invokeInteractive()` retorna iterator. Em "play mode" (sem debug),
|
|
403
|
+
* o consumer só quer o resultado final — drenar o iterator manualmente é
|
|
404
|
+
* verboso. Esses helpers fazem o trabalho.
|
|
405
|
+
*
|
|
406
|
+
* Em modo debug ou UX interativa real, o consumer dirige `next()` direto.
|
|
407
|
+
*/
|
|
408
|
+
/**
|
|
409
|
+
* Função do consumer pra responder a um yield do iterator. Retorna o valor
|
|
410
|
+
* que o iterator vai receber via `next(value)`.
|
|
411
|
+
*
|
|
412
|
+
* O `event` pode ser:
|
|
413
|
+
* - `PauseEvent` (engine-level — `type:"pause"`): tem `source`, `directive`,
|
|
414
|
+
* `frame`, `index`, `payload: { message }`.
|
|
415
|
+
* - **Qualquer coisa** (handler interactive): handler controla 100% o
|
|
416
|
+
* payload. Pode ser `{ prompt, options }`, `{ kind, data }`, etc.
|
|
417
|
+
*
|
|
418
|
+
* Retornos comuns:
|
|
419
|
+
* - `undefined` ou ausente → continua / captura `undefined` em `as`
|
|
420
|
+
* - `false` / `"abort"` / `"cancel"` → aborta `type:"pause"`
|
|
421
|
+
* - qualquer dado → entregue ao handler ou capturado em `as`
|
|
422
|
+
*/
|
|
423
|
+
type Responder = (event: PauseEvent | unknown) => unknown;
|
|
424
|
+
/**
|
|
425
|
+
* Drena uma `InteractiveSession` síncrona. Chama `next(value)` em loop até
|
|
426
|
+
* `done`, opcionalmente consultando `responder` em cada pausa.
|
|
427
|
+
*
|
|
428
|
+
* Sem responder: cada pausa recebe `undefined` (continua/captura `undefined`
|
|
429
|
+
* em `as`). Útil pra "play through" em testes determinísticos.
|
|
430
|
+
*
|
|
431
|
+
* @example
|
|
432
|
+
* ```ts
|
|
433
|
+
* const session = engine.invokeInteractive("foo", undefined, ctx) as InteractiveSession;
|
|
434
|
+
* const result = drainSync(session, (ev) => {
|
|
435
|
+
* if (ev.source === "pause") return "ok";
|
|
436
|
+
* if (ev.payload?.prompt === "Nome?") return "Anderson";
|
|
437
|
+
* return undefined;
|
|
438
|
+
* });
|
|
439
|
+
* ```
|
|
440
|
+
*/
|
|
441
|
+
declare function drainSync(session: InteractiveSession, responder?: Responder): DirectiveResult;
|
|
442
|
+
/**
|
|
443
|
+
* Drena uma `AsyncInteractiveSession`. Versão async de `drainSync`.
|
|
444
|
+
*
|
|
445
|
+
* Suporta responder sync ou async — se retornar Promise, é awaited.
|
|
446
|
+
*/
|
|
447
|
+
declare function drainAsync(session: AsyncInteractiveSession, responder?: Responder): Promise<DirectiveResult>;
|
|
448
|
+
/**
|
|
449
|
+
* Cria um responder pré-programado a partir de uma lista de respostas.
|
|
450
|
+
* Cada pausa consome a próxima resposta na ordem. Ideal pra testes.
|
|
451
|
+
*
|
|
452
|
+
* @example
|
|
453
|
+
* ```ts
|
|
454
|
+
* const responder = replayResponder(["Anderson", "yes", 42]);
|
|
455
|
+
* const result = drainSync(session, responder);
|
|
456
|
+
* ```
|
|
457
|
+
*
|
|
458
|
+
* Se o iterator pausar mais vezes que a lista tem respostas, retorna
|
|
459
|
+
* `undefined` pras pausas extras (sem erro).
|
|
460
|
+
*/
|
|
461
|
+
declare function replayResponder(responses: readonly unknown[]): Responder;
|
|
462
|
+
|
|
246
463
|
/**
|
|
247
464
|
* Type-safe event emitter. Zero deps. Browser-compatible.
|
|
248
465
|
*
|
|
@@ -288,7 +505,7 @@ declare class SimpleEmitter<TEvents = Record<string, unknown>> {
|
|
|
288
505
|
}
|
|
289
506
|
|
|
290
507
|
declare const RESERVED_TYPES: Set<string>;
|
|
291
|
-
declare function normalizeDirectives<TCtx>(directives: readonly Directive<TCtx>[],
|
|
508
|
+
declare function normalizeDirectives<TCtx>(directives: readonly Directive<TCtx>[], typeField: string): Directive<TCtx>[];
|
|
292
509
|
|
|
293
510
|
declare function createDirectiveInterpreter<TCtx>(analysis: SlotAnalysis, isAsync: boolean): DirectiveExecutorFn<TCtx>;
|
|
294
511
|
|
|
@@ -299,13 +516,53 @@ interface GeneratedDirectiveExecutor {
|
|
|
299
516
|
fn: RuntimeDirectiveExecutorFn;
|
|
300
517
|
isAsync: boolean;
|
|
301
518
|
}
|
|
302
|
-
|
|
519
|
+
/**
|
|
520
|
+
* Compila um executor genérico de diretivas via `new Function`.
|
|
521
|
+
*
|
|
522
|
+
* @param analysis — slot analysis dos directive hooks (filled/async).
|
|
523
|
+
* @param isAsync — se true, gera função `async ()` e prefixa `await` na chamada
|
|
524
|
+
* do handler. Default: `analysis.hasAnyAsync` (preserva o comportamento legado
|
|
525
|
+
* pra callers que não conhecem handler async). O engine sempre passa explícito,
|
|
526
|
+
* computado a partir de `directiveAnalysis.hasAnyAsync || asyncHandlerSet.size > 0`.
|
|
527
|
+
*/
|
|
528
|
+
declare function buildDirectiveExecutor(analysis: SlotAnalysis, isAsync?: boolean): GeneratedDirectiveExecutor;
|
|
303
529
|
|
|
304
530
|
type RuntimeActionExecutorFn = (frame: unknown, scope: unknown, $: unknown) => unknown;
|
|
305
531
|
interface GeneratedActionExecutor {
|
|
306
532
|
fn: RuntimeActionExecutorFn;
|
|
533
|
+
/** Wrapper async (`async function`/`async function*`)? */
|
|
307
534
|
isAsync: boolean;
|
|
535
|
+
/** Wrapper generator (`function*`/`async function*`)? Quando true, `fn(...)` retorna Generator/AsyncGenerator. */
|
|
536
|
+
isInteractive: boolean;
|
|
308
537
|
}
|
|
309
|
-
|
|
538
|
+
/**
|
|
539
|
+
* Compila um executor unrolled per-action via `new Function`.
|
|
540
|
+
*
|
|
541
|
+
* Decisão sync/async é **por action** (ADR-021 refinado):
|
|
542
|
+
* - Action com pelo menos 1 handler async (transitivamente, via mini-graph)
|
|
543
|
+
* ou hook async → wrapper `async ()`, `await` em todos os handlers.
|
|
544
|
+
* - Action 100% sync na sub-árvore inteira → wrapper sync `()`, zero `await`.
|
|
545
|
+
*
|
|
546
|
+
* Em um engine híbrido (alguns handlers async, outros sync), actions cuja
|
|
547
|
+
* sub-árvore inteira é sync não pagam o overhead de async functions.
|
|
548
|
+
*
|
|
549
|
+
* @param directives — diretivas normalizadas da action.
|
|
550
|
+
* @param analysis — slot analysis dos directive hooks (filled/async).
|
|
551
|
+
* @param typeField — campo de dispatch (default: "type").
|
|
552
|
+
* @param asyncHandlerSet — conjunto de tipos de handler marcados como async
|
|
553
|
+
* (via flag `async: true` ou auto-detect `isAsyncFunction`). Se omitido,
|
|
554
|
+
* nenhum handler é considerado async (compat backward).
|
|
555
|
+
* @param actionUsesAsyncOverride — se fornecido, substitui o cálculo local
|
|
556
|
+
* `directives.some(asyncHandlerSet.has)`. Usado pelo engine pra passar a
|
|
557
|
+
* info **transitiva** computada pelo mini-graph (ADR-026): action que
|
|
558
|
+
* invoca outra action async via `{ type: "action", id: X }` é async
|
|
559
|
+
* transitivamente, mas `asyncHandlerSet.has("action")` retorna false
|
|
560
|
+
* (handler `action` em si não é async). Sem essa override, JIT compilaria
|
|
561
|
+
* wrapper sync pra action async transitiva — bug.
|
|
562
|
+
*
|
|
563
|
+
* Hooks async (`hasAnyAsync`) sempre forçam wrapper async (independente
|
|
564
|
+
* do override) — wrapper sync não pode fazer await em hook.
|
|
565
|
+
*/
|
|
566
|
+
declare function buildActionExecutor(directives: readonly Directive[], analysis: SlotAnalysis, typeField: string, asyncHandlerSet?: ReadonlySet<string>, actionUsesAsyncOverride?: boolean, actionIsInteractive?: boolean, interactiveHandlerSet?: ReadonlySet<string>): GeneratedActionExecutor;
|
|
310
567
|
|
|
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
|
|
568
|
+
export { type ActionDefinition, type ActionHooks, type ActionInterceptResult, type AsyncInteractiveSession, 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 InteractiveApplyResult, type InteractiveConfig, type InteractiveSession, type Listener, type PauseEvent, RESERVED_TYPES, type RegisterError, type RegisterEvent, type RegisterResult, type Responder, SimpleEmitter, type UnregisterEvent, type ValidationResult, buildActionExecutor, buildDirectiveExecutor, createActionEngine, createDirectiveInterpreter, drainAsync, drainSync, normalizeDirectives, replayResponder };
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
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
|
-
`),
|
|
3
|
-
return (${
|
|
4
|
-
${
|
|
5
|
-
})();`),isAsync:
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
${
|
|
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};
|
|
1
|
+
import {processIntercept,Intercept,analyzeSlots,DIRECTIVE_SLOT_NAMES,isAsyncFunction,isGeneratorFunction,createRootFrame}from'@statedelta-actions/core';function Ae(s,e){let r;for(;;){let i=s.next(r);if(i.done)return i.value;r=e?e(i.value):void 0;}}async function Re(s,e){let r;for(;;){let i=await s.next(r);if(i.done)return i.value;r=e?await e(i.value):void 0;}}function Ie(s){let e=0;return ()=>{if(!(e>=s.length))return s[e++]}}var j=class{_listeners=new Map;on(e,r){let i=this._listeners.get(e);i||(i=new Set,this._listeners.set(e,i)),i.add(r);let o=false;return ()=>{o||(o=true,i.delete(r),i.size===0&&this._listeners.delete(e));}}once(e,r){let i=this.on(e,o=>{i(),r(o);});return i}emit(e,r){let i=this._listeners.get(e);if(!i||i.size===0)return;let o=[...i];for(let t=0;t<o.length;t++)try{o[t](r);}catch(n){console.error(`[SimpleEmitter] Listener error on "${e}":`,n);}}listenerCount(e){return this._listeners.get(e)?.size??0}hasListeners(e){let r=this._listeners.get(e);return r!==void 0&&r.size>0}off(e){this._listeners.delete(e);}removeAllListeners(){this._listeners.clear();}};var L=new Set(["const","let","return","throw","pause","if"]);function ue(s,e,r,i){let o=[];return X(s.directives,e,r,i,"directive",o,s.id),o}function X(s,e,r,i,o,t,n){for(let a=0;a<s.length;a++){let d=s[a],f=d[i],x=`${o}[${a}]`;if(!f){t.push(`${x}: missing type field "${i}"`);continue}if(f==="if"){let l=d.cond;typeof l!="function"&&typeof l!="boolean"&&t.push(`${x}: "if" requires cond as function or boolean`);let _=d.then;Array.isArray(_)?X(_,e,r,i,`${x}.then`,t,n):t.push(`${x}: "if" requires then as array`);let m=d.else;m!==void 0&&(Array.isArray(m)?X(m,e,r,i,`${x}.else`,t,n):t.push(`${x}.else: must be array`));continue}if(L.has(f))continue;if(!e[f])throw new Error(`Action "${n}" ${x}: no handler registered for type "${f}". Register the handler in createActionEngine({ handlers }) before registering this action.`);let C=r.get(f);if(C?.validate)try{let l=C.validate(d);l&&!l.valid&&t.push(`${x}: ${l.error??"validation failed"}`);}catch(l){t.push(`${x}: validate threw: ${l}`);}let y=d.catch;if(y&&Array.isArray(y))for(let l=0;l<y.length;l++){let m=y[l][i];if(!(m&&L.has(m))&&m&&!e[m])throw new Error(`Action "${n}" ${x}.catch[${l}]: no handler registered for type "${m}". Register the handler in createActionEngine({ handlers }) before registering this action.`)}}}function N(s,e){let r=s.length,i=new Array(r);for(let o=0;o<r;o++){let t=s[o],n=t[e],a=t,d=false,f=t.catch;if(Array.isArray(f)&&f.length>0&&(a={...a,catch:N(f,e)},d=true),n==="if"){let x=t.then;Array.isArray(x)&&x.length>0&&(a={...a,then:N(x,e)},d=true);let C=t.else;Array.isArray(C)&&C.length>0&&(a={...a,else:N(C,e)},d=true);}i[o]=d?a:t;}return i}function z(s,e,r,i,o,t,n){return {success:false,aborted:true,abortedBy:s,appliedCount:e,skippedCount:r,errors:i,processedCount:o,totalCount:t,counters:n}}function ke(s){let e=s.filledNames.has("beforeDirective"),r=s.filledNames.has("afterDirective"),i=s.filledNames.has("onDirectivesComplete");return function(t,n,a,d,f,x,C){let y=Math.min(t.length,C),l=[],_=0,m=0,{counters:p,scope:A}=n,$=n.ctx,w=[{dirs:t,i:0,len:y,topLevelIfIndex:-1}],k=0;for(;w.length>0;){let R=w[w.length-1];if(R.i>=R.len){w.pop();continue}let T=R.i++,S=R.topLevelIfIndex!==-1,b=S?R.topLevelIfIndex:T;S||(k=T+1);let h=R.dirs[T],E=h[f];if(E==="const"||E==="let"){let c=h.name;if(typeof h.resolve=="function")try{A[c]=h.resolve($,A).value;}catch(u){l.push({directiveIndex:b,error:`Binding resolve: ${u}`}),p.errors++;}else A[c]=h.value;continue}if(E==="return"){let c=k;if(typeof h.resolve=="function")try{let u=h.resolve($,A),v="value"in u?u.value:"return"in u?u.return:h.value;return {success:!0,aborted:!1,appliedCount:_,skippedCount:m,errors:l,processedCount:c,totalCount:y,counters:p,data:v}}catch(u){l.push({directiveIndex:b,error:`Control resolve: ${u}`}),p.errors++;}else return {success:true,aborted:false,appliedCount:_,skippedCount:m,errors:l,processedCount:c,totalCount:y,counters:p,data:h.value};continue}if(E==="throw"){let c=k;if(typeof h.resolve=="function")try{let u=h.resolve($,A),v="message"in u?u.message:"throw"in u?u.throw:h.message;return {success:!1,aborted:!0,abortedBy:"throw",appliedCount:_,skippedCount:m,errors:l,processedCount:c,totalCount:y,counters:p,data:v}}catch(u){l.push({directiveIndex:b,error:`Control resolve: ${u}`}),p.errors++;}else return {success:false,aborted:true,abortedBy:"throw",appliedCount:_,skippedCount:m,errors:l,processedCount:c,totalCount:y,counters:p,data:h.message};continue}if(E==="if"){let c;try{let v=h.cond;c=typeof v=="function"?!!v($,A):!!v;}catch(v){l.push({directiveIndex:b,error:`if cond: ${v}`}),p.errors++;continue}let u=c?h.then:h.else;if(Array.isArray(u)&&u.length>0){let v=Math.min(u.length,C),G=S?R.topLevelIfIndex:T;w.push({dirs:u,i:0,len:v,topLevelIfIndex:G});}continue}let g=h,I=n;if(e)try{let c=processIntercept(d.beforeDirective(g,n),"beforeDirective");if(c.action===Intercept.SKIP){m++,p.directivesSkipped++;continue}if(c.action===Intercept.ABORT)return z(c.abortReason,_,m,l,k===0?T:k-1,y,p);c.ctx!==void 0&&(I=n.withCtx(c.ctx)),c.directive!==void 0&&(g=c.directive);}catch(c){l.push({directiveIndex:b,error:`Hook beforeDirective: ${c}`}),p.errors++;}if(typeof g.resolve=="function")try{let c=g.resolve(I.ctx,I.scope);g={...g,...c};}catch(c){l.push({directiveIndex:b,error:`Directive resolve: ${c}`}),p.errors++;continue}let F=g[f],M=F?a[F]:void 0;if(!M){l.push({directiveIndex:b,error:`No handler for directive type: ${F??"undefined"}`}),p.errors++;continue}let D;try{D=M(g,I,x);}catch(c){D={ok:false,error:String(c)};}let H=k;if(D.ok){if(_++,p.directivesApplied++,typeof g.as=="string"&&(A[g.as]=D.data),D.halt)return {success:true,aborted:true,abortedBy:"halt",appliedCount:_,skippedCount:m,errors:l,processedCount:H,totalCount:y,counters:p,data:D.data}}else {if(D.halt)return {success:false,aborted:true,abortedBy:"halt",appliedCount:_,skippedCount:m,errors:l,processedCount:H,totalCount:y,counters:p,data:D.data};let c=g.catch;if(Array.isArray(c)&&c.length>0){A.$exception=D.error??"handler failed";let u=x.runDirectives(c,I);_+=u.appliedCount;for(let v=0;v<u.errors.length;v++)l.push(u.errors[v]);if(u.aborted)return {success:u.success,aborted:true,abortedBy:u.abortedBy,appliedCount:_,skippedCount:m,errors:l,processedCount:H,totalCount:y,counters:p,data:u.data}}else l.push({directiveIndex:b,error:D.error??"handler failed"}),p.errors++;}if(r)try{if(d.afterDirective(g,D,I)==="abort")return z("afterDirective",_,m,l,H,y,p)}catch(c){l.push({directiveIndex:b,error:`Hook afterDirective: ${c}`}),p.errors++;}}let P={success:true,aborted:false,appliedCount:_,skippedCount:m,errors:l,processedCount:y,totalCount:y,counters:p};if(i)try{d.onDirectivesComplete(P);}catch{}return P}}function Ee(s){let e=s.filledNames.has("beforeDirective"),r=s.filledNames.has("afterDirective"),i=s.filledNames.has("onDirectivesComplete");return async function(t,n,a,d,f,x,C){let y=Math.min(t.length,C),l=[],_=0,m=0,{counters:p,scope:A}=n,$=n.ctx,w=[{dirs:t,i:0,len:y,topLevelIfIndex:-1}],k=0;for(;w.length>0;){let R=w[w.length-1];if(R.i>=R.len){w.pop();continue}let T=R.i++,S=R.topLevelIfIndex!==-1,b=S?R.topLevelIfIndex:T;S||(k=T+1);let h=R.dirs[T],E=h[f];if(E==="const"||E==="let"){let c=h.name;if(typeof h.resolve=="function")try{A[c]=h.resolve($,A).value;}catch(u){l.push({directiveIndex:b,error:`Binding resolve: ${u}`}),p.errors++;}else A[c]=h.value;continue}if(E==="return"){let c=k;if(typeof h.resolve=="function")try{let u=h.resolve($,A),v="value"in u?u.value:"return"in u?u.return:h.value;return {success:!0,aborted:!1,appliedCount:_,skippedCount:m,errors:l,processedCount:c,totalCount:y,counters:p,data:v}}catch(u){l.push({directiveIndex:b,error:`Control resolve: ${u}`}),p.errors++;}else return {success:true,aborted:false,appliedCount:_,skippedCount:m,errors:l,processedCount:c,totalCount:y,counters:p,data:h.value};continue}if(E==="throw"){let c=k;if(typeof h.resolve=="function")try{let u=h.resolve($,A),v="message"in u?u.message:"throw"in u?u.throw:h.message;return {success:!1,aborted:!0,abortedBy:"throw",appliedCount:_,skippedCount:m,errors:l,processedCount:c,totalCount:y,counters:p,data:v}}catch(u){l.push({directiveIndex:b,error:`Control resolve: ${u}`}),p.errors++;}else return {success:false,aborted:true,abortedBy:"throw",appliedCount:_,skippedCount:m,errors:l,processedCount:c,totalCount:y,counters:p,data:h.message};continue}if(E==="if"){let c;try{let v=h.cond;c=typeof v=="function"?!!v($,A):!!v;}catch(v){l.push({directiveIndex:b,error:`if cond: ${v}`}),p.errors++;continue}let u=c?h.then:h.else;if(Array.isArray(u)&&u.length>0){let v=Math.min(u.length,C),G=S?R.topLevelIfIndex:T;w.push({dirs:u,i:0,len:v,topLevelIfIndex:G});}continue}let g=h,I=n;if(e)try{let c=processIntercept(await d.beforeDirective(g,n),"beforeDirective");if(c.action===Intercept.SKIP){m++,p.directivesSkipped++;continue}if(c.action===Intercept.ABORT)return z(c.abortReason,_,m,l,k===0?T:k-1,y,p);c.ctx!==void 0&&(I=n.withCtx(c.ctx)),c.directive!==void 0&&(g=c.directive);}catch(c){l.push({directiveIndex:b,error:`Hook beforeDirective: ${c}`}),p.errors++;}if(typeof g.resolve=="function")try{let c=g.resolve(I.ctx,I.scope);g={...g,...c};}catch(c){l.push({directiveIndex:b,error:`Directive resolve: ${c}`}),p.errors++;continue}let F=g[f],M=F?a[F]:void 0;if(!M){l.push({directiveIndex:b,error:`No handler for directive type: ${F??"undefined"}`}),p.errors++;continue}let D;try{D=await M(g,I,x);}catch(c){D={ok:false,error:String(c)};}let H=k;if(D.ok){if(_++,p.directivesApplied++,typeof g.as=="string"&&(A[g.as]=D.data),D.halt)return {success:true,aborted:true,abortedBy:"halt",appliedCount:_,skippedCount:m,errors:l,processedCount:H,totalCount:y,counters:p,data:D.data}}else {if(D.halt)return {success:false,aborted:true,abortedBy:"halt",appliedCount:_,skippedCount:m,errors:l,processedCount:H,totalCount:y,counters:p,data:D.data};let c=g.catch;if(Array.isArray(c)&&c.length>0){A.$exception=D.error??"handler failed";let u=await x.runDirectivesAsync(c,I);_+=u.appliedCount;for(let v=0;v<u.errors.length;v++)l.push(u.errors[v]);if(u.aborted)return {success:u.success,aborted:true,abortedBy:u.abortedBy,appliedCount:_,skippedCount:m,errors:l,processedCount:H,totalCount:y,counters:p,data:u.data}}else l.push({directiveIndex:b,error:D.error??"handler failed"}),p.errors++;}if(r)try{if(await d.afterDirective(g,D,I)==="abort")return z("afterDirective",_,m,l,H,y,p)}catch(c){l.push({directiveIndex:b,error:`Hook afterDirective: ${c}`}),p.errors++;}}let P={success:true,aborted:false,appliedCount:_,skippedCount:m,errors:l,processedCount:y,totalCount:y,counters:p};if(i)try{await d.onDirectivesComplete(P);}catch{}return P}}function U(s,e){return e?Ee(s):ke(s)}function B(s,e,r,i,o,t,n,a){return {success:false,aborted:true,abortedBy:s,appliedCount:e,skippedCount:r,errors:i,processedCount:o,totalCount:t,counters:n,data:a}}function fe(s){if(s===null||typeof s!="object")return null;if(typeof s.next=="function")return s;let e=s.iterator;return e!=null&&typeof e=="object"&&typeof e.next=="function"?e:null}function we(s){let e=s.filledNames.has("beforeDirective"),r=s.filledNames.has("afterDirective"),i=s.filledNames.has("onDirectivesComplete");return function*(t,n,a,d,f,x,C){let y=Math.min(t.length,C),l=[],_=0,m=0,{counters:p,scope:A}=n,$=n.ctx,w=[{dirs:t,i:0,len:y,topLevelIfIndex:-1}],k=0;for(;w.length>0;){let R=w[w.length-1];if(R.i>=R.len){w.pop();continue}let T=R.i++,S=R.topLevelIfIndex!==-1,b=S?R.topLevelIfIndex:T;S||(k=T+1);let h=R.dirs[T],E=h[f];if(E==="const"||E==="let"){let c=h.name;if(typeof h.resolve=="function")try{A[c]=h.resolve($,A).value;}catch(u){l.push({directiveIndex:b,error:`Binding resolve: ${u}`}),p.errors++;}else A[c]=h.value;continue}if(E==="return"){let c=k,u=h.value;if(typeof h.resolve=="function")try{let v=h.resolve($,A);u="value"in v?v.value:"return"in v?v.return:u;}catch(v){l.push({directiveIndex:b,error:`Control resolve: ${v}`}),p.errors++;continue}return {success:true,aborted:false,appliedCount:_,skippedCount:m,errors:l,processedCount:c,totalCount:y,counters:p,data:u}}if(E==="throw"){let c=k,u=h.message;if(typeof h.resolve=="function")try{let v=h.resolve($,A);u="message"in v?v.message:"throw"in v?v.throw:u;}catch(v){l.push({directiveIndex:b,error:`Control resolve: ${v}`}),p.errors++;continue}return B("throw",_,m,l,c,y,p,u)}if(E==="pause"){let c=k,u=yield {source:"pause",directive:h,frame:n,index:b,payload:{message:h.message}};if(u===false||u==="abort"||u==="cancel")return B("pause",_,m,l,c,y,p,u);_++,p.directivesApplied++,typeof h.as=="string"&&u!==void 0&&(A[h.as]=u);continue}if(E==="if"){let c;try{let v=h.cond;c=typeof v=="function"?!!v($,A):!!v;}catch(v){l.push({directiveIndex:b,error:`if cond: ${v}`}),p.errors++;continue}let u=c?h.then:h.else;if(Array.isArray(u)&&u.length>0){let v=Math.min(u.length,C),G=S?R.topLevelIfIndex:T;w.push({dirs:u,i:0,len:v,topLevelIfIndex:G});}continue}let g=h,I=n;if(e)try{let c=processIntercept(d.beforeDirective(g,n),"beforeDirective");if(c.action===Intercept.SKIP){m++,p.directivesSkipped++;continue}if(c.action===Intercept.ABORT)return B(c.abortReason,_,m,l,k===0?T:k-1,y,p);c.ctx!==void 0&&(I=n.withCtx(c.ctx)),c.directive!==void 0&&(g=c.directive);}catch(c){l.push({directiveIndex:b,error:`Hook beforeDirective: ${c}`}),p.errors++;}if(typeof g.resolve=="function")try{let c=g.resolve(I.ctx,I.scope);g={...g,...c};}catch(c){l.push({directiveIndex:b,error:`Directive resolve: ${c}`}),p.errors++;continue}let F=g[f],M=F?a[F]:void 0;if(!M){l.push({directiveIndex:b,error:`No handler for directive type: ${F??"undefined"}`}),p.errors++;continue}let D;try{let c=M(g,I,x),u=fe(c);u!==null?D=yield*u:D=c;}catch(c){D={ok:false,error:String(c)};}let H=k;if(D.ok){if(_++,p.directivesApplied++,typeof g.as=="string"&&(A[g.as]=D.data),D.halt)return {success:true,aborted:true,abortedBy:"halt",appliedCount:_,skippedCount:m,errors:l,processedCount:H,totalCount:y,counters:p,data:D.data}}else {if(D.halt)return B("halt",_,m,l,H,y,p,D.data);let c=g.catch;if(Array.isArray(c)&&c.length>0){A.$exception=D.error??"handler failed";let u=x.runDirectives(c,I);_+=u.appliedCount;for(let v=0;v<u.errors.length;v++)l.push(u.errors[v]);if(u.aborted)return {success:u.success,aborted:true,abortedBy:u.abortedBy,appliedCount:_,skippedCount:m,errors:l,processedCount:H,totalCount:y,counters:p,data:u.data}}else l.push({directiveIndex:b,error:D.error??"handler failed"}),p.errors++;}if(r)try{if(d.afterDirective(g,D,I)==="abort")return B("afterDirective",_,m,l,H,y,p)}catch(c){l.push({directiveIndex:b,error:`Hook afterDirective: ${c}`}),p.errors++;}}let P={success:true,aborted:false,appliedCount:_,skippedCount:m,errors:l,processedCount:y,totalCount:y,counters:p};if(i)try{d.onDirectivesComplete(P);}catch{}return P}}function Te(s){let e=s.filledNames.has("beforeDirective"),r=s.filledNames.has("afterDirective"),i=s.filledNames.has("onDirectivesComplete");return async function*(t,n,a,d,f,x,C){let y=Math.min(t.length,C),l=[],_=0,m=0,{counters:p,scope:A}=n,$=n.ctx,w=[{dirs:t,i:0,len:y,topLevelIfIndex:-1}],k=0;for(;w.length>0;){let R=w[w.length-1];if(R.i>=R.len){w.pop();continue}let T=R.i++,S=R.topLevelIfIndex!==-1,b=S?R.topLevelIfIndex:T;S||(k=T+1);let h=R.dirs[T],E=h[f];if(E==="const"||E==="let"){let c=h.name;if(typeof h.resolve=="function")try{A[c]=h.resolve($,A).value;}catch(u){l.push({directiveIndex:b,error:`Binding resolve: ${u}`}),p.errors++;}else A[c]=h.value;continue}if(E==="return"){let c=k,u=h.value;if(typeof h.resolve=="function")try{let v=h.resolve($,A);u="value"in v?v.value:"return"in v?v.return:u;}catch(v){l.push({directiveIndex:b,error:`Control resolve: ${v}`}),p.errors++;continue}return {success:true,aborted:false,appliedCount:_,skippedCount:m,errors:l,processedCount:c,totalCount:y,counters:p,data:u}}if(E==="throw"){let c=k,u=h.message;if(typeof h.resolve=="function")try{let v=h.resolve($,A);u="message"in v?v.message:"throw"in v?v.throw:u;}catch(v){l.push({directiveIndex:b,error:`Control resolve: ${v}`}),p.errors++;continue}return B("throw",_,m,l,c,y,p,u)}if(E==="pause"){let c=k,u=yield {source:"pause",directive:h,frame:n,index:b,payload:{message:h.message}};if(u===false||u==="abort"||u==="cancel")return B("pause",_,m,l,c,y,p,u);_++,p.directivesApplied++,typeof h.as=="string"&&u!==void 0&&(A[h.as]=u);continue}if(E==="if"){let c;try{let v=h.cond;c=typeof v=="function"?!!v($,A):!!v;}catch(v){l.push({directiveIndex:b,error:`if cond: ${v}`}),p.errors++;continue}let u=c?h.then:h.else;if(Array.isArray(u)&&u.length>0){let v=Math.min(u.length,C),G=S?R.topLevelIfIndex:T;w.push({dirs:u,i:0,len:v,topLevelIfIndex:G});}continue}let g=h,I=n;if(e)try{let c=processIntercept(await d.beforeDirective(g,n),"beforeDirective");if(c.action===Intercept.SKIP){m++,p.directivesSkipped++;continue}if(c.action===Intercept.ABORT)return B(c.abortReason,_,m,l,k===0?T:k-1,y,p);c.ctx!==void 0&&(I=n.withCtx(c.ctx)),c.directive!==void 0&&(g=c.directive);}catch(c){l.push({directiveIndex:b,error:`Hook beforeDirective: ${c}`}),p.errors++;}if(typeof g.resolve=="function")try{let c=g.resolve(I.ctx,I.scope);g={...g,...c};}catch(c){l.push({directiveIndex:b,error:`Directive resolve: ${c}`}),p.errors++;continue}let F=g[f],M=F?a[F]:void 0;if(!M){l.push({directiveIndex:b,error:`No handler for directive type: ${F??"undefined"}`}),p.errors++;continue}let D;try{let c=await M(g,I,x),u=fe(c);u!==null?D=yield*u:D=c;}catch(c){D={ok:false,error:String(c)};}let H=k;if(D.ok){if(_++,p.directivesApplied++,typeof g.as=="string"&&(A[g.as]=D.data),D.halt)return {success:true,aborted:true,abortedBy:"halt",appliedCount:_,skippedCount:m,errors:l,processedCount:H,totalCount:y,counters:p,data:D.data}}else {if(D.halt)return B("halt",_,m,l,H,y,p,D.data);let c=g.catch;if(Array.isArray(c)&&c.length>0){A.$exception=D.error??"handler failed";let u=await x.runDirectivesAsync(c,I);_+=u.appliedCount;for(let v=0;v<u.errors.length;v++)l.push(u.errors[v]);if(u.aborted)return {success:u.success,aborted:true,abortedBy:u.abortedBy,appliedCount:_,skippedCount:m,errors:l,processedCount:H,totalCount:y,counters:p,data:u.data}}else l.push({directiveIndex:b,error:D.error??"handler failed"}),p.errors++;}if(r)try{if(await d.afterDirective(g,D,I)==="abort")return B("afterDirective",_,m,l,H,y,p)}catch(c){l.push({directiveIndex:b,error:`Hook afterDirective: ${c}`}),p.errors++;}}let P={success:true,aborted:false,appliedCount:_,skippedCount:m,errors:l,processedCount:y,totalCount:y,counters:p};if(i)try{await d.onDirectivesComplete(P);}catch{}return P}}function Z(s,e){return e?Te(s):we(s)}function ee(s,e=s.hasAnyAsync){let{filledNames:r}=s,i=x=>r.has(x),o=x=>s.asyncNames.has(x)?"await ":"",t=e?"await ":"",n=[];for(let x of r)n.push(`const ${x} = directiveHooks.${x};`);n.push("const len = Math.min(directives.length, maxDirectives);"),n.push("const errors = []; let appliedCount = 0; let skippedCount = 0;"),n.push("const counters = frame.counters;"),n.push("for (let i = 0; i < len; i++) {"),n.push(" let directive = directives[i];"),i("beforeDirective")?(n.push(" let _df = frame;"),n.push(" try {"),n.push(` const _bd = ${o("beforeDirective")}beforeDirective(directive, frame);`),n.push(' if (_bd === "skip") { skippedCount++; counters.directivesSkipped++; continue; }'),n.push(' if (_bd === "abort") return { success: false, aborted: true, abortedBy: "beforeDirective", appliedCount, skippedCount, errors, processedCount: i, totalCount: len, counters };'),n.push(' if (typeof _bd === "object" && _bd !== null) {'),n.push(' if ("abort" in _bd) return { success: false, aborted: true, abortedBy: _bd.abort, appliedCount, skippedCount, errors, processedCount: i, totalCount: len, counters };'),n.push(' if ("ctx" in _bd) _df = frame.withCtx(_bd.ctx);'),n.push(' if ("directive" in _bd) directive = _bd.directive;'),n.push(" }"),n.push(' } catch (_e) { errors.push({ directiveIndex: i, error: "Hook beforeDirective: " + _e }); counters.errors++; }')):n.push(" const _df = frame;"),n.push(' if (typeof directive.resolve === "function") {'),n.push(" try { const _r = directive.resolve(_df.ctx); directive = Object.assign({}, directive, _r); }"),n.push(' catch (_e) { errors.push({ directiveIndex: i, error: "Directive resolve: " + _e }); counters.errors++; continue; }'),n.push(" }"),n.push(" const _type = directive[typeField];"),n.push(" const _handler = _type ? handlers[_type] : undefined;"),n.push(' if (!_handler) { errors.push({ directiveIndex: i, error: "No handler for directive type: " + (_type || "undefined") }); counters.errors++; continue; }'),n.push(" let _result;"),n.push(` try { _result = ${t}_handler(directive, _df, engine); } catch (_e) { errors.push({ directiveIndex: i, error: String(_e) }); counters.errors++; continue; }`),n.push(" if (_result.ok) { appliedCount++; counters.directivesApplied++; }"),n.push(' else { errors.push({ directiveIndex: i, error: _result.error || "handler failed" }); counters.errors++; }'),i("afterDirective")&&(n.push(" try {"),n.push(` const _ad = ${o("afterDirective")}afterDirective(directive, _result, _df);`),n.push(' if (_ad === "abort") return { success: false, aborted: true, abortedBy: "afterDirective", appliedCount, skippedCount, errors, processedCount: i + 1, totalCount: len, counters };'),n.push(' } catch (_e) { errors.push({ directiveIndex: i, error: "Hook afterDirective: " + _e }); counters.errors++; }')),n.push("}"),n.push("const _finalResult = { success: true, aborted: false, appliedCount, skippedCount, errors, processedCount: len, totalCount: len, counters };"),i("onDirectivesComplete")&&n.push(`try { ${o("onDirectivesComplete")}onDirectivesComplete(_finalResult); } catch (_e) {}`),n.push("return _finalResult;");let a=n.join(`
|
|
2
|
+
`),d=e?"async ":"";return {fn:new Function("directives","frame","handlers","directiveHooks","typeField","engine","maxDirectives",`"use strict";
|
|
3
|
+
return (${d}() => {
|
|
4
|
+
${a}
|
|
5
|
+
})();`),isAsync:e}}function te(s,e,r){return `return{success:false,aborted:true,abortedBy:${s},appliedCount,skippedCount,errors,processedCount:${e},totalCount:${r},counters};`}function $e(s,e){return `return{success:true,aborted:true,abortedBy:"halt",appliedCount,skippedCount,errors,processedCount:${s},totalCount:${e},counters,data:_result.data};`}function Se(s,e){return `return{success:false,aborted:true,abortedBy:"halt",appliedCount,skippedCount,errors,processedCount:${s},totalCount:${e},counters,data:_result.data};`}function He(s,e,r,i){let o=JSON.stringify(e.name);typeof e.resolve=="function"?(s.push("try{"),s.push(`scope[${o}]=${r}.resolve(ctx,scope).value;`),s.push(`}catch(_e){errors.push({directiveIndex:${i},error:"Binding resolve: "+_e});counters.errors++;}`)):s.push(`scope[${o}]=${r}.value;`);}function Fe(s,e,r,i,o,t){typeof e.resolve=="function"?(s.push("try{"),s.push(`const _rv=${r}.resolve(ctx,scope);`),s.push(`return{success:true,aborted:false,appliedCount,skippedCount,errors,processedCount:${o},totalCount:${t},counters,data:"value" in _rv?_rv.value:"return" in _rv?_rv.return:${r}.value};`),s.push(`}catch(_e){errors.push({directiveIndex:${i},error:"Control resolve: "+_e});counters.errors++;}`)):s.push(`return{success:true,aborted:false,appliedCount,skippedCount,errors,processedCount:${o},totalCount:${t},counters,data:${r}.value};`);}function Pe(s,e,r,i,o,t){typeof e.resolve=="function"?(s.push("try{"),s.push(`const _rv=${r}.resolve(ctx,scope);`),s.push(`return{success:false,aborted:true,abortedBy:"throw",appliedCount,skippedCount,errors,processedCount:${o},totalCount:${t},counters,data:"message" in _rv?_rv.message:"throw" in _rv?_rv.throw:${r}.message};`),s.push(`}catch(_e){errors.push({directiveIndex:${i},error:"Control resolve: "+_e});counters.errors++;}`)):s.push(`return{success:false,aborted:true,abortedBy:"throw",appliedCount,skippedCount,errors,processedCount:${o},totalCount:${t},counters,data:${r}.message};`);}function Me(s,e,r,i,o,t){let n=typeof e.as=="string",a=n?JSON.stringify(e.as):"";s.push(`{const _ack=yield{source:"pause",directive:${r},frame,index:${i},payload:{message:${r}.message}};`),s.push(`if(_ack===false||_ack==="abort"||_ack==="cancel")return{success:false,aborted:true,abortedBy:"pause",appliedCount,skippedCount,errors,processedCount:${o},totalCount:${t},counters,data:_ack};`),s.push("appliedCount++;counters.directivesApplied++;"),n&&s.push(`if(_ack!==undefined)scope[${a}]=_ack;`),s.push("}");}function Be(s,e,r,i,o){let{L:t,total:n,typeField:a,handlerVars:d,hasBefore:f,hasAfter:x,awBefore:C,awAfter:y,awHandler:l,actionIsAsync:_,actionIsInteractive:m,interactiveHandlerSet:p}=o,A=s[a],$=d.get(A),w=typeof s.resolve=="function",k=typeof s.as=="string",P=Array.isArray(s.catch)&&s.catch.length>0,R=k?JSON.stringify(s.as):"",T=m&&p.has(A),S=o.blockCounter.n++;t.push(`_b${S}:{`);let b=f||w,h=f;b&&t.push(`let _dir=${e};`),h&&t.push("let _df=frame;"),f&&(t.push("try{"),t.push(`const _bd=${C}_hookBefore(${e},frame);`),t.push(`if(_bd==="skip"){skippedCount++;counters.directivesSkipped++;break _b${S};}`),t.push(`if(_bd==="abort")${te('"beforeDirective"',i-1,n)}`),t.push('if(typeof _bd==="object"&&_bd!==null){'),t.push(`if("abort" in _bd)${te("_bd.abort",i-1,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:${r},error:"Hook beforeDirective: "+_e});counters.errors++;}`)),f?(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:${r},error:"Directive resolve: "+_e});counters.errors++;break _b${S};}}`)):w&&(t.push(`try{const _r=${e}.resolve(ctx,scope);_dir=Object.assign({},${e},_r);}`),t.push(`catch(_e){errors.push({directiveIndex:${r},error:"Directive resolve: "+_e});counters.errors++;break _b${S};}`));let E=b?"_dir":e,g=h?"_df":"frame";if(t.push("let _result;"),T?(t.push(`try{_result=yield* ${$}(${E},${g},$.engine);}`),t.push("catch(_e){_result={ok:false,error:String(_e)};}")):m?(t.push(`try{_result=${l}${$}(${E},${g},$.engine);if(_result&&_result.iterator)_result=yield* _result.iterator;}`),t.push("catch(_e){_result={ok:false,error:String(_e)};}")):(t.push(`try{_result=${l}${$}(${E},${g},$.engine);}`),t.push("catch(_e){_result={ok:false,error:String(_e)};}")),t.push("if(_result.ok){"),t.push("appliedCount++;counters.directivesApplied++;"),k&&t.push(`scope[${R}]=_result.data;`),t.push(`if(_result.halt)${$e(i,n)}`),t.push("}else{"),t.push(`if(_result.halt)${Se(i,n)}`),P){t.push('scope.$exception=_result.error||"handler failed";');let I=_?"$.runner":"$.runnerSync";t.push(`const _cr=${l}${I}(${e}.catch,${g});`),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:${i},totalCount:${n},counters,data:_cr.data};`);}else t.push(`errors.push({directiveIndex:${r},error:_result.error||"handler failed"});counters.errors++;`);t.push("}"),x&&(t.push("try{"),t.push(`const _ad=${y}_hookAfter(${E},_result,${g});`),t.push(`if(_ad==="abort")${te('"afterDirective"',i,n)}`),t.push(`}catch(_e){errors.push({directiveIndex:${r},error:"Hook afterDirective: "+_e});counters.errors++;}`)),t.push("}");}function Ge(s,e,r,i,o,t){let{L:n}=t,a=s.cond,d=typeof a=="boolean";n.push("{"),d?n.push(`if(${a?"true":"false"}){`):(n.push("let _cond=false,_condOk=true;"),n.push(`try{const _c=${e}.cond;_cond=typeof _c==="function"?!!_c(ctx,scope):!!_c;}`),n.push(`catch(_e){errors.push({directiveIndex:${r},error:"if cond: "+_e});counters.errors++;_condOk=false;}`),n.push("if(_condOk){"),n.push("if(_cond){"));let f=s.then;Array.isArray(f)&&f.length>0&&re(f,`${e}.then`,i,o,t),n.push("}");let x=s.else;Array.isArray(x)&&x.length>0&&(n.push("else{"),re(x,`${e}.else`,i,o,t),n.push("}")),d||n.push("}"),n.push("}");}function re(s,e,r,i,o){let t=r!==-1;for(let n=0;n<s.length;n++){let a=s[n],d=`${e}[${n}]`,f=t?r:n,x=t?i:n+1;switch(a[o.typeField]){case "const":case "let":He(o.L,a,d,f);break;case "return":Fe(o.L,a,d,f,x,o.total);break;case "throw":Pe(o.L,a,d,f,x,o.total);break;case "pause":Me(o.L,a,d,f,x,o.total);break;case "if":{let y=t?r:n,l=t?i:n+1;Ge(a,d,f,y,l,o);break}default:Be(a,d,f,x,o);break}}}function ne(s,e,r){for(let i of s){let o=i[e];if(o&&!L.has(o)&&r.add(o),o==="if"){let t=i.then;Array.isArray(t)&&t.length>0&&ne(t,e,r);let n=i.else;Array.isArray(n)&&n.length>0&&ne(n,e,r);}}}var pe=new Set;function ie(s,e,r,i=pe,o,t=false,n=pe){let a=[],d=s.length,{filledNames:f,hasAnyAsync:x,asyncNames:C}=e,y=f.has("beforeDirective"),l=f.has("afterDirective"),_=f.has("onDirectivesComplete"),m=o!==void 0?o:V(s,i,r),p=x||m,A=p?"await ":"",$=C.has("beforeDirective")?"await ":"",w=C.has("afterDirective")?"await ":"",k=C.has("onDirectivesComplete")?"await ":"",P=new Set;ne(s,r,P);let R=new Map,T=0;for(let I of P)R.set(I,`_h${T++}`);a.push("const counters=frame.counters;"),a.push("const ctx=frame.ctx;"),a.push("const errors=[];"),a.push("let appliedCount=0;"),a.push("let skippedCount=0;");for(let[I,F]of R)a.push(`const ${F}=$.h[${JSON.stringify(I)}];`);y&&a.push("const _hookBefore=$.hooks.beforeDirective;"),l&&a.push("const _hookAfter=$.hooks.afterDirective;"),re(s,"$.d",-1,0,{L:a,total:d,typeField:r,handlerVars:R,hasBefore:y,hasAfter:l,awBefore:$,awAfter:w,awHandler:A,actionIsAsync:p,actionIsInteractive:t,interactiveHandlerSet:n,blockCounter:{n:0}}),a.push(`const _finalResult={success:true,aborted:false,appliedCount,skippedCount,errors,processedCount:${d},totalCount:${d},counters};`),_&&a.push(`try{${k}$.hooks.onDirectivesComplete(_finalResult);}catch(_e){}`),a.push("return _finalResult;");let h=`{
|
|
6
|
+
${a.join(`
|
|
7
|
+
`)}
|
|
8
|
+
}`,E;return t?E=`(${p?"async function*()":"function*()"}${h})()`:E=`(${p?"async ()=>":"()=>"}${h})()`,{fn:new Function("frame","scope","$",`"use strict";
|
|
9
|
+
return ${E};`),isAsync:p,isInteractive:t}}function V(s,e,r){for(let i of s){let o=i[r];if(o&&e.has(o))return true;if(o==="if"){let n=i.then;if(Array.isArray(n)&&n.length>0&&V(n,e,r))return true;let a=i.else;if(Array.isArray(a)&&a.length>0&&V(a,e,r))return true}let t=i.catch;if(Array.isArray(t)&&t.length>0&&V(t,e,r))return true}return false}function se(s,e,r){return {success:false,aborted:false,appliedCount:0,skippedCount:0,processedCount:0,totalCount:0,errors:[{directiveIndex:-1,error:e}],counters:s,...r}}function ve(s,e){return se(e,`Action not found: "${s}"`,{aborted:true,abortedBy:"action-not-found"})}function he(s,e,r){return se(r,`Max depth ${e} exceeded invoking "${s}"`,{aborted:true,abortedBy:"maxDepth"})}function ye(s,e){return se(e,`Action "${s}" is private (sub-action). Can only be invoked from within its parent scope.`)}function W(s,e){return {success:true,aborted:false,appliedCount:0,skippedCount:0,processedCount:0,totalCount:0,errors:[],data:s,counters:e}}function Le(s){return typeof s=="object"&&s!==null&&"execute"in s}function xe(s){let e=Object.create(null),r=new Map;for(let i of Object.keys(s)){let o=s[i];Le(o)?(e[i]=o.execute,r.set(i,o)):(e[i]=o,r.set(i,{execute:o}));}return {handlers:e,definitions:r}}function me(s,e){if(s==="*")return true;if(!s.includes("*"))return s===e;let r=s.replace(/[.+^${}()|[\]\\]/g,"\\$&");return new RegExp("^"+r.replace(/\*/g,".*")+"$").test(e)}function _e(s){return typeof s=="string"?{pattern:s}:s}function ge(s,e,r){let i=new Map;if(!e&&!r){for(let o of s)i.set(o,{status:"available"});return i}if(e){let o=e.map(_e);for(let t of s){let n=o.some(a=>me(a.pattern,t));i.set(t,{status:n?"available":"denied"});}}else {let o=r.map(_e);for(let t of s){let n=o.find(a=>me(a.pattern,t));n?i.set(t,{status:"denied",reason:n.reason,source:n.source}):i.set(t,{status:"available"});}}return i}function Ce(s){let{typeField:e,asyncHandlerSet:r,interactiveHandlerSet:i}=s,o=new Map,t=new Set,n=new Set,a=new Set,d=new Set;return {upsert(f,x,C){o.set(f,Ne(x,e)),Y(x,r,e)?t.add(f):t.delete(f),C||Q(x,i,e)?n.add(f):n.delete(f);},remove(f){o.delete(f),t.delete(f),n.delete(f);},recompute(){a=De(o,t),d=De(o,n);},isAsync(f){return a.has(f)},isInteractive(f){return d.has(f)},has(f){return o.has(f)}}}function Ne(s,e){let r=new Set;return J(s,e,r),r}function J(s,e,r){for(let i of s){i[e]==="action"&&typeof i.id=="string"&&r.add(i.id);let o=i.catch;if(Array.isArray(o)&&o.length>0&&J(o,e,r),i[e]==="if"){let t=i.then;Array.isArray(t)&&t.length>0&&J(t,e,r);let n=i.else;Array.isArray(n)&&n.length>0&&J(n,e,r);}}}function Y(s,e,r){for(let i of s){let o=i[r];if(o&&e.has(o))return true;let t=i.catch;if(Array.isArray(t)&&t.length>0&&Y(t,e,r))return true;if(o==="if"){let n=i.then;if(Array.isArray(n)&&n.length>0&&Y(n,e,r))return true;let a=i.else;if(Array.isArray(a)&&a.length>0&&Y(a,e,r))return true}}return false}function Q(s,e,r){for(let i of s){let o=i[r];if(o==="pause"||o&&e.has(o))return true;let t=i.catch;if(Array.isArray(t)&&t.length>0&&Q(t,e,r))return true;if(o==="if"){let n=i.then;if(Array.isArray(n)&&n.length>0&&Q(n,e,r))return true;let a=i.else;if(Array.isArray(a)&&a.length>0&&Q(a,e,r))return true}}return false}function O(s,e){for(let r of s){let i=r[e];if(i==="pause")return true;let o=r.catch;if(Array.isArray(o)&&o.length>0&&O(o,e))return true;if(i==="if"){let t=r.then;if(Array.isArray(t)&&t.length>0&&O(t,e))return true;let n=r.else;if(Array.isArray(n)&&n.length>0&&O(n,e))return true}}return false}function De(s,e){let r=new Set(e),i=true;for(;i;){i=false;for(let[o,t]of s)if(!r.has(o)){for(let n of t)if(r.has(n)){r.add(o),i=true;break}}}return r}var Ue=8,qe="type",ce={maxDepth:10,maxRules:1e4,maxDirectives:1e5},ae=class{_directiveExecutor;_mode;_ctx;_requestedMode;_threshold;_limits;_typeField;_handlers;_definitions;_directiveHooks;_directiveAnalysis;_asyncHandlerSet;_interactiveHandlerSet;_isAsync;_isInteractive;_directivePermissions;_miniGraph;_interactiveExecutor;_beforeAction;_afterAction;_registry=new Map;_emitter=new j;_batchDepth=0;_batchErrors=[];_batchWarnings=[];_batchActions=[];_batchRegistered=[];_registeredIds=new Set;_directiveRunner;_directiveRunnerSync;_engineRef;constructor(e){this._requestedMode=e.mode??"auto",this._threshold=e.autoJitThreshold??Ue,this._typeField=e.typeField??qe,this._limits={maxDepth:e.limits?.maxDepth??ce.maxDepth,maxRules:e.limits?.maxRules??ce.maxRules,maxDirectives:e.limits?.maxDirectives??ce.maxDirectives};let{handlers:r,definitions:i}=xe(e.handlers);for(let a of Object.keys(e.handlers))if(L.has(a))throw new Error(`Handler type "${a}" 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=r,this._definitions=i,this._directivePermissions=ge(Object.keys(r),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);let o=new Set,t=new Set;for(let[a,d]of this._definitions)(d.async===true||isAsyncFunction(d.execute))&&o.add(a),(d.interactive===true||isGeneratorFunction(d.execute))&&t.add(a);if(this._asyncHandlerSet=o,this._interactiveHandlerSet=t,this._isInteractive=e.interactive!==void 0,!this._isInteractive&&t.size>0){let a=Array.from(t).join(", ");throw new Error(`Handler(s) [${a}] are interactive but engine has no \`interactive\` config. Add \`interactive: {}\` to enable interactive mode.`)}this._isAsync=this._directiveAnalysis.hasAnyAsync||o.size>0,this._miniGraph=Ce({typeField:this._typeField,asyncHandlerSet:o,interactiveHandlerSet:t}),this._engineRef={runDirectives:(a,d)=>this._executeDirectives(a,d),runDirectivesAsync:(a,d)=>this._executeDirectivesAsync(a,d),invoke:(a,d,f)=>this._invokeInternal(a,d,f),invokeAsync:(a,d,f)=>this._invokeInternalAsync(a,d,f),isActionAsync:a=>this._miniGraph.has(a)?this._miniGraph.isAsync(a):void 0,isActionInteractive:a=>this._miniGraph.has(a)?this._miniGraph.isInteractive(a):void 0,invokeInteractive:(a,d,f)=>this._invokeInteractiveInternal(a,d,f),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=(a,d)=>this._directiveExecutor(a,d,this._handlers,this._directiveHooks,this._typeField,this._engineRef,this._limits.maxDirectives);let n=U(this._directiveAnalysis,false);this._directiveRunnerSync=(a,d)=>n(a,d,this._handlers,this._directiveHooks,this._typeField,this._engineRef,this._limits.maxDirectives),this._requestedMode==="jit"?(this._directiveExecutor=this._buildJitDirectiveExecutor(),this._mode="jit"):this._isAsync?(this._directiveExecutor=U(this._directiveAnalysis,true),this._mode="interpret"):(this._directiveExecutor=n,this._mode="interpret"),this._interactiveExecutor=this._isInteractive?this._isAsync?Z(this._directiveAnalysis,true):Z(this._directiveAnalysis,false):null;}register(e){let r=[],i=[],o=[],t=[];for(let a of e){if(!a.id){i.push({actionId:"",error:"Action must have an id"});continue}if(!this._isInteractive&&O(a.directives,this._typeField)){i.push({actionId:a.id,error:'Action uses directive type:"pause" but engine has no `interactive` config. Add `interactive: {}` to enable.'});continue}let d=ue(a,this._handlers,this._definitions,this._typeField);if(d.length>0){for(let f of d)i.push({actionId:a.id,error:f});continue}t.push(a);}for(let a of t){let d=N(a.directives,this._typeField),f={definition:a,directives:d,compiled:null,invokeCount:0};this._registry.set(a.id,f),this._registeredIds.add(a.id),this._miniGraph.upsert(a.id,d,a.interactive===true),r.push(a.id);}if(this._batchDepth>0){this._batchErrors.push(...i),this._batchWarnings.push(...o);for(let a of t)this._batchActions.push(a);return this._batchRegistered.push(...r),{registered:r,errors:i,warnings:o}}t.length>0&&(this._miniGraph.recompute(),this._invalidateAndMaybeRecompile());let n={registered:r,errors:i,warnings:o};return r.length>0&&this._emitter.emit("register",{actions:t,result:n,registered:r}),n}unregister(e){let r=this._registry.delete(e);r&&(this._registeredIds.delete(e),this._miniGraph.remove(e));let i=e+"/",o=[];for(let t of this._registry.keys())t.startsWith(i)&&(this._registry.delete(t),this._registeredIds.delete(t),this._miniGraph.remove(t),o.push(t));return r&&(this._miniGraph.recompute(),this._invalidateAndMaybeRecompile(),this._emitter.emit("unregister",{id:e,cascaded:o})),r}invoke(e,r,i){if(this._miniGraph.isInteractive(e))throw new Error(`Cannot call invoke("${e}") \u2014 action is interactive (transitively). Use invokeInteractive() instead.`);if(this._miniGraph.isAsync(e))throw new Error(`Cannot call invoke("${e}") \u2014 action is async (transitively). Use invokeAsync() instead.`);if(this._directiveAnalysis.hasAnyAsync)throw new Error(`Cannot call invoke("${e}") \u2014 engine has async directive hooks. Use invokeAsync() instead.`);let o=i!==void 0?i:this._requireCtx(),t=createRootFrame(o,this._limits);return this._invokeInternal(e,r,t)}async invokeAsync(e,r,i){if(this._miniGraph.isInteractive(e))throw new Error(`Cannot call invokeAsync("${e}") \u2014 action is interactive (transitively). Use invokeInteractive() instead.`);let o=i!==void 0?i:this._requireCtx(),t=createRootFrame(o,this._limits);return this._invokeInternalAsync(e,r,t)}setContext(e){this._ctx=e;}context(e,r){let i=this._ctx;this._ctx=e;try{return r()}finally{this._ctx=i;}}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._miniGraph.recompute(),this._invalidateAndMaybeRecompile()),this._batchRegistered.length>0&&this._emitter.emit("register",{actions:this._batchActions,result:e,registered:this._batchRegistered}),e}on(e,r){return this._emitter.on(e,r)}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 isInteractive(){return this._isInteractive}isActionAsync(e){if(this._miniGraph.has(e))return this._miniGraph.isAsync(e)}isActionInteractive(e){if(this._miniGraph.has(e))return this._miniGraph.isInteractive(e)}invokeInteractive(e,r,i){if(!this._isInteractive||this._interactiveExecutor===null)throw new Error("Cannot call invokeInteractive() \u2014 engine has no `interactive` config. Add `interactive: {}` to enable.");let o=i!==void 0?i:this._requireCtx(),t=createRootFrame(o,this._limits);return this._invokeInteractiveInternal(e,r,t)}_invokeInteractiveInternal(e,r,i){let o=this._prepareInvoke(e,r,i);if("success"in o)return be(o,this._isAsync);let{stored:t,childFrame:n,childScope:a}=o;if(this._beforeAction!==null){let f=this._beforeAction(e,r,n);if(f?.skip)return be(W(f.data,n.counters),this._isAsync)}let d;if(t.compiled&&t.compiled.isInteractive)d=t.compiled.fn(n,n.scope,t.compiled.$);else {let f=this._interactiveExecutor;d=f(t.directives,n,this._handlers,this._directiveHooks,this._typeField,this._engineRef,this._limits.maxDirectives);}return Ve(d,e,r,n,this._afterAction,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,r]of this._registry)r.compiled||(r.compiled=this._compileAction(e,r.directives));}}_invokeInternal(e,r,i){let o=this._prepareInvoke(e,r,i);if("success"in o)return o;let{stored:t,childFrame:n,childScope:a}=o;if(this._beforeAction!==null){let f=this._beforeAction(e,r,n);if(f?.skip)return W(f.data,n.counters)}let d;if(t.compiled?d=t.compiled.fn(n,a,t.compiled.$):this._isAsync&&!this._miniGraph.isAsync(e)?(t.compiled=this._compileAction(e,t.directives),d=t.compiled.fn(n,a,t.compiled.$)):(d=this._directiveRunner(t.directives,n),this._maybeAutoPromote(t)),this._afterAction!==null){let f=this._afterAction(e,r,d,n);f!==void 0&&(d=f);}return d}async _invokeInternalAsync(e,r,i){let o=this._prepareInvoke(e,r,i);if("success"in o)return o;let{stored:t,childFrame:n,childScope:a}=o;if(this._beforeAction!==null){let f=this._beforeAction(e,r,n);if(f?.skip)return W(f.data,n.counters)}let d;if(t.compiled?d=await t.compiled.fn(n,a,t.compiled.$):(d=await this._directiveRunner(t.directives,n),this._maybeAutoPromote(t)),this._afterAction!==null){let f=this._afterAction(e,r,d,n);f!==void 0&&(d=f);}return d}_prepareInvoke(e,r,i){let o=this._registry.get(e);if(!o)return ve(e,i.counters);if(e.includes("/")&&!this._isAccessible(e,i))return ye(e,i.counters);if(i.depth>=i.limits.maxDepth)return he(e,i.limits.maxDepth,i.counters);let t=Object.create(i.scope);r&&Object.assign(t,r);let n=i.child("action:"+e,0,e).withScope(t);return {stored:o,childFrame:n,childScope:t}}_maybeAutoPromote(e){this._requestedMode==="auto"&&++e.invokeCount>=this._threshold&&(e.compiled=this._compileAction(e.definition.id,e.directives),this._mode!=="jit"&&this._promote());}_executeDirectives(e,r){return this._directiveExecutor(e,r,this._handlers,this._directiveHooks,this._typeField,this._engineRef,this._limits.maxDirectives)}async _executeDirectivesAsync(e,r){return this._directiveExecutor(e,r,this._handlers,this._directiveHooks,this._typeField,this._engineRef,this._limits.maxDirectives)}_compileAction(e,r){let i=this._miniGraph.isAsync(e),o=this._miniGraph.isInteractive(e),{fn:t,isAsync:n,isInteractive:a}=ie(r,this._directiveAnalysis,this._typeField,this._asyncHandlerSet,i,o,this._interactiveHandlerSet),d={d:r,h:this._handlers,hooks:this._directiveHooks,engine:this._engineRef,runner:this._directiveRunner,runnerSync:this._directiveRunnerSync};return {fn:t,$:d,isAsync:n,isInteractive:a}}_isAccessible(e,r){let o="action:"+e.slice(0,e.lastIndexOf("/"));return r.path.includes(o)}_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}=ee(this._directiveAnalysis,this._isAsync);return e}_invalidateAndMaybeRecompile(){for(let e of this._registry.values())e.compiled=null;if(this._requestedMode==="jit")for(let[e,r]of this._registry)r.compiled=this._compileAction(e,r.directives);}};function be(s,e){return e?{next:()=>Promise.resolve({value:s,done:true}),return:()=>Promise.resolve({value:s,done:true}),throw:o=>Promise.reject(o),[Symbol.asyncIterator](){return this}}:{next:()=>({value:s,done:true}),return:()=>({value:s,done:true}),throw:i=>{throw i},[Symbol.iterator](){return this}}}function Ve(s,e,r,i,o,t){if(t){let d=s;return {async next(x){let C=await d.next(x);if(C.done){let y=C.value;if(o!==null){let l=o(e,r,y,i);l!==void 0&&(y=l);}return {value:y,done:true}}return {value:C.value,done:false}},async return(){let x=await d.return(void 0),C=x.value;if(x.done&&o!==null){let y=o(e,r,C,i);y!==void 0&&(C=y);}return {value:C,done:true}},async throw(x){let C=await d.throw(x);if(C.done){let y=C.value;if(o!==null){let l=o(e,r,y,i);l!==void 0&&(y=l);}return {value:y,done:true}}return {value:C.value,done:false}},[Symbol.asyncIterator](){return this}}}let n=s;return {next(d){let f=n.next(d);if(f.done){let x=f.value;if(o!==null){let C=o(e,r,x,i);C!==void 0&&(x=C);}return {value:x,done:true}}return {value:f.value,done:false}},return(){let d=n.return(void 0),f=d.value;if(d.done&&o!==null){let x=o(e,r,f,i);x!==void 0&&(f=x);}return {value:f,done:true}},throw(d){let f=n.throw(d);if(f.done){let x=f.value;if(o!==null){let C=o(e,r,x,i);C!==void 0&&(x=C);}return {value:x,done:true}}return {value:f.value,done:false}},[Symbol.iterator](){return this}}}function We(s){return new ae(s)}export{L as RESERVED_TYPES,j as SimpleEmitter,ie as buildActionExecutor,ee as buildDirectiveExecutor,We as createActionEngine,U as createDirectiveInterpreter,Re as drainAsync,Ae as drainSync,N as normalizeDirectives,Ie as replayResponder};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@statedelta-actions/actions",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.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.
|
|
21
|
+
"@statedelta-actions/core": "0.5.0"
|
|
22
22
|
},
|
|
23
23
|
"author": "Anderson D. Rosa <andersondrosa@outlook.com>",
|
|
24
24
|
"license": "MIT",
|