Boam.Runtime
(boam v0.1.2)
Copy Markdown
GenServer wrapper around a single Boa runtime.
Each Boam.Runtime process owns one Rust resource, and that
resource owns one dedicated worker thread where the Boa engine actually runs.
This keeps the JavaScript engine isolated from BEAM scheduler threads while
still allowing synchronous eval/2 calls from Elixir.
Options
:name- optionalGenServername for the runtime process:dispatcher- existing dispatcher pid to receivebeam.call(...)messages; if omitted, a freshBoam.Dispatcherprocess is started automatically:exports- map or keyword list of dispatch handlers when Boam starts its own dispatcher:expose- nested tree of handlers that should also be installed as JavaScript functions during startup:prelude- JavaScript source string or list of strings to evaluate during startup, after any generated:exposeshims:fallback- optional(name, args -> result)function used when a dispatch name is not present in:exports:dispatch_timeout- timeout for a singlebeam.call(...)round-trip; defaults to30_000, accepts:infinity
Dispatch Contract
JavaScript code may call:
beam.call("name", arg1, arg2)The dispatcher receives the function name and arguments as JSON-compatible Elixir values and may reply with:
- any JSON-compatible value
{:ok, value}{:error, reason}
Returning {:error, reason} raises a JavaScript error with reason as the
message.
Exposing Functions
:expose lets you define nested JavaScript functions from Elixir:
expose: %{
console: %{
log: fn [message] -> "logged: #{message}" end,
warn: {:dispatch, "logger.warn", fn [message] -> "warn: #{message}" end}
}
}This creates console.log(...) and console.warn(...) automatically.
If you already manage your own dispatcher process, use :prelude together
with Boam.JS.export_prelude/1 instead of :expose.
Notes
- Avoid synchronously calling back into the same runtime from a dispatch handler before replying, or the call will deadlock.
- Top-level JavaScript
undefinedis surfaced as{:ok, :undefined}.
Summary
Functions
Returns a specification to start this module under a supervisor.
Evaluates a JavaScript string inside the runtime.
Starts a runtime process.
Types
@type dispatch_timeout() :: timeout()
@type start_option() :: {:name, GenServer.name()} | {:dispatcher, pid()} | {:exports, %{optional(export_name()) => Boam.Dispatcher.handler()} | keyword(Boam.Dispatcher.handler())} | {:expose, Boam.JS.export_tree()} | {:prelude, prelude()} | {:fallback, (String.t(), list() -> term())} | {:dispatch_timeout, dispatch_timeout()}
Functions
Returns a specification to start this module under a supervisor.
See Supervisor.
@spec eval(GenServer.server(), String.t()) :: {:ok, term()} | {:error, String.t()}
Evaluates a JavaScript string inside the runtime.
The return value is either:
{:ok, value}for a JSON-compatible JavaScript result{:ok, :undefined}for top-level JavaScriptundefined{:error, message}if evaluation or dispatch fails
Example
{:ok, runtime} =
Boam.Runtime.start_link(
exports: %{
greet: fn [name] -> "hello #{name}" end
}
)
Boam.Runtime.eval(runtime, "beam.call('greet', 'Ada')")
#=> {:ok, "hello Ada"}
@spec start_link([start_option()]) :: GenServer.on_start()
Starts a runtime process.
See the module documentation for the supported options and dispatch contract.