@codehz/json-expr 0.3.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +537 -86
- package/dist/index.d.mts +183 -94
- package/dist/index.mjs +870 -320
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -1,16 +1,66 @@
|
|
|
1
1
|
//#region src/types.d.ts
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
3
|
+
* Proxy Expression 类型标记(用于类型推导)
|
|
4
|
+
* 这是一个 phantom type,实际运行时是 Proxy 对象
|
|
5
5
|
*/
|
|
6
|
-
type
|
|
7
|
-
|
|
8
|
-
_type: T;
|
|
6
|
+
type ProxyExpression<T = unknown> = {
|
|
7
|
+
readonly __proxyExpression: T;
|
|
9
8
|
};
|
|
9
|
+
/**
|
|
10
|
+
* 处理函数参数的 Proxy 转换
|
|
11
|
+
* 参数可以是原始值或对应的 Proxy
|
|
12
|
+
*/
|
|
13
|
+
type ProxifyArgs<T extends unknown[]> = { [K in keyof T]: T[K] | Proxify<T[K]> };
|
|
14
|
+
/**
|
|
15
|
+
* 需要特殊处理的数组方法名(有泛型参数,需要显式定义以保留类型推导)
|
|
16
|
+
*/
|
|
17
|
+
type ProxifiedArrayMethods = "map" | "flatMap" | "filter" | "reduce" | "reduceRight" | "find" | "findIndex" | "findLast" | "findLastIndex" | "every" | "some" | "forEach" | "toSorted" | "sort";
|
|
18
|
+
/**
|
|
19
|
+
* 数组类型的 Proxify 版本
|
|
20
|
+
* 特殊处理泛型方法(map, filter 等),确保返回值类型正确
|
|
21
|
+
*/
|
|
22
|
+
type ProxifiedArray<T> = {
|
|
23
|
+
map<U>(callbackfn: Proxify<(value: T, index: number, array: T[]) => U>): Proxify<U[]>;
|
|
24
|
+
flatMap<U>(callbackfn: Proxify<(value: T, index: number, array: T[]) => U | readonly U[]>): Proxify<U[]>;
|
|
25
|
+
filter<S extends T>(predicate: Proxify<(value: T, index: number, array: T[]) => value is S>): Proxify<S[]>;
|
|
26
|
+
filter(predicate: Proxify<(value: T, index: number, array: T[]) => unknown>): Proxify<T[]>;
|
|
27
|
+
reduce<U>(callbackfn: Proxify<(previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U>, initialValue: U | Proxify<U>): Proxify<U>;
|
|
28
|
+
reduce(callbackfn: Proxify<(previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T>): Proxify<T>;
|
|
29
|
+
reduceRight<U>(callbackfn: Proxify<(previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U>, initialValue: U | Proxify<U>): Proxify<U>;
|
|
30
|
+
reduceRight(callbackfn: Proxify<(previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T>): Proxify<T>;
|
|
31
|
+
find<S extends T>(predicate: Proxify<(value: T, index: number, obj: T[]) => value is S>): Proxify<S | undefined>;
|
|
32
|
+
find(predicate: Proxify<(value: T, index: number, obj: T[]) => unknown>): Proxify<T | undefined>;
|
|
33
|
+
findIndex(predicate: Proxify<(value: T, index: number, obj: T[]) => unknown>): Proxify<number>;
|
|
34
|
+
findLast<S extends T>(predicate: Proxify<(value: T, index: number, array: T[]) => value is S>): Proxify<S | undefined>;
|
|
35
|
+
findLast(predicate: Proxify<(value: T, index: number, array: T[]) => unknown>): Proxify<T | undefined>;
|
|
36
|
+
findLastIndex(predicate: Proxify<(value: T, index: number, array: T[]) => unknown>): Proxify<number>;
|
|
37
|
+
every<S extends T>(predicate: Proxify<(value: T, index: number, array: T[]) => value is S>): Proxify<boolean>;
|
|
38
|
+
every(predicate: Proxify<(value: T, index: number, array: T[]) => unknown>): Proxify<boolean>;
|
|
39
|
+
some(predicate: Proxify<(value: T, index: number, array: T[]) => unknown>): Proxify<boolean>;
|
|
40
|
+
forEach(callbackfn: Proxify<(value: T, index: number, array: T[]) => void>): Proxify<void>;
|
|
41
|
+
toSorted(compareFn?: Proxify<(a: T, b: T) => number>): Proxify<T[]>;
|
|
42
|
+
sort(compareFn?: Proxify<(a: T, b: T) => number>): Proxify<T[]>;
|
|
43
|
+
} & { [K in Exclude<keyof T[], ProxifiedArrayMethods>]: Proxify<T[][K]> };
|
|
44
|
+
/**
|
|
45
|
+
* 将类型 T 转换为 Proxy 包装类型
|
|
46
|
+
* - 始终包含 ProxyExpression<T> 标记,用于 compile 函数类型检查
|
|
47
|
+
* - 函数类型:保持函数签名,但参数允许 Proxy 或原始值,返回值递归应用 Proxify
|
|
48
|
+
* - 数组类型:使用 ProxifiedArray 特殊处理泛型方法
|
|
49
|
+
* - 对象类型:映射所有属性为 Proxify
|
|
50
|
+
* - 原始类型:保持不变(返回 ProxyExpression 包装)
|
|
51
|
+
*/
|
|
52
|
+
type Proxify<T> = ProxyExpression<T> & (T extends ((...args: infer Args) => infer R) ? (...args: ProxifyArgs<Args>) => Proxify<R> : T extends readonly (infer E)[] ? ProxifiedArray<E> : T extends object ? { [K in keyof T]: Proxify<T[K]> } : unknown);
|
|
53
|
+
/**
|
|
54
|
+
* Variable 类型定义
|
|
55
|
+
* 总是返回 Proxy 包装后的类型
|
|
56
|
+
* @template T - 变量的值类型
|
|
57
|
+
*/
|
|
58
|
+
type Variable<T = unknown> = Proxify<T>;
|
|
10
59
|
/**
|
|
11
60
|
* 表示一个表达式
|
|
12
61
|
* @template TContext - 表达式上下文类型
|
|
13
62
|
* @template TResult - 表达式结果类型
|
|
63
|
+
* @deprecated 请使用新的 Proxy 类型系统
|
|
14
64
|
*/
|
|
15
65
|
type Expression<TContext = Record<string, unknown>, TResult = unknown> = {
|
|
16
66
|
_tag: "expression";
|
|
@@ -81,18 +131,61 @@ type InferContextType<C> = { [K in keyof C]: C[K] extends Variable<infer T> ? T
|
|
|
81
131
|
* @template E - Expression 类型
|
|
82
132
|
*/
|
|
83
133
|
type InferExpressionType<E> = E extends Expression<unknown, infer R> ? R : never;
|
|
134
|
+
/**
|
|
135
|
+
* Lambda 参数代理类型
|
|
136
|
+
* 与普通 Proxify<T> 相同,但标记为 lambda 参数
|
|
137
|
+
*/
|
|
138
|
+
type LambdaParam<T> = Proxify<T>;
|
|
139
|
+
/**
|
|
140
|
+
* 原始类型
|
|
141
|
+
*/
|
|
142
|
+
type Primitive = string | number | boolean | null | undefined | symbol | bigint;
|
|
143
|
+
/**
|
|
144
|
+
* 深度允许 Proxy 或原始值的类型
|
|
145
|
+
* 用于 lambda 返回值,允许对象/数组中混合 Proxy 和原始值
|
|
146
|
+
*/
|
|
147
|
+
type DeepPartialProxy<T> = T extends Primitive ? T : T extends readonly (infer E)[] ? readonly (Proxify<E> | DeepPartialProxy<E>)[] : T extends object ? { [K in keyof T]: Proxify<T[K]> | DeepPartialProxy<T[K]> } : T;
|
|
148
|
+
/**
|
|
149
|
+
* Lambda 函数体返回值类型
|
|
150
|
+
* 支持返回:
|
|
151
|
+
* - Proxify<R>: 完整的代理表达式
|
|
152
|
+
* - 原始值: 字符串、数字等
|
|
153
|
+
* - 对象/数组: 可以混合 Proxy 值和原始值
|
|
154
|
+
*/
|
|
155
|
+
type LambdaBodyResult<T> = Proxify<T> | DeepPartialProxy<T>;
|
|
156
|
+
/**
|
|
157
|
+
* Lambda 构建函数签名
|
|
158
|
+
* @template Args - 参数类型元组
|
|
159
|
+
* @template R - 返回值类型
|
|
160
|
+
*/
|
|
161
|
+
type LambdaBuilder<Args extends unknown[], R> = (...params: { [K in keyof Args]: LambdaParam<Args[K]> }) => LambdaBodyResult<R>;
|
|
162
|
+
/**
|
|
163
|
+
* Lambda 表达式类型
|
|
164
|
+
* 表示一个可序列化的函数
|
|
165
|
+
*/
|
|
166
|
+
type Lambda<Args extends unknown[], R> = Proxify<(...args: Args) => R>;
|
|
167
|
+
/**
|
|
168
|
+
* 从 Lambda 类型提取参数类型
|
|
169
|
+
*/
|
|
170
|
+
type InferLambdaArgs<L> = L extends Lambda<infer Args, unknown> ? Args : never;
|
|
171
|
+
/**
|
|
172
|
+
* 从 Lambda 类型提取返回类型
|
|
173
|
+
*/
|
|
174
|
+
type InferLambdaReturn<L> = L extends Lambda<unknown[], infer R> ? R : never;
|
|
175
|
+
/**
|
|
176
|
+
* 常用 Lambda 类型别名
|
|
177
|
+
*/
|
|
178
|
+
type MapCallback<T, R> = Lambda<[T, number, T[]], R>;
|
|
179
|
+
type FilterCallback<T> = Lambda<[T, number, T[]], boolean>;
|
|
180
|
+
type ReduceCallback<T, R> = Lambda<[R, T, number, T[]], R>;
|
|
181
|
+
type FindCallback<T> = Lambda<[T, number, T[]], boolean>;
|
|
182
|
+
type SortCallback<T> = Lambda<[T, T], number>;
|
|
84
183
|
//#endregion
|
|
85
184
|
//#region src/compile.d.ts
|
|
86
185
|
/**
|
|
87
186
|
* 编译选项
|
|
88
187
|
*/
|
|
89
188
|
interface CompileOptions {
|
|
90
|
-
/**
|
|
91
|
-
* 是否启用内联优化
|
|
92
|
-
* 将只被引用一次的子表达式内联到使用位置
|
|
93
|
-
* @default true
|
|
94
|
-
*/
|
|
95
|
-
inline?: boolean;
|
|
96
189
|
/**
|
|
97
190
|
* 是否启用短路求值
|
|
98
191
|
* 为 &&, ||, ??, 和三元表达式生成控制流节点
|
|
@@ -101,66 +194,27 @@ interface CompileOptions {
|
|
|
101
194
|
shortCircuit?: boolean;
|
|
102
195
|
}
|
|
103
196
|
/**
|
|
104
|
-
*
|
|
105
|
-
*/
|
|
106
|
-
type ExpressionContext = Record<string, Variable | Expression<Record<string, unknown>, unknown>>;
|
|
107
|
-
/**
|
|
108
|
-
* 将表达式树编译为可序列化的 JSON 结构
|
|
197
|
+
* 将 Proxy Expression 编译为可序列化的 JSON 结构
|
|
109
198
|
*
|
|
110
199
|
* @template TResult - 表达式结果类型
|
|
111
|
-
* @param expression -
|
|
200
|
+
* @param expression - Proxy Expression,或包含 Proxy 的对象/数组/原始值
|
|
112
201
|
* @param variables - 所有使用的变量定义
|
|
113
202
|
* @param options - 编译选项
|
|
114
203
|
* @returns 编译后的数据结构 [变量名列表, 表达式1, 表达式2, ...]
|
|
115
204
|
*
|
|
116
|
-
* @throws
|
|
205
|
+
* @throws 如果传入无效的表达式或未定义的变量引用
|
|
117
206
|
*
|
|
118
207
|
* @example
|
|
119
208
|
* ```ts
|
|
120
|
-
* const x = variable
|
|
121
|
-
* const y = variable
|
|
122
|
-
* const sum = expr({ x, y })
|
|
123
|
-
* const result = expr({ sum })
|
|
209
|
+
* const x = variable<number>()
|
|
210
|
+
* const y = variable<number>()
|
|
211
|
+
* const sum = expr({ x, y })("x + y")
|
|
212
|
+
* const result = expr({ sum, x })("sum * x")
|
|
124
213
|
* const compiled = compile(result, { x, y })
|
|
125
|
-
* // => [["x", "y"], "($0+$1)
|
|
214
|
+
* // => [["x", "y"], "($0+$1)*$0"]
|
|
126
215
|
* ```
|
|
127
216
|
*/
|
|
128
|
-
declare function compile<TResult>(expression:
|
|
129
|
-
//#endregion
|
|
130
|
-
//#region src/constant.d.ts
|
|
131
|
-
/**
|
|
132
|
-
* JSON 可序列化的值类型
|
|
133
|
-
*/
|
|
134
|
-
type JsonValue = string | number | boolean | null | JsonValue[] | {
|
|
135
|
-
[key: string]: JsonValue;
|
|
136
|
-
};
|
|
137
|
-
/**
|
|
138
|
-
* 创建一个编译期常量表达式
|
|
139
|
-
*
|
|
140
|
-
* 这是 `expr({})(JSON.stringify(value))` 的快速路径,
|
|
141
|
-
* 用于在表达式中嵌入静态值,避免在运行时传入或在多处重复编写。
|
|
142
|
-
*
|
|
143
|
-
* @template T - 常量值类型(必须是 JSON 可序列化的)
|
|
144
|
-
* @param value - 要嵌入的常量值
|
|
145
|
-
* @returns 返回一个 Expression 对象,其结果类型为 T
|
|
146
|
-
*
|
|
147
|
-
* @example
|
|
148
|
-
* ```ts
|
|
149
|
-
* // 创建一个数字常量
|
|
150
|
-
* const PI = constant(3.14159)
|
|
151
|
-
*
|
|
152
|
-
* // 创建一个字符串常量
|
|
153
|
-
* const greeting = constant("Hello, World!")
|
|
154
|
-
*
|
|
155
|
-
* // 创建一个对象常量
|
|
156
|
-
* const config = constant({ maxRetries: 3, timeout: 5000 })
|
|
157
|
-
*
|
|
158
|
-
* // 在表达式中使用常量
|
|
159
|
-
* const radius = variable(z.number())
|
|
160
|
-
* const area = expr({ PI, radius })("PI * radius * radius")
|
|
161
|
-
* ```
|
|
162
|
-
*/
|
|
163
|
-
declare function constant<const T extends JsonValue>(value: T): Expression<{}, T>;
|
|
217
|
+
declare function compile<TResult>(expression: LambdaBodyResult<TResult>, variables: Record<string, unknown>, options?: CompileOptions): CompiledData;
|
|
164
218
|
//#endregion
|
|
165
219
|
//#region src/evaluate.d.ts
|
|
166
220
|
/**
|
|
@@ -357,29 +411,12 @@ type ExpressionType<Source extends string, TContext> = ValidateExpression<Source
|
|
|
357
411
|
//#endregion
|
|
358
412
|
//#region src/expr.d.ts
|
|
359
413
|
/**
|
|
360
|
-
*
|
|
361
|
-
|
|
362
|
-
type ExprContext = Record<string, Variable | Expression<Record<string, unknown>, unknown>>;
|
|
363
|
-
/**
|
|
364
|
-
* 表达式错误类型
|
|
365
|
-
*/
|
|
366
|
-
type ExprError<Msg extends string, Details = unknown> = {
|
|
367
|
-
readonly __error: Msg;
|
|
368
|
-
readonly __details: Details;
|
|
369
|
-
};
|
|
370
|
-
/**
|
|
371
|
-
* 验证结果处理:如果验证失败返回错误类型,否则返回推导的结果类型
|
|
372
|
-
*/
|
|
373
|
-
type ExprResult<Source extends string, TContext extends ExprContext> = ValidateExpression<Source, TContext> extends true ? InferExpressionResult<Source, TContext> : ValidateExpression<Source, TContext> extends {
|
|
374
|
-
error: "undefined_identifiers";
|
|
375
|
-
identifiers: infer Ids;
|
|
376
|
-
} ? ExprError<"Undefined identifiers in expression", Ids> : ExprError<"Expression validation failed", ValidateExpression<Source, TContext>>;
|
|
377
|
-
/**
|
|
378
|
-
* 创建一个表达式,支持编译时类型检查和返回类型自动推导
|
|
414
|
+
* 创建表达式
|
|
415
|
+
* 返回 Proxy Expression,可以继续链式调用
|
|
379
416
|
*
|
|
380
|
-
* @template TContext -
|
|
381
|
-
* @param context - 包含 Variable 或 Expression 的上下文对象
|
|
382
|
-
* @returns 返回一个函数,该函数接收表达式源码字符串并返回 Expression
|
|
417
|
+
* @template TContext - 表达式上下文类型
|
|
418
|
+
* @param context - 包含 Variable 或 Proxy Expression 的上下文对象
|
|
419
|
+
* @returns 返回一个函数,该函数接收表达式源码字符串并返回 Proxy Expression
|
|
383
420
|
*
|
|
384
421
|
* 类型系统会:
|
|
385
422
|
* 1. 验证表达式中使用的所有标识符都在 context 中定义
|
|
@@ -387,8 +424,8 @@ type ExprResult<Source extends string, TContext extends ExprContext> = ValidateE
|
|
|
387
424
|
*
|
|
388
425
|
* @example
|
|
389
426
|
* ```ts
|
|
390
|
-
* const x = variable
|
|
391
|
-
* const y = variable
|
|
427
|
+
* const x = variable<number>();
|
|
428
|
+
* const y = variable<number>();
|
|
392
429
|
*
|
|
393
430
|
* // 自动推导返回类型为 number
|
|
394
431
|
* const sum = expr({ x, y })("x + y")
|
|
@@ -400,26 +437,78 @@ type ExprResult<Source extends string, TContext extends ExprContext> = ValidateE
|
|
|
400
437
|
* // const invalid = expr({ x, y })("x + z")
|
|
401
438
|
* ```
|
|
402
439
|
*/
|
|
403
|
-
declare function expr<TContext extends
|
|
440
|
+
declare function expr<TContext extends Record<string, unknown>>(context: TContext): <TSource extends string>(source: ValidateExpression<TSource, TContext> extends never ? never : TSource) => Proxify<InferExpressionResult<TSource, TContext>>;
|
|
441
|
+
//#endregion
|
|
442
|
+
//#region src/lambda.d.ts
|
|
443
|
+
/**
|
|
444
|
+
* 创建类型安全的 lambda 表达式
|
|
445
|
+
*
|
|
446
|
+
* @template Args - 参数类型元组
|
|
447
|
+
* @template R - 返回值类型
|
|
448
|
+
* @param builder - Lambda 构建函数,接收参数代理,返回函数体表达式
|
|
449
|
+
* @returns Lambda 表达式代理
|
|
450
|
+
*
|
|
451
|
+
* @example
|
|
452
|
+
* ```ts
|
|
453
|
+
* const add = lambda<[number, number], number>(
|
|
454
|
+
* (a, b) => expr({ a, b })("a + b")
|
|
455
|
+
* );
|
|
456
|
+
*
|
|
457
|
+
* const numbers = variable<number[]>();
|
|
458
|
+
* const sum = numbers.reduce(add, 0);
|
|
459
|
+
* ```
|
|
460
|
+
*/
|
|
461
|
+
declare function lambda<Args extends unknown[], R>(builder: LambdaBuilder<Args, R>): Lambda<Args, R>;
|
|
462
|
+
//#endregion
|
|
463
|
+
//#region src/proxy-metadata.d.ts
|
|
464
|
+
/**
|
|
465
|
+
* 检查对象是否是 Proxy variable
|
|
466
|
+
*/
|
|
467
|
+
declare function isProxyVariable(obj: unknown): obj is object;
|
|
468
|
+
/**
|
|
469
|
+
* 检查对象是否是 Proxy expression
|
|
470
|
+
*/
|
|
471
|
+
declare function isProxyExpression(obj: unknown): obj is object;
|
|
472
|
+
/**
|
|
473
|
+
* 检查对象是否是任意 Proxy (variable 或 expression)
|
|
474
|
+
*/
|
|
475
|
+
declare function isProxy(obj: unknown): obj is object;
|
|
476
|
+
//#endregion
|
|
477
|
+
//#region src/template.d.ts
|
|
478
|
+
/**
|
|
479
|
+
* Tagged template 函数,用于创建包含变量的字符串表达式
|
|
480
|
+
*
|
|
481
|
+
* @example
|
|
482
|
+
* ```ts
|
|
483
|
+
* const name = variable<string>();
|
|
484
|
+
* const count = variable<number>();
|
|
485
|
+
*
|
|
486
|
+
* const greeting = t`Hello, ${name}!`;
|
|
487
|
+
* const message = t`You have ${count} items.`;
|
|
488
|
+
*
|
|
489
|
+
* const compiled = compile(greeting, { name });
|
|
490
|
+
* const result = evaluate(compiled, { name: "Alice" }); // => "Hello, Alice!"
|
|
491
|
+
* ```
|
|
492
|
+
*/
|
|
493
|
+
declare function t(strings: TemplateStringsArray, ...values: unknown[]): Proxify<string>;
|
|
404
494
|
//#endregion
|
|
405
495
|
//#region src/variable.d.ts
|
|
406
496
|
/**
|
|
407
497
|
* 创建一个类型化变量
|
|
408
|
-
*
|
|
409
|
-
* @template T - 变量的值类型
|
|
410
|
-
* @returns 返回 Variable 对象,包含 _tag 标记
|
|
498
|
+
* 返回 Proxy 对象,支持链式属性访问和方法调用
|
|
411
499
|
*
|
|
412
500
|
* @example
|
|
413
501
|
* ```ts
|
|
414
|
-
* const x = variable<number>()
|
|
415
|
-
* const
|
|
416
|
-
* const
|
|
417
|
-
* count: number,
|
|
418
|
-
* enabled: boolean
|
|
419
|
-
* }>()
|
|
502
|
+
* const x = variable<number>();
|
|
503
|
+
* const config = variable<{ timeout: number }>();
|
|
504
|
+
* const timeout = config.timeout; // Proxy expression
|
|
420
505
|
* ```
|
|
421
506
|
*/
|
|
422
507
|
declare function variable<T>(): Variable<T>;
|
|
508
|
+
/**
|
|
509
|
+
* 获取 variable 的唯一 Symbol ID
|
|
510
|
+
*/
|
|
511
|
+
declare function getVariableId(variable: unknown): symbol | undefined;
|
|
423
512
|
//#endregion
|
|
424
|
-
export { type BranchNode, type CompileContext, type CompileOptions, type CompiledData, type CompiledExpression, type ContextTypeMap, type ControlFlowNode, type ExprNode, type Expression, type ExpressionType, type ExtractType, type InferContextType, type InferExpressionResult, type InferExpressionType, type InferVariableType, type JumpNode, type ParseExpression, type PhiNode, type ValidateExpression, type Variable, compile,
|
|
513
|
+
export { type BranchNode, type CompileContext, type CompileOptions, type CompiledData, type CompiledExpression, type ContextTypeMap, type ControlFlowNode, type ExprNode, type Expression, type ExpressionType, type ExtractType, type FilterCallback, type FindCallback, type InferContextType, type InferExpressionResult, type InferExpressionType, type InferLambdaArgs, type InferLambdaReturn, type InferVariableType, type JumpNode, type Lambda, type LambdaBuilder, type LambdaParam, type MapCallback, type ParseExpression, type PhiNode, type Proxify, type ProxyExpression, type ReduceCallback, type SortCallback, type ValidateExpression, type Variable, compile, evaluate, expr, getVariableId, isProxy, isProxyExpression, isProxyVariable, lambda, t, variable };
|
|
425
514
|
//# sourceMappingURL=index.d.mts.map
|