Lavash.Lifecycle.MountMacro (Lavash v0.4.0-rc.3)

Copy Markdown View Source

Capability: declare what happens at LiveView mount, beyond the state-defaults and reactive-graph initialisation lavash sets up automatically.

Symmetric with messages do message ... end end: the body is an op-sequence drawn from the shared vocabulary (run, effect, set, fire).

Shape

mount do
  fire :report
  fire :weather

  run fn socket ->
    Phoenix.PubSub.subscribe(MyApp.PubSub, "lobby")
    socket
  end
end

Why a block, not a callback override

Vanilla LiveView lets you override mount/3 and do anything. The block form is the declarative version of the common shapes: "fire these asyncs at mount", "subscribe to these topics", "schedule a timer", etc. The shared op vocabulary keeps the DSL internally consistent — the same ops work in mount do, messages do message ..., and (eventually) action bodies.

Firing asyncs

fire :name triggers an async :name do ... end declaration. Nothing about an async declaration is auto-fired — if a mount block doesn't list fire :name, the async never runs at mount. This is the central design choice of the layer-1 trigger model: declarations describe WHAT, lifecycle blocks describe WHEN.

when_connected do ... end

A guard block for ops that should only run when the LiveView is on a real websocket connection — the second mount that happens after the initial HTTP render. Same op vocabulary as the outer block. Compiles to an if Phoenix.LiveView.connected?(socket) wrapping the inner ops.

Use it for PubSub subscriptions, Process.send_after self-timers, and other side effects that would be wasted (or harmful) on the HTTP-only first mount:

mount do
  fire :report

  when_connected do
    run fn socket ->
      Phoenix.PubSub.subscribe(MyApp.PubSub, "lobby")
      Process.send_after(self(), :tick, 1000)
      socket
    end
  end
end

Note: async :foo field defaults are initialised on BOTH mounts (HTTP and websocket) — the field is AsyncResult.loading() on first render whether or not its fire actually executed. That keeps the template's case clauses matching the same shape on both passes.

Summary

Functions

Top-level mount do <ops> end declaration. Registers a list of ops to run at the end of mount, after the runtime has set up state, reactive graph, and assigns projection.

Functions

mount(list)

(macro)

Top-level mount do <ops> end declaration. Registers a list of ops to run at the end of mount, after the runtime has set up state, reactive graph, and assigns projection.