# `Mob.Event.Target`
[🔗](https://github.com/genericjam/mob/blob/master/lib/mob/event/target.ex#L1)

Resolves a `target:` spec to a concrete delivery pid.

See `guides/event_model.md` for the full event model.

## Forms

| Form | Resolves to | When checked |
|------|-------------|--------------|
| `:parent` | nearest stateful ancestor | render time |
| `:screen` | the containing screen | render time |
| `{:component, id}` | named ancestor component | render time |
| atom | registered process | event time (best-effort) |
| pid | that pid | n/a |
| `{:via, mod, key}` | whatever `mod` resolves it to | event time |

Resolution returns either `{:ok, pid}` or `{:error, reason}`. Callers decide
how to handle errors — typically log + drop (for in-tree, this means the
target was unmounted; for external, it was never registered).

# `render_scope`

```elixir
@type render_scope() :: %{
  screen_pid: pid(),
  component_chain: [{Mob.Event.Address.id(), pid()}]
}
```

The render-time scope used to resolve in-tree targets.

- `screen_pid` — the screen GenServer's pid
- `component_chain` — list of `{id, pid}` from outermost to innermost
  stateful ancestor of the widget being registered

# `spec`

```elixir
@type spec() ::
  :parent
  | :screen
  | {:component, Mob.Event.Address.id()}
  | atom()
  | pid()
  | {:via, module(), term()}
```

The user-facing form passed in `target:` props.

# `classify`

```elixir
@spec classify(spec()) :: :in_tree | :external
```

Classify a target spec as `:in_tree` or `:external`.

In-tree targets get framework guarantees (staleness check, lifecycle
cleanup); external targets are best-effort delivery.

# `resolve`

```elixir
@spec resolve(spec(), render_scope()) :: {:ok, pid()} | {:error, atom()}
```

Resolve a target spec to a pid using the render-time scope.

In-tree forms (`:parent`, `:screen`, `{:component, id}`) are resolved
against `scope`. External forms (atom/pid/via) are resolved against the
process registry at the moment of resolution.

Returns `{:ok, pid}` or `{:error, reason}`.

## Examples

    iex> Mob.Event.Target.resolve(:parent, %{screen_pid: self(), component_chain: []})
    {:ok, self()}

    iex> Mob.Event.Target.resolve(:screen, %{screen_pid: self(), component_chain: []})
    {:ok, self()}

    iex> Mob.Event.Target.resolve(self(), %{screen_pid: self(), component_chain: []})
    {:ok, self()}

---

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