@n8n/expression-runtime 0.2.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/ARCHITECTURE.md +427 -0
- package/LICENSE.md +88 -0
- package/README.md +305 -0
- package/dist/build.tsbuildinfo +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/types/bridge.d.ts +61 -0
- package/dist/types/bridge.d.ts.map +1 -0
- package/dist/types/bridge.js +8 -0
- package/dist/types/bridge.js.map +1 -0
- package/dist/types/evaluator.d.ts +197 -0
- package/dist/types/evaluator.d.ts.map +1 -0
- package/dist/types/evaluator.js +29 -0
- package/dist/types/evaluator.js.map +1 -0
- package/dist/types/index.d.ts +11 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +8 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/runtime.d.ts +122 -0
- package/dist/types/runtime.d.ts.map +1 -0
- package/dist/types/runtime.js +31 -0
- package/dist/types/runtime.js.map +1 -0
- package/package.json +43 -0
package/ARCHITECTURE.md
ADDED
|
@@ -0,0 +1,427 @@
|
|
|
1
|
+
# Expression Runtime Architecture
|
|
2
|
+
|
|
3
|
+
This package provides a secure, isolated expression evaluation runtime that works across multiple execution environments (isolated-vm, Web Workers, and task runners).
|
|
4
|
+
|
|
5
|
+
## Design Goals
|
|
6
|
+
|
|
7
|
+
1. **Environment Agnostic**: Single codebase that works in Node.js (isolated-vm), browsers (Web Workers), and task runner processes
|
|
8
|
+
2. **Security**: Expressions run in isolated contexts with memory limits and timeouts
|
|
9
|
+
3. **Performance**: Lazy data loading, code caching, and efficient data transfer
|
|
10
|
+
4. **Observability**: Built-in metrics, traces, and logs
|
|
11
|
+
5. **Maintainability**: Clear separation of concerns with well-defined interfaces
|
|
12
|
+
|
|
13
|
+
## Three-Layer Architecture
|
|
14
|
+
|
|
15
|
+
The architecture is split into three distinct layers:
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
┌─────────────────────────────────────────────────────────┐
|
|
19
|
+
│ Host Process │
|
|
20
|
+
│ │
|
|
21
|
+
│ ┌────────────────────────────────────────────────┐ │
|
|
22
|
+
│ │ ExpressionEvaluator (Layer 3) │ │
|
|
23
|
+
│ │ - Public API │ │
|
|
24
|
+
│ │ - Tournament integration │ │
|
|
25
|
+
│ │ - Code caching │ │
|
|
26
|
+
│ │ - Observability │ │
|
|
27
|
+
│ └────────────────┬───────────────────────────────┘ │
|
|
28
|
+
│ │ │
|
|
29
|
+
│ ┌────────────────▼───────────────────────────────┐ │
|
|
30
|
+
│ │ Bridge (Layer 2) │ │
|
|
31
|
+
│ │ - IsolatedVmBridge (Phase 1.1) │ │
|
|
32
|
+
│ │ - WebWorkerBridge (Phase 2+) │ │
|
|
33
|
+
│ │ - Task Runner Integration (TBD) │ │
|
|
34
|
+
│ └────────────────┬───────────────────────────────┘ │
|
|
35
|
+
│ │ IPC/Message Passing │
|
|
36
|
+
└───────────────────┼─────────────────────────────────────┘
|
|
37
|
+
│
|
|
38
|
+
┌───────────────────▼─────────────────────────────────────┐
|
|
39
|
+
│ Isolated Context │
|
|
40
|
+
│ │
|
|
41
|
+
│ ┌────────────────────────────────────────────────┐ │
|
|
42
|
+
│ │ Runtime (Layer 1) │ │
|
|
43
|
+
│ │ - Runs inside isolation │ │
|
|
44
|
+
│ │ - No Node.js dependencies │ │
|
|
45
|
+
│ │ - Lazy loading proxies │ │
|
|
46
|
+
│ │ - Helper functions ($json, $item, etc.) │ │
|
|
47
|
+
│ │ - lodash, Luxon │ │
|
|
48
|
+
│ └────────────────────────────────────────────────┘ │
|
|
49
|
+
│ │
|
|
50
|
+
└─────────────────────────────────────────────────────────┘
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Layer 1: Runtime (Isolated Context)
|
|
54
|
+
|
|
55
|
+
**Location**: Runs inside the isolated context (isolate, worker, subprocess)
|
|
56
|
+
|
|
57
|
+
**Purpose**: Provides the JavaScript execution environment for expressions
|
|
58
|
+
|
|
59
|
+
**Key Components**:
|
|
60
|
+
- **Lazy Loading Proxies**: Fetch data fields on-demand from host to avoid memory limits
|
|
61
|
+
- **Helper Functions**: `$json`, `$item`, `$input`, `$`, etc.
|
|
62
|
+
- **Libraries**: lodash, Luxon (bundled)
|
|
63
|
+
- **No Node.js APIs**: Pure JavaScript only
|
|
64
|
+
|
|
65
|
+
**Bundle**: IIFE format for isolated-vm, ESM for Web Workers
|
|
66
|
+
|
|
67
|
+
### Layer 2: Bridge (Host Process)
|
|
68
|
+
|
|
69
|
+
**Location**: Runs in the host process
|
|
70
|
+
|
|
71
|
+
**Purpose**: Manages communication between host and isolated context
|
|
72
|
+
|
|
73
|
+
**Key Components**:
|
|
74
|
+
- **RuntimeBridge Interface**: Abstract interface for all bridge implementations
|
|
75
|
+
- **IsolatedVmBridge**: Uses isolated-vm API for Node.js backend (Phase 1.1)
|
|
76
|
+
- **WebWorkerBridge**: Uses postMessage API for browser (Phase 2+)
|
|
77
|
+
- **Task Runner Integration**: TBD - May use IsolatedVmBridge locally or direct evaluation (Phase 2+)
|
|
78
|
+
|
|
79
|
+
**Responsibilities**:
|
|
80
|
+
- Initialize isolated context
|
|
81
|
+
- Transfer code to context
|
|
82
|
+
- Handle data requests from runtime (lazy loading)
|
|
83
|
+
- Enforce memory limits and timeouts
|
|
84
|
+
- Dispose of context when needed
|
|
85
|
+
|
|
86
|
+
### Layer 3: Evaluator (Host Process)
|
|
87
|
+
|
|
88
|
+
**Location**: Runs in the host process
|
|
89
|
+
|
|
90
|
+
**Purpose**: Public API for expression evaluation
|
|
91
|
+
|
|
92
|
+
**Key Components**:
|
|
93
|
+
- **ExpressionEvaluator**: Main class used by workflow package
|
|
94
|
+
- **Tournament Integration**: AST transformation and security validation
|
|
95
|
+
- **Code Cache**: Cache transformed code (not evaluation results)
|
|
96
|
+
- **Observability**: Emit metrics, traces, and logs
|
|
97
|
+
|
|
98
|
+
**Responsibilities**:
|
|
99
|
+
- Accept expression strings and workflow data
|
|
100
|
+
- Transform expressions with Tournament
|
|
101
|
+
- Cache transformed code to avoid re-transformation
|
|
102
|
+
- Convert WorkflowData to WorkflowDataProxy for lazy loading
|
|
103
|
+
- Use bridge to evaluate in isolated context
|
|
104
|
+
- Handle errors gracefully
|
|
105
|
+
- Emit observability data
|
|
106
|
+
|
|
107
|
+
## Data Flow
|
|
108
|
+
|
|
109
|
+
### Expression Evaluation Flow
|
|
110
|
+
|
|
111
|
+
```mermaid
|
|
112
|
+
sequenceDiagram
|
|
113
|
+
participant WF as Workflow
|
|
114
|
+
participant Eval as ExpressionEvaluator
|
|
115
|
+
participant Bridge as IsolatedVmBridge
|
|
116
|
+
participant Runtime as Runtime (Isolated)
|
|
117
|
+
|
|
118
|
+
WF->>Eval: evaluate(expr, data)
|
|
119
|
+
Eval->>Eval: Transform with Tournament (cached)
|
|
120
|
+
Eval->>Bridge: execute(transformedCode, data)
|
|
121
|
+
Bridge->>Bridge: registerCallbacks(data) — creates ivm.Reference callbacks
|
|
122
|
+
Bridge->>Runtime: resetDataProxies() — initialise $json, $input, etc. as lazy proxies
|
|
123
|
+
Bridge->>Runtime: run wrapped code (this === __data)
|
|
124
|
+
Runtime->>Runtime: Access $json.field
|
|
125
|
+
Runtime->>Bridge: __getValueAtPath(['$json','field']) via ivm.Reference
|
|
126
|
+
Bridge->>Bridge: Navigate data object
|
|
127
|
+
Bridge-->>Runtime: Metadata or primitive
|
|
128
|
+
Runtime-->>Bridge: Expression result
|
|
129
|
+
Bridge-->>Eval: Result (copied from isolate)
|
|
130
|
+
Eval-->>WF: Result
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Lazy Data Loading
|
|
134
|
+
|
|
135
|
+
Data access from inside the isolate goes through `ivm.Reference` callbacks
|
|
136
|
+
registered by the bridge — not through a method on `RuntimeBridge` itself.
|
|
137
|
+
|
|
138
|
+
```mermaid
|
|
139
|
+
sequenceDiagram
|
|
140
|
+
participant Runtime as Runtime (Isolated)
|
|
141
|
+
participant Proxy as Lazy Proxy
|
|
142
|
+
participant Bridge as IsolatedVmBridge (host)
|
|
143
|
+
|
|
144
|
+
Runtime->>Proxy: $json.user.email
|
|
145
|
+
Proxy->>Bridge: __getValueAtPath(['$json','user','email']) via ivm.Reference
|
|
146
|
+
Bridge->>Bridge: Navigate data object registered via registerCallbacks()
|
|
147
|
+
Bridge-->>Proxy: "test@example.com" (primitive copied into isolate)
|
|
148
|
+
Proxy-->>Runtime: "test@example.com"
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## Environment-Specific Implementations
|
|
152
|
+
|
|
153
|
+
### IsolatedVmBridge (Node.js Backend)
|
|
154
|
+
|
|
155
|
+
Uses [isolated-vm](https://github.com/laverdet/isolated-vm) for V8 isolate-based isolation:
|
|
156
|
+
|
|
157
|
+
```typescript
|
|
158
|
+
class IsolatedVmBridge implements RuntimeBridge {
|
|
159
|
+
private isolate: ivm.Isolate;
|
|
160
|
+
private context: ivm.Context;
|
|
161
|
+
|
|
162
|
+
async initialize(): Promise<void> {
|
|
163
|
+
this.isolate = new ivm.Isolate({
|
|
164
|
+
memoryLimit: 128
|
|
165
|
+
});
|
|
166
|
+
this.context = await this.isolate.createContext();
|
|
167
|
+
|
|
168
|
+
// Load runtime code
|
|
169
|
+
await this.context.eval(runtimeCode);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
async execute(code: string, dataId: string): Promise<unknown> {
|
|
173
|
+
// Implementation...
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### WebWorkerBridge (Browser Frontend)
|
|
179
|
+
|
|
180
|
+
Uses Web Workers for browser-based isolation:
|
|
181
|
+
|
|
182
|
+
```typescript
|
|
183
|
+
class WebWorkerBridge implements RuntimeBridge {
|
|
184
|
+
private worker: Worker;
|
|
185
|
+
|
|
186
|
+
async initialize(): Promise<void> {
|
|
187
|
+
this.worker = new Worker('/runtime.worker.js');
|
|
188
|
+
// Setup message handlers
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
async execute(code: string, dataId: string): Promise<unknown> {
|
|
192
|
+
// Implementation...
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### Task Runner Integration (TBD - Phase 2+)
|
|
198
|
+
|
|
199
|
+
Task runners already provide process-level isolation. When code nodes call `evaluateExpression()`, evaluation happens **inside the task runner** (not via IPC to worker).
|
|
200
|
+
|
|
201
|
+
**Architecture decision pending - two options**:
|
|
202
|
+
|
|
203
|
+
**Option A**: Task runner uses `IsolatedVmBridge` locally
|
|
204
|
+
```typescript
|
|
205
|
+
// Inside task runner process
|
|
206
|
+
const evaluator = new ExpressionEvaluator({
|
|
207
|
+
bridge: new IsolatedVmBridge(config), // Evaluates locally
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
// Code node calls evaluateExpression()
|
|
211
|
+
const result = await evaluator.evaluate(expression, workflowData);
|
|
212
|
+
// ^ All happens inside task runner, no IPC, no lazy loading needed
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
**Option B**: Task runner evaluates directly (no extra sandbox)
|
|
216
|
+
```typescript
|
|
217
|
+
// Task runner already isolated at process level
|
|
218
|
+
// No need for isolated-vm sandbox on top
|
|
219
|
+
const result = evaluateExpressionDirectly(expression, workflowData);
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
**Key point**: Task runner already has all workflow data, so no lazy loading or IPC communication is needed for data access.
|
|
223
|
+
|
|
224
|
+
## Package Structure
|
|
225
|
+
|
|
226
|
+
```
|
|
227
|
+
packages/@n8n/expression-runtime/
|
|
228
|
+
├── ARCHITECTURE.md # This file
|
|
229
|
+
├── README.md
|
|
230
|
+
├── package.json
|
|
231
|
+
├── tsconfig.json
|
|
232
|
+
├── tsconfig.build.json
|
|
233
|
+
├── vitest.config.ts
|
|
234
|
+
├── esbuild.config.js # Bundles src/runtime/index.ts → dist/bundle/runtime.iife.js
|
|
235
|
+
│
|
|
236
|
+
├── src/
|
|
237
|
+
│ ├── index.ts # Public API exports
|
|
238
|
+
│ │
|
|
239
|
+
│ ├── types/ # TypeScript interfaces (no implementations)
|
|
240
|
+
│ │ ├── index.ts
|
|
241
|
+
│ │ ├── bridge.ts # RuntimeBridge, BridgeConfig
|
|
242
|
+
│ │ ├── evaluator.ts # IExpressionEvaluator, EvaluatorConfig, error classes
|
|
243
|
+
│ │ └── runtime.ts # RuntimeHostInterface, RuntimeGlobals, RuntimeError
|
|
244
|
+
│ │
|
|
245
|
+
│ ├── runtime/ # Layer 1: runs inside the V8 isolate
|
|
246
|
+
│ │ └── index.ts # Proxy system, resetDataProxies, __sanitize,
|
|
247
|
+
│ │ # SafeObject, SafeError, Lodash/Luxon wiring,
|
|
248
|
+
│ │ # all extension functions
|
|
249
|
+
│ │
|
|
250
|
+
│ ├── bridge/ # Layer 2: host-process isolate management
|
|
251
|
+
│ │ └── isolated-vm-bridge.ts # IsolatedVmBridge (ivm.Isolate, callbacks, script cache)
|
|
252
|
+
│ │
|
|
253
|
+
│ ├── evaluator/ # Layer 3: public-facing API
|
|
254
|
+
│ │ └── expression-evaluator.ts # Tournament integration, expression code cache
|
|
255
|
+
│ │
|
|
256
|
+
│ ├── extensions/ # Expression extension functions (bundled into runtime)
|
|
257
|
+
│ │ ├── array-extensions.ts
|
|
258
|
+
│ │ ├── boolean-extensions.ts
|
|
259
|
+
│ │ ├── date-extensions.ts
|
|
260
|
+
│ │ ├── number-extensions.ts
|
|
261
|
+
│ │ ├── object-extensions.ts
|
|
262
|
+
│ │ ├── string-extensions.ts
|
|
263
|
+
│ │ ├── extend.ts
|
|
264
|
+
│ │ ├── extensions.ts
|
|
265
|
+
│ │ ├── expression-extension-error.ts
|
|
266
|
+
│ │ └── utils.ts
|
|
267
|
+
│ │
|
|
268
|
+
│ └── __tests__/
|
|
269
|
+
│ └── integration.test.ts
|
|
270
|
+
│
|
|
271
|
+
└── dist/
|
|
272
|
+
├── *.js / *.d.ts # Compiled TypeScript (tsc output)
|
|
273
|
+
└── bundle/
|
|
274
|
+
└── runtime.iife.js # Self-contained IIFE loaded into isolated-vm
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
## Key Design Decisions
|
|
278
|
+
|
|
279
|
+
### 1. Why Three Layers?
|
|
280
|
+
|
|
281
|
+
**Separation of Concerns**: Each layer has a single responsibility:
|
|
282
|
+
- Runtime: Execute expressions in isolation
|
|
283
|
+
- Bridge: Handle environment-specific communication
|
|
284
|
+
- Evaluator: Provide clean API with observability
|
|
285
|
+
|
|
286
|
+
**Environment Agnostic**: The Runtime and Evaluator layers are identical across all environments. Only the Bridge changes.
|
|
287
|
+
|
|
288
|
+
### 2. Why Lazy Loading?
|
|
289
|
+
|
|
290
|
+
**Memory Efficiency**: Large workflow data (100MB+) cannot fit in isolate memory limits (128MB). Lazy loading fetches only the fields that expressions actually access.
|
|
291
|
+
|
|
292
|
+
**Performance**: Transferring only accessed fields is faster than transferring entire objects.
|
|
293
|
+
|
|
294
|
+
**Limitation**: Lazy loading requires **synchronous** callbacks from runtime to host. This works for:
|
|
295
|
+
- ✅ **isolated-vm**: Uses `ivm.Reference` for true synchronous callbacks
|
|
296
|
+
- ✅ **Node.js vm**: Direct synchronous function calls
|
|
297
|
+
- ❌ **Web Workers**: postMessage is always async (see Known Limitations below)
|
|
298
|
+
|
|
299
|
+
### 3. Why Bundle the Runtime?
|
|
300
|
+
|
|
301
|
+
**No Node.js Dependencies**: Runtime must work in environments without Node.js (browser, isolated-vm). Bundling produces a self-contained IIFE/ESM module.
|
|
302
|
+
|
|
303
|
+
**Immutability**: Bundled runtime is immutable and can be cached.
|
|
304
|
+
|
|
305
|
+
### 4. Why Abstract Bridge?
|
|
306
|
+
|
|
307
|
+
**Future-Proofing**: Frontend will use Web Workers. Backend uses isolated-vm. Abstract bridge allows adding new environments without changing other layers.
|
|
308
|
+
|
|
309
|
+
**Testing**: NodeVmBridge allows fast testing without native isolated-vm dependency.
|
|
310
|
+
|
|
311
|
+
## Known Limitations
|
|
312
|
+
|
|
313
|
+
### Lazy Loading with Async Boundaries
|
|
314
|
+
|
|
315
|
+
JavaScript Proxy trap handlers are **synchronous**, which creates a fundamental limitation:
|
|
316
|
+
|
|
317
|
+
```javascript
|
|
318
|
+
const proxy = new Proxy({}, {
|
|
319
|
+
get(target, prop) {
|
|
320
|
+
// This handler MUST be synchronous
|
|
321
|
+
// Cannot use await or return Promise
|
|
322
|
+
return someValue;
|
|
323
|
+
}
|
|
324
|
+
});
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
**Impact by Environment**:
|
|
328
|
+
|
|
329
|
+
1. **isolated-vm** ✅
|
|
330
|
+
- Uses `ivm.Reference` for true synchronous callbacks from isolate to host
|
|
331
|
+
- Full lazy loading support
|
|
332
|
+
|
|
333
|
+
2. **Node.js vm** ✅
|
|
334
|
+
- Direct synchronous function calls
|
|
335
|
+
- Full lazy loading support (used for testing)
|
|
336
|
+
|
|
337
|
+
3. **Web Workers** ❌
|
|
338
|
+
- `postMessage` is always async
|
|
339
|
+
- **Phase 1 Limitation**: No lazy loading, must pre-fetch all data before evaluation
|
|
340
|
+
- **Future Enhancement (Phase 2+)**: Explore `SharedArrayBuffer` + `Atomics` for synchronous data access
|
|
341
|
+
|
|
342
|
+
### Web Worker Support Roadmap
|
|
343
|
+
|
|
344
|
+
**Phase 1** (Initial implementation):
|
|
345
|
+
- WebWorkerBridge will pre-fetch all workflow data
|
|
346
|
+
- Transfer complete data object to worker before evaluation
|
|
347
|
+
- Works for small/medium datasets (< 50MB)
|
|
348
|
+
- No lazy loading benefit
|
|
349
|
+
|
|
350
|
+
**Phase 2+** (Future enhancement):
|
|
351
|
+
- Investigate `SharedArrayBuffer` + `Atomics` for sync access
|
|
352
|
+
- Or accept pre-fetching as the Web Worker approach
|
|
353
|
+
- Decision based on real-world usage patterns
|
|
354
|
+
|
|
355
|
+
### Security Boundaries
|
|
356
|
+
|
|
357
|
+
The runtime has **no access** to:
|
|
358
|
+
- ❌ Node.js APIs (fs, net, child_process, etc.)
|
|
359
|
+
- ❌ Host process memory
|
|
360
|
+
- ❌ Other isolates/workers
|
|
361
|
+
- ❌ Cookies
|
|
362
|
+
|
|
363
|
+
The runtime **can only**:
|
|
364
|
+
- ✅ Call `getDataSync()` to fetch workflow data
|
|
365
|
+
- ✅ Access lodash and Luxon libraries
|
|
366
|
+
- ✅ Execute pure JavaScript code
|
|
367
|
+
|
|
368
|
+
## Testing Strategy
|
|
369
|
+
|
|
370
|
+
**Runtime Tests** (vitest):
|
|
371
|
+
- Use NodeVmBridge for fast, isolated tests
|
|
372
|
+
- Test lazy loading, helpers, error handling
|
|
373
|
+
- No native dependencies required
|
|
374
|
+
|
|
375
|
+
**Bridge Tests** (vitest):
|
|
376
|
+
- Test each bridge implementation
|
|
377
|
+
- Mock environment-specific APIs
|
|
378
|
+
- Test memory limits, timeouts, disposal
|
|
379
|
+
|
|
380
|
+
**Evaluator Tests** (vitest):
|
|
381
|
+
- Test Tournament integration (transformation and validation)
|
|
382
|
+
- Test code caching (transformed code, not results)
|
|
383
|
+
- Test WorkflowData to WorkflowDataProxy conversion
|
|
384
|
+
- Test observability emission
|
|
385
|
+
- Test error handling
|
|
386
|
+
|
|
387
|
+
**Integration Tests** (jest in workflow package):
|
|
388
|
+
- Test full stack with real isolated-vm
|
|
389
|
+
- Test concurrent evaluations
|
|
390
|
+
- Test with real workflow data
|
|
391
|
+
|
|
392
|
+
## Observability
|
|
393
|
+
|
|
394
|
+
All layers emit metrics, traces, and logs:
|
|
395
|
+
|
|
396
|
+
**Metrics**:
|
|
397
|
+
- `expression.evaluation.count`
|
|
398
|
+
- `expression.evaluation.duration_ms`
|
|
399
|
+
- `expression.code_cache.hit` (transformed code cache)
|
|
400
|
+
- `expression.code_cache.miss`
|
|
401
|
+
- `expression.isolate.memory_mb`
|
|
402
|
+
|
|
403
|
+
**Traces**:
|
|
404
|
+
- `expression.evaluate` span wraps entire evaluation
|
|
405
|
+
- `expression.tournament` span for AST transformation
|
|
406
|
+
- `expression.isolate.execute` span for isolated execution
|
|
407
|
+
|
|
408
|
+
**Logs**:
|
|
409
|
+
- Errors at all levels
|
|
410
|
+
- Warnings for memory pressure
|
|
411
|
+
- Debug logs for development
|
|
412
|
+
|
|
413
|
+
See observability package documentation for details.
|
|
414
|
+
|
|
415
|
+
## Next Steps
|
|
416
|
+
|
|
417
|
+
1. Implement TypeScript interfaces (Phase 0.1)
|
|
418
|
+
2. Implement observability infrastructure (Phase 0.2)
|
|
419
|
+
3. Create comprehensive benchmarks (Phase 0.3)
|
|
420
|
+
4. Implement runtime package (Phase 1.1)
|
|
421
|
+
5. Implement isolate pooling (Phase 1.2)
|
|
422
|
+
|
|
423
|
+
## References
|
|
424
|
+
|
|
425
|
+
- [isolated-vm GitHub](https://github.com/laverdet/isolated-vm)
|
|
426
|
+
- [Web Workers MDN](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API)
|
|
427
|
+
- [n8n workflow package](../workflow/)
|
package/LICENSE.md
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# License
|
|
2
|
+
|
|
3
|
+
Portions of this software are licensed as follows:
|
|
4
|
+
|
|
5
|
+
- Content of branches other than the main branch (i.e. "master") are not licensed.
|
|
6
|
+
- Source code files that contain ".ee." in their filename or ".ee" in their dirname are NOT licensed under
|
|
7
|
+
the Sustainable Use License.
|
|
8
|
+
To use source code files that contain ".ee." in their filename or ".ee" in their dirname you must hold a
|
|
9
|
+
valid n8n Enterprise License specifically allowing you access to such source code files and as defined
|
|
10
|
+
in "LICENSE_EE.md".
|
|
11
|
+
- All third party components incorporated into the n8n Software are licensed under the original license
|
|
12
|
+
provided by the owner of the applicable component.
|
|
13
|
+
- Content outside of the above mentioned files or restrictions is available under the "Sustainable Use
|
|
14
|
+
License" as defined below.
|
|
15
|
+
|
|
16
|
+
## Sustainable Use License
|
|
17
|
+
|
|
18
|
+
Version 1.0
|
|
19
|
+
|
|
20
|
+
### Acceptance
|
|
21
|
+
|
|
22
|
+
By using the software, you agree to all of the terms and conditions below.
|
|
23
|
+
|
|
24
|
+
### Copyright License
|
|
25
|
+
|
|
26
|
+
The licensor grants you a non-exclusive, royalty-free, worldwide, non-sublicensable, non-transferable license
|
|
27
|
+
to use, copy, distribute, make available, and prepare derivative works of the software, in each case subject
|
|
28
|
+
to the limitations below.
|
|
29
|
+
|
|
30
|
+
### Limitations
|
|
31
|
+
|
|
32
|
+
You may use or modify the software only for your own internal business purposes or for non-commercial or
|
|
33
|
+
personal use. You may distribute the software or provide it to others only if you do so free of charge for
|
|
34
|
+
non-commercial purposes. You may not alter, remove, or obscure any licensing, copyright, or other notices of
|
|
35
|
+
the licensor in the software. Any use of the licensor’s trademarks is subject to applicable law.
|
|
36
|
+
|
|
37
|
+
### Patents
|
|
38
|
+
|
|
39
|
+
The licensor grants you a license, under any patent claims the licensor can license, or becomes able to
|
|
40
|
+
license, to make, have made, use, sell, offer for sale, import and have imported the software, in each case
|
|
41
|
+
subject to the limitations and conditions in this license. This license does not cover any patent claims that
|
|
42
|
+
you cause to be infringed by modifications or additions to the software. If you or your company make any
|
|
43
|
+
written claim that the software infringes or contributes to infringement of any patent, your patent license
|
|
44
|
+
for the software granted under these terms ends immediately. If your company makes such a claim, your patent
|
|
45
|
+
license ends immediately for work on behalf of your company.
|
|
46
|
+
|
|
47
|
+
### Notices
|
|
48
|
+
|
|
49
|
+
You must ensure that anyone who gets a copy of any part of the software from you also gets a copy of these
|
|
50
|
+
terms. If you modify the software, you must include in any modified copies of the software a prominent notice
|
|
51
|
+
stating that you have modified the software.
|
|
52
|
+
|
|
53
|
+
### No Other Rights
|
|
54
|
+
|
|
55
|
+
These terms do not imply any licenses other than those expressly granted in these terms.
|
|
56
|
+
|
|
57
|
+
### Termination
|
|
58
|
+
|
|
59
|
+
If you use the software in violation of these terms, such use is not licensed, and your license will
|
|
60
|
+
automatically terminate. If the licensor provides you with a notice of your violation, and you cease all
|
|
61
|
+
violation of this license no later than 30 days after you receive that notice, your license will be reinstated
|
|
62
|
+
retroactively. However, if you violate these terms after such reinstatement, any additional violation of these
|
|
63
|
+
terms will cause your license to terminate automatically and permanently.
|
|
64
|
+
|
|
65
|
+
### No Liability
|
|
66
|
+
|
|
67
|
+
As far as the law allows, the software comes as is, without any warranty or condition, and the licensor will
|
|
68
|
+
not be liable to you for any damages arising out of these terms or the use or nature of the software, under
|
|
69
|
+
any kind of legal claim.
|
|
70
|
+
|
|
71
|
+
### Definitions
|
|
72
|
+
|
|
73
|
+
The “licensor” is the entity offering these terms.
|
|
74
|
+
|
|
75
|
+
The “software” is the software the licensor makes available under these terms, including any portion of it.
|
|
76
|
+
|
|
77
|
+
“You” refers to the individual or entity agreeing to these terms.
|
|
78
|
+
|
|
79
|
+
“Your company” is any legal entity, sole proprietorship, or other kind of organization that you work for, plus
|
|
80
|
+
all organizations that have control over, are under the control of, or are under common control with that
|
|
81
|
+
organization. Control means ownership of substantially all the assets of an entity, or the power to direct its
|
|
82
|
+
management and policies by vote, contract, or otherwise. Control can be direct or indirect.
|
|
83
|
+
|
|
84
|
+
“Your license” is the license granted to you for the software under these terms.
|
|
85
|
+
|
|
86
|
+
“Use” means anything you do with the software requiring your license.
|
|
87
|
+
|
|
88
|
+
“Trademark” means trademarks, service marks, and similar rights.
|