IFClite TypeScript API
    Preparing search index...

    Class Sandbox

    @ifc-lite/sandbox — QuickJS-in-WASM sandboxed script execution

    Runs user scripts in a secure, isolated environment with only the bim.* API exposed. No DOM, no global fetch. Outbound HTTP is available only through bim.network.fetch, gated by the network permission (off by default) plus an exact-host grant list re-checked on every call — see network-request.ts and bridge-network.ts.

    import { createSandbox } from '@ifc-lite/sandbox';
    import { createBimContext } from '@ifc-lite/sdk';

    const bim = createBimContext({ backend: myBackend });
    const sandbox = await createSandbox(bim, {
    permissions: { mutate: true },
    limits: { timeoutMs: 10_000 },
    });

    const result = await sandbox.eval(`
    const walls = bim.query.byType('IfcWall');
    console.log('Found', walls.length, 'walls');
    walls.length;
    `);

    console.log(result.value); // number of walls
    console.log(result.logs); // captured console.log output

    sandbox.dispose();
    Index
    • get disposed(): boolean

      Whether dispose() has run. A disposed sandbox rejects every later eval(); callers holding one across an async boundary (a React cleanup, an extension unload) can check this instead of catching.

      Returns boolean

    • get moduleRetired(): boolean

      Whether the WASM module backing this sandbox was retired after a teardown abort (#1922).

      True means some sandbox on this module hit the upstream JS_FreeRuntime assertion, so emscripten's module-wide ABORT latch has fired: this sandbox still runs scripts, but its own teardown can no longer report a failure, and it will silently leak whatever JS_FreeRuntime does not reach. A long-lived host (the extension runtime) should drop such a sandbox and create a new one — the replacement is built on a fresh module, so no page reload is needed. Sandboxes created per run (the viewer's script panel) never observe this: they are already gone.

      Always false after dispose(), which releases the module reference.

      Returns boolean

    • Dispose the sandbox and free WASM memory.

      Each field is cleared before the step that frees it, so a step that throws is never retried. That matters for runtime.dispose(): an out-of-memory or CPU-interrupt exception raised inside a drained promise job leaves QuickJS holding objects with leaked refcounts, and upstream JS_FreeRuntime then trips assert(list_empty(&rt->gc_obj_list)) and throws out of dispose() part-way through freeing the runtime (#1922). Re-entering it — from a second dispose(), a React cleanup, or an extension unload — would free those same structures twice.

      The failure is still reported: the throw propagates, so a caller that cannot tolerate a broken teardown still sees it, and the leak-oracle tests in dispose-leak.test.ts still fail on a retained handle.

      The steps run in sequence rather than through a finally chain. Freeing the runtime after a throwing vm.dispose() would run JS_FreeRuntime against a live context, which aborts the WASM module for the rest of the document — a worse outcome than the ~17KB the skipped free costs, and it would mask the original error.

      The abort itself is upstream and cannot be prevented from here (#1922) — see SandboxAbortError for what was measured and what is done instead. What is done here is to retire the aborted WASM module, so the next sandbox is created on a fresh one instead of inheriting a poisoned heap and a fired ABORT latch (see quickjs-module.ts).

      Returns void

    • Execute a script in the sandbox.

      Supports both JavaScript and TypeScript (TypeScript is type-stripped before execution).

      Runs are serialized per sandbox: calling eval() while another run is in flight queues behind it rather than interleaving with it (#2110). One sandbox owns one QuickJS realm and one log-capture buffer, so overlapping runs could never have been independent.

      Parameters

      • code: string
      • Optionaloptions: { filename?: string; typescript?: boolean }

      Returns Promise<ScriptResult>

    • Initialize the sandbox (loads WASM module if not cached)

      Returns Promise<void>