# VmEngine _(no submodules)_ ## Purpose `VmEngine` is the default sandbox engine. It uses `node:vm` directly: caller code is compiled with `new vm.Script(...)` and executed via `script.runInContext(ctx, { timeout })`. The context is created with `codeGeneration: { strings: false, wasm: false }` so `eval` and the Function constructor are syntactically unavailable inside the sandbox even if the code-transformer's regex filter fails. Context variables and registered modules are injected as own properties of the context object; the host's intrinsics (`Object`, `Array`, etc.) are reachable through the shared realm. `VmEngine` is NOT a security boundary against adversarial code. `node:vm`'s context-sharing model means a determined attacker with code-injection can escape via `this.constructor.constructor("...")` or prototype-chain tricks. For adversarial isolation use `worker-engine` (OS-thread isolation) or `spawn-engine` (process isolation). ## Features - Real `node:vm` execution — synchronous, deterministic. - Frozen intrinsics flag (`codeGeneration: { strings: false, wasm: false }`). - Captured console (`log`/`warn`/`error`) with output-size cap. - Module + context-variable injection per execution. - V8 heap statistics via `v8.getHeapStatistics()`. - OTel `recordExecution` + `recordDuration` emission per call. - `executeSync` companion for pool callers that prefer synchronous APIs. ## Usage: Basic ```ts import { VmEngine } from "@suaveplan/sandbox/vm-engine"; const engine = new VmEngine({ timeout: 5000, maxOutputSize: 1024, memoryLimit: 50 * 1024 * 1024, }); const r = await engine.execute("1 + 1"); console.log(r.result); // 2 engine.destroy(); ``` ## Usage: Advanced Inject a host bridge as a module so user code can interact with the controlled-vocabulary API rather than the host's intrinsics: ```ts import { VmEngine } from "@suaveplan/sandbox/vm-engine"; const engine = new VmEngine({ timeout: 5000, maxOutputSize: 1024, memoryLimit: 50 * 1024 * 1024, modules: [ { name: "host", exports: { fetchProduct: (id: string) => loadProduct(id), }, }, ], }); const r = await engine.execute('host.fetchProduct("sku-42")'); ``` ## API Reference - `new VmEngine(config: SandboxEngineConfig)`. - `execute(code, context?, options?): Promise`. - `executeSync(code, context?, options?): SandboxResult`. - `registerModule(mod): void`. - `unregisterModule(name): boolean`. - `getHeapStatistics(): { usedHeapSize, heapSizeLimit } | null`. - `reset(): void`. - `destroy(): void`. ## Implementation Notes The compiled script wraps the user code in `(${code})` so a bare expression (e.g. `1 + 1`) returns its value rather than throwing a syntax error from a missing semicolon. An IIFE (`function(){...}()`) compiles to `(function(){...}())` which is also valid. The wrapper is intentionally lightweight; callers who want statement-level execution should use `executeFunction` on the facade or wrap their code in a function themselves. The `breakOnSigint: true` flag is set so a SIGINT delivered to the host terminates the running script rather than killing the entire process.