Current section
Files
Jump to
Current section
Files
doc/dist/search_data-B4AF62D2.js
searchData={"items":[{"type":"module","title":"Boam","doc":"High-level entrypoint for running JavaScript through Boa from Elixir.\n\n`Boam` wraps a dedicated Boa runtime behind a `GenServer`. Each runtime owns a\nsingle Rust worker thread because Boa `Context` values are not thread-safe.\n\nJavaScript code can call back into Elixir with `beam.call(name, ...args)`. The\ndispatch itself happens through a separate BEAM process, which keeps the\nruntime process focused on driving the JavaScript engine.\n\nYou can either:\n\n * expose Elixir handlers directly as JavaScript functions with `:expose`\n * run startup JavaScript with `:prelude`\n * generate shim code manually with `Boam.JS.export_prelude/1`","ref":"Boam.html"},{"type":"module","title":"Quick Start - Boam","doc":"```elixir\n{:ok, runtime} =\n Boam.start_link(\n exports: %{\n sum: fn [left, right] -> left + right end\n }\n )\n\nBoam.eval(runtime, \"1 + 2\")\n#=> {:ok, 3}\n\nBoam.eval(runtime, \"beam.call('sum', 2, 3)\")\n#=> {:ok, 5}\n```\n\nOr expose a nested JavaScript API directly:\n\n```elixir\n{:ok, runtime} =\n Boam.start_link(\n expose: %{\n console: %{\n log: fn [message] -> \"logged: #{message}\" end\n }\n }\n )\n\nBoam.eval(runtime, \"console.log('hello')\")\n#=> {:ok, \"logged: hello\"}\n```","ref":"Boam.html#module-quick-start"},{"type":"module","title":"Value Bridge - Boam","doc":"Values crossing between JavaScript and Elixir are intentionally restricted to\nJSON-compatible data:\n\n * `null` maps to `nil`\n * booleans, numbers, strings, arrays, and objects round-trip normally\n * top-level JavaScript `undefined` is returned as `:undefined`\n * `undefined` cannot be passed through `beam.call/1`\n\nReturned JavaScript objects are serialized through Boa's JSON conversion, so\nobject keys come back to Elixir as strings.","ref":"Boam.html#module-value-bridge"},{"type":"module","title":"Architecture - Boam","doc":"* [`Boam.Runtime`](`Boam.Runtime`) owns the Rust runtime resource\n * [`Boam.Dispatcher`](`Boam.Dispatcher`) receives `beam.call(...)` requests\n * [`Boam.JS`](`Boam.JS`) generates JavaScript shim preludes\n * `Boam` provides the small public entrypoint for the common case","ref":"Boam.html#module-architecture"},{"type":"type","title":"Boam.start_option/0","doc":"","ref":"Boam.html#t:start_option/0"},{"type":"function","title":"Boam.eval/2","doc":"Evaluates JavaScript source code inside a running runtime.\n\nThis is a convenience wrapper around `Boam.Runtime.eval/2`.","ref":"Boam.html#eval/2"},{"type":"function","title":"Boam.start_link/1","doc":"Starts a Boa runtime process.\n\nThis is a convenience wrapper around `Boam.Runtime.start_link/1`.\n\nSee `Boam.Runtime` for the full option contract.","ref":"Boam.html#start_link/1"},{"type":"module","title":"Boam.Dispatcher","doc":"Dispatch process for `beam.call(...)` requests originating in JavaScript.\n\nA dispatcher is an ordinary `GenServer` that receives messages from the Rust\nruntime, resolves the requested handler, executes it on the BEAM, and replies\nback to the waiting JavaScript call.\n\nIn the default setup you do not need to start this module manually;\n[`Boam.Runtime`](`Boam.Runtime`) starts one automatically when no explicit\n`:dispatcher` pid is supplied.","ref":"Boam.Dispatcher.html"},{"type":"module","title":"Handler Forms - Boam.Dispatcher","doc":"Handlers can be provided in three shapes:\n\n * `fn args -> result end`\n * `fn name, args -> result end`\n * `{Module, :function}` which is called as `apply(Module, :function, [args])`","ref":"Boam.Dispatcher.html#module-handler-forms"},{"type":"module","title":"Return Contract - Boam.Dispatcher","doc":"A handler may return:\n\n * any JSON-compatible value, which becomes the JavaScript return value\n * `{:ok, value}`, which unwraps to `value`\n * `{:error, reason}`, which raises a JavaScript error\n\nIf a handler crashes, the formatted exception is sent back as a JavaScript\nerror message instead of leaving the runtime hanging.","ref":"Boam.Dispatcher.html#module-return-contract"},{"type":"type","title":"Boam.Dispatcher.export_name/0","doc":"","ref":"Boam.Dispatcher.html#t:export_name/0"},{"type":"type","title":"Boam.Dispatcher.handler/0","doc":"Function or MFA that can satisfy a `beam.call(...)` request.","ref":"Boam.Dispatcher.html#t:handler/0"},{"type":"type","title":"Boam.Dispatcher.start_option/0","doc":"","ref":"Boam.Dispatcher.html#t:start_option/0"},{"type":"function","title":"Boam.Dispatcher.child_spec/1","doc":"Returns a specification to start this module under a supervisor.\n\nSee `Supervisor`.","ref":"Boam.Dispatcher.html#child_spec/1"},{"type":"function","title":"Boam.Dispatcher.start_link/1","doc":"Starts a dispatcher process.\n\nMost callers should let `Boam.Runtime` create a dispatcher\nautomatically. Start this module directly when you want to reuse a single\ndispatch process across several runtimes or supervise it yourself.","ref":"Boam.Dispatcher.html#start_link/1"},{"type":"module","title":"Boam.JS","doc":"Helpers for generating JavaScript shim code around the `beam.call(...)` bridge.\n\nThe main entrypoint is `export_prelude/1`, which takes a nested export tree and\nreturns JavaScript source that installs functions on `globalThis`.\n\nThis is useful in two modes:\n\n * pass the generated string through `prelude:` when you want manual control\n over dispatching\n * let `Boam.Runtime` do the same work automatically with `expose:`","ref":"Boam.JS.html"},{"type":"module","title":"Examples - Boam.JS","doc":"Generate a manual prelude:\n\n```elixir\nprelude =\n Boam.JS.export_prelude(%{\n console: %{\n log: true,\n error: {:dispatch, \"logger.error\"}\n }\n })\n```\n\nThat produces JavaScript equivalent to:\n\n```javascript\nif (globalThis[\"console\"] == null) { globalThis[\"console\"] = {}; }\nglobalThis[\"console\"][\"log\"] = (...args) => beam.call(\"console.log\", ...args);\nglobalThis[\"console\"][\"error\"] = (...args) => beam.call(\"logger.error\", ...args);\n```","ref":"Boam.JS.html#module-examples"},{"type":"type","title":"Boam.JS.export_tree/0","doc":"","ref":"Boam.JS.html#t:export_tree/0"},{"type":"type","title":"Boam.JS.leaf/0","doc":"Leaf spec for a generated JavaScript function.\n\n * `true` derives the dispatch name from the nested path\n * a `Dispatcher.handler/0` also derives the dispatch name from the path\n * `{:dispatch, name}` generates a shim without attaching a handler\n * `{:dispatch, name, handler}` uses a custom dispatch name and handler","ref":"Boam.JS.html#t:leaf/0"},{"type":"type","title":"Boam.JS.path_key/0","doc":"","ref":"Boam.JS.html#t:path_key/0"},{"type":"function","title":"Boam.JS.export_prelude/1","doc":"Builds a JavaScript prelude that exposes nested shim functions on `globalThis`.\n\nLeaf dispatch names default to the dot-joined path. For example:\n\n```elixir\nBoam.JS.export_prelude(%{\n console: %{\n log: true\n }\n})\n```\n\ndefines `globalThis.console.log = (...args) => beam.call(\"console.log\", ...args)`.","ref":"Boam.JS.html#export_prelude/1"},{"type":"module","title":"Boam.Runtime","doc":"`GenServer` wrapper around a single Boa runtime.\n\nEach `Boam.Runtime` process owns one Rust resource, and that\nresource owns one dedicated worker thread where the Boa engine actually runs.\nThis keeps the JavaScript engine isolated from BEAM scheduler threads while\nstill allowing synchronous `eval/2` calls from Elixir.","ref":"Boam.Runtime.html"},{"type":"module","title":"Options - Boam.Runtime","doc":"* `:name` - optional `GenServer` name for the runtime process\n * `:dispatcher` - existing dispatcher pid to receive `beam.call(...)`\n messages; if omitted, a fresh [`Boam.Dispatcher`](`Boam.Dispatcher`)\n process is started automatically\n * `:exports` - map or keyword list of dispatch handlers when Boam starts\n its own dispatcher\n * `:expose` - nested tree of handlers that should also be installed as\n JavaScript functions during startup\n * `:prelude` - JavaScript source string or list of strings to evaluate\n during startup, after any generated `:expose` shims\n * `:fallback` - optional `(name, args -> result)` function used when a\n dispatch name is not present in `:exports`\n * `:dispatch_timeout` - timeout for a single `beam.call(...)` round-trip;\n defaults to `30_000`, accepts `:infinity`","ref":"Boam.Runtime.html#module-options"},{"type":"module","title":"Dispatch Contract - Boam.Runtime","doc":"JavaScript code may call:\n\n```javascript\nbeam.call(\"name\", arg1, arg2)\n```\n\nThe dispatcher receives the function name and arguments as JSON-compatible\nElixir values and may reply with:\n\n * any JSON-compatible value\n * `{:ok, value}`\n * `{:error, reason}`\n\nReturning `{:error, reason}` raises a JavaScript error with `reason` as the\nmessage.","ref":"Boam.Runtime.html#module-dispatch-contract"},{"type":"module","title":"Exposing Functions - Boam.Runtime","doc":"`:expose` lets you define nested JavaScript functions from Elixir:\n\n```elixir\nexpose: %{\n console: %{\n log: fn [message] -> \"logged: #{message}\" end,\n warn: {:dispatch, \"logger.warn\", fn [message] -> \"warn: #{message}\" end}\n }\n}\n```\n\nThis creates `console.log(...)` and `console.warn(...)` automatically.\n\nIf you already manage your own dispatcher process, use `:prelude` together\nwith `Boam.JS.export_prelude/1` instead of `:expose`.","ref":"Boam.Runtime.html#module-exposing-functions"},{"type":"module","title":"Notes - Boam.Runtime","doc":"* Avoid synchronously calling back into the same runtime from a dispatch\n handler before replying, or the call will deadlock.\n * Top-level JavaScript `undefined` is surfaced as `{:ok, :undefined}`.","ref":"Boam.Runtime.html#module-notes"},{"type":"type","title":"Boam.Runtime.dispatch_timeout/0","doc":"","ref":"Boam.Runtime.html#t:dispatch_timeout/0"},{"type":"type","title":"Boam.Runtime.export_name/0","doc":"","ref":"Boam.Runtime.html#t:export_name/0"},{"type":"type","title":"Boam.Runtime.prelude/0","doc":"","ref":"Boam.Runtime.html#t:prelude/0"},{"type":"type","title":"Boam.Runtime.start_option/0","doc":"","ref":"Boam.Runtime.html#t:start_option/0"},{"type":"function","title":"Boam.Runtime.child_spec/1","doc":"Returns a specification to start this module under a supervisor.\n\nSee `Supervisor`.","ref":"Boam.Runtime.html#child_spec/1"},{"type":"function","title":"Boam.Runtime.eval/2","doc":"Evaluates a JavaScript string inside the runtime.\n\nThe return value is either:\n\n * `{:ok, value}` for a JSON-compatible JavaScript result\n * `{:ok, :undefined}` for top-level JavaScript `undefined`\n * `{:error, message}` if evaluation or dispatch fails","ref":"Boam.Runtime.html#eval/2"},{"type":"function","title":"Example - Boam.Runtime.eval/2","doc":"```elixir\n{:ok, runtime} =\n Boam.Runtime.start_link(\n exports: %{\n greet: fn [name] -> \"hello #{name}\" end\n }\n )\n\nBoam.Runtime.eval(runtime, \"beam.call('greet', 'Ada')\")\n#=> {:ok, \"hello Ada\"}\n```","ref":"Boam.Runtime.html#eval/2-example"},{"type":"function","title":"Boam.Runtime.start_link/1","doc":"Starts a runtime process.\n\nSee the module documentation for the supported options and dispatch contract.","ref":"Boam.Runtime.html#start_link/1"},{"type":"extras","title":"Boam","doc":"# Boam\n\nBoam is an Elixir wrapper around the [Boa](https://boajs.dev/) JavaScript\nengine, implemented as a Rustler NIF.\n\nThe library starts a dedicated JavaScript runtime per Elixir process and lets\nJavaScript call back into the BEAM through an explicit dispatch bridge.","ref":"readme.html"},{"type":"extras","title":"Features - Boam","doc":"- Boa-backed JavaScript evaluation from Elixir\n- Dedicated runtime thread per engine, matching Boa's thread-safety model\n- `beam.call(name, ...args)` bridge from JavaScript into Elixir\n- JSON-compatible value round-tripping between JS and Elixir\n- Configurable dispatcher process for custom routing and supervision setups","ref":"readme.html#features"},{"type":"extras","title":"Installation - Boam","doc":"Add `boam` to your list of dependencies in `mix.exs`:\n\n```elixir\ndef deps do\n [\n {:boam, \"~> 0.1.0\"}\n ]\nend\n```","ref":"readme.html#installation"},{"type":"extras","title":"Quick Start - Boam","doc":"```elixir\n{:ok, runtime} =\n Boam.start_link(\n exports: %{\n sum: fn [left, right] -> left + right end,\n greet: fn [name] -> \"hello #{name}\" end\n }\n )\n\nBoam.eval(runtime, \"1 + 2\")\n#=> {:ok, 3}\n\nBoam.eval(runtime, \"beam.call('sum', 2, 3)\")\n#=> {:ok, 5}\n\nBoam.eval(runtime, \"beam.call('greet', 'Ada')\")\n#=> {:ok, \"hello Ada\"}\n```","ref":"readme.html#quick-start"},{"type":"extras","title":"Startup Prelude - Boam","doc":"Run JavaScript during runtime startup with `prelude:`:\n\n```elixir\n{:ok, runtime} =\n Boam.start_link(\n prelude: [\n \"globalThis.appName = 'boam';\",\n \"globalThis.version = 1;\"\n ]\n )\n```\n\nThose snippets run before your first call to `Boam.eval/2`.","ref":"readme.html#startup-prelude"},{"type":"extras","title":"Automatic Function Exposure - Boam","doc":"If you want JavaScript functions like `console.log(...)` without writing wrapper\ncode by hand, use `expose:`:\n\n```elixir\n{:ok, runtime} =\n Boam.start_link(\n expose: %{\n console: %{\n log: fn [message] -> \"logged: #{message}\" end,\n warn: {:dispatch, \"logger.warn\", fn [message] -> \"warn: #{message}\" end}\n }\n }\n )\n\nBoam.eval(runtime, \"console.log('hello')\")\n#=> {:ok, \"logged: hello\"}\n```\n\nLeaf dispatch names default to the dot-joined path, so `console.log` dispatches\nto `\"console.log\"` unless you override it with\n`{:dispatch, \"custom.name\", handler}`.","ref":"readme.html#automatic-function-exposure"},{"type":"extras","title":"Manual Shim Generation - Boam","doc":"If you want to keep dispatch setup separate from runtime startup, generate the\nshim code yourself:\n\n```elixir\nprelude =\n Boam.JS.export_prelude(%{\n console: %{\n log: true,\n error: {:dispatch, \"logger.error\"}\n }\n })\n\n{:ok, runtime} =\n Boam.start_link(\n prelude: prelude,\n fallback: fn name, args -> {name, args} end\n )\n```","ref":"readme.html#manual-shim-generation"},{"type":"extras","title":"Value Model - Boam","doc":"Boam intentionally restricts the bridge to JSON-compatible values:\n\n- JavaScript `null` maps to Elixir `nil`\n- booleans, numbers, strings, arrays, and objects round-trip normally\n- top-level JavaScript `undefined` becomes `{:ok, :undefined}`\n- `undefined` is rejected when passed through `beam.call(...)`\n- JavaScript object keys come back as strings\n\nFor predictable round-tripping, return Elixir maps with string keys from\ndispatch handlers.","ref":"readme.html#value-model"},{"type":"extras","title":"Dispatching Into Elixir - Boam","doc":"JavaScript code can call:\n\n```javascript\nbeam.call(\"name\", arg1, arg2)\n```\n\nThat request is delivered to a `Boam.Dispatcher` process on the BEAM side. A\nhandler can return:\n\n- any JSON-compatible value\n- `{:ok, value}`\n- `{:error, reason}`\n\nIf a handler crashes, the JavaScript caller receives an error instead of\nhanging forever.","ref":"readme.html#dispatching-into-elixir"},{"type":"extras","title":"Architecture - Boam","doc":"- `Boam` is the small public entrypoint\n- `Boam.Runtime` owns the NIF resource and runtime lifecycle\n- `Boam.Dispatcher` resolves and executes `beam.call(...)` handlers\n- `Boam.JS` generates JavaScript shim preludes from nested export trees\n- the internal NIF bridge module is intentionally hidden from the generated docs","ref":"readme.html#architecture"},{"type":"extras","title":"Generating Docs - Boam","doc":"Generate the docs locally with:\n\n```bash\nmix docs\n```\n\nThe generated site will be written to `doc/`.","ref":"readme.html#generating-docs"}],"proglang":"elixir","content_type":"text/markdown","producer":{"name":"ex_doc","version":"0.40.1"}}