Packages

Boa-powered JavaScript runtimes for Elixir with BEAM dispatch hooks.

Current section

Files

Jump to
boam doc Boam.Runtime.html
Raw

doc/Boam.Runtime.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="generator" content="ExDoc v0.40.1">
<meta name="project" content="boam v0.1.4">
<title>Boam.Runtime — boam v0.1.4</title>
<link rel="stylesheet" href="dist/html-elixir-YJO4MOOW.css" />
<script defer src="dist/sidebar_items-CF3A9E4F.js"></script>
<script defer src="docs_config.js"></script>
<script defer src="dist/html-YU4BZFVS.js"></script>
</head>
<body>
<script>(()=>{var t="ex_doc:settings",e="dark";var o="dark",s="light";var E="sidebar_state",n="closed";var r="sidebar_width";var a="sidebar-open";var i=new URLSearchParams(window.location.search),S=i.get("theme")||JSON.parse(localStorage.getItem(t)||"{}").theme;(S===o||S!==s&&window.matchMedia("(prefers-color-scheme: dark)").matches)&&document.body.classList.add(e);var d=sessionStorage.getItem(E),A=d!==n&&!window.matchMedia(`screen and (max-width: ${768}px)`).matches;document.body.classList.toggle(a,A);var c=sessionStorage.getItem(r);c&&document.body.style.setProperty("--sidebarWidth",`${c}px`);var p=/(Macintosh|iPhone|iPad|iPod)/.test(window.navigator.userAgent);document.documentElement.classList.toggle("apple-os",p);})();
</script>
<div class="body-wrapper">
<button id="sidebar-menu" class="sidebar-button sidebar-toggle" aria-label="toggle sidebar" aria-controls="sidebar">
<i class="ri-menu-line ri-lg" title="Collapse/expand sidebar"></i>
</button>
<nav id="sidebar" class="sidebar">
<div class="sidebar-header">
<div class="sidebar-projectInfo">
<div>
<a href="readme.html" class="sidebar-projectName" translate="no">
boam
</a>
<div class="sidebar-projectVersion" translate="no">
v0.1.4
</div>
</div>
</div>
<ul id="sidebar-list-nav" class="sidebar-list-nav" role="tablist" data-extras="Pages"></ul>
</div>
</nav>
<output role="status" id="toast"></output>
<main class="content page-module" id="main" data-type="modules">
<div id="content" class="content-inner">
<div class="top-search">
<div class="search-settings">
<form class="search-bar" action="search.html">
<label class="search-label">
<span class="sr-only">Search documentation of boam</span>
<div class="search-input-wrapper">
<input name="q" type="text" class="search-input" placeholder="Press / to search" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" />
<button type="button" tabindex="-1" class="search-close-button" aria-hidden="true">
<i class="ri-close-line ri-lg" title="Cancel search"></i>
</button>
</div>
</label>
</form>
<div class="autocomplete">
</div>
<div class="engine-selector" data-multiple="false">
<button type="button" class="engine-button" aria-label="Select search engine" aria-haspopup="true" aria-expanded="false">
<i class="ri-search-2-line" aria-hidden="true"></i>
<span class="engine-name">Default</span>
<i class="ri-arrow-down-s-line" aria-hidden="true"></i>
</button>
<div class="engine-dropdown" hidden role="menu">
<button type="button"
class="engine-option"
data-engine-url="search.html?q="
role="menuitemradio"
aria-checked="true">
<span class="name">Default</span>
<span class="help">In-browser search</span>
</button>
</div>
</div>
<button class="icon-settings display-settings">
<i class="ri-settings-3-line"></i>
<span class="sr-only">Settings</span>
</button>
</div>
</div>
<div id="top-content">
<div class="heading-with-actions top-heading">
<h1>
<span translate="no">Boam.<wbr>Runtime</span>
<small class="app-vsn" translate="no">(boam v0.1.4)</small>
</h1>
<a href="Boam.Runtime.md" title="Copy Markdown (hold Ctrl/Cmd and click it to open as Markdown)" class="copy-markdown icon-action" rel="help">
<i class="ri-markdown-line" aria-hidden="true"></i>
<span class="sr-only">Copy Markdown</span>
</a>
</div>
<section id="moduledoc">
<p><a href="https://hexdocs.pm/elixir/GenServer.html"><code class="inline">GenServer</code></a> wrapper around a single Boa runtime.</p><p>Each <a href="Boam.Runtime.html"><code class="inline">Boam.Runtime</code></a> 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 <a href="#eval/2"><code class="inline">eval/2</code></a> calls from Elixir.</p><h2 id="module-options" class="section-heading"><a href="#module-options" class="hover-link"><i class="ri-link-m" aria-hidden="true"></i></a><span class="text">Options</span></h2><ul><li><code class="inline">:name</code> - optional <a href="https://hexdocs.pm/elixir/GenServer.html"><code class="inline">GenServer</code></a> name for the runtime process</li><li><code class="inline">:dispatcher</code> - existing dispatcher server to receive <code class="inline">beam.call(...)</code>
messages; accepts any <code class="inline">GenServer.server/0</code>. This is the primary way to
integrate Boam into a supervised application.</li><li><code class="inline">:exports</code> - map or keyword list of dispatch handlers when Boam starts
its own convenience dispatcher</li><li><code class="inline">:js_expose</code> - nested tree of JavaScript shims to install on <code class="inline">globalThis</code>
during startup</li><li><code class="inline">:expose</code> - legacy combined tree that configures both <code class="inline">:exports</code> and
<code class="inline">:js_expose</code></li><li><code class="inline">:prelude</code> - JavaScript source string or list of strings to evaluate
during startup, after any generated exposure shims</li><li><code class="inline">:fallback</code> - optional <code class="inline">(name, args -&gt; result)</code> function used when a
dispatch name is not present in <code class="inline">:exports</code></li><li><code class="inline">:dispatch_timeout</code> - timeout for a single <code class="inline">beam.call(...)</code> round-trip;
defaults to <code class="inline">30_000</code>, accepts <code class="inline">:infinity</code></li></ul><h2 id="module-dispatch-contract" class="section-heading"><a href="#module-dispatch-contract" class="hover-link"><i class="ri-link-m" aria-hidden="true"></i></a><span class="text">Dispatch Contract</span></h2><p>JavaScript code may call:</p><pre><code class="javascript">beam.call(&quot;name&quot;, arg1, arg2)</code></pre><p>The dispatcher receives the function name and arguments as JSON-compatible
Elixir values and may reply with:</p><ul><li>any JSON-compatible value</li><li><code class="inline">{:ok, value}</code></li><li><code class="inline">{:error, reason}</code></li></ul><p>Returning <code class="inline">{:error, reason}</code> raises a JavaScript error with <code class="inline">reason</code> as the
message.</p><h2 id="module-exposing-functions" class="section-heading"><a href="#module-exposing-functions" class="hover-link"><i class="ri-link-m" aria-hidden="true"></i></a><span class="text">Exposing Functions</span></h2><p>In most applications you will manage your own dispatch process and pass it in
through <code class="inline">:dispatcher</code>:</p><pre><code class="makeup elixir" translate="no"><span class="n">children</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p" data-group-id="2865555205-1">[</span><span class="w">
</span><span class="p" data-group-id="2865555205-2">{</span><span class="nc">MyApp.JsDispatcher</span><span class="p">,</span><span class="w"> </span><span class="ss">name</span><span class="p">:</span><span class="w"> </span><span class="nc">MyApp.JsDispatcher</span><span class="p" data-group-id="2865555205-2">}</span><span class="p">,</span><span class="w">
</span><span class="p" data-group-id="2865555205-3">{</span><span class="nc">Boam.Runtime</span><span class="p">,</span><span class="w">
</span><span class="ss">dispatcher</span><span class="p">:</span><span class="w"> </span><span class="nc">MyApp.JsDispatcher</span><span class="p">,</span><span class="w">
</span><span class="ss">js_expose</span><span class="p">:</span><span class="w"> </span><span class="p" data-group-id="2865555205-4">%{</span><span class="ss">console</span><span class="p">:</span><span class="w"> </span><span class="p" data-group-id="2865555205-5">%{</span><span class="ss">log</span><span class="p">:</span><span class="w"> </span><span class="no">true</span><span class="p" data-group-id="2865555205-5">}</span><span class="p" data-group-id="2865555205-4">}</span><span class="p" data-group-id="2865555205-3">}</span><span class="w">
</span><span class="p" data-group-id="2865555205-1">]</span></code></pre><p>The built-in dispatcher exists as convenience sugar. Register Elixir handlers
with <code class="inline">:exports</code> and install JavaScript shims with <code class="inline">:js_expose</code>:</p><pre><code class="makeup elixir" translate="no"><span class="ss">exports</span><span class="p">:</span><span class="w"> </span><span class="p" data-group-id="2897937876-1">%{</span><span class="w">
</span><span class="s">&quot;console.log&quot;</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="k" data-group-id="2897937876-2">fn</span><span class="w"> </span><span class="p" data-group-id="2897937876-3">[</span><span class="n">message</span><span class="p" data-group-id="2897937876-3">]</span><span class="w"> </span><span class="o">-&gt;</span><span class="w"> </span><span class="s">&quot;logged: </span><span class="si" data-group-id="2897937876-4">#{</span><span class="n">message</span><span class="si" data-group-id="2897937876-4">}</span><span class="s">&quot;</span><span class="w"> </span><span class="k" data-group-id="2897937876-2">end</span><span class="p">,</span><span class="w">
</span><span class="s">&quot;logger.warn&quot;</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="k" data-group-id="2897937876-5">fn</span><span class="w"> </span><span class="p" data-group-id="2897937876-6">[</span><span class="n">message</span><span class="p" data-group-id="2897937876-6">]</span><span class="w"> </span><span class="o">-&gt;</span><span class="w"> </span><span class="s">&quot;warn: </span><span class="si" data-group-id="2897937876-7">#{</span><span class="n">message</span><span class="si" data-group-id="2897937876-7">}</span><span class="s">&quot;</span><span class="w"> </span><span class="k" data-group-id="2897937876-5">end</span><span class="w">
</span><span class="p" data-group-id="2897937876-1">}</span><span class="p">,</span><span class="w">
</span><span class="ss">js_expose</span><span class="p">:</span><span class="w"> </span><span class="p" data-group-id="2897937876-8">%{</span><span class="w">
</span><span class="ss">console</span><span class="p">:</span><span class="w"> </span><span class="p" data-group-id="2897937876-9">%{</span><span class="w">
</span><span class="ss">log</span><span class="p">:</span><span class="w"> </span><span class="no">true</span><span class="p">,</span><span class="w">
</span><span class="ss">warn</span><span class="p">:</span><span class="w"> </span><span class="p" data-group-id="2897937876-10">{</span><span class="ss">:dispatch</span><span class="p">,</span><span class="w"> </span><span class="s">&quot;logger.warn&quot;</span><span class="p" data-group-id="2897937876-10">}</span><span class="w">
</span><span class="p" data-group-id="2897937876-9">}</span><span class="w">
</span><span class="p" data-group-id="2897937876-8">}</span></code></pre><p>This creates <code class="inline">console.log(...)</code> and <code class="inline">console.warn(...)</code> automatically.</p><p>Dispatch handlers can also queue JS exposure at runtime by sending:</p><pre><code class="makeup elixir" translate="no"><span class="n">send</span><span class="p" data-group-id="3924097788-1">(</span><span class="n">runtime</span><span class="p">,</span><span class="w"> </span><span class="p" data-group-id="3924097788-2">{</span><span class="ss">:boam_expose_js</span><span class="p">,</span><span class="w"> </span><span class="p" data-group-id="3924097788-3">%{</span><span class="ss">console</span><span class="p">:</span><span class="w"> </span><span class="p" data-group-id="3924097788-4">%{</span><span class="ss">debug</span><span class="p">:</span><span class="w"> </span><span class="no">true</span><span class="p" data-group-id="3924097788-4">}</span><span class="p" data-group-id="3924097788-3">}</span><span class="p" data-group-id="3924097788-2">}</span><span class="p" data-group-id="3924097788-1">)</span></code></pre><p>The message is applied after the current runtime operation completes, which
avoids deadlocking a <code class="inline">beam.call(...)</code> handler.</p><h2 id="module-notes" class="section-heading"><a href="#module-notes" class="hover-link"><i class="ri-link-m" aria-hidden="true"></i></a><span class="text">Notes</span></h2><ul><li>Avoid synchronously calling back into the same runtime from a dispatch
handler before replying, or the call will deadlock. Use
<a href="#notify_expose_js/2"><code class="inline">notify_expose_js/2</code></a> or <code class="inline">send(runtime, {:boam_expose_js, tree})</code> from
dispatch handlers instead.</li><li>If you pass a named sibling dispatcher, use a supervisor strategy that
restarts the runtime after the dispatcher restarts, because the runtime
resolves the dispatcher to a pid during startup.</li><li>Top-level JavaScript <code class="inline">undefined</code> is surfaced as <code class="inline">{:ok, :undefined}</code>.</li></ul>
</section>
</div>
<section id="summary" class="details-list">
<h2 class="section-heading">
<a class="hover-link" href="#summary">
<i class="ri-link-m" aria-hidden="true"></i>
</a>
<span class="text">Summary</span>
</h2>
<div class="summary-types summary">
<h3>
<a href="#types">Types</a>
</h3>
<div class="summary-row">
<div class="summary-signature">
<a href="#t:dispatch_timeout/0" data-no-tooltip="" translate="no">dispatch_timeout()</a>
</div>
</div>
<div class="summary-row">
<div class="summary-signature">
<a href="#t:export_name/0" data-no-tooltip="" translate="no">export_name()</a>
</div>
</div>
<div class="summary-row">
<div class="summary-signature">
<a href="#t:legacy_expose/0" data-no-tooltip="" translate="no">legacy_expose()</a>
</div>
</div>
<div class="summary-row">
<div class="summary-signature">
<a href="#t:prelude/0" data-no-tooltip="" translate="no">prelude()</a>
</div>
</div>
<div class="summary-row">
<div class="summary-signature">
<a href="#t:start_option/0" data-no-tooltip="" translate="no">start_option()</a>
</div>
</div>
</div>
<div class="summary-functions summary">
<h3>
<a href="#functions">Functions</a>
</h3>
<div class="summary-row">
<div class="summary-signature">
<a href="#child_spec/1" data-no-tooltip="" translate="no">child_spec(init_arg)</a>
</div>
<div class="summary-synopsis"><p>Returns a specification to start this module under a supervisor.</p></div>
</div>
<div class="summary-row">
<div class="summary-signature">
<a href="#dispatcher/1" data-no-tooltip="" translate="no">dispatcher(runtime)</a>
</div>
<div class="summary-synopsis"><p>Returns the dispatcher pid currently attached to the runtime.</p></div>
</div>
<div class="summary-row">
<div class="summary-signature">
<a href="#eval/2" data-no-tooltip="" translate="no">eval(runtime, source)</a>
</div>
<div class="summary-synopsis"><p>Evaluates a JavaScript string inside the runtime.</p></div>
</div>
<div class="summary-row">
<div class="summary-signature">
<a href="#expose_js/2" data-no-tooltip="" translate="no">expose_js(runtime, tree)</a>
</div>
<div class="summary-synopsis"><p>Installs JavaScript shim functions on <code class="inline">globalThis</code>.</p></div>
</div>
<div class="summary-row">
<div class="summary-signature">
<a href="#notify_expose_js/2" data-no-tooltip="" translate="no">notify_expose_js(runtime, tree)</a>
</div>
<div class="summary-synopsis"><p>Queues JavaScript shim exposure through an asynchronous message.</p></div>
</div>
<div class="summary-row">
<div class="summary-signature">
<a href="#start_link/1" data-no-tooltip="" translate="no">start_link(opts \\ [])</a>
</div>
<div class="summary-synopsis"><p>Starts a runtime process.</p></div>
</div>
</div>
</section>
<section id="types" class="details-list">
<h2 class="section-heading">
<a class="hover-link" href="#types">
<i class="ri-link-m" aria-hidden="true"></i>
</a>
<span class="text">Types</span>
</h2>
<div class="types-list">
<section class="detail" id="t:dispatch_timeout/0">
<div class="detail-header">
<a href="#t:dispatch_timeout/0" class="detail-link" data-no-tooltip="" aria-label="Link to this type">
<i class="ri-link-m" aria-hidden="true"></i>
</a>
<div class="heading-with-actions">
<h1 class="signature" translate="no">dispatch_timeout()</h1>
</div>
</div>
<section class="docstring">
<div class="specs">
<pre translate="no"><span class="attribute">@type</span> dispatch_timeout() :: <a href="https://hexdocs.pm/elixir/typespecs.html#built-in-types">timeout</a>()</pre>
</div>
</section>
</section>
<section class="detail" id="t:export_name/0">
<div class="detail-header">
<a href="#t:export_name/0" class="detail-link" data-no-tooltip="" aria-label="Link to this type">
<i class="ri-link-m" aria-hidden="true"></i>
</a>
<div class="heading-with-actions">
<h1 class="signature" translate="no">export_name()</h1>
</div>
</div>
<section class="docstring">
<div class="specs">
<pre translate="no"><span class="attribute">@type</span> export_name() :: <a href="https://hexdocs.pm/elixir/typespecs.html#basic-types">atom</a>() | <a href="https://hexdocs.pm/elixir/String.html#t:t/0">String.t</a>()</pre>
</div>
</section>
</section>
<section class="detail" id="t:legacy_expose/0">
<div class="detail-header">
<a href="#t:legacy_expose/0" class="detail-link" data-no-tooltip="" aria-label="Link to this type">
<i class="ri-link-m" aria-hidden="true"></i>
</a>
<div class="heading-with-actions">
<h1 class="signature" translate="no">legacy_expose()</h1>
</div>
</div>
<section class="docstring">
<div class="specs">
<pre translate="no"><span class="attribute">@type</span> legacy_expose() :: <a href="https://hexdocs.pm/elixir/typespecs.html#basic-types">map</a>() | <a href="https://hexdocs.pm/elixir/typespecs.html#built-in-types">keyword</a>()</pre>
</div>
</section>
</section>
<section class="detail" id="t:prelude/0">
<div class="detail-header">
<a href="#t:prelude/0" class="detail-link" data-no-tooltip="" aria-label="Link to this type">
<i class="ri-link-m" aria-hidden="true"></i>
</a>
<div class="heading-with-actions">
<h1 class="signature" translate="no">prelude()</h1>
</div>
</div>
<section class="docstring">
<div class="specs">
<pre translate="no"><span class="attribute">@type</span> prelude() :: <a href="https://hexdocs.pm/elixir/String.html#t:t/0">String.t</a>() | [<a href="https://hexdocs.pm/elixir/String.html#t:t/0">String.t</a>()]</pre>
</div>
</section>
</section>
<section class="detail" id="t:start_option/0">
<div class="detail-header">
<a href="#t:start_option/0" class="detail-link" data-no-tooltip="" aria-label="Link to this type">
<i class="ri-link-m" aria-hidden="true"></i>
</a>
<div class="heading-with-actions">
<h1 class="signature" translate="no">start_option()</h1>
</div>
</div>
<section class="docstring">
<div class="specs">
<pre translate="no"><span class="attribute">@type</span> start_option() ::
{:name, <a href="https://hexdocs.pm/elixir/GenServer.html#t:name/0">GenServer.name</a>()}
| {:dispatcher, <a href="https://hexdocs.pm/elixir/GenServer.html#t:server/0">GenServer.server</a>()}
| {:exports,
%{optional(<a href="#t:export_name/0">export_name</a>()) =&gt; <a href="Boam.Dispatcher.html#t:handler/0">Boam.Dispatcher.handler</a>()}
| <a href="https://hexdocs.pm/elixir/typespecs.html#built-in-types">keyword</a>(<a href="Boam.Dispatcher.html#t:handler/0">Boam.Dispatcher.handler</a>())}
| {:js_expose, <a href="Boam.JS.html#t:export_tree/0">Boam.JS.export_tree</a>()}
| {:expose, <a href="#t:legacy_expose/0">legacy_expose</a>()}
| {:prelude, <a href="#t:prelude/0">prelude</a>()}
| {:fallback, (<a href="https://hexdocs.pm/elixir/String.html#t:t/0">String.t</a>(), <a href="https://hexdocs.pm/elixir/typespecs.html#built-in-types">list</a>() -&gt; <a href="https://hexdocs.pm/elixir/typespecs.html#built-in-types">term</a>())}
| {:dispatch_timeout, <a href="#t:dispatch_timeout/0">dispatch_timeout</a>()}</pre>
</div>
</section>
</section>
</div>
</section>
<section id="functions" class="details-list">
<h2 class="section-heading">
<a class="hover-link" href="#functions">
<i class="ri-link-m" aria-hidden="true"></i>
</a>
<span class="text">Functions</span>
</h2>
<div class="functions-list">
<section class="detail" id="child_spec/1">
<div class="detail-header">
<a href="#child_spec/1" class="detail-link" data-no-tooltip="" aria-label="Link to this function">
<i class="ri-link-m" aria-hidden="true"></i>
</a>
<div class="heading-with-actions">
<h1 class="signature" translate="no">child_spec(init_arg)</h1>
</div>
</div>
<section class="docstring">
<p>Returns a specification to start this module under a supervisor.</p><p>See <a href="https://hexdocs.pm/elixir/Supervisor.html"><code class="inline">Supervisor</code></a>.</p>
</section>
</section>
<section class="detail" id="dispatcher/1">
<div class="detail-header">
<a href="#dispatcher/1" class="detail-link" data-no-tooltip="" aria-label="Link to this function">
<i class="ri-link-m" aria-hidden="true"></i>
</a>
<div class="heading-with-actions">
<h1 class="signature" translate="no">dispatcher(runtime)</h1>
</div>
</div>
<section class="docstring">
<div class="specs">
<pre translate="no"><span class="attribute">@spec</span> dispatcher(<a href="https://hexdocs.pm/elixir/GenServer.html#t:server/0">GenServer.server</a>()) :: <a href="https://hexdocs.pm/elixir/typespecs.html#basic-types">pid</a>()</pre>
</div>
<p>Returns the dispatcher pid currently attached to the runtime.</p>
</section>
</section>
<section class="detail" id="eval/2">
<div class="detail-header">
<a href="#eval/2" class="detail-link" data-no-tooltip="" aria-label="Link to this function">
<i class="ri-link-m" aria-hidden="true"></i>
</a>
<div class="heading-with-actions">
<h1 class="signature" translate="no">eval(runtime, source)</h1>
</div>
</div>
<section class="docstring">
<div class="specs">
<pre translate="no"><span class="attribute">@spec</span> eval(<a href="https://hexdocs.pm/elixir/GenServer.html#t:server/0">GenServer.server</a>(), <a href="https://hexdocs.pm/elixir/String.html#t:t/0">String.t</a>()) :: {:ok, <a href="https://hexdocs.pm/elixir/typespecs.html#built-in-types">term</a>()} | {:error, <a href="https://hexdocs.pm/elixir/String.html#t:t/0">String.t</a>()}</pre>
</div>
<p>Evaluates a JavaScript string inside the runtime.</p><p>The return value is either:</p><ul><li><code class="inline">{:ok, value}</code> for a JSON-compatible JavaScript result</li><li><code class="inline">{:ok, :undefined}</code> for top-level JavaScript <code class="inline">undefined</code></li><li><code class="inline">{:error, message}</code> if evaluation or dispatch fails</li></ul><h2 id="eval/2-example" class="section-heading"><a href="#eval/2-example" class="hover-link"><i class="ri-link-m" aria-hidden="true"></i></a><span class="text">Example</span></h2><pre><code class="makeup elixir" translate="no"><span class="p" data-group-id="3273853349-1">{</span><span class="ss">:ok</span><span class="p">,</span><span class="w"> </span><span class="n">runtime</span><span class="p" data-group-id="3273853349-1">}</span><span class="w"> </span><span class="o">=</span><span class="w">
</span><span class="nc">Boam.Runtime</span><span class="o">.</span><span class="n">start_link</span><span class="p" data-group-id="3273853349-2">(</span><span class="w">
</span><span class="ss">exports</span><span class="p">:</span><span class="w"> </span><span class="p" data-group-id="3273853349-3">%{</span><span class="w">
</span><span class="ss">greet</span><span class="p">:</span><span class="w"> </span><span class="k" data-group-id="3273853349-4">fn</span><span class="w"> </span><span class="p" data-group-id="3273853349-5">[</span><span class="n">name</span><span class="p" data-group-id="3273853349-5">]</span><span class="w"> </span><span class="o">-&gt;</span><span class="w"> </span><span class="s">&quot;hello </span><span class="si" data-group-id="3273853349-6">#{</span><span class="n">name</span><span class="si" data-group-id="3273853349-6">}</span><span class="s">&quot;</span><span class="w"> </span><span class="k" data-group-id="3273853349-4">end</span><span class="w">
</span><span class="p" data-group-id="3273853349-3">}</span><span class="w">
</span><span class="p" data-group-id="3273853349-2">)</span><span class="w">
</span><span class="nc">Boam.Runtime</span><span class="o">.</span><span class="n">eval</span><span class="p" data-group-id="3273853349-7">(</span><span class="n">runtime</span><span class="p">,</span><span class="w"> </span><span class="s">&quot;beam.call(&#39;greet&#39;, &#39;Ada&#39;)&quot;</span><span class="p" data-group-id="3273853349-7">)</span><span class="w">
</span><span class="c1">#=&gt; {:ok, &quot;hello Ada&quot;}</span></code></pre>
</section>
</section>
<section class="detail" id="expose_js/2">
<div class="detail-header">
<a href="#expose_js/2" class="detail-link" data-no-tooltip="" aria-label="Link to this function">
<i class="ri-link-m" aria-hidden="true"></i>
</a>
<div class="heading-with-actions">
<h1 class="signature" translate="no">expose_js(runtime, tree)</h1>
</div>
</div>
<section class="docstring">
<div class="specs">
<pre translate="no"><span class="attribute">@spec</span> expose_js(<a href="https://hexdocs.pm/elixir/GenServer.html#t:server/0">GenServer.server</a>(), <a href="Boam.JS.html#t:export_tree/0">Boam.JS.export_tree</a>()) ::
:ok | {:error, <a href="https://hexdocs.pm/elixir/String.html#t:t/0">String.t</a>()}</pre>
</div>
<p>Installs JavaScript shim functions on <code class="inline">globalThis</code>.</p><p>This call is synchronous and should be used only when the runtime is idle.
Do not call it from a <code class="inline">beam.call(...)</code> dispatch handler; use
<a href="#notify_expose_js/2"><code class="inline">notify_expose_js/2</code></a> instead.</p>
</section>
</section>
<section class="detail" id="notify_expose_js/2">
<div class="detail-header">
<a href="#notify_expose_js/2" class="detail-link" data-no-tooltip="" aria-label="Link to this function">
<i class="ri-link-m" aria-hidden="true"></i>
</a>
<div class="heading-with-actions">
<h1 class="signature" translate="no">notify_expose_js(runtime, tree)</h1>
</div>
</div>
<section class="docstring">
<div class="specs">
<pre translate="no"><span class="attribute">@spec</span> notify_expose_js(<a href="https://hexdocs.pm/elixir/GenServer.html#t:server/0">GenServer.server</a>(), <a href="Boam.JS.html#t:export_tree/0">Boam.JS.export_tree</a>()) :: :ok</pre>
</div>
<p>Queues JavaScript shim exposure through an asynchronous message.</p><p>This is safe to use from dispatch handlers because it does not wait for the
runtime process to finish its current evaluation.</p>
</section>
</section>
<section class="detail" id="start_link/1">
<span id="start_link/0"></span>
<div class="detail-header">
<a href="#start_link/1" class="detail-link" data-no-tooltip="" aria-label="Link to this function">
<i class="ri-link-m" aria-hidden="true"></i>
</a>
<div class="heading-with-actions">
<h1 class="signature" translate="no">start_link(opts \\ [])</h1>
</div>
</div>
<section class="docstring">
<div class="specs">
<pre translate="no"><span class="attribute">@spec</span> start_link([<a href="#t:start_option/0">start_option</a>()]) :: <a href="https://hexdocs.pm/elixir/GenServer.html#t:on_start/0">GenServer.on_start</a>()</pre>
</div>
<p>Starts a runtime process.</p><p>See the module documentation for the supported options and dispatch contract.</p>
</section>
</section>
</div>
</section>
<footer class="footer">
<p>
<span class="line">
<a href="https://hex.pm/packages/boam/0.1.4">Hex Package</a>
<a href="https://preview.hex.pm/preview/boam/0.1.4">Hex Preview</a>
</span>
<span class="line">
<button class="a-main footer-button display-quick-switch" title="Go to package docs">
Go to package docs
</button>
<a href="llms.txt" target="_blank">
View llms.txt
</a>
<a href="boam.epub">
Download ePub version
</a>
</span>
</p>
<p class="built-using">
Built using
<a href="https://github.com/elixir-lang/ex_doc" title="ExDoc" target="_blank" rel="help noopener" translate="no">ExDoc</a> (v0.40.1) for the
<a href="https://elixir-lang.org" title="Elixir" target="_blank" translate="no">Elixir programming language</a>
</p>
</footer>
</div>
</main>
</div>
</body>
</html>