Packages
livebook
0.15.2
0.19.8
0.19.7
0.19.6
0.19.5
0.19.4
0.19.3
0.19.2
0.19.1
0.19.0
0.18.6
0.18.5
0.18.4
0.18.3
0.18.2
0.18.1
0.18.0
0.17.3
0.17.2
0.17.1
0.17.0
0.16.4
0.16.3
0.16.2
0.16.1
0.16.0
0.15.5
0.15.4
0.15.3
0.15.2
0.15.1
0.15.0
0.14.7
0.14.6
0.14.5
0.14.4
0.14.3
0.14.2
0.14.1
0.14.0
0.14.0-rc.1
0.14.0-rc.0
0.13.3
0.13.2
0.13.1
0.13.0
0.12.1
0.12.0
0.11.4
0.11.3
0.11.2
0.11.1
0.11.0
0.10.0
0.9.3
0.9.2
0.9.1
0.9.0
0.8.2
0.8.1
0.8.0
0.7.2
0.7.1
0.7.0
0.6.3
0.6.2
0.6.1
0.6.0
0.5.2
0.5.1
0.5.0
0.4.1
0.4.0
0.3.2
0.3.1
0.3.0
0.2.3
0.2.2
0.2.1
0.2.0
0.1.2
0.1.1
0.1.0
Automate code & data workflows with interactive notebooks
Current section
Files
Jump to
Current section
Files
lib/livebook_web/live/session_live/standalone_runtime_component.ex
defmodule LivebookWeb.SessionLive.StandaloneRuntimeComponent do
use LivebookWeb, :live_component
import Ecto.Changeset
alias Livebook.{Session, Runtime}
@impl true
def mount(socket) do
unless Livebook.Config.runtime_enabled?(Livebook.Runtime.Standalone) do
raise "runtime module not allowed"
end
{:ok, socket}
end
@impl true
def update(assigns, socket) do
changeset =
case socket.assigns[:changeset] do
nil ->
changeset(assigns.runtime)
changeset when socket.assigns.runtime == assigns.runtime ->
changeset
changeset ->
changeset(assigns.runtime, changeset.params)
end
socket =
socket
|> assign(assigns)
|> assign(:changeset, changeset)
{:ok, socket}
end
defp changeset(runtime, attrs \\ %{}) do
data =
case runtime do
%Runtime.Standalone{erl_flags: erl_flags} ->
%{erl_flags: erl_flags}
_ ->
%{erl_flags: nil}
end
types = %{erl_flags: :string}
cast({data, types}, attrs, [:erl_flags])
end
@impl true
def render(assigns) do
~H"""
<div id={@id} class="flex-col space-y-5">
<p class="text-gray-700">
Start a new local Elixir node to evaluate code. Whenever you reconnect this runtime,
a fresh node is started.
</p>
<.form
:let={f}
for={@changeset}
as={:data}
phx-submit="init"
phx-change="validate"
phx-target={@myself}
autocomplete="off"
spellcheck="false"
>
<div id={"#{@id}-advanced"} class="mb-6">
<div
class="flex items-center gap-0.5 text-gray-700 font-medium cursor-pointer"
phx-click={JS.toggle(to: "##{@id}-advanced [data-toggle]")}
>
<span>Advanced configuration</span>
<.remix_icon icon="arrow-down-s-line" class="text-xl hidden" data-toggle />
<.remix_icon icon="arrow-right-s-line" class="text-xl" data-toggle />
</div>
<div class="mt-2 flex flex-col space-y-4 hidden" data-toggle>
<.text_field field={f[:erl_flags]} label="Erl flags" />
</div>
</div>
<.button type="submit" disabled={@runtime_status == :connecting or not @changeset.valid?}>
{label(@changeset, @runtime_status)}
</.button>
</.form>
</div>
"""
end
defp label(changeset, runtime_status) do
reconnecting? = changeset.valid? and changeset.data == apply_changes(changeset)
case {reconnecting?, runtime_status} do
{true, :connected} -> "Reconnect"
{true, :connecting} -> "Connecting..."
_ -> "Connect"
end
end
@impl true
def handle_event("validate", %{"data" => data}, socket) do
changeset =
socket.assigns.runtime
|> changeset(data)
|> Map.replace!(:action, :validate)
{:noreply, assign(socket, changeset: changeset)}
end
def handle_event("init", %{"data" => data}, socket) do
socket.assigns.runtime
|> changeset(data)
|> apply_action(:insert)
|> case do
{:ok, data} ->
runtime = Runtime.Standalone.new(erl_flags: data.erl_flags)
Session.set_runtime(socket.assigns.session.pid, runtime)
Session.connect_runtime(socket.assigns.session.pid)
{:noreply, socket}
{:error, changeset} ->
{:noreply, assign(socket, changeset: changeset)}
end
end
end