# WorkerEngine _(no submodules)_ ## Purpose `WorkerEngine` uses real `node:worker_threads` for true OS-thread isolation. Each `execute` call spawns a fresh `Worker` constructed from an inline source string (`eval: true`), posts the code + context + modules over the structured-clone message channel, and awaits the structured reply. Intrinsics are NOT shared with the host realm — the worker has its own V8 isolate, its own heap, and its own event loop. Timeouts are enforced by calling `worker.terminate()`, which is a hard stop the running script cannot intercept. Use `WorkerEngine` when the code being sandboxed may be adversarial: a true OS-thread boundary defeats the prototype-chain escapes that compromise `vm-engine`. The cost is per-call worker startup, which is non-trivial; pair with `SandboxPool` when latency matters. ## Features - Real `node:worker_threads` execution — OS-thread isolation. - Worker spawned per call, terminated after every result. - `worker.terminate()` enforces timeout — script cannot intercept. - Structured-clone passes context + modules. - Output-size cap applied inside the worker before postMessage. - OTel `recordExecution` + `recordDuration` per call. ## Usage: Basic ```ts import { WorkerEngine } from "@suaveplan/sandbox/worker-engine"; const e = new WorkerEngine({ timeout: 5000, maxOutputSize: 1024, memoryLimit: 50 * 1024 * 1024, }); const r = await e.execute("2 + 2"); e.destroy(); ``` ## Usage: Advanced Wrap the engine in a pool to amortise startup: ```ts import { SandboxPool } from "@suaveplan/sandbox/pool"; import { WorkerEngine } from "@suaveplan/sandbox/worker-engine"; const pool = new SandboxPool({ minSize: 2, maxSize: 8, engineConfig: { timeout: 5000, maxOutputSize: 1024, memoryLimit: 5e7 }, factory: (cfg) => new WorkerEngine(cfg), }); ``` ## API Reference - `new WorkerEngine(config: SandboxEngineConfig)`. - `execute(code, context?, options?): Promise`. - `registerModule(mod): void`. - `unregisterModule(name): boolean`. - `reset(): void`. - `destroy(): void`. ## Implementation Notes The inline worker source is a single string literal. The worker uses a runtime `Reflect.construct(Function, [...keys, source])` to wrap the user code in an isolated function scope — this is acceptable inside the worker because the worker IS the security boundary. Outside the worker, in the host, no dynamic code construction happens. The post-message channel uses structured clone, which copies primitives + plain objects + typed arrays but not functions or symbols — module exports must therefore be data, not host references; for host bridges use `spawn-engine` plus an IPC channel.