@statedelta-libs/expressions 0.0.2 → 0.1.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 +138 -3
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +151 -8
- package/dist/index.d.ts +151 -8
- package/dist/index.js +1 -1
- package/package.json +17 -14
- package/LICENSE +0 -21
package/README.md
CHANGED
|
@@ -8,8 +8,9 @@
|
|
|
8
8
|
## Características
|
|
9
9
|
|
|
10
10
|
- **Compilação** - Compila uma vez, executa milhões de vezes
|
|
11
|
-
- **Alta performance** - ~
|
|
11
|
+
- **Alta performance** - ~25-30M ops/s após compilação
|
|
12
12
|
- **Scope externo** - Funções vêm via scope, não hardcoded
|
|
13
|
+
- **Accessor customizado** - Suporte a `ctx.get(path)` para objetos especiais
|
|
13
14
|
- **$pipe** - Composição com valor inicial (sintaxe DSL)
|
|
14
15
|
- **Path syntax** - Suporte a wildcards (`items[*].price`)
|
|
15
16
|
- **Dependency extraction** - Para dirty tracking/reatividade
|
|
@@ -221,6 +222,42 @@ const scope = {
|
|
|
221
222
|
const { fn } = compile(expression, { scope });
|
|
222
223
|
```
|
|
223
224
|
|
|
225
|
+
## Accessor Customizado
|
|
226
|
+
|
|
227
|
+
Para objetos que usam interface de acesso customizada (como `ctx.get(path)`), use o `accessor`:
|
|
228
|
+
|
|
229
|
+
```typescript
|
|
230
|
+
// Contexto com método get() customizado
|
|
231
|
+
interface TickContext {
|
|
232
|
+
get(path: string): unknown;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
const accessor = (path: string, ctx: TickContext) => ctx.get(path);
|
|
236
|
+
|
|
237
|
+
// Compilação com accessor
|
|
238
|
+
const { fn } = compile<TickContext>(
|
|
239
|
+
{ $: "hp:value" },
|
|
240
|
+
{ accessor }
|
|
241
|
+
);
|
|
242
|
+
|
|
243
|
+
fn(tickContext); // usa ctx.get('hp:value')
|
|
244
|
+
|
|
245
|
+
// Com scope + accessor
|
|
246
|
+
const { fn } = compile<TickContext>(
|
|
247
|
+
{ $fn: "add", args: [{ $: "a" }, { $: "b" }] },
|
|
248
|
+
{ scope, accessor }
|
|
249
|
+
);
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
O accessor é propagado para:
|
|
253
|
+
- Referências (`{ $: "path" }`)
|
|
254
|
+
- Shorthand de `$if` (`{ $if: "path", ... }`)
|
|
255
|
+
- Argumentos de `$fn`
|
|
256
|
+
- Steps de `$pipe`
|
|
257
|
+
- Conditions (delegadas para `@statedelta-libs/conditions`)
|
|
258
|
+
|
|
259
|
+
**Performance:** Igual ao acesso direto (~25-30M ops/s).
|
|
260
|
+
|
|
224
261
|
## Path Syntax
|
|
225
262
|
|
|
226
263
|
| Path | Resultado |
|
|
@@ -253,11 +290,12 @@ cache.clear(); // Limpar
|
|
|
253
290
|
| Operação | Velocidade |
|
|
254
291
|
|----------|------------|
|
|
255
292
|
| Compile (literal) | ~6.5M ops/s |
|
|
256
|
-
| Compile (ref) | ~
|
|
293
|
+
| Compile (ref) | ~3M ops/s |
|
|
257
294
|
| Compile (fn nested) | ~550K ops/s |
|
|
258
295
|
| Compile (complex) | ~300K ops/s |
|
|
259
|
-
| Execute (ref) | ~
|
|
296
|
+
| Execute (ref) | ~28-30M ops/s |
|
|
260
297
|
| Execute (fn nested) | ~9M ops/s |
|
|
298
|
+
| Execute (com accessor) | ~23-30M ops/s |
|
|
261
299
|
|
|
262
300
|
### compileAST() - AST + new Function
|
|
263
301
|
|
|
@@ -326,6 +364,102 @@ Objetos com `path` e `op` só são tratados como conditions se `op` for um opera
|
|
|
326
364
|
|
|
327
365
|
Isso permite que effect objects de handlers (que usam `{ resource, op: "set", path, value }`) sejam processados corretamente sem serem confundidos com conditions.
|
|
328
366
|
|
|
367
|
+
## Builders
|
|
368
|
+
|
|
369
|
+
Funções declarativas para construir expressões. Disponíveis via namespace `builders`:
|
|
370
|
+
|
|
371
|
+
```typescript
|
|
372
|
+
import { builders, compile } from '@statedelta-libs/expressions';
|
|
373
|
+
|
|
374
|
+
const { $, $fn, $if, $pipe } = builders;
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
### `$` / `ref` - Path Reference
|
|
378
|
+
|
|
379
|
+
```typescript
|
|
380
|
+
$("player.hp") // { $: "player.hp" }
|
|
381
|
+
$("items[0].price") // { $: "items[0].price" }
|
|
382
|
+
$("items[*].price") // { $: "items[*].price" } (wildcard)
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
### `$fn` / `fn` - Function Call
|
|
386
|
+
|
|
387
|
+
```typescript
|
|
388
|
+
// Com argumentos - chama a função
|
|
389
|
+
$fn("add", [$("a"), $("b")]) // { $fn: "add", args: [...] }
|
|
390
|
+
$fn("multiply", [10, $("x")]) // literal + expression
|
|
391
|
+
|
|
392
|
+
// Sem argumentos - retorna referência à função (útil em $pipe)
|
|
393
|
+
$fn("sum") // { $fn: "sum" }
|
|
394
|
+
|
|
395
|
+
// Com callbacks (predicados, mappers)
|
|
396
|
+
$fn("filter", [(item) => item.active])
|
|
397
|
+
$fn("map", [(item) => item.price])
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
### `$if` - Conditional
|
|
401
|
+
|
|
402
|
+
```typescript
|
|
403
|
+
// Com else
|
|
404
|
+
$if($("isVip"), 0.2, 0)
|
|
405
|
+
// { $if: { $: "isVip" }, then: 0.2, else: 0 }
|
|
406
|
+
|
|
407
|
+
// Sem else
|
|
408
|
+
$if($("active"), "yes")
|
|
409
|
+
// { $if: { $: "active" }, then: "yes" }
|
|
410
|
+
|
|
411
|
+
// Nested
|
|
412
|
+
$if($("level1"), $if($("level2"), "deep", "shallow"), "none")
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
### `$pipe` / `pipe` - Composition
|
|
416
|
+
|
|
417
|
+
```typescript
|
|
418
|
+
$pipe(
|
|
419
|
+
$("items"), // valor inicial
|
|
420
|
+
$fn("filter", [(x) => x.active]), // transforma
|
|
421
|
+
$fn("map", [(x) => x.price]), // transforma
|
|
422
|
+
$fn("sum") // resultado
|
|
423
|
+
)
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
### Exemplo Completo
|
|
427
|
+
|
|
428
|
+
```typescript
|
|
429
|
+
import { builders, compile } from '@statedelta-libs/expressions';
|
|
430
|
+
import { filter, map, sum } from '@statedelta-libs/operators';
|
|
431
|
+
|
|
432
|
+
const { $, $fn, $if, $pipe } = builders;
|
|
433
|
+
|
|
434
|
+
const scope = { filter, map, sum };
|
|
435
|
+
|
|
436
|
+
// Soma preços de itens ativos com desconto VIP
|
|
437
|
+
const expr = $pipe(
|
|
438
|
+
$("items"),
|
|
439
|
+
$fn("filter", [(item) => item.active]),
|
|
440
|
+
$fn("map", [(item) => item.price]),
|
|
441
|
+
$fn("sum")
|
|
442
|
+
);
|
|
443
|
+
|
|
444
|
+
const { fn } = compile(expr, { scope });
|
|
445
|
+
|
|
446
|
+
fn({
|
|
447
|
+
items: [
|
|
448
|
+
{ price: 10, active: true },
|
|
449
|
+
{ price: 20, active: false },
|
|
450
|
+
{ price: 30, active: true }
|
|
451
|
+
]
|
|
452
|
+
}); // 40
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
### Aliases
|
|
456
|
+
|
|
457
|
+
| Builder | Alias |
|
|
458
|
+
|---------|-------|
|
|
459
|
+
| `$` | `ref` |
|
|
460
|
+
| `$fn` | `fn` |
|
|
461
|
+
| `$pipe` | `pipe` |
|
|
462
|
+
|
|
329
463
|
## TypeScript
|
|
330
464
|
|
|
331
465
|
```typescript
|
|
@@ -338,6 +472,7 @@ import type {
|
|
|
338
472
|
PipeExpr,
|
|
339
473
|
Scope,
|
|
340
474
|
CompileOptions,
|
|
475
|
+
AccessorFn,
|
|
341
476
|
} from '@statedelta-libs/expressions';
|
|
342
477
|
|
|
343
478
|
// Type guards
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
'use strict';var conditions=require('@statedelta-libs/conditions'),omniAst=require('omni-ast');var m=n=>n!==null&&typeof n=="object"&&"$"in n&&typeof n.$=="string"&&Object.keys(n).length===1,h=n=>n!==null&&typeof n=="object"&&"$if"in n&&"then"in n,E=n=>n!==null&&typeof n=="object"&&"$fn"in n&&typeof n.$fn=="string",C=n=>n!==null&&typeof n=="object"&&"$pipe"in n&&Array.isArray(n.$pipe),M=new Set(["eq","neq","gt","gte","lt","lte","in","notIn","contains","notContains","exists","notExists","matches","notMatches","startsWith","endsWith"]),g=n=>n!==null&&typeof n=="object"&&"path"in n&&"op"in n&&M.has(n.op)&&!("$"in n)&&!("$if"in n)&&!("$fn"in n),y=n=>n!==null&&typeof n=="object"&&"logic"in n&&"conditions"in n,H=n=>g(n)||y(n),W=n=>{if(n===null)return true;let e=typeof n;if(e==="string"||e==="number"||e==="boolean"||Array.isArray(n))return true;if(e==="object"&&n!==null){let t=n,o="path"in t&&"op"in t&&M.has(t.op);return !("$"in t)&&!("$if"in t)&&!("$fn"in t)&&!("$pipe"in t)&&!o&&!("logic"in t)}return false};var R=new Map;function I(n){let e=[],t=n.length,o=0,i="";for(;o<t;){let s=n[o];if(s===".")i&&(e.push({type:"key",value:i}),i=""),o++;else if(s==="["){i&&(e.push({type:"key",value:i}),i=""),o++;let r=o;for(;o<t&&n[o]!=="]";)o++;let c=n.slice(r,o);if(o++,c==="*")e.push({type:"wildcard",value:"*"});else {let f=parseInt(c,10);e.push({type:"index",value:isNaN(f)?c:f});}}else i+=s,o++;}return i&&e.push({type:"key",value:i}),e}function V(n){return n.includes("[*]")}function x(n){let e=R.get(n);return e||(e=V(n)?U(n):Q(n),R.set(n,e),e)}function Q(n){if(!n.includes(".")&&!n.includes("["))return i=>i?.[n];let e=I(n),t=e.length;if(t===2){let[i,s]=e,r=i.value,c=s.value;return f=>f?.[r]?.[c]}if(t===3){let[i,s,r]=e,c=i.value,f=s.value,a=r.value;return u=>u?.[c]?.[f]?.[a]}let o=e.map(i=>i.value);return i=>{let s=i;for(let r=0;r<t&&s!=null;r++)s=s[o[r]];return s}}function U(n){let e=I(n),t=[];for(let o=0;o<e.length;o++)e[o].type==="wildcard"&&t.push(o);return t.length===1?X(e,t[0]):Z(e,t)}function X(n,e){let t=n.slice(0,e).map(r=>r.value),o=n.slice(e+1).map(r=>r.value),i=t.length,s=o.length;if(s===0){if(i===1){let r=t[0];return c=>c?.[r]}return r=>{let c=r;for(let f=0;f<i&&c!=null;f++)c=c[t[f]];return c}}if(s===1){let r=o[0];if(i===1){let c=t[0];return f=>{let a=f?.[c];if(Array.isArray(a))return a.map(u=>u?.[r])}}return c=>{let f=c;for(let a=0;a<i&&f!=null;a++)f=f[t[a]];if(Array.isArray(f))return f.map(a=>a?.[r])}}return r=>{let c=r;for(let f=0;f<i&&c!=null;f++)c=c[t[f]];if(Array.isArray(c))return c.map(f=>{let a=f;for(let u=0;u<s&&a!=null;u++)a=a[o[u]];return a})}}function Z(n,e){let t=[],o=0;for(let s=0;s<e.length;s++){let r=e[s],c=s===e.length-1,f=n.slice(o,r).map(a=>a.value);f.length>0&&t.push({type:"access",keys:f}),t.push({type:c?"map":"flatMap",keys:[]}),o=r+1;}let i=n.slice(o).map(s=>s.value);return s=>{let r=s;for(let c of t){if(r==null)return;if(c.type==="access")for(let f of c.keys){if(r==null)return;r=r[f];}else if(c.type==="flatMap"){if(!Array.isArray(r))return;r=r.flatMap(f=>{let a=f;return Array.isArray(a)?a:[a]});}else if(c.type==="map"){if(!Array.isArray(r))return;i.length>0&&(r=r.map(f=>{let a=f;for(let u of i){if(a==null)return;a=a[u];}return a}));}}return r}}function nn(n,e){return x(e)(n)}function k(n){let e=n.indexOf("[*]");return e===-1?n:n.slice(0,e)}function en(){R.clear();}function tn(){return R.size}function T(n){let e=new Set;return A(n,e),Array.from(e)}function A(n,e){if(n===null||typeof n!="object")return;if(Array.isArray(n)){for(let i=0;i<n.length;i++)A(n[i],e);return}if(m(n)){e.add(k(n.$));return}if(h(n)){if(typeof n.$if=="string"){let i=n.$if.startsWith("!")?n.$if.slice(1):n.$if;e.add(k(i));}else A(n.$if,e);A(n.then,e),n.else!==void 0&&A(n.else,e);return}if(C(n)){for(let i=0;i<n.$pipe.length;i++)A(n.$pipe[i],e);return}if(E(n)){if(n.args)for(let i=0;i<n.args.length;i++)A(n.args[i],e);return}if(g(n)){e.add(k(n.path)),n.value!==void 0&&conditions.isRef(n.value)&&e.add(k(n.value.$));return}if(y(n)){for(let i=0;i<n.conditions.length;i++)A(n.conditions[i],e);return}let t=n,o=Object.keys(t);for(let i=0;i<o.length;i++)A(t[o[i]],e);}function rn(n){return T(n).length>0}function sn(n){return T(n).length===0}function ln(n){return JSON.stringify(n)}function O(n,e={}){let t=e.scope??{},o=b(n,t),i=T(n),s=ln(n);return {fn:o,deps:i,hash:s}}function b(n,e){if(n===null)return ()=>null;if(typeof n!="object")return ()=>n;if(Array.isArray(n)){let t=n.map(o=>b(o,e));return o=>t.map(i=>i(o))}if(m(n))return cn(n);if(h(n))return fn(n,e);if(C(n))return an(n,e);if(E(n))return un(n,e);if(g(n))return conditions.compile(n);if(y(n))return conditions.compile(n);if(W(n)){let t=n,o=Object.keys(t),i=o.map(s=>b(t[s],e));return s=>{let r={};for(let c=0;c<o.length;c++)r[o[c]]=i[c](s);return r}}return ()=>n}function cn(n){return x(n.$)}function fn(n,e){let t;if(typeof n.$if=="string"){let s=n.$if.startsWith("!")?n.$if.slice(1):n.$if,r=x(s);t=n.$if.startsWith("!")?f=>!r(f):f=>!!r(f);}else {let s=b(n.$if,e);t=r=>!!s(r);}let o=b(n.then,e),i=n.else!==void 0?b(n.else,e):()=>{};return s=>t(s)?o(s):i(s)}function an(n,e){let t=n.$pipe;if(t.length===0)return ()=>{};if(t.length===1)return b(t[0],e);let o=b(t[0],e),i=t.slice(1).map(r=>b(r,e)),s=i.length;if(s===1){let[r]=i;return c=>{let f=o(c),a=r(c);return typeof a=="function"?a(f):a}}if(s===2){let[r,c]=i;return f=>{let a=o(f),u=r(f);return a=typeof u=="function"?u(a):u,u=c(f),typeof u=="function"?u(a):u}}if(s===3){let[r,c,f]=i;return a=>{let u=o(a),p=r(a);return u=typeof p=="function"?p(u):p,p=c(a),u=typeof p=="function"?p(u):p,p=f(a),typeof p=="function"?p(u):p}}return r=>{let c=o(r);for(let f=0;f<s;f++){let a=i[f](r);c=typeof a=="function"?a(c):a;}return c}}function un(n,e){let t=n.$fn,o=n.args;if(o===void 0)return ()=>{let r=e[t];if(!r)throw new Error(`Function not found in scope: ${t}`);return r};let i=o.map(r=>b(r,e)),s=i.length;if(s===0)return r=>{let c=e[t];if(!c)throw new Error(`Function not found in scope: ${t}`);return c()};if(s===1){let[r]=i;return c=>{let f=e[t];if(!f)throw new Error(`Function not found in scope: ${t}`);return f(r(c))}}if(s===2){let[r,c]=i;return f=>{let a=e[t];if(!a)throw new Error(`Function not found in scope: ${t}`);return a(r(f),c(f))}}if(s===3){let[r,c,f]=i;return a=>{let u=e[t];if(!u)throw new Error(`Function not found in scope: ${t}`);return u(r(a),c(a),f(a))}}return r=>{let c=e[t];if(!c)throw new Error(`Function not found in scope: ${t}`);return c(...i.map(f=>f(r)))}}function pn(n,e,t={}){return O(n,t).fn(e)}var v=class{constructor(e=1e3){this.cache=new Map,this._maxSize=e;}get(e,t={}){let o=JSON.stringify(e),i=this.cache.get(o);if(i)return this.cache.delete(o),this.cache.set(o,i),i;let s=O(e,t);if(this.cache.size>=this._maxSize){let r=this.cache.keys().next().value;r&&this.cache.delete(r);}return this.cache.set(o,s),s}has(e){return this.cache.has(JSON.stringify(e))}delete(e){return this.cache.delete(JSON.stringify(e))}clear(){this.cache.clear();}get size(){return this.cache.size}get maxSize(){return this._maxSize}set maxSize(e){for(this._maxSize=e;this.cache.size>this._maxSize;){let t=this.cache.keys().next().value;t&&this.cache.delete(t);}}},_=new v;function dn(n,e={}){return _.get(n,e)}function z(n,e="root",t={}){let o=[];return $(n,e,o,t),{valid:o.length===0,errors:o}}function $(n,e,t,o){if(n===null||typeof n!="object")return;if(Array.isArray(n)){for(let r=0;r<n.length;r++)$(n[r],`${e}[${r}]`,t,o);return}if(m(n)){(!n.$||typeof n.$!="string")&&t.push(`${e}: invalid reference, $ must be non-empty string`);return}if(h(n)){typeof n.$if=="string"?(n.$if.startsWith("!")?n.$if.slice(1):n.$if)||t.push(`${e}.$if: empty path in string shorthand`):$(n.$if,`${e}.$if`,t,o),$(n.then,`${e}.then`,t,o),n.else!==void 0&&$(n.else,`${e}.else`,t,o);return}if(C(n)){if(!Array.isArray(n.$pipe)){t.push(`${e}.$pipe: must be an array`);return}if(n.$pipe.length===0){t.push(`${e}.$pipe: must have at least one element`);return}for(let r=0;r<n.$pipe.length;r++)$(n.$pipe[r],`${e}.$pipe[${r}]`,t,o);return}if(E(n)){if(!n.$fn||typeof n.$fn!="string"){t.push(`${e}: invalid function, $fn must be non-empty string`);return}if(o.scope&&!(n.$fn in o.scope)&&t.push(`${e}: function "${n.$fn}" not found in scope`),n.args!==void 0)if(!Array.isArray(n.args))t.push(`${e}.args: must be an array`);else for(let r=0;r<n.args.length;r++)$(n.args[r],`${e}.args[${r}]`,t,o);return}if(g(n)){let r=conditions.validate(n,e);r.valid||t.push(...r.errors);return}if(y(n)){let r=conditions.validate(n,e);r.valid||t.push(...r.errors);return}let i=n,s=Object.keys(i);for(let r=0;r<s.length;r++){let c=s[r];$(i[c],`${e}.${c}`,t,o);}}function mn(n,e={}){let t=z(n,"root",e);if(!t.valid)throw new Error(`Invalid expression: ${t.errors.join("; ")}`)}function gn(n,e={}){return z(n,"root",e).valid}var P="data",J="scope",yn={eq:"===",neq:"!==",gt:">",gte:">=",lt:"<",lte:"<="};function N(n,e={}){let{dataParam:t=P,scopeParam:o=J,noPrefixes:i=false}=e;return d(n,t,o,i)}function d(n,e,t,o){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(i=>d(i,e,t,o)));if(m(n))return hn(n.$,e,o);if(h(n))return Cn(n,e,t,o);if(C(n))return Sn(n.$pipe,e,t,o);if(E(n))return bn(n,e,t,o);if(g(n))return An(n,e,t,o);if(y(n))return $n(n,e,t,o);if(typeof n=="object"){let s=Object.entries(n).map(([r,c])=>omniAst.builders.property(omniAst.builders.identifier(r),d(c,e,t,o)));return omniAst.builders.objectExpression(s)}return omniAst.builders.literal(null)}function hn(n,e,t){return n.includes("[*]")?En(n,e,t):w(n,e,t)}function w(n,e,t){let o=F(n);if(o.length===0)return t?omniAst.builders.identifier("undefined"):omniAst.builders.identifier(e);let i;if(t){let s=o[0];i=omniAst.builders.identifier(s.value);for(let r=1;r<o.length;r++){let c=o[r];c.type==="key"?i=omniAst.builders.memberExpression(i,omniAst.builders.identifier(c.value),false,true):i=omniAst.builders.memberExpression(i,omniAst.builders.literal(c.value),true,true);}}else {i=omniAst.builders.identifier(e);for(let s of o)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 En(n,e,t){let o=n.indexOf("[*]"),i=n.slice(0,o),s=n.slice(o+3),r;if(i?r=w(i,e,t):r=t?omniAst.builders.identifier("undefined"):omniAst.builders.identifier(e),!s||s==="")return r;if(s.includes("[*]"))return B(r,s);let c="_i",f=s.startsWith(".")?s.slice(1):s,a=omniAst.builders.identifier(c);if(f){let u=F(f);for(let p of u)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(r,omniAst.builders.identifier("map"),false,true),[omniAst.builders.arrowFunctionExpression([omniAst.builders.identifier(c)],a)])}function B(n,e){let t=e.indexOf("[*]"),o=e.slice(0,t),i=e.slice(t+3),s="_i",r=o.startsWith(".")?o.slice(1):o,c=omniAst.builders.identifier(s);if(r){let a=F(r);for(let u of a)u.type==="key"&&(c=omniAst.builders.memberExpression(c,omniAst.builders.identifier(u.value),false,true));}if(i.includes("[*]")){let a=B(c,i);return omniAst.builders.callExpression(omniAst.builders.memberExpression(n,omniAst.builders.identifier("flatMap"),false,true),[omniAst.builders.arrowFunctionExpression([omniAst.builders.identifier(s)],a)])}let f=i.startsWith(".")?i.slice(1):i;if(f){let a=F(f);for(let u of a)u.type==="key"&&(c=omniAst.builders.memberExpression(c,omniAst.builders.identifier(u.value),false,true));}return omniAst.builders.callExpression(omniAst.builders.memberExpression(n,omniAst.builders.identifier("flatMap"),false,true),[omniAst.builders.arrowFunctionExpression([omniAst.builders.identifier(s)],c)])}function Cn(n,e,t,o){let i;if(typeof n.$if=="string"){let c=n.$if.startsWith("!"),f=c?n.$if.slice(1):n.$if,a=w(f,e,o);i=c?omniAst.builders.unaryExpression("!",a):a;}else i=d(n.$if,e,t,o);let s=d(n.then,e,t,o),r=n.else!==void 0?d(n.else,e,t,o):omniAst.builders.identifier("undefined");return omniAst.builders.conditionalExpression(i,s,r)}function bn(n,e,t,o){let i=o?omniAst.builders.identifier(n.$fn):omniAst.builders.memberExpression(omniAst.builders.identifier(t),omniAst.builders.identifier(n.$fn),false,false);if(n.args===void 0)return i;let s=n.args.map(r=>d(r,e,t,o));return omniAst.builders.callExpression(i,s)}function Sn(n,e,t,o){if(n.length===0)return omniAst.builders.identifier("undefined");if(n.length===1)return d(n[0],e,t,o);let i=d(n[0],e,t,o);for(let s=1;s<n.length;s++){let r=d(n[s],e,t,o);i=omniAst.builders.callExpression(r,[i]);}return i}function An(n,e,t,o){let i=w(n.path,e,o),s=n.value!==void 0?m(n.value)?w(n.value.$,e,o):d(n.value,e,t,o):omniAst.builders.literal(null),r=yn[n.op];if(r)return omniAst.builders.binaryExpression(r,i,s);switch(n.op){case "in":return omniAst.builders.callExpression(omniAst.builders.memberExpression(s,omniAst.builders.identifier("includes")),[i]);case "notIn":return omniAst.builders.unaryExpression("!",omniAst.builders.callExpression(omniAst.builders.memberExpression(s,omniAst.builders.identifier("includes")),[i]));case "contains":return omniAst.builders.callExpression(omniAst.builders.memberExpression(i,omniAst.builders.identifier("includes"),false,true),[s]);case "notContains":return omniAst.builders.unaryExpression("!",omniAst.builders.callExpression(omniAst.builders.memberExpression(i,omniAst.builders.identifier("includes"),false,true),[s]));case "exists":return omniAst.builders.binaryExpression("!=",i,omniAst.builders.literal(null));case "notExists":return omniAst.builders.binaryExpression("==",i,omniAst.builders.literal(null));case "matches":return omniAst.builders.callExpression(omniAst.builders.memberExpression(omniAst.builders.newExpression(omniAst.builders.identifier("RegExp"),[s]),omniAst.builders.identifier("test")),[i]);case "notMatches":return omniAst.builders.unaryExpression("!",omniAst.builders.callExpression(omniAst.builders.memberExpression(omniAst.builders.newExpression(omniAst.builders.identifier("RegExp"),[s]),omniAst.builders.identifier("test")),[i]));case "startsWith":return omniAst.builders.callExpression(omniAst.builders.memberExpression(i,omniAst.builders.identifier("startsWith"),false,true),[s]);case "endsWith":return omniAst.builders.callExpression(omniAst.builders.memberExpression(i,omniAst.builders.identifier("endsWith"),false,true),[s]);default:return omniAst.builders.binaryExpression("===",i,s)}}function $n(n,e,t,o){let{logic:i,conditions:s}=n,r=i==="AND"?"&&":"||";if(s.length===0)return omniAst.builders.literal(i==="AND");if(s.length===1)return d(s[0],e,t,o);let c=d(s[0],e,t,o);for(let f=1;f<s.length;f++){let a=d(s[f],e,t,o);c=omniAst.builders.logicalExpression(r,c,a);}return c}function F(n){let e=[],t=n.length,o=0,i="";for(;o<t;){let s=n[o];if(s===".")i&&(e.push({type:"key",value:i}),i=""),o++;else if(s==="["){i&&(e.push({type:"key",value:i}),i=""),o++;let r=o;for(;o<t&&n[o]!=="]";)o++;let c=n.slice(r,o);if(o++,c!=="*"){let f=parseInt(c,10);e.push({type:"index",value:isNaN(f)?c:f});}}else i+=s,o++;}return i&&e.push({type:"key",value:i}),e}function K(n,e=[P]){return omniAst.builders.arrowFunctionExpression(e.map(t=>omniAst.builders.identifier(t)),n)}function j(n){let e=new Set;return S(n,e),e}function S(n,e){if(n===null||typeof n!="object")return;if(Array.isArray(n)){for(let o of n)S(o,e);return}if(m(n))return;if(h(n)){S(n.$if,e),S(n.then,e),n.else!==void 0&&S(n.else,e);return}if(C(n)){for(let o of n.$pipe)S(o,e);return}if(E(n)){if(e.add(n.$fn),n.args)for(let o of n.args)S(o,e);return}if(g(n)){n.value!==void 0&&typeof n.value=="object"&&S(n.value,e);return}if(y(n)){for(let o of n.conditions)S(o,e);return}let t=n;for(let o of Object.keys(t))S(t[o],e);}function G(n){let e=new Set;for(let t of n){let o=t.indexOf("."),i=t.indexOf("["),s=t.length;o!==-1&&(s=Math.min(s,o)),i!==-1&&(s=Math.min(s,i));let r=t.slice(0,s);r&&e.add(r);}return e}function kn(n){return JSON.stringify(n)}function xn(n,e,t){let o=N(n,{noPrefixes:true}),i=omniAst.generate(o),s=e.size>0?`const{${[...e].join(",")}}=data??{};`:"",r=t.size>0?`const{${[...t].join(",")}}=scope;`:"";return r?`(function(scope){${r}return function(data){${s}return ${i}}})`:`(function(){return function(data){${s}return ${i}}})`}function D(n,e={}){let{scope:t={},returnCode:o=false}=e,i=T(n),s=G(i),r=j(n),c=kn(n),f=xn(n,s,r);if(o)return {code:f,deps:i,hash:c,dataRoots:[...s],scopeFns:[...r]};let a;try{a=new Function(`return ${f}`)()(t);}catch(u){throw new Error(`AST compilation failed. If this is due to CSP, use the standard compile() function instead. Error: ${u instanceof Error?u.message:String(u)}`)}return {fn:a,deps:i,hash:c}}function Y(n,e,t={}){let{fn:o}=D(n,t);return o(e)}var ie="0.0.1";exports.ExpressionCache=v;exports.VERSION=ie;exports.assertValid=mn;exports.cache=_;exports.cached=dn;exports.clearPathCache=en;exports.compile=O;exports.compileAST=D;exports.compilePath=x;exports.dslToAST=N;exports.evaluate=pn;exports.evaluateAST=Y;exports.extractDataRoots=G;exports.extractDeps=T;exports.extractScopeFns=j;exports.get=nn;exports.getPathCacheSize=tn;exports.hasDeps=rn;exports.hasWildcard=V;exports.isCondition=g;exports.isConditionExpr=H;exports.isConditionGroup=y;exports.isConditional=h;exports.isFn=E;exports.isLiteral=W;exports.isPipe=C;exports.isPure=sn;exports.isRef=m;exports.isValid=gn;exports.normalizePath=k;exports.validate=z;exports.wrapInFunction=K;
|
|
1
|
+
'use strict';var conditions=require('@statedelta-libs/conditions'),omniAst=require('omni-ast');var en=Object.defineProperty;var tn=(n,e)=>{for(var i in e)en(n,i,{get:e[i],enumerable:true});};var m=n=>n!==null&&typeof n=="object"&&"$"in n&&typeof n.$=="string"&&Object.keys(n).length===1,E=n=>n!==null&&typeof n=="object"&&"$if"in n&&"then"in n,T=n=>n!==null&&typeof n=="object"&&"$fn"in n&&typeof n.$fn=="string",C=n=>n!==null&&typeof n=="object"&&"$pipe"in n&&Array.isArray(n.$pipe),I=new Set(["eq","neq","gt","gte","lt","lte","in","notIn","contains","notContains","exists","notExists","matches","notMatches","startsWith","endsWith"]),g=n=>n!==null&&typeof n=="object"&&"path"in n&&"op"in n&&I.has(n.op)&&!("$"in n)&&!("$if"in n)&&!("$fn"in n),y=n=>n!==null&&typeof n=="object"&&"logic"in n&&"conditions"in n,on=n=>g(n)||y(n),P=n=>{if(n===null)return true;let e=typeof n;if(e==="string"||e==="number"||e==="boolean"||Array.isArray(n))return true;if(e==="object"&&n!==null){let i=n,t="path"in i&&"op"in i&&I.has(i.op);return !("$"in i)&&!("$if"in i)&&!("$fn"in i)&&!("$pipe"in i)&&!t&&!("logic"in i)}return false};var R=new Map;function V(n){let e=[],i=n.length,t=0,o="";for(;t<i;){let s=n[t];if(s===".")o&&(e.push({type:"key",value:o}),o=""),t++;else if(s==="["){o&&(e.push({type:"key",value:o}),o=""),t++;let r=t;for(;t<i&&n[t]!=="]";)t++;let f=n.slice(r,t);if(t++,f==="*")e.push({type:"wildcard",value:"*"});else {let u=parseInt(f,10);e.push({type:"index",value:isNaN(u)?f:u});}}else o+=s,t++;}return o&&e.push({type:"key",value:o}),e}function L(n){return n.includes("[*]")}function O(n){let e=R.get(n);return e||(e=L(n)?sn(n):rn(n),R.set(n,e),e)}function rn(n){if(!n.includes(".")&&!n.includes("["))return o=>o?.[n];let e=V(n),i=e.length;if(i===2){let[o,s]=e,r=o.value,f=s.value;return u=>u?.[r]?.[f]}if(i===3){let[o,s,r]=e,f=o.value,u=s.value,c=r.value;return a=>a?.[f]?.[u]?.[c]}let t=e.map(o=>o.value);return o=>{let s=o;for(let r=0;r<i&&s!=null;r++)s=s[t[r]];return s}}function sn(n){let e=V(n),i=[];for(let t=0;t<e.length;t++)e[t].type==="wildcard"&&i.push(t);return i.length===1?ln(e,i[0]):fn(e,i)}function ln(n,e){let i=n.slice(0,e).map(r=>r.value),t=n.slice(e+1).map(r=>r.value),o=i.length,s=t.length;if(s===0){if(o===1){let r=i[0];return f=>f?.[r]}return r=>{let f=r;for(let u=0;u<o&&f!=null;u++)f=f[i[u]];return f}}if(s===1){let r=t[0];if(o===1){let f=i[0];return u=>{let c=u?.[f];if(Array.isArray(c))return c.map(a=>a?.[r])}}return f=>{let u=f;for(let c=0;c<o&&u!=null;c++)u=u[i[c]];if(Array.isArray(u))return u.map(c=>c?.[r])}}return r=>{let f=r;for(let u=0;u<o&&f!=null;u++)f=f[i[u]];if(Array.isArray(f))return f.map(u=>{let c=u;for(let a=0;a<s&&c!=null;a++)c=c[t[a]];return c})}}function fn(n,e){let i=[],t=0;for(let s=0;s<e.length;s++){let r=e[s],f=s===e.length-1,u=n.slice(t,r).map(c=>c.value);u.length>0&&i.push({type:"access",keys:u}),i.push({type:f?"map":"flatMap",keys:[]}),t=r+1;}let o=n.slice(t).map(s=>s.value);return s=>{let r=s;for(let f of i){if(r==null)return;if(f.type==="access")for(let u of f.keys){if(r==null)return;r=r[u];}else if(f.type==="flatMap"){if(!Array.isArray(r))return;r=r.flatMap(u=>{let c=u;return Array.isArray(c)?c:[c]});}else if(f.type==="map"){if(!Array.isArray(r))return;o.length>0&&(r=r.map(u=>{let c=u;for(let a of o){if(c==null)return;c=c[a];}return c}));}}return r}}function un(n,e){return O(e)(n)}function k(n){let e=n.indexOf("[*]");return e===-1?n:n.slice(0,e)}function cn(){R.clear();}function an(){return R.size}function S(n){let e=new Set;return $(n,e),Array.from(e)}function $(n,e){if(n===null||typeof n!="object")return;if(Array.isArray(n)){for(let o=0;o<n.length;o++)$(n[o],e);return}if(m(n)){e.add(k(n.$));return}if(E(n)){if(typeof n.$if=="string"){let o=n.$if.startsWith("!")?n.$if.slice(1):n.$if;e.add(k(o));}else $(n.$if,e);$(n.then,e),n.else!==void 0&&$(n.else,e);return}if(C(n)){for(let o=0;o<n.$pipe.length;o++)$(n.$pipe[o],e);return}if(T(n)){if(n.args)for(let o=0;o<n.args.length;o++)$(n.args[o],e);return}if(g(n)){e.add(k(n.path)),n.value!==void 0&&conditions.isRef(n.value)&&e.add(k(n.value.$));return}if(y(n)){for(let o=0;o<n.conditions.length;o++)$(n.conditions[o],e);return}let i=n,t=Object.keys(i);for(let o=0;o<t.length;o++)$(i[t[o]],e);}function dn(n){return S(n).length>0}function mn(n){return S(n).length===0}function gn(n){return JSON.stringify(n)}function F(n,e={}){let i=e.scope??{},t=e.accessor,o=A(n,i,t),s=S(n),r=gn(n);return {fn:o,deps:s,hash:r}}function A(n,e,i){if(n===null)return ()=>null;if(typeof n!="object")return ()=>n;if(Array.isArray(n)){let t=n.map(o=>A(o,e,i));return o=>t.map(s=>s(o))}if(m(n))return yn(n,i);if(E(n))return hn(n,e,i);if(C(n))return En(n,e,i);if(T(n))return Tn(n,e,i);if(g(n))return conditions.compile(n,i?{accessor:i}:void 0);if(y(n))return conditions.compile(n,i?{accessor:i}:void 0);if(P(n)){let t=n,o=Object.keys(t),s=o.map(r=>A(t[r],e,i));return r=>{let f={};for(let u=0;u<o.length;u++)f[o[u]]=s[u](r);return f}}return ()=>n}function q(n,e){return e?i=>e(n,i):O(n)}function yn(n,e){return q(n.$,e)}function hn(n,e,i){let t;if(typeof n.$if=="string"){let r=n.$if.startsWith("!")?n.$if.slice(1):n.$if,f=q(r,i);t=n.$if.startsWith("!")?c=>!f(c):c=>!!f(c);}else {let r=A(n.$if,e,i);t=f=>!!r(f);}let o=A(n.then,e,i),s=n.else!==void 0?A(n.else,e,i):()=>{};return r=>t(r)?o(r):s(r)}function En(n,e,i){let t=n.$pipe;if(t.length===0)return ()=>{};if(t.length===1)return A(t[0],e,i);let o=A(t[0],e,i),s=t.slice(1).map(f=>A(f,e,i)),r=s.length;if(r===1){let[f]=s;return u=>{let c=o(u),a=f(u);return typeof a=="function"?a(c):a}}if(r===2){let[f,u]=s;return c=>{let a=o(c),p=f(c);return a=typeof p=="function"?p(a):p,p=u(c),typeof p=="function"?p(a):p}}if(r===3){let[f,u,c]=s;return a=>{let p=o(a),h=f(a);return p=typeof h=="function"?h(p):h,h=u(a),p=typeof h=="function"?h(p):h,h=c(a),typeof h=="function"?h(p):h}}return f=>{let u=o(f);for(let c=0;c<r;c++){let a=s[c](f);u=typeof a=="function"?a(u):a;}return u}}function Tn(n,e,i){let t=n.$fn,o=n.args;if(o===void 0)return ()=>{let f=e[t];if(!f)throw new Error(`Function not found in scope: ${t}`);return f};let s=o.map(f=>A(f,e,i)),r=s.length;if(r===0)return f=>{let u=e[t];if(!u)throw new Error(`Function not found in scope: ${t}`);return u()};if(r===1){let[f]=s;return u=>{let c=e[t];if(!c)throw new Error(`Function not found in scope: ${t}`);return c(f(u))}}if(r===2){let[f,u]=s;return c=>{let a=e[t];if(!a)throw new Error(`Function not found in scope: ${t}`);return a(f(c),u(c))}}if(r===3){let[f,u,c]=s;return a=>{let p=e[t];if(!p)throw new Error(`Function not found in scope: ${t}`);return p(f(a),u(a),c(a))}}return f=>{let u=e[t];if(!u)throw new Error(`Function not found in scope: ${t}`);return u(...s.map(c=>c(f)))}}function Cn(n,e,i={}){return F(n,i).fn(e)}var v=class{constructor(e=1e3){this.cache=new Map,this._maxSize=e;}get(e,i={}){let t=JSON.stringify(e),o=this.cache.get(t);if(o)return this.cache.delete(t),this.cache.set(t,o),o;let s=F(e,i);if(this.cache.size>=this._maxSize){let r=this.cache.keys().next().value;r&&this.cache.delete(r);}return this.cache.set(t,s),s}has(e){return this.cache.has(JSON.stringify(e))}delete(e){return this.cache.delete(JSON.stringify(e))}clear(){this.cache.clear();}get size(){return this.cache.size}get maxSize(){return this._maxSize}set maxSize(e){for(this._maxSize=e;this.cache.size>this._maxSize;){let i=this.cache.keys().next().value;i&&this.cache.delete(i);}}},J=new v;function An(n,e={}){return J.get(n,e)}function z(n,e="root",i={}){let t=[];return x(n,e,t,i),{valid:t.length===0,errors:t}}function x(n,e,i,t){if(n===null||typeof n!="object")return;if(Array.isArray(n)){for(let r=0;r<n.length;r++)x(n[r],`${e}[${r}]`,i,t);return}if(m(n)){(!n.$||typeof n.$!="string")&&i.push(`${e}: invalid reference, $ must be non-empty string`);return}if(E(n)){typeof n.$if=="string"?(n.$if.startsWith("!")?n.$if.slice(1):n.$if)||i.push(`${e}.$if: empty path in string shorthand`):x(n.$if,`${e}.$if`,i,t),x(n.then,`${e}.then`,i,t),n.else!==void 0&&x(n.else,`${e}.else`,i,t);return}if(C(n)){if(!Array.isArray(n.$pipe)){i.push(`${e}.$pipe: must be an array`);return}if(n.$pipe.length===0){i.push(`${e}.$pipe: must have at least one element`);return}for(let r=0;r<n.$pipe.length;r++)x(n.$pipe[r],`${e}.$pipe[${r}]`,i,t);return}if(T(n)){if(!n.$fn||typeof n.$fn!="string"){i.push(`${e}: invalid function, $fn must be non-empty string`);return}if(t.scope&&!(n.$fn in t.scope)&&i.push(`${e}: function "${n.$fn}" not found in scope`),n.args!==void 0)if(!Array.isArray(n.args))i.push(`${e}.args: must be an array`);else for(let r=0;r<n.args.length;r++)x(n.args[r],`${e}.args[${r}]`,i,t);return}if(g(n)){let r=conditions.validate(n,e);r.valid||i.push(...r.errors);return}if(y(n)){let r=conditions.validate(n,e);r.valid||i.push(...r.errors);return}let o=n,s=Object.keys(o);for(let r=0;r<s.length;r++){let f=s[r];x(o[f],`${e}.${f}`,i,t);}}function bn(n,e={}){let i=z(n,"root",e);if(!i.valid)throw new Error(`Invalid expression: ${i.errors.join("; ")}`)}function $n(n,e={}){return z(n,"root",e).valid}var Q={};tn(Q,{$:()=>K,$fn:()=>Y,$if:()=>kn,$pipe:()=>H,fn:()=>Sn,pipe:()=>wn,ref:()=>xn});function K(n){return {$:n}}var xn=K;function Y(n,e){return e===void 0||e.length===0?{$fn:n}:{$fn:n,args:e}}var Sn=Y;function kn(n,e,i){return i===void 0?{$if:n,then:e}:{$if:n,then:e,else:i}}function H(...n){return {$pipe:n}}var wn=H;var D="data",U="scope",Rn={eq:"===",neq:"!==",gt:">",gte:">=",lt:"<",lte:"<="};function j(n,e={}){let{dataParam:i=D,scopeParam:t=U,noPrefixes:o=false}=e;return d(n,i,t,o)}function d(n,e,i,t){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(o=>d(o,e,i,t)));if(m(n))return On(n.$,e,t);if(E(n))return vn(n,e,i,t);if(C(n))return jn(n.$pipe,e,i,t);if(T(n))return Nn(n,e,i,t);if(g(n))return Gn(n,e,i,t);if(y(n))return Wn(n,e,i,t);if(typeof n=="object"){let s=Object.entries(n).map(([r,f])=>omniAst.builders.property(omniAst.builders.identifier(r),d(f,e,i,t)));return omniAst.builders.objectExpression(s)}return omniAst.builders.literal(null)}function On(n,e,i){return n.includes("[*]")?Fn(n,e,i):w(n,e,i)}function w(n,e,i){let t=N(n);if(t.length===0)return i?omniAst.builders.identifier("undefined"):omniAst.builders.identifier(e);let o;if(i){let s=t[0];o=omniAst.builders.identifier(s.value);for(let r=1;r<t.length;r++){let f=t[r];f.type==="key"?o=omniAst.builders.memberExpression(o,omniAst.builders.identifier(f.value),false,true):o=omniAst.builders.memberExpression(o,omniAst.builders.literal(f.value),true,true);}}else {o=omniAst.builders.identifier(e);for(let s of t)s.type==="key"?o=omniAst.builders.memberExpression(o,omniAst.builders.identifier(s.value),false,true):o=omniAst.builders.memberExpression(o,omniAst.builders.literal(s.value),true,true);}return o}function Fn(n,e,i){let t=n.indexOf("[*]"),o=n.slice(0,t),s=n.slice(t+3),r;if(o?r=w(o,e,i):r=i?omniAst.builders.identifier("undefined"):omniAst.builders.identifier(e),!s||s==="")return r;if(s.includes("[*]"))return X(r,s);let f="_i",u=s.startsWith(".")?s.slice(1):s,c=omniAst.builders.identifier(f);if(u){let a=N(u);for(let p of a)p.type==="key"?c=omniAst.builders.memberExpression(c,omniAst.builders.identifier(p.value),false,true):c=omniAst.builders.memberExpression(c,omniAst.builders.literal(p.value),true,true);}return omniAst.builders.callExpression(omniAst.builders.memberExpression(r,omniAst.builders.identifier("map"),false,true),[omniAst.builders.arrowFunctionExpression([omniAst.builders.identifier(f)],c)])}function X(n,e){let i=e.indexOf("[*]"),t=e.slice(0,i),o=e.slice(i+3),s="_i",r=t.startsWith(".")?t.slice(1):t,f=omniAst.builders.identifier(s);if(r){let c=N(r);for(let a of c)a.type==="key"&&(f=omniAst.builders.memberExpression(f,omniAst.builders.identifier(a.value),false,true));}if(o.includes("[*]")){let c=X(f,o);return omniAst.builders.callExpression(omniAst.builders.memberExpression(n,omniAst.builders.identifier("flatMap"),false,true),[omniAst.builders.arrowFunctionExpression([omniAst.builders.identifier(s)],c)])}let u=o.startsWith(".")?o.slice(1):o;if(u){let c=N(u);for(let a of c)a.type==="key"&&(f=omniAst.builders.memberExpression(f,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)],f)])}function vn(n,e,i,t){let o;if(typeof n.$if=="string"){let f=n.$if.startsWith("!"),u=f?n.$if.slice(1):n.$if,c=w(u,e,t);o=f?omniAst.builders.unaryExpression("!",c):c;}else o=d(n.$if,e,i,t);let s=d(n.then,e,i,t),r=n.else!==void 0?d(n.else,e,i,t):omniAst.builders.identifier("undefined");return omniAst.builders.conditionalExpression(o,s,r)}function Nn(n,e,i,t){let o=t?omniAst.builders.identifier(n.$fn):omniAst.builders.memberExpression(omniAst.builders.identifier(i),omniAst.builders.identifier(n.$fn),false,false);if(n.args===void 0)return o;let s=n.args.map(r=>d(r,e,i,t));return omniAst.builders.callExpression(o,s)}function jn(n,e,i,t){if(n.length===0)return omniAst.builders.identifier("undefined");if(n.length===1)return d(n[0],e,i,t);let o=d(n[0],e,i,t);for(let s=1;s<n.length;s++){let r=d(n[s],e,i,t);o=omniAst.builders.callExpression(r,[o]);}return o}function Gn(n,e,i,t){let o=w(n.path,e,t),s=n.value!==void 0?m(n.value)?w(n.value.$,e,t):d(n.value,e,i,t):omniAst.builders.literal(null),r=Rn[n.op];if(r)return omniAst.builders.binaryExpression(r,o,s);switch(n.op){case "in":return omniAst.builders.callExpression(omniAst.builders.memberExpression(s,omniAst.builders.identifier("includes")),[o]);case "notIn":return omniAst.builders.unaryExpression("!",omniAst.builders.callExpression(omniAst.builders.memberExpression(s,omniAst.builders.identifier("includes")),[o]));case "contains":return omniAst.builders.callExpression(omniAst.builders.memberExpression(o,omniAst.builders.identifier("includes"),false,true),[s]);case "notContains":return omniAst.builders.unaryExpression("!",omniAst.builders.callExpression(omniAst.builders.memberExpression(o,omniAst.builders.identifier("includes"),false,true),[s]));case "exists":return omniAst.builders.binaryExpression("!=",o,omniAst.builders.literal(null));case "notExists":return omniAst.builders.binaryExpression("==",o,omniAst.builders.literal(null));case "matches":return omniAst.builders.callExpression(omniAst.builders.memberExpression(omniAst.builders.newExpression(omniAst.builders.identifier("RegExp"),[s]),omniAst.builders.identifier("test")),[o]);case "notMatches":return omniAst.builders.unaryExpression("!",omniAst.builders.callExpression(omniAst.builders.memberExpression(omniAst.builders.newExpression(omniAst.builders.identifier("RegExp"),[s]),omniAst.builders.identifier("test")),[o]));case "startsWith":return omniAst.builders.callExpression(omniAst.builders.memberExpression(o,omniAst.builders.identifier("startsWith"),false,true),[s]);case "endsWith":return omniAst.builders.callExpression(omniAst.builders.memberExpression(o,omniAst.builders.identifier("endsWith"),false,true),[s]);default:return omniAst.builders.binaryExpression("===",o,s)}}function Wn(n,e,i,t){let{logic:o,conditions:s}=n,r=o==="AND"?"&&":"||";if(s.length===0)return omniAst.builders.literal(o==="AND");if(s.length===1)return d(s[0],e,i,t);let f=d(s[0],e,i,t);for(let u=1;u<s.length;u++){let c=d(s[u],e,i,t);f=omniAst.builders.logicalExpression(r,f,c);}return f}function N(n){let e=[],i=n.length,t=0,o="";for(;t<i;){let s=n[t];if(s===".")o&&(e.push({type:"key",value:o}),o=""),t++;else if(s==="["){o&&(e.push({type:"key",value:o}),o=""),t++;let r=t;for(;t<i&&n[t]!=="]";)t++;let f=n.slice(r,t);if(t++,f!=="*"){let u=parseInt(f,10);e.push({type:"index",value:isNaN(u)?f:u});}}else o+=s,t++;}return o&&e.push({type:"key",value:o}),e}function Z(n,e=[D]){return omniAst.builders.arrowFunctionExpression(e.map(i=>omniAst.builders.identifier(i)),n)}function G(n){let e=new Set;return b(n,e),e}function b(n,e){if(n===null||typeof n!="object")return;if(Array.isArray(n)){for(let t of n)b(t,e);return}if(m(n))return;if(E(n)){b(n.$if,e),b(n.then,e),n.else!==void 0&&b(n.else,e);return}if(C(n)){for(let t of n.$pipe)b(t,e);return}if(T(n)){if(e.add(n.$fn),n.args)for(let t of n.args)b(t,e);return}if(g(n)){n.value!==void 0&&typeof n.value=="object"&&b(n.value,e);return}if(y(n)){for(let t of n.conditions)b(t,e);return}let i=n;for(let t of Object.keys(i))b(i[t],e);}function W(n){let e=new Set;for(let i of n){let t=i.indexOf("."),o=i.indexOf("["),s=i.length;t!==-1&&(s=Math.min(s,t)),o!==-1&&(s=Math.min(s,o));let r=i.slice(0,s);r&&e.add(r);}return e}function zn(n){return JSON.stringify(n)}function Dn(n,e,i){let t=j(n,{noPrefixes:true}),o=omniAst.generate(t),s=e.size>0?`const{${[...e].join(",")}}=data??{};`:"",r=i.size>0?`const{${[...i].join(",")}}=scope;`:"";return r?`(function(scope){${r}return function(data){${s}return ${o}}})`:`(function(){return function(data){${s}return ${o}}})`}function M(n,e={}){let{scope:i={},returnCode:t=false}=e,o=S(n),s=W(o),r=G(n),f=zn(n),u=Dn(n,s,r);if(t)return {code:u,deps:o,hash:f,dataRoots:[...s],scopeFns:[...r]};let c;try{c=new Function(`return ${u}`)()(i);}catch(a){throw new Error(`AST compilation failed. If this is due to CSP, use the standard compile() function instead. Error: ${a instanceof Error?a.message:String(a)}`)}return {fn:c,deps:o,hash:f}}function nn(n,e,i={}){let{fn:t}=M(n,i);return t(e)}var ye="0.1.0";exports.ExpressionCache=v;exports.VERSION=ye;exports.assertValid=bn;exports.builders=Q;exports.cache=J;exports.cached=An;exports.clearPathCache=cn;exports.compile=F;exports.compileAST=M;exports.compilePath=O;exports.dslToAST=j;exports.evaluate=Cn;exports.evaluateAST=nn;exports.extractDataRoots=W;exports.extractDeps=S;exports.extractScopeFns=G;exports.get=un;exports.getPathCacheSize=an;exports.hasDeps=dn;exports.hasWildcard=L;exports.isCondition=g;exports.isConditionExpr=on;exports.isConditionGroup=y;exports.isConditional=E;exports.isFn=T;exports.isLiteral=P;exports.isPipe=C;exports.isPure=mn;exports.isRef=m;exports.isValid=$n;exports.normalizePath=k;exports.validate=z;exports.wrapInFunction=Z;
|
package/dist/index.d.cts
CHANGED
|
@@ -48,10 +48,17 @@ interface PipeExpr {
|
|
|
48
48
|
type Literal = string | number | boolean | null | Literal[] | {
|
|
49
49
|
[key: string]: Literal;
|
|
50
50
|
};
|
|
51
|
+
/**
|
|
52
|
+
* Callback function - used as argument in $fn (e.g., predicates, mappers)
|
|
53
|
+
* Not serializable to JSON, but valid in code.
|
|
54
|
+
* @example (item) => item.active
|
|
55
|
+
* @example (a, b) => a + b
|
|
56
|
+
*/
|
|
57
|
+
type CallbackFn = (...args: any[]) => unknown;
|
|
51
58
|
/**
|
|
52
59
|
* Union of all expression types
|
|
53
60
|
*/
|
|
54
|
-
type Expression = Literal | RefExpr | ConditionalExpr | FnExpr | PipeExpr | ConditionExpr;
|
|
61
|
+
type Expression = Literal | RefExpr | ConditionalExpr | FnExpr | PipeExpr | ConditionExpr | CallbackFn;
|
|
55
62
|
/**
|
|
56
63
|
* Compiled expression function
|
|
57
64
|
*/
|
|
@@ -71,6 +78,15 @@ interface CompiledExpression<T = unknown, R = unknown> {
|
|
|
71
78
|
* Path getter function
|
|
72
79
|
*/
|
|
73
80
|
type PathGetter<T = unknown> = (data: T) => unknown;
|
|
81
|
+
/**
|
|
82
|
+
* Accessor customizado para resolver paths
|
|
83
|
+
* Permite usar ctx.get(path) em vez de acesso direto por propriedade
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* // Com TickContext
|
|
87
|
+
* const accessor: AccessorFn<TickContext> = (path, ctx) => ctx.get(path);
|
|
88
|
+
*/
|
|
89
|
+
type AccessorFn<T = unknown> = (path: string, data: T) => unknown;
|
|
74
90
|
/**
|
|
75
91
|
* Validation result
|
|
76
92
|
*/
|
|
@@ -82,13 +98,22 @@ interface ValidationResult {
|
|
|
82
98
|
* Function scope - functions available to $fn expressions
|
|
83
99
|
* @example { add, subtract, multiply, filter, map, sum }
|
|
84
100
|
*/
|
|
85
|
-
type Scope = Record<string, (...args:
|
|
101
|
+
type Scope = Record<string, (...args: any[]) => any>;
|
|
86
102
|
/**
|
|
87
103
|
* Options for compilation
|
|
88
104
|
*/
|
|
89
|
-
interface CompileOptions {
|
|
105
|
+
interface CompileOptions<T = unknown> {
|
|
90
106
|
/** Functions available to $fn expressions */
|
|
91
107
|
scope?: Scope;
|
|
108
|
+
/**
|
|
109
|
+
* Accessor customizado para resolver paths.
|
|
110
|
+
* Quando fornecido, substitui o acesso direto por propriedade.
|
|
111
|
+
*
|
|
112
|
+
* @example
|
|
113
|
+
* // Com TickContext
|
|
114
|
+
* compile(expr, { accessor: (path, ctx) => ctx.get(path) })
|
|
115
|
+
*/
|
|
116
|
+
accessor?: AccessorFn<T>;
|
|
92
117
|
}
|
|
93
118
|
/**
|
|
94
119
|
* Check if value is a reference expression
|
|
@@ -139,11 +164,12 @@ declare const isLiteral: (v: unknown) => v is Literal;
|
|
|
139
164
|
* Compile expression to optimized function
|
|
140
165
|
*
|
|
141
166
|
* @param expr - Expression to compile
|
|
142
|
-
* @param options - Compile options (scope with functions)
|
|
167
|
+
* @param options - Compile options (scope with functions, accessor)
|
|
143
168
|
* @returns Compiled expression with fn, deps, and hash
|
|
144
169
|
*
|
|
145
170
|
* @example
|
|
146
171
|
* ```ts
|
|
172
|
+
* // Uso padrão - acesso direto por propriedade
|
|
147
173
|
* import { add, filter, sum } from '@statedelta-libs/operators';
|
|
148
174
|
*
|
|
149
175
|
* const { fn } = compile(
|
|
@@ -153,21 +179,40 @@ declare const isLiteral: (v: unknown) => v is Literal;
|
|
|
153
179
|
*
|
|
154
180
|
* fn({ a: 1, b: 2 }); // 3
|
|
155
181
|
* ```
|
|
182
|
+
*
|
|
183
|
+
* @example
|
|
184
|
+
* ```ts
|
|
185
|
+
* // Com accessor customizado (ex: TickContext)
|
|
186
|
+
* const { fn } = compile(
|
|
187
|
+
* { $: "hp:value" },
|
|
188
|
+
* { accessor: (path, ctx) => ctx.get(path) }
|
|
189
|
+
* );
|
|
190
|
+
*
|
|
191
|
+
* fn(tickContext); // usa ctx.get('hp:value')
|
|
192
|
+
* ```
|
|
156
193
|
*/
|
|
157
|
-
declare function compile<T = unknown, R = unknown>(expr: Expression, options?: CompileOptions): CompiledExpression<T, R>;
|
|
194
|
+
declare function compile<T = unknown, R = unknown>(expr: Expression, options?: CompileOptions<T>): CompiledExpression<T, R>;
|
|
158
195
|
/**
|
|
159
196
|
* Compile and execute in one step
|
|
160
197
|
*
|
|
161
198
|
* @example
|
|
162
199
|
* ```ts
|
|
200
|
+
* // Uso padrão
|
|
163
201
|
* evaluate(
|
|
164
202
|
* { $fn: "add", args: [{ $: "a" }, { $: "b" }] },
|
|
165
203
|
* { a: 1, b: 2 },
|
|
166
204
|
* { scope: { add } }
|
|
167
205
|
* ); // 3
|
|
206
|
+
*
|
|
207
|
+
* // Com accessor customizado
|
|
208
|
+
* evaluate(
|
|
209
|
+
* { $: "hp:value" },
|
|
210
|
+
* tickContext,
|
|
211
|
+
* { accessor: (path, ctx) => ctx.get(path) }
|
|
212
|
+
* );
|
|
168
213
|
* ```
|
|
169
214
|
*/
|
|
170
|
-
declare function evaluate<T = unknown, R = unknown>(expr: Expression, data: T, options?: CompileOptions): R;
|
|
215
|
+
declare function evaluate<T = unknown, R = unknown>(expr: Expression, data: T, options?: CompileOptions<T>): R;
|
|
171
216
|
|
|
172
217
|
/**
|
|
173
218
|
* @statedelta-libs/expressions - Path Compiler
|
|
@@ -311,6 +356,104 @@ declare function assertValid(expr: Expression, options?: ValidateOptions): void;
|
|
|
311
356
|
*/
|
|
312
357
|
declare function isValid(expr: Expression, options?: ValidateOptions): boolean;
|
|
313
358
|
|
|
359
|
+
/**
|
|
360
|
+
* @statedelta-libs/expressions - Builders
|
|
361
|
+
*
|
|
362
|
+
* Funções declarativas para construir expressões.
|
|
363
|
+
*
|
|
364
|
+
* @example
|
|
365
|
+
* ```typescript
|
|
366
|
+
* import { $, $fn, $if, $pipe } from "@statedelta-libs/expressions";
|
|
367
|
+
*
|
|
368
|
+
* // Path reference
|
|
369
|
+
* $("player.hp") // { $: "player.hp" }
|
|
370
|
+
*
|
|
371
|
+
* // Function call
|
|
372
|
+
* $fn("add", [$("a"), $("b")]) // { $fn: "add", args: [{ $: "a" }, { $: "b" }] }
|
|
373
|
+
*
|
|
374
|
+
* // Conditional
|
|
375
|
+
* $if(condition, "then", "else")
|
|
376
|
+
*
|
|
377
|
+
* // Pipe
|
|
378
|
+
* $pipe($("items"), $fn("filter", [pred]), $fn("sum"))
|
|
379
|
+
* ```
|
|
380
|
+
*/
|
|
381
|
+
|
|
382
|
+
/**
|
|
383
|
+
* Create a path reference expression.
|
|
384
|
+
*
|
|
385
|
+
* @param path - Dot-notation path to value
|
|
386
|
+
* @returns RefExpr
|
|
387
|
+
*
|
|
388
|
+
* @example
|
|
389
|
+
* $("player.hp") // { $: "player.hp" }
|
|
390
|
+
* $("items[0].price") // { $: "items[0].price" }
|
|
391
|
+
* $("items[*].price") // { $: "items[*].price" } (wildcard)
|
|
392
|
+
*/
|
|
393
|
+
declare function $(path: string): RefExpr;
|
|
394
|
+
/**
|
|
395
|
+
* Alias for $ (ref builder)
|
|
396
|
+
*/
|
|
397
|
+
declare const ref: typeof $;
|
|
398
|
+
/**
|
|
399
|
+
* Create a function call expression.
|
|
400
|
+
*
|
|
401
|
+
* @param name - Function name (from scope)
|
|
402
|
+
* @param args - Arguments (can be expressions)
|
|
403
|
+
* @returns FnExpr
|
|
404
|
+
*
|
|
405
|
+
* @example
|
|
406
|
+
* $fn("add", [$("a"), $("b")]) // { $fn: "add", args: [...] }
|
|
407
|
+
* $fn("multiply", [10, $("x")]) // literal + expression
|
|
408
|
+
* $fn("sum") // no args - returns function reference
|
|
409
|
+
* $fn("now", []) // empty args - calls function
|
|
410
|
+
*/
|
|
411
|
+
declare function $fn(name: string, args?: Expression[]): FnExpr;
|
|
412
|
+
/**
|
|
413
|
+
* Alias for $fn (function builder)
|
|
414
|
+
*/
|
|
415
|
+
declare const fn: typeof $fn;
|
|
416
|
+
/**
|
|
417
|
+
* Create a conditional expression.
|
|
418
|
+
*
|
|
419
|
+
* @param condition - Condition to evaluate
|
|
420
|
+
* @param thenExpr - Value if true
|
|
421
|
+
* @param elseExpr - Value if false (optional)
|
|
422
|
+
* @returns ConditionalExpr
|
|
423
|
+
*
|
|
424
|
+
* @example
|
|
425
|
+
* $if(condition, "alive", "dead")
|
|
426
|
+
* $if($("isVip"), 0.2, 0)
|
|
427
|
+
* $if(gte("hp", 0), $("hp"), 0)
|
|
428
|
+
*/
|
|
429
|
+
declare function $if(condition: Expression, thenExpr: Expression, elseExpr?: Expression): ConditionalExpr;
|
|
430
|
+
/**
|
|
431
|
+
* Create a pipe expression (composition with initial value).
|
|
432
|
+
*
|
|
433
|
+
* @param steps - Pipeline steps (first is input, rest are transformers)
|
|
434
|
+
* @returns PipeExpr
|
|
435
|
+
*
|
|
436
|
+
* @example
|
|
437
|
+
* $pipe($("items"), $fn("filter", [pred]), $fn("sum"))
|
|
438
|
+
* $pipe($("name"), $fn("uppercase"), $fn("trim"))
|
|
439
|
+
*/
|
|
440
|
+
declare function $pipe(...steps: Expression[]): PipeExpr;
|
|
441
|
+
/**
|
|
442
|
+
* Alias for $pipe (pipe builder)
|
|
443
|
+
*/
|
|
444
|
+
declare const pipe: typeof $pipe;
|
|
445
|
+
|
|
446
|
+
declare const builders_$: typeof $;
|
|
447
|
+
declare const builders_$fn: typeof $fn;
|
|
448
|
+
declare const builders_$if: typeof $if;
|
|
449
|
+
declare const builders_$pipe: typeof $pipe;
|
|
450
|
+
declare const builders_fn: typeof fn;
|
|
451
|
+
declare const builders_pipe: typeof pipe;
|
|
452
|
+
declare const builders_ref: typeof ref;
|
|
453
|
+
declare namespace builders {
|
|
454
|
+
export { builders_$ as $, builders_$fn as $fn, builders_$if as $if, builders_$pipe as $pipe, builders_fn as fn, builders_pipe as pipe, builders_ref as ref };
|
|
455
|
+
}
|
|
456
|
+
|
|
314
457
|
/**
|
|
315
458
|
* @statedelta-libs/expressions - DSL to AST Transformer
|
|
316
459
|
*
|
|
@@ -506,6 +649,6 @@ declare function evaluateAST<T = unknown, R = unknown>(expr: Expression, data: T
|
|
|
506
649
|
* ); // 3
|
|
507
650
|
* ```
|
|
508
651
|
*/
|
|
509
|
-
declare const VERSION = "0.0
|
|
652
|
+
declare const VERSION = "0.1.0";
|
|
510
653
|
|
|
511
|
-
export { type CompileASTCodeResult, type CompileASTOptions, type CompileOptions, type CompiledExpression, type CompiledFn, type ConditionalExpr, type Expression, ExpressionCache, type FnExpr, type Literal, type PathGetter, type PipeExpr, type RefExpr, type Scope, type TransformOptions, VERSION, type ValidateOptions, type ValidationResult, assertValid, cache, cached, clearPathCache, compile, compileAST, compilePath, dslToAST, evaluate, evaluateAST, extractDataRoots, extractDeps, extractScopeFns, get, getPathCacheSize, hasDeps, hasWildcard, isCondition, isConditionExpr, isConditionGroup, isConditional, isFn, isLiteral, isPipe, isPure, isRef, isValid, normalizePath, validate, wrapInFunction };
|
|
654
|
+
export { type AccessorFn, type CallbackFn, type CompileASTCodeResult, type CompileASTOptions, type CompileOptions, type CompiledExpression, type CompiledFn, type ConditionalExpr, type Expression, ExpressionCache, type FnExpr, type Literal, type PathGetter, type PipeExpr, type RefExpr, type Scope, type TransformOptions, VERSION, type ValidateOptions, type ValidationResult, assertValid, builders, cache, cached, clearPathCache, compile, compileAST, compilePath, dslToAST, evaluate, evaluateAST, extractDataRoots, extractDeps, extractScopeFns, get, getPathCacheSize, hasDeps, hasWildcard, isCondition, isConditionExpr, isConditionGroup, isConditional, isFn, isLiteral, isPipe, isPure, isRef, isValid, normalizePath, validate, wrapInFunction };
|
package/dist/index.d.ts
CHANGED
|
@@ -48,10 +48,17 @@ interface PipeExpr {
|
|
|
48
48
|
type Literal = string | number | boolean | null | Literal[] | {
|
|
49
49
|
[key: string]: Literal;
|
|
50
50
|
};
|
|
51
|
+
/**
|
|
52
|
+
* Callback function - used as argument in $fn (e.g., predicates, mappers)
|
|
53
|
+
* Not serializable to JSON, but valid in code.
|
|
54
|
+
* @example (item) => item.active
|
|
55
|
+
* @example (a, b) => a + b
|
|
56
|
+
*/
|
|
57
|
+
type CallbackFn = (...args: any[]) => unknown;
|
|
51
58
|
/**
|
|
52
59
|
* Union of all expression types
|
|
53
60
|
*/
|
|
54
|
-
type Expression = Literal | RefExpr | ConditionalExpr | FnExpr | PipeExpr | ConditionExpr;
|
|
61
|
+
type Expression = Literal | RefExpr | ConditionalExpr | FnExpr | PipeExpr | ConditionExpr | CallbackFn;
|
|
55
62
|
/**
|
|
56
63
|
* Compiled expression function
|
|
57
64
|
*/
|
|
@@ -71,6 +78,15 @@ interface CompiledExpression<T = unknown, R = unknown> {
|
|
|
71
78
|
* Path getter function
|
|
72
79
|
*/
|
|
73
80
|
type PathGetter<T = unknown> = (data: T) => unknown;
|
|
81
|
+
/**
|
|
82
|
+
* Accessor customizado para resolver paths
|
|
83
|
+
* Permite usar ctx.get(path) em vez de acesso direto por propriedade
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* // Com TickContext
|
|
87
|
+
* const accessor: AccessorFn<TickContext> = (path, ctx) => ctx.get(path);
|
|
88
|
+
*/
|
|
89
|
+
type AccessorFn<T = unknown> = (path: string, data: T) => unknown;
|
|
74
90
|
/**
|
|
75
91
|
* Validation result
|
|
76
92
|
*/
|
|
@@ -82,13 +98,22 @@ interface ValidationResult {
|
|
|
82
98
|
* Function scope - functions available to $fn expressions
|
|
83
99
|
* @example { add, subtract, multiply, filter, map, sum }
|
|
84
100
|
*/
|
|
85
|
-
type Scope = Record<string, (...args:
|
|
101
|
+
type Scope = Record<string, (...args: any[]) => any>;
|
|
86
102
|
/**
|
|
87
103
|
* Options for compilation
|
|
88
104
|
*/
|
|
89
|
-
interface CompileOptions {
|
|
105
|
+
interface CompileOptions<T = unknown> {
|
|
90
106
|
/** Functions available to $fn expressions */
|
|
91
107
|
scope?: Scope;
|
|
108
|
+
/**
|
|
109
|
+
* Accessor customizado para resolver paths.
|
|
110
|
+
* Quando fornecido, substitui o acesso direto por propriedade.
|
|
111
|
+
*
|
|
112
|
+
* @example
|
|
113
|
+
* // Com TickContext
|
|
114
|
+
* compile(expr, { accessor: (path, ctx) => ctx.get(path) })
|
|
115
|
+
*/
|
|
116
|
+
accessor?: AccessorFn<T>;
|
|
92
117
|
}
|
|
93
118
|
/**
|
|
94
119
|
* Check if value is a reference expression
|
|
@@ -139,11 +164,12 @@ declare const isLiteral: (v: unknown) => v is Literal;
|
|
|
139
164
|
* Compile expression to optimized function
|
|
140
165
|
*
|
|
141
166
|
* @param expr - Expression to compile
|
|
142
|
-
* @param options - Compile options (scope with functions)
|
|
167
|
+
* @param options - Compile options (scope with functions, accessor)
|
|
143
168
|
* @returns Compiled expression with fn, deps, and hash
|
|
144
169
|
*
|
|
145
170
|
* @example
|
|
146
171
|
* ```ts
|
|
172
|
+
* // Uso padrão - acesso direto por propriedade
|
|
147
173
|
* import { add, filter, sum } from '@statedelta-libs/operators';
|
|
148
174
|
*
|
|
149
175
|
* const { fn } = compile(
|
|
@@ -153,21 +179,40 @@ declare const isLiteral: (v: unknown) => v is Literal;
|
|
|
153
179
|
*
|
|
154
180
|
* fn({ a: 1, b: 2 }); // 3
|
|
155
181
|
* ```
|
|
182
|
+
*
|
|
183
|
+
* @example
|
|
184
|
+
* ```ts
|
|
185
|
+
* // Com accessor customizado (ex: TickContext)
|
|
186
|
+
* const { fn } = compile(
|
|
187
|
+
* { $: "hp:value" },
|
|
188
|
+
* { accessor: (path, ctx) => ctx.get(path) }
|
|
189
|
+
* );
|
|
190
|
+
*
|
|
191
|
+
* fn(tickContext); // usa ctx.get('hp:value')
|
|
192
|
+
* ```
|
|
156
193
|
*/
|
|
157
|
-
declare function compile<T = unknown, R = unknown>(expr: Expression, options?: CompileOptions): CompiledExpression<T, R>;
|
|
194
|
+
declare function compile<T = unknown, R = unknown>(expr: Expression, options?: CompileOptions<T>): CompiledExpression<T, R>;
|
|
158
195
|
/**
|
|
159
196
|
* Compile and execute in one step
|
|
160
197
|
*
|
|
161
198
|
* @example
|
|
162
199
|
* ```ts
|
|
200
|
+
* // Uso padrão
|
|
163
201
|
* evaluate(
|
|
164
202
|
* { $fn: "add", args: [{ $: "a" }, { $: "b" }] },
|
|
165
203
|
* { a: 1, b: 2 },
|
|
166
204
|
* { scope: { add } }
|
|
167
205
|
* ); // 3
|
|
206
|
+
*
|
|
207
|
+
* // Com accessor customizado
|
|
208
|
+
* evaluate(
|
|
209
|
+
* { $: "hp:value" },
|
|
210
|
+
* tickContext,
|
|
211
|
+
* { accessor: (path, ctx) => ctx.get(path) }
|
|
212
|
+
* );
|
|
168
213
|
* ```
|
|
169
214
|
*/
|
|
170
|
-
declare function evaluate<T = unknown, R = unknown>(expr: Expression, data: T, options?: CompileOptions): R;
|
|
215
|
+
declare function evaluate<T = unknown, R = unknown>(expr: Expression, data: T, options?: CompileOptions<T>): R;
|
|
171
216
|
|
|
172
217
|
/**
|
|
173
218
|
* @statedelta-libs/expressions - Path Compiler
|
|
@@ -311,6 +356,104 @@ declare function assertValid(expr: Expression, options?: ValidateOptions): void;
|
|
|
311
356
|
*/
|
|
312
357
|
declare function isValid(expr: Expression, options?: ValidateOptions): boolean;
|
|
313
358
|
|
|
359
|
+
/**
|
|
360
|
+
* @statedelta-libs/expressions - Builders
|
|
361
|
+
*
|
|
362
|
+
* Funções declarativas para construir expressões.
|
|
363
|
+
*
|
|
364
|
+
* @example
|
|
365
|
+
* ```typescript
|
|
366
|
+
* import { $, $fn, $if, $pipe } from "@statedelta-libs/expressions";
|
|
367
|
+
*
|
|
368
|
+
* // Path reference
|
|
369
|
+
* $("player.hp") // { $: "player.hp" }
|
|
370
|
+
*
|
|
371
|
+
* // Function call
|
|
372
|
+
* $fn("add", [$("a"), $("b")]) // { $fn: "add", args: [{ $: "a" }, { $: "b" }] }
|
|
373
|
+
*
|
|
374
|
+
* // Conditional
|
|
375
|
+
* $if(condition, "then", "else")
|
|
376
|
+
*
|
|
377
|
+
* // Pipe
|
|
378
|
+
* $pipe($("items"), $fn("filter", [pred]), $fn("sum"))
|
|
379
|
+
* ```
|
|
380
|
+
*/
|
|
381
|
+
|
|
382
|
+
/**
|
|
383
|
+
* Create a path reference expression.
|
|
384
|
+
*
|
|
385
|
+
* @param path - Dot-notation path to value
|
|
386
|
+
* @returns RefExpr
|
|
387
|
+
*
|
|
388
|
+
* @example
|
|
389
|
+
* $("player.hp") // { $: "player.hp" }
|
|
390
|
+
* $("items[0].price") // { $: "items[0].price" }
|
|
391
|
+
* $("items[*].price") // { $: "items[*].price" } (wildcard)
|
|
392
|
+
*/
|
|
393
|
+
declare function $(path: string): RefExpr;
|
|
394
|
+
/**
|
|
395
|
+
* Alias for $ (ref builder)
|
|
396
|
+
*/
|
|
397
|
+
declare const ref: typeof $;
|
|
398
|
+
/**
|
|
399
|
+
* Create a function call expression.
|
|
400
|
+
*
|
|
401
|
+
* @param name - Function name (from scope)
|
|
402
|
+
* @param args - Arguments (can be expressions)
|
|
403
|
+
* @returns FnExpr
|
|
404
|
+
*
|
|
405
|
+
* @example
|
|
406
|
+
* $fn("add", [$("a"), $("b")]) // { $fn: "add", args: [...] }
|
|
407
|
+
* $fn("multiply", [10, $("x")]) // literal + expression
|
|
408
|
+
* $fn("sum") // no args - returns function reference
|
|
409
|
+
* $fn("now", []) // empty args - calls function
|
|
410
|
+
*/
|
|
411
|
+
declare function $fn(name: string, args?: Expression[]): FnExpr;
|
|
412
|
+
/**
|
|
413
|
+
* Alias for $fn (function builder)
|
|
414
|
+
*/
|
|
415
|
+
declare const fn: typeof $fn;
|
|
416
|
+
/**
|
|
417
|
+
* Create a conditional expression.
|
|
418
|
+
*
|
|
419
|
+
* @param condition - Condition to evaluate
|
|
420
|
+
* @param thenExpr - Value if true
|
|
421
|
+
* @param elseExpr - Value if false (optional)
|
|
422
|
+
* @returns ConditionalExpr
|
|
423
|
+
*
|
|
424
|
+
* @example
|
|
425
|
+
* $if(condition, "alive", "dead")
|
|
426
|
+
* $if($("isVip"), 0.2, 0)
|
|
427
|
+
* $if(gte("hp", 0), $("hp"), 0)
|
|
428
|
+
*/
|
|
429
|
+
declare function $if(condition: Expression, thenExpr: Expression, elseExpr?: Expression): ConditionalExpr;
|
|
430
|
+
/**
|
|
431
|
+
* Create a pipe expression (composition with initial value).
|
|
432
|
+
*
|
|
433
|
+
* @param steps - Pipeline steps (first is input, rest are transformers)
|
|
434
|
+
* @returns PipeExpr
|
|
435
|
+
*
|
|
436
|
+
* @example
|
|
437
|
+
* $pipe($("items"), $fn("filter", [pred]), $fn("sum"))
|
|
438
|
+
* $pipe($("name"), $fn("uppercase"), $fn("trim"))
|
|
439
|
+
*/
|
|
440
|
+
declare function $pipe(...steps: Expression[]): PipeExpr;
|
|
441
|
+
/**
|
|
442
|
+
* Alias for $pipe (pipe builder)
|
|
443
|
+
*/
|
|
444
|
+
declare const pipe: typeof $pipe;
|
|
445
|
+
|
|
446
|
+
declare const builders_$: typeof $;
|
|
447
|
+
declare const builders_$fn: typeof $fn;
|
|
448
|
+
declare const builders_$if: typeof $if;
|
|
449
|
+
declare const builders_$pipe: typeof $pipe;
|
|
450
|
+
declare const builders_fn: typeof fn;
|
|
451
|
+
declare const builders_pipe: typeof pipe;
|
|
452
|
+
declare const builders_ref: typeof ref;
|
|
453
|
+
declare namespace builders {
|
|
454
|
+
export { builders_$ as $, builders_$fn as $fn, builders_$if as $if, builders_$pipe as $pipe, builders_fn as fn, builders_pipe as pipe, builders_ref as ref };
|
|
455
|
+
}
|
|
456
|
+
|
|
314
457
|
/**
|
|
315
458
|
* @statedelta-libs/expressions - DSL to AST Transformer
|
|
316
459
|
*
|
|
@@ -506,6 +649,6 @@ declare function evaluateAST<T = unknown, R = unknown>(expr: Expression, data: T
|
|
|
506
649
|
* ); // 3
|
|
507
650
|
* ```
|
|
508
651
|
*/
|
|
509
|
-
declare const VERSION = "0.0
|
|
652
|
+
declare const VERSION = "0.1.0";
|
|
510
653
|
|
|
511
|
-
export { type CompileASTCodeResult, type CompileASTOptions, type CompileOptions, type CompiledExpression, type CompiledFn, type ConditionalExpr, type Expression, ExpressionCache, type FnExpr, type Literal, type PathGetter, type PipeExpr, type RefExpr, type Scope, type TransformOptions, VERSION, type ValidateOptions, type ValidationResult, assertValid, cache, cached, clearPathCache, compile, compileAST, compilePath, dslToAST, evaluate, evaluateAST, extractDataRoots, extractDeps, extractScopeFns, get, getPathCacheSize, hasDeps, hasWildcard, isCondition, isConditionExpr, isConditionGroup, isConditional, isFn, isLiteral, isPipe, isPure, isRef, isValid, normalizePath, validate, wrapInFunction };
|
|
654
|
+
export { type AccessorFn, type CallbackFn, type CompileASTCodeResult, type CompileASTOptions, type CompileOptions, type CompiledExpression, type CompiledFn, type ConditionalExpr, type Expression, ExpressionCache, type FnExpr, type Literal, type PathGetter, type PipeExpr, type RefExpr, type Scope, type TransformOptions, VERSION, type ValidateOptions, type ValidationResult, assertValid, builders, cache, cached, clearPathCache, compile, compileAST, compilePath, dslToAST, evaluate, evaluateAST, extractDataRoots, extractDeps, extractScopeFns, get, getPathCacheSize, hasDeps, hasWildcard, isCondition, isConditionExpr, isConditionGroup, isConditional, isFn, isLiteral, isPipe, isPure, isRef, isValid, normalizePath, validate, wrapInFunction };
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import {isRef,compile,validate}from'@statedelta-libs/conditions';import {builders,generate}from'omni-ast';var m=n=>n!==null&&typeof n=="object"&&"$"in n&&typeof n.$=="string"&&Object.keys(n).length===1,h=n=>n!==null&&typeof n=="object"&&"$if"in n&&"then"in n,E=n=>n!==null&&typeof n=="object"&&"$fn"in n&&typeof n.$fn=="string",C=n=>n!==null&&typeof n=="object"&&"$pipe"in n&&Array.isArray(n.$pipe),M=new Set(["eq","neq","gt","gte","lt","lte","in","notIn","contains","notContains","exists","notExists","matches","notMatches","startsWith","endsWith"]),g=n=>n!==null&&typeof n=="object"&&"path"in n&&"op"in n&&M.has(n.op)&&!("$"in n)&&!("$if"in n)&&!("$fn"in n),y=n=>n!==null&&typeof n=="object"&&"logic"in n&&"conditions"in n,H=n=>g(n)||y(n),W=n=>{if(n===null)return true;let e=typeof n;if(e==="string"||e==="number"||e==="boolean"||Array.isArray(n))return true;if(e==="object"&&n!==null){let t=n,o="path"in t&&"op"in t&&M.has(t.op);return !("$"in t)&&!("$if"in t)&&!("$fn"in t)&&!("$pipe"in t)&&!o&&!("logic"in t)}return false};var R=new Map;function I(n){let e=[],t=n.length,o=0,i="";for(;o<t;){let s=n[o];if(s===".")i&&(e.push({type:"key",value:i}),i=""),o++;else if(s==="["){i&&(e.push({type:"key",value:i}),i=""),o++;let r=o;for(;o<t&&n[o]!=="]";)o++;let c=n.slice(r,o);if(o++,c==="*")e.push({type:"wildcard",value:"*"});else {let f=parseInt(c,10);e.push({type:"index",value:isNaN(f)?c:f});}}else i+=s,o++;}return i&&e.push({type:"key",value:i}),e}function V(n){return n.includes("[*]")}function x(n){let e=R.get(n);return e||(e=V(n)?U(n):Q(n),R.set(n,e),e)}function Q(n){if(!n.includes(".")&&!n.includes("["))return i=>i?.[n];let e=I(n),t=e.length;if(t===2){let[i,s]=e,r=i.value,c=s.value;return f=>f?.[r]?.[c]}if(t===3){let[i,s,r]=e,c=i.value,f=s.value,a=r.value;return u=>u?.[c]?.[f]?.[a]}let o=e.map(i=>i.value);return i=>{let s=i;for(let r=0;r<t&&s!=null;r++)s=s[o[r]];return s}}function U(n){let e=I(n),t=[];for(let o=0;o<e.length;o++)e[o].type==="wildcard"&&t.push(o);return t.length===1?X(e,t[0]):Z(e,t)}function X(n,e){let t=n.slice(0,e).map(r=>r.value),o=n.slice(e+1).map(r=>r.value),i=t.length,s=o.length;if(s===0){if(i===1){let r=t[0];return c=>c?.[r]}return r=>{let c=r;for(let f=0;f<i&&c!=null;f++)c=c[t[f]];return c}}if(s===1){let r=o[0];if(i===1){let c=t[0];return f=>{let a=f?.[c];if(Array.isArray(a))return a.map(u=>u?.[r])}}return c=>{let f=c;for(let a=0;a<i&&f!=null;a++)f=f[t[a]];if(Array.isArray(f))return f.map(a=>a?.[r])}}return r=>{let c=r;for(let f=0;f<i&&c!=null;f++)c=c[t[f]];if(Array.isArray(c))return c.map(f=>{let a=f;for(let u=0;u<s&&a!=null;u++)a=a[o[u]];return a})}}function Z(n,e){let t=[],o=0;for(let s=0;s<e.length;s++){let r=e[s],c=s===e.length-1,f=n.slice(o,r).map(a=>a.value);f.length>0&&t.push({type:"access",keys:f}),t.push({type:c?"map":"flatMap",keys:[]}),o=r+1;}let i=n.slice(o).map(s=>s.value);return s=>{let r=s;for(let c of t){if(r==null)return;if(c.type==="access")for(let f of c.keys){if(r==null)return;r=r[f];}else if(c.type==="flatMap"){if(!Array.isArray(r))return;r=r.flatMap(f=>{let a=f;return Array.isArray(a)?a:[a]});}else if(c.type==="map"){if(!Array.isArray(r))return;i.length>0&&(r=r.map(f=>{let a=f;for(let u of i){if(a==null)return;a=a[u];}return a}));}}return r}}function nn(n,e){return x(e)(n)}function k(n){let e=n.indexOf("[*]");return e===-1?n:n.slice(0,e)}function en(){R.clear();}function tn(){return R.size}function T(n){let e=new Set;return A(n,e),Array.from(e)}function A(n,e){if(n===null||typeof n!="object")return;if(Array.isArray(n)){for(let i=0;i<n.length;i++)A(n[i],e);return}if(m(n)){e.add(k(n.$));return}if(h(n)){if(typeof n.$if=="string"){let i=n.$if.startsWith("!")?n.$if.slice(1):n.$if;e.add(k(i));}else A(n.$if,e);A(n.then,e),n.else!==void 0&&A(n.else,e);return}if(C(n)){for(let i=0;i<n.$pipe.length;i++)A(n.$pipe[i],e);return}if(E(n)){if(n.args)for(let i=0;i<n.args.length;i++)A(n.args[i],e);return}if(g(n)){e.add(k(n.path)),n.value!==void 0&&isRef(n.value)&&e.add(k(n.value.$));return}if(y(n)){for(let i=0;i<n.conditions.length;i++)A(n.conditions[i],e);return}let t=n,o=Object.keys(t);for(let i=0;i<o.length;i++)A(t[o[i]],e);}function rn(n){return T(n).length>0}function sn(n){return T(n).length===0}function ln(n){return JSON.stringify(n)}function O(n,e={}){let t=e.scope??{},o=b(n,t),i=T(n),s=ln(n);return {fn:o,deps:i,hash:s}}function b(n,e){if(n===null)return ()=>null;if(typeof n!="object")return ()=>n;if(Array.isArray(n)){let t=n.map(o=>b(o,e));return o=>t.map(i=>i(o))}if(m(n))return cn(n);if(h(n))return fn(n,e);if(C(n))return an(n,e);if(E(n))return un(n,e);if(g(n))return compile(n);if(y(n))return compile(n);if(W(n)){let t=n,o=Object.keys(t),i=o.map(s=>b(t[s],e));return s=>{let r={};for(let c=0;c<o.length;c++)r[o[c]]=i[c](s);return r}}return ()=>n}function cn(n){return x(n.$)}function fn(n,e){let t;if(typeof n.$if=="string"){let s=n.$if.startsWith("!")?n.$if.slice(1):n.$if,r=x(s);t=n.$if.startsWith("!")?f=>!r(f):f=>!!r(f);}else {let s=b(n.$if,e);t=r=>!!s(r);}let o=b(n.then,e),i=n.else!==void 0?b(n.else,e):()=>{};return s=>t(s)?o(s):i(s)}function an(n,e){let t=n.$pipe;if(t.length===0)return ()=>{};if(t.length===1)return b(t[0],e);let o=b(t[0],e),i=t.slice(1).map(r=>b(r,e)),s=i.length;if(s===1){let[r]=i;return c=>{let f=o(c),a=r(c);return typeof a=="function"?a(f):a}}if(s===2){let[r,c]=i;return f=>{let a=o(f),u=r(f);return a=typeof u=="function"?u(a):u,u=c(f),typeof u=="function"?u(a):u}}if(s===3){let[r,c,f]=i;return a=>{let u=o(a),p=r(a);return u=typeof p=="function"?p(u):p,p=c(a),u=typeof p=="function"?p(u):p,p=f(a),typeof p=="function"?p(u):p}}return r=>{let c=o(r);for(let f=0;f<s;f++){let a=i[f](r);c=typeof a=="function"?a(c):a;}return c}}function un(n,e){let t=n.$fn,o=n.args;if(o===void 0)return ()=>{let r=e[t];if(!r)throw new Error(`Function not found in scope: ${t}`);return r};let i=o.map(r=>b(r,e)),s=i.length;if(s===0)return r=>{let c=e[t];if(!c)throw new Error(`Function not found in scope: ${t}`);return c()};if(s===1){let[r]=i;return c=>{let f=e[t];if(!f)throw new Error(`Function not found in scope: ${t}`);return f(r(c))}}if(s===2){let[r,c]=i;return f=>{let a=e[t];if(!a)throw new Error(`Function not found in scope: ${t}`);return a(r(f),c(f))}}if(s===3){let[r,c,f]=i;return a=>{let u=e[t];if(!u)throw new Error(`Function not found in scope: ${t}`);return u(r(a),c(a),f(a))}}return r=>{let c=e[t];if(!c)throw new Error(`Function not found in scope: ${t}`);return c(...i.map(f=>f(r)))}}function pn(n,e,t={}){return O(n,t).fn(e)}var v=class{constructor(e=1e3){this.cache=new Map,this._maxSize=e;}get(e,t={}){let o=JSON.stringify(e),i=this.cache.get(o);if(i)return this.cache.delete(o),this.cache.set(o,i),i;let s=O(e,t);if(this.cache.size>=this._maxSize){let r=this.cache.keys().next().value;r&&this.cache.delete(r);}return this.cache.set(o,s),s}has(e){return this.cache.has(JSON.stringify(e))}delete(e){return this.cache.delete(JSON.stringify(e))}clear(){this.cache.clear();}get size(){return this.cache.size}get maxSize(){return this._maxSize}set maxSize(e){for(this._maxSize=e;this.cache.size>this._maxSize;){let t=this.cache.keys().next().value;t&&this.cache.delete(t);}}},_=new v;function dn(n,e={}){return _.get(n,e)}function z(n,e="root",t={}){let o=[];return $(n,e,o,t),{valid:o.length===0,errors:o}}function $(n,e,t,o){if(n===null||typeof n!="object")return;if(Array.isArray(n)){for(let r=0;r<n.length;r++)$(n[r],`${e}[${r}]`,t,o);return}if(m(n)){(!n.$||typeof n.$!="string")&&t.push(`${e}: invalid reference, $ must be non-empty string`);return}if(h(n)){typeof n.$if=="string"?(n.$if.startsWith("!")?n.$if.slice(1):n.$if)||t.push(`${e}.$if: empty path in string shorthand`):$(n.$if,`${e}.$if`,t,o),$(n.then,`${e}.then`,t,o),n.else!==void 0&&$(n.else,`${e}.else`,t,o);return}if(C(n)){if(!Array.isArray(n.$pipe)){t.push(`${e}.$pipe: must be an array`);return}if(n.$pipe.length===0){t.push(`${e}.$pipe: must have at least one element`);return}for(let r=0;r<n.$pipe.length;r++)$(n.$pipe[r],`${e}.$pipe[${r}]`,t,o);return}if(E(n)){if(!n.$fn||typeof n.$fn!="string"){t.push(`${e}: invalid function, $fn must be non-empty string`);return}if(o.scope&&!(n.$fn in o.scope)&&t.push(`${e}: function "${n.$fn}" not found in scope`),n.args!==void 0)if(!Array.isArray(n.args))t.push(`${e}.args: must be an array`);else for(let r=0;r<n.args.length;r++)$(n.args[r],`${e}.args[${r}]`,t,o);return}if(g(n)){let r=validate(n,e);r.valid||t.push(...r.errors);return}if(y(n)){let r=validate(n,e);r.valid||t.push(...r.errors);return}let i=n,s=Object.keys(i);for(let r=0;r<s.length;r++){let c=s[r];$(i[c],`${e}.${c}`,t,o);}}function mn(n,e={}){let t=z(n,"root",e);if(!t.valid)throw new Error(`Invalid expression: ${t.errors.join("; ")}`)}function gn(n,e={}){return z(n,"root",e).valid}var P="data",J="scope",yn={eq:"===",neq:"!==",gt:">",gte:">=",lt:"<",lte:"<="};function N(n,e={}){let{dataParam:t=P,scopeParam:o=J,noPrefixes:i=false}=e;return d(n,t,o,i)}function d(n,e,t,o){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(i=>d(i,e,t,o)));if(m(n))return hn(n.$,e,o);if(h(n))return Cn(n,e,t,o);if(C(n))return Sn(n.$pipe,e,t,o);if(E(n))return bn(n,e,t,o);if(g(n))return An(n,e,t,o);if(y(n))return $n(n,e,t,o);if(typeof n=="object"){let s=Object.entries(n).map(([r,c])=>builders.property(builders.identifier(r),d(c,e,t,o)));return builders.objectExpression(s)}return builders.literal(null)}function hn(n,e,t){return n.includes("[*]")?En(n,e,t):w(n,e,t)}function w(n,e,t){let o=F(n);if(o.length===0)return t?builders.identifier("undefined"):builders.identifier(e);let i;if(t){let s=o[0];i=builders.identifier(s.value);for(let r=1;r<o.length;r++){let c=o[r];c.type==="key"?i=builders.memberExpression(i,builders.identifier(c.value),false,true):i=builders.memberExpression(i,builders.literal(c.value),true,true);}}else {i=builders.identifier(e);for(let s of o)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 En(n,e,t){let o=n.indexOf("[*]"),i=n.slice(0,o),s=n.slice(o+3),r;if(i?r=w(i,e,t):r=t?builders.identifier("undefined"):builders.identifier(e),!s||s==="")return r;if(s.includes("[*]"))return B(r,s);let c="_i",f=s.startsWith(".")?s.slice(1):s,a=builders.identifier(c);if(f){let u=F(f);for(let p of u)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(r,builders.identifier("map"),false,true),[builders.arrowFunctionExpression([builders.identifier(c)],a)])}function B(n,e){let t=e.indexOf("[*]"),o=e.slice(0,t),i=e.slice(t+3),s="_i",r=o.startsWith(".")?o.slice(1):o,c=builders.identifier(s);if(r){let a=F(r);for(let u of a)u.type==="key"&&(c=builders.memberExpression(c,builders.identifier(u.value),false,true));}if(i.includes("[*]")){let a=B(c,i);return builders.callExpression(builders.memberExpression(n,builders.identifier("flatMap"),false,true),[builders.arrowFunctionExpression([builders.identifier(s)],a)])}let f=i.startsWith(".")?i.slice(1):i;if(f){let a=F(f);for(let u of a)u.type==="key"&&(c=builders.memberExpression(c,builders.identifier(u.value),false,true));}return builders.callExpression(builders.memberExpression(n,builders.identifier("flatMap"),false,true),[builders.arrowFunctionExpression([builders.identifier(s)],c)])}function Cn(n,e,t,o){let i;if(typeof n.$if=="string"){let c=n.$if.startsWith("!"),f=c?n.$if.slice(1):n.$if,a=w(f,e,o);i=c?builders.unaryExpression("!",a):a;}else i=d(n.$if,e,t,o);let s=d(n.then,e,t,o),r=n.else!==void 0?d(n.else,e,t,o):builders.identifier("undefined");return builders.conditionalExpression(i,s,r)}function bn(n,e,t,o){let i=o?builders.identifier(n.$fn):builders.memberExpression(builders.identifier(t),builders.identifier(n.$fn),false,false);if(n.args===void 0)return i;let s=n.args.map(r=>d(r,e,t,o));return builders.callExpression(i,s)}function Sn(n,e,t,o){if(n.length===0)return builders.identifier("undefined");if(n.length===1)return d(n[0],e,t,o);let i=d(n[0],e,t,o);for(let s=1;s<n.length;s++){let r=d(n[s],e,t,o);i=builders.callExpression(r,[i]);}return i}function An(n,e,t,o){let i=w(n.path,e,o),s=n.value!==void 0?m(n.value)?w(n.value.$,e,o):d(n.value,e,t,o):builders.literal(null),r=yn[n.op];if(r)return builders.binaryExpression(r,i,s);switch(n.op){case "in":return builders.callExpression(builders.memberExpression(s,builders.identifier("includes")),[i]);case "notIn":return builders.unaryExpression("!",builders.callExpression(builders.memberExpression(s,builders.identifier("includes")),[i]));case "contains":return builders.callExpression(builders.memberExpression(i,builders.identifier("includes"),false,true),[s]);case "notContains":return builders.unaryExpression("!",builders.callExpression(builders.memberExpression(i,builders.identifier("includes"),false,true),[s]));case "exists":return builders.binaryExpression("!=",i,builders.literal(null));case "notExists":return builders.binaryExpression("==",i,builders.literal(null));case "matches":return builders.callExpression(builders.memberExpression(builders.newExpression(builders.identifier("RegExp"),[s]),builders.identifier("test")),[i]);case "notMatches":return builders.unaryExpression("!",builders.callExpression(builders.memberExpression(builders.newExpression(builders.identifier("RegExp"),[s]),builders.identifier("test")),[i]));case "startsWith":return builders.callExpression(builders.memberExpression(i,builders.identifier("startsWith"),false,true),[s]);case "endsWith":return builders.callExpression(builders.memberExpression(i,builders.identifier("endsWith"),false,true),[s]);default:return builders.binaryExpression("===",i,s)}}function $n(n,e,t,o){let{logic:i,conditions:s}=n,r=i==="AND"?"&&":"||";if(s.length===0)return builders.literal(i==="AND");if(s.length===1)return d(s[0],e,t,o);let c=d(s[0],e,t,o);for(let f=1;f<s.length;f++){let a=d(s[f],e,t,o);c=builders.logicalExpression(r,c,a);}return c}function F(n){let e=[],t=n.length,o=0,i="";for(;o<t;){let s=n[o];if(s===".")i&&(e.push({type:"key",value:i}),i=""),o++;else if(s==="["){i&&(e.push({type:"key",value:i}),i=""),o++;let r=o;for(;o<t&&n[o]!=="]";)o++;let c=n.slice(r,o);if(o++,c!=="*"){let f=parseInt(c,10);e.push({type:"index",value:isNaN(f)?c:f});}}else i+=s,o++;}return i&&e.push({type:"key",value:i}),e}function K(n,e=[P]){return builders.arrowFunctionExpression(e.map(t=>builders.identifier(t)),n)}function j(n){let e=new Set;return S(n,e),e}function S(n,e){if(n===null||typeof n!="object")return;if(Array.isArray(n)){for(let o of n)S(o,e);return}if(m(n))return;if(h(n)){S(n.$if,e),S(n.then,e),n.else!==void 0&&S(n.else,e);return}if(C(n)){for(let o of n.$pipe)S(o,e);return}if(E(n)){if(e.add(n.$fn),n.args)for(let o of n.args)S(o,e);return}if(g(n)){n.value!==void 0&&typeof n.value=="object"&&S(n.value,e);return}if(y(n)){for(let o of n.conditions)S(o,e);return}let t=n;for(let o of Object.keys(t))S(t[o],e);}function G(n){let e=new Set;for(let t of n){let o=t.indexOf("."),i=t.indexOf("["),s=t.length;o!==-1&&(s=Math.min(s,o)),i!==-1&&(s=Math.min(s,i));let r=t.slice(0,s);r&&e.add(r);}return e}function kn(n){return JSON.stringify(n)}function xn(n,e,t){let o=N(n,{noPrefixes:true}),i=generate(o),s=e.size>0?`const{${[...e].join(",")}}=data??{};`:"",r=t.size>0?`const{${[...t].join(",")}}=scope;`:"";return r?`(function(scope){${r}return function(data){${s}return ${i}}})`:`(function(){return function(data){${s}return ${i}}})`}function D(n,e={}){let{scope:t={},returnCode:o=false}=e,i=T(n),s=G(i),r=j(n),c=kn(n),f=xn(n,s,r);if(o)return {code:f,deps:i,hash:c,dataRoots:[...s],scopeFns:[...r]};let a;try{a=new Function(`return ${f}`)()(t);}catch(u){throw new Error(`AST compilation failed. If this is due to CSP, use the standard compile() function instead. Error: ${u instanceof Error?u.message:String(u)}`)}return {fn:a,deps:i,hash:c}}function Y(n,e,t={}){let{fn:o}=D(n,t);return o(e)}var ie="0.0.1";export{v as ExpressionCache,ie as VERSION,mn as assertValid,_ as cache,dn as cached,en as clearPathCache,O as compile,D as compileAST,x as compilePath,N as dslToAST,pn as evaluate,Y as evaluateAST,G as extractDataRoots,T as extractDeps,j as extractScopeFns,nn as get,tn as getPathCacheSize,rn as hasDeps,V as hasWildcard,g as isCondition,H as isConditionExpr,y as isConditionGroup,h as isConditional,E as isFn,W as isLiteral,C as isPipe,sn as isPure,m as isRef,gn as isValid,k as normalizePath,z as validate,K as wrapInFunction};
|
|
1
|
+
import {isRef,compile,validate}from'@statedelta-libs/conditions';import {builders,generate}from'omni-ast';var en=Object.defineProperty;var tn=(n,e)=>{for(var i in e)en(n,i,{get:e[i],enumerable:true});};var m=n=>n!==null&&typeof n=="object"&&"$"in n&&typeof n.$=="string"&&Object.keys(n).length===1,E=n=>n!==null&&typeof n=="object"&&"$if"in n&&"then"in n,T=n=>n!==null&&typeof n=="object"&&"$fn"in n&&typeof n.$fn=="string",C=n=>n!==null&&typeof n=="object"&&"$pipe"in n&&Array.isArray(n.$pipe),I=new Set(["eq","neq","gt","gte","lt","lte","in","notIn","contains","notContains","exists","notExists","matches","notMatches","startsWith","endsWith"]),g=n=>n!==null&&typeof n=="object"&&"path"in n&&"op"in n&&I.has(n.op)&&!("$"in n)&&!("$if"in n)&&!("$fn"in n),y=n=>n!==null&&typeof n=="object"&&"logic"in n&&"conditions"in n,on=n=>g(n)||y(n),P=n=>{if(n===null)return true;let e=typeof n;if(e==="string"||e==="number"||e==="boolean"||Array.isArray(n))return true;if(e==="object"&&n!==null){let i=n,t="path"in i&&"op"in i&&I.has(i.op);return !("$"in i)&&!("$if"in i)&&!("$fn"in i)&&!("$pipe"in i)&&!t&&!("logic"in i)}return false};var R=new Map;function V(n){let e=[],i=n.length,t=0,o="";for(;t<i;){let s=n[t];if(s===".")o&&(e.push({type:"key",value:o}),o=""),t++;else if(s==="["){o&&(e.push({type:"key",value:o}),o=""),t++;let r=t;for(;t<i&&n[t]!=="]";)t++;let f=n.slice(r,t);if(t++,f==="*")e.push({type:"wildcard",value:"*"});else {let u=parseInt(f,10);e.push({type:"index",value:isNaN(u)?f:u});}}else o+=s,t++;}return o&&e.push({type:"key",value:o}),e}function L(n){return n.includes("[*]")}function O(n){let e=R.get(n);return e||(e=L(n)?sn(n):rn(n),R.set(n,e),e)}function rn(n){if(!n.includes(".")&&!n.includes("["))return o=>o?.[n];let e=V(n),i=e.length;if(i===2){let[o,s]=e,r=o.value,f=s.value;return u=>u?.[r]?.[f]}if(i===3){let[o,s,r]=e,f=o.value,u=s.value,c=r.value;return a=>a?.[f]?.[u]?.[c]}let t=e.map(o=>o.value);return o=>{let s=o;for(let r=0;r<i&&s!=null;r++)s=s[t[r]];return s}}function sn(n){let e=V(n),i=[];for(let t=0;t<e.length;t++)e[t].type==="wildcard"&&i.push(t);return i.length===1?ln(e,i[0]):fn(e,i)}function ln(n,e){let i=n.slice(0,e).map(r=>r.value),t=n.slice(e+1).map(r=>r.value),o=i.length,s=t.length;if(s===0){if(o===1){let r=i[0];return f=>f?.[r]}return r=>{let f=r;for(let u=0;u<o&&f!=null;u++)f=f[i[u]];return f}}if(s===1){let r=t[0];if(o===1){let f=i[0];return u=>{let c=u?.[f];if(Array.isArray(c))return c.map(a=>a?.[r])}}return f=>{let u=f;for(let c=0;c<o&&u!=null;c++)u=u[i[c]];if(Array.isArray(u))return u.map(c=>c?.[r])}}return r=>{let f=r;for(let u=0;u<o&&f!=null;u++)f=f[i[u]];if(Array.isArray(f))return f.map(u=>{let c=u;for(let a=0;a<s&&c!=null;a++)c=c[t[a]];return c})}}function fn(n,e){let i=[],t=0;for(let s=0;s<e.length;s++){let r=e[s],f=s===e.length-1,u=n.slice(t,r).map(c=>c.value);u.length>0&&i.push({type:"access",keys:u}),i.push({type:f?"map":"flatMap",keys:[]}),t=r+1;}let o=n.slice(t).map(s=>s.value);return s=>{let r=s;for(let f of i){if(r==null)return;if(f.type==="access")for(let u of f.keys){if(r==null)return;r=r[u];}else if(f.type==="flatMap"){if(!Array.isArray(r))return;r=r.flatMap(u=>{let c=u;return Array.isArray(c)?c:[c]});}else if(f.type==="map"){if(!Array.isArray(r))return;o.length>0&&(r=r.map(u=>{let c=u;for(let a of o){if(c==null)return;c=c[a];}return c}));}}return r}}function un(n,e){return O(e)(n)}function k(n){let e=n.indexOf("[*]");return e===-1?n:n.slice(0,e)}function cn(){R.clear();}function an(){return R.size}function S(n){let e=new Set;return $(n,e),Array.from(e)}function $(n,e){if(n===null||typeof n!="object")return;if(Array.isArray(n)){for(let o=0;o<n.length;o++)$(n[o],e);return}if(m(n)){e.add(k(n.$));return}if(E(n)){if(typeof n.$if=="string"){let o=n.$if.startsWith("!")?n.$if.slice(1):n.$if;e.add(k(o));}else $(n.$if,e);$(n.then,e),n.else!==void 0&&$(n.else,e);return}if(C(n)){for(let o=0;o<n.$pipe.length;o++)$(n.$pipe[o],e);return}if(T(n)){if(n.args)for(let o=0;o<n.args.length;o++)$(n.args[o],e);return}if(g(n)){e.add(k(n.path)),n.value!==void 0&&isRef(n.value)&&e.add(k(n.value.$));return}if(y(n)){for(let o=0;o<n.conditions.length;o++)$(n.conditions[o],e);return}let i=n,t=Object.keys(i);for(let o=0;o<t.length;o++)$(i[t[o]],e);}function dn(n){return S(n).length>0}function mn(n){return S(n).length===0}function gn(n){return JSON.stringify(n)}function F(n,e={}){let i=e.scope??{},t=e.accessor,o=A(n,i,t),s=S(n),r=gn(n);return {fn:o,deps:s,hash:r}}function A(n,e,i){if(n===null)return ()=>null;if(typeof n!="object")return ()=>n;if(Array.isArray(n)){let t=n.map(o=>A(o,e,i));return o=>t.map(s=>s(o))}if(m(n))return yn(n,i);if(E(n))return hn(n,e,i);if(C(n))return En(n,e,i);if(T(n))return Tn(n,e,i);if(g(n))return compile(n,i?{accessor:i}:void 0);if(y(n))return compile(n,i?{accessor:i}:void 0);if(P(n)){let t=n,o=Object.keys(t),s=o.map(r=>A(t[r],e,i));return r=>{let f={};for(let u=0;u<o.length;u++)f[o[u]]=s[u](r);return f}}return ()=>n}function q(n,e){return e?i=>e(n,i):O(n)}function yn(n,e){return q(n.$,e)}function hn(n,e,i){let t;if(typeof n.$if=="string"){let r=n.$if.startsWith("!")?n.$if.slice(1):n.$if,f=q(r,i);t=n.$if.startsWith("!")?c=>!f(c):c=>!!f(c);}else {let r=A(n.$if,e,i);t=f=>!!r(f);}let o=A(n.then,e,i),s=n.else!==void 0?A(n.else,e,i):()=>{};return r=>t(r)?o(r):s(r)}function En(n,e,i){let t=n.$pipe;if(t.length===0)return ()=>{};if(t.length===1)return A(t[0],e,i);let o=A(t[0],e,i),s=t.slice(1).map(f=>A(f,e,i)),r=s.length;if(r===1){let[f]=s;return u=>{let c=o(u),a=f(u);return typeof a=="function"?a(c):a}}if(r===2){let[f,u]=s;return c=>{let a=o(c),p=f(c);return a=typeof p=="function"?p(a):p,p=u(c),typeof p=="function"?p(a):p}}if(r===3){let[f,u,c]=s;return a=>{let p=o(a),h=f(a);return p=typeof h=="function"?h(p):h,h=u(a),p=typeof h=="function"?h(p):h,h=c(a),typeof h=="function"?h(p):h}}return f=>{let u=o(f);for(let c=0;c<r;c++){let a=s[c](f);u=typeof a=="function"?a(u):a;}return u}}function Tn(n,e,i){let t=n.$fn,o=n.args;if(o===void 0)return ()=>{let f=e[t];if(!f)throw new Error(`Function not found in scope: ${t}`);return f};let s=o.map(f=>A(f,e,i)),r=s.length;if(r===0)return f=>{let u=e[t];if(!u)throw new Error(`Function not found in scope: ${t}`);return u()};if(r===1){let[f]=s;return u=>{let c=e[t];if(!c)throw new Error(`Function not found in scope: ${t}`);return c(f(u))}}if(r===2){let[f,u]=s;return c=>{let a=e[t];if(!a)throw new Error(`Function not found in scope: ${t}`);return a(f(c),u(c))}}if(r===3){let[f,u,c]=s;return a=>{let p=e[t];if(!p)throw new Error(`Function not found in scope: ${t}`);return p(f(a),u(a),c(a))}}return f=>{let u=e[t];if(!u)throw new Error(`Function not found in scope: ${t}`);return u(...s.map(c=>c(f)))}}function Cn(n,e,i={}){return F(n,i).fn(e)}var v=class{constructor(e=1e3){this.cache=new Map,this._maxSize=e;}get(e,i={}){let t=JSON.stringify(e),o=this.cache.get(t);if(o)return this.cache.delete(t),this.cache.set(t,o),o;let s=F(e,i);if(this.cache.size>=this._maxSize){let r=this.cache.keys().next().value;r&&this.cache.delete(r);}return this.cache.set(t,s),s}has(e){return this.cache.has(JSON.stringify(e))}delete(e){return this.cache.delete(JSON.stringify(e))}clear(){this.cache.clear();}get size(){return this.cache.size}get maxSize(){return this._maxSize}set maxSize(e){for(this._maxSize=e;this.cache.size>this._maxSize;){let i=this.cache.keys().next().value;i&&this.cache.delete(i);}}},J=new v;function An(n,e={}){return J.get(n,e)}function z(n,e="root",i={}){let t=[];return x(n,e,t,i),{valid:t.length===0,errors:t}}function x(n,e,i,t){if(n===null||typeof n!="object")return;if(Array.isArray(n)){for(let r=0;r<n.length;r++)x(n[r],`${e}[${r}]`,i,t);return}if(m(n)){(!n.$||typeof n.$!="string")&&i.push(`${e}: invalid reference, $ must be non-empty string`);return}if(E(n)){typeof n.$if=="string"?(n.$if.startsWith("!")?n.$if.slice(1):n.$if)||i.push(`${e}.$if: empty path in string shorthand`):x(n.$if,`${e}.$if`,i,t),x(n.then,`${e}.then`,i,t),n.else!==void 0&&x(n.else,`${e}.else`,i,t);return}if(C(n)){if(!Array.isArray(n.$pipe)){i.push(`${e}.$pipe: must be an array`);return}if(n.$pipe.length===0){i.push(`${e}.$pipe: must have at least one element`);return}for(let r=0;r<n.$pipe.length;r++)x(n.$pipe[r],`${e}.$pipe[${r}]`,i,t);return}if(T(n)){if(!n.$fn||typeof n.$fn!="string"){i.push(`${e}: invalid function, $fn must be non-empty string`);return}if(t.scope&&!(n.$fn in t.scope)&&i.push(`${e}: function "${n.$fn}" not found in scope`),n.args!==void 0)if(!Array.isArray(n.args))i.push(`${e}.args: must be an array`);else for(let r=0;r<n.args.length;r++)x(n.args[r],`${e}.args[${r}]`,i,t);return}if(g(n)){let r=validate(n,e);r.valid||i.push(...r.errors);return}if(y(n)){let r=validate(n,e);r.valid||i.push(...r.errors);return}let o=n,s=Object.keys(o);for(let r=0;r<s.length;r++){let f=s[r];x(o[f],`${e}.${f}`,i,t);}}function bn(n,e={}){let i=z(n,"root",e);if(!i.valid)throw new Error(`Invalid expression: ${i.errors.join("; ")}`)}function $n(n,e={}){return z(n,"root",e).valid}var Q={};tn(Q,{$:()=>K,$fn:()=>Y,$if:()=>kn,$pipe:()=>H,fn:()=>Sn,pipe:()=>wn,ref:()=>xn});function K(n){return {$:n}}var xn=K;function Y(n,e){return e===void 0||e.length===0?{$fn:n}:{$fn:n,args:e}}var Sn=Y;function kn(n,e,i){return i===void 0?{$if:n,then:e}:{$if:n,then:e,else:i}}function H(...n){return {$pipe:n}}var wn=H;var D="data",U="scope",Rn={eq:"===",neq:"!==",gt:">",gte:">=",lt:"<",lte:"<="};function j(n,e={}){let{dataParam:i=D,scopeParam:t=U,noPrefixes:o=false}=e;return d(n,i,t,o)}function d(n,e,i,t){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(o=>d(o,e,i,t)));if(m(n))return On(n.$,e,t);if(E(n))return vn(n,e,i,t);if(C(n))return jn(n.$pipe,e,i,t);if(T(n))return Nn(n,e,i,t);if(g(n))return Gn(n,e,i,t);if(y(n))return Wn(n,e,i,t);if(typeof n=="object"){let s=Object.entries(n).map(([r,f])=>builders.property(builders.identifier(r),d(f,e,i,t)));return builders.objectExpression(s)}return builders.literal(null)}function On(n,e,i){return n.includes("[*]")?Fn(n,e,i):w(n,e,i)}function w(n,e,i){let t=N(n);if(t.length===0)return i?builders.identifier("undefined"):builders.identifier(e);let o;if(i){let s=t[0];o=builders.identifier(s.value);for(let r=1;r<t.length;r++){let f=t[r];f.type==="key"?o=builders.memberExpression(o,builders.identifier(f.value),false,true):o=builders.memberExpression(o,builders.literal(f.value),true,true);}}else {o=builders.identifier(e);for(let s of t)s.type==="key"?o=builders.memberExpression(o,builders.identifier(s.value),false,true):o=builders.memberExpression(o,builders.literal(s.value),true,true);}return o}function Fn(n,e,i){let t=n.indexOf("[*]"),o=n.slice(0,t),s=n.slice(t+3),r;if(o?r=w(o,e,i):r=i?builders.identifier("undefined"):builders.identifier(e),!s||s==="")return r;if(s.includes("[*]"))return X(r,s);let f="_i",u=s.startsWith(".")?s.slice(1):s,c=builders.identifier(f);if(u){let a=N(u);for(let p of a)p.type==="key"?c=builders.memberExpression(c,builders.identifier(p.value),false,true):c=builders.memberExpression(c,builders.literal(p.value),true,true);}return builders.callExpression(builders.memberExpression(r,builders.identifier("map"),false,true),[builders.arrowFunctionExpression([builders.identifier(f)],c)])}function X(n,e){let i=e.indexOf("[*]"),t=e.slice(0,i),o=e.slice(i+3),s="_i",r=t.startsWith(".")?t.slice(1):t,f=builders.identifier(s);if(r){let c=N(r);for(let a of c)a.type==="key"&&(f=builders.memberExpression(f,builders.identifier(a.value),false,true));}if(o.includes("[*]")){let c=X(f,o);return builders.callExpression(builders.memberExpression(n,builders.identifier("flatMap"),false,true),[builders.arrowFunctionExpression([builders.identifier(s)],c)])}let u=o.startsWith(".")?o.slice(1):o;if(u){let c=N(u);for(let a of c)a.type==="key"&&(f=builders.memberExpression(f,builders.identifier(a.value),false,true));}return builders.callExpression(builders.memberExpression(n,builders.identifier("flatMap"),false,true),[builders.arrowFunctionExpression([builders.identifier(s)],f)])}function vn(n,e,i,t){let o;if(typeof n.$if=="string"){let f=n.$if.startsWith("!"),u=f?n.$if.slice(1):n.$if,c=w(u,e,t);o=f?builders.unaryExpression("!",c):c;}else o=d(n.$if,e,i,t);let s=d(n.then,e,i,t),r=n.else!==void 0?d(n.else,e,i,t):builders.identifier("undefined");return builders.conditionalExpression(o,s,r)}function Nn(n,e,i,t){let o=t?builders.identifier(n.$fn):builders.memberExpression(builders.identifier(i),builders.identifier(n.$fn),false,false);if(n.args===void 0)return o;let s=n.args.map(r=>d(r,e,i,t));return builders.callExpression(o,s)}function jn(n,e,i,t){if(n.length===0)return builders.identifier("undefined");if(n.length===1)return d(n[0],e,i,t);let o=d(n[0],e,i,t);for(let s=1;s<n.length;s++){let r=d(n[s],e,i,t);o=builders.callExpression(r,[o]);}return o}function Gn(n,e,i,t){let o=w(n.path,e,t),s=n.value!==void 0?m(n.value)?w(n.value.$,e,t):d(n.value,e,i,t):builders.literal(null),r=Rn[n.op];if(r)return builders.binaryExpression(r,o,s);switch(n.op){case "in":return builders.callExpression(builders.memberExpression(s,builders.identifier("includes")),[o]);case "notIn":return builders.unaryExpression("!",builders.callExpression(builders.memberExpression(s,builders.identifier("includes")),[o]));case "contains":return builders.callExpression(builders.memberExpression(o,builders.identifier("includes"),false,true),[s]);case "notContains":return builders.unaryExpression("!",builders.callExpression(builders.memberExpression(o,builders.identifier("includes"),false,true),[s]));case "exists":return builders.binaryExpression("!=",o,builders.literal(null));case "notExists":return builders.binaryExpression("==",o,builders.literal(null));case "matches":return builders.callExpression(builders.memberExpression(builders.newExpression(builders.identifier("RegExp"),[s]),builders.identifier("test")),[o]);case "notMatches":return builders.unaryExpression("!",builders.callExpression(builders.memberExpression(builders.newExpression(builders.identifier("RegExp"),[s]),builders.identifier("test")),[o]));case "startsWith":return builders.callExpression(builders.memberExpression(o,builders.identifier("startsWith"),false,true),[s]);case "endsWith":return builders.callExpression(builders.memberExpression(o,builders.identifier("endsWith"),false,true),[s]);default:return builders.binaryExpression("===",o,s)}}function Wn(n,e,i,t){let{logic:o,conditions:s}=n,r=o==="AND"?"&&":"||";if(s.length===0)return builders.literal(o==="AND");if(s.length===1)return d(s[0],e,i,t);let f=d(s[0],e,i,t);for(let u=1;u<s.length;u++){let c=d(s[u],e,i,t);f=builders.logicalExpression(r,f,c);}return f}function N(n){let e=[],i=n.length,t=0,o="";for(;t<i;){let s=n[t];if(s===".")o&&(e.push({type:"key",value:o}),o=""),t++;else if(s==="["){o&&(e.push({type:"key",value:o}),o=""),t++;let r=t;for(;t<i&&n[t]!=="]";)t++;let f=n.slice(r,t);if(t++,f!=="*"){let u=parseInt(f,10);e.push({type:"index",value:isNaN(u)?f:u});}}else o+=s,t++;}return o&&e.push({type:"key",value:o}),e}function Z(n,e=[D]){return builders.arrowFunctionExpression(e.map(i=>builders.identifier(i)),n)}function G(n){let e=new Set;return b(n,e),e}function b(n,e){if(n===null||typeof n!="object")return;if(Array.isArray(n)){for(let t of n)b(t,e);return}if(m(n))return;if(E(n)){b(n.$if,e),b(n.then,e),n.else!==void 0&&b(n.else,e);return}if(C(n)){for(let t of n.$pipe)b(t,e);return}if(T(n)){if(e.add(n.$fn),n.args)for(let t of n.args)b(t,e);return}if(g(n)){n.value!==void 0&&typeof n.value=="object"&&b(n.value,e);return}if(y(n)){for(let t of n.conditions)b(t,e);return}let i=n;for(let t of Object.keys(i))b(i[t],e);}function W(n){let e=new Set;for(let i of n){let t=i.indexOf("."),o=i.indexOf("["),s=i.length;t!==-1&&(s=Math.min(s,t)),o!==-1&&(s=Math.min(s,o));let r=i.slice(0,s);r&&e.add(r);}return e}function zn(n){return JSON.stringify(n)}function Dn(n,e,i){let t=j(n,{noPrefixes:true}),o=generate(t),s=e.size>0?`const{${[...e].join(",")}}=data??{};`:"",r=i.size>0?`const{${[...i].join(",")}}=scope;`:"";return r?`(function(scope){${r}return function(data){${s}return ${o}}})`:`(function(){return function(data){${s}return ${o}}})`}function M(n,e={}){let{scope:i={},returnCode:t=false}=e,o=S(n),s=W(o),r=G(n),f=zn(n),u=Dn(n,s,r);if(t)return {code:u,deps:o,hash:f,dataRoots:[...s],scopeFns:[...r]};let c;try{c=new Function(`return ${u}`)()(i);}catch(a){throw new Error(`AST compilation failed. If this is due to CSP, use the standard compile() function instead. Error: ${a instanceof Error?a.message:String(a)}`)}return {fn:c,deps:o,hash:f}}function nn(n,e,i={}){let{fn:t}=M(n,i);return t(e)}var ye="0.1.0";export{v as ExpressionCache,ye as VERSION,bn as assertValid,Q as builders,J as cache,An as cached,cn as clearPathCache,F as compile,M as compileAST,O as compilePath,j as dslToAST,Cn as evaluate,nn as evaluateAST,W as extractDataRoots,S as extractDeps,G as extractScopeFns,un as get,an as getPathCacheSize,dn as hasDeps,L as hasWildcard,g as isCondition,on as isConditionExpr,y as isConditionGroup,E as isConditional,T as isFn,P as isLiteral,C as isPipe,mn as isPure,m as isRef,$n as isValid,k as normalizePath,z as validate,Z as wrapInFunction};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@statedelta-libs/expressions",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"description": "JSON DSL compiler for optimized functions - StateDelta expression engine",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -13,9 +13,20 @@
|
|
|
13
13
|
"require": "./dist/index.cjs"
|
|
14
14
|
}
|
|
15
15
|
},
|
|
16
|
+
"scripts": {
|
|
17
|
+
"build": "tsup",
|
|
18
|
+
"dev": "tsup --watch",
|
|
19
|
+
"test": "vitest run",
|
|
20
|
+
"test:watch": "vitest",
|
|
21
|
+
"test:coverage": "vitest run --coverage",
|
|
22
|
+
"typecheck": "tsc --noEmit",
|
|
23
|
+
"clean": "rm -rf dist",
|
|
24
|
+
"format": "prettier --write \"src/**/*.ts\"",
|
|
25
|
+
"format:check": "prettier --check \"src/**/*.ts\""
|
|
26
|
+
},
|
|
16
27
|
"dependencies": {
|
|
17
|
-
"
|
|
18
|
-
"
|
|
28
|
+
"@statedelta-libs/conditions": "workspace:^",
|
|
29
|
+
"omni-ast": "^2.0.0"
|
|
19
30
|
},
|
|
20
31
|
"files": [
|
|
21
32
|
"dist",
|
|
@@ -44,15 +55,7 @@
|
|
|
44
55
|
"publishConfig": {
|
|
45
56
|
"access": "public"
|
|
46
57
|
},
|
|
47
|
-
"
|
|
48
|
-
"
|
|
49
|
-
"dev": "tsup --watch",
|
|
50
|
-
"test": "vitest run",
|
|
51
|
-
"test:watch": "vitest",
|
|
52
|
-
"test:coverage": "vitest run --coverage",
|
|
53
|
-
"typecheck": "tsc --noEmit",
|
|
54
|
-
"clean": "rm -rf dist",
|
|
55
|
-
"format": "prettier --write \"src/**/*.ts\"",
|
|
56
|
-
"format:check": "prettier --check \"src/**/*.ts\""
|
|
58
|
+
"devDependencies": {
|
|
59
|
+
"@vitest/coverage-v8": "^4.0.16"
|
|
57
60
|
}
|
|
58
|
-
}
|
|
61
|
+
}
|
package/LICENSE
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2025 Anderson D. Rosa
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|