@unrdf/knowledge-engine 5.0.1 → 26.4.2
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/package.json +23 -17
- package/src/ai-enhanced-search.mjs +371 -0
- package/src/anomaly-detector.mjs +226 -0
- package/src/artifact-generator.mjs +252 -0
- package/src/browser.mjs +1 -1
- package/src/chatman/disruption-arithmetic.mjs +140 -0
- package/src/chatman/market-dynamics.mjs +140 -0
- package/src/chatman/organizational-dynamics.mjs +140 -0
- package/src/chatman/strategic-dynamics.mjs +140 -0
- package/src/chatman-config-loader.mjs +282 -0
- package/src/chatman-engine.mjs +435 -0
- package/src/chatman-operator.mjs +343 -0
- package/src/dark-field-detector.mjs +332 -0
- package/src/formation-theorems.mjs +345 -0
- package/src/index.mjs +20 -2
- package/src/knowledge-hook-manager.mjs +1 -1
- package/src/lockchain-writer-browser.mjs +2 -2
- package/src/observability.mjs +40 -4
- package/src/query-optimizer.mjs +1 -1
- package/src/resolution-layer.mjs +1 -1
- package/src/transaction.mjs +11 -9
- package/README.md +0 -84
- package/src/browser-shims.mjs +0 -343
- package/src/canonicalize.mjs +0 -414
- package/src/condition-cache.mjs +0 -109
- package/src/condition-evaluator.mjs +0 -722
- package/src/dark-matter-core.mjs +0 -742
- package/src/define-hook.mjs +0 -213
- package/src/effect-sandbox-browser.mjs +0 -283
- package/src/effect-sandbox-worker.mjs +0 -170
- package/src/effect-sandbox.mjs +0 -517
- package/src/engines/index.mjs +0 -11
- package/src/engines/rdf-engine.mjs +0 -299
- package/src/file-resolver.mjs +0 -387
- package/src/hook-executor-batching.mjs +0 -277
- package/src/hook-executor.mjs +0 -870
- package/src/hook-management.mjs +0 -150
- package/src/ken-parliment.mjs +0 -119
- package/src/ken.mjs +0 -149
- package/src/knowledge-engine/builtin-rules.mjs +0 -190
- package/src/knowledge-engine/inference-engine.mjs +0 -418
- package/src/knowledge-engine/knowledge-engine.mjs +0 -317
- package/src/knowledge-engine/pattern-dsl.mjs +0 -142
- package/src/knowledge-engine/pattern-matcher.mjs +0 -215
- package/src/knowledge-engine/rules.mjs +0 -184
- package/src/knowledge-engine.mjs +0 -319
- package/src/knowledge-hook-engine.mjs +0 -360
- package/src/knowledge-substrate-core.mjs +0 -927
- package/src/lite.mjs +0 -222
- package/src/lockchain-writer.mjs +0 -602
- package/src/monitoring/andon-signals.mjs +0 -775
- package/src/parse.mjs +0 -290
- package/src/performance-optimizer.mjs +0 -678
- package/src/policy-pack.mjs +0 -572
- package/src/query-cache.mjs +0 -116
- package/src/query.mjs +0 -306
- package/src/reason.mjs +0 -350
- package/src/schemas.mjs +0 -1063
- package/src/security/error-sanitizer.mjs +0 -257
- package/src/security/path-validator.mjs +0 -194
- package/src/security/sandbox-restrictions.mjs +0 -331
- package/src/security-validator.mjs +0 -389
- package/src/store-cache.mjs +0 -137
- package/src/telemetry.mjs +0 -167
- package/src/utils/adaptive-monitor.mjs +0 -746
- package/src/utils/circuit-breaker.mjs +0 -513
- package/src/utils/edge-case-handler.mjs +0 -503
- package/src/utils/memory-manager.mjs +0 -498
- package/src/utils/ring-buffer.mjs +0 -282
- package/src/validate.mjs +0 -319
- package/src/validators/index.mjs +0 -338
package/src/effect-sandbox.mjs
DELETED
|
@@ -1,517 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @file Effect Sandbox for secure hook execution
|
|
3
|
-
* @module effect-sandbox
|
|
4
|
-
*
|
|
5
|
-
* @description
|
|
6
|
-
* Provides secure sandboxing for hook effects using vm2 or worker threads
|
|
7
|
-
* to prevent malicious code execution and system access.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
import { Worker, _isMainThread, _parentPort, _workerData } from 'worker_threads';
|
|
11
|
-
import { join } from 'path';
|
|
12
|
-
import { randomUUID } from 'crypto';
|
|
13
|
-
import { z } from 'zod';
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Schema for sandbox configuration
|
|
17
|
-
*/
|
|
18
|
-
const SandboxConfigSchema = z.object({
|
|
19
|
-
type: z.enum(['vm2', 'worker', 'isolate']).default('worker'),
|
|
20
|
-
timeout: z.number().int().positive().max(300000).default(30000),
|
|
21
|
-
memoryLimit: z
|
|
22
|
-
.number()
|
|
23
|
-
.int()
|
|
24
|
-
.positive()
|
|
25
|
-
.max(1024 * 1024 * 1024)
|
|
26
|
-
.default(64 * 1024 * 1024), // 64MB
|
|
27
|
-
cpuLimit: z.number().int().positive().max(100).default(50), // 50% CPU
|
|
28
|
-
allowedModules: z.array(z.string()).default([]),
|
|
29
|
-
allowedGlobals: z.array(z.string()).default(['console', 'Date', 'Math', 'JSON']),
|
|
30
|
-
enableNetwork: z.boolean().default(false),
|
|
31
|
-
enableFileSystem: z.boolean().default(false),
|
|
32
|
-
enableProcess: z.boolean().default(false),
|
|
33
|
-
strictMode: z.boolean().default(true),
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Schema for sandbox execution context
|
|
38
|
-
*/
|
|
39
|
-
const SandboxContextSchema = z.object({
|
|
40
|
-
event: z.any(),
|
|
41
|
-
store: z.any(),
|
|
42
|
-
delta: z.any(),
|
|
43
|
-
metadata: z.record(z.any()).optional(),
|
|
44
|
-
allowedFunctions: z.array(z.string()).default(['emitEvent', 'log', 'assert']),
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Schema for sandbox execution result
|
|
49
|
-
*/
|
|
50
|
-
const _SandboxResultSchema = z.object({
|
|
51
|
-
success: z.boolean(),
|
|
52
|
-
result: z.any().optional(),
|
|
53
|
-
error: z.string().optional(),
|
|
54
|
-
duration: z.number().nonnegative(),
|
|
55
|
-
memoryUsed: z.number().nonnegative().optional(),
|
|
56
|
-
cpuUsed: z.number().nonnegative().optional(),
|
|
57
|
-
assertions: z
|
|
58
|
-
.array(
|
|
59
|
-
z.object({
|
|
60
|
-
subject: z.string(),
|
|
61
|
-
predicate: z.string(),
|
|
62
|
-
object: z.string(),
|
|
63
|
-
graph: z.string().optional(),
|
|
64
|
-
})
|
|
65
|
-
)
|
|
66
|
-
.optional(),
|
|
67
|
-
events: z.array(z.any()).optional(),
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Extended sandbox configuration schema with worker pool settings
|
|
72
|
-
*/
|
|
73
|
-
const ExtendedSandboxConfigSchema = SandboxConfigSchema.extend({
|
|
74
|
-
maxWorkerPoolSize: z.number().int().positive().max(200).default(50),
|
|
75
|
-
workerTTL: z.number().int().positive().default(300000), // 5 minutes default TTL
|
|
76
|
-
cleanupInterval: z.number().int().positive().default(60000), // 1 minute cleanup interval
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* Effect Sandbox for secure hook execution
|
|
81
|
-
*/
|
|
82
|
-
export class EffectSandbox {
|
|
83
|
-
/**
|
|
84
|
-
* Create a new effect sandbox
|
|
85
|
-
* @param {Object} [config] - Sandbox configuration
|
|
86
|
-
*/
|
|
87
|
-
constructor(config = {}) {
|
|
88
|
-
this.config = ExtendedSandboxConfigSchema.parse(config);
|
|
89
|
-
this.workers = new Map();
|
|
90
|
-
this.workerTimestamps = new Map(); // Track worker creation time for TTL
|
|
91
|
-
this.executionCount = 0;
|
|
92
|
-
this.totalExecutions = 0;
|
|
93
|
-
this.totalDuration = 0;
|
|
94
|
-
|
|
95
|
-
// Start periodic cleanup for stale workers
|
|
96
|
-
this._startWorkerCleanup();
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* Start periodic cleanup of stale workers
|
|
101
|
-
* @private
|
|
102
|
-
*/
|
|
103
|
-
_startWorkerCleanup() {
|
|
104
|
-
this.cleanupTimer = setInterval(() => {
|
|
105
|
-
this._cleanupStaleWorkers();
|
|
106
|
-
}, this.config.cleanupInterval);
|
|
107
|
-
|
|
108
|
-
// Don't let cleanup timer prevent process exit
|
|
109
|
-
if (this.cleanupTimer.unref) {
|
|
110
|
-
this.cleanupTimer.unref();
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* Cleanup workers that have exceeded TTL
|
|
116
|
-
* @private
|
|
117
|
-
*/
|
|
118
|
-
_cleanupStaleWorkers() {
|
|
119
|
-
const now = Date.now();
|
|
120
|
-
const ttl = this.config.workerTTL;
|
|
121
|
-
|
|
122
|
-
for (const [executionId, timestamp] of this.workerTimestamps) {
|
|
123
|
-
if (now - timestamp > ttl) {
|
|
124
|
-
const worker = this.workers.get(executionId);
|
|
125
|
-
if (worker) {
|
|
126
|
-
console.warn(
|
|
127
|
-
`[EffectSandbox] Force terminating stale worker ${executionId} (exceeded TTL of ${ttl}ms)`
|
|
128
|
-
);
|
|
129
|
-
worker.terminate();
|
|
130
|
-
this.workers.delete(executionId);
|
|
131
|
-
}
|
|
132
|
-
this.workerTimestamps.delete(executionId);
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
/**
|
|
138
|
-
* Execute a hook effect in the sandbox
|
|
139
|
-
* @param {Function} effect - The effect function to execute
|
|
140
|
-
* @param {Object} context - Execution context
|
|
141
|
-
* @param {Object} [options] - Execution options
|
|
142
|
-
* @returns {Promise<Object>} Execution result
|
|
143
|
-
*/
|
|
144
|
-
async executeEffect(effect, context, options = {}) {
|
|
145
|
-
const executionId = randomUUID();
|
|
146
|
-
const startTime = Date.now();
|
|
147
|
-
|
|
148
|
-
try {
|
|
149
|
-
// Validate context
|
|
150
|
-
const validatedContext = SandboxContextSchema.parse(context);
|
|
151
|
-
|
|
152
|
-
// Choose execution method based on config
|
|
153
|
-
let result;
|
|
154
|
-
switch (this.config.type) {
|
|
155
|
-
case 'worker':
|
|
156
|
-
result = await this._executeInWorker(effect, validatedContext, executionId, options);
|
|
157
|
-
break;
|
|
158
|
-
case 'vm2':
|
|
159
|
-
result = await this._executeInVM2(effect, validatedContext, executionId, options);
|
|
160
|
-
break;
|
|
161
|
-
case 'isolate':
|
|
162
|
-
result = await this._executeInIsolate(effect, validatedContext, executionId, options);
|
|
163
|
-
break;
|
|
164
|
-
default:
|
|
165
|
-
throw new Error(`Unsupported sandbox type: ${this.config.type}`);
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
const duration = Date.now() - startTime;
|
|
169
|
-
this._updateMetrics(duration);
|
|
170
|
-
|
|
171
|
-
return {
|
|
172
|
-
...result,
|
|
173
|
-
executionId,
|
|
174
|
-
duration,
|
|
175
|
-
success: true,
|
|
176
|
-
};
|
|
177
|
-
} catch (error) {
|
|
178
|
-
const duration = Date.now() - startTime;
|
|
179
|
-
this._updateMetrics(duration);
|
|
180
|
-
|
|
181
|
-
return {
|
|
182
|
-
executionId,
|
|
183
|
-
duration,
|
|
184
|
-
success: false,
|
|
185
|
-
error: error.message,
|
|
186
|
-
result: null,
|
|
187
|
-
};
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
/**
|
|
192
|
-
* Execute effect in worker thread
|
|
193
|
-
* @param {Function} effect - Effect function
|
|
194
|
-
* @param {Object} context - Execution context
|
|
195
|
-
* @param {string} executionId - Execution ID
|
|
196
|
-
* @param {Object} options - Execution options
|
|
197
|
-
* @returns {Promise<Object>} Execution result
|
|
198
|
-
* @private
|
|
199
|
-
*/
|
|
200
|
-
async _executeInWorker(effect, context, executionId, options) {
|
|
201
|
-
// Check pool size limit before creating new worker
|
|
202
|
-
if (this.workers.size >= this.config.maxWorkerPoolSize) {
|
|
203
|
-
// Cleanup stale workers first
|
|
204
|
-
this._cleanupStaleWorkers();
|
|
205
|
-
|
|
206
|
-
// If still at limit, reject with clear error
|
|
207
|
-
if (this.workers.size >= this.config.maxWorkerPoolSize) {
|
|
208
|
-
throw new Error(
|
|
209
|
-
`Worker pool exhausted: ${this.workers.size}/${this.config.maxWorkerPoolSize} workers active. Try again later.`
|
|
210
|
-
);
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
return new Promise((resolve, reject) => {
|
|
215
|
-
const timeout = setTimeout(() => {
|
|
216
|
-
// Force terminate worker on timeout
|
|
217
|
-
const worker = this.workers.get(executionId);
|
|
218
|
-
if (worker) {
|
|
219
|
-
console.warn(`[EffectSandbox] Force terminating worker ${executionId} after timeout`);
|
|
220
|
-
worker.terminate();
|
|
221
|
-
this.workers.delete(executionId);
|
|
222
|
-
this.workerTimestamps.delete(executionId);
|
|
223
|
-
}
|
|
224
|
-
reject(new Error(`Worker execution timeout after ${this.config.timeout}ms`));
|
|
225
|
-
}, this.config.timeout);
|
|
226
|
-
|
|
227
|
-
const worker = new Worker(join(__dirname, 'effect-sandbox-worker.mjs'), {
|
|
228
|
-
workerData: {
|
|
229
|
-
effect: effect.toString(),
|
|
230
|
-
context,
|
|
231
|
-
executionId,
|
|
232
|
-
config: this.config,
|
|
233
|
-
options,
|
|
234
|
-
},
|
|
235
|
-
});
|
|
236
|
-
|
|
237
|
-
worker.on('message', result => {
|
|
238
|
-
clearTimeout(timeout);
|
|
239
|
-
this.workers.delete(executionId);
|
|
240
|
-
this.workerTimestamps.delete(executionId);
|
|
241
|
-
resolve(result);
|
|
242
|
-
});
|
|
243
|
-
|
|
244
|
-
worker.on('error', error => {
|
|
245
|
-
clearTimeout(timeout);
|
|
246
|
-
this.workers.delete(executionId);
|
|
247
|
-
this.workerTimestamps.delete(executionId);
|
|
248
|
-
reject(error);
|
|
249
|
-
});
|
|
250
|
-
|
|
251
|
-
worker.on('exit', code => {
|
|
252
|
-
if (code !== 0) {
|
|
253
|
-
clearTimeout(timeout);
|
|
254
|
-
this.workers.delete(executionId);
|
|
255
|
-
this.workerTimestamps.delete(executionId);
|
|
256
|
-
reject(new Error(`Worker exited with code ${code}`));
|
|
257
|
-
}
|
|
258
|
-
});
|
|
259
|
-
|
|
260
|
-
this.workers.set(executionId, worker);
|
|
261
|
-
this.workerTimestamps.set(executionId, Date.now());
|
|
262
|
-
});
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
/**
|
|
266
|
-
* Execute effect in VM2 (if available) - DEPRECATED
|
|
267
|
-
* @param {Function} effect - Effect function
|
|
268
|
-
* @param {Object} context - Execution context
|
|
269
|
-
* @param {string} executionId - Execution ID
|
|
270
|
-
* @param {Object} options - Execution options
|
|
271
|
-
* @returns {Promise<Object>} Execution result
|
|
272
|
-
* @private
|
|
273
|
-
* @deprecated Use isolated-vm or worker executors instead
|
|
274
|
-
*/
|
|
275
|
-
async _executeInVM2(effect, context, executionId, options) {
|
|
276
|
-
try {
|
|
277
|
-
// Use new executor pattern
|
|
278
|
-
const { createExecutor } = await import('../security/sandbox/detector.mjs');
|
|
279
|
-
const executor = await createExecutor('vm2', {
|
|
280
|
-
timeout: this.config.timeout,
|
|
281
|
-
strictMode: this.config.strictMode,
|
|
282
|
-
});
|
|
283
|
-
|
|
284
|
-
// Create safe effect function
|
|
285
|
-
const safeEffect = this._createSafeEffect(effect, context);
|
|
286
|
-
|
|
287
|
-
const executionResult = await executor.run(safeEffect, context, options);
|
|
288
|
-
|
|
289
|
-
if (!executionResult.success) {
|
|
290
|
-
throw new Error(executionResult.error || 'VM2 execution failed');
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
return {
|
|
294
|
-
result: executionResult.result,
|
|
295
|
-
assertions: context.assertions || [],
|
|
296
|
-
events: context.events || [],
|
|
297
|
-
};
|
|
298
|
-
} catch (error) {
|
|
299
|
-
if (error.message.includes('vm2')) {
|
|
300
|
-
throw new Error('VM2 not available. Install with: pnpm add vm2');
|
|
301
|
-
}
|
|
302
|
-
throw error;
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
/**
|
|
307
|
-
* Execute effect in isolate (isolated-vm)
|
|
308
|
-
* @param {Function} effect - Effect function
|
|
309
|
-
* @param {Object} context - Execution context
|
|
310
|
-
* @param {string} executionId - Execution ID
|
|
311
|
-
* @param {Object} options - Execution options
|
|
312
|
-
* @returns {Promise<Object>} Execution result
|
|
313
|
-
* @private
|
|
314
|
-
*/
|
|
315
|
-
async _executeInIsolate(effect, context, executionId, options) {
|
|
316
|
-
try {
|
|
317
|
-
// Use isolated-vm executor
|
|
318
|
-
const { createExecutor } = await import('../security/sandbox/detector.mjs');
|
|
319
|
-
const executor = await createExecutor('isolated-vm', {
|
|
320
|
-
memoryLimit: this.config.memoryLimit / (1024 * 1024), // Convert bytes to MB
|
|
321
|
-
timeout: this.config.timeout,
|
|
322
|
-
enableAsync: true,
|
|
323
|
-
enableThreatDetection: true,
|
|
324
|
-
strictMode: this.config.strictMode,
|
|
325
|
-
});
|
|
326
|
-
|
|
327
|
-
// Create safe effect function
|
|
328
|
-
const safeEffect = this._createSafeEffect(effect, context);
|
|
329
|
-
|
|
330
|
-
const executionResult = await executor.run(safeEffect, context, options);
|
|
331
|
-
|
|
332
|
-
if (!executionResult.success) {
|
|
333
|
-
throw new Error(executionResult.error || 'Isolate execution failed');
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
// Cleanup executor
|
|
337
|
-
await executor.cleanup();
|
|
338
|
-
|
|
339
|
-
return {
|
|
340
|
-
result: executionResult.result,
|
|
341
|
-
assertions: context.assertions || [],
|
|
342
|
-
events: context.events || [],
|
|
343
|
-
memoryUsed: executionResult.memoryUsed,
|
|
344
|
-
codeHash: executionResult.codeHash,
|
|
345
|
-
};
|
|
346
|
-
} catch (error) {
|
|
347
|
-
throw new Error(`Isolate execution failed: ${error.message}`);
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
/**
|
|
352
|
-
* Create sandbox globals
|
|
353
|
-
* @param {Object} context - Execution context
|
|
354
|
-
* @returns {Object} Sandbox globals
|
|
355
|
-
* @private
|
|
356
|
-
*/
|
|
357
|
-
_createSandboxGlobals(context) {
|
|
358
|
-
const globals = {};
|
|
359
|
-
|
|
360
|
-
// Add allowed globals
|
|
361
|
-
for (const globalName of this.config.allowedGlobals) {
|
|
362
|
-
if (globalName in globalThis) {
|
|
363
|
-
globals[globalName] = globalThis[globalName];
|
|
364
|
-
}
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
// Add context-specific globals
|
|
368
|
-
globals.event = context.event;
|
|
369
|
-
globals.store = context.store;
|
|
370
|
-
globals.delta = context.delta;
|
|
371
|
-
globals.metadata = context.metadata || {};
|
|
372
|
-
|
|
373
|
-
// Add safe functions
|
|
374
|
-
globals.emitEvent = eventData => {
|
|
375
|
-
if (!context.events) context.events = [];
|
|
376
|
-
context.events.push(eventData);
|
|
377
|
-
};
|
|
378
|
-
|
|
379
|
-
globals.log = (message, level = 'info') => {
|
|
380
|
-
console.log(`[Sandbox ${level.toUpperCase()}] ${message}`);
|
|
381
|
-
};
|
|
382
|
-
|
|
383
|
-
globals.assert = (subject, predicate, object, graph) => {
|
|
384
|
-
if (!context.assertions) context.assertions = [];
|
|
385
|
-
context.assertions.push({ subject, predicate, object, graph });
|
|
386
|
-
};
|
|
387
|
-
|
|
388
|
-
return globals;
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
/**
|
|
392
|
-
* Create safe console
|
|
393
|
-
* @returns {Object} Safe console object
|
|
394
|
-
* @private
|
|
395
|
-
*/
|
|
396
|
-
_createSafeConsole() {
|
|
397
|
-
return {
|
|
398
|
-
log: message => console.log(`[Sandbox] ${message}`),
|
|
399
|
-
warn: message => console.warn(`[Sandbox] ${message}`),
|
|
400
|
-
error: message => console.error(`[Sandbox] ${message}`),
|
|
401
|
-
info: message => console.info(`[Sandbox] ${message}`),
|
|
402
|
-
};
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
/**
|
|
406
|
-
* Create safe require function
|
|
407
|
-
* @returns {Function} Safe require function
|
|
408
|
-
* @private
|
|
409
|
-
*/
|
|
410
|
-
_createSafeRequire() {
|
|
411
|
-
return moduleName => {
|
|
412
|
-
if (!this.config.allowedModules.includes(moduleName)) {
|
|
413
|
-
throw new Error(`Module ${moduleName} is not allowed in sandbox`);
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
try {
|
|
417
|
-
return require(moduleName);
|
|
418
|
-
} catch (error) {
|
|
419
|
-
throw new Error(`Failed to require ${moduleName}: ${error.message}`);
|
|
420
|
-
}
|
|
421
|
-
};
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
/**
|
|
425
|
-
* Create safe effect function
|
|
426
|
-
* @param {Function} effect - Original effect function
|
|
427
|
-
* @param {Object} context - Execution context
|
|
428
|
-
* @returns {string} Safe effect code
|
|
429
|
-
* @private
|
|
430
|
-
*/
|
|
431
|
-
_createSafeEffect(effect, context) {
|
|
432
|
-
// Convert function to string and wrap in safe context
|
|
433
|
-
const effectCode = effect.toString();
|
|
434
|
-
|
|
435
|
-
return `
|
|
436
|
-
const context = ${JSON.stringify(context)};
|
|
437
|
-
const effect = ${effectCode};
|
|
438
|
-
`;
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
/**
|
|
442
|
-
* Update execution metrics
|
|
443
|
-
* @param {number} duration - Execution duration
|
|
444
|
-
* @private
|
|
445
|
-
*/
|
|
446
|
-
_updateMetrics(duration) {
|
|
447
|
-
this.executionCount++;
|
|
448
|
-
this.totalExecutions++;
|
|
449
|
-
this.totalDuration += duration;
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
/**
|
|
453
|
-
* Get sandbox statistics
|
|
454
|
-
* @returns {Object} Statistics
|
|
455
|
-
*/
|
|
456
|
-
getStats() {
|
|
457
|
-
return {
|
|
458
|
-
config: this.config,
|
|
459
|
-
executionCount: this.executionCount,
|
|
460
|
-
totalExecutions: this.totalExecutions,
|
|
461
|
-
averageDuration: this.totalExecutions > 0 ? this.totalDuration / this.totalExecutions : 0,
|
|
462
|
-
activeWorkers: this.workers.size,
|
|
463
|
-
};
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
/**
|
|
467
|
-
* Terminate all workers
|
|
468
|
-
*/
|
|
469
|
-
async terminate() {
|
|
470
|
-
// Stop cleanup timer
|
|
471
|
-
if (this.cleanupTimer) {
|
|
472
|
-
clearInterval(this.cleanupTimer);
|
|
473
|
-
this.cleanupTimer = null;
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
const terminationPromises = Array.from(this.workers.values()).map(worker => {
|
|
477
|
-
return new Promise(resolve => {
|
|
478
|
-
worker.terminate();
|
|
479
|
-
resolve();
|
|
480
|
-
});
|
|
481
|
-
});
|
|
482
|
-
|
|
483
|
-
await Promise.all(terminationPromises);
|
|
484
|
-
this.workers.clear();
|
|
485
|
-
this.workerTimestamps.clear();
|
|
486
|
-
}
|
|
487
|
-
}
|
|
488
|
-
|
|
489
|
-
/**
|
|
490
|
-
* Create a sandboxed hook executor
|
|
491
|
-
* @param {Function} hook - Hook function
|
|
492
|
-
* @param {Object} [config] - Sandbox configuration
|
|
493
|
-
* @returns {Function} Sandboxed hook function
|
|
494
|
-
*/
|
|
495
|
-
export function createSandboxedHook(hook, config = {}) {
|
|
496
|
-
const sandbox = new EffectSandbox(config);
|
|
497
|
-
|
|
498
|
-
return async (event, context) => {
|
|
499
|
-
const sandboxContext = {
|
|
500
|
-
event,
|
|
501
|
-
store: context?.graph,
|
|
502
|
-
delta: event?.payload?.delta,
|
|
503
|
-
metadata: context?.metadata || {},
|
|
504
|
-
};
|
|
505
|
-
|
|
506
|
-
return sandbox.executeEffect(hook, sandboxContext);
|
|
507
|
-
};
|
|
508
|
-
}
|
|
509
|
-
|
|
510
|
-
/**
|
|
511
|
-
* Create an effect sandbox instance
|
|
512
|
-
* @param {Object} [config] - Sandbox configuration
|
|
513
|
-
* @returns {EffectSandbox} Sandbox instance
|
|
514
|
-
*/
|
|
515
|
-
export function createEffectSandbox(config = {}) {
|
|
516
|
-
return new EffectSandbox(config);
|
|
517
|
-
}
|
package/src/engines/index.mjs
DELETED