@statedelta-libs/expressions 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +382 -0
- package/dist/index.cjs +1 -0
- package/dist/index.d.cts +511 -0
- package/dist/index.d.ts +511 -0
- package/dist/index.js +1 -0
- package/package.json +58 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,511 @@
|
|
|
1
|
+
import { ConditionExpr, Condition, ConditionGroup } from '@statedelta-libs/conditions';
|
|
2
|
+
export { Condition, ConditionExpr, ConditionGroup, Ref } from '@statedelta-libs/conditions';
|
|
3
|
+
import { types } from 'omni-ast';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @statedelta-libs/expressions - Types
|
|
7
|
+
*
|
|
8
|
+
* Core types for expression compilation.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Reference to a path in data object
|
|
13
|
+
* @example { "$": "user.name" }
|
|
14
|
+
* @example { "$": "items[*].price" }
|
|
15
|
+
*/
|
|
16
|
+
interface RefExpr {
|
|
17
|
+
$: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Conditional expression
|
|
21
|
+
* @example { "$if": condition, "then": expr, "else": expr }
|
|
22
|
+
*/
|
|
23
|
+
interface ConditionalExpr {
|
|
24
|
+
$if: Expression;
|
|
25
|
+
then: Expression;
|
|
26
|
+
else?: Expression;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Function call expression
|
|
30
|
+
* Calls a function from the provided scope with compiled arguments
|
|
31
|
+
* @example { "$fn": "add", "args": [{ "$": "a" }, { "$": "b" }] }
|
|
32
|
+
*/
|
|
33
|
+
interface FnExpr {
|
|
34
|
+
$fn: string;
|
|
35
|
+
args?: Expression[];
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Pipe expression (DSL syntax for composition with initial value)
|
|
39
|
+
* First element is the initial value, rest are transformers
|
|
40
|
+
* @example { "$pipe": [{ "$": "items" }, { "$fn": "filter", "args": [pred] }, { "$fn": "sum" }] }
|
|
41
|
+
*/
|
|
42
|
+
interface PipeExpr {
|
|
43
|
+
$pipe: Expression[];
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Literal values (primitives, arrays, plain objects)
|
|
47
|
+
*/
|
|
48
|
+
type Literal = string | number | boolean | null | Literal[] | {
|
|
49
|
+
[key: string]: Literal;
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Union of all expression types
|
|
53
|
+
*/
|
|
54
|
+
type Expression = Literal | RefExpr | ConditionalExpr | FnExpr | PipeExpr | ConditionExpr;
|
|
55
|
+
/**
|
|
56
|
+
* Compiled expression function
|
|
57
|
+
*/
|
|
58
|
+
type CompiledFn<T = unknown, R = unknown> = (data: T) => R;
|
|
59
|
+
/**
|
|
60
|
+
* Result of compiling an expression
|
|
61
|
+
*/
|
|
62
|
+
interface CompiledExpression<T = unknown, R = unknown> {
|
|
63
|
+
/** Compiled function */
|
|
64
|
+
fn: CompiledFn<T, R>;
|
|
65
|
+
/** Paths this expression depends on */
|
|
66
|
+
deps: string[];
|
|
67
|
+
/** Unique hash for caching */
|
|
68
|
+
hash: string;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Path getter function
|
|
72
|
+
*/
|
|
73
|
+
type PathGetter<T = unknown> = (data: T) => unknown;
|
|
74
|
+
/**
|
|
75
|
+
* Validation result
|
|
76
|
+
*/
|
|
77
|
+
interface ValidationResult {
|
|
78
|
+
valid: boolean;
|
|
79
|
+
errors: string[];
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Function scope - functions available to $fn expressions
|
|
83
|
+
* @example { add, subtract, multiply, filter, map, sum }
|
|
84
|
+
*/
|
|
85
|
+
type Scope = Record<string, (...args: unknown[]) => unknown>;
|
|
86
|
+
/**
|
|
87
|
+
* Options for compilation
|
|
88
|
+
*/
|
|
89
|
+
interface CompileOptions {
|
|
90
|
+
/** Functions available to $fn expressions */
|
|
91
|
+
scope?: Scope;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Check if value is a reference expression
|
|
95
|
+
*/
|
|
96
|
+
declare const isRef: (v: unknown) => v is RefExpr;
|
|
97
|
+
/**
|
|
98
|
+
* Check if value is a conditional expression
|
|
99
|
+
*/
|
|
100
|
+
declare const isConditional: (v: unknown) => v is ConditionalExpr;
|
|
101
|
+
/**
|
|
102
|
+
* Check if value is a function call expression
|
|
103
|
+
*/
|
|
104
|
+
declare const isFn: (v: unknown) => v is FnExpr;
|
|
105
|
+
/**
|
|
106
|
+
* Check if value is a pipe expression
|
|
107
|
+
*/
|
|
108
|
+
declare const isPipe: (v: unknown) => v is PipeExpr;
|
|
109
|
+
/**
|
|
110
|
+
* Check if value is a condition (from @statedelta-libs/conditions)
|
|
111
|
+
*
|
|
112
|
+
* IMPORTANT: Must verify that `op` is a valid condition operator,
|
|
113
|
+
* not just any string. Effect objects also have `path` and `op`
|
|
114
|
+
* properties (e.g., { resource: "x", op: "set", path: "y", value: z })
|
|
115
|
+
* but "set" is NOT a condition operator.
|
|
116
|
+
*/
|
|
117
|
+
declare const isCondition: (v: unknown) => v is Condition;
|
|
118
|
+
/**
|
|
119
|
+
* Check if value is a condition group (from @statedelta-libs/conditions)
|
|
120
|
+
*/
|
|
121
|
+
declare const isConditionGroup: (v: unknown) => v is ConditionGroup;
|
|
122
|
+
/**
|
|
123
|
+
* Check if value is any condition expression
|
|
124
|
+
*/
|
|
125
|
+
declare const isConditionExpr: (v: unknown) => v is ConditionExpr;
|
|
126
|
+
/**
|
|
127
|
+
* Check if value is a literal (not an expression object)
|
|
128
|
+
*/
|
|
129
|
+
declare const isLiteral: (v: unknown) => v is Literal;
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* @statedelta-libs/expressions - Compiler
|
|
133
|
+
*
|
|
134
|
+
* Compiles JSON DSL expressions to optimized functions.
|
|
135
|
+
* Functions are provided via scope, not hardcoded.
|
|
136
|
+
*/
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Compile expression to optimized function
|
|
140
|
+
*
|
|
141
|
+
* @param expr - Expression to compile
|
|
142
|
+
* @param options - Compile options (scope with functions)
|
|
143
|
+
* @returns Compiled expression with fn, deps, and hash
|
|
144
|
+
*
|
|
145
|
+
* @example
|
|
146
|
+
* ```ts
|
|
147
|
+
* import { add, filter, sum } from '@statedelta-libs/operators';
|
|
148
|
+
*
|
|
149
|
+
* const { fn } = compile(
|
|
150
|
+
* { $fn: "add", args: [{ $: "a" }, { $: "b" }] },
|
|
151
|
+
* { scope: { add, filter, sum } }
|
|
152
|
+
* );
|
|
153
|
+
*
|
|
154
|
+
* fn({ a: 1, b: 2 }); // 3
|
|
155
|
+
* ```
|
|
156
|
+
*/
|
|
157
|
+
declare function compile<T = unknown, R = unknown>(expr: Expression, options?: CompileOptions): CompiledExpression<T, R>;
|
|
158
|
+
/**
|
|
159
|
+
* Compile and execute in one step
|
|
160
|
+
*
|
|
161
|
+
* @example
|
|
162
|
+
* ```ts
|
|
163
|
+
* evaluate(
|
|
164
|
+
* { $fn: "add", args: [{ $: "a" }, { $: "b" }] },
|
|
165
|
+
* { a: 1, b: 2 },
|
|
166
|
+
* { scope: { add } }
|
|
167
|
+
* ); // 3
|
|
168
|
+
* ```
|
|
169
|
+
*/
|
|
170
|
+
declare function evaluate<T = unknown, R = unknown>(expr: Expression, data: T, options?: CompileOptions): R;
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* @statedelta-libs/expressions - Path Compiler
|
|
174
|
+
*
|
|
175
|
+
* Compiles paths to optimized getters with wildcard support.
|
|
176
|
+
* Performance: ~50M ops/sec for simple paths, ~10M ops/sec for wildcards
|
|
177
|
+
*/
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Check if path has wildcards
|
|
181
|
+
*/
|
|
182
|
+
declare function hasWildcard(path: string): boolean;
|
|
183
|
+
/**
|
|
184
|
+
* Compile path to optimized getter
|
|
185
|
+
*/
|
|
186
|
+
declare function compilePath<T = unknown>(path: string): PathGetter<T>;
|
|
187
|
+
/**
|
|
188
|
+
* Get value at path directly (without caching)
|
|
189
|
+
*/
|
|
190
|
+
declare function get<T = unknown>(data: T, path: string): unknown;
|
|
191
|
+
/**
|
|
192
|
+
* Normalize path for dependency tracking (remove wildcards)
|
|
193
|
+
* @example "items[*].price" → "items"
|
|
194
|
+
* @example "users[*].posts[*].title" → "users"
|
|
195
|
+
*/
|
|
196
|
+
declare function normalizePath(path: string): string;
|
|
197
|
+
/**
|
|
198
|
+
* Clear path cache
|
|
199
|
+
*/
|
|
200
|
+
declare function clearPathCache(): void;
|
|
201
|
+
/**
|
|
202
|
+
* Get cache size
|
|
203
|
+
*/
|
|
204
|
+
declare function getPathCacheSize(): number;
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* @statedelta-libs/expressions - Dependency Extraction
|
|
208
|
+
*
|
|
209
|
+
* Extracts paths that an expression depends on.
|
|
210
|
+
* Performance: ~200K ops/sec
|
|
211
|
+
*/
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Extract all paths an expression depends on
|
|
215
|
+
* @example { "$": "user.age" } → ["user.age"]
|
|
216
|
+
* @example { "$if": "$isVip", "then": { "$": "price.vip" } } → ["$isVip", "price.vip"]
|
|
217
|
+
*/
|
|
218
|
+
declare function extractDeps(expr: Expression): string[];
|
|
219
|
+
/**
|
|
220
|
+
* Check if expression has dependencies
|
|
221
|
+
*/
|
|
222
|
+
declare function hasDeps(expr: Expression): boolean;
|
|
223
|
+
/**
|
|
224
|
+
* Check if expression is pure (no dependencies)
|
|
225
|
+
*/
|
|
226
|
+
declare function isPure(expr: Expression): boolean;
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* @statedelta-libs/expressions - Cache
|
|
230
|
+
*
|
|
231
|
+
* LRU cache for compiled expressions.
|
|
232
|
+
* Performance: cache hit ~10M ops/sec
|
|
233
|
+
*/
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* LRU Cache for compiled expressions
|
|
237
|
+
*/
|
|
238
|
+
declare class ExpressionCache {
|
|
239
|
+
private cache;
|
|
240
|
+
private _maxSize;
|
|
241
|
+
constructor(maxSize?: number);
|
|
242
|
+
/**
|
|
243
|
+
* Get or compile expression
|
|
244
|
+
*
|
|
245
|
+
* Note: The cache key is based on the expression only, not the scope.
|
|
246
|
+
* If you use different scopes for the same expression, consider using
|
|
247
|
+
* separate cache instances or not caching at all.
|
|
248
|
+
*/
|
|
249
|
+
get<T = unknown, R = unknown>(expr: Expression, options?: CompileOptions): CompiledExpression<T, R>;
|
|
250
|
+
/**
|
|
251
|
+
* Check if expression is cached
|
|
252
|
+
*/
|
|
253
|
+
has(expr: Expression): boolean;
|
|
254
|
+
/**
|
|
255
|
+
* Delete specific expression from cache
|
|
256
|
+
*/
|
|
257
|
+
delete(expr: Expression): boolean;
|
|
258
|
+
/**
|
|
259
|
+
* Clear the cache
|
|
260
|
+
*/
|
|
261
|
+
clear(): void;
|
|
262
|
+
/**
|
|
263
|
+
* Current cache size
|
|
264
|
+
*/
|
|
265
|
+
get size(): number;
|
|
266
|
+
/**
|
|
267
|
+
* Maximum cache size
|
|
268
|
+
*/
|
|
269
|
+
get maxSize(): number;
|
|
270
|
+
/**
|
|
271
|
+
* Set maximum cache size
|
|
272
|
+
*/
|
|
273
|
+
set maxSize(value: number);
|
|
274
|
+
}
|
|
275
|
+
declare const cache: ExpressionCache;
|
|
276
|
+
/**
|
|
277
|
+
* Compile and cache expression (convenience function)
|
|
278
|
+
*
|
|
279
|
+
* Note: Uses global cache. For custom scope management,
|
|
280
|
+
* use a dedicated ExpressionCache instance.
|
|
281
|
+
*/
|
|
282
|
+
declare function cached<T = unknown, R = unknown>(expr: Expression, options?: CompileOptions): CompiledExpression<T, R>;
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* @statedelta-libs/expressions - Validation
|
|
286
|
+
*
|
|
287
|
+
* Validates expression structure before compilation.
|
|
288
|
+
*/
|
|
289
|
+
|
|
290
|
+
/**
|
|
291
|
+
* Validation options
|
|
292
|
+
*/
|
|
293
|
+
interface ValidateOptions {
|
|
294
|
+
/** Scope to validate function names against (optional) */
|
|
295
|
+
scope?: Scope;
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Validate expression structure
|
|
299
|
+
*
|
|
300
|
+
* @param expr - Expression to validate
|
|
301
|
+
* @param path - Current path in expression tree (for error messages)
|
|
302
|
+
* @param options - Validation options
|
|
303
|
+
*/
|
|
304
|
+
declare function validate(expr: Expression, path?: string, options?: ValidateOptions): ValidationResult;
|
|
305
|
+
/**
|
|
306
|
+
* Validate and throw if invalid
|
|
307
|
+
*/
|
|
308
|
+
declare function assertValid(expr: Expression, options?: ValidateOptions): void;
|
|
309
|
+
/**
|
|
310
|
+
* Check if expression is valid
|
|
311
|
+
*/
|
|
312
|
+
declare function isValid(expr: Expression, options?: ValidateOptions): boolean;
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* @statedelta-libs/expressions - DSL to AST Transformer
|
|
316
|
+
*
|
|
317
|
+
* Transforms JSON DSL expressions to ESTree AST nodes using omni-ast builders.
|
|
318
|
+
* Supports two modes:
|
|
319
|
+
* - With prefixes (default): generates `data?.user?.name`, `scope.add()`
|
|
320
|
+
* - Without prefixes: generates `user?.name`, `add()` (for use with destructuring)
|
|
321
|
+
*/
|
|
322
|
+
|
|
323
|
+
type ASTNode = types.Expression;
|
|
324
|
+
/** Options for DSL to AST transformation */
|
|
325
|
+
interface TransformOptions {
|
|
326
|
+
/**
|
|
327
|
+
* Name of data parameter (default: "data")
|
|
328
|
+
* When noPrefixes=true, this is ignored for property access
|
|
329
|
+
*/
|
|
330
|
+
dataParam?: string;
|
|
331
|
+
/**
|
|
332
|
+
* Name of scope parameter (default: "scope")
|
|
333
|
+
* When noPrefixes=true, this is ignored for function calls
|
|
334
|
+
*/
|
|
335
|
+
scopeParam?: string;
|
|
336
|
+
/**
|
|
337
|
+
* When true, generates code without data/scope prefixes.
|
|
338
|
+
* Assumes variables are available via destructuring.
|
|
339
|
+
* - `user?.name` instead of `data?.user?.name`
|
|
340
|
+
* - `add(a, b)` instead of `scope.add(data?.a, data?.b)`
|
|
341
|
+
*/
|
|
342
|
+
noPrefixes?: boolean;
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* Transform DSL expression to AST node
|
|
346
|
+
*
|
|
347
|
+
* @param expr - DSL expression
|
|
348
|
+
* @param options - Transform options
|
|
349
|
+
* @returns ESTree AST node
|
|
350
|
+
*
|
|
351
|
+
* @example
|
|
352
|
+
* ```ts
|
|
353
|
+
* // With prefixes (default)
|
|
354
|
+
* dslToAST({ $: "user.name" })
|
|
355
|
+
* // → data?.user?.name
|
|
356
|
+
*
|
|
357
|
+
* // Without prefixes (for destructuring)
|
|
358
|
+
* dslToAST({ $: "user.name" }, { noPrefixes: true })
|
|
359
|
+
* // → user?.name
|
|
360
|
+
* ```
|
|
361
|
+
*/
|
|
362
|
+
declare function dslToAST(expr: Expression, options?: TransformOptions): ASTNode;
|
|
363
|
+
/**
|
|
364
|
+
* Wrap AST expression in an arrow function
|
|
365
|
+
*/
|
|
366
|
+
declare function wrapInFunction(bodyAst: ASTNode, params?: string[]): ASTNode;
|
|
367
|
+
|
|
368
|
+
/**
|
|
369
|
+
* @statedelta-libs/expressions - Extract Scope Functions
|
|
370
|
+
*
|
|
371
|
+
* Extracts function names used from scope in a DSL expression.
|
|
372
|
+
* Used to generate optimized destructuring: const { add, filter } = scope;
|
|
373
|
+
*/
|
|
374
|
+
|
|
375
|
+
/**
|
|
376
|
+
* Extract all function names used from scope in an expression
|
|
377
|
+
*
|
|
378
|
+
* @param expr - DSL expression to analyze
|
|
379
|
+
* @returns Set of function names used
|
|
380
|
+
*
|
|
381
|
+
* @example
|
|
382
|
+
* ```ts
|
|
383
|
+
* extractScopeFns({ $fn: "add", args: [{ $: "a" }, { $: "b" }] })
|
|
384
|
+
* // Set { "add" }
|
|
385
|
+
*
|
|
386
|
+
* extractScopeFns({
|
|
387
|
+
* $pipe: [
|
|
388
|
+
* { $: "items" },
|
|
389
|
+
* { $fn: "filter", args: [pred] },
|
|
390
|
+
* { $fn: "sum" }
|
|
391
|
+
* ]
|
|
392
|
+
* })
|
|
393
|
+
* // Set { "filter", "sum" }
|
|
394
|
+
* ```
|
|
395
|
+
*/
|
|
396
|
+
declare function extractScopeFns(expr: Expression): Set<string>;
|
|
397
|
+
/**
|
|
398
|
+
* Extract root-level data dependencies from paths
|
|
399
|
+
*
|
|
400
|
+
* @param deps - Array of dependency paths
|
|
401
|
+
* @returns Set of root-level property names
|
|
402
|
+
*
|
|
403
|
+
* @example
|
|
404
|
+
* ```ts
|
|
405
|
+
* extractDataRoots(["user.name", "user.age", "items", "config.theme"])
|
|
406
|
+
* // Set { "user", "items", "config" }
|
|
407
|
+
* ```
|
|
408
|
+
*/
|
|
409
|
+
declare function extractDataRoots(deps: string[]): Set<string>;
|
|
410
|
+
|
|
411
|
+
/**
|
|
412
|
+
* @statedelta-libs/expressions - AST Compiler
|
|
413
|
+
*
|
|
414
|
+
* Compiles DSL expressions to optimized functions using AST generation.
|
|
415
|
+
* Uses destructuring for better performance:
|
|
416
|
+
* - Variables from data are destructured into local scope
|
|
417
|
+
* - Functions from scope are destructured into local scope
|
|
418
|
+
* - Generated code is smaller and faster
|
|
419
|
+
*/
|
|
420
|
+
|
|
421
|
+
/** Options for AST compilation */
|
|
422
|
+
interface CompileASTOptions {
|
|
423
|
+
/** Scope with functions available to the expression */
|
|
424
|
+
scope?: Scope;
|
|
425
|
+
/** Return generated code instead of function (for debugging) */
|
|
426
|
+
returnCode?: boolean;
|
|
427
|
+
}
|
|
428
|
+
/** Result when returnCode is true */
|
|
429
|
+
interface CompileASTCodeResult {
|
|
430
|
+
code: string;
|
|
431
|
+
deps: string[];
|
|
432
|
+
hash: string;
|
|
433
|
+
dataRoots: string[];
|
|
434
|
+
scopeFns: string[];
|
|
435
|
+
}
|
|
436
|
+
/**
|
|
437
|
+
* Compile DSL expression to optimized function using AST generation
|
|
438
|
+
*
|
|
439
|
+
* This is the high-performance compiler that:
|
|
440
|
+
* 1. Extracts dependencies and scope functions
|
|
441
|
+
* 2. Generates AST without prefixes
|
|
442
|
+
* 3. Wraps in destructuring for optimal variable access
|
|
443
|
+
* 4. Creates function via `new Function()` or `eval()`
|
|
444
|
+
*
|
|
445
|
+
* @example
|
|
446
|
+
* ```ts
|
|
447
|
+
* import { compileAST } from '@statedelta-libs/expressions';
|
|
448
|
+
* import { add, filter, sum } from '@statedelta-libs/operators';
|
|
449
|
+
*
|
|
450
|
+
* const { fn } = compileAST(
|
|
451
|
+
* { $fn: "add", args: [{ $: "a" }, { $: "b" }] },
|
|
452
|
+
* { scope: { add, filter, sum } }
|
|
453
|
+
* );
|
|
454
|
+
*
|
|
455
|
+
* fn({ a: 1, b: 2 }); // 3
|
|
456
|
+
* ```
|
|
457
|
+
*/
|
|
458
|
+
declare function compileAST<T = unknown, R = unknown>(expr: Expression, options: CompileASTOptions & {
|
|
459
|
+
returnCode: true;
|
|
460
|
+
}): CompileASTCodeResult;
|
|
461
|
+
declare function compileAST<T = unknown, R = unknown>(expr: Expression, options?: CompileASTOptions): CompiledExpression<T, R>;
|
|
462
|
+
/**
|
|
463
|
+
* Compile and execute in one step
|
|
464
|
+
*
|
|
465
|
+
* @example
|
|
466
|
+
* ```ts
|
|
467
|
+
* evaluateAST(
|
|
468
|
+
* { $fn: "add", args: [{ $: "a" }, { $: "b" }] },
|
|
469
|
+
* { a: 1, b: 2 },
|
|
470
|
+
* { scope: { add } }
|
|
471
|
+
* ); // 3
|
|
472
|
+
* ```
|
|
473
|
+
*/
|
|
474
|
+
declare function evaluateAST<T = unknown, R = unknown>(expr: Expression, data: T, options?: CompileASTOptions): R;
|
|
475
|
+
|
|
476
|
+
/**
|
|
477
|
+
* @statedelta-libs/expressions
|
|
478
|
+
*
|
|
479
|
+
* JSON DSL compiler for optimized functions.
|
|
480
|
+
* Functions are provided via scope, not hardcoded.
|
|
481
|
+
*
|
|
482
|
+
* @example
|
|
483
|
+
* ```ts
|
|
484
|
+
* import { compile, evaluate } from '@statedelta-libs/expressions';
|
|
485
|
+
* import { filter, map, sum } from '@statedelta-libs/operators';
|
|
486
|
+
*
|
|
487
|
+
* const scope = { filter, map, sum };
|
|
488
|
+
*
|
|
489
|
+
* // Using $pipe for composition with initial value
|
|
490
|
+
* const { fn } = compile({
|
|
491
|
+
* $pipe: [
|
|
492
|
+
* { $: "items" },
|
|
493
|
+
* { $fn: "filter", args: [{ path: "active", op: "eq", value: true }] },
|
|
494
|
+
* { $fn: "map", args: [{ $: "price" }] },
|
|
495
|
+
* { $fn: "sum" }
|
|
496
|
+
* ]
|
|
497
|
+
* }, { scope });
|
|
498
|
+
*
|
|
499
|
+
* fn({ items: [...] }); // sum of active item prices
|
|
500
|
+
*
|
|
501
|
+
* // Using $fn for simple function calls
|
|
502
|
+
* evaluate(
|
|
503
|
+
* { $fn: "add", args: [{ $: "a" }, { $: "b" }] },
|
|
504
|
+
* { a: 1, b: 2 },
|
|
505
|
+
* { scope: { add: (a, b) => a + b } }
|
|
506
|
+
* ); // 3
|
|
507
|
+
* ```
|
|
508
|
+
*/
|
|
509
|
+
declare const VERSION = "0.0.1";
|
|
510
|
+
|
|
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 };
|
package/dist/index.js
ADDED
|
@@ -0,0 +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};
|
package/package.json
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@statedelta-libs/expressions",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "JSON DSL compiler for optimized functions - StateDelta expression engine",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.cjs",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js",
|
|
13
|
+
"require": "./dist/index.cjs"
|
|
14
|
+
}
|
|
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
|
+
},
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"@statedelta-libs/conditions": "workspace:*",
|
|
29
|
+
"omni-ast": "^2.0.0"
|
|
30
|
+
},
|
|
31
|
+
"files": [
|
|
32
|
+
"dist",
|
|
33
|
+
"README.md"
|
|
34
|
+
],
|
|
35
|
+
"sideEffects": false,
|
|
36
|
+
"engines": {
|
|
37
|
+
"node": ">=18"
|
|
38
|
+
},
|
|
39
|
+
"repository": {
|
|
40
|
+
"type": "git",
|
|
41
|
+
"url": "https://github.com/andersondrosa/statedelta.git",
|
|
42
|
+
"directory": "engine/expressions"
|
|
43
|
+
},
|
|
44
|
+
"keywords": [
|
|
45
|
+
"statedelta",
|
|
46
|
+
"expressions",
|
|
47
|
+
"dsl",
|
|
48
|
+
"compiler",
|
|
49
|
+
"json",
|
|
50
|
+
"functional",
|
|
51
|
+
"typescript"
|
|
52
|
+
],
|
|
53
|
+
"author": "Anderson D. Rosa <andersondrosa@outlook.com>",
|
|
54
|
+
"license": "MIT",
|
|
55
|
+
"publishConfig": {
|
|
56
|
+
"access": "public"
|
|
57
|
+
}
|
|
58
|
+
}
|