# `StatifierBlocks.Runtime.Handled`
[🔗](https://github.com/riddler/statifier_blocks/blob/v0.44.1/lib/statifier_blocks/runtime/handled.ex#L1)

Which block's state handled a macrostep, from a trace read model and a
provenance map.

`StatifierBlocks.Runtime.Marks` answers where a run *is*. This answers
where one macrostep *happened*: an author clicking an entry in a run's
event log is pointing at a step, and the useful thing to select for them
is the block whose state took the transition that step selected.

The join is the same shape as `Marks`' and made of the same two halves.
statifier-ui's trace wire format numbers every transition and every state,
and its `session.start` manifest carries the table that turns a transition
number into the index of the state that owns it. This package turns a
state id into the block that produced it
(`StatifierBlocks.Provenance.owner_of_state/2`). Composing the two is the
whole of the resolution.

## The manifest is read as data, not through a module

`statifier_ui` is optional here, so `Marks` takes the read model's
`messages`, `selection` and `initial_configuration` as public fields
rather than as calls. This module goes one step further and reads the
wire format itself: `session.start`'s `transitions` table gives each
transition's `source` state index, its `states` table gives that state's
`id`, and `trace.transitions_selected`'s `t_indexes` names which
transitions a round selected. Those are the format's own published
fields, so nothing here names a statifier-ui module at all - the module
is pure, carries no LiveView presence wrapper, and the headless suite
exercises it directly.

## One transition, and the first one

A round selects a list, and a macrostep holds several rounds. The answer
is the **first** transition the **first** round with a non-empty selection
chose, because that is the transition the macrostep's own event fired: the
rounds below it are the internal cascade that transition started, and
selecting the block that caused the cascade is what an author clicking the
step meant. A macrostep whose every round selected nothing - the initialize
step, which enters states rather than transitioning between them - has no
handler and answers `:error`.

# `block`

```elixir
@spec block(map(), non_neg_integer(), StatifierBlocks.Provenance.t()) ::
  {:ok, String.t()} | :error
```

The block whose state handled `macrostep`, resolved through `provenance`.

`state` is statifier-ui's `StatifierUI.Live.State` - anything carrying a
`messages` list of wire-format messages.

`:error` for every gap, and they are all ordinary rather than exceptional:
a stream with no `session.start` to resolve numbers through, a macrostep
no round of which selected a transition, a transition number the manifest
does not carry, a source state that is anonymous, and a state id this
provenance map does not own - a run over a different chart revision, which
is exactly the case `owner_of_state/2` is written to refuse.

---

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