# `Raxol.Gateway.Adapter.Email.ThreadStore`
[🔗](https://github.com/DROOdotFOO/raxol/blob/raxol_gateway-v0.2.0/lib/raxol/gateway/adapter/email/thread_store.ex#L1)

Remembers the last inbound message per email conversation so an outbound
reply can thread against it.

`Raxol.Gateway.Adapter.Email.send_message/3` cannot learn the inbound
`Message-ID` from its arguments -- the `Raxol.Gateway.Adapter` contract is
frozen at `(conn, route, rendered)`. This store closes that gap: the inbound
feed's wiring records each normalized message here (keyed by the conversation
address), and the adapter reads it back at send time through the `conn`'s
`:thread_lookup` function, which `thread_lookup_fn/1` builds.

The store is a small in-memory cap map (one entry per conversation address,
most-recently-seen wins), bounded by `:max_entries` (default 10_000) with
oldest-recorded eviction. It holds only mail metadata (`Message-ID`,
references, subject) -- never message bodies.

## Wiring

    {:ok, store} = ThreadStore.start_link(name: MyThreads)

    on_message = fn raw ->
      case Email.normalize_event(raw) do
        {:ok, route, event} ->
          ThreadStore.record_event(store, route, event)
          SessionRouter.route(router, route, event)

        :ignore ->
          :ok
      end
    end

    {:ok, conn} =
      Email.connect(
        relay: relay,
        from: from,
        thread_lookup: ThreadStore.thread_lookup_fn(store)
      )

# `meta`

```elixir
@type meta() :: %{optional(atom()) =&gt; term()}
```

# `child_spec`

Returns a specification to start this module under a supervisor.

See `Supervisor`.

# `handle_manager_cast`

# `handle_manager_info`

# `lookup`

```elixir
@spec lookup(GenServer.server(), String.t()) :: {:ok, meta()} | :none
```

The recorded inbound message for `key`, or `:none`.

# `record`

```elixir
@spec record(GenServer.server(), String.t(), meta()) :: :ok
```

Record the inbound message `meta` for a conversation `key`.

# `record_event`

```elixir
@spec record_event(GenServer.server(), Raxol.Gateway.Route.t() | map(), map()) :: :ok
```

Record the inbound message from a normalized `{route, event}`.

A no-op unless the event carries the `:email` metadata `normalize_event/1`
produces, so it is safe to call on every routed event.

# `start_link`

```elixir
@spec start_link(keyword()) :: GenServer.on_start()
```

# `thread_lookup_fn`

```elixir
@spec thread_lookup_fn(GenServer.server()) :: (map() -&gt; meta() | nil)
```

A `(route -> meta | nil)` function for `Email.connect`'s `:thread_lookup`.

Resolves the reply-threading metadata for a route by its `chat_id` (the
conversation address); `nil` when nothing has been recorded yet.

---

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