# `Sourced.Middleware.Domain`
[🔗](https://gitlab.com/dimakula/sourced/-/blob/0.2.0/lib/sourced/middleware/domain.ex#L1)

Converts domain event structs into event maps and back again.

Configured with the list of domain event modules the store knows about, so
callers can append plain structs and get them back from queries, while the
store persists a stable string in the `type` column:

    Sourced.EventStore.new(
      adapter: Sourced.EventStore.Postgres,
      config: [repo: MyApp.Repo],
      middleware: [
        {Sourced.Middleware.Domain, [OrderPlaced, OrderCancelled]}
      ]
    )

Returned `Sourced.StoredEvent`s carry the event module in `type` — the stored
string is an implementation detail of the store, so what goes in comes back
out.

Each entry is a struct module using `Sourced.Middleware.Domain.Event`.
Its stored type is the module's `c:Sourced.Middleware.Domain.Event.to_type/0`,
which defaults to the full module name (`MyApp.OrderPlaced` becomes
`"MyApp.OrderPlaced"`) and can be overridden on the module itself.

Appending a bare struct also derives its tags from
`c:Sourced.Middleware.Domain.Event.to_tags/1`, so queries can match the event
by the domain concepts it concerns rather than by type alone. A caller-built
event map keeps whatever tags it was given.

`c:Sourced.Middleware.init/1` validates the list when the store is built:
every module must implement that behaviour and define a struct, and modules and
types must be unique. It also builds the type lookup tables once, so no work is
repeated per operation.

See `Sourced.EventStore` for the append and query ergonomics this enables.

# `t`

```elixir
@type t() :: %Sourced.Middleware.Domain{
  by_module: %{required(module()) =&gt; type()},
  by_type: %{required(type()) =&gt; module()}
}
```

The compiled lookup tables for the registered events.

# `type`

```elixir
@type type() :: String.t()
```

The stored type of an event, e.g. `"MyApp.OrderPlaced"`.

# `init`

```elixir
@spec init([module()]) :: t()
```

Validates the registered event modules and compiles them into lookup tables.

Runs when the store is built, so registered event modules must already be
compiled.

---

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