@codehz/json-expr 0.2.1 → 0.4.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 +93 -83
- package/dist/index.d.mts +86 -103
- package/dist/index.mjs +363 -292
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -4
package/README.md
CHANGED
|
@@ -6,12 +6,13 @@
|
|
|
6
6
|
|
|
7
7
|
## 特性
|
|
8
8
|
|
|
9
|
-
- 🎯 **类型安全** - 使用 TypeScript
|
|
9
|
+
- 🎯 **类型安全** - 使用 TypeScript 泛型进行完整的编译时类型推导
|
|
10
10
|
- 📦 **可序列化** - 编译后的表达式为纯 JSON 格式,易于传输和存储
|
|
11
11
|
- 🔧 **灵活的表达式** - 支持任意 JavaScript 表达式,包括函数调用和对象属性访问
|
|
12
|
-
- ⚡ **高性能** -
|
|
12
|
+
- ⚡ **高性能** - 优化的表达式编译和执行
|
|
13
13
|
- 🧩 **可组合** - 表达式可以相互组合,形成复杂的计算树
|
|
14
|
-
-
|
|
14
|
+
- 🔄 **短路求值** - 支持 `&&`、`||`、`??` 和三元表达式的控制流优化
|
|
15
|
+
- 📝 **内联优化** - 自动内联只被引用一次的子表达式
|
|
15
16
|
|
|
16
17
|
## 快速开始
|
|
17
18
|
|
|
@@ -24,12 +25,11 @@ bun install @codehz/json-expr
|
|
|
24
25
|
### 基本用法
|
|
25
26
|
|
|
26
27
|
```typescript
|
|
27
|
-
import {
|
|
28
|
-
import { variable, expr, compile, evaluate, constant } from "@codehz/json-expr";
|
|
28
|
+
import { variable, expr, compile, evaluate } from "@codehz/json-expr";
|
|
29
29
|
|
|
30
|
-
//
|
|
31
|
-
const x = variable
|
|
32
|
-
const y = variable
|
|
30
|
+
// 定义类型化变量(使用 TypeScript 泛型)
|
|
31
|
+
const x = variable<number>();
|
|
32
|
+
const y = variable<number>();
|
|
33
33
|
|
|
34
34
|
// 构建表达式
|
|
35
35
|
const sum = expr({ x, y })("x + y");
|
|
@@ -49,17 +49,15 @@ const value = evaluate(compiled, { x: 2, y: 3 });
|
|
|
49
49
|
|
|
50
50
|
### Variable(变量)
|
|
51
51
|
|
|
52
|
-
|
|
52
|
+
变量是表达式中的占位符,使用 TypeScript 泛型定义其类型。
|
|
53
53
|
|
|
54
54
|
```typescript
|
|
55
|
-
const age = variable
|
|
56
|
-
const name = variable
|
|
57
|
-
const config = variable
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
})
|
|
62
|
-
);
|
|
55
|
+
const age = variable<number>();
|
|
56
|
+
const name = variable<string>();
|
|
57
|
+
const config = variable<{
|
|
58
|
+
debug: boolean;
|
|
59
|
+
timeout: number;
|
|
60
|
+
}>();
|
|
63
61
|
```
|
|
64
62
|
|
|
65
63
|
### Expression(表达式)
|
|
@@ -67,8 +65,8 @@ const config = variable(
|
|
|
67
65
|
表达式对变量或其他表达式进行运算,使用字符串形式描述。
|
|
68
66
|
|
|
69
67
|
```typescript
|
|
70
|
-
const x = variable
|
|
71
|
-
const y = variable
|
|
68
|
+
const x = variable<number>();
|
|
69
|
+
const y = variable<number>();
|
|
72
70
|
|
|
73
71
|
// 简单表达式
|
|
74
72
|
const sum = expr({ x, y })("x + y");
|
|
@@ -93,51 +91,23 @@ const compiled = compile(result, { x, y });
|
|
|
93
91
|
|
|
94
92
|
## API 参考
|
|
95
93
|
|
|
96
|
-
### `
|
|
97
|
-
|
|
98
|
-
创建一个编译期常量表达式。这是 `expr({})(JSON.stringify(value))` 的快速路径,用于在表达式中嵌入静态值,避免在运行时传入或在多处重复编写。
|
|
99
|
-
|
|
100
|
-
**参数:**
|
|
101
|
-
|
|
102
|
-
- `value` - 要嵌入的常量值(必须是 JSON 可序列化的:string、number、boolean、null、数组或对象)
|
|
103
|
-
|
|
104
|
-
**返回值:** Expression 对象
|
|
105
|
-
|
|
106
|
-
**示例:**
|
|
107
|
-
|
|
108
|
-
```typescript
|
|
109
|
-
import { constant, expr, variable, compile, evaluate } from "@codehz/json-expr";
|
|
110
|
-
import { z } from "zod";
|
|
111
|
-
|
|
112
|
-
// 创建常量
|
|
113
|
-
const PI = constant(3.14159);
|
|
114
|
-
const config = constant({ maxRetries: 3, timeout: 5000 });
|
|
115
|
-
|
|
116
|
-
// 在表达式中使用常量
|
|
117
|
-
const radius = variable(z.number());
|
|
118
|
-
const area = expr({ PI, radius })("PI * radius * radius");
|
|
119
|
-
|
|
120
|
-
const compiled = compile(area, { radius });
|
|
121
|
-
const result = evaluate(compiled, { radius: 2 });
|
|
122
|
-
// => 12.56636
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
### `variable<T>(schema: T): Variable<T>`
|
|
94
|
+
### `variable<T>(): Variable<T>`
|
|
126
95
|
|
|
127
96
|
创建一个类型化变量。
|
|
128
97
|
|
|
129
|
-
**参数:**
|
|
98
|
+
**参数:** 无(类型通过泛型参数 `T` 指定)
|
|
130
99
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
**返回值:** Variable 对象
|
|
100
|
+
**返回值:** Variable 对象,支持属性访问和方法调用
|
|
134
101
|
|
|
135
102
|
**示例:**
|
|
136
103
|
|
|
137
104
|
```typescript
|
|
138
|
-
const num = variable
|
|
139
|
-
const str = variable
|
|
140
|
-
const
|
|
105
|
+
const num = variable<number>();
|
|
106
|
+
const str = variable<string>();
|
|
107
|
+
const config = variable<{ timeout: number }>();
|
|
108
|
+
|
|
109
|
+
// 支持链式属性访问
|
|
110
|
+
const timeout = config.timeout; // 自动转换为表达式
|
|
141
111
|
```
|
|
142
112
|
|
|
143
113
|
### `expr<TContext>(context: TContext): (source: string) => Expression<TContext, TResult>`
|
|
@@ -153,21 +123,21 @@ const date = variable(z.date());
|
|
|
153
123
|
**示例:**
|
|
154
124
|
|
|
155
125
|
```typescript
|
|
156
|
-
const x = variable
|
|
157
|
-
const y = variable
|
|
126
|
+
const x = variable<number>();
|
|
127
|
+
const y = variable<number>();
|
|
158
128
|
|
|
159
129
|
const sum = expr({ x, y })("x + y");
|
|
160
130
|
const result = expr({ sum, x })("sum * x");
|
|
161
131
|
```
|
|
162
132
|
|
|
163
|
-
### `compile<TResult>(expression: Expression<any, TResult>, variables: Record<string, Variable<any
|
|
133
|
+
### `compile<TResult>(expression: Expression<any, TResult>, variables: Record<string, Variable<any>> | Variable<any>[], options?: CompileOptions): CompiledData`
|
|
164
134
|
|
|
165
135
|
将表达式树编译为可序列化的 JSON 结构。
|
|
166
136
|
|
|
167
137
|
**参数:**
|
|
168
138
|
|
|
169
139
|
- `expression` - 要编译的表达式
|
|
170
|
-
- `variables` -
|
|
140
|
+
- `variables` - 表达式中使用的所有变量映射或数组
|
|
171
141
|
- `options` - 编译选项(可选)
|
|
172
142
|
- `inline?: boolean` - 是否启用内联优化,将只被引用一次的子表达式内联到使用位置(默认:true)
|
|
173
143
|
- `shortCircuit?: boolean` - 是否启用短路求值,为 &&, ||, ??, 和三元表达式生成控制流节点(默认:true)
|
|
@@ -177,14 +147,14 @@ const result = expr({ sum, x })("sum * x");
|
|
|
177
147
|
**示例:**
|
|
178
148
|
|
|
179
149
|
```typescript
|
|
180
|
-
const x = variable
|
|
181
|
-
const y = variable
|
|
150
|
+
const x = variable<number>();
|
|
151
|
+
const y = variable<number>();
|
|
182
152
|
const sum = expr({ x, y })("x + y");
|
|
183
153
|
const product = expr({ x, y })("x * y");
|
|
184
154
|
const result = expr({ sum, product })("sum + product");
|
|
185
155
|
|
|
186
156
|
const compiled = compile(result, { x, y });
|
|
187
|
-
// [["x", "y"], "
|
|
157
|
+
// [["x", "y"], "$0+$1", "$0*$1", "$2+$3"]
|
|
188
158
|
|
|
189
159
|
// 禁用内联优化
|
|
190
160
|
const noInline = compile(result, { x, y }, { inline: false });
|
|
@@ -209,30 +179,66 @@ const noShortCircuit = compile(result, { x, y }, { shortCircuit: false });
|
|
|
209
179
|
**示例:**
|
|
210
180
|
|
|
211
181
|
```typescript
|
|
182
|
+
const x = variable<number>();
|
|
183
|
+
const y = variable<number>();
|
|
184
|
+
const sum = expr({ x, y })("x + y");
|
|
185
|
+
const product = expr({ x, y })("x * y");
|
|
186
|
+
const result = expr({ sum, product })("sum + product");
|
|
187
|
+
|
|
212
188
|
const compiled = compile(result, { x, y });
|
|
213
189
|
const value = evaluate(compiled, { x: 5, y: 3 });
|
|
214
190
|
// => 23 ((5+3) + (5*3) = 8 + 15 = 23)
|
|
215
191
|
```
|
|
216
192
|
|
|
193
|
+
### `t(strings: TemplateStringsArray, ...values: unknown[]): Proxify<string>`
|
|
194
|
+
|
|
195
|
+
使用标签模板函数创建包含变量的字符串表达式。
|
|
196
|
+
|
|
197
|
+
**参数:**
|
|
198
|
+
|
|
199
|
+
- `strings` - 模板字符串的静态部分
|
|
200
|
+
- `values` - 模板中插值的变量和表达式
|
|
201
|
+
|
|
202
|
+
**返回值:** 字符串类型的 Proxy Expression
|
|
203
|
+
|
|
204
|
+
**示例:**
|
|
205
|
+
|
|
206
|
+
```typescript
|
|
207
|
+
const name = variable<string>();
|
|
208
|
+
const count = variable<number>();
|
|
209
|
+
|
|
210
|
+
const greeting = t`Hello, ${name}!`;
|
|
211
|
+
const message = t`You have ${count} items.`;
|
|
212
|
+
|
|
213
|
+
const compiled = compile(greeting, { name });
|
|
214
|
+
const result = evaluate(compiled, { name: "Alice" });
|
|
215
|
+
// => "Hello, Alice!"
|
|
216
|
+
```
|
|
217
|
+
|
|
217
218
|
## 高级用法
|
|
218
219
|
|
|
219
|
-
###
|
|
220
|
+
### 内置全局对象
|
|
220
221
|
|
|
221
|
-
|
|
222
|
+
表达式中可以直接使用以下内置对象(无需在上下文中定义):
|
|
223
|
+
|
|
224
|
+
- `Math`, `JSON`, `Date`, `RegExp`
|
|
225
|
+
- `Number`, `String`, `Boolean`, `Array`, `Object`
|
|
226
|
+
- `undefined`, `NaN`, `Infinity`
|
|
227
|
+
- `isNaN`, `isFinite`, `parseInt`, `parseFloat`
|
|
222
228
|
|
|
223
229
|
```typescript
|
|
224
|
-
const x = variable
|
|
230
|
+
const x = variable<number>();
|
|
225
231
|
|
|
226
|
-
const sqrtExpr = expr({ x
|
|
227
|
-
const compiled = compile(sqrtExpr, { x
|
|
228
|
-
const result = evaluate(compiled, { x: 16
|
|
232
|
+
const sqrtExpr = expr({ x })("Math.sqrt(x)");
|
|
233
|
+
const compiled = compile(sqrtExpr, { x });
|
|
234
|
+
const result = evaluate(compiled, { x: 16 });
|
|
229
235
|
// => 4
|
|
230
236
|
```
|
|
231
237
|
|
|
232
238
|
### 条件表达式
|
|
233
239
|
|
|
234
240
|
```typescript
|
|
235
|
-
const score = variable
|
|
241
|
+
const score = variable<number>();
|
|
236
242
|
const gradeExpr = expr({ score })("score >= 90 ? 'A' : score >= 80 ? 'B' : score >= 70 ? 'C' : 'F'");
|
|
237
243
|
|
|
238
244
|
const compiled = compile(gradeExpr, { score });
|
|
@@ -243,7 +249,7 @@ const grade = evaluate(compiled, { score: 85 });
|
|
|
243
249
|
### 数组和对象操作
|
|
244
250
|
|
|
245
251
|
```typescript
|
|
246
|
-
const numbers = variable
|
|
252
|
+
const numbers = variable<number[]>();
|
|
247
253
|
|
|
248
254
|
const sumExpr = expr({ numbers })("numbers.reduce((a, b) => a + b, 0)");
|
|
249
255
|
|
|
@@ -255,8 +261,8 @@ const sum = evaluate(compiled, { numbers: [1, 2, 3, 4, 5] });
|
|
|
255
261
|
### 链式表达式组合
|
|
256
262
|
|
|
257
263
|
```typescript
|
|
258
|
-
const a = variable
|
|
259
|
-
const b = variable
|
|
264
|
+
const a = variable<number>();
|
|
265
|
+
const b = variable<number>();
|
|
260
266
|
|
|
261
267
|
const sum = expr({ a, b })("a + b");
|
|
262
268
|
const product = expr({ a, b })("a * b");
|
|
@@ -295,11 +301,12 @@ const value = evaluate(deserialized, { x: 5, y: 3 });
|
|
|
295
301
|
项目充分利用 TypeScript 的类型系统进行编译时检查和类型推导:
|
|
296
302
|
|
|
297
303
|
```typescript
|
|
298
|
-
const x = variable
|
|
299
|
-
const y = variable
|
|
304
|
+
const x = variable<number>();
|
|
305
|
+
const y = variable<string>();
|
|
300
306
|
|
|
301
|
-
//
|
|
302
|
-
const
|
|
307
|
+
// 类型错误会在编译时捕获
|
|
308
|
+
// const invalid = expr({ x, y })("z + y"); // Error: 'z' not in context
|
|
309
|
+
const valid = expr({ x })("-x"); // 编译器推导为 number
|
|
303
310
|
```
|
|
304
311
|
|
|
305
312
|
## 性能考虑
|
|
@@ -313,12 +320,15 @@ const sum = expr({ x, y })("x + y");
|
|
|
313
320
|
```
|
|
314
321
|
src/
|
|
315
322
|
├── index.ts # 导出入口
|
|
316
|
-
├── variable.ts # variable
|
|
317
|
-
├── expr.ts # expr
|
|
318
|
-
├──
|
|
319
|
-
├──
|
|
320
|
-
├──
|
|
321
|
-
├──
|
|
323
|
+
├── variable.ts # variable<T>() 函数
|
|
324
|
+
├── expr.ts # expr() 函数
|
|
325
|
+
├── template.ts # t() 标签模板函数
|
|
326
|
+
├── compile.ts # 编译器(内联优化、短路求值)
|
|
327
|
+
├── evaluate.ts # 运行时求值
|
|
328
|
+
├── parser.ts # 表达式 AST 解析器
|
|
329
|
+
├── type-parser.ts # TypeScript 类型级表达式解析
|
|
330
|
+
├── proxy-variable.ts # Proxy 变量实现
|
|
331
|
+
├── proxy-metadata.ts # Proxy 元数据管理
|
|
322
332
|
├── types.ts # 类型定义
|
|
323
333
|
└── *.test.ts # 测试文件
|
|
324
334
|
```
|
package/dist/index.d.mts
CHANGED
|
@@ -1,19 +1,35 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
|
-
|
|
3
1
|
//#region src/types.d.ts
|
|
4
2
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
3
|
+
* Proxy Expression 类型标记(用于类型推导)
|
|
4
|
+
* 这是一个 phantom type,实际运行时是 Proxy 对象
|
|
7
5
|
*/
|
|
8
|
-
type
|
|
9
|
-
|
|
10
|
-
schema: T;
|
|
11
|
-
_type: z.infer<T>;
|
|
6
|
+
type ProxyExpression<T = unknown> = {
|
|
7
|
+
readonly __proxyExpression: T;
|
|
12
8
|
};
|
|
9
|
+
/**
|
|
10
|
+
* 处理函数参数的 Proxy 转换
|
|
11
|
+
* 参数可以是原始值或对应的 Proxy
|
|
12
|
+
*/
|
|
13
|
+
type ProxifyArgs<T extends unknown[]> = { [K in keyof T]: T[K] | Proxify<T[K]> };
|
|
14
|
+
/**
|
|
15
|
+
* 将类型 T 转换为 Proxy 包装类型
|
|
16
|
+
* - 始终包含 ProxyExpression<T> 标记,用于 compile 函数类型检查
|
|
17
|
+
* - 函数类型:保持函数签名,但参数允许 Proxy 或原始值,返回值递归应用 Proxify
|
|
18
|
+
* - 对象类型:映射所有属性为 Proxify
|
|
19
|
+
* - 原始类型:保持不变(返回 ProxyExpression 包装)
|
|
20
|
+
*/
|
|
21
|
+
type Proxify<T> = ProxyExpression<T> & (T extends ((...args: infer Args) => infer R) ? (...args: ProxifyArgs<Args>) => Proxify<R> : T extends object ? { [K in keyof T]: Proxify<T[K]> } : unknown);
|
|
22
|
+
/**
|
|
23
|
+
* Variable 类型定义
|
|
24
|
+
* 总是返回 Proxy 包装后的类型
|
|
25
|
+
* @template T - 变量的值类型
|
|
26
|
+
*/
|
|
27
|
+
type Variable<T = unknown> = Proxify<T>;
|
|
13
28
|
/**
|
|
14
29
|
* 表示一个表达式
|
|
15
30
|
* @template TContext - 表达式上下文类型
|
|
16
31
|
* @template TResult - 表达式结果类型
|
|
32
|
+
* @deprecated 请使用新的 Proxy 类型系统
|
|
17
33
|
*/
|
|
18
34
|
type Expression<TContext = Record<string, unknown>, TResult = unknown> = {
|
|
19
35
|
_tag: "expression";
|
|
@@ -58,7 +74,6 @@ type CompiledData = [variableNames: string[], ...expressions: CompiledExpression
|
|
|
58
74
|
interface ExprNode {
|
|
59
75
|
id: symbol;
|
|
60
76
|
tag: "variable" | "expression";
|
|
61
|
-
schema?: z.ZodType;
|
|
62
77
|
context?: Record<string, ExprNode>;
|
|
63
78
|
source?: string;
|
|
64
79
|
}
|
|
@@ -74,12 +89,12 @@ interface CompileContext {
|
|
|
74
89
|
* 从 Variable 推导值类型
|
|
75
90
|
* @template V - Variable 类型
|
|
76
91
|
*/
|
|
77
|
-
type InferVariableType<V> = V extends Variable<infer T> ?
|
|
92
|
+
type InferVariableType<V> = V extends Variable<infer T> ? T : never;
|
|
78
93
|
/**
|
|
79
94
|
* 从上下文对象推导各项的类型
|
|
80
95
|
* @template C - 上下文对象类型
|
|
81
96
|
*/
|
|
82
|
-
type InferContextType<C> = { [K in keyof C]: C[K] extends Variable<infer T> ?
|
|
97
|
+
type InferContextType<C> = { [K in keyof C]: C[K] extends Variable<infer T> ? T : C[K] extends Expression<unknown, infer R> ? R : never };
|
|
83
98
|
/**
|
|
84
99
|
* 从 Expression 推导结果类型
|
|
85
100
|
* @template E - Expression 类型
|
|
@@ -91,12 +106,6 @@ type InferExpressionType<E> = E extends Expression<unknown, infer R> ? R : never
|
|
|
91
106
|
* 编译选项
|
|
92
107
|
*/
|
|
93
108
|
interface CompileOptions {
|
|
94
|
-
/**
|
|
95
|
-
* 是否启用内联优化
|
|
96
|
-
* 将只被引用一次的子表达式内联到使用位置
|
|
97
|
-
* @default true
|
|
98
|
-
*/
|
|
99
|
-
inline?: boolean;
|
|
100
109
|
/**
|
|
101
110
|
* 是否启用短路求值
|
|
102
111
|
* 为 &&, ||, ??, 和三元表达式生成控制流节点
|
|
@@ -105,66 +114,27 @@ interface CompileOptions {
|
|
|
105
114
|
shortCircuit?: boolean;
|
|
106
115
|
}
|
|
107
116
|
/**
|
|
108
|
-
*
|
|
109
|
-
*/
|
|
110
|
-
type ExpressionContext = Record<string, Variable<z.ZodType> | Expression<Record<string, unknown>, unknown>>;
|
|
111
|
-
/**
|
|
112
|
-
* 将表达式树编译为可序列化的 JSON 结构
|
|
117
|
+
* 将 Proxy Expression 编译为可序列化的 JSON 结构
|
|
113
118
|
*
|
|
114
119
|
* @template TResult - 表达式结果类型
|
|
115
|
-
* @param expression -
|
|
120
|
+
* @param expression - Proxy Expression
|
|
116
121
|
* @param variables - 所有使用的变量定义
|
|
117
122
|
* @param options - 编译选项
|
|
118
123
|
* @returns 编译后的数据结构 [变量名列表, 表达式1, 表达式2, ...]
|
|
119
124
|
*
|
|
120
|
-
* @throws
|
|
125
|
+
* @throws 如果传入无效的表达式或未定义的变量引用
|
|
121
126
|
*
|
|
122
127
|
* @example
|
|
123
128
|
* ```ts
|
|
124
|
-
* const x = variable
|
|
125
|
-
* const y = variable
|
|
126
|
-
* const sum = expr({ x, y })
|
|
127
|
-
* const result = expr({ sum })
|
|
129
|
+
* const x = variable<number>()
|
|
130
|
+
* const y = variable<number>()
|
|
131
|
+
* const sum = expr({ x, y })("x + y")
|
|
132
|
+
* const result = expr({ sum, x })("sum * x")
|
|
128
133
|
* const compiled = compile(result, { x, y })
|
|
129
|
-
* // => [["x", "y"], "($0+$1)
|
|
130
|
-
* ```
|
|
131
|
-
*/
|
|
132
|
-
declare function compile<TResult>(expression: Expression<ExpressionContext, TResult>, variables: Record<string, Variable<z.ZodType>>, options?: CompileOptions): CompiledData;
|
|
133
|
-
//#endregion
|
|
134
|
-
//#region src/constant.d.ts
|
|
135
|
-
/**
|
|
136
|
-
* JSON 可序列化的值类型
|
|
137
|
-
*/
|
|
138
|
-
type JsonValue = string | number | boolean | null | JsonValue[] | {
|
|
139
|
-
[key: string]: JsonValue;
|
|
140
|
-
};
|
|
141
|
-
/**
|
|
142
|
-
* 创建一个编译期常量表达式
|
|
143
|
-
*
|
|
144
|
-
* 这是 `expr({})(JSON.stringify(value))` 的快速路径,
|
|
145
|
-
* 用于在表达式中嵌入静态值,避免在运行时传入或在多处重复编写。
|
|
146
|
-
*
|
|
147
|
-
* @template T - 常量值类型(必须是 JSON 可序列化的)
|
|
148
|
-
* @param value - 要嵌入的常量值
|
|
149
|
-
* @returns 返回一个 Expression 对象,其结果类型为 T
|
|
150
|
-
*
|
|
151
|
-
* @example
|
|
152
|
-
* ```ts
|
|
153
|
-
* // 创建一个数字常量
|
|
154
|
-
* const PI = constant(3.14159)
|
|
155
|
-
*
|
|
156
|
-
* // 创建一个字符串常量
|
|
157
|
-
* const greeting = constant("Hello, World!")
|
|
158
|
-
*
|
|
159
|
-
* // 创建一个对象常量
|
|
160
|
-
* const config = constant({ maxRetries: 3, timeout: 5000 })
|
|
161
|
-
*
|
|
162
|
-
* // 在表达式中使用常量
|
|
163
|
-
* const radius = variable(z.number())
|
|
164
|
-
* const area = expr({ PI, radius })("PI * radius * radius")
|
|
134
|
+
* // => [["x", "y"], "($0+$1)*$0"]
|
|
165
135
|
* ```
|
|
166
136
|
*/
|
|
167
|
-
declare function
|
|
137
|
+
declare function compile<TResult>(expression: ProxyExpression<TResult>, variables: Record<string, unknown>, options?: CompileOptions): CompiledData;
|
|
168
138
|
//#endregion
|
|
169
139
|
//#region src/evaluate.d.ts
|
|
170
140
|
/**
|
|
@@ -216,7 +186,7 @@ type SkipTemplateStringContent<S extends string> = S extends `\\\`${infer Rest}`
|
|
|
216
186
|
*/
|
|
217
187
|
type ExtractIdentifiers<S extends string, Collected extends string = never> = S extends "" ? Collected : TrimStart<S> extends `${infer Trimmed}` ? Trimmed extends "" ? Collected : Trimmed extends `'${string}` ? ExtractIdentifiers<SkipSingleQuoteString<Trimmed>, Collected> : Trimmed extends `"${string}` ? ExtractIdentifiers<SkipDoubleQuoteString<Trimmed>, Collected> : Trimmed extends `\`${string}` ? ExtractIdentifiers<SkipTemplateString<Trimmed>, Collected> : Trimmed extends `${infer First}${infer Rest}` ? IsIdentifierStart<First> extends true ? ParseIdentifier<Trimmed> extends [infer Id extends string, infer Remaining extends string] ? Id extends ReservedWords ? ExtractIdentifiers<Remaining, Collected> : ExtractIdentifiers<Remaining, Collected | Id> : Collected : IsDigit<First> extends true ? ExtractIdentifiers<SkipNumber<Trimmed>, Collected> : ExtractIdentifiers<Rest, Collected> : Collected : Collected;
|
|
218
188
|
/** 从 Variable 或 Expression 提取值类型 */
|
|
219
|
-
type ExtractType<T> = T extends Variable<infer
|
|
189
|
+
type ExtractType<T> = T extends Variable<infer V> ? V : T extends Expression<unknown, infer R> ? R : never;
|
|
220
190
|
/** 从上下文对象构建类型映射 */
|
|
221
191
|
type ContextTypeMap<TContext> = { [K in keyof TContext]: ExtractType<TContext[K]> };
|
|
222
192
|
/** 找出未定义的标识符 */
|
|
@@ -361,29 +331,12 @@ type ExpressionType<Source extends string, TContext> = ValidateExpression<Source
|
|
|
361
331
|
//#endregion
|
|
362
332
|
//#region src/expr.d.ts
|
|
363
333
|
/**
|
|
364
|
-
*
|
|
365
|
-
|
|
366
|
-
type ExprContext = Record<string, Variable<z.ZodType> | Expression<Record<string, unknown>, unknown>>;
|
|
367
|
-
/**
|
|
368
|
-
* 表达式错误类型
|
|
369
|
-
*/
|
|
370
|
-
type ExprError<Msg extends string, Details = unknown> = {
|
|
371
|
-
readonly __error: Msg;
|
|
372
|
-
readonly __details: Details;
|
|
373
|
-
};
|
|
374
|
-
/**
|
|
375
|
-
* 验证结果处理:如果验证失败返回错误类型,否则返回推导的结果类型
|
|
376
|
-
*/
|
|
377
|
-
type ExprResult<Source extends string, TContext extends ExprContext> = ValidateExpression<Source, TContext> extends true ? InferExpressionResult<Source, TContext> : ValidateExpression<Source, TContext> extends {
|
|
378
|
-
error: "undefined_identifiers";
|
|
379
|
-
identifiers: infer Ids;
|
|
380
|
-
} ? ExprError<"Undefined identifiers in expression", Ids> : ExprError<"Expression validation failed", ValidateExpression<Source, TContext>>;
|
|
381
|
-
/**
|
|
382
|
-
* 创建一个表达式,支持编译时类型检查和返回类型自动推导
|
|
334
|
+
* 创建表达式
|
|
335
|
+
* 返回 Proxy Expression,可以继续链式调用
|
|
383
336
|
*
|
|
384
|
-
* @template TContext -
|
|
385
|
-
* @param context - 包含 Variable 或 Expression 的上下文对象
|
|
386
|
-
* @returns 返回一个函数,该函数接收表达式源码字符串并返回 Expression
|
|
337
|
+
* @template TContext - 表达式上下文类型
|
|
338
|
+
* @param context - 包含 Variable 或 Proxy Expression 的上下文对象
|
|
339
|
+
* @returns 返回一个函数,该函数接收表达式源码字符串并返回 Proxy Expression
|
|
387
340
|
*
|
|
388
341
|
* 类型系统会:
|
|
389
342
|
* 1. 验证表达式中使用的所有标识符都在 context 中定义
|
|
@@ -391,8 +344,8 @@ type ExprResult<Source extends string, TContext extends ExprContext> = ValidateE
|
|
|
391
344
|
*
|
|
392
345
|
* @example
|
|
393
346
|
* ```ts
|
|
394
|
-
* const x = variable
|
|
395
|
-
* const y = variable
|
|
347
|
+
* const x = variable<number>();
|
|
348
|
+
* const y = variable<number>();
|
|
396
349
|
*
|
|
397
350
|
* // 自动推导返回类型为 number
|
|
398
351
|
* const sum = expr({ x, y })("x + y")
|
|
@@ -404,27 +357,57 @@ type ExprResult<Source extends string, TContext extends ExprContext> = ValidateE
|
|
|
404
357
|
* // const invalid = expr({ x, y })("x + z")
|
|
405
358
|
* ```
|
|
406
359
|
*/
|
|
407
|
-
declare function expr<TContext extends
|
|
360
|
+
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>>;
|
|
361
|
+
//#endregion
|
|
362
|
+
//#region src/proxy-metadata.d.ts
|
|
363
|
+
/**
|
|
364
|
+
* 检查对象是否是 Proxy variable
|
|
365
|
+
*/
|
|
366
|
+
declare function isProxyVariable(obj: unknown): obj is object;
|
|
367
|
+
/**
|
|
368
|
+
* 检查对象是否是 Proxy expression
|
|
369
|
+
*/
|
|
370
|
+
declare function isProxyExpression(obj: unknown): obj is object;
|
|
371
|
+
/**
|
|
372
|
+
* 检查对象是否是任意 Proxy (variable 或 expression)
|
|
373
|
+
*/
|
|
374
|
+
declare function isProxy(obj: unknown): obj is object;
|
|
375
|
+
//#endregion
|
|
376
|
+
//#region src/template.d.ts
|
|
377
|
+
/**
|
|
378
|
+
* Tagged template 函数,用于创建包含变量的字符串表达式
|
|
379
|
+
*
|
|
380
|
+
* @example
|
|
381
|
+
* ```ts
|
|
382
|
+
* const name = variable<string>();
|
|
383
|
+
* const count = variable<number>();
|
|
384
|
+
*
|
|
385
|
+
* const greeting = t`Hello, ${name}!`;
|
|
386
|
+
* const message = t`You have ${count} items.`;
|
|
387
|
+
*
|
|
388
|
+
* const compiled = compile(greeting, { name });
|
|
389
|
+
* const result = evaluate(compiled, { name: "Alice" }); // => "Hello, Alice!"
|
|
390
|
+
* ```
|
|
391
|
+
*/
|
|
392
|
+
declare function t(strings: TemplateStringsArray, ...values: unknown[]): Proxify<string>;
|
|
408
393
|
//#endregion
|
|
409
394
|
//#region src/variable.d.ts
|
|
410
395
|
/**
|
|
411
396
|
* 创建一个类型化变量
|
|
412
|
-
*
|
|
413
|
-
* @template T - Zod schema 类型
|
|
414
|
-
* @param schema - Zod schema 对象,定义变量的类型和验证规则
|
|
415
|
-
* @returns 返回 Variable 对象,包含 _tag 标记和 schema
|
|
397
|
+
* 返回 Proxy 对象,支持链式属性访问和方法调用
|
|
416
398
|
*
|
|
417
399
|
* @example
|
|
418
400
|
* ```ts
|
|
419
|
-
* const x = variable
|
|
420
|
-
* const
|
|
421
|
-
* const
|
|
422
|
-
* count: z.number(),
|
|
423
|
-
* enabled: z.boolean()
|
|
424
|
-
* }))
|
|
401
|
+
* const x = variable<number>();
|
|
402
|
+
* const config = variable<{ timeout: number }>();
|
|
403
|
+
* const timeout = config.timeout; // Proxy expression
|
|
425
404
|
* ```
|
|
426
405
|
*/
|
|
427
|
-
declare function variable<T
|
|
406
|
+
declare function variable<T>(): Variable<T>;
|
|
407
|
+
/**
|
|
408
|
+
* 获取 variable 的唯一 Symbol ID
|
|
409
|
+
*/
|
|
410
|
+
declare function getVariableId(variable: unknown): symbol | undefined;
|
|
428
411
|
//#endregion
|
|
429
|
-
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,
|
|
412
|
+
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 Proxify, type ProxyExpression, type ValidateExpression, type Variable, compile, evaluate, expr, getVariableId, isProxy, isProxyExpression, isProxyVariable, t, variable };
|
|
430
413
|
//# sourceMappingURL=index.d.mts.map
|