Non-DSL entry point for using the Lavash reactive graph from a plain Phoenix.LiveView.
This is the path for "I want the reactive recomputation machinery
without the Spark DSL, the ~L template transformer, or the optimistic
JS hook." You get the dependency graph and automatic recomputation; you
write mount/3, handle_event/3, and render/1 like any other
Phoenix.LiveView.
Compare with use Lavash.LiveView, which adds the DSL (state,
actions), the template transformer (~L), URL/socket-backed state,
forms, bindings, overlays, and the optimistic JS hook — a much larger
API surface in exchange for less code at the call site.
Example
defmodule MyAppWeb.CounterLive do
use Lavash.LiveView.Explicit
reactive do
state :count, 0
state :step, 1
derive :doubled, rx(@count * @step)
end
@impl Phoenix.LiveView
def handle_event("inc", _, socket) do
{:noreply, put_state(socket, :count, &(&1 + 1))}
end
@impl Phoenix.LiveView
def render(assigns) do
~H"""
<p>{@count} (doubled = {@doubled})</p>
<button phx-click="inc">+</button>
"""
end
endWhat use Lavash.LiveView.Explicit does for you
use Phoenix.LiveViewand importsLavash.Rx.rx/1.mount/3is provided automatically and callsLavash.Reactive.init/2with the graph built fromreactive do ... end. You can override it;super(params, session, socket)does the lavash init.handle_info/2dispatches{:lavash_reactive, ...}messages from async derives toLavash.Reactive.handle_async/2. Other messages fall through to the user's clauses.put_state/3is a single-call helper that combinesLavash.Reactive.put/3+Lavash.Reactive.recompute/1so you can't forget the recompute.- The graph is cached in
:persistent_term. An@after_compilehook drops the cache when the module recompiles in dev.
What's NOT included
- No URL-backed or socket-backed state; you wire
handle_params/3yourself. - No
~Ltemplate transformer. Use~H. No auto-injecteddata-lavash-*attributes. - No optimistic JS hook. Updates take a server round-trip.
- No
bind=, no<.lavash_component>, no forms, no overlays. These are DSL features.
Summary
Functions
Mutates a state field and immediately recomputes the dependent graph.
Declares the reactive graph for this LiveView.
Functions
Mutates a state field and immediately recomputes the dependent graph.
Equivalent to Lavash.Reactive.put/3 |> Lavash.Reactive.recompute/1
but in one call so the "forgot to recompute" footgun goes away.
def handle_event("inc", _, socket) do
{:noreply, put_state(socket, :count, &(&1 + 1))}
endAccepts either a literal value or a 1-arity function that receives the current value.
Declares the reactive graph for this LiveView.
Accepts a block of state name, default and derive name, rx_expr
(with optional opts) calls. Translates to a Lavash.Reactive builder
pipeline at compile time.
reactive do
state :count, 0
derive :doubled, rx(@count * 2)
derive :slow, rx(fetch(@count)), async: true
end