High-level driver for interactive TypeScript execution — the ExMonty.Sandbox
analog for zapcode.
Automates the start/resume loop: each external function the guest awaits is
dispatched to a handler in the :functions map, and the run is resumed with
the result until it completes. The return contract matches ExMonty.Sandbox.run/2
so the two are drop-in siblings:
{:ok, value, output} | {:error, %ExZapcode.Exception{}}Example
{:ok, 1, ""} =
ExZapcode.Sandbox.run(
"""
const r = await execute_sql({ statement: "SELECT 1 as val" });
r.rows[0].val
""",
functions: %{
"execute_sql" => fn [args] -> {:ok, %{"rows" => [%{"val" => 1}]}} end
}
)Handlers
A handler is fn args -> result (or fn args, kwargs -> result for ExMonty
parity — kwargs is always %{} since TypeScript calls are positional). By TS
convention a tool is called with a single options object, so args is
typically [opts_map].
Return {:ok, value} or {:error, type, message}.
Fidelity gap vs Monty
zapcode-core's resume only accepts a return value — there is no way to
inject a throwable error into the guest. So a handler {:error, ...}
aborts the whole run and is returned to the caller, rather than raising a
catchable exception inside the TypeScript (which Monty supports).
Summary
Functions
Compiles and runs TypeScript code with automatic handler dispatch.
Types
Functions
@spec run( String.t(), keyword() ) :: {:ok, term(), String.t()} | {:error, ExZapcode.Exception.t()}
Compiles and runs TypeScript code with automatic handler dispatch.
Options
:inputs— map ofname => valuebound as globals (default:%{}):functions— map of function-name strings to handler funs (default:%{}):limits— resource limits map (merged overExZapcode.default_limits/0):script_name— accepted forExMontyparity; currently unused
Examples
# Pure expression — no tools
{:ok, 6, ""} = ExZapcode.Sandbox.run("[1, 2, 3].reduce((a, b) => a + b, 0)")
# With a tool the guest awaits
{:ok, 2, ""} =
ExZapcode.Sandbox.run(
~s(const r = await db({ sql: "SELECT 1" }); r.rows[0].n + 1),
functions: %{"db" => fn [%{"sql" => _}] -> {:ok, %{"rows" => [%{"n" => 1}]}} end}
)
# A handler error aborts the run
{:error, %ExZapcode.Exception{type: :runtime_error}} =
ExZapcode.Sandbox.run("await boom()",
functions: %{"boom" => fn _ -> {:error, :runtime_error, "kaboom"} end})