StatifierUI.Kino (StatifierUI v0.9.1)

Copy Markdown View Source

The Livebook inspector: inspect/3 composes the four panes - configuration diagram, datamodel explorer, event injection, event log - over one shared StatifierUI.Trace.Subscriber, attached with catch-up (statifier ADR-0049), inside one Kino.Layout.

Compiled only when the optional :kino dependency is present (ADR-0004); a host without it gets a stub whose inspect/3 raises with instructions. Nothing else in this package touches Kino.

The scrubber (sui-3gg)

Four buttons above the diagram - First, Prev, Next, Live - move the diagram from the live tip to any macrostep in the log and back. Selecting a macrostep draws the configuration that macrostep settled in, opens its entry in the event log, and marks that entry - shown in the diagram; the note above the diagram says which point is on screen. StatifierUI.Inspector decides all of it, so the whole behaviour is testable without Kino - this module only wires buttons to Updater.scrub/2.

Buttons rather than a click target on the log entry itself: the log pane is Kino.Markdown, which renders text and cannot carry a click handler back to the runtime. A directly clickable entry is the ADR-0008 renderer's to give, not Mermaid-and-Markdown's.

Lifecycle

Every process this module starts - the subscriber and the updater - goes through Kino.start_child/1, so re-evaluating the cell terminates them with it. The session notices the dead subscriber through its own monitor and drops it from its subscriber set: that is the clean detach, with nothing to unsubscribe by hand. The session itself is not owned here - it keeps running across cell re-evaluations, which is exactly what makes catch-up worth having.

Catch-up needs record: true

Start the session with record: true (and trace: true) for the inspector to reconstruct everything it missed. Without it the subscriber falls back to live delivery and the status header labels the panes Live-only - a partial stream is never presented as whole. Replay cost grows with run length (it re-runs the recording in the attaching process), so expect cell evaluation on a very long-lived session to take correspondingly longer.

Summary

Functions

Builds the inspector for session and returns the composed Kino.Layout for the cell to render.

Reopens a saved trace: the third leg of StatifierUI.Trace.Capture's record / save / reload.

Renders every bundle a palette discovery found, one panel after another, as a single Kino.Markdown widget.

Renders one fragment's fixture bundle as its "test this step" panel - its truth table plus its expectation results (sui-13q) - as a Kino.Markdown widget.

Renders fixtures' truth table - every expression evaluated across every dataset (ADR-0006) - as a Kino.Markdown widget.

Functions

inspect(session, fixtures \\ nil, opts \\ [])

@spec inspect(pid(), StatifierUI.Fixtures.t() | nil, keyword()) :: Kino.Layout.t()

Builds the inspector for session and returns the composed Kino.Layout for the cell to render.

fixtures is a StatifierUI.Fixtures.t/0 (or nil): it feeds the injection palette's per-event buttons. opts:

  • :source - the SCXML text, forwarded to the subscriber for the session.start manifest.
  • :capacity - the subscriber's buffer capacity (default 1000).

inspect_trace(trace, fixtures \\ nil, opts \\ [])

Reopens a saved trace: the third leg of StatifierUI.Trace.Capture's record / save / reload.

StatifierUI.Kino.inspect_trace("run.jsonl")

trace is a file path (read through StatifierUI.Trace.Capture.load/1) or an already-loaded StatifierUI.Trace.Message.t/0 list. fixtures is accepted for symmetry with inspect/3 and is currently unused - the palette it feeds is an injection affordance, and there is nothing to inject into.

opts:

  • :machine - the compiled %Statifier.Machine{} to draw against. Optional: without it the machine is recompiled from the SCXML the trace carries in its own session.start message, which is what StatifierUI.Trace.Capture.record/3's :source option puts there. A trace captured without :source and reopened without :machine has no chart to draw and returns a Kino.Markdown saying so rather than a diagram it cannot draw.

Stepping it (sui-2uz)

The layout carries the same |< First / < Prev / Next > / Live scrubber inspect/3 has, plus a jump to select listing every macrostep by number and event, and a datamodel diff pane saying what the selected macrostep changed. A persisted stream has no tip that moves, so "Live" here means the end of the recording.

Stepping a recording asks the engine for nothing: every configuration shown was stamped by the engine into the file, and a trace read back through StatifierUI.Trace.Capture.load/1 got its contents from statifier ADR-0034 replay re-driving the core at capture time. The controls move a selection over messages already in hand.

What this is still not

There is no injection form. Injection drives a session, and a file has none. The fixtures argument stays accepted and unused for that reason.

palette_panel(discovery, opts \\ [])

Renders every bundle a palette discovery found, one panel after another, as a single Kino.Markdown widget.

discovery is what StatifierUI.Fixtures.Bundle.discover/2 or discover_dir/2 returned.

test_panel(bundle, opts \\ [])

@spec test_panel(
  StatifierUI.Fixtures.Bundle.t(),
  keyword()
) :: Kino.Markdown.t()

Renders one fragment's fixture bundle as its "test this step" panel - its truth table plus its expectation results (sui-13q) - as a Kino.Markdown widget.

Like truth_table/2, independent of inspect/3 and of any session: a bundle is a fact about one palette entry's examples, so this needs no running chart. opts go to StatifierUI.Fixtures.Bundle.Markdown.render/2, which forwards each one to the layer that owns it.

truth_table(fixtures, opts \\ [])

@spec truth_table(
  StatifierUI.Fixtures.t(),
  keyword()
) :: Kino.Markdown.t()

Renders fixtures' truth table - every expression evaluated across every dataset (ADR-0006) - as a Kino.Markdown widget.

Independent of inspect/3 and of any session: a truth table is a fact about expressions and datasets, so this needs no running chart and no Phoenix. opts are split by owner - :expressions, :datasets, :functions, and :providers go to StatifierUI.TruthTable.build/2, and the rest to StatifierUI.TruthTable.Markdown.render/2.