@statedelta-libs/expressions 2.3.0 → 3.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 +140 -781
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +241 -667
- package/dist/index.d.ts +241 -667
- package/dist/index.js +1 -1
- package/package.json +2 -2
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { types } from 'omni-ast';
|
|
2
|
-
|
|
3
1
|
/**
|
|
4
2
|
* @statedelta-libs/expressions - Types
|
|
5
3
|
*
|
|
@@ -45,15 +43,16 @@ interface PipeExpr {
|
|
|
45
43
|
$pipe: Expression[];
|
|
46
44
|
}
|
|
47
45
|
/**
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
* @example { $
|
|
46
|
+
* Arrow expression — closure deferida
|
|
47
|
+
* Cria uma função sem executar. Pode receber args posicionais nomeados.
|
|
48
|
+
*
|
|
49
|
+
* @example { "$arrow": { "$fn": "query" } } // () => query()
|
|
50
|
+
* @example { "$arrow": { "$": "item.price" }, "args": ["item"] } // (item) => item.price
|
|
52
51
|
*/
|
|
53
|
-
interface
|
|
54
|
-
$
|
|
55
|
-
|
|
56
|
-
|
|
52
|
+
interface ArrowExpr {
|
|
53
|
+
$arrow: Expression;
|
|
54
|
+
args?: string[];
|
|
55
|
+
schema?: Record<string, unknown>;
|
|
57
56
|
}
|
|
58
57
|
/**
|
|
59
58
|
* Literal values (primitives, arrays, plain objects)
|
|
@@ -86,7 +85,7 @@ type ConditionExpr = Condition | ConditionGroup;
|
|
|
86
85
|
/**
|
|
87
86
|
* Union of all expression types
|
|
88
87
|
*/
|
|
89
|
-
type Expression = Literal | RefExpr | ConditionalExpr | FnExpr | PipeExpr |
|
|
88
|
+
type Expression = Literal | RefExpr | ConditionalExpr | FnExpr | PipeExpr | ArrowExpr | ConditionExpr;
|
|
90
89
|
/**
|
|
91
90
|
* Compiled expression function
|
|
92
91
|
*/
|
|
@@ -107,14 +106,13 @@ interface CompiledExpression<T = unknown, R = unknown> {
|
|
|
107
106
|
*/
|
|
108
107
|
type PathGetter<T = unknown> = (data: T) => unknown;
|
|
109
108
|
/**
|
|
110
|
-
* Accessor customizado para resolver paths
|
|
111
|
-
*
|
|
109
|
+
* Accessor customizado para resolver paths.
|
|
110
|
+
* Closure auto-suficiente — já sabe de onde ler.
|
|
112
111
|
*
|
|
113
112
|
* @example
|
|
114
|
-
*
|
|
115
|
-
* const accessor: AccessorFn<TickContext> = (path, ctx) => ctx.get(path);
|
|
113
|
+
* const accessor: AccessorFn = (path) => tickContext.get(path);
|
|
116
114
|
*/
|
|
117
|
-
type AccessorFn
|
|
115
|
+
type AccessorFn = (path: string) => unknown;
|
|
118
116
|
/**
|
|
119
117
|
* Validation result
|
|
120
118
|
*/
|
|
@@ -133,74 +131,6 @@ interface ValidationResult {
|
|
|
133
131
|
* @example { add, subtract, multiply, filter, map, sum }
|
|
134
132
|
*/
|
|
135
133
|
type Scope = Record<string, (...args: any[]) => any>;
|
|
136
|
-
/**
|
|
137
|
-
* Path getter function - accessor de paths.
|
|
138
|
-
*/
|
|
139
|
-
type PathGetterFn = (path: string) => unknown;
|
|
140
|
-
/**
|
|
141
|
-
* Runtime context - contexto unificado passado para ContextFn.
|
|
142
|
-
* Agrupa dados e utilitários da lib em um único objeto imutável.
|
|
143
|
-
*
|
|
144
|
-
* @example
|
|
145
|
-
* ```ts
|
|
146
|
-
* // No ContextFn
|
|
147
|
-
* const tryCatch: ContextFn = (cb, ctx, params) => {
|
|
148
|
-
* console.log(ctx.data); // dados do usuário
|
|
149
|
-
* console.log(ctx.get("path")); // accessor
|
|
150
|
-
* };
|
|
151
|
-
* ```
|
|
152
|
-
*/
|
|
153
|
-
interface RuntimeCtx<T = unknown> {
|
|
154
|
-
/** Dados do runtime (passados pelo usuário) */
|
|
155
|
-
data: T;
|
|
156
|
-
/** Accessor de paths - resolve { $: "path" } */
|
|
157
|
-
get: PathGetterFn;
|
|
158
|
-
}
|
|
159
|
-
/**
|
|
160
|
-
* Context function - HOC que controla execução do body.
|
|
161
|
-
* Recebe o body como callback e decide quando/se executá-lo.
|
|
162
|
-
*
|
|
163
|
-
* @param cb - Body compilado (recebe ctx)
|
|
164
|
-
* @param ctx - Contexto de runtime (data + get)
|
|
165
|
-
* @param params - Parâmetros específicos deste $cb (opcional)
|
|
166
|
-
*
|
|
167
|
-
* @example
|
|
168
|
-
* ```ts
|
|
169
|
-
* const tryCatch: ContextFn = (cb, ctx, params) => {
|
|
170
|
-
* try {
|
|
171
|
-
* return cb(ctx);
|
|
172
|
-
* } catch (e) {
|
|
173
|
-
* return params?.fallback ?? null;
|
|
174
|
-
* }
|
|
175
|
-
* };
|
|
176
|
-
*
|
|
177
|
-
* const transaction: ContextFn = (cb, ctx, params) => {
|
|
178
|
-
* const tx = db.beginTransaction(params);
|
|
179
|
-
* try {
|
|
180
|
-
* // Pode criar novo ctx com dados extras
|
|
181
|
-
* const result = cb({ ...ctx, data: { ...ctx.data, tx } });
|
|
182
|
-
* tx.commit();
|
|
183
|
-
* return result;
|
|
184
|
-
* } catch (e) {
|
|
185
|
-
* tx.rollback();
|
|
186
|
-
* throw e;
|
|
187
|
-
* }
|
|
188
|
-
* };
|
|
189
|
-
*
|
|
190
|
-
* // Context pode injetar accessor customizado
|
|
191
|
-
* const simulate: ContextFn = (cb, ctx, params) => {
|
|
192
|
-
* const simulatedGet = (path) => store.getSimulated(path);
|
|
193
|
-
* return cb({ ...ctx, get: simulatedGet });
|
|
194
|
-
* };
|
|
195
|
-
* ```
|
|
196
|
-
*/
|
|
197
|
-
type ContextFn<T = any, R = any> = (cb: (ctx: RuntimeCtx<T>) => R, ctx: RuntimeCtx<T>, params?: unknown) => R;
|
|
198
|
-
/**
|
|
199
|
-
* Context registry - HOC functions available to $cb expressions.
|
|
200
|
-
*
|
|
201
|
-
* @example { tryCatch, transaction, simulate }
|
|
202
|
-
*/
|
|
203
|
-
type Context = Record<string, ContextFn>;
|
|
204
134
|
/**
|
|
205
135
|
* Options for compilation
|
|
206
136
|
*/
|
|
@@ -212,267 +142,186 @@ interface CompileOptions<T = unknown> {
|
|
|
212
142
|
* Quando fornecido, substitui o acesso direto por propriedade.
|
|
213
143
|
*
|
|
214
144
|
* @example
|
|
215
|
-
*
|
|
216
|
-
* compile(expr, { accessor: (path, ctx) => ctx.get(path) })
|
|
217
|
-
*/
|
|
218
|
-
accessor?: AccessorFn<T>;
|
|
219
|
-
/**
|
|
220
|
-
* Context functions available to $cb expressions.
|
|
221
|
-
* HOC functions that control body execution (tryCatch, transaction, etc.).
|
|
222
|
-
*
|
|
223
|
-
* @example
|
|
224
|
-
* compile(expr, {
|
|
225
|
-
* context: {
|
|
226
|
-
* tryCatch: (cb, data, get) => { try { return cb(data, get); } catch { return null; } }
|
|
227
|
-
* }
|
|
228
|
-
* })
|
|
145
|
+
* compile(expr, { accessor: (path) => ctx.get(path) })
|
|
229
146
|
*/
|
|
230
|
-
|
|
147
|
+
accessor?: AccessorFn;
|
|
148
|
+
/** Boundary definitions for compile-time interception */
|
|
149
|
+
boundaries?: BoundaryDef<T>[];
|
|
150
|
+
/** Wrapped handlers (ctx already bound) for $fn "namespace:method" calls */
|
|
151
|
+
handlers?: WrappedHandlers;
|
|
231
152
|
}
|
|
232
153
|
/**
|
|
233
|
-
*
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
/**
|
|
237
|
-
* Check if value is a conditional expression
|
|
238
|
-
*/
|
|
239
|
-
declare const isConditional: (v: unknown) => v is ConditionalExpr;
|
|
240
|
-
/**
|
|
241
|
-
* Check if value is a function call expression
|
|
242
|
-
*/
|
|
243
|
-
declare const isFn: (v: unknown) => v is FnExpr;
|
|
244
|
-
/**
|
|
245
|
-
* Check if value is a pipe expression
|
|
246
|
-
*/
|
|
247
|
-
declare const isPipe: (v: unknown) => v is PipeExpr;
|
|
248
|
-
/**
|
|
249
|
-
* Check if value is a callback expression
|
|
250
|
-
*/
|
|
251
|
-
declare const isCb: (v: unknown) => v is CbExpr;
|
|
252
|
-
/**
|
|
253
|
-
* Check if value is a condition expression
|
|
154
|
+
* Handler function — receives HandlerContext via `this` (bound at compile time).
|
|
155
|
+
* Must be a regular function or method shorthand (NOT arrow function).
|
|
156
|
+
* HandlerContext is defined in compiler.ts.
|
|
254
157
|
*
|
|
255
|
-
*
|
|
256
|
-
*
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
*
|
|
158
|
+
* @example
|
|
159
|
+
* {
|
|
160
|
+
* query: {
|
|
161
|
+
* find(key: string) { return this.scope.add(key, 1); }
|
|
162
|
+
* }
|
|
163
|
+
* }
|
|
261
164
|
*/
|
|
262
|
-
|
|
165
|
+
type HandlerFn = (...args: any[]) => any;
|
|
263
166
|
/**
|
|
264
|
-
*
|
|
167
|
+
* Handlers map — namespaces of handler methods.
|
|
168
|
+
* Provided by consumer in ExpressionCompiler constructor.
|
|
169
|
+
* Handlers access context via `this` (bound automatically via .bind()).
|
|
170
|
+
*
|
|
171
|
+
* @example
|
|
172
|
+
* {
|
|
173
|
+
* query: {
|
|
174
|
+
* find(filter: string) { return this.scope.transform(filter); },
|
|
175
|
+
* findAll() { return this.handlers.other.list(); },
|
|
176
|
+
* },
|
|
177
|
+
* }
|
|
265
178
|
*/
|
|
266
|
-
|
|
179
|
+
type HandlersMap = Record<string, Record<string, HandlerFn>>;
|
|
267
180
|
/**
|
|
268
|
-
*
|
|
181
|
+
* Wrapped handlers (ctx already bound via .bind()).
|
|
182
|
+
* Used internally by both pipelines.
|
|
269
183
|
*/
|
|
270
|
-
|
|
271
|
-
|
|
184
|
+
type WrappedHandlers = Record<string, Record<string, (...args: any[]) => any>>;
|
|
272
185
|
/**
|
|
273
|
-
*
|
|
186
|
+
* Boundary definition for compile-time interception.
|
|
187
|
+
* Allows foreign DSLs and compilers to plug into the expression walk.
|
|
188
|
+
* The handler is a self-sufficient closure — it captures whatever it needs
|
|
189
|
+
* from the consumer's scope (ExpressionCompiler, databases, other compilers).
|
|
274
190
|
*
|
|
275
|
-
*
|
|
276
|
-
*
|
|
191
|
+
* @example
|
|
192
|
+
* ```ts
|
|
193
|
+
* const rawBoundary: BoundaryDef = {
|
|
194
|
+
* check: (node) => "$raw" in node,
|
|
195
|
+
* handle: (node) => () => node.$raw,
|
|
196
|
+
* };
|
|
197
|
+
* ```
|
|
277
198
|
*/
|
|
199
|
+
interface BoundaryDef<T = unknown> {
|
|
200
|
+
/** Check if node belongs to this boundary */
|
|
201
|
+
check: (node: Record<string, unknown>) => boolean;
|
|
202
|
+
/** Compile the node. Returns a ready-to-call function. */
|
|
203
|
+
handle: (node: Record<string, unknown>) => CompiledFn<T>;
|
|
204
|
+
}
|
|
278
205
|
|
|
279
206
|
/**
|
|
280
|
-
*
|
|
207
|
+
* @statedelta-libs/expressions - Normalize
|
|
281
208
|
*
|
|
282
|
-
*
|
|
283
|
-
*
|
|
284
|
-
*
|
|
209
|
+
* External normalization helper for custom expression types.
|
|
210
|
+
* Converts custom DSL nodes ($query, $mapper, etc.) to standard Expression
|
|
211
|
+
* BEFORE compilation. Keeps the core compiler pure.
|
|
285
212
|
*
|
|
286
213
|
* @example
|
|
287
214
|
* ```ts
|
|
288
|
-
*
|
|
289
|
-
*
|
|
290
|
-
*
|
|
291
|
-
* const { fn } = compile(
|
|
292
|
-
* { $fn: "add", args: [{ $: "a" }, { $: "b" }] },
|
|
293
|
-
* { scope: { add, filter, sum } }
|
|
294
|
-
* );
|
|
295
|
-
*
|
|
296
|
-
* fn({ a: 1, b: 2 }); // 3
|
|
297
|
-
* ```
|
|
215
|
+
* const transforms = {
|
|
216
|
+
* $query: (node) => ({ $fn: "__query", args: [node.$query, node.params ?? {}] })
|
|
217
|
+
* };
|
|
298
218
|
*
|
|
299
|
-
*
|
|
300
|
-
*
|
|
301
|
-
*
|
|
302
|
-
* const { fn } = compile(
|
|
303
|
-
* { $: "hp:value" },
|
|
304
|
-
* { accessor: (path, ctx) => ctx.get(path) }
|
|
219
|
+
* const pure = normalize(
|
|
220
|
+
* { $query: "isAttacked", params: { row: { $: "kingRow" } } },
|
|
221
|
+
* transforms
|
|
305
222
|
* );
|
|
223
|
+
* // → { $fn: "__query", args: ["isAttacked", { row: { $: "kingRow" } }] }
|
|
306
224
|
*
|
|
307
|
-
*
|
|
225
|
+
* compile(pure, { scope });
|
|
308
226
|
* ```
|
|
309
227
|
*/
|
|
310
|
-
|
|
228
|
+
|
|
311
229
|
/**
|
|
312
|
-
*
|
|
230
|
+
* Transform function for custom expression types.
|
|
231
|
+
* Receives the raw node and returns a standard Expression.
|
|
313
232
|
*
|
|
314
233
|
* @example
|
|
315
234
|
* ```ts
|
|
316
|
-
*
|
|
317
|
-
*
|
|
318
|
-
*
|
|
319
|
-
*
|
|
320
|
-
*
|
|
321
|
-
*
|
|
322
|
-
*
|
|
323
|
-
* // Com accessor customizado
|
|
324
|
-
* evaluate(
|
|
325
|
-
* { $: "hp:value" },
|
|
326
|
-
* tickContext,
|
|
327
|
-
* { accessor: (path, ctx) => ctx.get(path) }
|
|
328
|
-
* );
|
|
235
|
+
* const transforms: Transforms = {
|
|
236
|
+
* $query: (node) => ({
|
|
237
|
+
* $fn: "__query",
|
|
238
|
+
* args: [node.$query, node.params ?? {}]
|
|
239
|
+
* }),
|
|
240
|
+
* };
|
|
329
241
|
* ```
|
|
330
242
|
*/
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
/**
|
|
334
|
-
* @statedelta-libs/expressions - Path Compiler
|
|
335
|
-
*
|
|
336
|
-
* Compiles paths to optimized getters with wildcard support.
|
|
337
|
-
* Performance: ~50M ops/sec for simple paths, ~10M ops/sec for wildcards
|
|
338
|
-
*/
|
|
339
|
-
|
|
340
|
-
/**
|
|
341
|
-
* Check if path has wildcards
|
|
342
|
-
*/
|
|
343
|
-
declare function hasWildcard(path: string): boolean;
|
|
344
|
-
/**
|
|
345
|
-
* Compile path to optimized getter
|
|
346
|
-
*/
|
|
347
|
-
declare function compilePath<T = unknown>(path: string): PathGetter<T>;
|
|
348
|
-
/**
|
|
349
|
-
* Get value at path directly (without caching)
|
|
350
|
-
*/
|
|
351
|
-
declare function get<T = unknown>(data: T, path: string): unknown;
|
|
352
|
-
/**
|
|
353
|
-
* Normalize path for dependency tracking (remove wildcards)
|
|
354
|
-
* @example "items[*].price" → "items"
|
|
355
|
-
* @example "users[*].posts[*].title" → "users"
|
|
356
|
-
*/
|
|
357
|
-
declare function normalizePath(path: string): string;
|
|
358
|
-
/**
|
|
359
|
-
* Clear path cache
|
|
360
|
-
*/
|
|
361
|
-
declare function clearPathCache(): void;
|
|
362
|
-
/**
|
|
363
|
-
* Get cache size
|
|
364
|
-
*/
|
|
365
|
-
declare function getPathCacheSize(): number;
|
|
366
|
-
|
|
367
|
-
/**
|
|
368
|
-
* @statedelta-libs/expressions - Dependency Extraction
|
|
369
|
-
*
|
|
370
|
-
* Extracts paths that an expression depends on.
|
|
371
|
-
* Performance: ~200K ops/sec
|
|
372
|
-
*/
|
|
373
|
-
|
|
374
|
-
/**
|
|
375
|
-
* Extract all paths an expression depends on
|
|
376
|
-
* @example { "$": "user.age" } → ["user.age"]
|
|
377
|
-
* @example { "$if": "$isVip", "then": { "$": "price.vip" } } → ["$isVip", "price.vip"]
|
|
378
|
-
*/
|
|
379
|
-
declare function extractDeps(expr: Expression): string[];
|
|
380
|
-
/**
|
|
381
|
-
* Check if expression has dependencies
|
|
382
|
-
*/
|
|
383
|
-
declare function hasDeps(expr: Expression): boolean;
|
|
243
|
+
type TransformFn = (node: Record<string, unknown>) => Expression;
|
|
384
244
|
/**
|
|
385
|
-
*
|
|
245
|
+
* Map of transform functions keyed by marker (e.g. "$query", "$mapper")
|
|
386
246
|
*/
|
|
387
|
-
|
|
247
|
+
type Transforms = Record<string, TransformFn>;
|
|
388
248
|
|
|
389
249
|
/**
|
|
390
|
-
* @statedelta-libs/expressions -
|
|
250
|
+
* @statedelta-libs/expressions - ExpressionCompiler
|
|
391
251
|
*
|
|
392
|
-
*
|
|
393
|
-
*
|
|
252
|
+
* Unified public API for expression compilation.
|
|
253
|
+
* Centralizes scope, accessor, and cache in a single reusable instance.
|
|
394
254
|
*/
|
|
395
255
|
|
|
256
|
+
interface ExpressionCompilerOptions<T = unknown> {
|
|
257
|
+
/** Functions available to $fn expressions */
|
|
258
|
+
scope?: Scope;
|
|
259
|
+
/** Custom accessor for resolving paths */
|
|
260
|
+
accessor?: AccessorFn;
|
|
261
|
+
/** Max LRU cache size per mode (default: 1000) */
|
|
262
|
+
cacheSize?: number;
|
|
263
|
+
/** Boundary definitions for compile-time interception */
|
|
264
|
+
boundaries?: BoundaryDef<T>[];
|
|
265
|
+
/** Handler namespaces — services with injected context */
|
|
266
|
+
handlers?: HandlersMap;
|
|
267
|
+
}
|
|
268
|
+
interface JITOptions {
|
|
269
|
+
/** Use accessor to resolve paths instead of direct access */
|
|
270
|
+
useAccessor?: boolean;
|
|
271
|
+
/** Prefix for paths that bypass accessor (direct access) */
|
|
272
|
+
lexicalPrefix?: string;
|
|
273
|
+
}
|
|
396
274
|
/**
|
|
397
|
-
*
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
/**
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
clear(): void;
|
|
423
|
-
/**
|
|
424
|
-
* Current cache size
|
|
425
|
-
*/
|
|
426
|
-
get size(): number;
|
|
427
|
-
/**
|
|
428
|
-
* Maximum cache size
|
|
429
|
-
*/
|
|
430
|
-
get maxSize(): number;
|
|
275
|
+
* Context available via `this` inside every handler (bound via .bind()).
|
|
276
|
+
* Created once per ExpressionCompiler instance — zero per-call overhead.
|
|
277
|
+
*/
|
|
278
|
+
interface HandlerContext<T = unknown> {
|
|
279
|
+
/** Custom accessor for resolving paths */
|
|
280
|
+
accessor?: AccessorFn;
|
|
281
|
+
/** All wrapped handlers — handlers can call other handlers */
|
|
282
|
+
handlers: WrappedHandlers;
|
|
283
|
+
/** Compiler instance — can compile sub-expressions */
|
|
284
|
+
compiler: ExpressionCompiler<T>;
|
|
285
|
+
/** Pure scope functions */
|
|
286
|
+
scope: Scope;
|
|
287
|
+
}
|
|
288
|
+
declare class ExpressionCompiler<T = unknown> {
|
|
289
|
+
private readonly scope;
|
|
290
|
+
private readonly accessor?;
|
|
291
|
+
private readonly boundaries?;
|
|
292
|
+
private readonly wrappedHandlers?;
|
|
293
|
+
private readonly cacheClosures;
|
|
294
|
+
private readonly cacheJIT;
|
|
295
|
+
constructor(options?: ExpressionCompilerOptions<T>);
|
|
296
|
+
/** Compile via closure composition (interpretation) */
|
|
297
|
+
compile<R = unknown>(expr: Expression): CompiledExpression<T, R>;
|
|
298
|
+
/** Compile via JS code generation (JIT) */
|
|
299
|
+
jit<R = unknown>(expr: Expression, opts?: JITOptions): CompiledExpression<T, R>;
|
|
431
300
|
/**
|
|
432
|
-
*
|
|
301
|
+
* Wrap raw handlers with ctx via .bind().
|
|
302
|
+
* Creates ctx once, binds each handler method once.
|
|
303
|
+
* Resolves circular reference: ctx.handlers = wrappedHandlers.
|
|
304
|
+
* Handlers access ctx via `this`.
|
|
433
305
|
*/
|
|
434
|
-
|
|
306
|
+
private wrapHandlers;
|
|
307
|
+
/** Compile (closures) and execute in one step */
|
|
308
|
+
evaluate<R = unknown>(expr: Expression, data: T): R;
|
|
309
|
+
/** Compile (JIT) and execute in one step */
|
|
310
|
+
evaluateJIT<R = unknown>(expr: Expression, data: T, opts?: JITOptions): R;
|
|
311
|
+
/** Normalize custom expression to pure DSL */
|
|
312
|
+
normalize(expr: Expression, transforms: Transforms): Expression;
|
|
313
|
+
/** Extract dependencies without compiling */
|
|
314
|
+
extractDeps(expr: Expression): string[];
|
|
315
|
+
/** Cache size per mode */
|
|
316
|
+
get cacheSize(): {
|
|
317
|
+
closures: number;
|
|
318
|
+
jit: number;
|
|
319
|
+
};
|
|
320
|
+
/** Clear both caches */
|
|
321
|
+
clearCache(): void;
|
|
322
|
+
/** Read-only access to scope */
|
|
323
|
+
getScope(): Readonly<Scope>;
|
|
435
324
|
}
|
|
436
|
-
declare const cache: ExpressionCache;
|
|
437
|
-
/**
|
|
438
|
-
* Compile and cache expression (convenience function)
|
|
439
|
-
*
|
|
440
|
-
* Note: Uses global cache. For custom scope management,
|
|
441
|
-
* use a dedicated ExpressionCache instance.
|
|
442
|
-
*/
|
|
443
|
-
declare function cached<T = unknown, R = unknown>(expr: Expression, options?: CompileOptions): CompiledExpression<T, R>;
|
|
444
|
-
|
|
445
|
-
/**
|
|
446
|
-
* @statedelta-libs/expressions - Validation
|
|
447
|
-
*
|
|
448
|
-
* Validates expression structure before compilation.
|
|
449
|
-
*/
|
|
450
|
-
|
|
451
|
-
/**
|
|
452
|
-
* Validation options
|
|
453
|
-
*/
|
|
454
|
-
interface ValidateOptions {
|
|
455
|
-
/** Scope to validate function names against (optional) */
|
|
456
|
-
scope?: Scope;
|
|
457
|
-
/** Context to validate $cb function names against (optional) */
|
|
458
|
-
context?: Context;
|
|
459
|
-
}
|
|
460
|
-
/**
|
|
461
|
-
* Validate expression structure
|
|
462
|
-
*
|
|
463
|
-
* @param expr - Expression to validate
|
|
464
|
-
* @param path - Current path in expression tree (for error messages)
|
|
465
|
-
* @param options - Validation options
|
|
466
|
-
*/
|
|
467
|
-
declare function validate(expr: Expression, path?: string, options?: ValidateOptions): ValidationResult;
|
|
468
|
-
/**
|
|
469
|
-
* Validate and throw if invalid
|
|
470
|
-
*/
|
|
471
|
-
declare function assertValid(expr: Expression, options?: ValidateOptions): void;
|
|
472
|
-
/**
|
|
473
|
-
* Check if expression is valid
|
|
474
|
-
*/
|
|
475
|
-
declare function isValid(expr: Expression, options?: ValidateOptions): boolean;
|
|
476
325
|
|
|
477
326
|
/**
|
|
478
327
|
* @statedelta-libs/expressions - Builders
|
|
@@ -579,25 +428,22 @@ declare function $cond(left: Expression, op: ConditionOp, right?: Expression): C
|
|
|
579
428
|
*/
|
|
580
429
|
declare const cond: typeof $cond;
|
|
581
430
|
/**
|
|
582
|
-
* Create
|
|
431
|
+
* Create an arrow expression (closure).
|
|
583
432
|
*
|
|
584
|
-
* @param
|
|
585
|
-
* @param
|
|
586
|
-
* @
|
|
587
|
-
* @returns CbExpr
|
|
433
|
+
* @param body - Expression to defer
|
|
434
|
+
* @param args - Named positional arguments (optional)
|
|
435
|
+
* @returns ArrowExpr
|
|
588
436
|
*
|
|
589
437
|
* @example
|
|
590
|
-
* $
|
|
591
|
-
*
|
|
592
|
-
*
|
|
593
|
-
* $cb("transaction", $fn("saveUser"), { isolation: "serializable" })
|
|
594
|
-
* // { $cb: "transaction", body: {...}, params: {...} }
|
|
438
|
+
* $arrow($fn("query")) // () => query()
|
|
439
|
+
* $arrow($("item.price"), ["item"]) // (item) => item.price
|
|
440
|
+
* $arrow($fn("add", [$("a"), $("b")]), ["a", "b"]) // (a, b) => add(a, b)
|
|
595
441
|
*/
|
|
596
|
-
declare function $
|
|
442
|
+
declare function $arrow(body: Expression, args?: string[]): ArrowExpr;
|
|
597
443
|
/**
|
|
598
|
-
* Alias for $
|
|
444
|
+
* Alias for $arrow
|
|
599
445
|
*/
|
|
600
|
-
declare const
|
|
446
|
+
declare const arrow: typeof $arrow;
|
|
601
447
|
/**
|
|
602
448
|
* Create a function call expression that always calls the function.
|
|
603
449
|
* Unlike $fn which returns function reference when args is empty/undefined,
|
|
@@ -618,428 +464,156 @@ declare function $call(name: string, args?: Expression[]): FnExpr;
|
|
|
618
464
|
declare const call: typeof $call;
|
|
619
465
|
|
|
620
466
|
declare const builders_$: typeof $;
|
|
467
|
+
declare const builders_$arrow: typeof $arrow;
|
|
621
468
|
declare const builders_$call: typeof $call;
|
|
622
|
-
declare const builders_$cb: typeof $cb;
|
|
623
469
|
declare const builders_$cond: typeof $cond;
|
|
624
470
|
declare const builders_$fn: typeof $fn;
|
|
625
471
|
declare const builders_$if: typeof $if;
|
|
626
472
|
declare const builders_$pipe: typeof $pipe;
|
|
473
|
+
declare const builders_arrow: typeof arrow;
|
|
627
474
|
declare const builders_call: typeof call;
|
|
628
|
-
declare const builders_cb: typeof cb;
|
|
629
475
|
declare const builders_cond: typeof cond;
|
|
630
476
|
declare const builders_fn: typeof fn;
|
|
631
477
|
declare const builders_pipe: typeof pipe;
|
|
632
478
|
declare const builders_ref: typeof ref;
|
|
633
479
|
declare namespace builders {
|
|
634
|
-
export { builders_$ as $, builders_$
|
|
480
|
+
export { builders_$ as $, builders_$arrow as $arrow, builders_$call as $call, builders_$cond as $cond, builders_$fn as $fn, builders_$if as $if, builders_$pipe as $pipe, builders_arrow as arrow, builders_call as call, builders_cond as cond, builders_fn as fn, builders_pipe as pipe, builders_ref as ref };
|
|
635
481
|
}
|
|
636
482
|
|
|
637
483
|
/**
|
|
638
|
-
* @statedelta-libs/expressions -
|
|
484
|
+
* @statedelta-libs/expressions - Type Guards
|
|
639
485
|
*
|
|
640
|
-
*
|
|
641
|
-
* Supports two modes:
|
|
642
|
-
* - With prefixes (default): generates `data?.user?.name`, `scope.add()`
|
|
643
|
-
* - Without prefixes: generates `user?.name`, `add()` (for use with destructuring)
|
|
486
|
+
* Type guards and constants for expression type checking.
|
|
644
487
|
*/
|
|
645
488
|
|
|
646
|
-
type ASTNode = types.Expression;
|
|
647
|
-
/** Options for DSL to AST transformation */
|
|
648
|
-
interface TransformOptions {
|
|
649
|
-
/**
|
|
650
|
-
* Name of data parameter (default: "data")
|
|
651
|
-
* When noPrefixes=true, this is ignored for property access
|
|
652
|
-
*/
|
|
653
|
-
dataParam?: string;
|
|
654
|
-
/**
|
|
655
|
-
* Name of scope parameter (default: "scope")
|
|
656
|
-
* When noPrefixes=true, this is ignored for function calls
|
|
657
|
-
*/
|
|
658
|
-
scopeParam?: string;
|
|
659
|
-
/**
|
|
660
|
-
* When true, generates code without data/scope prefixes.
|
|
661
|
-
* Assumes variables are available via destructuring.
|
|
662
|
-
* - `user?.name` instead of `data?.user?.name`
|
|
663
|
-
* - `add(a, b)` instead of `scope.add(data?.a, data?.b)`
|
|
664
|
-
*/
|
|
665
|
-
noPrefixes?: boolean;
|
|
666
|
-
/**
|
|
667
|
-
* When true, generates accessor("path", data) instead of property access.
|
|
668
|
-
* Requires `accessor` function in scope.
|
|
669
|
-
* - `accessor("user.name", data)` instead of `user?.name`
|
|
670
|
-
*/
|
|
671
|
-
useAccessor?: boolean;
|
|
672
|
-
/**
|
|
673
|
-
* Path prefix that should use direct property access instead of accessor.
|
|
674
|
-
* Only used when useAccessor is true.
|
|
675
|
-
* - `lexicalPrefix: "params"` → `params?.foo` instead of `accessor("params.foo", data)`
|
|
676
|
-
*/
|
|
677
|
-
lexicalPrefix?: string;
|
|
678
|
-
}
|
|
679
489
|
/**
|
|
680
|
-
*
|
|
681
|
-
*
|
|
682
|
-
* @param expr - DSL expression
|
|
683
|
-
* @param options - Transform options
|
|
684
|
-
* @returns ESTree AST node
|
|
685
|
-
*
|
|
686
|
-
* @example
|
|
687
|
-
* ```ts
|
|
688
|
-
* // With prefixes (default)
|
|
689
|
-
* dslToAST({ $: "user.name" })
|
|
690
|
-
* // → data?.user?.name
|
|
691
|
-
*
|
|
692
|
-
* // Without prefixes (for destructuring)
|
|
693
|
-
* dslToAST({ $: "user.name" }, { noPrefixes: true })
|
|
694
|
-
* // → user?.name
|
|
695
|
-
* ```
|
|
490
|
+
* Check if value is a reference expression
|
|
696
491
|
*/
|
|
697
|
-
declare
|
|
492
|
+
declare const isRef: (v: unknown) => v is RefExpr;
|
|
698
493
|
/**
|
|
699
|
-
*
|
|
494
|
+
* Check if value is a conditional expression
|
|
700
495
|
*/
|
|
701
|
-
declare
|
|
702
|
-
|
|
496
|
+
declare const isConditional: (v: unknown) => v is ConditionalExpr;
|
|
703
497
|
/**
|
|
704
|
-
*
|
|
705
|
-
*
|
|
706
|
-
* Extracts function names used from scope in a DSL expression.
|
|
707
|
-
* Used to generate optimized destructuring: const { add, filter } = scope;
|
|
498
|
+
* Check if value is a function call expression
|
|
708
499
|
*/
|
|
709
|
-
|
|
500
|
+
declare const isFn: (v: unknown) => v is FnExpr;
|
|
710
501
|
/**
|
|
711
|
-
*
|
|
712
|
-
*
|
|
713
|
-
* @param expr - DSL expression to analyze
|
|
714
|
-
* @returns Set of function names used
|
|
715
|
-
*
|
|
716
|
-
* @example
|
|
717
|
-
* ```ts
|
|
718
|
-
* extractScopeFns({ $fn: "add", args: [{ $: "a" }, { $: "b" }] })
|
|
719
|
-
* // Set { "add" }
|
|
720
|
-
*
|
|
721
|
-
* extractScopeFns({
|
|
722
|
-
* $pipe: [
|
|
723
|
-
* { $: "items" },
|
|
724
|
-
* { $fn: "filter", args: [pred] },
|
|
725
|
-
* { $fn: "sum" }
|
|
726
|
-
* ]
|
|
727
|
-
* })
|
|
728
|
-
* // Set { "filter", "sum" }
|
|
729
|
-
* ```
|
|
502
|
+
* Check if value is a pipe expression
|
|
730
503
|
*/
|
|
731
|
-
declare
|
|
504
|
+
declare const isPipe: (v: unknown) => v is PipeExpr;
|
|
732
505
|
/**
|
|
733
|
-
*
|
|
734
|
-
*
|
|
735
|
-
* @param expr - DSL expression to analyze
|
|
736
|
-
* @returns Set of context function names used
|
|
737
|
-
*
|
|
738
|
-
* @example
|
|
739
|
-
* ```ts
|
|
740
|
-
* extractContextFns({ $cb: "tryCatch", body: { $fn: "query" } })
|
|
741
|
-
* // Set { "tryCatch" }
|
|
742
|
-
* ```
|
|
506
|
+
* Check if value is an arrow expression (closure)
|
|
743
507
|
*/
|
|
744
|
-
declare
|
|
508
|
+
declare const isArrow: (v: unknown) => v is ArrowExpr;
|
|
745
509
|
/**
|
|
746
|
-
*
|
|
747
|
-
*
|
|
748
|
-
* @param deps - Array of dependency paths
|
|
749
|
-
* @returns Set of root-level property names
|
|
510
|
+
* Check if value is a condition expression
|
|
750
511
|
*
|
|
751
|
-
*
|
|
752
|
-
*
|
|
753
|
-
* extractDataRoots(["user.name", "user.age", "items", "config.theme"])
|
|
754
|
-
* // Set { "user", "items", "config" }
|
|
755
|
-
* ```
|
|
512
|
+
* Verifies `op` is a valid condition operator to distinguish from
|
|
513
|
+
* effect objects that also have `left` and `op` (e.g. op: "set").
|
|
756
514
|
*/
|
|
757
|
-
declare
|
|
758
|
-
|
|
515
|
+
declare const isCondition: (v: unknown) => v is Condition;
|
|
759
516
|
/**
|
|
760
|
-
*
|
|
761
|
-
*
|
|
762
|
-
* Compiles DSL expressions to optimized functions using AST generation.
|
|
763
|
-
* Uses destructuring for better performance:
|
|
764
|
-
* - Variables from data are destructured into local scope
|
|
765
|
-
* - Functions from scope are destructured into local scope
|
|
766
|
-
* - Generated code is smaller and faster
|
|
517
|
+
* Check if value is a condition group
|
|
767
518
|
*/
|
|
768
|
-
|
|
769
|
-
/** Options for AST compilation */
|
|
770
|
-
interface CompileASTOptions {
|
|
771
|
-
/** Scope with functions available to the expression */
|
|
772
|
-
scope?: Scope;
|
|
773
|
-
/** Context with HOC functions available to $cb expressions */
|
|
774
|
-
context?: Context;
|
|
775
|
-
/** Return generated code instead of function (for debugging) */
|
|
776
|
-
returnCode?: boolean;
|
|
777
|
-
/**
|
|
778
|
-
* When true, generates accessor("path", data) instead of property access.
|
|
779
|
-
* Requires `accessor` function in scope.
|
|
780
|
-
*/
|
|
781
|
-
useAccessor?: boolean;
|
|
782
|
-
/**
|
|
783
|
-
* Path prefix that should use direct property access instead of accessor.
|
|
784
|
-
* Only used when useAccessor is true.
|
|
785
|
-
* - `lexicalPrefix: "params"` → `params?.foo` instead of `accessor("params.foo", data)`
|
|
786
|
-
*/
|
|
787
|
-
lexicalPrefix?: string;
|
|
788
|
-
}
|
|
789
|
-
/** Result when returnCode is true */
|
|
790
|
-
interface CompileASTCodeResult {
|
|
791
|
-
code: string;
|
|
792
|
-
deps: string[];
|
|
793
|
-
hash: string;
|
|
794
|
-
dataRoots: string[];
|
|
795
|
-
scopeFns: string[];
|
|
796
|
-
contextFns: string[];
|
|
797
|
-
}
|
|
519
|
+
declare const isConditionGroup: (v: unknown) => v is ConditionGroup;
|
|
798
520
|
/**
|
|
799
|
-
*
|
|
800
|
-
*
|
|
801
|
-
* This is the high-performance compiler that:
|
|
802
|
-
* 1. Extracts dependencies and scope functions
|
|
803
|
-
* 2. Generates AST without prefixes
|
|
804
|
-
* 3. Wraps in destructuring for optimal variable access
|
|
805
|
-
* 4. Creates function via `new Function()` or `eval()`
|
|
806
|
-
*
|
|
807
|
-
* @example
|
|
808
|
-
* ```ts
|
|
809
|
-
* import { compileAST } from '@statedelta-libs/expressions';
|
|
810
|
-
* import { add, filter, sum } from '@statedelta-libs/operators';
|
|
811
|
-
*
|
|
812
|
-
* const { fn } = compileAST(
|
|
813
|
-
* { $fn: "add", args: [{ $: "a" }, { $: "b" }] },
|
|
814
|
-
* { scope: { add, filter, sum } }
|
|
815
|
-
* );
|
|
816
|
-
*
|
|
817
|
-
* fn({ a: 1, b: 2 }); // 3
|
|
818
|
-
* ```
|
|
521
|
+
* Check if value is any condition expression
|
|
819
522
|
*/
|
|
820
|
-
declare
|
|
821
|
-
returnCode: true;
|
|
822
|
-
}): CompileASTCodeResult;
|
|
823
|
-
declare function compileAST<T = unknown, R = unknown>(expr: Expression, options?: CompileASTOptions): CompiledExpression<T, R>;
|
|
523
|
+
declare const isConditionExpr: (v: unknown) => v is ConditionExpr;
|
|
824
524
|
/**
|
|
825
|
-
*
|
|
826
|
-
*
|
|
827
|
-
* @example
|
|
828
|
-
* ```ts
|
|
829
|
-
* evaluateAST(
|
|
830
|
-
* { $fn: "add", args: [{ $: "a" }, { $: "b" }] },
|
|
831
|
-
* { a: 1, b: 2 },
|
|
832
|
-
* { scope: { add } }
|
|
833
|
-
* ); // 3
|
|
834
|
-
* ```
|
|
525
|
+
* Check if value is a literal (not an expression object)
|
|
835
526
|
*/
|
|
836
|
-
declare
|
|
527
|
+
declare const isLiteral: (v: unknown) => v is Literal;
|
|
837
528
|
|
|
838
529
|
/**
|
|
839
|
-
* @statedelta-libs/expressions -
|
|
840
|
-
*
|
|
841
|
-
* External normalization helper for custom expression types.
|
|
842
|
-
* Converts custom DSL nodes ($query, $mapper, etc.) to standard Expression
|
|
843
|
-
* BEFORE compilation. Keeps the core compiler pure.
|
|
844
|
-
*
|
|
845
|
-
* @example
|
|
846
|
-
* ```ts
|
|
847
|
-
* const transforms = {
|
|
848
|
-
* $query: (node) => ({ $fn: "__query", args: [node.$query, node.params ?? {}] })
|
|
849
|
-
* };
|
|
850
|
-
*
|
|
851
|
-
* const pure = normalize(
|
|
852
|
-
* { $query: "isAttacked", params: { row: { $: "kingRow" } } },
|
|
853
|
-
* transforms
|
|
854
|
-
* );
|
|
855
|
-
* // → { $fn: "__query", args: ["isAttacked", { row: { $: "kingRow" } }] }
|
|
530
|
+
* @statedelta-libs/expressions - Validation
|
|
856
531
|
*
|
|
857
|
-
*
|
|
858
|
-
* ```
|
|
532
|
+
* Validates expression structure before compilation.
|
|
859
533
|
*/
|
|
860
534
|
|
|
861
535
|
/**
|
|
862
|
-
*
|
|
863
|
-
|
|
536
|
+
* Validation options
|
|
537
|
+
*/
|
|
538
|
+
interface ValidateOptions {
|
|
539
|
+
/** Scope to validate function names against (optional) */
|
|
540
|
+
scope?: Scope;
|
|
541
|
+
/** Boundary definitions — matched nodes skip validation */
|
|
542
|
+
boundaries?: BoundaryDef[];
|
|
543
|
+
/** Handlers map to validate handler names against (optional) */
|
|
544
|
+
handlers?: HandlersMap;
|
|
545
|
+
}
|
|
546
|
+
/**
|
|
547
|
+
* Validate expression structure
|
|
864
548
|
*
|
|
865
|
-
* @
|
|
866
|
-
*
|
|
867
|
-
*
|
|
868
|
-
* $query: (node) => ({
|
|
869
|
-
* $fn: "__query",
|
|
870
|
-
* args: [node.$query, node.params ?? {}]
|
|
871
|
-
* }),
|
|
872
|
-
* };
|
|
873
|
-
* ```
|
|
549
|
+
* @param expr - Expression to validate
|
|
550
|
+
* @param path - Current path in expression tree (for error messages)
|
|
551
|
+
* @param options - Validation options
|
|
874
552
|
*/
|
|
875
|
-
|
|
553
|
+
declare function validate(expr: Expression, path?: string, options?: ValidateOptions): ValidationResult;
|
|
876
554
|
/**
|
|
877
|
-
*
|
|
555
|
+
* Validate and throw if invalid
|
|
878
556
|
*/
|
|
879
|
-
|
|
557
|
+
declare function assertValid(expr: Expression, options?: ValidateOptions): void;
|
|
880
558
|
/**
|
|
881
|
-
*
|
|
882
|
-
* Converts custom DSL nodes to standard Expression types.
|
|
883
|
-
*
|
|
884
|
-
* @param expr - Expression (possibly with custom nodes)
|
|
885
|
-
* @param transforms - Map of transform functions
|
|
886
|
-
* @returns Pure Expression with all custom nodes converted
|
|
887
|
-
*
|
|
888
|
-
* @example
|
|
889
|
-
* ```ts
|
|
890
|
-
* const transforms = {
|
|
891
|
-
* $query: (node) => ({ $fn: "__query", args: [node.$query, node.params ?? {}] })
|
|
892
|
-
* };
|
|
893
|
-
*
|
|
894
|
-
* normalize({ $query: "check", params: { x: 1 } }, transforms);
|
|
895
|
-
* // → { $fn: "__query", args: ["check", { x: 1 }] }
|
|
896
|
-
*
|
|
897
|
-
* // Nested expressions in params are also normalized
|
|
898
|
-
* normalize({ $query: "check", params: { row: { $: "myRow" } } }, transforms);
|
|
899
|
-
* // → { $fn: "__query", args: ["check", { row: { $: "myRow" } }] }
|
|
900
|
-
* ```
|
|
559
|
+
* Check if expression is valid
|
|
901
560
|
*/
|
|
902
|
-
declare function
|
|
561
|
+
declare function isValid(expr: Expression, options?: ValidateOptions): boolean;
|
|
903
562
|
|
|
904
563
|
/**
|
|
905
|
-
* @statedelta-libs/expressions -
|
|
906
|
-
*
|
|
907
|
-
* Resolve custom boundaries ($simulate, $query, etc.) before compilation.
|
|
908
|
-
* Boundaries are "foreign bodies" that stop the expression flow and delegate
|
|
909
|
-
* to external handlers. The handler can compile internal slots independently.
|
|
910
|
-
*
|
|
911
|
-
* @example
|
|
912
|
-
* ```ts
|
|
913
|
-
* const { expr, scope } = resolveBoundaries(
|
|
914
|
-
* { $simulate: { effects: [...], query: {...} } },
|
|
915
|
-
* {
|
|
916
|
-
* scope: baseScope,
|
|
917
|
-
* resolvers: {
|
|
918
|
-
* $simulate: (node, { compile, genId }) => {
|
|
919
|
-
* const id = `__simulate_${genId()}`;
|
|
920
|
-
* const fn = buildSimulateFn(node, compile);
|
|
921
|
-
* return {
|
|
922
|
-
* expr: { $fn: id },
|
|
923
|
-
* scopeEntry: [id, fn]
|
|
924
|
-
* };
|
|
925
|
-
* }
|
|
926
|
-
* }
|
|
927
|
-
* }
|
|
928
|
-
* );
|
|
564
|
+
* @statedelta-libs/expressions - Path Compiler
|
|
929
565
|
*
|
|
930
|
-
*
|
|
931
|
-
*
|
|
566
|
+
* Compiles paths to optimized getters with wildcard support.
|
|
567
|
+
* Performance: ~50M ops/sec for simple paths, ~10M ops/sec for wildcards
|
|
932
568
|
*/
|
|
933
569
|
|
|
934
570
|
/**
|
|
935
|
-
*
|
|
571
|
+
* Check if path has wildcards
|
|
936
572
|
*/
|
|
937
|
-
|
|
938
|
-
/** Expression to replace the boundary with */
|
|
939
|
-
expr: Expression;
|
|
940
|
-
/** Optional entry to add to scope [key, value] */
|
|
941
|
-
scopeEntry?: [string, unknown];
|
|
942
|
-
}
|
|
573
|
+
declare function hasWildcard(path: string): boolean;
|
|
943
574
|
/**
|
|
944
|
-
*
|
|
945
|
-
*/
|
|
946
|
-
|
|
947
|
-
/** Compile function for compiling internal slots */
|
|
948
|
-
compile: typeof compile;
|
|
949
|
-
/** Generate unique ID for scope entries */
|
|
950
|
-
genId: () => string;
|
|
951
|
-
/** Current scope (read-only reference) */
|
|
952
|
-
scope: Readonly<Scope>;
|
|
953
|
-
/** Compile options passed to resolveBoundaries */
|
|
954
|
-
options: Readonly<CompileOptions>;
|
|
955
|
-
}
|
|
575
|
+
* Compile path to optimized getter
|
|
576
|
+
*/
|
|
577
|
+
declare function compilePath<T = unknown>(path: string): PathGetter<T>;
|
|
956
578
|
/**
|
|
957
|
-
*
|
|
958
|
-
* Receives the raw node and context, returns replacement expression.
|
|
579
|
+
* Get value at path directly (without caching)
|
|
959
580
|
*/
|
|
960
|
-
|
|
581
|
+
declare function get<T = unknown>(data: T, path: string): unknown;
|
|
961
582
|
/**
|
|
962
|
-
*
|
|
583
|
+
* Normalize path for dependency tracking (remove wildcards)
|
|
584
|
+
* @example "items[*].price" → "items"
|
|
585
|
+
* @example "users[*].posts[*].title" → "users"
|
|
963
586
|
*/
|
|
964
|
-
|
|
587
|
+
declare function normalizePath(path: string): string;
|
|
588
|
+
|
|
965
589
|
/**
|
|
966
|
-
*
|
|
590
|
+
* @statedelta-libs/expressions - Dependency Extraction
|
|
591
|
+
*
|
|
592
|
+
* Extracts paths that an expression depends on.
|
|
593
|
+
* Performance: ~200K ops/sec
|
|
967
594
|
*/
|
|
968
|
-
|
|
595
|
+
|
|
969
596
|
/**
|
|
970
|
-
*
|
|
597
|
+
* Extract all paths an expression depends on
|
|
598
|
+
* @example { "$": "user.age" } → ["user.age"]
|
|
599
|
+
* @example { "$if": "$isVip", "then": { "$": "price.vip" } } → ["$isVip", "price.vip"]
|
|
971
600
|
*/
|
|
972
|
-
|
|
973
|
-
/** Map of boundary resolvers */
|
|
974
|
-
resolvers: BoundaryResolvers;
|
|
975
|
-
/** Custom ID generator. Default: simple counter ("0", "1", "2"...) */
|
|
976
|
-
genId?: IdGenerator;
|
|
977
|
-
}
|
|
601
|
+
declare function extractDeps(expr: Expression): string[];
|
|
978
602
|
/**
|
|
979
|
-
*
|
|
603
|
+
* Check if expression has dependencies
|
|
980
604
|
*/
|
|
981
|
-
|
|
982
|
-
/** Pure expression with boundaries replaced */
|
|
983
|
-
expr: Expression;
|
|
984
|
-
/** Enriched scope with boundary handlers */
|
|
985
|
-
scope: Scope;
|
|
986
|
-
}
|
|
605
|
+
declare function hasDeps(expr: Expression): boolean;
|
|
987
606
|
/**
|
|
988
|
-
*
|
|
989
|
-
*
|
|
990
|
-
* Boundaries are custom DSL nodes ($simulate, $query, etc.) that stop the
|
|
991
|
-
* normal expression compilation flow. Each boundary is extracted, processed
|
|
992
|
-
* by its resolver, and replaced with a standard expression.
|
|
993
|
-
*
|
|
994
|
-
* The resolver receives:
|
|
995
|
-
* - `node`: The raw boundary object (e.g. { $simulate: {...}, effects: [...] })
|
|
996
|
-
* - `ctx.compile`: Compile function for internal slots
|
|
997
|
-
* - `ctx.genId`: Unique ID generator
|
|
998
|
-
* - `ctx.scope`: Current scope (read-only)
|
|
999
|
-
*
|
|
1000
|
-
* The resolver returns:
|
|
1001
|
-
* - `expr`: Replacement expression (typically { $fn: "__id" })
|
|
1002
|
-
* - `scopeEntry`: Optional [key, fn] to add to scope
|
|
1003
|
-
*
|
|
1004
|
-
* @param expr - Expression (possibly with boundaries)
|
|
1005
|
-
* @param options - Resolvers, scope, and compile options
|
|
1006
|
-
* @returns Pure expression and enriched scope
|
|
607
|
+
* Check if expression is pure (no dependencies)
|
|
1007
608
|
*/
|
|
1008
|
-
declare function
|
|
609
|
+
declare function isPure(expr: Expression): boolean;
|
|
1009
610
|
|
|
1010
611
|
/**
|
|
1011
612
|
* @statedelta-libs/expressions
|
|
1012
613
|
*
|
|
1013
614
|
* JSON DSL compiler for optimized functions.
|
|
1014
615
|
* Functions are provided via scope, not hardcoded.
|
|
1015
|
-
*
|
|
1016
|
-
* @example
|
|
1017
|
-
* ```ts
|
|
1018
|
-
* import { compile, evaluate } from '@statedelta-libs/expressions';
|
|
1019
|
-
* import { filter, map, sum } from '@statedelta-libs/operators';
|
|
1020
|
-
*
|
|
1021
|
-
* const scope = { filter, map, sum };
|
|
1022
|
-
*
|
|
1023
|
-
* // Using $pipe for composition with initial value
|
|
1024
|
-
* const { fn } = compile({
|
|
1025
|
-
* $pipe: [
|
|
1026
|
-
* { $: "items" },
|
|
1027
|
-
* { $fn: "filter", args: [{ path: "active", op: "eq", value: true }] },
|
|
1028
|
-
* { $fn: "map", args: [{ $: "price" }] },
|
|
1029
|
-
* { $fn: "sum" }
|
|
1030
|
-
* ]
|
|
1031
|
-
* }, { scope });
|
|
1032
|
-
*
|
|
1033
|
-
* fn({ items: [...] }); // sum of active item prices
|
|
1034
|
-
*
|
|
1035
|
-
* // Using $fn for simple function calls
|
|
1036
|
-
* evaluate(
|
|
1037
|
-
* { $fn: "add", args: [{ $: "a" }, { $: "b" }] },
|
|
1038
|
-
* { a: 1, b: 2 },
|
|
1039
|
-
* { scope: { add: (a, b) => a + b } }
|
|
1040
|
-
* ); // 3
|
|
1041
|
-
* ```
|
|
1042
616
|
*/
|
|
1043
|
-
declare const VERSION = "
|
|
617
|
+
declare const VERSION = "3.0.0";
|
|
1044
618
|
|
|
1045
|
-
export { type AccessorFn, type
|
|
619
|
+
export { type AccessorFn, type ArrowExpr, type BoundaryDef, type CompileOptions, type CompiledExpression, type CompiledFn, type Condition, type ConditionExpr, type ConditionGroup, type ConditionOp, type ConditionalExpr, type Expression, ExpressionCompiler, type ExpressionCompilerOptions, type FnExpr, type HandlerContext, type HandlerFn, type HandlersMap, type JITOptions, type Literal, type PipeExpr, type RefExpr, type Scope, type TransformFn, type Transforms, VERSION, type ValidateOptions, type ValidationResult, type WrappedHandlers, assertValid, builders, compilePath, extractDeps, get, hasDeps, hasWildcard, isArrow, isCondition, isConditionExpr, isConditionGroup, isConditional, isFn, isLiteral, isPipe, isPure, isRef, isValid, normalizePath, validate };
|