@choiceform/expr-engine
v0.0.3
Published
A high-performance JavaScript expression runtime engine with modular architecture and full TypeScript support
Readme
Expression Runtime
English
A high-performance JavaScript expression runtime engine that supports dynamic expression parsing, compilation, and execution. Features modular architecture design with complete TypeScript type support.
Project Structure
expression-runtime/
├── lib/
│ ├── runtime/ # Runtime engine
│ │ └── engine.ts # Main engine class (ExpressionEngine)
│ ├── compiler/ # Compiler module
│ │ ├── code-generator.ts # Code generator
│ │ └── transformer.ts # AST transformer
│ ├── parser/ # Parser module
│ │ ├── tokenizer.ts # Expression tokenizer
│ │ └── ast-parser.ts # AST parser
│ ├── evaluator/ # Evaluator module
│ │ └── function-executor.ts # Function executor
│ └── types/ # Type definitions
│ ├── ast.ts # AST related types
│ ├── expression.ts # Expression related types
│ └── constants.ts # Constant definitions
└── index.ts # Main entry fileCore Features
Modular Architecture
- Parser Module: Handles expression parsing and tokenization, converts strings to AST
- Compiler Module: Handles code generation and AST transformation, optimizes expression execution
- Evaluator Module: Handles expression evaluation, supports custom function executors
- Runtime Module: Provides unified runtime engine interface, simplifies usage
- Types Module: Centralized management of all type definitions, complete TypeScript support
Advanced Features
- ✅ ES6+ syntax support (arrow functions, template strings, destructuring, etc.)
- ✅ AST hooks support for custom compilation pipeline
- ✅ Complete TypeScript type definitions
- ✅ Compatible with riot-tmpl expression syntax
- ✅ Custom error handling support
- ✅ Flexible data context management
Quick Start
Basic Usage
import { ExpressionEngine } from './expression-runtime';
// Create engine instance
const engine = new ExpressionEngine();
// Execute simple expression
engine.execute('{{ 1 + 2 }}', {}); // 3
// Execute expression with data context
engine.execute('{{ user.name }}', { user: { name: 'John' } }); // 'John'
// Execute complex expression
engine.execute('{{ items.map(x => x * 2).join(", ") }}', {
items: [1, 2, 3]
}); // '2, 4, 6'Advanced Configuration
import { ExpressionEngine, FunctionExecutor } from './expression-runtime';
// Custom configuration
const engine = new ExpressionEngine(
// Error handler
(error) => console.error('Expression Error:', error),
// Data context variable name
'___expr_data',
// Function executor
FunctionExecutor,
// AST hooks
{
before: [(ast) => {
// Process AST before compilation
console.log('Before compile:', ast);
return ast;
}],
after: [(ast) => {
// Process AST after compilation
console.log('After compile:', ast);
return ast;
}]
}
);
// Execute expression
const result = engine.execute('{{ user.age >= 18 ? "adult" : "minor" }}', {
user: { age: 20 }
});
console.log(result); // 'adult'Core Modules
ExpressionEngine
Main runtime engine that provides a unified interface for expression execution.
class ExpressionEngine {
constructor(
errorHandler?: (error: Error) => void,
dataContextName?: string,
executorClass?: typeof FunctionExecutor,
astHooks?: { before: AstHook[], after: AstHook[] }
)
execute(expression: string, context: any): any
}FunctionExecutor
Function executor responsible for converting compiled code into executable functions.
class FunctionExecutor {
constructor(
code: string,
dataContextName: string,
errorHandler: (error: Error) => void
)
evaluate(context: any): any
}Expression Syntax
Basic Syntax
// Variable access
'{{ user.name }}'
'{{ user["email"] }}'
// Operators
'{{ a + b }}'
'{{ x > 10 }}'
'{{ flag && result }}'
// Ternary operator
'{{ age >= 18 ? "adult" : "minor" }}'
// Function calls
'{{ Math.max(a, b, c) }}'
'{{ items.filter(x => x > 0) }}'ES6 Features
// Arrow functions
'{{ items.map(x => x * 2) }}'
// Template strings
'{{ `Hello, ${name}!` }}'
// Destructuring
'{{ [first, ...rest] = items }}'
// Spread operator
'{{ [...arr1, ...arr2] }}'Development Notes
Design Principles
- Modularity: Clear module responsibilities, easy to maintain and extend
- Type Safety: Complete TypeScript type definitions
- Extensibility: Support for custom executors and AST hooks
- High Performance: Optimized compilation and execution pipeline
Technical Features
- AST-based expression compilation
- Dynamic code generation support
- Flexible error handling mechanism
- Configurable data context
中文
一个高性能的 JavaScript 表达式运行时引擎,支持动态表达式解析、编译和执行。采用模块化架构设计,提供完整的 TypeScript 类型支持。
项目结构
expression-runtime/
├── lib/
│ ├── runtime/ # 运行时引擎
│ │ └── engine.ts # 主引擎类 (ExpressionEngine)
│ ├── compiler/ # 编译器模块
│ │ ├── code-generator.ts # 代码生成器
│ │ └── transformer.ts # AST 转换器
│ ├── parser/ # 解析器模块
│ │ ├── tokenizer.ts # 表达式分词器
│ │ └── ast-parser.ts # AST 解析器
│ ├── evaluator/ # 求值器模块
│ │ └── function-executor.ts # 函数执行器
│ └── types/ # 类型定义
│ ├── ast.ts # AST 相关类型
│ ├── expression.ts # 表达式相关类型
│ └── constants.ts # 常量定义
└── index.ts # 主入口文件核心特性
模块化架构
- Parser 模块: 负责表达式的解析和分词,将字符串转换为 AST
- Compiler 模块: 负责代码生成和 AST 转换,优化表达式执行
- Evaluator 模块: 负责表达式求值,支持自定义函数执行器
- Runtime 模块: 提供统一的运行时引擎接口,简化使用
- Types 模块: 集中管理所有类型定义,完整的 TypeScript 支持
高级功能
- ✅ 支持 ES6+ 语法(箭头函数、模板字符串、解构等)
- ✅ AST hooks 支持,可自定义编译流程
- ✅ 完整的 TypeScript 类型定义
- ✅ 兼容 riot-tmpl 表达式语法
- ✅ 支持自定义错误处理
- ✅ 灵活的数据上下文管理
快速开始
基本用法
import { ExpressionEngine } from './expression-runtime';
// 创建引擎实例
const engine = new ExpressionEngine();
// 执行简单表达式
engine.execute('{{ 1 + 2 }}', {}); // 3
// 执行带数据上下文的表达式
engine.execute('{{ user.name }}', { user: { name: 'John' } }); // 'John'
// 执行复杂表达式
engine.execute('{{ items.map(x => x * 2).join(", ") }}', {
items: [1, 2, 3]
}); // '2, 4, 6'高级配置
import { ExpressionEngine, FunctionExecutor } from './expression-runtime';
// 自定义配置
const engine = new ExpressionEngine(
// 错误处理函数
(error) => console.error('Expression Error:', error),
// 数据上下文变量名
'___expr_data',
// 函数执行器
FunctionExecutor,
// AST hooks
{
before: [(ast) => {
// 编译前处理 AST
console.log('Before compile:', ast);
return ast;
}],
after: [(ast) => {
// 编译后处理 AST
console.log('After compile:', ast);
return ast;
}]
}
);
// 执行表达式
const result = engine.execute('{{ user.age >= 18 ? "成年" : "未成年" }}', {
user: { age: 20 }
});
console.log(result); // '成年'核心模块说明
ExpressionEngine
主运行时引擎,提供统一的表达式执行接口。
class ExpressionEngine {
constructor(
errorHandler?: (error: Error) => void,
dataContextName?: string,
executorClass?: typeof FunctionExecutor,
astHooks?: { before: AstHook[], after: AstHook[] }
)
execute(expression: string, context: any): any
}FunctionExecutor
函数执行器,负责将编译后的代码转换为可执行函数。
class FunctionExecutor {
constructor(
code: string,
dataContextName: string,
errorHandler: (error: Error) => void
)
evaluate(context: any): any
}表达式语法
基本语法
// 变量访问
'{{ user.name }}'
'{{ user["email"] }}'
// 运算符
'{{ a + b }}'
'{{ x > 10 }}'
'{{ flag && result }}'
// 三元运算符
'{{ age >= 18 ? "adult" : "minor" }}'
// 函数调用
'{{ Math.max(a, b, c) }}'
'{{ items.filter(x => x > 0) }}'ES6 特性
// 箭头函数
'{{ items.map(x => x * 2) }}'
// 模板字符串
'{{ `Hello, ${name}!` }}'
// 解构
'{{ [first, ...rest] = items }}'
// 扩展运算符
'{{ [...arr1, ...arr2] }}'开发说明
设计原则
- 模块化: 各模块职责清晰,易于维护和扩展
- 类型安全: 完整的 TypeScript 类型定义
- 可扩展: 支持自定义执行器和 AST hooks
- 高性能: 优化的编译和执行流程
技术特点
- 基于 AST 的表达式编译
- 支持动态代码生成
- 灵活的错误处理机制
- 可配置的数据上下文
