@statedelta-libs/expressions 2.1.0 → 2.3.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 +280 -20
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +164 -14
- package/dist/index.d.ts +164 -14
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
- **Alta performance** - ~25-30M ops/s após compilação
|
|
13
13
|
- **Scope externo** - Funções puras vêm via scope, não hardcoded
|
|
14
14
|
- **Context externo** - HOCs de continuidade via context (`tryCatch`, `transaction`, etc.)
|
|
15
|
+
- **RuntimeCtx unificado** - Contexto de runtime limpo com `{ data, get }`
|
|
15
16
|
- **Accessor customizado** - Suporte a `ctx.get(path)` para objetos especiais
|
|
16
17
|
- **$pipe** - Composição com valor inicial (sintaxe DSL)
|
|
17
18
|
- **$cb** - Callback expressions para HOCs de continuidade
|
|
@@ -19,6 +20,7 @@
|
|
|
19
20
|
- **Dependency extraction** - Para dirty tracking/reatividade
|
|
20
21
|
- **Conditions nativo** - Condicionais integradas com expressions nos lados
|
|
21
22
|
- **normalize()** - Helper externo para custom transforms (`$query`, `$mapper`, etc.)
|
|
23
|
+
- **resolveBoundaries()** - Resolve boundaries customizados (`$simulate`, `$context`, etc.) com compilação independente
|
|
22
24
|
- **Type-safe** - TypeScript nativo com inferência
|
|
23
25
|
|
|
24
26
|
## Instalação
|
|
@@ -322,23 +324,49 @@ HOC de continuidade - executa body dentro de um context function.
|
|
|
322
324
|
|
|
323
325
|
## Context
|
|
324
326
|
|
|
325
|
-
O context define HOCs disponíveis para `$cb`. Diferente de scope (funções puras), context functions controlam a execução do body
|
|
327
|
+
O context define HOCs disponíveis para `$cb`. Diferente de scope (funções puras), context functions controlam a execução do body.
|
|
328
|
+
|
|
329
|
+
### RuntimeCtx
|
|
330
|
+
|
|
331
|
+
O context recebe um `RuntimeCtx` unificado com `{ data, get }`:
|
|
332
|
+
|
|
333
|
+
```typescript
|
|
334
|
+
interface RuntimeCtx<T> {
|
|
335
|
+
data: T; // Dados do runtime
|
|
336
|
+
get: (path: string) => unknown; // Accessor de paths
|
|
337
|
+
}
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
### ContextFn
|
|
326
341
|
|
|
327
342
|
```typescript
|
|
328
|
-
|
|
343
|
+
type ContextFn<T, R> = (
|
|
344
|
+
cb: (ctx: RuntimeCtx<T>) => R, // Body compilado
|
|
345
|
+
ctx: RuntimeCtx<T>, // Contexto de runtime
|
|
346
|
+
params?: unknown // Parâmetros do $cb (opcional)
|
|
347
|
+
) => R;
|
|
348
|
+
```
|
|
329
349
|
|
|
330
|
-
|
|
350
|
+
### Exemplos
|
|
351
|
+
|
|
352
|
+
```typescript
|
|
353
|
+
import type { Context, ContextFn, RuntimeCtx } from '@statedelta-libs/expressions';
|
|
354
|
+
|
|
355
|
+
// tryCatch - captura erros
|
|
356
|
+
const tryCatch: ContextFn = (cb, ctx, params) => {
|
|
331
357
|
try {
|
|
332
|
-
return cb(
|
|
358
|
+
return cb(ctx);
|
|
333
359
|
} catch {
|
|
334
|
-
return params?.fallback ?? null;
|
|
360
|
+
return (params as { fallback?: unknown })?.fallback ?? null;
|
|
335
361
|
}
|
|
336
362
|
};
|
|
337
363
|
|
|
338
|
-
|
|
364
|
+
// transaction - modifica data para o body
|
|
365
|
+
const transaction: ContextFn = (cb, ctx, params) => {
|
|
339
366
|
const tx = db.beginTransaction(params);
|
|
340
367
|
try {
|
|
341
|
-
|
|
368
|
+
// Cria novo ctx com tx no data
|
|
369
|
+
const result = cb({ ...ctx, data: { ...ctx.data, tx } });
|
|
342
370
|
tx.commit();
|
|
343
371
|
return result;
|
|
344
372
|
} catch (e) {
|
|
@@ -347,27 +375,40 @@ const transaction: ContextFn = (cb, data, get, params) => {
|
|
|
347
375
|
}
|
|
348
376
|
};
|
|
349
377
|
|
|
350
|
-
//
|
|
351
|
-
const cached: ContextFn = (cb,
|
|
352
|
-
|
|
353
|
-
|
|
378
|
+
// cached - pode ignorar o cb e retornar outro valor
|
|
379
|
+
const cached: ContextFn = (cb, ctx, params) => {
|
|
380
|
+
const key = (params as { key: string })?.key;
|
|
381
|
+
if (cache.has(key)) {
|
|
382
|
+
return cache.get(key); // Não executa cb
|
|
354
383
|
}
|
|
355
|
-
|
|
384
|
+
const result = cb(ctx);
|
|
385
|
+
cache.set(key, result);
|
|
386
|
+
return result;
|
|
387
|
+
};
|
|
388
|
+
|
|
389
|
+
// simulate - injeta accessor customizado
|
|
390
|
+
const simulate: ContextFn = (cb, ctx, params) => {
|
|
391
|
+
// Cria get que lê de store simulado
|
|
392
|
+
const simulatedGet = (path: string) => store.getSimulated(path);
|
|
393
|
+
// Body usa simulatedGet ao invés do get padrão
|
|
394
|
+
return cb({ ...ctx, get: simulatedGet });
|
|
356
395
|
};
|
|
357
396
|
|
|
358
|
-
const context: Context = { tryCatch, transaction, cached };
|
|
397
|
+
const context: Context = { tryCatch, transaction, cached, simulate };
|
|
359
398
|
|
|
360
399
|
compile(expression, { scope, context });
|
|
361
400
|
```
|
|
362
401
|
|
|
363
|
-
|
|
402
|
+
### O que o Context pode fazer
|
|
364
403
|
|
|
365
|
-
|
|
|
366
|
-
|
|
367
|
-
|
|
|
368
|
-
|
|
|
369
|
-
|
|
|
370
|
-
|
|
|
404
|
+
| Ação | Exemplo |
|
|
405
|
+
|------|---------|
|
|
406
|
+
| **Executar normalmente** | `return cb(ctx)` |
|
|
407
|
+
| **Modificar data** | `return cb({ ...ctx, data: { ...ctx.data, extra } })` |
|
|
408
|
+
| **Injetar accessor** | `return cb({ ...ctx, get: customGet })` |
|
|
409
|
+
| **Ignorar body** | `return cachedValue` (não chama cb) |
|
|
410
|
+
| **Capturar erros** | `try { cb(ctx) } catch { ... }` |
|
|
411
|
+
| **Usar ctx.get** | `const val = ctx.get("user.name")` |
|
|
371
412
|
|
|
372
413
|
## Scope
|
|
373
414
|
|
|
@@ -464,6 +505,156 @@ normalize({ $loop: "test" }, badTransforms);
|
|
|
464
505
|
// Error: Transform "$loop" returned object with same key — infinite loop
|
|
465
506
|
```
|
|
466
507
|
|
|
508
|
+
## Boundaries (resolveBoundaries)
|
|
509
|
+
|
|
510
|
+
Para DSL customizados que precisam de **compilação independente** dos slots internos, use `resolveBoundaries()`. Diferente de `normalize()` (que apenas transforma), boundaries param o fluxo de compilação e delegam para um resolver externo.
|
|
511
|
+
|
|
512
|
+
### Conceito
|
|
513
|
+
|
|
514
|
+
Um **boundary** é um "corpo estranho" no DSL que:
|
|
515
|
+
1. **Para** o fluxo normal de compilação
|
|
516
|
+
2. **Delega** para um resolver customizado
|
|
517
|
+
3. O resolver **compila slots internos** independentemente
|
|
518
|
+
4. **Substitui** por uma referência no scope
|
|
519
|
+
|
|
520
|
+
```
|
|
521
|
+
DSL "rico" DSL puro
|
|
522
|
+
{ $simulate: {...} } → { $fn: "__simulate_0", args: [] }
|
|
523
|
+
+ scope["__simulate_0"] = fn compilada
|
|
524
|
+
```
|
|
525
|
+
|
|
526
|
+
### Uso básico
|
|
527
|
+
|
|
528
|
+
```typescript
|
|
529
|
+
import { resolveBoundaries, compile, type BoundaryResolvers } from '@statedelta-libs/expressions';
|
|
530
|
+
|
|
531
|
+
const resolvers: BoundaryResolvers = {
|
|
532
|
+
$context: (node, { compile: compileFn, genId, scope }) => {
|
|
533
|
+
const id = `__context_${genId()}`;
|
|
534
|
+
const body = (node.$context as { body: Expression }).body;
|
|
535
|
+
|
|
536
|
+
// Compila o body internamente
|
|
537
|
+
const bodyFn = compileFn(body, { scope }).fn;
|
|
538
|
+
|
|
539
|
+
// Retorna função com lifecycle begin/end
|
|
540
|
+
const contextFn = () => (data: unknown) => {
|
|
541
|
+
console.log("begin");
|
|
542
|
+
try {
|
|
543
|
+
return bodyFn(data);
|
|
544
|
+
} finally {
|
|
545
|
+
console.log("end");
|
|
546
|
+
}
|
|
547
|
+
};
|
|
548
|
+
|
|
549
|
+
return {
|
|
550
|
+
expr: { $fn: id, args: [] },
|
|
551
|
+
scopeEntry: [id, contextFn],
|
|
552
|
+
};
|
|
553
|
+
},
|
|
554
|
+
};
|
|
555
|
+
|
|
556
|
+
// 1. Resolve boundaries (extrai e compila internamente)
|
|
557
|
+
const { expr, scope } = resolveBoundaries(
|
|
558
|
+
{ $context: { body: { $fn: "add", args: [{ $: "a" }, { $: "b" }] } } },
|
|
559
|
+
{ resolvers, scope: { add: (a, b) => a + b } }
|
|
560
|
+
);
|
|
561
|
+
|
|
562
|
+
// 2. Compila DSL puro resultante
|
|
563
|
+
const { fn } = compile(expr, { scope });
|
|
564
|
+
|
|
565
|
+
// 3. Executa
|
|
566
|
+
const contextFn = fn({}); // Retorna a função com lifecycle
|
|
567
|
+
const result = contextFn({ a: 1, b: 2 }); // "begin" → 3 → "end"
|
|
568
|
+
```
|
|
569
|
+
|
|
570
|
+
### Caso de uso: $simulate com múltiplos slots
|
|
571
|
+
|
|
572
|
+
```typescript
|
|
573
|
+
interface SimulateNode {
|
|
574
|
+
$simulate: {
|
|
575
|
+
effects: Expression[];
|
|
576
|
+
query: Expression;
|
|
577
|
+
};
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
const resolvers: BoundaryResolvers = {
|
|
581
|
+
$simulate: (node, { compile: compileFn, genId, scope }) => {
|
|
582
|
+
const id = `__simulate_${genId()}`;
|
|
583
|
+
const sim = (node as unknown as SimulateNode).$simulate;
|
|
584
|
+
|
|
585
|
+
// Compila cada slot independentemente
|
|
586
|
+
const effectFns = sim.effects.map((e) => compileFn(e, { scope }).fn);
|
|
587
|
+
const queryFn = compileFn(sim.query, { scope }).fn;
|
|
588
|
+
|
|
589
|
+
// Cria função que orquestra a execução
|
|
590
|
+
const simulateFn = () => (data: unknown) => {
|
|
591
|
+
const effects = effectFns.map((fn) => fn(data));
|
|
592
|
+
const query = queryFn(data);
|
|
593
|
+
return { effects, query };
|
|
594
|
+
};
|
|
595
|
+
|
|
596
|
+
return {
|
|
597
|
+
expr: { $fn: id, args: [] },
|
|
598
|
+
scopeEntry: [id, simulateFn],
|
|
599
|
+
};
|
|
600
|
+
},
|
|
601
|
+
};
|
|
602
|
+
|
|
603
|
+
const { expr, scope } = resolveBoundaries(
|
|
604
|
+
{
|
|
605
|
+
$simulate: {
|
|
606
|
+
effects: [
|
|
607
|
+
{ $fn: "increment", args: [{ $: "hp" }] },
|
|
608
|
+
{ $fn: "decrement", args: [{ $: "mp" }] },
|
|
609
|
+
],
|
|
610
|
+
query: { $fn: "isAlive", args: [{ $: "hp" }] },
|
|
611
|
+
},
|
|
612
|
+
},
|
|
613
|
+
{ resolvers, scope: myScope }
|
|
614
|
+
);
|
|
615
|
+
```
|
|
616
|
+
|
|
617
|
+
### Contexto do resolver
|
|
618
|
+
|
|
619
|
+
O resolver recebe um contexto com:
|
|
620
|
+
|
|
621
|
+
| Propriedade | Tipo | Descrição |
|
|
622
|
+
|-------------|------|-----------|
|
|
623
|
+
| `compile` | `typeof compile` | Mesmo compilador do fluxo principal |
|
|
624
|
+
| `genId` | `() => string` | Gerador de IDs únicos |
|
|
625
|
+
| `scope` | `Scope` | Scope atual (read-only) |
|
|
626
|
+
| `options` | `CompileOptions` | Opções de compilação |
|
|
627
|
+
|
|
628
|
+
### ID Generator customizado
|
|
629
|
+
|
|
630
|
+
Por padrão, IDs são gerados como `"0"`, `"1"`, `"2"`... Para IDs únicos globais, passe um `genId` customizado:
|
|
631
|
+
|
|
632
|
+
```typescript
|
|
633
|
+
import { nanoid } from 'nanoid';
|
|
634
|
+
|
|
635
|
+
const { expr, scope } = resolveBoundaries(expr, {
|
|
636
|
+
resolvers,
|
|
637
|
+
scope: baseScope,
|
|
638
|
+
genId: () => nanoid(), // IDs únicos globais
|
|
639
|
+
});
|
|
640
|
+
```
|
|
641
|
+
|
|
642
|
+
### Diferença entre normalize e resolveBoundaries
|
|
643
|
+
|
|
644
|
+
| | `normalize()` | `resolveBoundaries()` |
|
|
645
|
+
|---|---|---|
|
|
646
|
+
| **Propósito** | Transformar sintaxe | Compilação independente |
|
|
647
|
+
| **Retorno** | `Expression` | `{ expr, scope }` |
|
|
648
|
+
| **Compila slots** | Não | Sim (via `ctx.compile`) |
|
|
649
|
+
| **Acumula scope** | Não | Sim |
|
|
650
|
+
| **Uso típico** | `$query` → `$fn` | `$simulate`, `$context` |
|
|
651
|
+
|
|
652
|
+
Use `normalize()` para sugar syntax simples. Use `resolveBoundaries()` quando precisar:
|
|
653
|
+
- Compilar múltiplos slots independentemente
|
|
654
|
+
- Controlar ordem/momento de execução
|
|
655
|
+
- Adicionar lógica de lifecycle (begin/end, try/finally)
|
|
656
|
+
- DSL completamente diferente internamente
|
|
657
|
+
|
|
467
658
|
## Builders
|
|
468
659
|
|
|
469
660
|
Funções declarativas para construir expressões:
|
|
@@ -516,11 +707,20 @@ import type {
|
|
|
516
707
|
Scope,
|
|
517
708
|
Context,
|
|
518
709
|
ContextFn,
|
|
710
|
+
RuntimeCtx,
|
|
519
711
|
PathGetterFn,
|
|
520
712
|
CompileOptions,
|
|
521
713
|
AccessorFn,
|
|
522
714
|
TransformFn,
|
|
523
715
|
Transforms,
|
|
716
|
+
// Boundaries
|
|
717
|
+
BoundaryResolver,
|
|
718
|
+
BoundaryResolvers,
|
|
719
|
+
ResolverContext,
|
|
720
|
+
ResolverResult,
|
|
721
|
+
ResolveBoundariesOptions,
|
|
722
|
+
ResolveBoundariesResult,
|
|
723
|
+
IdGenerator,
|
|
524
724
|
} from '@statedelta-libs/expressions';
|
|
525
725
|
|
|
526
726
|
// Type guards
|
|
@@ -608,6 +808,66 @@ Funções só são acessíveis se existirem no `scope` fornecido pelo desenvolve
|
|
|
608
808
|
|
|
609
809
|
6. **Novo extractor**: `extractContextFns()`
|
|
610
810
|
|
|
811
|
+
7. **Novo `resolveBoundaries()`**: Para DSL customizados com compilação independente de slots:
|
|
812
|
+
```typescript
|
|
813
|
+
const { expr, scope } = resolveBoundaries(richExpr, {
|
|
814
|
+
resolvers: { $simulate: (node, ctx) => ... },
|
|
815
|
+
scope: baseScope,
|
|
816
|
+
genId: () => nanoid(), // opcional
|
|
817
|
+
});
|
|
818
|
+
compile(expr, { scope });
|
|
819
|
+
```
|
|
820
|
+
|
|
821
|
+
8. **Novos tipos**: `BoundaryResolver`, `BoundaryResolvers`, `ResolverContext`, `ResolverResult`, `ResolveBoundariesOptions`, `ResolveBoundariesResult`, `IdGenerator`
|
|
822
|
+
|
|
823
|
+
### v2.0 → v2.1
|
|
824
|
+
|
|
825
|
+
1. **Nova API do ContextFn**: Agora usa `RuntimeCtx` unificado ao invés de parâmetros separados:
|
|
826
|
+
```typescript
|
|
827
|
+
// Antes (v2.0)
|
|
828
|
+
const tryCatch: ContextFn = (cb, data, get, params) => {
|
|
829
|
+
try {
|
|
830
|
+
return cb(data, get);
|
|
831
|
+
} catch {
|
|
832
|
+
return params?.fallback;
|
|
833
|
+
}
|
|
834
|
+
};
|
|
835
|
+
|
|
836
|
+
// Depois (v2.1)
|
|
837
|
+
const tryCatch: ContextFn = (cb, ctx, params) => {
|
|
838
|
+
try {
|
|
839
|
+
return cb(ctx);
|
|
840
|
+
} catch {
|
|
841
|
+
return params?.fallback;
|
|
842
|
+
}
|
|
843
|
+
};
|
|
844
|
+
```
|
|
845
|
+
|
|
846
|
+
2. **RuntimeCtx**: Novo tipo que agrupa `data` e `get`:
|
|
847
|
+
```typescript
|
|
848
|
+
interface RuntimeCtx<T> {
|
|
849
|
+
data: T;
|
|
850
|
+
get: (path: string) => unknown;
|
|
851
|
+
}
|
|
852
|
+
```
|
|
853
|
+
|
|
854
|
+
3. **Injeção de accessor**: Context pode injetar `get` customizado:
|
|
855
|
+
```typescript
|
|
856
|
+
const simulate: ContextFn = (cb, ctx) => {
|
|
857
|
+
const customGet = (path) => store.getSimulated(path);
|
|
858
|
+
return cb({ ...ctx, get: customGet });
|
|
859
|
+
};
|
|
860
|
+
```
|
|
861
|
+
|
|
862
|
+
4. **Modificar data**: Agora via spread do ctx:
|
|
863
|
+
```typescript
|
|
864
|
+
// Antes
|
|
865
|
+
cb({ ...data, tx }, get)
|
|
866
|
+
|
|
867
|
+
// Depois
|
|
868
|
+
cb({ ...ctx, data: { ...ctx.data, tx } })
|
|
869
|
+
```
|
|
870
|
+
|
|
611
871
|
## Licença
|
|
612
872
|
|
|
613
873
|
MIT © Anderson D. Rosa
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
'use strict';var omniAst=require('omni-ast');var gn=Object.defineProperty;var mn=(n,t)=>{for(var o in t)gn(n,o,{get:t[o],enumerable:true});};var E=n=>n!==null&&typeof n=="object"&&"$"in n&&typeof n.$=="string"&&Object.keys(n).length===1,S=n=>n!==null&&typeof n=="object"&&"$if"in n&&"then"in n,w=n=>n!==null&&typeof n=="object"&&"$fn"in n&&typeof n.$fn=="string",k=n=>n!==null&&typeof n=="object"&&"$pipe"in n&&Array.isArray(n.$pipe),x=n=>n!==null&&typeof n=="object"&&"$cb"in n&&typeof n.$cb=="string"&&"body"in n,v=new Set(["eq","neq","gt","gte","lt","lte","in","notIn","contains","notContains","exists","notExists","matches","notMatches","startsWith","endsWith"]),h=n=>n!==null&&typeof n=="object"&&"left"in n&&"op"in n&&v.has(n.op)&&!("$"in n)&&!("$if"in n)&&!("$fn"in n),b=n=>n!==null&&typeof n=="object"&&"logic"in n&&"conditions"in n,yn=n=>h(n)||b(n),B=n=>{if(n===null)return true;let t=typeof n;if(t==="string"||t==="number"||t==="boolean"||Array.isArray(n))return true;if(t==="object"&&n!==null){let o=n,r="left"in o&&"op"in o&&v.has(o.op);return !("$"in o)&&!("$if"in o)&&!("$fn"in o)&&!("$pipe"in o)&&!("$cb"in o)&&!r&&!("logic"in o)}return false};var G=new Map;function Q(n){let t=[],o=n.length,r=0,i="";for(;r<o;){let s=n[r];if(s===".")i&&(t.push({type:"key",value:i}),i=""),r++;else if(s==="["){i&&(t.push({type:"key",value:i}),i=""),r++;let e=r;for(;r<o&&n[r]!=="]";)r++;let f=n.slice(e,r);if(r++,f==="*")t.push({type:"wildcard",value:"*"});else {let u=parseInt(f,10);t.push({type:"index",value:isNaN(u)?f:u});}}else i+=s,r++;}return i&&t.push({type:"key",value:i}),t}function U(n){return n.includes("[*]")}function j(n){let t=G.get(n);return t||(t=U(n)?hn(n):En(n),G.set(n,t),t)}function En(n){if(!n.includes(".")&&!n.includes("["))return i=>i?.[n];let t=Q(n),o=t.length;if(o===2){let[i,s]=t,e=i.value,f=s.value;return u=>u?.[e]?.[f]}if(o===3){let[i,s,e]=t,f=i.value,u=s.value,a=e.value;return l=>l?.[f]?.[u]?.[a]}let r=t.map(i=>i.value);return i=>{let s=i;for(let e=0;e<o&&s!=null;e++)s=s[r[e]];return s}}function hn(n){let t=Q(n),o=[];for(let r=0;r<t.length;r++)t[r].type==="wildcard"&&o.push(r);return o.length===1?bn(t,o[0]):Cn(t,o)}function bn(n,t){let o=n.slice(0,t).map(e=>e.value),r=n.slice(t+1).map(e=>e.value),i=o.length,s=r.length;if(s===0){if(i===1){let e=o[0];return f=>f?.[e]}return e=>{let f=e;for(let u=0;u<i&&f!=null;u++)f=f[o[u]];return f}}if(s===1){let e=r[0];if(i===1){let f=o[0];return u=>{let a=u?.[f];if(Array.isArray(a))return a.map(l=>l?.[e])}}return f=>{let u=f;for(let a=0;a<i&&u!=null;a++)u=u[o[a]];if(Array.isArray(u))return u.map(a=>a?.[e])}}return e=>{let f=e;for(let u=0;u<i&&f!=null;u++)f=f[o[u]];if(Array.isArray(f))return f.map(u=>{let a=u;for(let l=0;l<s&&a!=null;l++)a=a[r[l]];return a})}}function Cn(n,t){let o=[],r=0;for(let s=0;s<t.length;s++){let e=t[s],f=s===t.length-1,u=n.slice(r,e).map(a=>a.value);u.length>0&&o.push({type:"access",keys:u}),o.push({type:f?"map":"flatMap",keys:[]}),r=e+1;}let i=n.slice(r).map(s=>s.value);return s=>{let e=s;for(let f of o){if(e==null)return;if(f.type==="access")for(let u of f.keys){if(e==null)return;e=e[u];}else if(f.type==="flatMap"){if(!Array.isArray(e))return;e=e.flatMap(u=>{let a=u;return Array.isArray(a)?a:[a]});}else if(f.type==="map"){if(!Array.isArray(e))return;i.length>0&&(e=e.map(u=>{let a=u;for(let l of i){if(a==null)return;a=a[l];}return a}));}}return e}}function Tn(n,t){return j(t)(n)}function W(n){let t=n.indexOf("[*]");return t===-1?n:n.slice(0,t)}function $n(){G.clear();}function An(){return G.size}function R(n){let t=new Set;return C(n,t),Array.from(t)}function C(n,t){if(n===null||typeof n!="object")return;if(Array.isArray(n)){for(let i=0;i<n.length;i++)C(n[i],t);return}if(E(n)){t.add(W(n.$));return}if(S(n)){if(typeof n.$if=="string"){let i=n.$if.startsWith("!")?n.$if.slice(1):n.$if;t.add(W(i));}else C(n.$if,t);C(n.then,t),n.else!==void 0&&C(n.else,t);return}if(k(n)){for(let i=0;i<n.$pipe.length;i++)C(n.$pipe[i],t);return}if(w(n)){if(n.args)for(let i=0;i<n.args.length;i++)C(n.args[i],t);return}if(x(n)){C(n.body,t),n.params!==void 0&&C(n.params,t);return}if(h(n)){C(n.left,t),n.right!==void 0&&C(n.right,t);return}if(b(n)){for(let i=0;i<n.conditions.length;i++)C(n.conditions[i],t);return}let o=n,r=Object.keys(o);for(let i=0;i<r.length;i++)C(o[r[i]],t);}function Sn(n){return R(n).length>0}function wn(n){return R(n).length===0}function kn(n){return JSON.stringify(n)}function z(n,t={}){let o=t.scope??{},r=t.accessor,i=t.context??{},s=y(n,o,r,i),e=R(n),f=kn(n);return {fn:s,deps:e,hash:f}}function y(n,t,o,r){if(n===null)return ()=>null;if(typeof n!="object")return ()=>n;if(Array.isArray(n)){let i=n.map(s=>y(s,t,o,r));return s=>i.map(e=>e(s))}if(E(n))return xn(n,o);if(S(n))return Fn(n,t,o,r);if(k(n))return Rn(n,t,o,r);if(w(n))return On(n,t,o,r);if(x(n))return Nn(n,t,o,r);if(h(n))return jn(n,t,o,r);if(b(n))return vn(n,t,o,r);if(B(n)){let i=n,s=Object.keys(i),e=s.map(f=>y(i[f],t,o,r));return f=>{let u={};for(let a=0;a<s.length;a++)u[s[a]]=e[a](f);return u}}return ()=>n}function Z(n,t){return t?o=>t(n,o):j(n)}function xn(n,t){return Z(n.$,t)}function Fn(n,t,o,r){let i;if(typeof n.$if=="string"){let f=n.$if.startsWith("!")?n.$if.slice(1):n.$if,u=Z(f,o);i=n.$if.startsWith("!")?l=>!u(l):l=>!!u(l);}else {let f=y(n.$if,t,o,r);i=u=>!!f(u);}let s=y(n.then,t,o,r),e=n.else!==void 0?y(n.else,t,o,r):()=>{};return f=>i(f)?s(f):e(f)}function Rn(n,t,o,r){let i=n.$pipe;if(i.length===0)return ()=>{};if(i.length===1)return y(i[0],t,o,r);let s=y(i[0],t,o,r),e=i.slice(1).map(u=>y(u,t,o,r)),f=e.length;if(f===1){let[u]=e;return a=>{let l=s(a),p=u(a);return typeof p=="function"?p(l):p}}if(f===2){let[u,a]=e;return l=>{let p=s(l),d=u(l);return p=typeof d=="function"?d(p):d,d=a(l),typeof d=="function"?d(p):d}}if(f===3){let[u,a,l]=e;return p=>{let d=s(p),g=u(p);return d=typeof g=="function"?g(d):g,g=a(p),d=typeof g=="function"?g(d):g,g=l(p),typeof g=="function"?g(d):g}}return u=>{let a=s(u);for(let l=0;l<f;l++){let p=e[l](u);a=typeof p=="function"?p(a):p;}return a}}function On(n,t,o,r){let i=n.$fn,s=n.args;if(s===void 0)return ()=>{let u=t[i];if(!u)throw new Error(`Function not found in scope: ${i}`);return u};let e=s.map(u=>y(u,t,o,r)),f=e.length;if(f===0)return ()=>{let u=t[i];if(!u)throw new Error(`Function not found in scope: ${i}`);return u()};if(f===1){let[u]=e;return a=>{let l=t[i];if(!l)throw new Error(`Function not found in scope: ${i}`);return l(u(a))}}if(f===2){let[u,a]=e;return l=>{let p=t[i];if(!p)throw new Error(`Function not found in scope: ${i}`);return p(u(l),a(l))}}if(f===3){let[u,a,l]=e;return p=>{let d=t[i];if(!d)throw new Error(`Function not found in scope: ${i}`);return d(u(p),a(p),l(p))}}return u=>{let a=t[i];if(!a)throw new Error(`Function not found in scope: ${i}`);return a(...e.map(l=>l(u)))}}function Nn(n,t,o,r){let i=n.$cb,s=y(n.body,t,o,r),e=n.params?y(n.params,t,o,r):void 0,f=u=>o?a=>o(a,u):a=>j(a)(u);return u=>{let a=r?.[i];if(!a)throw new Error(`Context function not found: ${i}`);let l=(g,F)=>s(g),p=f(u),d=e?e(u):void 0;return a(l,u,p,d)}}function jn(n,t,o,r){let i=y(n.left,t,o,r),s=n.right!==void 0?y(n.right,t,o,r):()=>{};switch(n.op){case "eq":return e=>i(e)===s(e);case "neq":return e=>i(e)!==s(e);case "gt":return e=>i(e)>s(e);case "gte":return e=>i(e)>=s(e);case "lt":return e=>i(e)<s(e);case "lte":return e=>i(e)<=s(e);case "in":return e=>{let f=s(e);return Array.isArray(f)&&f.includes(i(e))};case "notIn":return e=>{let f=s(e);return !Array.isArray(f)||!f.includes(i(e))};case "contains":return e=>{let f=i(e);return Array.isArray(f)&&f.includes(s(e))};case "notContains":return e=>{let f=i(e);return !Array.isArray(f)||!f.includes(s(e))};case "exists":return e=>i(e)!==void 0;case "notExists":return e=>i(e)===void 0;case "matches":return e=>{let f=i(e),u=s(e);return typeof f!="string"||typeof u!="string"?false:new RegExp(u).test(f)};case "notMatches":return e=>{let f=i(e),u=s(e);return typeof f!="string"||typeof u!="string"?true:!new RegExp(u).test(f)};case "startsWith":return e=>{let f=i(e),u=s(e);return typeof f=="string"&&typeof u=="string"&&f.startsWith(u)};case "endsWith":return e=>{let f=i(e),u=s(e);return typeof f=="string"&&typeof u=="string"&&f.endsWith(u)}}}function vn(n,t,o,r){let i=n.conditions.map(e=>y(e,t,o,r)),s=i.length;if(s===1)return e=>!!i[0](e);if(s===2){let[e,f]=i;return n.logic==="AND"?u=>!!e(u)&&!!f(u):u=>!!e(u)||!!f(u)}if(s===3){let[e,f,u]=i;return n.logic==="AND"?a=>!!e(a)&&!!f(a)&&!!u(a):a=>!!e(a)||!!f(a)||!!u(a)}return n.logic==="AND"?e=>{for(let f=0;f<s;f++)if(!i[f](e))return false;return true}:e=>{for(let f=0;f<s;f++)if(i[f](e))return true;return false}}function Gn(n,t,o={}){return z(n,o).fn(t)}var D=class{constructor(t=1e3){this.cache=new Map,this._maxSize=t;}get(t,o={}){let r=JSON.stringify(t),i=this.cache.get(r);if(i)return this.cache.delete(r),this.cache.set(r,i),i;let s=z(t,o);if(this.cache.size>=this._maxSize){let e=this.cache.keys().next().value;e&&this.cache.delete(e);}return this.cache.set(r,s),s}has(t){return this.cache.has(JSON.stringify(t))}delete(t){return this.cache.delete(JSON.stringify(t))}clear(){this.cache.clear();}get size(){return this.cache.size}get maxSize(){return this._maxSize}set maxSize(t){for(this._maxSize=t;this.cache.size>this._maxSize;){let o=this.cache.keys().next().value;o&&this.cache.delete(o);}}},P=new D;function Wn(n,t={}){return P.get(n,t)}function J(n,t="root",o={}){let r=[];return T(n,t,r,o),{valid:r.length===0,errors:r}}function T(n,t,o,r){if(n===null||typeof n!="object")return;if(Array.isArray(n)){for(let e=0;e<n.length;e++)T(n[e],`${t}[${e}]`,o,r);return}if(E(n)){(!n.$||typeof n.$!="string")&&o.push(`${t}: invalid reference, $ must be non-empty string`);return}if(S(n)){typeof n.$if=="string"?(n.$if.startsWith("!")?n.$if.slice(1):n.$if)||o.push(`${t}.$if: empty path in string shorthand`):T(n.$if,`${t}.$if`,o,r),T(n.then,`${t}.then`,o,r),n.else!==void 0&&T(n.else,`${t}.else`,o,r);return}if(k(n)){if(!Array.isArray(n.$pipe)){o.push(`${t}.$pipe: must be an array`);return}if(n.$pipe.length===0){o.push(`${t}.$pipe: must have at least one element`);return}for(let e=0;e<n.$pipe.length;e++)T(n.$pipe[e],`${t}.$pipe[${e}]`,o,r);return}if(w(n)){if(!n.$fn||typeof n.$fn!="string"){o.push(`${t}: invalid function, $fn must be non-empty string`);return}if(r.scope&&!(n.$fn in r.scope)&&o.push(`${t}: function "${n.$fn}" not found in scope`),n.args!==void 0)if(!Array.isArray(n.args))o.push(`${t}.args: must be an array`);else for(let e=0;e<n.args.length;e++)T(n.args[e],`${t}.args[${e}]`,o,r);return}if(x(n)){if(!n.$cb||typeof n.$cb!="string"){o.push(`${t}: invalid callback, $cb must be non-empty string`);return}r.context&&!(n.$cb in r.context)&&o.push(`${t}: context function "${n.$cb}" not found`),T(n.body,`${t}.body`,o,r),n.params!==void 0&&T(n.params,`${t}.params`,o,r);return}if(h(n)){v.has(n.op)||o.push(`${t}: invalid operator "${n.op}"`),T(n.left,`${t}.left`,o,r),n.right!==void 0&&T(n.right,`${t}.right`,o,r);return}if(b(n)){if(n.logic!=="AND"&&n.logic!=="OR"&&o.push(`${t}: invalid logic "${n.logic}", must be "AND" or "OR"`),!Array.isArray(n.conditions)){o.push(`${t}.conditions: must be an array`);return}for(let e=0;e<n.conditions.length;e++)T(n.conditions[e],`${t}.conditions[${e}]`,o,r);return}let i=n,s=Object.keys(i);for(let e=0;e<s.length;e++){let f=s[e];T(i[f],`${t}.${f}`,o,r);}}function zn(n,t={}){let o=J(n,"root",t);if(!o.valid)throw new Error(`Invalid expression: ${o.errors.join("; ")}`)}function Dn(n,t={}){return J(n,"root",t).valid}var sn={};mn(sn,{$:()=>nn,$cb:()=>rn,$cond:()=>on,$fn:()=>tn,$if:()=>_n,$pipe:()=>en,cb:()=>qn,cond:()=>Ln,fn:()=>In,pipe:()=>Vn,ref:()=>Mn});function nn(n){return {$:n}}var Mn=nn;function tn(n,t){return t===void 0||t.length===0?{$fn:n}:{$fn:n,args:t}}var In=tn;function _n(n,t,o){return o===void 0?{$if:n,then:t}:{$if:n,then:t,else:o}}function en(...n){return {$pipe:n}}var Vn=en;function on(n,t,o){return o===void 0?{left:n,op:t}:{left:n,op:t,right:o}}var Ln=on;function rn(n,t,o){return o===void 0?{$cb:n,body:t}:{$cb:n,body:t,params:o}}var qn=rn;var K="data",un="scope",Bn={eq:"===",neq:"!==",gt:">",gte:">=",lt:"<",lte:"<="};function I(n,t={}){let{dataParam:o=K,scopeParam:r=un,noPrefixes:i=false,useAccessor:s=false,lexicalPrefix:e}=t;return m(n,o,r,i,s,e)}function m(n,t,o,r,i,s){if(n===null)return omniAst.builders.literal(null);if(typeof n=="string")return omniAst.builders.literal(n);if(typeof n=="number")return omniAst.builders.literal(n);if(typeof n=="boolean")return omniAst.builders.literal(n);if(Array.isArray(n))return omniAst.builders.arrayExpression(n.map(e=>m(e,t,o,r,i,s)));if(E(n))return Jn(n.$,t,r,i,s);if(S(n))return Xn(n,t,o,r,i,s);if(k(n))return Un(n.$pipe,t,o,r,i,s);if(w(n))return Yn(n,t,o,r,i,s);if(x(n))return Qn(n,t,o,r,i,s);if(h(n))return Zn(n,t,o,r,i,s);if(b(n))return Pn(n,t,o,r,i,s);if(typeof n=="object"){let f=Object.entries(n).map(([u,a])=>omniAst.builders.property(omniAst.builders.identifier(u),m(a,t,o,r,i,s)));return omniAst.builders.objectExpression(f)}return omniAst.builders.literal(null)}var X="accessor";function Y(n,t){return t?n===t||n.startsWith(t+"."):false}function Jn(n,t,o,r,i){return r?Y(n,i)?O(n,t,true):omniAst.builders.callExpression(omniAst.builders.identifier(X),[omniAst.builders.literal(n),omniAst.builders.identifier(t)]):n.includes("[*]")?Kn(n,t,o):O(n,t,o)}function O(n,t,o){let r=M(n);if(r.length===0)return o?omniAst.builders.identifier("undefined"):omniAst.builders.identifier(t);let i;if(o){let s=r[0];i=omniAst.builders.identifier(s.value);for(let e=1;e<r.length;e++){let f=r[e];f.type==="key"?i=omniAst.builders.memberExpression(i,omniAst.builders.identifier(f.value),false,true):i=omniAst.builders.memberExpression(i,omniAst.builders.literal(f.value),true,true);}}else {i=omniAst.builders.identifier(t);for(let s of r)s.type==="key"?i=omniAst.builders.memberExpression(i,omniAst.builders.identifier(s.value),false,true):i=omniAst.builders.memberExpression(i,omniAst.builders.literal(s.value),true,true);}return i}function Kn(n,t,o){let r=n.indexOf("[*]"),i=n.slice(0,r),s=n.slice(r+3),e;if(i?e=O(i,t,o):e=o?omniAst.builders.identifier("undefined"):omniAst.builders.identifier(t),!s||s==="")return e;if(s.includes("[*]"))return cn(e,s);let f="_i",u=s.startsWith(".")?s.slice(1):s,a=omniAst.builders.identifier(f);if(u){let l=M(u);for(let p of l)p.type==="key"?a=omniAst.builders.memberExpression(a,omniAst.builders.identifier(p.value),false,true):a=omniAst.builders.memberExpression(a,omniAst.builders.literal(p.value),true,true);}return omniAst.builders.callExpression(omniAst.builders.memberExpression(e,omniAst.builders.identifier("map"),false,true),[omniAst.builders.arrowFunctionExpression([omniAst.builders.identifier(f)],a)])}function cn(n,t){let o=t.indexOf("[*]"),r=t.slice(0,o),i=t.slice(o+3),s="_i",e=r.startsWith(".")?r.slice(1):r,f=omniAst.builders.identifier(s);if(e){let a=M(e);for(let l of a)l.type==="key"&&(f=omniAst.builders.memberExpression(f,omniAst.builders.identifier(l.value),false,true));}if(i.includes("[*]")){let a=cn(f,i);return omniAst.builders.callExpression(omniAst.builders.memberExpression(n,omniAst.builders.identifier("flatMap"),false,true),[omniAst.builders.arrowFunctionExpression([omniAst.builders.identifier(s)],a)])}let u=i.startsWith(".")?i.slice(1):i;if(u){let a=M(u);for(let l of a)l.type==="key"&&(f=omniAst.builders.memberExpression(f,omniAst.builders.identifier(l.value),false,true));}return omniAst.builders.callExpression(omniAst.builders.memberExpression(n,omniAst.builders.identifier("flatMap"),false,true),[omniAst.builders.arrowFunctionExpression([omniAst.builders.identifier(s)],f)])}function Xn(n,t,o,r,i,s){let e;if(typeof n.$if=="string"){let a=n.$if.startsWith("!"),l=a?n.$if.slice(1):n.$if,p;i?Y(l,s)?p=O(l,t,true):p=omniAst.builders.callExpression(omniAst.builders.identifier(X),[omniAst.builders.literal(l),omniAst.builders.identifier(t)]):p=O(l,t,r),e=a?omniAst.builders.unaryExpression("!",p):p;}else e=m(n.$if,t,o,r,i,s);let f=m(n.then,t,o,r,i,s),u=n.else!==void 0?m(n.else,t,o,r,i,s):omniAst.builders.identifier("undefined");return omniAst.builders.conditionalExpression(e,f,u)}function Yn(n,t,o,r,i,s){let e=r?omniAst.builders.identifier(n.$fn):omniAst.builders.memberExpression(omniAst.builders.identifier(o),omniAst.builders.identifier(n.$fn),false,false);if(n.args===void 0)return e;let f=n.args.map(u=>m(u,t,o,r,i,s));return omniAst.builders.callExpression(e,f)}var Hn="context";function Qn(n,t,o,r,i,s){let e=r?omniAst.builders.identifier(n.$cb):omniAst.builders.memberExpression(omniAst.builders.identifier(Hn),omniAst.builders.identifier(n.$cb),false,false),f=m(n.body,t,o,r,i,s),a=[omniAst.builders.arrowFunctionExpression([omniAst.builders.identifier(t),omniAst.builders.identifier("get")],f),omniAst.builders.identifier(t),omniAst.builders.identifier("get")];if(n.params!==void 0){let l=m(n.params,t,o,r,i,s);a.push(l);}return omniAst.builders.callExpression(e,a)}function Un(n,t,o,r,i,s){if(n.length===0)return omniAst.builders.identifier("undefined");if(n.length===1)return m(n[0],t,o,r,i,s);let e=m(n[0],t,o,r,i,s);for(let f=1;f<n.length;f++){let u=m(n[f],t,o,r,i,s);e=omniAst.builders.callExpression(u,[e]);}return e}function fn(n,t,o,r,i,s){if(E(n)){let e=n.$;return i?Y(e,s)?O(e,t,true):omniAst.builders.callExpression(omniAst.builders.identifier(X),[omniAst.builders.literal(e),omniAst.builders.identifier(t)]):O(e,t,r)}return m(n,t,o,r,i,s)}function Zn(n,t,o,r,i,s){let e=fn(n.left,t,o,r,i,s),f=n.right!==void 0?fn(n.right,t,o,r,i,s):omniAst.builders.literal(null),u=Bn[n.op];if(u)return omniAst.builders.binaryExpression(u,e,f);switch(n.op){case "in":return omniAst.builders.callExpression(omniAst.builders.memberExpression(f,omniAst.builders.identifier("includes")),[e]);case "notIn":return omniAst.builders.unaryExpression("!",omniAst.builders.callExpression(omniAst.builders.memberExpression(f,omniAst.builders.identifier("includes")),[e]));case "contains":return omniAst.builders.callExpression(omniAst.builders.memberExpression(e,omniAst.builders.identifier("includes"),false,true),[f]);case "notContains":return omniAst.builders.unaryExpression("!",omniAst.builders.callExpression(omniAst.builders.memberExpression(e,omniAst.builders.identifier("includes"),false,true),[f]));case "exists":return omniAst.builders.binaryExpression("!=",e,omniAst.builders.literal(null));case "notExists":return omniAst.builders.binaryExpression("==",e,omniAst.builders.literal(null));case "matches":return omniAst.builders.callExpression(omniAst.builders.memberExpression(omniAst.builders.newExpression(omniAst.builders.identifier("RegExp"),[f]),omniAst.builders.identifier("test")),[e]);case "notMatches":return omniAst.builders.unaryExpression("!",omniAst.builders.callExpression(omniAst.builders.memberExpression(omniAst.builders.newExpression(omniAst.builders.identifier("RegExp"),[f]),omniAst.builders.identifier("test")),[e]));case "startsWith":return omniAst.builders.callExpression(omniAst.builders.memberExpression(e,omniAst.builders.identifier("startsWith"),false,true),[f]);case "endsWith":return omniAst.builders.callExpression(omniAst.builders.memberExpression(e,omniAst.builders.identifier("endsWith"),false,true),[f]);default:return omniAst.builders.binaryExpression("===",e,f)}}function Pn(n,t,o,r,i,s){let{logic:e,conditions:f}=n,u=e==="AND"?"&&":"||";if(f.length===0)return omniAst.builders.literal(e==="AND");if(f.length===1)return m(f[0],t,o,r,i,s);let a=m(f[0],t,o,r,i,s);for(let l=1;l<f.length;l++){let p=m(f[l],t,o,r,i,s);a=omniAst.builders.logicalExpression(u,a,p);}return a}function M(n){let t=[],o=n.length,r=0,i="";for(;r<o;){let s=n[r];if(s===".")i&&(t.push({type:"key",value:i}),i=""),r++;else if(s==="["){i&&(t.push({type:"key",value:i}),i=""),r++;let e=r;for(;r<o&&n[r]!=="]";)r++;let f=n.slice(e,r);if(r++,f!=="*"){let u=parseInt(f,10);t.push({type:"index",value:isNaN(u)?f:u});}}else i+=s,r++;}return i&&t.push({type:"key",value:i}),t}function an(n,t=[K]){return omniAst.builders.arrowFunctionExpression(t.map(o=>omniAst.builders.identifier(o)),n)}function _(n){let t=new Set;return $(n,t),t}function $(n,t){if(n===null||typeof n!="object")return;if(Array.isArray(n)){for(let r of n)$(r,t);return}if(E(n))return;if(S(n)){$(n.$if,t),$(n.then,t),n.else!==void 0&&$(n.else,t);return}if(k(n)){for(let r of n.$pipe)$(r,t);return}if(w(n)){if(t.add(n.$fn),n.args)for(let r of n.args)$(r,t);return}if(x(n)){$(n.body,t),n.params!==void 0&&$(n.params,t);return}if(h(n)){n.left!==void 0&&typeof n.left=="object"&&$(n.left,t),n.right!==void 0&&typeof n.right=="object"&&$(n.right,t);return}if(b(n)){for(let r of n.conditions)$(r,t);return}let o=n;for(let r of Object.keys(o))$(o[r],t);}function V(n){let t=new Set;return A(n,t),t}function A(n,t){if(n===null||typeof n!="object")return;if(Array.isArray(n)){for(let r of n)A(r,t);return}if(E(n))return;if(S(n)){A(n.$if,t),A(n.then,t),n.else!==void 0&&A(n.else,t);return}if(k(n)){for(let r of n.$pipe)A(r,t);return}if(w(n)){if(n.args)for(let r of n.args)A(r,t);return}if(x(n)){t.add(n.$cb),A(n.body,t),n.params!==void 0&&A(n.params,t);return}if(h(n)){n.left!==void 0&&typeof n.left=="object"&&A(n.left,t),n.right!==void 0&&typeof n.right=="object"&&A(n.right,t);return}if(b(n)){for(let r of n.conditions)A(r,t);return}let o=n;for(let r of Object.keys(o))A(o[r],t);}function L(n){let t=new Set;for(let o of n){let r=o.indexOf("."),i=o.indexOf("["),s=o.length;r!==-1&&(s=Math.min(s,r)),i!==-1&&(s=Math.min(s,i));let e=o.slice(0,s);e&&t.add(e);}return t}function tt(n){return JSON.stringify(n)}function et(n,t,o,r,i,s){let e=I(n,{noPrefixes:true,useAccessor:i,lexicalPrefix:s}),f=omniAst.generate(e),u="";i?s&&(u=`const{${s}}=data??{};`):t.size>0&&(u=`const{${[...t].join(",")}}=data??{};`);let a=i?new Set([...o,"accessor"]):o,l=a.size>0?`const{${[...a].join(",")}}=scope;`:"",p=r.size>0?`const{${[...r].join(",")}}=context;`:"",d=r.size>0,g="";d&&(i?g="const get=(path)=>accessor(path,data);":g="const get=(path)=>path.split('.').reduce((o,k)=>o?.[k],data);");let F=a.size>0,N;if(F||d){let pn=d?"scope,context":"scope",dn=`${u}${g}return ${f}`;N=`(function(${pn}){${l}${p}return function(data){${dn}}})`;}else N=`(function(){return function(data){${u}return ${f}}})`;return N}function H(n,t={}){let{scope:o={},context:r={},returnCode:i=false,useAccessor:s=false,lexicalPrefix:e}=t,f=R(n),u=L(f),a=_(n),l=V(n),p=tt(n),d=et(n,u,a,l,s,e);if(i)return {code:d,deps:f,hash:p,dataRoots:[...u],scopeFns:[...a],contextFns:[...l]};let g;try{let F=l.size>0,N=new Function(`return ${d}`)();g=F?N(o,r):N(o);}catch(F){throw new Error(`AST compilation failed. If this is due to CSP, use the standard compile() function instead. Error: ${F instanceof Error?F.message:String(F)}`)}return {fn:g,deps:f,hash:p}}function ln(n,t,o={}){let{fn:r}=H(n,o);return r(t)}function it(n,t){return q(n,t)}function q(n,t){if(n===null)return null;if(typeof n!="object")return n;if(Array.isArray(n))return n.map(s=>q(s,t));let o=n,r=Object.keys(o);for(let s of r)if(s in t){let e=t[s](o);if(typeof e=="object"&&e!==null&&s in e)throw new Error(`Transform "${s}" returned object with same key \u2014 infinite loop`);return q(e,t)}let i={};for(let s of r)i[s]=q(o[s],t);return i}var vt="2.0.0";exports.ExpressionCache=D;exports.VERSION=vt;exports.assertValid=zn;exports.builders=sn;exports.cache=P;exports.cached=Wn;exports.clearPathCache=$n;exports.compile=z;exports.compileAST=H;exports.compilePath=j;exports.dslToAST=I;exports.evaluate=Gn;exports.evaluateAST=ln;exports.extractContextFns=V;exports.extractDataRoots=L;exports.extractDeps=R;exports.extractScopeFns=_;exports.get=Tn;exports.getPathCacheSize=An;exports.hasDeps=Sn;exports.hasWildcard=U;exports.isCb=x;exports.isCondition=h;exports.isConditionExpr=yn;exports.isConditionGroup=b;exports.isConditional=S;exports.isFn=w;exports.isLiteral=B;exports.isPipe=k;exports.isPure=wn;exports.isRef=E;exports.isValid=Dn;exports.normalize=it;exports.normalizePath=W;exports.validate=J;exports.wrapInFunction=an;
|
|
1
|
+
'use strict';var omniAst=require('omni-ast');var yn=Object.defineProperty;var En=(n,t)=>{for(var o in t)yn(n,o,{get:t[o],enumerable:true});};var E=n=>n!==null&&typeof n=="object"&&"$"in n&&typeof n.$=="string"&&Object.keys(n).length===1,x=n=>n!==null&&typeof n=="object"&&"$if"in n&&"then"in n,S=n=>n!==null&&typeof n=="object"&&"$fn"in n&&typeof n.$fn=="string",R=n=>n!==null&&typeof n=="object"&&"$pipe"in n&&Array.isArray(n.$pipe),k=n=>n!==null&&typeof n=="object"&&"$cb"in n&&typeof n.$cb=="string"&&"body"in n,I=new Set(["eq","neq","gt","gte","lt","lte","in","notIn","contains","notContains","exists","notExists","matches","notMatches","startsWith","endsWith"]),h=n=>n!==null&&typeof n=="object"&&"left"in n&&"op"in n&&I.has(n.op)&&!("$"in n)&&!("$if"in n)&&!("$fn"in n),b=n=>n!==null&&typeof n=="object"&&"logic"in n&&"conditions"in n,hn=n=>h(n)||b(n),J=n=>{if(n===null)return true;let t=typeof n;if(t==="string"||t==="number"||t==="boolean"||Array.isArray(n))return true;if(t==="object"&&n!==null){let o=n,r="left"in o&&"op"in o&&I.has(o.op);return !("$"in o)&&!("$if"in o)&&!("$fn"in o)&&!("$pipe"in o)&&!("$cb"in o)&&!r&&!("logic"in o)}return false};var W=new Map;function U(n){let t=[],o=n.length,r=0,i="";for(;r<o;){let s=n[r];if(s===".")i&&(t.push({type:"key",value:i}),i=""),r++;else if(s==="["){i&&(t.push({type:"key",value:i}),i=""),r++;let e=r;for(;r<o&&n[r]!=="]";)r++;let u=n.slice(e,r);if(r++,u==="*")t.push({type:"wildcard",value:"*"});else {let f=parseInt(u,10);t.push({type:"index",value:isNaN(f)?u:f});}}else i+=s,r++;}return i&&t.push({type:"key",value:i}),t}function Z(n){return n.includes("[*]")}function j(n){let t=W.get(n);return t||(t=Z(n)?Cn(n):bn(n),W.set(n,t),t)}function bn(n){if(!n.includes(".")&&!n.includes("["))return i=>i?.[n];let t=U(n),o=t.length;if(o===2){let[i,s]=t,e=i.value,u=s.value;return f=>f?.[e]?.[u]}if(o===3){let[i,s,e]=t,u=i.value,f=s.value,l=e.value;return a=>a?.[u]?.[f]?.[l]}let r=t.map(i=>i.value);return i=>{let s=i;for(let e=0;e<o&&s!=null;e++)s=s[r[e]];return s}}function Cn(n){let t=U(n),o=[];for(let r=0;r<t.length;r++)t[r].type==="wildcard"&&o.push(r);return o.length===1?Tn(t,o[0]):$n(t,o)}function Tn(n,t){let o=n.slice(0,t).map(e=>e.value),r=n.slice(t+1).map(e=>e.value),i=o.length,s=r.length;if(s===0){if(i===1){let e=o[0];return u=>u?.[e]}return e=>{let u=e;for(let f=0;f<i&&u!=null;f++)u=u[o[f]];return u}}if(s===1){let e=r[0];if(i===1){let u=o[0];return f=>{let l=f?.[u];if(Array.isArray(l))return l.map(a=>a?.[e])}}return u=>{let f=u;for(let l=0;l<i&&f!=null;l++)f=f[o[l]];if(Array.isArray(f))return f.map(l=>l?.[e])}}return e=>{let u=e;for(let f=0;f<i&&u!=null;f++)u=u[o[f]];if(Array.isArray(u))return u.map(f=>{let l=f;for(let a=0;a<s&&l!=null;a++)l=l[r[a]];return l})}}function $n(n,t){let o=[],r=0;for(let s=0;s<t.length;s++){let e=t[s],u=s===t.length-1,f=n.slice(r,e).map(l=>l.value);f.length>0&&o.push({type:"access",keys:f}),o.push({type:u?"map":"flatMap",keys:[]}),r=e+1;}let i=n.slice(r).map(s=>s.value);return s=>{let e=s;for(let u of o){if(e==null)return;if(u.type==="access")for(let f of u.keys){if(e==null)return;e=e[f];}else if(u.type==="flatMap"){if(!Array.isArray(e))return;e=e.flatMap(f=>{let l=f;return Array.isArray(l)?l:[l]});}else if(u.type==="map"){if(!Array.isArray(e))return;i.length>0&&(e=e.map(f=>{let l=f;for(let a of i){if(l==null)return;l=l[a];}return l}));}}return e}}function An(n,t){return j(t)(n)}function z(n){let t=n.indexOf("[*]");return t===-1?n:n.slice(0,t)}function xn(){W.clear();}function Sn(){return W.size}function O(n){let t=new Set;return C(n,t),Array.from(t)}function C(n,t){if(n===null||typeof n!="object")return;if(Array.isArray(n)){for(let i=0;i<n.length;i++)C(n[i],t);return}if(E(n)){t.add(z(n.$));return}if(x(n)){if(typeof n.$if=="string"){let i=n.$if.startsWith("!")?n.$if.slice(1):n.$if;t.add(z(i));}else C(n.$if,t);C(n.then,t),n.else!==void 0&&C(n.else,t);return}if(R(n)){for(let i=0;i<n.$pipe.length;i++)C(n.$pipe[i],t);return}if(S(n)){if(n.args)for(let i=0;i<n.args.length;i++)C(n.args[i],t);return}if(k(n)){C(n.body,t),n.params!==void 0&&C(n.params,t);return}if(h(n)){C(n.left,t),n.right!==void 0&&C(n.right,t);return}if(b(n)){for(let i=0;i<n.conditions.length;i++)C(n.conditions[i],t);return}let o=n,r=Object.keys(o);for(let i=0;i<r.length;i++)C(o[r[i]],t);}function Rn(n){return O(n).length>0}function kn(n){return O(n).length===0}function wn(n){return JSON.stringify(n)}function N(n,t={}){let o=t.scope??{},r=t.accessor,i=t.context??{},s=y(n,o,r,i),e=O(n),u=wn(n);return {fn:s,deps:e,hash:u}}function y(n,t,o,r){if(n===null)return ()=>null;if(typeof n!="object")return ()=>n;if(Array.isArray(n)){let i=n.map(s=>y(s,t,o,r));return s=>i.map(e=>e(s))}if(E(n))return Fn(n,o);if(x(n))return On(n,t,o,r);if(R(n))return vn(n,t,o,r);if(S(n))return jn(n,t,o,r);if(k(n))return Nn(n,t,o,r);if(h(n))return Gn(n,t,o,r);if(b(n))return In(n,t,o,r);if(J(n)){let i=n,s=Object.keys(i),e=s.map(u=>y(i[u],t,o,r));return u=>{let f={};for(let l=0;l<s.length;l++)f[s[l]]=e[l](u);return f}}return ()=>n}function nn(n,t){return t?o=>t(n,o):j(n)}function Fn(n,t){return nn(n.$,t)}function On(n,t,o,r){let i;if(typeof n.$if=="string"){let u=n.$if.startsWith("!")?n.$if.slice(1):n.$if,f=nn(u,o);i=n.$if.startsWith("!")?a=>!f(a):a=>!!f(a);}else {let u=y(n.$if,t,o,r);i=f=>!!u(f);}let s=y(n.then,t,o,r),e=n.else!==void 0?y(n.else,t,o,r):()=>{};return u=>i(u)?s(u):e(u)}function vn(n,t,o,r){let i=n.$pipe;if(i.length===0)return ()=>{};if(i.length===1)return y(i[0],t,o,r);let s=y(i[0],t,o,r),e=i.slice(1).map(f=>y(f,t,o,r)),u=e.length;if(u===1){let[f]=e;return l=>{let a=s(l),p=f(l);return typeof p=="function"?p(a):p}}if(u===2){let[f,l]=e;return a=>{let p=s(a),d=f(a);return p=typeof d=="function"?d(p):d,d=l(a),typeof d=="function"?d(p):d}}if(u===3){let[f,l,a]=e;return p=>{let d=s(p),g=f(p);return d=typeof g=="function"?g(d):g,g=l(p),d=typeof g=="function"?g(d):g,g=a(p),typeof g=="function"?g(d):g}}return f=>{let l=s(f);for(let a=0;a<u;a++){let p=e[a](f);l=typeof p=="function"?p(l):p;}return l}}function jn(n,t,o,r){let i=n.$fn,s=n.args;if(s===void 0)return ()=>{let f=t[i];if(!f)throw new Error(`Function not found in scope: ${i}`);return f};let e=s.map(f=>y(f,t,o,r)),u=e.length;if(u===0)return ()=>{let f=t[i];if(!f)throw new Error(`Function not found in scope: ${i}`);return f()};if(u===1){let[f]=e;return l=>{let a=t[i];if(!a)throw new Error(`Function not found in scope: ${i}`);return a(f(l))}}if(u===2){let[f,l]=e;return a=>{let p=t[i];if(!p)throw new Error(`Function not found in scope: ${i}`);return p(f(a),l(a))}}if(u===3){let[f,l,a]=e;return p=>{let d=t[i];if(!d)throw new Error(`Function not found in scope: ${i}`);return d(f(p),l(p),a(p))}}return f=>{let l=t[i];if(!l)throw new Error(`Function not found in scope: ${i}`);return l(...e.map(a=>a(f)))}}function Nn(n,t,o,r){let i=n.$cb,s,e=(a,p)=>s?s(a):o?o(a,p):j(a)(p),u=y(n.body,t,e,r),f=n.params?y(n.params,t,o,r):void 0,l=a=>o?p=>o(p,a):p=>j(p)(a);return a=>{let p=r?.[i];if(!p)throw new Error(`Context function not found: ${i}`);let d=l(a),g={data:a,get:d},w=G=>{G.get!==d&&(s=G.get);try{return u(G.data)}finally{s=void 0;}},F=f?f(a):void 0;return p(w,g,F)}}function Gn(n,t,o,r){let i=y(n.left,t,o,r),s=n.right!==void 0?y(n.right,t,o,r):()=>{};switch(n.op){case "eq":return e=>i(e)===s(e);case "neq":return e=>i(e)!==s(e);case "gt":return e=>i(e)>s(e);case "gte":return e=>i(e)>=s(e);case "lt":return e=>i(e)<s(e);case "lte":return e=>i(e)<=s(e);case "in":return e=>{let u=s(e);return Array.isArray(u)&&u.includes(i(e))};case "notIn":return e=>{let u=s(e);return !Array.isArray(u)||!u.includes(i(e))};case "contains":return e=>{let u=i(e);return Array.isArray(u)&&u.includes(s(e))};case "notContains":return e=>{let u=i(e);return !Array.isArray(u)||!u.includes(s(e))};case "exists":return e=>i(e)!==void 0;case "notExists":return e=>i(e)===void 0;case "matches":return e=>{let u=i(e),f=s(e);return typeof u!="string"||typeof f!="string"?false:new RegExp(f).test(u)};case "notMatches":return e=>{let u=i(e),f=s(e);return typeof u!="string"||typeof f!="string"?true:!new RegExp(f).test(u)};case "startsWith":return e=>{let u=i(e),f=s(e);return typeof u=="string"&&typeof f=="string"&&u.startsWith(f)};case "endsWith":return e=>{let u=i(e),f=s(e);return typeof u=="string"&&typeof f=="string"&&u.endsWith(f)}}}function In(n,t,o,r){let i=n.conditions.map(e=>y(e,t,o,r)),s=i.length;if(s===1)return e=>!!i[0](e);if(s===2){let[e,u]=i;return n.logic==="AND"?f=>!!e(f)&&!!u(f):f=>!!e(f)||!!u(f)}if(s===3){let[e,u,f]=i;return n.logic==="AND"?l=>!!e(l)&&!!u(l)&&!!f(l):l=>!!e(l)||!!u(l)||!!f(l)}return n.logic==="AND"?e=>{for(let u=0;u<s;u++)if(!i[u](e))return false;return true}:e=>{for(let u=0;u<s;u++)if(i[u](e))return true;return false}}function Wn(n,t,o={}){return N(n,o).fn(t)}var D=class{constructor(t=1e3){this.cache=new Map,this._maxSize=t;}get(t,o={}){let r=JSON.stringify(t),i=this.cache.get(r);if(i)return this.cache.delete(r),this.cache.set(r,i),i;let s=N(t,o);if(this.cache.size>=this._maxSize){let e=this.cache.keys().next().value;e&&this.cache.delete(e);}return this.cache.set(r,s),s}has(t){return this.cache.has(JSON.stringify(t))}delete(t){return this.cache.delete(JSON.stringify(t))}clear(){this.cache.clear();}get size(){return this.cache.size}get maxSize(){return this._maxSize}set maxSize(t){for(this._maxSize=t;this.cache.size>this._maxSize;){let o=this.cache.keys().next().value;o&&this.cache.delete(o);}}},tn=new D;function zn(n,t={}){return tn.get(n,t)}function K(n,t="root",o={}){let r=[];return T(n,t,r,o),{valid:r.length===0,errors:r}}function T(n,t,o,r){if(n===null||typeof n!="object")return;if(Array.isArray(n)){for(let e=0;e<n.length;e++)T(n[e],`${t}[${e}]`,o,r);return}if(E(n)){(!n.$||typeof n.$!="string")&&o.push(`${t}: invalid reference, $ must be non-empty string`);return}if(x(n)){typeof n.$if=="string"?(n.$if.startsWith("!")?n.$if.slice(1):n.$if)||o.push(`${t}.$if: empty path in string shorthand`):T(n.$if,`${t}.$if`,o,r),T(n.then,`${t}.then`,o,r),n.else!==void 0&&T(n.else,`${t}.else`,o,r);return}if(R(n)){if(!Array.isArray(n.$pipe)){o.push(`${t}.$pipe: must be an array`);return}if(n.$pipe.length===0){o.push(`${t}.$pipe: must have at least one element`);return}for(let e=0;e<n.$pipe.length;e++)T(n.$pipe[e],`${t}.$pipe[${e}]`,o,r);return}if(S(n)){if(!n.$fn||typeof n.$fn!="string"){o.push(`${t}: invalid function, $fn must be non-empty string`);return}if(r.scope&&!(n.$fn in r.scope)&&o.push(`${t}: function "${n.$fn}" not found in scope`),n.args!==void 0)if(!Array.isArray(n.args))o.push(`${t}.args: must be an array`);else for(let e=0;e<n.args.length;e++)T(n.args[e],`${t}.args[${e}]`,o,r);return}if(k(n)){if(!n.$cb||typeof n.$cb!="string"){o.push(`${t}: invalid callback, $cb must be non-empty string`);return}r.context&&!(n.$cb in r.context)&&o.push(`${t}: context function "${n.$cb}" not found`),T(n.body,`${t}.body`,o,r),n.params!==void 0&&T(n.params,`${t}.params`,o,r);return}if(h(n)){I.has(n.op)||o.push(`${t}: invalid operator "${n.op}"`),T(n.left,`${t}.left`,o,r),n.right!==void 0&&T(n.right,`${t}.right`,o,r);return}if(b(n)){if(n.logic!=="AND"&&n.logic!=="OR"&&o.push(`${t}: invalid logic "${n.logic}", must be "AND" or "OR"`),!Array.isArray(n.conditions)){o.push(`${t}.conditions: must be an array`);return}for(let e=0;e<n.conditions.length;e++)T(n.conditions[e],`${t}.conditions[${e}]`,o,r);return}let i=n,s=Object.keys(i);for(let e=0;e<s.length;e++){let u=s[e];T(i[u],`${t}.${u}`,o,r);}}function Dn(n,t={}){let o=K(n,"root",t);if(!o.valid)throw new Error(`Invalid expression: ${o.errors.join("; ")}`)}function Mn(n,t={}){return K(n,"root",t).valid}var cn={};En(cn,{$:()=>en,$call:()=>fn,$cb:()=>un,$cond:()=>sn,$fn:()=>on,$if:()=>_n,$pipe:()=>rn,call:()=>Kn,cb:()=>Jn,cond:()=>qn,fn:()=>Vn,pipe:()=>Ln,ref:()=>Bn});function en(n){return {$:n}}var Bn=en;function on(n,t){return t===void 0||t.length===0?{$fn:n}:{$fn:n,args:t}}var Vn=on;function _n(n,t,o){return o===void 0?{$if:n,then:t}:{$if:n,then:t,else:o}}function rn(...n){return {$pipe:n}}var Ln=rn;function sn(n,t,o){return o===void 0?{left:n,op:t}:{left:n,op:t,right:o}}var qn=sn;function un(n,t,o){return o===void 0?{$cb:n,body:t}:{$cb:n,body:t,params:o}}var Jn=un;function fn(n,t=[]){return {$fn:n,args:t}}var Kn=fn;var P="data",an="scope",Pn={eq:"===",neq:"!==",gt:">",gte:">=",lt:"<",lte:"<="};function B(n,t={}){let{dataParam:o=P,scopeParam:r=an,noPrefixes:i=false,useAccessor:s=false,lexicalPrefix:e}=t;return m(n,o,r,i,s,e)}function m(n,t,o,r,i,s){if(n===null)return omniAst.builders.literal(null);if(typeof n=="string")return omniAst.builders.literal(n);if(typeof n=="number")return omniAst.builders.literal(n);if(typeof n=="boolean")return omniAst.builders.literal(n);if(Array.isArray(n))return omniAst.builders.arrayExpression(n.map(e=>m(e,t,o,r,i,s)));if(E(n))return Xn(n.$,t,r,i,s);if(x(n))return Hn(n,t,o,r,i,s);if(R(n))return nt(n.$pipe,t,o,r,i,s);if(S(n))return Qn(n,t,o,r,i,s);if(k(n))return Zn(n,t,o,r,i,s);if(h(n))return tt(n,t,o,r,i,s);if(b(n))return et(n,t,o,r,i,s);if(typeof n=="object"){let u=Object.entries(n).map(([f,l])=>omniAst.builders.property(omniAst.builders.identifier(f),m(l,t,o,r,i,s)));return omniAst.builders.objectExpression(u)}return omniAst.builders.literal(null)}var X="accessor";function Y(n,t){return t?n===t||n.startsWith(t+"."):false}function Xn(n,t,o,r,i){return r?Y(n,i)?v(n,t,true):omniAst.builders.callExpression(omniAst.builders.identifier(X),[omniAst.builders.literal(n),omniAst.builders.identifier(t)]):n.includes("[*]")?Yn(n,t,o):v(n,t,o)}function v(n,t,o){let r=M(n);if(r.length===0)return o?omniAst.builders.identifier("undefined"):omniAst.builders.identifier(t);let i;if(o){let s=r[0];i=omniAst.builders.identifier(s.value);for(let e=1;e<r.length;e++){let u=r[e];u.type==="key"?i=omniAst.builders.memberExpression(i,omniAst.builders.identifier(u.value),false,true):i=omniAst.builders.memberExpression(i,omniAst.builders.literal(u.value),true,true);}}else {i=omniAst.builders.identifier(t);for(let s of r)s.type==="key"?i=omniAst.builders.memberExpression(i,omniAst.builders.identifier(s.value),false,true):i=omniAst.builders.memberExpression(i,omniAst.builders.literal(s.value),true,true);}return i}function Yn(n,t,o){let r=n.indexOf("[*]"),i=n.slice(0,r),s=n.slice(r+3),e;if(i?e=v(i,t,o):e=o?omniAst.builders.identifier("undefined"):omniAst.builders.identifier(t),!s||s==="")return e;if(s.includes("[*]"))return pn(e,s);let u="_i",f=s.startsWith(".")?s.slice(1):s,l=omniAst.builders.identifier(u);if(f){let a=M(f);for(let p of a)p.type==="key"?l=omniAst.builders.memberExpression(l,omniAst.builders.identifier(p.value),false,true):l=omniAst.builders.memberExpression(l,omniAst.builders.literal(p.value),true,true);}return omniAst.builders.callExpression(omniAst.builders.memberExpression(e,omniAst.builders.identifier("map"),false,true),[omniAst.builders.arrowFunctionExpression([omniAst.builders.identifier(u)],l)])}function pn(n,t){let o=t.indexOf("[*]"),r=t.slice(0,o),i=t.slice(o+3),s="_i",e=r.startsWith(".")?r.slice(1):r,u=omniAst.builders.identifier(s);if(e){let l=M(e);for(let a of l)a.type==="key"&&(u=omniAst.builders.memberExpression(u,omniAst.builders.identifier(a.value),false,true));}if(i.includes("[*]")){let l=pn(u,i);return omniAst.builders.callExpression(omniAst.builders.memberExpression(n,omniAst.builders.identifier("flatMap"),false,true),[omniAst.builders.arrowFunctionExpression([omniAst.builders.identifier(s)],l)])}let f=i.startsWith(".")?i.slice(1):i;if(f){let l=M(f);for(let a of l)a.type==="key"&&(u=omniAst.builders.memberExpression(u,omniAst.builders.identifier(a.value),false,true));}return omniAst.builders.callExpression(omniAst.builders.memberExpression(n,omniAst.builders.identifier("flatMap"),false,true),[omniAst.builders.arrowFunctionExpression([omniAst.builders.identifier(s)],u)])}function Hn(n,t,o,r,i,s){let e;if(typeof n.$if=="string"){let l=n.$if.startsWith("!"),a=l?n.$if.slice(1):n.$if,p;i?Y(a,s)?p=v(a,t,true):p=omniAst.builders.callExpression(omniAst.builders.identifier(X),[omniAst.builders.literal(a),omniAst.builders.identifier(t)]):p=v(a,t,r),e=l?omniAst.builders.unaryExpression("!",p):p;}else e=m(n.$if,t,o,r,i,s);let u=m(n.then,t,o,r,i,s),f=n.else!==void 0?m(n.else,t,o,r,i,s):omniAst.builders.identifier("undefined");return omniAst.builders.conditionalExpression(e,u,f)}function Qn(n,t,o,r,i,s){let e=r?omniAst.builders.identifier(n.$fn):omniAst.builders.memberExpression(omniAst.builders.identifier(o),omniAst.builders.identifier(n.$fn),false,false);if(n.args===void 0)return e;let u=n.args.map(f=>m(f,t,o,r,i,s));return omniAst.builders.callExpression(e,u)}var Un="context";function Zn(n,t,o,r,i,s){let e=r?omniAst.builders.identifier(n.$cb):omniAst.builders.memberExpression(omniAst.builders.identifier(Un),omniAst.builders.identifier(n.$cb),false,false),u=m(n.body,t,o,r,i,s),l=[omniAst.builders.arrowFunctionExpression([omniAst.builders.identifier("ctx")],u),omniAst.builders.identifier("ctx")];if(n.params!==void 0){let a=m(n.params,t,o,r,i,s);l.push(a);}return omniAst.builders.callExpression(e,l)}function nt(n,t,o,r,i,s){if(n.length===0)return omniAst.builders.identifier("undefined");if(n.length===1)return m(n[0],t,o,r,i,s);let e=m(n[0],t,o,r,i,s);for(let u=1;u<n.length;u++){let f=m(n[u],t,o,r,i,s);e=omniAst.builders.callExpression(f,[e]);}return e}function ln(n,t,o,r,i,s){if(E(n)){let e=n.$;return i?Y(e,s)?v(e,t,true):omniAst.builders.callExpression(omniAst.builders.identifier(X),[omniAst.builders.literal(e),omniAst.builders.identifier(t)]):v(e,t,r)}return m(n,t,o,r,i,s)}function tt(n,t,o,r,i,s){let e=ln(n.left,t,o,r,i,s),u=n.right!==void 0?ln(n.right,t,o,r,i,s):omniAst.builders.literal(null),f=Pn[n.op];if(f)return omniAst.builders.binaryExpression(f,e,u);switch(n.op){case "in":return omniAst.builders.callExpression(omniAst.builders.memberExpression(u,omniAst.builders.identifier("includes")),[e]);case "notIn":return omniAst.builders.unaryExpression("!",omniAst.builders.callExpression(omniAst.builders.memberExpression(u,omniAst.builders.identifier("includes")),[e]));case "contains":return omniAst.builders.callExpression(omniAst.builders.memberExpression(e,omniAst.builders.identifier("includes"),false,true),[u]);case "notContains":return omniAst.builders.unaryExpression("!",omniAst.builders.callExpression(omniAst.builders.memberExpression(e,omniAst.builders.identifier("includes"),false,true),[u]));case "exists":return omniAst.builders.binaryExpression("!=",e,omniAst.builders.literal(null));case "notExists":return omniAst.builders.binaryExpression("==",e,omniAst.builders.literal(null));case "matches":return omniAst.builders.callExpression(omniAst.builders.memberExpression(omniAst.builders.newExpression(omniAst.builders.identifier("RegExp"),[u]),omniAst.builders.identifier("test")),[e]);case "notMatches":return omniAst.builders.unaryExpression("!",omniAst.builders.callExpression(omniAst.builders.memberExpression(omniAst.builders.newExpression(omniAst.builders.identifier("RegExp"),[u]),omniAst.builders.identifier("test")),[e]));case "startsWith":return omniAst.builders.callExpression(omniAst.builders.memberExpression(e,omniAst.builders.identifier("startsWith"),false,true),[u]);case "endsWith":return omniAst.builders.callExpression(omniAst.builders.memberExpression(e,omniAst.builders.identifier("endsWith"),false,true),[u]);default:return omniAst.builders.binaryExpression("===",e,u)}}function et(n,t,o,r,i,s){let{logic:e,conditions:u}=n,f=e==="AND"?"&&":"||";if(u.length===0)return omniAst.builders.literal(e==="AND");if(u.length===1)return m(u[0],t,o,r,i,s);let l=m(u[0],t,o,r,i,s);for(let a=1;a<u.length;a++){let p=m(u[a],t,o,r,i,s);l=omniAst.builders.logicalExpression(f,l,p);}return l}function M(n){let t=[],o=n.length,r=0,i="";for(;r<o;){let s=n[r];if(s===".")i&&(t.push({type:"key",value:i}),i=""),r++;else if(s==="["){i&&(t.push({type:"key",value:i}),i=""),r++;let e=r;for(;r<o&&n[r]!=="]";)r++;let u=n.slice(e,r);if(r++,u!=="*"){let f=parseInt(u,10);t.push({type:"index",value:isNaN(f)?u:f});}}else i+=s,r++;}return i&&t.push({type:"key",value:i}),t}function dn(n,t=[P]){return omniAst.builders.arrowFunctionExpression(t.map(o=>omniAst.builders.identifier(o)),n)}function V(n){let t=new Set;return $(n,t),t}function $(n,t){if(n===null||typeof n!="object")return;if(Array.isArray(n)){for(let r of n)$(r,t);return}if(E(n))return;if(x(n)){$(n.$if,t),$(n.then,t),n.else!==void 0&&$(n.else,t);return}if(R(n)){for(let r of n.$pipe)$(r,t);return}if(S(n)){if(t.add(n.$fn),n.args)for(let r of n.args)$(r,t);return}if(k(n)){$(n.body,t),n.params!==void 0&&$(n.params,t);return}if(h(n)){n.left!==void 0&&typeof n.left=="object"&&$(n.left,t),n.right!==void 0&&typeof n.right=="object"&&$(n.right,t);return}if(b(n)){for(let r of n.conditions)$(r,t);return}let o=n;for(let r of Object.keys(o))$(o[r],t);}function _(n){let t=new Set;return A(n,t),t}function A(n,t){if(n===null||typeof n!="object")return;if(Array.isArray(n)){for(let r of n)A(r,t);return}if(E(n))return;if(x(n)){A(n.$if,t),A(n.then,t),n.else!==void 0&&A(n.else,t);return}if(R(n)){for(let r of n.$pipe)A(r,t);return}if(S(n)){if(n.args)for(let r of n.args)A(r,t);return}if(k(n)){t.add(n.$cb),A(n.body,t),n.params!==void 0&&A(n.params,t);return}if(h(n)){n.left!==void 0&&typeof n.left=="object"&&A(n.left,t),n.right!==void 0&&typeof n.right=="object"&&A(n.right,t);return}if(b(n)){for(let r of n.conditions)A(r,t);return}let o=n;for(let r of Object.keys(o))A(o[r],t);}function L(n){let t=new Set;for(let o of n){let r=o.indexOf("."),i=o.indexOf("["),s=o.length;r!==-1&&(s=Math.min(s,r)),i!==-1&&(s=Math.min(s,i));let e=o.slice(0,s);e&&t.add(e);}return t}function ot(n){return JSON.stringify(n)}function rt(n,t,o,r,i,s){let e=B(n,{noPrefixes:true,useAccessor:i,lexicalPrefix:s}),u=omniAst.generate(e),f="";i?s&&(f=`const{${s}}=data??{};`):t.size>0&&(f=`const{${[...t].join(",")}}=data??{};`);let l=i?new Set([...o,"accessor"]):o,a=l.size>0?`const{${[...l].join(",")}}=scope;`:"",p=r.size>0?`const{${[...r].join(",")}}=context;`:"",d=r.size>0,g="";d&&(i?g="const get=(path)=>accessor(path,data);const ctx={data,get};":g="const get=(path)=>path.split('.').reduce((o,k)=>o?.[k],data);const ctx={data,get};");let w=l.size>0,F;if(w||d){let G=d?"scope,context":"scope",mn=`${f}${g}return ${u}`;F=`(function(${G}){${a}${p}return function(data){${mn}}})`;}else F=`(function(){return function(data){${f}return ${u}}})`;return F}function H(n,t={}){let{scope:o={},context:r={},returnCode:i=false,useAccessor:s=false,lexicalPrefix:e}=t,u=O(n),f=L(u),l=V(n),a=_(n),p=ot(n),d=rt(n,f,l,a,s,e);if(i)return {code:d,deps:u,hash:p,dataRoots:[...f],scopeFns:[...l],contextFns:[...a]};let g;try{let w=a.size>0,F=new Function(`return ${d}`)();g=w?F(o,r):F(o);}catch(w){throw new Error(`AST compilation failed. If this is due to CSP, use the standard compile() function instead. Error: ${w instanceof Error?w.message:String(w)}`)}return {fn:g,deps:u,hash:p}}function gn(n,t,o={}){let{fn:r}=H(n,o);return r(t)}function st(n,t){return q(n,t)}function q(n,t){if(n===null)return null;if(typeof n!="object")return n;if(Array.isArray(n))return n.map(s=>q(s,t));let o=n,r=Object.keys(o);for(let s of r)if(s in t){let e=t[s](o);if(typeof e=="object"&&e!==null&&s in e)throw new Error(`Transform "${s}" returned object with same key \u2014 infinite loop`);return q(e,t)}let i={};for(let s of r)i[s]=q(o[s],t);return i}var ut=new Set(["$","$if","$fn","$pipe","$cb"]);function ft(){let n=0;return ()=>String(n++)}function ct(n,t){let{resolvers:o,scope:r={},genId:i,...s}=t,e=Object.keys(o);if(e.length===0)return {expr:n,scope:r};let u=new Set(e),f=[],l={compile:N,genId:i??ft(),scope:r,options:s},a=Q(n,u,o,l,f),p={...r};for(let d=0;d<f.length;d++){let[g,w]=f[d];p[g]=w;}return {expr:a,scope:p}}function Q(n,t,o,r,i){if(n===null)return null;if(typeof n!="object")return n;if(Array.isArray(n)){let l=n.length,a=new Array(l);for(let p=0;p<l;p++)a[p]=Q(n[p],t,o,r,i);return a}let s=n,e=Object.keys(s),u=e.length;for(let l=0;l<u;l++){let a=e[l];if(a[0]==="$"&&!ut.has(a)&&t.has(a)){let p=o[a],d=p(s,r);return d.scopeEntry&&i.push(d.scopeEntry),d.expr}}let f={};for(let l=0;l<u;l++){let a=e[l];f[a]=Q(s[a],t,o,r,i);}return f}var Vt="2.0.0";exports.ExpressionCache=D;exports.VERSION=Vt;exports.assertValid=Dn;exports.builders=cn;exports.cache=tn;exports.cached=zn;exports.clearPathCache=xn;exports.compile=N;exports.compileAST=H;exports.compilePath=j;exports.dslToAST=B;exports.evaluate=Wn;exports.evaluateAST=gn;exports.extractContextFns=_;exports.extractDataRoots=L;exports.extractDeps=O;exports.extractScopeFns=V;exports.get=An;exports.getPathCacheSize=Sn;exports.hasDeps=Rn;exports.hasWildcard=Z;exports.isCb=k;exports.isCondition=h;exports.isConditionExpr=hn;exports.isConditionGroup=b;exports.isConditional=x;exports.isFn=S;exports.isLiteral=J;exports.isPipe=R;exports.isPure=kn;exports.isRef=E;exports.isValid=Mn;exports.normalize=st;exports.normalizePath=z;exports.resolveBoundaries=ct;exports.validate=K;exports.wrapInFunction=dn;
|
package/dist/index.d.cts
CHANGED
|
@@ -134,32 +134,51 @@ interface ValidationResult {
|
|
|
134
134
|
*/
|
|
135
135
|
type Scope = Record<string, (...args: any[]) => any>;
|
|
136
136
|
/**
|
|
137
|
-
* Path getter function
|
|
137
|
+
* Path getter function - accessor de paths.
|
|
138
138
|
*/
|
|
139
139
|
type PathGetterFn = (path: string) => unknown;
|
|
140
|
+
/**
|
|
141
|
+
* Runtime context - contexto unificado passado para ContextFn.
|
|
142
|
+
* Agrupa dados e utilitários da lib em um único objeto imutável.
|
|
143
|
+
*
|
|
144
|
+
* @example
|
|
145
|
+
* ```ts
|
|
146
|
+
* // No ContextFn
|
|
147
|
+
* const tryCatch: ContextFn = (cb, ctx, params) => {
|
|
148
|
+
* console.log(ctx.data); // dados do usuário
|
|
149
|
+
* console.log(ctx.get("path")); // accessor
|
|
150
|
+
* };
|
|
151
|
+
* ```
|
|
152
|
+
*/
|
|
153
|
+
interface RuntimeCtx<T = unknown> {
|
|
154
|
+
/** Dados do runtime (passados pelo usuário) */
|
|
155
|
+
data: T;
|
|
156
|
+
/** Accessor de paths - resolve { $: "path" } */
|
|
157
|
+
get: PathGetterFn;
|
|
158
|
+
}
|
|
140
159
|
/**
|
|
141
160
|
* Context function - HOC que controla execução do body.
|
|
142
161
|
* Recebe o body como callback e decide quando/se executá-lo.
|
|
143
162
|
*
|
|
144
|
-
* @param cb - Body compilado
|
|
145
|
-
* @param
|
|
146
|
-
* @param
|
|
147
|
-
* @param params - Parâmetros extras para o context (opcional)
|
|
163
|
+
* @param cb - Body compilado (recebe ctx)
|
|
164
|
+
* @param ctx - Contexto de runtime (data + get)
|
|
165
|
+
* @param params - Parâmetros específicos deste $cb (opcional)
|
|
148
166
|
*
|
|
149
167
|
* @example
|
|
150
168
|
* ```ts
|
|
151
|
-
* const tryCatch: ContextFn = (cb,
|
|
169
|
+
* const tryCatch: ContextFn = (cb, ctx, params) => {
|
|
152
170
|
* try {
|
|
153
|
-
* return cb(
|
|
171
|
+
* return cb(ctx);
|
|
154
172
|
* } catch (e) {
|
|
155
173
|
* return params?.fallback ?? null;
|
|
156
174
|
* }
|
|
157
175
|
* };
|
|
158
176
|
*
|
|
159
|
-
* const transaction: ContextFn = (cb,
|
|
177
|
+
* const transaction: ContextFn = (cb, ctx, params) => {
|
|
160
178
|
* const tx = db.beginTransaction(params);
|
|
161
179
|
* try {
|
|
162
|
-
*
|
|
180
|
+
* // Pode criar novo ctx com dados extras
|
|
181
|
+
* const result = cb({ ...ctx, data: { ...ctx.data, tx } });
|
|
163
182
|
* tx.commit();
|
|
164
183
|
* return result;
|
|
165
184
|
* } catch (e) {
|
|
@@ -167,14 +186,19 @@ type PathGetterFn = (path: string) => unknown;
|
|
|
167
186
|
* throw e;
|
|
168
187
|
* }
|
|
169
188
|
* };
|
|
189
|
+
*
|
|
190
|
+
* // Context pode injetar accessor customizado
|
|
191
|
+
* const simulate: ContextFn = (cb, ctx, params) => {
|
|
192
|
+
* const simulatedGet = (path) => store.getSimulated(path);
|
|
193
|
+
* return cb({ ...ctx, get: simulatedGet });
|
|
194
|
+
* };
|
|
170
195
|
* ```
|
|
171
196
|
*/
|
|
172
|
-
type ContextFn<T = any, R = any> = (cb: (
|
|
197
|
+
type ContextFn<T = any, R = any> = (cb: (ctx: RuntimeCtx<T>) => R, ctx: RuntimeCtx<T>, params?: unknown) => R;
|
|
173
198
|
/**
|
|
174
199
|
* Context registry - HOC functions available to $cb expressions.
|
|
175
|
-
* Separate from scope because context functions have different signature.
|
|
176
200
|
*
|
|
177
|
-
* @example { tryCatch, transaction,
|
|
201
|
+
* @example { tryCatch, transaction, simulate }
|
|
178
202
|
*/
|
|
179
203
|
type Context = Record<string, ContextFn>;
|
|
180
204
|
/**
|
|
@@ -574,20 +598,40 @@ declare function $cb(name: string, body: Expression, params?: Expression): CbExp
|
|
|
574
598
|
* Alias for $cb (callback builder)
|
|
575
599
|
*/
|
|
576
600
|
declare const cb: typeof $cb;
|
|
601
|
+
/**
|
|
602
|
+
* Create a function call expression that always calls the function.
|
|
603
|
+
* Unlike $fn which returns function reference when args is empty/undefined,
|
|
604
|
+
* $call always includes args (defaults to empty array).
|
|
605
|
+
*
|
|
606
|
+
* @param name - Function name (from scope)
|
|
607
|
+
* @param args - Arguments (can be expressions, defaults to [])
|
|
608
|
+
* @returns FnExpr with args always present
|
|
609
|
+
*
|
|
610
|
+
* @example
|
|
611
|
+
* $call("now") // { $fn: "now", args: [] } - calls function
|
|
612
|
+
* $call("add", [$("a"), 1]) // { $fn: "add", args: [...] }
|
|
613
|
+
*/
|
|
614
|
+
declare function $call(name: string, args?: Expression[]): FnExpr;
|
|
615
|
+
/**
|
|
616
|
+
* Alias for $call (call builder)
|
|
617
|
+
*/
|
|
618
|
+
declare const call: typeof $call;
|
|
577
619
|
|
|
578
620
|
declare const builders_$: typeof $;
|
|
621
|
+
declare const builders_$call: typeof $call;
|
|
579
622
|
declare const builders_$cb: typeof $cb;
|
|
580
623
|
declare const builders_$cond: typeof $cond;
|
|
581
624
|
declare const builders_$fn: typeof $fn;
|
|
582
625
|
declare const builders_$if: typeof $if;
|
|
583
626
|
declare const builders_$pipe: typeof $pipe;
|
|
627
|
+
declare const builders_call: typeof call;
|
|
584
628
|
declare const builders_cb: typeof cb;
|
|
585
629
|
declare const builders_cond: typeof cond;
|
|
586
630
|
declare const builders_fn: typeof fn;
|
|
587
631
|
declare const builders_pipe: typeof pipe;
|
|
588
632
|
declare const builders_ref: typeof ref;
|
|
589
633
|
declare namespace builders {
|
|
590
|
-
export { builders_$ as $, builders_$cb as $cb, builders_$cond as $cond, builders_$fn as $fn, builders_$if as $if, builders_$pipe as $pipe, builders_cb as cb, builders_cond as cond, builders_fn as fn, builders_pipe as pipe, builders_ref as ref };
|
|
634
|
+
export { builders_$ as $, builders_$call as $call, builders_$cb as $cb, builders_$cond as $cond, builders_$fn as $fn, builders_$if as $if, builders_$pipe as $pipe, builders_call as call, builders_cb as cb, builders_cond as cond, builders_fn as fn, builders_pipe as pipe, builders_ref as ref };
|
|
591
635
|
}
|
|
592
636
|
|
|
593
637
|
/**
|
|
@@ -857,6 +901,112 @@ type Transforms = Record<string, TransformFn>;
|
|
|
857
901
|
*/
|
|
858
902
|
declare function normalize(expr: unknown, transforms: Transforms): Expression;
|
|
859
903
|
|
|
904
|
+
/**
|
|
905
|
+
* @statedelta-libs/expressions - Boundaries
|
|
906
|
+
*
|
|
907
|
+
* Resolve custom boundaries ($simulate, $query, etc.) before compilation.
|
|
908
|
+
* Boundaries are "foreign bodies" that stop the expression flow and delegate
|
|
909
|
+
* to external handlers. The handler can compile internal slots independently.
|
|
910
|
+
*
|
|
911
|
+
* @example
|
|
912
|
+
* ```ts
|
|
913
|
+
* const { expr, scope } = resolveBoundaries(
|
|
914
|
+
* { $simulate: { effects: [...], query: {...} } },
|
|
915
|
+
* {
|
|
916
|
+
* scope: baseScope,
|
|
917
|
+
* resolvers: {
|
|
918
|
+
* $simulate: (node, { compile, genId }) => {
|
|
919
|
+
* const id = `__simulate_${genId()}`;
|
|
920
|
+
* const fn = buildSimulateFn(node, compile);
|
|
921
|
+
* return {
|
|
922
|
+
* expr: { $fn: id },
|
|
923
|
+
* scopeEntry: [id, fn]
|
|
924
|
+
* };
|
|
925
|
+
* }
|
|
926
|
+
* }
|
|
927
|
+
* }
|
|
928
|
+
* );
|
|
929
|
+
*
|
|
930
|
+
* compile(expr, { scope });
|
|
931
|
+
* ```
|
|
932
|
+
*/
|
|
933
|
+
|
|
934
|
+
/**
|
|
935
|
+
* Result returned by a boundary resolver
|
|
936
|
+
*/
|
|
937
|
+
interface ResolverResult {
|
|
938
|
+
/** Expression to replace the boundary with */
|
|
939
|
+
expr: Expression;
|
|
940
|
+
/** Optional entry to add to scope [key, value] */
|
|
941
|
+
scopeEntry?: [string, unknown];
|
|
942
|
+
}
|
|
943
|
+
/**
|
|
944
|
+
* Context provided to boundary resolvers
|
|
945
|
+
*/
|
|
946
|
+
interface ResolverContext {
|
|
947
|
+
/** Compile function for compiling internal slots */
|
|
948
|
+
compile: typeof compile;
|
|
949
|
+
/** Generate unique ID for scope entries */
|
|
950
|
+
genId: () => string;
|
|
951
|
+
/** Current scope (read-only reference) */
|
|
952
|
+
scope: Readonly<Scope>;
|
|
953
|
+
/** Compile options passed to resolveBoundaries */
|
|
954
|
+
options: Readonly<CompileOptions>;
|
|
955
|
+
}
|
|
956
|
+
/**
|
|
957
|
+
* Boundary resolver function.
|
|
958
|
+
* Receives the raw node and context, returns replacement expression.
|
|
959
|
+
*/
|
|
960
|
+
type BoundaryResolver = (node: Record<string, unknown>, ctx: ResolverContext) => ResolverResult;
|
|
961
|
+
/**
|
|
962
|
+
* Map of boundary resolvers keyed by marker (e.g. "$simulate", "$query")
|
|
963
|
+
*/
|
|
964
|
+
type BoundaryResolvers = Record<string, BoundaryResolver>;
|
|
965
|
+
/**
|
|
966
|
+
* ID generator function
|
|
967
|
+
*/
|
|
968
|
+
type IdGenerator = () => string;
|
|
969
|
+
/**
|
|
970
|
+
* Options for resolveBoundaries
|
|
971
|
+
*/
|
|
972
|
+
interface ResolveBoundariesOptions extends CompileOptions {
|
|
973
|
+
/** Map of boundary resolvers */
|
|
974
|
+
resolvers: BoundaryResolvers;
|
|
975
|
+
/** Custom ID generator. Default: simple counter ("0", "1", "2"...) */
|
|
976
|
+
genId?: IdGenerator;
|
|
977
|
+
}
|
|
978
|
+
/**
|
|
979
|
+
* Result of resolveBoundaries
|
|
980
|
+
*/
|
|
981
|
+
interface ResolveBoundariesResult {
|
|
982
|
+
/** Pure expression with boundaries replaced */
|
|
983
|
+
expr: Expression;
|
|
984
|
+
/** Enriched scope with boundary handlers */
|
|
985
|
+
scope: Scope;
|
|
986
|
+
}
|
|
987
|
+
/**
|
|
988
|
+
* Resolve boundaries in an expression tree.
|
|
989
|
+
*
|
|
990
|
+
* Boundaries are custom DSL nodes ($simulate, $query, etc.) that stop the
|
|
991
|
+
* normal expression compilation flow. Each boundary is extracted, processed
|
|
992
|
+
* by its resolver, and replaced with a standard expression.
|
|
993
|
+
*
|
|
994
|
+
* The resolver receives:
|
|
995
|
+
* - `node`: The raw boundary object (e.g. { $simulate: {...}, effects: [...] })
|
|
996
|
+
* - `ctx.compile`: Compile function for internal slots
|
|
997
|
+
* - `ctx.genId`: Unique ID generator
|
|
998
|
+
* - `ctx.scope`: Current scope (read-only)
|
|
999
|
+
*
|
|
1000
|
+
* The resolver returns:
|
|
1001
|
+
* - `expr`: Replacement expression (typically { $fn: "__id" })
|
|
1002
|
+
* - `scopeEntry`: Optional [key, fn] to add to scope
|
|
1003
|
+
*
|
|
1004
|
+
* @param expr - Expression (possibly with boundaries)
|
|
1005
|
+
* @param options - Resolvers, scope, and compile options
|
|
1006
|
+
* @returns Pure expression and enriched scope
|
|
1007
|
+
*/
|
|
1008
|
+
declare function resolveBoundaries(expr: unknown, options: ResolveBoundariesOptions): ResolveBoundariesResult;
|
|
1009
|
+
|
|
860
1010
|
/**
|
|
861
1011
|
* @statedelta-libs/expressions
|
|
862
1012
|
*
|
|
@@ -892,4 +1042,4 @@ declare function normalize(expr: unknown, transforms: Transforms): Expression;
|
|
|
892
1042
|
*/
|
|
893
1043
|
declare const VERSION = "2.0.0";
|
|
894
1044
|
|
|
895
|
-
export { type AccessorFn, type CbExpr, type CompileASTCodeResult, type CompileASTOptions, type CompileOptions, type CompiledExpression, type CompiledFn, type Condition, type ConditionExpr, type ConditionGroup, type ConditionOp, type ConditionalExpr, type Context, type ContextFn, type Expression, ExpressionCache, type FnExpr, type Literal, type PathGetter, type PathGetterFn, type PipeExpr, type RefExpr, type Scope, type TransformFn, type TransformOptions, type Transforms, VERSION, type ValidateOptions, type ValidationResult, assertValid, builders, cache, cached, clearPathCache, compile, compileAST, compilePath, dslToAST, evaluate, evaluateAST, extractContextFns, extractDataRoots, extractDeps, extractScopeFns, get, getPathCacheSize, hasDeps, hasWildcard, isCb, isCondition, isConditionExpr, isConditionGroup, isConditional, isFn, isLiteral, isPipe, isPure, isRef, isValid, normalize, normalizePath, validate, wrapInFunction };
|
|
1045
|
+
export { type AccessorFn, type BoundaryResolver, type BoundaryResolvers, type CbExpr, type CompileASTCodeResult, type CompileASTOptions, type CompileOptions, type CompiledExpression, type CompiledFn, type Condition, type ConditionExpr, type ConditionGroup, type ConditionOp, type ConditionalExpr, type Context, type ContextFn, type Expression, ExpressionCache, type FnExpr, type IdGenerator, type Literal, type PathGetter, type PathGetterFn, type PipeExpr, type RefExpr, type ResolveBoundariesOptions, type ResolveBoundariesResult, type ResolverContext, type ResolverResult, type RuntimeCtx, type Scope, type TransformFn, type TransformOptions, type Transforms, VERSION, type ValidateOptions, type ValidationResult, assertValid, builders, cache, cached, clearPathCache, compile, compileAST, compilePath, dslToAST, evaluate, evaluateAST, extractContextFns, extractDataRoots, extractDeps, extractScopeFns, get, getPathCacheSize, hasDeps, hasWildcard, isCb, isCondition, isConditionExpr, isConditionGroup, isConditional, isFn, isLiteral, isPipe, isPure, isRef, isValid, normalize, normalizePath, resolveBoundaries, validate, wrapInFunction };
|
package/dist/index.d.ts
CHANGED
|
@@ -134,32 +134,51 @@ interface ValidationResult {
|
|
|
134
134
|
*/
|
|
135
135
|
type Scope = Record<string, (...args: any[]) => any>;
|
|
136
136
|
/**
|
|
137
|
-
* Path getter function
|
|
137
|
+
* Path getter function - accessor de paths.
|
|
138
138
|
*/
|
|
139
139
|
type PathGetterFn = (path: string) => unknown;
|
|
140
|
+
/**
|
|
141
|
+
* Runtime context - contexto unificado passado para ContextFn.
|
|
142
|
+
* Agrupa dados e utilitários da lib em um único objeto imutável.
|
|
143
|
+
*
|
|
144
|
+
* @example
|
|
145
|
+
* ```ts
|
|
146
|
+
* // No ContextFn
|
|
147
|
+
* const tryCatch: ContextFn = (cb, ctx, params) => {
|
|
148
|
+
* console.log(ctx.data); // dados do usuário
|
|
149
|
+
* console.log(ctx.get("path")); // accessor
|
|
150
|
+
* };
|
|
151
|
+
* ```
|
|
152
|
+
*/
|
|
153
|
+
interface RuntimeCtx<T = unknown> {
|
|
154
|
+
/** Dados do runtime (passados pelo usuário) */
|
|
155
|
+
data: T;
|
|
156
|
+
/** Accessor de paths - resolve { $: "path" } */
|
|
157
|
+
get: PathGetterFn;
|
|
158
|
+
}
|
|
140
159
|
/**
|
|
141
160
|
* Context function - HOC que controla execução do body.
|
|
142
161
|
* Recebe o body como callback e decide quando/se executá-lo.
|
|
143
162
|
*
|
|
144
|
-
* @param cb - Body compilado
|
|
145
|
-
* @param
|
|
146
|
-
* @param
|
|
147
|
-
* @param params - Parâmetros extras para o context (opcional)
|
|
163
|
+
* @param cb - Body compilado (recebe ctx)
|
|
164
|
+
* @param ctx - Contexto de runtime (data + get)
|
|
165
|
+
* @param params - Parâmetros específicos deste $cb (opcional)
|
|
148
166
|
*
|
|
149
167
|
* @example
|
|
150
168
|
* ```ts
|
|
151
|
-
* const tryCatch: ContextFn = (cb,
|
|
169
|
+
* const tryCatch: ContextFn = (cb, ctx, params) => {
|
|
152
170
|
* try {
|
|
153
|
-
* return cb(
|
|
171
|
+
* return cb(ctx);
|
|
154
172
|
* } catch (e) {
|
|
155
173
|
* return params?.fallback ?? null;
|
|
156
174
|
* }
|
|
157
175
|
* };
|
|
158
176
|
*
|
|
159
|
-
* const transaction: ContextFn = (cb,
|
|
177
|
+
* const transaction: ContextFn = (cb, ctx, params) => {
|
|
160
178
|
* const tx = db.beginTransaction(params);
|
|
161
179
|
* try {
|
|
162
|
-
*
|
|
180
|
+
* // Pode criar novo ctx com dados extras
|
|
181
|
+
* const result = cb({ ...ctx, data: { ...ctx.data, tx } });
|
|
163
182
|
* tx.commit();
|
|
164
183
|
* return result;
|
|
165
184
|
* } catch (e) {
|
|
@@ -167,14 +186,19 @@ type PathGetterFn = (path: string) => unknown;
|
|
|
167
186
|
* throw e;
|
|
168
187
|
* }
|
|
169
188
|
* };
|
|
189
|
+
*
|
|
190
|
+
* // Context pode injetar accessor customizado
|
|
191
|
+
* const simulate: ContextFn = (cb, ctx, params) => {
|
|
192
|
+
* const simulatedGet = (path) => store.getSimulated(path);
|
|
193
|
+
* return cb({ ...ctx, get: simulatedGet });
|
|
194
|
+
* };
|
|
170
195
|
* ```
|
|
171
196
|
*/
|
|
172
|
-
type ContextFn<T = any, R = any> = (cb: (
|
|
197
|
+
type ContextFn<T = any, R = any> = (cb: (ctx: RuntimeCtx<T>) => R, ctx: RuntimeCtx<T>, params?: unknown) => R;
|
|
173
198
|
/**
|
|
174
199
|
* Context registry - HOC functions available to $cb expressions.
|
|
175
|
-
* Separate from scope because context functions have different signature.
|
|
176
200
|
*
|
|
177
|
-
* @example { tryCatch, transaction,
|
|
201
|
+
* @example { tryCatch, transaction, simulate }
|
|
178
202
|
*/
|
|
179
203
|
type Context = Record<string, ContextFn>;
|
|
180
204
|
/**
|
|
@@ -574,20 +598,40 @@ declare function $cb(name: string, body: Expression, params?: Expression): CbExp
|
|
|
574
598
|
* Alias for $cb (callback builder)
|
|
575
599
|
*/
|
|
576
600
|
declare const cb: typeof $cb;
|
|
601
|
+
/**
|
|
602
|
+
* Create a function call expression that always calls the function.
|
|
603
|
+
* Unlike $fn which returns function reference when args is empty/undefined,
|
|
604
|
+
* $call always includes args (defaults to empty array).
|
|
605
|
+
*
|
|
606
|
+
* @param name - Function name (from scope)
|
|
607
|
+
* @param args - Arguments (can be expressions, defaults to [])
|
|
608
|
+
* @returns FnExpr with args always present
|
|
609
|
+
*
|
|
610
|
+
* @example
|
|
611
|
+
* $call("now") // { $fn: "now", args: [] } - calls function
|
|
612
|
+
* $call("add", [$("a"), 1]) // { $fn: "add", args: [...] }
|
|
613
|
+
*/
|
|
614
|
+
declare function $call(name: string, args?: Expression[]): FnExpr;
|
|
615
|
+
/**
|
|
616
|
+
* Alias for $call (call builder)
|
|
617
|
+
*/
|
|
618
|
+
declare const call: typeof $call;
|
|
577
619
|
|
|
578
620
|
declare const builders_$: typeof $;
|
|
621
|
+
declare const builders_$call: typeof $call;
|
|
579
622
|
declare const builders_$cb: typeof $cb;
|
|
580
623
|
declare const builders_$cond: typeof $cond;
|
|
581
624
|
declare const builders_$fn: typeof $fn;
|
|
582
625
|
declare const builders_$if: typeof $if;
|
|
583
626
|
declare const builders_$pipe: typeof $pipe;
|
|
627
|
+
declare const builders_call: typeof call;
|
|
584
628
|
declare const builders_cb: typeof cb;
|
|
585
629
|
declare const builders_cond: typeof cond;
|
|
586
630
|
declare const builders_fn: typeof fn;
|
|
587
631
|
declare const builders_pipe: typeof pipe;
|
|
588
632
|
declare const builders_ref: typeof ref;
|
|
589
633
|
declare namespace builders {
|
|
590
|
-
export { builders_$ as $, builders_$cb as $cb, builders_$cond as $cond, builders_$fn as $fn, builders_$if as $if, builders_$pipe as $pipe, builders_cb as cb, builders_cond as cond, builders_fn as fn, builders_pipe as pipe, builders_ref as ref };
|
|
634
|
+
export { builders_$ as $, builders_$call as $call, builders_$cb as $cb, builders_$cond as $cond, builders_$fn as $fn, builders_$if as $if, builders_$pipe as $pipe, builders_call as call, builders_cb as cb, builders_cond as cond, builders_fn as fn, builders_pipe as pipe, builders_ref as ref };
|
|
591
635
|
}
|
|
592
636
|
|
|
593
637
|
/**
|
|
@@ -857,6 +901,112 @@ type Transforms = Record<string, TransformFn>;
|
|
|
857
901
|
*/
|
|
858
902
|
declare function normalize(expr: unknown, transforms: Transforms): Expression;
|
|
859
903
|
|
|
904
|
+
/**
|
|
905
|
+
* @statedelta-libs/expressions - Boundaries
|
|
906
|
+
*
|
|
907
|
+
* Resolve custom boundaries ($simulate, $query, etc.) before compilation.
|
|
908
|
+
* Boundaries are "foreign bodies" that stop the expression flow and delegate
|
|
909
|
+
* to external handlers. The handler can compile internal slots independently.
|
|
910
|
+
*
|
|
911
|
+
* @example
|
|
912
|
+
* ```ts
|
|
913
|
+
* const { expr, scope } = resolveBoundaries(
|
|
914
|
+
* { $simulate: { effects: [...], query: {...} } },
|
|
915
|
+
* {
|
|
916
|
+
* scope: baseScope,
|
|
917
|
+
* resolvers: {
|
|
918
|
+
* $simulate: (node, { compile, genId }) => {
|
|
919
|
+
* const id = `__simulate_${genId()}`;
|
|
920
|
+
* const fn = buildSimulateFn(node, compile);
|
|
921
|
+
* return {
|
|
922
|
+
* expr: { $fn: id },
|
|
923
|
+
* scopeEntry: [id, fn]
|
|
924
|
+
* };
|
|
925
|
+
* }
|
|
926
|
+
* }
|
|
927
|
+
* }
|
|
928
|
+
* );
|
|
929
|
+
*
|
|
930
|
+
* compile(expr, { scope });
|
|
931
|
+
* ```
|
|
932
|
+
*/
|
|
933
|
+
|
|
934
|
+
/**
|
|
935
|
+
* Result returned by a boundary resolver
|
|
936
|
+
*/
|
|
937
|
+
interface ResolverResult {
|
|
938
|
+
/** Expression to replace the boundary with */
|
|
939
|
+
expr: Expression;
|
|
940
|
+
/** Optional entry to add to scope [key, value] */
|
|
941
|
+
scopeEntry?: [string, unknown];
|
|
942
|
+
}
|
|
943
|
+
/**
|
|
944
|
+
* Context provided to boundary resolvers
|
|
945
|
+
*/
|
|
946
|
+
interface ResolverContext {
|
|
947
|
+
/** Compile function for compiling internal slots */
|
|
948
|
+
compile: typeof compile;
|
|
949
|
+
/** Generate unique ID for scope entries */
|
|
950
|
+
genId: () => string;
|
|
951
|
+
/** Current scope (read-only reference) */
|
|
952
|
+
scope: Readonly<Scope>;
|
|
953
|
+
/** Compile options passed to resolveBoundaries */
|
|
954
|
+
options: Readonly<CompileOptions>;
|
|
955
|
+
}
|
|
956
|
+
/**
|
|
957
|
+
* Boundary resolver function.
|
|
958
|
+
* Receives the raw node and context, returns replacement expression.
|
|
959
|
+
*/
|
|
960
|
+
type BoundaryResolver = (node: Record<string, unknown>, ctx: ResolverContext) => ResolverResult;
|
|
961
|
+
/**
|
|
962
|
+
* Map of boundary resolvers keyed by marker (e.g. "$simulate", "$query")
|
|
963
|
+
*/
|
|
964
|
+
type BoundaryResolvers = Record<string, BoundaryResolver>;
|
|
965
|
+
/**
|
|
966
|
+
* ID generator function
|
|
967
|
+
*/
|
|
968
|
+
type IdGenerator = () => string;
|
|
969
|
+
/**
|
|
970
|
+
* Options for resolveBoundaries
|
|
971
|
+
*/
|
|
972
|
+
interface ResolveBoundariesOptions extends CompileOptions {
|
|
973
|
+
/** Map of boundary resolvers */
|
|
974
|
+
resolvers: BoundaryResolvers;
|
|
975
|
+
/** Custom ID generator. Default: simple counter ("0", "1", "2"...) */
|
|
976
|
+
genId?: IdGenerator;
|
|
977
|
+
}
|
|
978
|
+
/**
|
|
979
|
+
* Result of resolveBoundaries
|
|
980
|
+
*/
|
|
981
|
+
interface ResolveBoundariesResult {
|
|
982
|
+
/** Pure expression with boundaries replaced */
|
|
983
|
+
expr: Expression;
|
|
984
|
+
/** Enriched scope with boundary handlers */
|
|
985
|
+
scope: Scope;
|
|
986
|
+
}
|
|
987
|
+
/**
|
|
988
|
+
* Resolve boundaries in an expression tree.
|
|
989
|
+
*
|
|
990
|
+
* Boundaries are custom DSL nodes ($simulate, $query, etc.) that stop the
|
|
991
|
+
* normal expression compilation flow. Each boundary is extracted, processed
|
|
992
|
+
* by its resolver, and replaced with a standard expression.
|
|
993
|
+
*
|
|
994
|
+
* The resolver receives:
|
|
995
|
+
* - `node`: The raw boundary object (e.g. { $simulate: {...}, effects: [...] })
|
|
996
|
+
* - `ctx.compile`: Compile function for internal slots
|
|
997
|
+
* - `ctx.genId`: Unique ID generator
|
|
998
|
+
* - `ctx.scope`: Current scope (read-only)
|
|
999
|
+
*
|
|
1000
|
+
* The resolver returns:
|
|
1001
|
+
* - `expr`: Replacement expression (typically { $fn: "__id" })
|
|
1002
|
+
* - `scopeEntry`: Optional [key, fn] to add to scope
|
|
1003
|
+
*
|
|
1004
|
+
* @param expr - Expression (possibly with boundaries)
|
|
1005
|
+
* @param options - Resolvers, scope, and compile options
|
|
1006
|
+
* @returns Pure expression and enriched scope
|
|
1007
|
+
*/
|
|
1008
|
+
declare function resolveBoundaries(expr: unknown, options: ResolveBoundariesOptions): ResolveBoundariesResult;
|
|
1009
|
+
|
|
860
1010
|
/**
|
|
861
1011
|
* @statedelta-libs/expressions
|
|
862
1012
|
*
|
|
@@ -892,4 +1042,4 @@ declare function normalize(expr: unknown, transforms: Transforms): Expression;
|
|
|
892
1042
|
*/
|
|
893
1043
|
declare const VERSION = "2.0.0";
|
|
894
1044
|
|
|
895
|
-
export { type AccessorFn, type CbExpr, type CompileASTCodeResult, type CompileASTOptions, type CompileOptions, type CompiledExpression, type CompiledFn, type Condition, type ConditionExpr, type ConditionGroup, type ConditionOp, type ConditionalExpr, type Context, type ContextFn, type Expression, ExpressionCache, type FnExpr, type Literal, type PathGetter, type PathGetterFn, type PipeExpr, type RefExpr, type Scope, type TransformFn, type TransformOptions, type Transforms, VERSION, type ValidateOptions, type ValidationResult, assertValid, builders, cache, cached, clearPathCache, compile, compileAST, compilePath, dslToAST, evaluate, evaluateAST, extractContextFns, extractDataRoots, extractDeps, extractScopeFns, get, getPathCacheSize, hasDeps, hasWildcard, isCb, isCondition, isConditionExpr, isConditionGroup, isConditional, isFn, isLiteral, isPipe, isPure, isRef, isValid, normalize, normalizePath, validate, wrapInFunction };
|
|
1045
|
+
export { type AccessorFn, type BoundaryResolver, type BoundaryResolvers, type CbExpr, type CompileASTCodeResult, type CompileASTOptions, type CompileOptions, type CompiledExpression, type CompiledFn, type Condition, type ConditionExpr, type ConditionGroup, type ConditionOp, type ConditionalExpr, type Context, type ContextFn, type Expression, ExpressionCache, type FnExpr, type IdGenerator, type Literal, type PathGetter, type PathGetterFn, type PipeExpr, type RefExpr, type ResolveBoundariesOptions, type ResolveBoundariesResult, type ResolverContext, type ResolverResult, type RuntimeCtx, type Scope, type TransformFn, type TransformOptions, type Transforms, VERSION, type ValidateOptions, type ValidationResult, assertValid, builders, cache, cached, clearPathCache, compile, compileAST, compilePath, dslToAST, evaluate, evaluateAST, extractContextFns, extractDataRoots, extractDeps, extractScopeFns, get, getPathCacheSize, hasDeps, hasWildcard, isCb, isCondition, isConditionExpr, isConditionGroup, isConditional, isFn, isLiteral, isPipe, isPure, isRef, isValid, normalize, normalizePath, resolveBoundaries, validate, wrapInFunction };
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import {builders,generate}from'omni-ast';var gn=Object.defineProperty;var mn=(n,t)=>{for(var o in t)gn(n,o,{get:t[o],enumerable:true});};var E=n=>n!==null&&typeof n=="object"&&"$"in n&&typeof n.$=="string"&&Object.keys(n).length===1,S=n=>n!==null&&typeof n=="object"&&"$if"in n&&"then"in n,w=n=>n!==null&&typeof n=="object"&&"$fn"in n&&typeof n.$fn=="string",k=n=>n!==null&&typeof n=="object"&&"$pipe"in n&&Array.isArray(n.$pipe),x=n=>n!==null&&typeof n=="object"&&"$cb"in n&&typeof n.$cb=="string"&&"body"in n,v=new Set(["eq","neq","gt","gte","lt","lte","in","notIn","contains","notContains","exists","notExists","matches","notMatches","startsWith","endsWith"]),h=n=>n!==null&&typeof n=="object"&&"left"in n&&"op"in n&&v.has(n.op)&&!("$"in n)&&!("$if"in n)&&!("$fn"in n),b=n=>n!==null&&typeof n=="object"&&"logic"in n&&"conditions"in n,yn=n=>h(n)||b(n),B=n=>{if(n===null)return true;let t=typeof n;if(t==="string"||t==="number"||t==="boolean"||Array.isArray(n))return true;if(t==="object"&&n!==null){let o=n,r="left"in o&&"op"in o&&v.has(o.op);return !("$"in o)&&!("$if"in o)&&!("$fn"in o)&&!("$pipe"in o)&&!("$cb"in o)&&!r&&!("logic"in o)}return false};var G=new Map;function Q(n){let t=[],o=n.length,r=0,i="";for(;r<o;){let s=n[r];if(s===".")i&&(t.push({type:"key",value:i}),i=""),r++;else if(s==="["){i&&(t.push({type:"key",value:i}),i=""),r++;let e=r;for(;r<o&&n[r]!=="]";)r++;let f=n.slice(e,r);if(r++,f==="*")t.push({type:"wildcard",value:"*"});else {let u=parseInt(f,10);t.push({type:"index",value:isNaN(u)?f:u});}}else i+=s,r++;}return i&&t.push({type:"key",value:i}),t}function U(n){return n.includes("[*]")}function j(n){let t=G.get(n);return t||(t=U(n)?hn(n):En(n),G.set(n,t),t)}function En(n){if(!n.includes(".")&&!n.includes("["))return i=>i?.[n];let t=Q(n),o=t.length;if(o===2){let[i,s]=t,e=i.value,f=s.value;return u=>u?.[e]?.[f]}if(o===3){let[i,s,e]=t,f=i.value,u=s.value,a=e.value;return l=>l?.[f]?.[u]?.[a]}let r=t.map(i=>i.value);return i=>{let s=i;for(let e=0;e<o&&s!=null;e++)s=s[r[e]];return s}}function hn(n){let t=Q(n),o=[];for(let r=0;r<t.length;r++)t[r].type==="wildcard"&&o.push(r);return o.length===1?bn(t,o[0]):Cn(t,o)}function bn(n,t){let o=n.slice(0,t).map(e=>e.value),r=n.slice(t+1).map(e=>e.value),i=o.length,s=r.length;if(s===0){if(i===1){let e=o[0];return f=>f?.[e]}return e=>{let f=e;for(let u=0;u<i&&f!=null;u++)f=f[o[u]];return f}}if(s===1){let e=r[0];if(i===1){let f=o[0];return u=>{let a=u?.[f];if(Array.isArray(a))return a.map(l=>l?.[e])}}return f=>{let u=f;for(let a=0;a<i&&u!=null;a++)u=u[o[a]];if(Array.isArray(u))return u.map(a=>a?.[e])}}return e=>{let f=e;for(let u=0;u<i&&f!=null;u++)f=f[o[u]];if(Array.isArray(f))return f.map(u=>{let a=u;for(let l=0;l<s&&a!=null;l++)a=a[r[l]];return a})}}function Cn(n,t){let o=[],r=0;for(let s=0;s<t.length;s++){let e=t[s],f=s===t.length-1,u=n.slice(r,e).map(a=>a.value);u.length>0&&o.push({type:"access",keys:u}),o.push({type:f?"map":"flatMap",keys:[]}),r=e+1;}let i=n.slice(r).map(s=>s.value);return s=>{let e=s;for(let f of o){if(e==null)return;if(f.type==="access")for(let u of f.keys){if(e==null)return;e=e[u];}else if(f.type==="flatMap"){if(!Array.isArray(e))return;e=e.flatMap(u=>{let a=u;return Array.isArray(a)?a:[a]});}else if(f.type==="map"){if(!Array.isArray(e))return;i.length>0&&(e=e.map(u=>{let a=u;for(let l of i){if(a==null)return;a=a[l];}return a}));}}return e}}function Tn(n,t){return j(t)(n)}function W(n){let t=n.indexOf("[*]");return t===-1?n:n.slice(0,t)}function $n(){G.clear();}function An(){return G.size}function R(n){let t=new Set;return C(n,t),Array.from(t)}function C(n,t){if(n===null||typeof n!="object")return;if(Array.isArray(n)){for(let i=0;i<n.length;i++)C(n[i],t);return}if(E(n)){t.add(W(n.$));return}if(S(n)){if(typeof n.$if=="string"){let i=n.$if.startsWith("!")?n.$if.slice(1):n.$if;t.add(W(i));}else C(n.$if,t);C(n.then,t),n.else!==void 0&&C(n.else,t);return}if(k(n)){for(let i=0;i<n.$pipe.length;i++)C(n.$pipe[i],t);return}if(w(n)){if(n.args)for(let i=0;i<n.args.length;i++)C(n.args[i],t);return}if(x(n)){C(n.body,t),n.params!==void 0&&C(n.params,t);return}if(h(n)){C(n.left,t),n.right!==void 0&&C(n.right,t);return}if(b(n)){for(let i=0;i<n.conditions.length;i++)C(n.conditions[i],t);return}let o=n,r=Object.keys(o);for(let i=0;i<r.length;i++)C(o[r[i]],t);}function Sn(n){return R(n).length>0}function wn(n){return R(n).length===0}function kn(n){return JSON.stringify(n)}function z(n,t={}){let o=t.scope??{},r=t.accessor,i=t.context??{},s=y(n,o,r,i),e=R(n),f=kn(n);return {fn:s,deps:e,hash:f}}function y(n,t,o,r){if(n===null)return ()=>null;if(typeof n!="object")return ()=>n;if(Array.isArray(n)){let i=n.map(s=>y(s,t,o,r));return s=>i.map(e=>e(s))}if(E(n))return xn(n,o);if(S(n))return Fn(n,t,o,r);if(k(n))return Rn(n,t,o,r);if(w(n))return On(n,t,o,r);if(x(n))return Nn(n,t,o,r);if(h(n))return jn(n,t,o,r);if(b(n))return vn(n,t,o,r);if(B(n)){let i=n,s=Object.keys(i),e=s.map(f=>y(i[f],t,o,r));return f=>{let u={};for(let a=0;a<s.length;a++)u[s[a]]=e[a](f);return u}}return ()=>n}function Z(n,t){return t?o=>t(n,o):j(n)}function xn(n,t){return Z(n.$,t)}function Fn(n,t,o,r){let i;if(typeof n.$if=="string"){let f=n.$if.startsWith("!")?n.$if.slice(1):n.$if,u=Z(f,o);i=n.$if.startsWith("!")?l=>!u(l):l=>!!u(l);}else {let f=y(n.$if,t,o,r);i=u=>!!f(u);}let s=y(n.then,t,o,r),e=n.else!==void 0?y(n.else,t,o,r):()=>{};return f=>i(f)?s(f):e(f)}function Rn(n,t,o,r){let i=n.$pipe;if(i.length===0)return ()=>{};if(i.length===1)return y(i[0],t,o,r);let s=y(i[0],t,o,r),e=i.slice(1).map(u=>y(u,t,o,r)),f=e.length;if(f===1){let[u]=e;return a=>{let l=s(a),p=u(a);return typeof p=="function"?p(l):p}}if(f===2){let[u,a]=e;return l=>{let p=s(l),d=u(l);return p=typeof d=="function"?d(p):d,d=a(l),typeof d=="function"?d(p):d}}if(f===3){let[u,a,l]=e;return p=>{let d=s(p),g=u(p);return d=typeof g=="function"?g(d):g,g=a(p),d=typeof g=="function"?g(d):g,g=l(p),typeof g=="function"?g(d):g}}return u=>{let a=s(u);for(let l=0;l<f;l++){let p=e[l](u);a=typeof p=="function"?p(a):p;}return a}}function On(n,t,o,r){let i=n.$fn,s=n.args;if(s===void 0)return ()=>{let u=t[i];if(!u)throw new Error(`Function not found in scope: ${i}`);return u};let e=s.map(u=>y(u,t,o,r)),f=e.length;if(f===0)return ()=>{let u=t[i];if(!u)throw new Error(`Function not found in scope: ${i}`);return u()};if(f===1){let[u]=e;return a=>{let l=t[i];if(!l)throw new Error(`Function not found in scope: ${i}`);return l(u(a))}}if(f===2){let[u,a]=e;return l=>{let p=t[i];if(!p)throw new Error(`Function not found in scope: ${i}`);return p(u(l),a(l))}}if(f===3){let[u,a,l]=e;return p=>{let d=t[i];if(!d)throw new Error(`Function not found in scope: ${i}`);return d(u(p),a(p),l(p))}}return u=>{let a=t[i];if(!a)throw new Error(`Function not found in scope: ${i}`);return a(...e.map(l=>l(u)))}}function Nn(n,t,o,r){let i=n.$cb,s=y(n.body,t,o,r),e=n.params?y(n.params,t,o,r):void 0,f=u=>o?a=>o(a,u):a=>j(a)(u);return u=>{let a=r?.[i];if(!a)throw new Error(`Context function not found: ${i}`);let l=(g,F)=>s(g),p=f(u),d=e?e(u):void 0;return a(l,u,p,d)}}function jn(n,t,o,r){let i=y(n.left,t,o,r),s=n.right!==void 0?y(n.right,t,o,r):()=>{};switch(n.op){case "eq":return e=>i(e)===s(e);case "neq":return e=>i(e)!==s(e);case "gt":return e=>i(e)>s(e);case "gte":return e=>i(e)>=s(e);case "lt":return e=>i(e)<s(e);case "lte":return e=>i(e)<=s(e);case "in":return e=>{let f=s(e);return Array.isArray(f)&&f.includes(i(e))};case "notIn":return e=>{let f=s(e);return !Array.isArray(f)||!f.includes(i(e))};case "contains":return e=>{let f=i(e);return Array.isArray(f)&&f.includes(s(e))};case "notContains":return e=>{let f=i(e);return !Array.isArray(f)||!f.includes(s(e))};case "exists":return e=>i(e)!==void 0;case "notExists":return e=>i(e)===void 0;case "matches":return e=>{let f=i(e),u=s(e);return typeof f!="string"||typeof u!="string"?false:new RegExp(u).test(f)};case "notMatches":return e=>{let f=i(e),u=s(e);return typeof f!="string"||typeof u!="string"?true:!new RegExp(u).test(f)};case "startsWith":return e=>{let f=i(e),u=s(e);return typeof f=="string"&&typeof u=="string"&&f.startsWith(u)};case "endsWith":return e=>{let f=i(e),u=s(e);return typeof f=="string"&&typeof u=="string"&&f.endsWith(u)}}}function vn(n,t,o,r){let i=n.conditions.map(e=>y(e,t,o,r)),s=i.length;if(s===1)return e=>!!i[0](e);if(s===2){let[e,f]=i;return n.logic==="AND"?u=>!!e(u)&&!!f(u):u=>!!e(u)||!!f(u)}if(s===3){let[e,f,u]=i;return n.logic==="AND"?a=>!!e(a)&&!!f(a)&&!!u(a):a=>!!e(a)||!!f(a)||!!u(a)}return n.logic==="AND"?e=>{for(let f=0;f<s;f++)if(!i[f](e))return false;return true}:e=>{for(let f=0;f<s;f++)if(i[f](e))return true;return false}}function Gn(n,t,o={}){return z(n,o).fn(t)}var D=class{constructor(t=1e3){this.cache=new Map,this._maxSize=t;}get(t,o={}){let r=JSON.stringify(t),i=this.cache.get(r);if(i)return this.cache.delete(r),this.cache.set(r,i),i;let s=z(t,o);if(this.cache.size>=this._maxSize){let e=this.cache.keys().next().value;e&&this.cache.delete(e);}return this.cache.set(r,s),s}has(t){return this.cache.has(JSON.stringify(t))}delete(t){return this.cache.delete(JSON.stringify(t))}clear(){this.cache.clear();}get size(){return this.cache.size}get maxSize(){return this._maxSize}set maxSize(t){for(this._maxSize=t;this.cache.size>this._maxSize;){let o=this.cache.keys().next().value;o&&this.cache.delete(o);}}},P=new D;function Wn(n,t={}){return P.get(n,t)}function J(n,t="root",o={}){let r=[];return T(n,t,r,o),{valid:r.length===0,errors:r}}function T(n,t,o,r){if(n===null||typeof n!="object")return;if(Array.isArray(n)){for(let e=0;e<n.length;e++)T(n[e],`${t}[${e}]`,o,r);return}if(E(n)){(!n.$||typeof n.$!="string")&&o.push(`${t}: invalid reference, $ must be non-empty string`);return}if(S(n)){typeof n.$if=="string"?(n.$if.startsWith("!")?n.$if.slice(1):n.$if)||o.push(`${t}.$if: empty path in string shorthand`):T(n.$if,`${t}.$if`,o,r),T(n.then,`${t}.then`,o,r),n.else!==void 0&&T(n.else,`${t}.else`,o,r);return}if(k(n)){if(!Array.isArray(n.$pipe)){o.push(`${t}.$pipe: must be an array`);return}if(n.$pipe.length===0){o.push(`${t}.$pipe: must have at least one element`);return}for(let e=0;e<n.$pipe.length;e++)T(n.$pipe[e],`${t}.$pipe[${e}]`,o,r);return}if(w(n)){if(!n.$fn||typeof n.$fn!="string"){o.push(`${t}: invalid function, $fn must be non-empty string`);return}if(r.scope&&!(n.$fn in r.scope)&&o.push(`${t}: function "${n.$fn}" not found in scope`),n.args!==void 0)if(!Array.isArray(n.args))o.push(`${t}.args: must be an array`);else for(let e=0;e<n.args.length;e++)T(n.args[e],`${t}.args[${e}]`,o,r);return}if(x(n)){if(!n.$cb||typeof n.$cb!="string"){o.push(`${t}: invalid callback, $cb must be non-empty string`);return}r.context&&!(n.$cb in r.context)&&o.push(`${t}: context function "${n.$cb}" not found`),T(n.body,`${t}.body`,o,r),n.params!==void 0&&T(n.params,`${t}.params`,o,r);return}if(h(n)){v.has(n.op)||o.push(`${t}: invalid operator "${n.op}"`),T(n.left,`${t}.left`,o,r),n.right!==void 0&&T(n.right,`${t}.right`,o,r);return}if(b(n)){if(n.logic!=="AND"&&n.logic!=="OR"&&o.push(`${t}: invalid logic "${n.logic}", must be "AND" or "OR"`),!Array.isArray(n.conditions)){o.push(`${t}.conditions: must be an array`);return}for(let e=0;e<n.conditions.length;e++)T(n.conditions[e],`${t}.conditions[${e}]`,o,r);return}let i=n,s=Object.keys(i);for(let e=0;e<s.length;e++){let f=s[e];T(i[f],`${t}.${f}`,o,r);}}function zn(n,t={}){let o=J(n,"root",t);if(!o.valid)throw new Error(`Invalid expression: ${o.errors.join("; ")}`)}function Dn(n,t={}){return J(n,"root",t).valid}var sn={};mn(sn,{$:()=>nn,$cb:()=>rn,$cond:()=>on,$fn:()=>tn,$if:()=>_n,$pipe:()=>en,cb:()=>qn,cond:()=>Ln,fn:()=>In,pipe:()=>Vn,ref:()=>Mn});function nn(n){return {$:n}}var Mn=nn;function tn(n,t){return t===void 0||t.length===0?{$fn:n}:{$fn:n,args:t}}var In=tn;function _n(n,t,o){return o===void 0?{$if:n,then:t}:{$if:n,then:t,else:o}}function en(...n){return {$pipe:n}}var Vn=en;function on(n,t,o){return o===void 0?{left:n,op:t}:{left:n,op:t,right:o}}var Ln=on;function rn(n,t,o){return o===void 0?{$cb:n,body:t}:{$cb:n,body:t,params:o}}var qn=rn;var K="data",un="scope",Bn={eq:"===",neq:"!==",gt:">",gte:">=",lt:"<",lte:"<="};function I(n,t={}){let{dataParam:o=K,scopeParam:r=un,noPrefixes:i=false,useAccessor:s=false,lexicalPrefix:e}=t;return m(n,o,r,i,s,e)}function m(n,t,o,r,i,s){if(n===null)return builders.literal(null);if(typeof n=="string")return builders.literal(n);if(typeof n=="number")return builders.literal(n);if(typeof n=="boolean")return builders.literal(n);if(Array.isArray(n))return builders.arrayExpression(n.map(e=>m(e,t,o,r,i,s)));if(E(n))return Jn(n.$,t,r,i,s);if(S(n))return Xn(n,t,o,r,i,s);if(k(n))return Un(n.$pipe,t,o,r,i,s);if(w(n))return Yn(n,t,o,r,i,s);if(x(n))return Qn(n,t,o,r,i,s);if(h(n))return Zn(n,t,o,r,i,s);if(b(n))return Pn(n,t,o,r,i,s);if(typeof n=="object"){let f=Object.entries(n).map(([u,a])=>builders.property(builders.identifier(u),m(a,t,o,r,i,s)));return builders.objectExpression(f)}return builders.literal(null)}var X="accessor";function Y(n,t){return t?n===t||n.startsWith(t+"."):false}function Jn(n,t,o,r,i){return r?Y(n,i)?O(n,t,true):builders.callExpression(builders.identifier(X),[builders.literal(n),builders.identifier(t)]):n.includes("[*]")?Kn(n,t,o):O(n,t,o)}function O(n,t,o){let r=M(n);if(r.length===0)return o?builders.identifier("undefined"):builders.identifier(t);let i;if(o){let s=r[0];i=builders.identifier(s.value);for(let e=1;e<r.length;e++){let f=r[e];f.type==="key"?i=builders.memberExpression(i,builders.identifier(f.value),false,true):i=builders.memberExpression(i,builders.literal(f.value),true,true);}}else {i=builders.identifier(t);for(let s of r)s.type==="key"?i=builders.memberExpression(i,builders.identifier(s.value),false,true):i=builders.memberExpression(i,builders.literal(s.value),true,true);}return i}function Kn(n,t,o){let r=n.indexOf("[*]"),i=n.slice(0,r),s=n.slice(r+3),e;if(i?e=O(i,t,o):e=o?builders.identifier("undefined"):builders.identifier(t),!s||s==="")return e;if(s.includes("[*]"))return cn(e,s);let f="_i",u=s.startsWith(".")?s.slice(1):s,a=builders.identifier(f);if(u){let l=M(u);for(let p of l)p.type==="key"?a=builders.memberExpression(a,builders.identifier(p.value),false,true):a=builders.memberExpression(a,builders.literal(p.value),true,true);}return builders.callExpression(builders.memberExpression(e,builders.identifier("map"),false,true),[builders.arrowFunctionExpression([builders.identifier(f)],a)])}function cn(n,t){let o=t.indexOf("[*]"),r=t.slice(0,o),i=t.slice(o+3),s="_i",e=r.startsWith(".")?r.slice(1):r,f=builders.identifier(s);if(e){let a=M(e);for(let l of a)l.type==="key"&&(f=builders.memberExpression(f,builders.identifier(l.value),false,true));}if(i.includes("[*]")){let a=cn(f,i);return builders.callExpression(builders.memberExpression(n,builders.identifier("flatMap"),false,true),[builders.arrowFunctionExpression([builders.identifier(s)],a)])}let u=i.startsWith(".")?i.slice(1):i;if(u){let a=M(u);for(let l of a)l.type==="key"&&(f=builders.memberExpression(f,builders.identifier(l.value),false,true));}return builders.callExpression(builders.memberExpression(n,builders.identifier("flatMap"),false,true),[builders.arrowFunctionExpression([builders.identifier(s)],f)])}function Xn(n,t,o,r,i,s){let e;if(typeof n.$if=="string"){let a=n.$if.startsWith("!"),l=a?n.$if.slice(1):n.$if,p;i?Y(l,s)?p=O(l,t,true):p=builders.callExpression(builders.identifier(X),[builders.literal(l),builders.identifier(t)]):p=O(l,t,r),e=a?builders.unaryExpression("!",p):p;}else e=m(n.$if,t,o,r,i,s);let f=m(n.then,t,o,r,i,s),u=n.else!==void 0?m(n.else,t,o,r,i,s):builders.identifier("undefined");return builders.conditionalExpression(e,f,u)}function Yn(n,t,o,r,i,s){let e=r?builders.identifier(n.$fn):builders.memberExpression(builders.identifier(o),builders.identifier(n.$fn),false,false);if(n.args===void 0)return e;let f=n.args.map(u=>m(u,t,o,r,i,s));return builders.callExpression(e,f)}var Hn="context";function Qn(n,t,o,r,i,s){let e=r?builders.identifier(n.$cb):builders.memberExpression(builders.identifier(Hn),builders.identifier(n.$cb),false,false),f=m(n.body,t,o,r,i,s),a=[builders.arrowFunctionExpression([builders.identifier(t),builders.identifier("get")],f),builders.identifier(t),builders.identifier("get")];if(n.params!==void 0){let l=m(n.params,t,o,r,i,s);a.push(l);}return builders.callExpression(e,a)}function Un(n,t,o,r,i,s){if(n.length===0)return builders.identifier("undefined");if(n.length===1)return m(n[0],t,o,r,i,s);let e=m(n[0],t,o,r,i,s);for(let f=1;f<n.length;f++){let u=m(n[f],t,o,r,i,s);e=builders.callExpression(u,[e]);}return e}function fn(n,t,o,r,i,s){if(E(n)){let e=n.$;return i?Y(e,s)?O(e,t,true):builders.callExpression(builders.identifier(X),[builders.literal(e),builders.identifier(t)]):O(e,t,r)}return m(n,t,o,r,i,s)}function Zn(n,t,o,r,i,s){let e=fn(n.left,t,o,r,i,s),f=n.right!==void 0?fn(n.right,t,o,r,i,s):builders.literal(null),u=Bn[n.op];if(u)return builders.binaryExpression(u,e,f);switch(n.op){case "in":return builders.callExpression(builders.memberExpression(f,builders.identifier("includes")),[e]);case "notIn":return builders.unaryExpression("!",builders.callExpression(builders.memberExpression(f,builders.identifier("includes")),[e]));case "contains":return builders.callExpression(builders.memberExpression(e,builders.identifier("includes"),false,true),[f]);case "notContains":return builders.unaryExpression("!",builders.callExpression(builders.memberExpression(e,builders.identifier("includes"),false,true),[f]));case "exists":return builders.binaryExpression("!=",e,builders.literal(null));case "notExists":return builders.binaryExpression("==",e,builders.literal(null));case "matches":return builders.callExpression(builders.memberExpression(builders.newExpression(builders.identifier("RegExp"),[f]),builders.identifier("test")),[e]);case "notMatches":return builders.unaryExpression("!",builders.callExpression(builders.memberExpression(builders.newExpression(builders.identifier("RegExp"),[f]),builders.identifier("test")),[e]));case "startsWith":return builders.callExpression(builders.memberExpression(e,builders.identifier("startsWith"),false,true),[f]);case "endsWith":return builders.callExpression(builders.memberExpression(e,builders.identifier("endsWith"),false,true),[f]);default:return builders.binaryExpression("===",e,f)}}function Pn(n,t,o,r,i,s){let{logic:e,conditions:f}=n,u=e==="AND"?"&&":"||";if(f.length===0)return builders.literal(e==="AND");if(f.length===1)return m(f[0],t,o,r,i,s);let a=m(f[0],t,o,r,i,s);for(let l=1;l<f.length;l++){let p=m(f[l],t,o,r,i,s);a=builders.logicalExpression(u,a,p);}return a}function M(n){let t=[],o=n.length,r=0,i="";for(;r<o;){let s=n[r];if(s===".")i&&(t.push({type:"key",value:i}),i=""),r++;else if(s==="["){i&&(t.push({type:"key",value:i}),i=""),r++;let e=r;for(;r<o&&n[r]!=="]";)r++;let f=n.slice(e,r);if(r++,f!=="*"){let u=parseInt(f,10);t.push({type:"index",value:isNaN(u)?f:u});}}else i+=s,r++;}return i&&t.push({type:"key",value:i}),t}function an(n,t=[K]){return builders.arrowFunctionExpression(t.map(o=>builders.identifier(o)),n)}function _(n){let t=new Set;return $(n,t),t}function $(n,t){if(n===null||typeof n!="object")return;if(Array.isArray(n)){for(let r of n)$(r,t);return}if(E(n))return;if(S(n)){$(n.$if,t),$(n.then,t),n.else!==void 0&&$(n.else,t);return}if(k(n)){for(let r of n.$pipe)$(r,t);return}if(w(n)){if(t.add(n.$fn),n.args)for(let r of n.args)$(r,t);return}if(x(n)){$(n.body,t),n.params!==void 0&&$(n.params,t);return}if(h(n)){n.left!==void 0&&typeof n.left=="object"&&$(n.left,t),n.right!==void 0&&typeof n.right=="object"&&$(n.right,t);return}if(b(n)){for(let r of n.conditions)$(r,t);return}let o=n;for(let r of Object.keys(o))$(o[r],t);}function V(n){let t=new Set;return A(n,t),t}function A(n,t){if(n===null||typeof n!="object")return;if(Array.isArray(n)){for(let r of n)A(r,t);return}if(E(n))return;if(S(n)){A(n.$if,t),A(n.then,t),n.else!==void 0&&A(n.else,t);return}if(k(n)){for(let r of n.$pipe)A(r,t);return}if(w(n)){if(n.args)for(let r of n.args)A(r,t);return}if(x(n)){t.add(n.$cb),A(n.body,t),n.params!==void 0&&A(n.params,t);return}if(h(n)){n.left!==void 0&&typeof n.left=="object"&&A(n.left,t),n.right!==void 0&&typeof n.right=="object"&&A(n.right,t);return}if(b(n)){for(let r of n.conditions)A(r,t);return}let o=n;for(let r of Object.keys(o))A(o[r],t);}function L(n){let t=new Set;for(let o of n){let r=o.indexOf("."),i=o.indexOf("["),s=o.length;r!==-1&&(s=Math.min(s,r)),i!==-1&&(s=Math.min(s,i));let e=o.slice(0,s);e&&t.add(e);}return t}function tt(n){return JSON.stringify(n)}function et(n,t,o,r,i,s){let e=I(n,{noPrefixes:true,useAccessor:i,lexicalPrefix:s}),f=generate(e),u="";i?s&&(u=`const{${s}}=data??{};`):t.size>0&&(u=`const{${[...t].join(",")}}=data??{};`);let a=i?new Set([...o,"accessor"]):o,l=a.size>0?`const{${[...a].join(",")}}=scope;`:"",p=r.size>0?`const{${[...r].join(",")}}=context;`:"",d=r.size>0,g="";d&&(i?g="const get=(path)=>accessor(path,data);":g="const get=(path)=>path.split('.').reduce((o,k)=>o?.[k],data);");let F=a.size>0,N;if(F||d){let pn=d?"scope,context":"scope",dn=`${u}${g}return ${f}`;N=`(function(${pn}){${l}${p}return function(data){${dn}}})`;}else N=`(function(){return function(data){${u}return ${f}}})`;return N}function H(n,t={}){let{scope:o={},context:r={},returnCode:i=false,useAccessor:s=false,lexicalPrefix:e}=t,f=R(n),u=L(f),a=_(n),l=V(n),p=tt(n),d=et(n,u,a,l,s,e);if(i)return {code:d,deps:f,hash:p,dataRoots:[...u],scopeFns:[...a],contextFns:[...l]};let g;try{let F=l.size>0,N=new Function(`return ${d}`)();g=F?N(o,r):N(o);}catch(F){throw new Error(`AST compilation failed. If this is due to CSP, use the standard compile() function instead. Error: ${F instanceof Error?F.message:String(F)}`)}return {fn:g,deps:f,hash:p}}function ln(n,t,o={}){let{fn:r}=H(n,o);return r(t)}function it(n,t){return q(n,t)}function q(n,t){if(n===null)return null;if(typeof n!="object")return n;if(Array.isArray(n))return n.map(s=>q(s,t));let o=n,r=Object.keys(o);for(let s of r)if(s in t){let e=t[s](o);if(typeof e=="object"&&e!==null&&s in e)throw new Error(`Transform "${s}" returned object with same key \u2014 infinite loop`);return q(e,t)}let i={};for(let s of r)i[s]=q(o[s],t);return i}var vt="2.0.0";export{D as ExpressionCache,vt as VERSION,zn as assertValid,sn as builders,P as cache,Wn as cached,$n as clearPathCache,z as compile,H as compileAST,j as compilePath,I as dslToAST,Gn as evaluate,ln as evaluateAST,V as extractContextFns,L as extractDataRoots,R as extractDeps,_ as extractScopeFns,Tn as get,An as getPathCacheSize,Sn as hasDeps,U as hasWildcard,x as isCb,h as isCondition,yn as isConditionExpr,b as isConditionGroup,S as isConditional,w as isFn,B as isLiteral,k as isPipe,wn as isPure,E as isRef,Dn as isValid,it as normalize,W as normalizePath,J as validate,an as wrapInFunction};
|
|
1
|
+
import {builders,generate}from'omni-ast';var yn=Object.defineProperty;var En=(n,t)=>{for(var o in t)yn(n,o,{get:t[o],enumerable:true});};var E=n=>n!==null&&typeof n=="object"&&"$"in n&&typeof n.$=="string"&&Object.keys(n).length===1,x=n=>n!==null&&typeof n=="object"&&"$if"in n&&"then"in n,S=n=>n!==null&&typeof n=="object"&&"$fn"in n&&typeof n.$fn=="string",R=n=>n!==null&&typeof n=="object"&&"$pipe"in n&&Array.isArray(n.$pipe),k=n=>n!==null&&typeof n=="object"&&"$cb"in n&&typeof n.$cb=="string"&&"body"in n,I=new Set(["eq","neq","gt","gte","lt","lte","in","notIn","contains","notContains","exists","notExists","matches","notMatches","startsWith","endsWith"]),h=n=>n!==null&&typeof n=="object"&&"left"in n&&"op"in n&&I.has(n.op)&&!("$"in n)&&!("$if"in n)&&!("$fn"in n),b=n=>n!==null&&typeof n=="object"&&"logic"in n&&"conditions"in n,hn=n=>h(n)||b(n),J=n=>{if(n===null)return true;let t=typeof n;if(t==="string"||t==="number"||t==="boolean"||Array.isArray(n))return true;if(t==="object"&&n!==null){let o=n,r="left"in o&&"op"in o&&I.has(o.op);return !("$"in o)&&!("$if"in o)&&!("$fn"in o)&&!("$pipe"in o)&&!("$cb"in o)&&!r&&!("logic"in o)}return false};var W=new Map;function U(n){let t=[],o=n.length,r=0,i="";for(;r<o;){let s=n[r];if(s===".")i&&(t.push({type:"key",value:i}),i=""),r++;else if(s==="["){i&&(t.push({type:"key",value:i}),i=""),r++;let e=r;for(;r<o&&n[r]!=="]";)r++;let u=n.slice(e,r);if(r++,u==="*")t.push({type:"wildcard",value:"*"});else {let f=parseInt(u,10);t.push({type:"index",value:isNaN(f)?u:f});}}else i+=s,r++;}return i&&t.push({type:"key",value:i}),t}function Z(n){return n.includes("[*]")}function j(n){let t=W.get(n);return t||(t=Z(n)?Cn(n):bn(n),W.set(n,t),t)}function bn(n){if(!n.includes(".")&&!n.includes("["))return i=>i?.[n];let t=U(n),o=t.length;if(o===2){let[i,s]=t,e=i.value,u=s.value;return f=>f?.[e]?.[u]}if(o===3){let[i,s,e]=t,u=i.value,f=s.value,l=e.value;return a=>a?.[u]?.[f]?.[l]}let r=t.map(i=>i.value);return i=>{let s=i;for(let e=0;e<o&&s!=null;e++)s=s[r[e]];return s}}function Cn(n){let t=U(n),o=[];for(let r=0;r<t.length;r++)t[r].type==="wildcard"&&o.push(r);return o.length===1?Tn(t,o[0]):$n(t,o)}function Tn(n,t){let o=n.slice(0,t).map(e=>e.value),r=n.slice(t+1).map(e=>e.value),i=o.length,s=r.length;if(s===0){if(i===1){let e=o[0];return u=>u?.[e]}return e=>{let u=e;for(let f=0;f<i&&u!=null;f++)u=u[o[f]];return u}}if(s===1){let e=r[0];if(i===1){let u=o[0];return f=>{let l=f?.[u];if(Array.isArray(l))return l.map(a=>a?.[e])}}return u=>{let f=u;for(let l=0;l<i&&f!=null;l++)f=f[o[l]];if(Array.isArray(f))return f.map(l=>l?.[e])}}return e=>{let u=e;for(let f=0;f<i&&u!=null;f++)u=u[o[f]];if(Array.isArray(u))return u.map(f=>{let l=f;for(let a=0;a<s&&l!=null;a++)l=l[r[a]];return l})}}function $n(n,t){let o=[],r=0;for(let s=0;s<t.length;s++){let e=t[s],u=s===t.length-1,f=n.slice(r,e).map(l=>l.value);f.length>0&&o.push({type:"access",keys:f}),o.push({type:u?"map":"flatMap",keys:[]}),r=e+1;}let i=n.slice(r).map(s=>s.value);return s=>{let e=s;for(let u of o){if(e==null)return;if(u.type==="access")for(let f of u.keys){if(e==null)return;e=e[f];}else if(u.type==="flatMap"){if(!Array.isArray(e))return;e=e.flatMap(f=>{let l=f;return Array.isArray(l)?l:[l]});}else if(u.type==="map"){if(!Array.isArray(e))return;i.length>0&&(e=e.map(f=>{let l=f;for(let a of i){if(l==null)return;l=l[a];}return l}));}}return e}}function An(n,t){return j(t)(n)}function z(n){let t=n.indexOf("[*]");return t===-1?n:n.slice(0,t)}function xn(){W.clear();}function Sn(){return W.size}function O(n){let t=new Set;return C(n,t),Array.from(t)}function C(n,t){if(n===null||typeof n!="object")return;if(Array.isArray(n)){for(let i=0;i<n.length;i++)C(n[i],t);return}if(E(n)){t.add(z(n.$));return}if(x(n)){if(typeof n.$if=="string"){let i=n.$if.startsWith("!")?n.$if.slice(1):n.$if;t.add(z(i));}else C(n.$if,t);C(n.then,t),n.else!==void 0&&C(n.else,t);return}if(R(n)){for(let i=0;i<n.$pipe.length;i++)C(n.$pipe[i],t);return}if(S(n)){if(n.args)for(let i=0;i<n.args.length;i++)C(n.args[i],t);return}if(k(n)){C(n.body,t),n.params!==void 0&&C(n.params,t);return}if(h(n)){C(n.left,t),n.right!==void 0&&C(n.right,t);return}if(b(n)){for(let i=0;i<n.conditions.length;i++)C(n.conditions[i],t);return}let o=n,r=Object.keys(o);for(let i=0;i<r.length;i++)C(o[r[i]],t);}function Rn(n){return O(n).length>0}function kn(n){return O(n).length===0}function wn(n){return JSON.stringify(n)}function N(n,t={}){let o=t.scope??{},r=t.accessor,i=t.context??{},s=y(n,o,r,i),e=O(n),u=wn(n);return {fn:s,deps:e,hash:u}}function y(n,t,o,r){if(n===null)return ()=>null;if(typeof n!="object")return ()=>n;if(Array.isArray(n)){let i=n.map(s=>y(s,t,o,r));return s=>i.map(e=>e(s))}if(E(n))return Fn(n,o);if(x(n))return On(n,t,o,r);if(R(n))return vn(n,t,o,r);if(S(n))return jn(n,t,o,r);if(k(n))return Nn(n,t,o,r);if(h(n))return Gn(n,t,o,r);if(b(n))return In(n,t,o,r);if(J(n)){let i=n,s=Object.keys(i),e=s.map(u=>y(i[u],t,o,r));return u=>{let f={};for(let l=0;l<s.length;l++)f[s[l]]=e[l](u);return f}}return ()=>n}function nn(n,t){return t?o=>t(n,o):j(n)}function Fn(n,t){return nn(n.$,t)}function On(n,t,o,r){let i;if(typeof n.$if=="string"){let u=n.$if.startsWith("!")?n.$if.slice(1):n.$if,f=nn(u,o);i=n.$if.startsWith("!")?a=>!f(a):a=>!!f(a);}else {let u=y(n.$if,t,o,r);i=f=>!!u(f);}let s=y(n.then,t,o,r),e=n.else!==void 0?y(n.else,t,o,r):()=>{};return u=>i(u)?s(u):e(u)}function vn(n,t,o,r){let i=n.$pipe;if(i.length===0)return ()=>{};if(i.length===1)return y(i[0],t,o,r);let s=y(i[0],t,o,r),e=i.slice(1).map(f=>y(f,t,o,r)),u=e.length;if(u===1){let[f]=e;return l=>{let a=s(l),p=f(l);return typeof p=="function"?p(a):p}}if(u===2){let[f,l]=e;return a=>{let p=s(a),d=f(a);return p=typeof d=="function"?d(p):d,d=l(a),typeof d=="function"?d(p):d}}if(u===3){let[f,l,a]=e;return p=>{let d=s(p),g=f(p);return d=typeof g=="function"?g(d):g,g=l(p),d=typeof g=="function"?g(d):g,g=a(p),typeof g=="function"?g(d):g}}return f=>{let l=s(f);for(let a=0;a<u;a++){let p=e[a](f);l=typeof p=="function"?p(l):p;}return l}}function jn(n,t,o,r){let i=n.$fn,s=n.args;if(s===void 0)return ()=>{let f=t[i];if(!f)throw new Error(`Function not found in scope: ${i}`);return f};let e=s.map(f=>y(f,t,o,r)),u=e.length;if(u===0)return ()=>{let f=t[i];if(!f)throw new Error(`Function not found in scope: ${i}`);return f()};if(u===1){let[f]=e;return l=>{let a=t[i];if(!a)throw new Error(`Function not found in scope: ${i}`);return a(f(l))}}if(u===2){let[f,l]=e;return a=>{let p=t[i];if(!p)throw new Error(`Function not found in scope: ${i}`);return p(f(a),l(a))}}if(u===3){let[f,l,a]=e;return p=>{let d=t[i];if(!d)throw new Error(`Function not found in scope: ${i}`);return d(f(p),l(p),a(p))}}return f=>{let l=t[i];if(!l)throw new Error(`Function not found in scope: ${i}`);return l(...e.map(a=>a(f)))}}function Nn(n,t,o,r){let i=n.$cb,s,e=(a,p)=>s?s(a):o?o(a,p):j(a)(p),u=y(n.body,t,e,r),f=n.params?y(n.params,t,o,r):void 0,l=a=>o?p=>o(p,a):p=>j(p)(a);return a=>{let p=r?.[i];if(!p)throw new Error(`Context function not found: ${i}`);let d=l(a),g={data:a,get:d},w=G=>{G.get!==d&&(s=G.get);try{return u(G.data)}finally{s=void 0;}},F=f?f(a):void 0;return p(w,g,F)}}function Gn(n,t,o,r){let i=y(n.left,t,o,r),s=n.right!==void 0?y(n.right,t,o,r):()=>{};switch(n.op){case "eq":return e=>i(e)===s(e);case "neq":return e=>i(e)!==s(e);case "gt":return e=>i(e)>s(e);case "gte":return e=>i(e)>=s(e);case "lt":return e=>i(e)<s(e);case "lte":return e=>i(e)<=s(e);case "in":return e=>{let u=s(e);return Array.isArray(u)&&u.includes(i(e))};case "notIn":return e=>{let u=s(e);return !Array.isArray(u)||!u.includes(i(e))};case "contains":return e=>{let u=i(e);return Array.isArray(u)&&u.includes(s(e))};case "notContains":return e=>{let u=i(e);return !Array.isArray(u)||!u.includes(s(e))};case "exists":return e=>i(e)!==void 0;case "notExists":return e=>i(e)===void 0;case "matches":return e=>{let u=i(e),f=s(e);return typeof u!="string"||typeof f!="string"?false:new RegExp(f).test(u)};case "notMatches":return e=>{let u=i(e),f=s(e);return typeof u!="string"||typeof f!="string"?true:!new RegExp(f).test(u)};case "startsWith":return e=>{let u=i(e),f=s(e);return typeof u=="string"&&typeof f=="string"&&u.startsWith(f)};case "endsWith":return e=>{let u=i(e),f=s(e);return typeof u=="string"&&typeof f=="string"&&u.endsWith(f)}}}function In(n,t,o,r){let i=n.conditions.map(e=>y(e,t,o,r)),s=i.length;if(s===1)return e=>!!i[0](e);if(s===2){let[e,u]=i;return n.logic==="AND"?f=>!!e(f)&&!!u(f):f=>!!e(f)||!!u(f)}if(s===3){let[e,u,f]=i;return n.logic==="AND"?l=>!!e(l)&&!!u(l)&&!!f(l):l=>!!e(l)||!!u(l)||!!f(l)}return n.logic==="AND"?e=>{for(let u=0;u<s;u++)if(!i[u](e))return false;return true}:e=>{for(let u=0;u<s;u++)if(i[u](e))return true;return false}}function Wn(n,t,o={}){return N(n,o).fn(t)}var D=class{constructor(t=1e3){this.cache=new Map,this._maxSize=t;}get(t,o={}){let r=JSON.stringify(t),i=this.cache.get(r);if(i)return this.cache.delete(r),this.cache.set(r,i),i;let s=N(t,o);if(this.cache.size>=this._maxSize){let e=this.cache.keys().next().value;e&&this.cache.delete(e);}return this.cache.set(r,s),s}has(t){return this.cache.has(JSON.stringify(t))}delete(t){return this.cache.delete(JSON.stringify(t))}clear(){this.cache.clear();}get size(){return this.cache.size}get maxSize(){return this._maxSize}set maxSize(t){for(this._maxSize=t;this.cache.size>this._maxSize;){let o=this.cache.keys().next().value;o&&this.cache.delete(o);}}},tn=new D;function zn(n,t={}){return tn.get(n,t)}function K(n,t="root",o={}){let r=[];return T(n,t,r,o),{valid:r.length===0,errors:r}}function T(n,t,o,r){if(n===null||typeof n!="object")return;if(Array.isArray(n)){for(let e=0;e<n.length;e++)T(n[e],`${t}[${e}]`,o,r);return}if(E(n)){(!n.$||typeof n.$!="string")&&o.push(`${t}: invalid reference, $ must be non-empty string`);return}if(x(n)){typeof n.$if=="string"?(n.$if.startsWith("!")?n.$if.slice(1):n.$if)||o.push(`${t}.$if: empty path in string shorthand`):T(n.$if,`${t}.$if`,o,r),T(n.then,`${t}.then`,o,r),n.else!==void 0&&T(n.else,`${t}.else`,o,r);return}if(R(n)){if(!Array.isArray(n.$pipe)){o.push(`${t}.$pipe: must be an array`);return}if(n.$pipe.length===0){o.push(`${t}.$pipe: must have at least one element`);return}for(let e=0;e<n.$pipe.length;e++)T(n.$pipe[e],`${t}.$pipe[${e}]`,o,r);return}if(S(n)){if(!n.$fn||typeof n.$fn!="string"){o.push(`${t}: invalid function, $fn must be non-empty string`);return}if(r.scope&&!(n.$fn in r.scope)&&o.push(`${t}: function "${n.$fn}" not found in scope`),n.args!==void 0)if(!Array.isArray(n.args))o.push(`${t}.args: must be an array`);else for(let e=0;e<n.args.length;e++)T(n.args[e],`${t}.args[${e}]`,o,r);return}if(k(n)){if(!n.$cb||typeof n.$cb!="string"){o.push(`${t}: invalid callback, $cb must be non-empty string`);return}r.context&&!(n.$cb in r.context)&&o.push(`${t}: context function "${n.$cb}" not found`),T(n.body,`${t}.body`,o,r),n.params!==void 0&&T(n.params,`${t}.params`,o,r);return}if(h(n)){I.has(n.op)||o.push(`${t}: invalid operator "${n.op}"`),T(n.left,`${t}.left`,o,r),n.right!==void 0&&T(n.right,`${t}.right`,o,r);return}if(b(n)){if(n.logic!=="AND"&&n.logic!=="OR"&&o.push(`${t}: invalid logic "${n.logic}", must be "AND" or "OR"`),!Array.isArray(n.conditions)){o.push(`${t}.conditions: must be an array`);return}for(let e=0;e<n.conditions.length;e++)T(n.conditions[e],`${t}.conditions[${e}]`,o,r);return}let i=n,s=Object.keys(i);for(let e=0;e<s.length;e++){let u=s[e];T(i[u],`${t}.${u}`,o,r);}}function Dn(n,t={}){let o=K(n,"root",t);if(!o.valid)throw new Error(`Invalid expression: ${o.errors.join("; ")}`)}function Mn(n,t={}){return K(n,"root",t).valid}var cn={};En(cn,{$:()=>en,$call:()=>fn,$cb:()=>un,$cond:()=>sn,$fn:()=>on,$if:()=>_n,$pipe:()=>rn,call:()=>Kn,cb:()=>Jn,cond:()=>qn,fn:()=>Vn,pipe:()=>Ln,ref:()=>Bn});function en(n){return {$:n}}var Bn=en;function on(n,t){return t===void 0||t.length===0?{$fn:n}:{$fn:n,args:t}}var Vn=on;function _n(n,t,o){return o===void 0?{$if:n,then:t}:{$if:n,then:t,else:o}}function rn(...n){return {$pipe:n}}var Ln=rn;function sn(n,t,o){return o===void 0?{left:n,op:t}:{left:n,op:t,right:o}}var qn=sn;function un(n,t,o){return o===void 0?{$cb:n,body:t}:{$cb:n,body:t,params:o}}var Jn=un;function fn(n,t=[]){return {$fn:n,args:t}}var Kn=fn;var P="data",an="scope",Pn={eq:"===",neq:"!==",gt:">",gte:">=",lt:"<",lte:"<="};function B(n,t={}){let{dataParam:o=P,scopeParam:r=an,noPrefixes:i=false,useAccessor:s=false,lexicalPrefix:e}=t;return m(n,o,r,i,s,e)}function m(n,t,o,r,i,s){if(n===null)return builders.literal(null);if(typeof n=="string")return builders.literal(n);if(typeof n=="number")return builders.literal(n);if(typeof n=="boolean")return builders.literal(n);if(Array.isArray(n))return builders.arrayExpression(n.map(e=>m(e,t,o,r,i,s)));if(E(n))return Xn(n.$,t,r,i,s);if(x(n))return Hn(n,t,o,r,i,s);if(R(n))return nt(n.$pipe,t,o,r,i,s);if(S(n))return Qn(n,t,o,r,i,s);if(k(n))return Zn(n,t,o,r,i,s);if(h(n))return tt(n,t,o,r,i,s);if(b(n))return et(n,t,o,r,i,s);if(typeof n=="object"){let u=Object.entries(n).map(([f,l])=>builders.property(builders.identifier(f),m(l,t,o,r,i,s)));return builders.objectExpression(u)}return builders.literal(null)}var X="accessor";function Y(n,t){return t?n===t||n.startsWith(t+"."):false}function Xn(n,t,o,r,i){return r?Y(n,i)?v(n,t,true):builders.callExpression(builders.identifier(X),[builders.literal(n),builders.identifier(t)]):n.includes("[*]")?Yn(n,t,o):v(n,t,o)}function v(n,t,o){let r=M(n);if(r.length===0)return o?builders.identifier("undefined"):builders.identifier(t);let i;if(o){let s=r[0];i=builders.identifier(s.value);for(let e=1;e<r.length;e++){let u=r[e];u.type==="key"?i=builders.memberExpression(i,builders.identifier(u.value),false,true):i=builders.memberExpression(i,builders.literal(u.value),true,true);}}else {i=builders.identifier(t);for(let s of r)s.type==="key"?i=builders.memberExpression(i,builders.identifier(s.value),false,true):i=builders.memberExpression(i,builders.literal(s.value),true,true);}return i}function Yn(n,t,o){let r=n.indexOf("[*]"),i=n.slice(0,r),s=n.slice(r+3),e;if(i?e=v(i,t,o):e=o?builders.identifier("undefined"):builders.identifier(t),!s||s==="")return e;if(s.includes("[*]"))return pn(e,s);let u="_i",f=s.startsWith(".")?s.slice(1):s,l=builders.identifier(u);if(f){let a=M(f);for(let p of a)p.type==="key"?l=builders.memberExpression(l,builders.identifier(p.value),false,true):l=builders.memberExpression(l,builders.literal(p.value),true,true);}return builders.callExpression(builders.memberExpression(e,builders.identifier("map"),false,true),[builders.arrowFunctionExpression([builders.identifier(u)],l)])}function pn(n,t){let o=t.indexOf("[*]"),r=t.slice(0,o),i=t.slice(o+3),s="_i",e=r.startsWith(".")?r.slice(1):r,u=builders.identifier(s);if(e){let l=M(e);for(let a of l)a.type==="key"&&(u=builders.memberExpression(u,builders.identifier(a.value),false,true));}if(i.includes("[*]")){let l=pn(u,i);return builders.callExpression(builders.memberExpression(n,builders.identifier("flatMap"),false,true),[builders.arrowFunctionExpression([builders.identifier(s)],l)])}let f=i.startsWith(".")?i.slice(1):i;if(f){let l=M(f);for(let a of l)a.type==="key"&&(u=builders.memberExpression(u,builders.identifier(a.value),false,true));}return builders.callExpression(builders.memberExpression(n,builders.identifier("flatMap"),false,true),[builders.arrowFunctionExpression([builders.identifier(s)],u)])}function Hn(n,t,o,r,i,s){let e;if(typeof n.$if=="string"){let l=n.$if.startsWith("!"),a=l?n.$if.slice(1):n.$if,p;i?Y(a,s)?p=v(a,t,true):p=builders.callExpression(builders.identifier(X),[builders.literal(a),builders.identifier(t)]):p=v(a,t,r),e=l?builders.unaryExpression("!",p):p;}else e=m(n.$if,t,o,r,i,s);let u=m(n.then,t,o,r,i,s),f=n.else!==void 0?m(n.else,t,o,r,i,s):builders.identifier("undefined");return builders.conditionalExpression(e,u,f)}function Qn(n,t,o,r,i,s){let e=r?builders.identifier(n.$fn):builders.memberExpression(builders.identifier(o),builders.identifier(n.$fn),false,false);if(n.args===void 0)return e;let u=n.args.map(f=>m(f,t,o,r,i,s));return builders.callExpression(e,u)}var Un="context";function Zn(n,t,o,r,i,s){let e=r?builders.identifier(n.$cb):builders.memberExpression(builders.identifier(Un),builders.identifier(n.$cb),false,false),u=m(n.body,t,o,r,i,s),l=[builders.arrowFunctionExpression([builders.identifier("ctx")],u),builders.identifier("ctx")];if(n.params!==void 0){let a=m(n.params,t,o,r,i,s);l.push(a);}return builders.callExpression(e,l)}function nt(n,t,o,r,i,s){if(n.length===0)return builders.identifier("undefined");if(n.length===1)return m(n[0],t,o,r,i,s);let e=m(n[0],t,o,r,i,s);for(let u=1;u<n.length;u++){let f=m(n[u],t,o,r,i,s);e=builders.callExpression(f,[e]);}return e}function ln(n,t,o,r,i,s){if(E(n)){let e=n.$;return i?Y(e,s)?v(e,t,true):builders.callExpression(builders.identifier(X),[builders.literal(e),builders.identifier(t)]):v(e,t,r)}return m(n,t,o,r,i,s)}function tt(n,t,o,r,i,s){let e=ln(n.left,t,o,r,i,s),u=n.right!==void 0?ln(n.right,t,o,r,i,s):builders.literal(null),f=Pn[n.op];if(f)return builders.binaryExpression(f,e,u);switch(n.op){case "in":return builders.callExpression(builders.memberExpression(u,builders.identifier("includes")),[e]);case "notIn":return builders.unaryExpression("!",builders.callExpression(builders.memberExpression(u,builders.identifier("includes")),[e]));case "contains":return builders.callExpression(builders.memberExpression(e,builders.identifier("includes"),false,true),[u]);case "notContains":return builders.unaryExpression("!",builders.callExpression(builders.memberExpression(e,builders.identifier("includes"),false,true),[u]));case "exists":return builders.binaryExpression("!=",e,builders.literal(null));case "notExists":return builders.binaryExpression("==",e,builders.literal(null));case "matches":return builders.callExpression(builders.memberExpression(builders.newExpression(builders.identifier("RegExp"),[u]),builders.identifier("test")),[e]);case "notMatches":return builders.unaryExpression("!",builders.callExpression(builders.memberExpression(builders.newExpression(builders.identifier("RegExp"),[u]),builders.identifier("test")),[e]));case "startsWith":return builders.callExpression(builders.memberExpression(e,builders.identifier("startsWith"),false,true),[u]);case "endsWith":return builders.callExpression(builders.memberExpression(e,builders.identifier("endsWith"),false,true),[u]);default:return builders.binaryExpression("===",e,u)}}function et(n,t,o,r,i,s){let{logic:e,conditions:u}=n,f=e==="AND"?"&&":"||";if(u.length===0)return builders.literal(e==="AND");if(u.length===1)return m(u[0],t,o,r,i,s);let l=m(u[0],t,o,r,i,s);for(let a=1;a<u.length;a++){let p=m(u[a],t,o,r,i,s);l=builders.logicalExpression(f,l,p);}return l}function M(n){let t=[],o=n.length,r=0,i="";for(;r<o;){let s=n[r];if(s===".")i&&(t.push({type:"key",value:i}),i=""),r++;else if(s==="["){i&&(t.push({type:"key",value:i}),i=""),r++;let e=r;for(;r<o&&n[r]!=="]";)r++;let u=n.slice(e,r);if(r++,u!=="*"){let f=parseInt(u,10);t.push({type:"index",value:isNaN(f)?u:f});}}else i+=s,r++;}return i&&t.push({type:"key",value:i}),t}function dn(n,t=[P]){return builders.arrowFunctionExpression(t.map(o=>builders.identifier(o)),n)}function V(n){let t=new Set;return $(n,t),t}function $(n,t){if(n===null||typeof n!="object")return;if(Array.isArray(n)){for(let r of n)$(r,t);return}if(E(n))return;if(x(n)){$(n.$if,t),$(n.then,t),n.else!==void 0&&$(n.else,t);return}if(R(n)){for(let r of n.$pipe)$(r,t);return}if(S(n)){if(t.add(n.$fn),n.args)for(let r of n.args)$(r,t);return}if(k(n)){$(n.body,t),n.params!==void 0&&$(n.params,t);return}if(h(n)){n.left!==void 0&&typeof n.left=="object"&&$(n.left,t),n.right!==void 0&&typeof n.right=="object"&&$(n.right,t);return}if(b(n)){for(let r of n.conditions)$(r,t);return}let o=n;for(let r of Object.keys(o))$(o[r],t);}function _(n){let t=new Set;return A(n,t),t}function A(n,t){if(n===null||typeof n!="object")return;if(Array.isArray(n)){for(let r of n)A(r,t);return}if(E(n))return;if(x(n)){A(n.$if,t),A(n.then,t),n.else!==void 0&&A(n.else,t);return}if(R(n)){for(let r of n.$pipe)A(r,t);return}if(S(n)){if(n.args)for(let r of n.args)A(r,t);return}if(k(n)){t.add(n.$cb),A(n.body,t),n.params!==void 0&&A(n.params,t);return}if(h(n)){n.left!==void 0&&typeof n.left=="object"&&A(n.left,t),n.right!==void 0&&typeof n.right=="object"&&A(n.right,t);return}if(b(n)){for(let r of n.conditions)A(r,t);return}let o=n;for(let r of Object.keys(o))A(o[r],t);}function L(n){let t=new Set;for(let o of n){let r=o.indexOf("."),i=o.indexOf("["),s=o.length;r!==-1&&(s=Math.min(s,r)),i!==-1&&(s=Math.min(s,i));let e=o.slice(0,s);e&&t.add(e);}return t}function ot(n){return JSON.stringify(n)}function rt(n,t,o,r,i,s){let e=B(n,{noPrefixes:true,useAccessor:i,lexicalPrefix:s}),u=generate(e),f="";i?s&&(f=`const{${s}}=data??{};`):t.size>0&&(f=`const{${[...t].join(",")}}=data??{};`);let l=i?new Set([...o,"accessor"]):o,a=l.size>0?`const{${[...l].join(",")}}=scope;`:"",p=r.size>0?`const{${[...r].join(",")}}=context;`:"",d=r.size>0,g="";d&&(i?g="const get=(path)=>accessor(path,data);const ctx={data,get};":g="const get=(path)=>path.split('.').reduce((o,k)=>o?.[k],data);const ctx={data,get};");let w=l.size>0,F;if(w||d){let G=d?"scope,context":"scope",mn=`${f}${g}return ${u}`;F=`(function(${G}){${a}${p}return function(data){${mn}}})`;}else F=`(function(){return function(data){${f}return ${u}}})`;return F}function H(n,t={}){let{scope:o={},context:r={},returnCode:i=false,useAccessor:s=false,lexicalPrefix:e}=t,u=O(n),f=L(u),l=V(n),a=_(n),p=ot(n),d=rt(n,f,l,a,s,e);if(i)return {code:d,deps:u,hash:p,dataRoots:[...f],scopeFns:[...l],contextFns:[...a]};let g;try{let w=a.size>0,F=new Function(`return ${d}`)();g=w?F(o,r):F(o);}catch(w){throw new Error(`AST compilation failed. If this is due to CSP, use the standard compile() function instead. Error: ${w instanceof Error?w.message:String(w)}`)}return {fn:g,deps:u,hash:p}}function gn(n,t,o={}){let{fn:r}=H(n,o);return r(t)}function st(n,t){return q(n,t)}function q(n,t){if(n===null)return null;if(typeof n!="object")return n;if(Array.isArray(n))return n.map(s=>q(s,t));let o=n,r=Object.keys(o);for(let s of r)if(s in t){let e=t[s](o);if(typeof e=="object"&&e!==null&&s in e)throw new Error(`Transform "${s}" returned object with same key \u2014 infinite loop`);return q(e,t)}let i={};for(let s of r)i[s]=q(o[s],t);return i}var ut=new Set(["$","$if","$fn","$pipe","$cb"]);function ft(){let n=0;return ()=>String(n++)}function ct(n,t){let{resolvers:o,scope:r={},genId:i,...s}=t,e=Object.keys(o);if(e.length===0)return {expr:n,scope:r};let u=new Set(e),f=[],l={compile:N,genId:i??ft(),scope:r,options:s},a=Q(n,u,o,l,f),p={...r};for(let d=0;d<f.length;d++){let[g,w]=f[d];p[g]=w;}return {expr:a,scope:p}}function Q(n,t,o,r,i){if(n===null)return null;if(typeof n!="object")return n;if(Array.isArray(n)){let l=n.length,a=new Array(l);for(let p=0;p<l;p++)a[p]=Q(n[p],t,o,r,i);return a}let s=n,e=Object.keys(s),u=e.length;for(let l=0;l<u;l++){let a=e[l];if(a[0]==="$"&&!ut.has(a)&&t.has(a)){let p=o[a],d=p(s,r);return d.scopeEntry&&i.push(d.scopeEntry),d.expr}}let f={};for(let l=0;l<u;l++){let a=e[l];f[a]=Q(s[a],t,o,r,i);}return f}var Vt="2.0.0";export{D as ExpressionCache,Vt as VERSION,Dn as assertValid,cn as builders,tn as cache,zn as cached,xn as clearPathCache,N as compile,H as compileAST,j as compilePath,B as dslToAST,Wn as evaluate,gn as evaluateAST,_ as extractContextFns,L as extractDataRoots,O as extractDeps,V as extractScopeFns,An as get,Sn as getPathCacheSize,Rn as hasDeps,Z as hasWildcard,k as isCb,h as isCondition,hn as isConditionExpr,b as isConditionGroup,x as isConditional,S as isFn,J as isLiteral,R as isPipe,kn as isPure,E as isRef,Mn as isValid,st as normalize,z as normalizePath,ct as resolveBoundaries,K as validate,dn as wrapInFunction};
|