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

Throttle / debounce config for high-frequency event subscriptions.

See `guides/event_model.md` and `PLAN.md` Batch 5.

## Forms accepted

    on_scroll: {pid, tag}                        # default: 30 Hz throttle
    on_scroll: {pid, tag, throttle: 100}         # 10 Hz
    on_scroll: {pid, tag, throttle: 0}           # raw firing rate (no throttle)
    on_scroll: {pid, tag, debounce: 200}         # only after 200 ms of stillness
    on_scroll: {pid, tag, throttle: 50, delta: 4} # 20 Hz + 4 px delta threshold

Defaults differ by event type:

| Event | Default throttle | Default delta |
|---|---|---|
| `:scroll` | 30 Hz (33 ms) | 1 px |
| `:drag` | 60 Hz (16 ms) | 1 px |
| `:pinch` | 60 Hz (16 ms) | 0.01 (1%) |
| `:rotate` | 60 Hz (16 ms) | 1° |
| `:pointer_move` | 30 Hz (33 ms) | 4 px |

## Resulting native config

Parsed config is passed across the NIF boundary as a small map (or atom for
the default). The native side stores this per registered handle and
enforces it before any `enif_send` is issued.

# `config`

```elixir
@type config() :: %{
  throttle_ms: non_neg_integer(),
  debounce_ms: non_neg_integer(),
  delta_threshold: number(),
  leading: boolean(),
  trailing: boolean()
}
```

# `event_kind`

```elixir
@type event_kind() :: :scroll | :drag | :pinch | :rotate | :pointer_move
```

# `default?`

```elixir
@spec default?(event_kind(), config()) :: boolean()
```

Returns true if the throttle config equals the defaults — used by the
renderer to skip serialising trivial configs across the NIF boundary.

# `default_for`

```elixir
@spec default_for(event_kind()) :: config()
```

Returns the default throttle config for an event kind.

    iex> Mob.Event.Throttle.default_for(:scroll)
    %{throttle_ms: 33, debounce_ms: 0, delta_threshold: 1, leading: true, trailing: true}

    iex> Mob.Event.Throttle.default_for(:pointer_move).throttle_ms
    33

# `parse`

```elixir
@spec parse(
  event_kind(),
  keyword()
) :: config()
```

Parse a user-supplied opts list into a normalised config.

Always returns a complete config (defaults filled in). Validates that
numeric fields are non-negative and the right types.

    iex> Mob.Event.Throttle.parse(:scroll, [])
    %{throttle_ms: 33, debounce_ms: 0, delta_threshold: 1, leading: true, trailing: true}

    iex> Mob.Event.Throttle.parse(:scroll, throttle: 100)
    %{throttle_ms: 100, debounce_ms: 0, delta_threshold: 1, leading: true, trailing: true}

    iex> Mob.Event.Throttle.parse(:scroll, throttle: 0)
    %{throttle_ms: 0, debounce_ms: 0, delta_threshold: 1, leading: true, trailing: true}

    iex> Mob.Event.Throttle.parse(:scroll, debounce: 200)
    %{throttle_ms: 33, debounce_ms: 200, delta_threshold: 1, leading: true, trailing: true}

---

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