# `Choreo.Lab.DSL.FSM`
[🔗](https://github.com/code-shoily/choreo/blob/v0.14.1/lib/choreo/lab/dsl/fsm.ex#L1)

Experimental Livebook-friendly DSL for sketching finite-state machines.

This Lab DSL compiles to the stable, pipe-first `Choreo.FSM` builders and
returns an ordinary `%Choreo.FSM{}`. It follows the same identity rule as the
infrastructure Lab DSL: in assignment form, the variable name becomes the node
id and the string becomes the display label; in inline form, the string is
slugged into an id and also used as the label.

## Examples

    iex> import Choreo.Lab.DSL.FSM
    ...> machine = fsm do
    ...>   idle = initial("Idle")
    ...>   authorized = state("Authorized")
    ...>   denied = final("Denied")
    ...>
    ...>   idle ~> authorized |> on("token valid")
    ...>   edge idle ~> denied, with: "token invalid"
    ...> end
    iex> Choreo.FSM.initial_state(machine)
    :idle
    iex> Choreo.FSM.final_states(machine)
    [:denied]
    iex> Choreo.FSM.transitions(machine) |> Enum.sort()
    [{:idle, :authorized, "token valid"}, {:idle, :denied, "token invalid"}]

Transition labels can use pipe modifiers or the explicit `edge` form:

    idle ~> authorized |> on("token valid")
    idle ~> authorized |> label("token valid")
    idle ~> authorized |> guard("claims.tenant == request.tenant")
    edge idle ~> denied, "token invalid"
    edge idle ~> denied, with: "token invalid"
    edge idle ~> denied, label: "token invalid"

# `state_decl`

```elixir
@type state_decl() :: %{id: Yog.node_id(), builder: atom(), opts: keyword()}
```

# `transition_decl`

```elixir
@type transition_decl() :: %{from: Yog.node_id(), to: Yog.node_id(), opts: keyword()}
```

# `done`

# `edge`

# `final`

# `fsm`
*macro* 

Builds a `%Choreo.FSM{}` from a compact Lab DSL block.

# `fsm`
*macro* 

# `guard`

# `init`

# `initial`

# `label`

# `on`

# `start`

# `state`

# `taxonomy`

```elixir
@spec taxonomy() :: %{
  states: [atom()],
  edges: [atom()],
  modifiers: [atom()],
  options: [atom()]
}
```

Returns the vocabulary supported by the FSM DSL.

This is meant as a lightweight Livebook discovery helper when autocomplete is
not enough.

    iex> taxonomy = Choreo.Lab.DSL.FSM.taxonomy()
    iex> :initial in taxonomy.states
    true
    iex> :~> in taxonomy.edges
    true
    iex> :guard in taxonomy.modifiers
    true

# `verbs`

```elixir
@spec verbs() :: %{
  states: [atom()],
  edges: [atom()],
  modifiers: [atom()],
  options: [atom()]
}
```

Compatibility alias for `taxonomy/0`.

---

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