# `Bourse.WS.MessageRouter`
[🔗](https://github.com/ZenHive/bourse/blob/main/lib/bourse/ws/message_router.ex#L1)

Routes decoded WS frames to payload families using envelope extraction.

Channel → family resolution reads `websocket.dispatch` via `Bourse.WS.Dispatch`.

# `route_result`

```elixir
@type route_result() ::
  {:routed, atom(), term(), String.t()} | {:system, map()} | {:unknown, map()}
```

# `extract_channel`

```elixir
@spec extract_channel(map(), map()) :: String.t() | nil
```

Extracts the channel name using the envelope's `discriminator_field`.

# `extract_data`

```elixir
@spec extract_data(map(), map()) :: term()
```

Extracts payload data using the envelope's `data_field`.

# `extract_market_id`

```elixir
@spec extract_market_id(String.t() | nil) :: String.t() | nil
```

Extracts a market id segment from a dot-delimited channel string.

# `get_nested`

```elixir
@spec get_nested(map(), String.t() | nil) :: term()
```

Resolves a dot-notation path in a nested map.

# `route`

```elixir
@spec route(map(), Bourse.Exchange.t()) :: route_result()
```

Routes a decoded WS message for an exchange.

# `route`

```elixir
@spec route(map(), map() | nil, Bourse.Exchange.t()) :: route_result()
```

Routes a decoded WS message using an explicit envelope config.

---

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