RamalLive.Router (RamalLive v0.2.0)

Copy Markdown View Source

The router macro that mounts the inspector.

Import it in the host's router and put the macro where the page should live, inside the host's own scope, pipeline and live_session, so the page gets the host's root layout, its LiveView socket and its JavaScript, and goes through the host's authentication:

import RamalLive.Router

scope "/admin", MyAppWeb do
  pipe_through [:browser, :require_admin]

  live_session :admin, on_mount: [{MyAppWeb.UserAuth, :ensure_admin}] do
    ramal_inspector "/ramal", domain: MyApp.Farm, pubsub: MyApp.PubSub, actor: {MyAppWeb.Inspector, :actor}
  end
end

Why it does not open a live_session of its own, as Phoenix.LiveDashboard does: that would give the page a root layout and a socket path other than the host's, and an asset pipeline to carry the JavaScript. See ADR 0015.

The inspector can merge, approve, reject, discard and fork any branch of the domain. Put it behind the host's own authorization; nothing in RamalLive checks who is looking. Two mounts in one live_session share its authorization, because the page reads its options from the route that the URL the browser joins with matches: give mounts that differ in who may use them a live_session each. See SECURITY.md for the full list.

Options

  • :domain - the Ash domain whose branches are shown. Required.
  • :pubsub - the host's Phoenix.PubSub name, which the page subscribes to for live updates. Required, and the same one given to RamalLive.Broadcaster.
  • :actor - {module, function}. Required. Called as module.function(socket) when someone forks, merges, discards, approves or rejects, and returning the actor, or nil when nobody is signed in. The actor is recorded as :decided_by and, for merge and approve, replays the log as that actor (:actor of Ramal.merge/2). When it returns nil the page refuses every action. It is required because a page that acts for nobody lets whoever reaches the route merge every branch with the actors the writes were captured with, and leaves the decision with no decider (ADR 0016). A router that leaves it out does not compile, and a route mounted without it (with live) raises when the page opens.
  • :debounce - milliseconds to wait, after a branch changes, before the page reads it again. A branch that writes in a loop causes one read per window instead of one per write. 0 reads at once. Default: 50.

Example

ramal_inspector "/ramal", domain: MyApp.Farm, pubsub: MyApp.PubSub, actor: {MyAppWeb.Inspector, :actor}

Summary

Functions

Mounts the inspector at path. See the module doc for the options.

Functions

ramal_inspector(path, opts)

(macro)

Mounts the inspector at path. See the module doc for the options.

Example

ramal_inspector "/ramal", domain: MyApp.Farm, pubsub: MyApp.PubSub, actor: {MyAppWeb.Inspector, :actor}