# `Layr8.Handler`
[🔗](https://github.com/layr8/elixir_sdk/blob/main/lib/layr8/handler.ex#L1)

Registry mapping DIDComm message types to handler functions.

## Handler Signature

A handler is a function with the signature:

    (Layr8.Message.t()) -> {:reply, Layr8.Message.t()} | :noreply | :pass | {:error, term()}

## Registration

    registry = Layr8.Handler.new()
    registry = Layr8.Handler.register(registry, "https://example.com/proto/1.0/request", fn msg ->
      {:reply, %Layr8.Message{type: "https://example.com/proto/1.0/response", body: %{text: "pong"}}}
    end)

## Protocol Derivation

`protocols/1` returns the unique protocol base URIs derived from registered handler types
by stripping the last path segment:

    "https://layr8.io/protocols/echo/1.0/request" → "https://layr8.io/protocols/echo/1.0"

# `entry`

```elixir
@type entry() :: %{fn: handler_fn()}
```

# `handler_fn`

```elixir
@type handler_fn() :: (Layr8.Message.t() -&gt;
                   {:reply, Layr8.Message.t()}
                   | :noreply
                   | :pass
                   | {:error, term()})
```

# `t`

```elixir
@type t() :: %{optional(String.t()) =&gt; entry(), optional(:catch_all) =&gt; entry()}
```

# `lookup`

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

Looks up a handler entry for the given message type.

Returns `{:ok, entry}` or `:error`. Falls back to the catch-all handler
when no exact match exists.

# `new`

```elixir
@spec new() :: t()
```

Creates a new empty handler registry.

# `protocols`

```elixir
@spec protocols(t()) :: [String.t()]
```

Returns the unique protocol base URIs derived from registered handler types.

Strips the last path segment from each registered type.

## Example

    iex> registry = Layr8.Handler.new()
    iex> registry = Layr8.Handler.register(registry, "https://example.com/proto/1.0/request", fn _ -> :noreply end)
    iex> Layr8.Handler.protocols(registry)
    ["https://example.com/proto/1.0"]

# `register`

```elixir
@spec register(t(), String.t(), handler_fn()) :: t()
```

Registers a handler for a DIDComm message type.

Raises if a handler is already registered for `msg_type`.

# `register_catch_all`

```elixir
@spec register_catch_all(t(), handler_fn()) :: t()
```

Registers a catch-all handler invoked when no specific handler matches.

Raises if a catch-all handler is already registered.

---

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