Breeze.RemoteInspector.Page behaviour (Breeze v0.5.0)

Copy Markdown View Source

Behaviour for custom remote inspector pages.

An inspected application registers pages with its server:

Breeze.Server.start_link(
  view: MyApp.View,
  inspector: [pages: [MyApp.TimelinePage]]
)

App-registered pages are published with the inspector snapshot and shown while that app is the active source. The page module must also be available to the inspector node. If it is missing, the tab remains visible and reports which package needs to be added to the inspector project.

Register page modules directly in the inspector configuration:

inspector: [
  pages: [
    MyApp.TimelinePage,
    MyApp.ToolsPage
  ]
]

Each page defines its display label and optional initial assigns through page/1. A page registered as a bare module receives an empty keyword list. Assigns accept a map or keyword list:

def page(_opts) do
  [label: "Runtime tools", assigns: %{mode: :compact, limit: 200}]
end

Register a page as {module, options} to pass per-registration options. A page may contribute generic runtime hooks; hook declarations remain inside the source application and are not published to the remote inspector:

def page(opts) do
  [
    label: "Runtime tools",
    runtime_hooks: [{MyApp.RuntimeHook, opts}]
  ]
end

render/1 receives the standard :breeze assigns, the active source server PID, page-specific assigns, and page state. Pages can explicitly request optional source details with request/3:

{:ok, snapshot} = Breeze.RemoteInspector.Page.request(assigns, :snapshot)

{:ok, tree} =
  Breeze.RemoteInspector.Page.request(assigns, :render_tree,
    kind: :rendered,
    limit: 200
  )

This keeps the default page contract small and avoids coupling every page to the inspector's internal caches.

Interactive pages can return {:noreply, state} from handle_event/3 or handle_info/2. That state is scoped to the page id and inspected source, then merged into future render assigns. Asynchronous page messages should use message/2 so replies retain that source:

send(inspector_pid, Breeze.RemoteInspector.Page.message(assigns, result))

Use this module to define a page with Breeze template support:

defmodule MyApp.TimelinePage do
  use Breeze.RemoteInspector.Page

  def page(_opts), do: [label: "Timeline"]

  def render(assigns) do
    ~H"<box>Timeline</box>"
  end
end

Summary

Functions

Wraps an asynchronous message for this page and inspected source.

Requests optional details from the active source application.

Requests source details and raises if they are unavailable.

Returns the active source server PID from page assigns.

Types

detail()

@type detail() :: :snapshot | :render_tree | :stats

Callbacks

handle_event(term, map, map)

(optional)
@callback handle_event(term(), map(), map()) :: {:noreply, map()} | :noreply

handle_info(term, map)

(optional)
@callback handle_info(term(), map()) :: {:noreply, map()} | :noreply

page(keyword)

@callback page(keyword()) :: keyword() | map()

render(map)

@callback render(map()) :: any()

Functions

message(assigns, message)

@spec message(map(), term()) :: {:remote_inspector_page, term(), term()}

Wraps an asynchronous message for this page and inspected source.

request(assigns, detail, opts \\ [])

@spec request(map(), detail(), keyword()) :: {:ok, term()} | {:error, term()}

Requests optional details from the active source application.

Supported requests are :snapshot, :render_tree, and :stats.

request!(assigns, detail, opts \\ [])

@spec request!(map(), detail(), keyword()) :: term()

Requests source details and raises if they are unavailable.

source_server_pid(assigns)

@spec source_server_pid(map()) :: pid() | nil

Returns the active source server PID from page assigns.