# `Drafter.Runtime.Renderer`
[🔗](https://github.com/jaman/drafter/blob/main/lib/drafter/runtime/renderer.ex#L1)

Rendering pipeline for Drafter applications.

Converts a widget hierarchy into terminal output via the compositor.
Stateless — no process state, no message passing.

# `rect`

```elixir
@type rect() :: %{
  x: integer(),
  y: integer(),
  width: non_neg_integer(),
  height: non_neg_integer()
}
```

A rectangle in terminal cells, as carried through the render pipeline.

# `create_widget_layers_from_hierarchy`

```elixir
@spec create_widget_layers_from_hierarchy(map(), rect(), non_neg_integer()) :: [map()]
```

One compositor layer per visible widget in `hierarchy`.

Widgets listed in the hierarchy's `:hidden_widgets` set are skipped. `z_base` is
added to each layer's z-index, so a screen's layers can be lifted above the app's.
Default: `0`. The `rect` argument is accepted for call-site symmetry and ignored;
each layer is bounded by its own widget rect.

# `rebuild_hierarchy`

```elixir
@spec rebuild_hierarchy(module(), term(), rect(), map() | nil) :: map() | nil
```

Rebuild the widget hierarchy for `app_module`'s current state without painting.

Mounts, updates and hides widgets exactly as `render_app/4` would, so events that
arrive before the next painted frame are routed against the tree the state
describes. Returns the hierarchy to reuse, or `existing_hierarchy` while screens are
pushed on the screen manager or the app's `render/1` returned something other than a
component tree.

# `render_app`

```elixir
@spec render_app(module(), term(), rect(), map() | nil) ::
  {:ok, map() | nil} | {:error, nil}
```

Render one frame for `app_module` and return the hierarchy to reuse next frame.

With screens pushed on the screen manager, the screens are rendered and
`existing_hierarchy` is returned untouched. With toasts but no screens, the app's
hierarchy is rebuilt first so the toast composites over it. Otherwise the app is
rendered directly, reusing `existing_hierarchy` when the app state hash and layout
are both unchanged.

Returns `{:ok, hierarchy}`, `{:ok, nil}` when the app's `render/1` returned strips
rather than a component tree, or `{:error, nil}` when it returned `{:error, reason}`.

# `render_hierarchy`

```elixir
@spec render_hierarchy(map(), rect()) :: :ok
```

Composite an already-built hierarchy and push the result to the compositor.

Used on the fast path, when the app state and layout are unchanged and no widget
tree needs rebuilding. Any pushed screens and toasts are composited on top.

# `render_screens_from_manager`

```elixir
@spec render_screens_from_manager(rect(), module(), term(), map() | nil) :: :ok
```

Composite the app, every screen on the screen stack, and any toasts, in that order.

`existing_hierarchy` supplies the app's base layers when it is not `nil`; otherwise
the app is re-rendered to produce them. Note the argument order: `screen_rect` comes
first here, unlike `render_app/4`.

# `update_hierarchy_preferred_sizes`

```elixir
@spec update_hierarchy_preferred_sizes(map()) :: map()
```

Refresh each widget's cached state from its server and recompute preferred sizes.

Widgets whose entry carries no live pid are left alone, as is a widget whose server
fails to answer — its previously cached state is kept.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
