# `Pixir.Events`
[🔗](https://github.com/Ranvier-Technologies/pixir/blob/main/lib/pixir/events.ex#L1)

The event bus facade (ADR 0004, decision D-06): the seam between the core and
every front-end. Front-ends subscribe; the core publishes. A renderer is just a
subscriber that pattern-matches on `event.type`.

Dispatch is backed by a `Registry` (`keys: :duplicate`) keyed by `session_id`.
Callers never touch the Registry directly — only this module. When web/multi-node
support arrives, the backend swaps to `Phoenix.PubSub` behind the same API.

Subscribers receive messages shaped as `{:pixir_event, event}` where `event` is a
`Pixir.Event` map. Subscribers may pass `only: [:status, ...]` to receive a
bounded set of event types when they are acting as runtime control-plane processes
instead of full presenters.

# `publish`

```elixir
@spec publish(Pixir.Event.t()) :: Pixir.Event.t() | {:error, map()}
```

Publish an Event to every subscriber of its `session_id`. Returns the event so it
can be threaded (e.g. logged after publishing). Fan-out only — persistence is the
Session's responsibility (canonical events go to the Log).

# `registry_child_spec`

```elixir
@spec registry_child_spec() :: Supervisor.child_spec()
```

Child spec for the backing Registry (added to the supervision tree).

# `subscribe`

```elixir
@spec subscribe(
  String.t(),
  keyword()
) :: :ok | {:error, map()}
```

Subscribe the calling process to a Session's events. Delivered as
`{:pixir_event, %Pixir.Event{}}` messages.

# `subscriber_count`

```elixir
@spec subscriber_count(String.t()) :: non_neg_integer() | {:error, map()}
```

Number of live subscribers for a Session (mostly for tests/diagnostics).

# `unsubscribe`

```elixir
@spec unsubscribe(String.t()) :: :ok | {:error, map()}
```

Unsubscribe the calling process from a Session's events.

---

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