You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+82-37Lines changed: 82 additions & 37 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,10 +1,18 @@
1
1
# cel-typescript
2
2
3
-
A TypeScript binding for the Common Expression Language (CEL) using [cel-rust](https://github.com/clarkmcc/cel-rust). This project provides a Node.js native module that allows you to use CEL in your TypeScript/JavaScript projects.
3
+
A TypeScript binding for the Common Expression Language (CEL) using
4
+
[cel-rust](https://github.com/clarkmcc/cel-rust). This project provides a
5
+
Node.js native module that allows you to use CEL in your TypeScript/JavaScript
6
+
projects.
4
7
5
8
## What is CEL?
6
9
7
-
[Common Expression Language (CEL)](https://github.com/google/cel-spec) is an expression language created by Google that implements common semantics for expression evaluation. It's a simple language for expressing boolean conditions, calculations, and variable substitutions. CEL is used in various Google products and open-source projects for policy enforcement, configuration validation, and business rule evaluation.
10
+
[Common Expression Language (CEL)](https://github.com/google/cel-spec) is an
11
+
expression language created by Google that implements common semantics for
12
+
expression evaluation. It's a simple language for expressing boolean conditions,
13
+
calculations, and variable substitutions. CEL is used in various Google products
14
+
and open-source projects for policy enforcement, configuration validation, and
15
+
business rule evaluation.
8
16
9
17
## Usage
10
18
@@ -19,90 +27,121 @@ There are two ways to use CEL expressions in your code:
19
27
For simple use cases where you evaluate an expression once:
> Performance measurements on an Apple M3 Pro show that compiling a complex CEL
86
+
> expression (with map/filter operations) takes about 1.4ms, while execution
87
+
> takes about 0.7ms. The one-step `evaluate()` function takes roughly 2ms as it
88
+
> performs both steps.
89
+
>
90
+
> Consider pre-compiling expressions when:
91
+
>
92
+
> - You evaluate the same expression repeatedly with different data
93
+
> - You're building a rules engine or validator that reuses expressions
94
+
> - You want to amortize the compilation cost across multiple evaluations
95
+
> - Performance is critical in your application
96
+
>
97
+
> For one-off evaluations or when expressions change frequently, the convenience
98
+
> of `evaluate()` likely outweighs the performance benefit of pre-compilation.
99
+
73
100
## Architecture
74
101
75
102
This project consists of three main components:
76
103
77
-
1.**cel-rust**: The underlying Rust implementation of the CEL interpreter, created by clarkmcc. This provides the core CEL evaluation engine.
104
+
1.**cel-rust**: The underlying Rust implementation of the CEL interpreter,
105
+
created by clarkmcc. This provides the core CEL evaluation engine.
106
+
107
+
2.**NAPI-RS Bindings**: A thin Rust layer that bridges cel-rust with Node.js
108
+
using [NAPI-RS](https://napi.rs/). NAPI-RS is a framework for building
109
+
pre-compiled Node.js addons in Rust, providing:
78
110
79
-
2.**NAPI-RS Bindings**: A thin Rust layer that bridges cel-rust with Node.js using [NAPI-RS](https://napi.rs/). NAPI-RS is a framework for building pre-compiled Node.js addons in Rust, providing:
80
111
- Type-safe bindings between Rust and Node.js
81
112
- Cross-platform compilation support
82
113
- Automatic TypeScript type definitions generation
83
114
84
-
3.**TypeScript Wrapper**: A TypeScript API that provides a clean interface to the native module, handling type conversions and providing a more idiomatic JavaScript experience.
115
+
3.**TypeScript Wrapper**: A TypeScript API that provides a clean interface to
116
+
the native module, handling type conversions and providing a more idiomatic
117
+
JavaScript experience.
85
118
86
119
## Native Module Structure
87
120
88
121
The native module is built using NAPI-RS and provides cross-platform support:
89
122
90
-
- Platform-specific builds are named `cel-typescript.<platform>-<arch>.node` (e.g., `cel-typescript.darwin-arm64.node` for Apple Silicon Macs)
91
-
- NAPI-RS generates a platform-agnostic loader (`index.js`) that automatically detects the current platform and loads the appropriate `.node` file
92
-
- The module interface is defined in `src/binding.d.ts` which declares the types for the native module
93
-
- At runtime, the TypeScript wrapper (`src/index.ts`) uses the NAPI-RS loader to dynamically load the correct native module
94
-
- This structure allows for seamless cross-platform distribution while maintaining platform-specific optimizations
95
-
123
+
- Platform-specific builds are named `cel-typescript.<platform>-<arch>.node`
124
+
(e.g., `cel-typescript.darwin-arm64.node` for Apple Silicon Macs)
125
+
- NAPI-RS generates a platform-agnostic loader (`index.js`) that automatically
126
+
detects the current platform and loads the appropriate `.node` file
127
+
- The module interface is defined in `src/binding.d.ts` which declares the types
128
+
for the native module
129
+
- At runtime, the TypeScript wrapper (`src/index.ts`) uses the NAPI-RS loader to
130
+
dynamically load the correct native module
131
+
- This structure allows for seamless cross-platform distribution while
132
+
maintaining platform-specific optimizations
96
133
97
134
## How it Works
98
135
99
136
When you build this project:
100
137
101
-
1. The Rust code in `src/lib.rs` is compiled into a native Node.js addon (`.node` file) using NAPI-RS
138
+
1. The Rust code in `src/lib.rs` is compiled into a native Node.js addon
139
+
(`.node` file) using NAPI-RS
102
140
2. The TypeScript code in `src/index.ts` is compiled to JavaScript
103
141
3. The native module is loaded by Node.js when you import the package
104
142
105
143
The build process creates several important files:
144
+
106
145
-`.node` file: The compiled native module containing the Rust code
107
146
-`index.js`: The compiled JavaScript wrapper around the native module
108
147
-`index.d.ts`: TypeScript type definitions generated from the Rust code
@@ -121,25 +160,31 @@ npm test
121
160
122
161
### Prerequisites
123
162
124
-
1. Clone the [cel-rust](https://github.com/clarkmcc/cel-rust) repository as a sibling to this project:
163
+
1. Clone the [cel-rust](https://github.com/clarkmcc/cel-rust) repository as a
164
+
sibling to this project:
165
+
125
166
```bash
126
167
parent-directory/
127
168
├── cel-rust/
128
169
└── cel-typescript/
129
170
```
130
-
This is required because the project depends on `cel-interpreter` from the local cel-rust project (as specified in Cargo.toml).
171
+
172
+
This is required because the project depends on `cel-interpreter` from the
173
+
local cel-rust project (as specified in Cargo.toml).
131
174
132
175
2. Ensure you have Rust and Node.js installed.
133
176
134
177
### Project Structure
135
178
136
179
The project uses:
180
+
137
181
-`napi-rs` for Rust/Node.js bindings
138
182
-`vitest` for testing
139
183
- TypeScript for type safety
140
184
- CEL for expression evaluation
141
185
142
-
To modify the native module, edit `src/lib.rs`. To modify the TypeScript interface, edit `src/index.ts`.
186
+
To modify the native module, edit `src/lib.rs`. To modify the TypeScript
0 commit comments