Skip to content

feat: rewrite nova_liveboard on Nova + Datastar (drop Arizona) - #5

Merged
Taure merged 6 commits into
masterfrom
feat/datastar-rewrite
May 28, 2026
Merged

feat: rewrite nova_liveboard on Nova + Datastar (drop Arizona)#5
Taure merged 6 commits into
masterfrom
feat/datastar-rewrite

Conversation

@Taure

@Taure Taure commented May 27, 2026

Copy link
Copy Markdown
Contributor

Why

Arizona is deprecated for this use: it moved its HTTP layer from Cowboy to its own roadrunner server, and arizona_nova never followed, so the Nova(cowboy) + arizona_nova bridge the dashboard relied on is dead. This rebuilds nova_liveboard on Nova + Datastar - server-rendered HTML, live updates over SSE, no Arizona, no JS build step, no off-origin requests. Same proven pattern as gakudan_liveboard.

What changed

  • Kept the BEAM data layer (nova_liveboard_data) intact.
  • Replaced every Arizona view with a pure iodata() render layer (nova_liveboard_html) in a new "BEAM mission control" design - deep-space instrument panel, a live vitals deck, nova-gold + signal-cyan accents, self-hosted IBM Plex Mono + datastar.js under a strict default-src 'self' CSP.
  • Live transport (nova_liveboard_sse): one long-lived SSE stream per page region via a registered {stream, ...} return-handler (as a fun/3); polled regions repaint on a timer, the requests feed is event-driven. No Nova patch needed (see Support streamed / long-lived responses (SSE, server-push) — controllers can only return a single buffered reply nova#387).
  • New Requests page + request tracer: a nova_plugin records per-request timing / reductions / handler MFA for every route on the node, plus an opt-in deep mode that scope-traces a request (erlang:trace with set_on_spawn) and shows the exact tree of processes it spawned. Overhead is only paid while armed.
  • Preserves every existing page (overview, processes, metrics, ETS, applications, ports, supervisors, and the Kura database/schemas pages).

Pages

Overview · Metrics · Processes · Requests (new) · Supervisors · Applications · ETS · Ports · Database/Schemas (Kura).

Enabling request tracing

Register the plugin globally in the host's Nova config:

{nova, [{plugins, [
    {pre_request,  nova_liveboard_trace_plugin, #{}},
    {post_request, nova_liveboard_trace_plugin, #{}}
]}]}.

Verification

  • rebar3 fmt --check, rebar3 xref, rebar3 dialyzer all clean.
  • rebar3 eunit - 49 tests, 0 failures (data, html render + escaping, tracer ring buffer + synthetic spawn-tree, plugin summary build, SSE frame shape).
  • Final in-browser verification happens when embedded in a host Nova app (this is a library; no standalone harness was added).

Breaking

Drops the arizona_core / arizona_nova dependencies. Mount via {nova_apps, [nova_liveboard]} instead of arizona_nova, and register nova_liveboard_trace_plugin to enable the Requests page.

Follow-ups

  • Add a Taure/erlang-ci workflow (repo currently has none).
  • Push the latent datastar_nova fun/3 handler fix upstream.

Taure added 6 commits March 26, 2026 11:05
- Remove custom WS handler (nova_liveboard_ws.erl) — use arizona_nova's
  shared WebSocket endpoint
- Remove page controller — replaced with nova_liveboard_controller.erl
  with resolve_view/1 for arizona_nova view resolver
- Add nova_liveboard_app.erl to register views with arizona_nova on start
- Update layout to load JS from arizona_nova prefix
- Move views from src/views/ to src/ (prevents double compilation)
- Remove src_dirs recursive from rebar.config
- Add .gitignore
- Update deps to use novaframework/* repos
- Add dialyzer exclude_mods for view modules
Arizona was deprecated (it moved its HTTP layer to its own roadrunner
server, breaking the Nova/cowboy + arizona_nova bridge), so the dashboard
is rebuilt on Nova + Datastar: server-rendered HTML with live updates over
SSE, no Arizona, no JS build step, no off-origin requests.

- Preserve the BEAM data layer (nova_liveboard_data); replace all Arizona
  views with a pure iodata render layer (nova_liveboard_html) in a new
  "BEAM mission control" design, self-hosted CSS + IBM Plex Mono + datastar.js
  under a strict default-src 'self' CSP.
- Live transport (nova_liveboard_sse): one long-lived SSE stream per page
  region via a registered {stream, ...} return-handler (fun/3); polled
  regions repaint on a timer, the requests feed is event-driven.
- New Requests page + request tracer: a nova_plugin records per-request
  timing/reductions/handler for every route on the node, plus an opt-in deep
  mode that scope-traces a request and shows the tree of processes it spawned.
- Keep every existing page (overview, processes, metrics, ETS, applications,
  ports, supervisors, and the Kura database/schemas pages).
- Full EUnit coverage; fmt/xref/dialyzer clean.

BREAKING CHANGE: drops the arizona_core/arizona_nova dependencies. Mount via
{nova_apps, [nova_liveboard]} instead of arizona_nova, and register
nova_liveboard_trace_plugin in the host's {nova, [{plugins, ...}]} config to
enable the Requests page.
- Add Taure/erlang-ci ci.yml + release.yml pinned to v2.1.1, triggering on
  master with docs paths-ignore. audit/sbom are off for now: they crash on
  this repo's {vsn, git} deps (sbom badarg on the `git` atom; audit on a
  LOW-advisory glyph under OTP 29) - to re-enable once the plugins handle it.
- Add cliff.toml and covertool.
- Fix rebar.lock: nova was mis-pinned to a nova_liveboard commit (an empty dep
  checkout made git rev-parse walk up to the parent repo); now correctly
  9ee7e21.
@Taure
Taure merged commit 21c6570 into master May 28, 2026
15 checks passed
@Taure
Taure deleted the feat/datastar-rewrite branch May 28, 2026 05:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant