# `MOQX.Helpers`
[🔗](https://github.com/dmorn/moqx/blob/main/lib/moqx/helpers.ex#L1)

Optional convenience helpers built on top of the low-level `MOQX` core API.

This module composes core primitives and typed lifecycle events; it does not
change core message contracts.

# `catalog_payload`

```elixir
@type catalog_payload() :: MOQX.catalog_payload()
```

Raw CMSF catalog payload bytes (UTF-8 JSON).

# `await_catalog`

```elixir
@spec await_catalog(MOQX.fetch_ref(), timeout()) ::
  {:ok, MOQX.Catalog.t()} | {:error, String.t()}
```

Collects fetch messages for `ref` and decodes the payload as a CMSF catalog.

# `await_track_active`

```elixir
@spec await_track_active(MOQX.track(), timeout()) ::
  :ok | {:error, :timeout | MOQX.RequestError.t()}
```

Waits until the given publisher track becomes active.

Returns `:ok` on activation, `{:error, :timeout}` if no lifecycle event
arrives within `timeout`, or `{:error, %MOQX.RequestError{code: :track_closed}}`
if the track closes first.

# `fetch_catalog`

```elixir
@spec fetch_catalog(MOQX.session(), Keyword.t()) ::
  {:ok, MOQX.fetch_ref()} | {:error, MOQX.RequestError.t()}
```

Fetches the raw catalog track bytes.

Thin wrapper over `MOQX.fetch/4` with catalog defaults.

## Options

  * `:namespace` - broadcast namespace. Default: `"moqtail"`.
  * `:track` - catalog track name. Default: `"catalog"`.
  * any other options are passed through to `MOQX.fetch/4`.

# `publish_catalog`

```elixir
@spec publish_catalog(MOQX.broadcast(), catalog_payload()) ::
  {:ok, MOQX.track()} | {:error, MOQX.RequestError.t()}
```

Creates and publishes the initial catalog object on the `"catalog"` track.

# `update_catalog`

```elixir
@spec update_catalog(MOQX.track(), catalog_payload()) ::
  :ok | {:error, MOQX.RequestError.t()}
```

Writes one catalog object to an existing catalog track.

# `write_frame_when_active`

```elixir
@spec write_frame_when_active(MOQX.track(), binary(), timeout()) ::
  :ok | {:error, :timeout | MOQX.RequestError.t()}
```

Waits for track activation, then writes one frame.

---

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