# `StarView.Elements`
[🔗](https://github.com/Neophen/star_view/blob/v0.7.0/lib/star_view/elements.ex#L1)

Datastar `datastar-patch-elements` helpers.

# `format_patch`

```elixir
@spec format_patch(iodata() | tuple() | nil, keyword()) :: String.t()
```

Formats an element patch event without writing to a connection.

# `format_remove`

```elixir
@spec format_remove(String.t(), keyword()) :: String.t()
```

Formats an element removal event without writing to a connection.

# `patch`

```elixir
@spec patch(Plug.Conn.t(), iodata() | tuple() | nil, keyword()) :: Plug.Conn.t()
```

Sends HTML elements to the browser for DOM patching.

## Skipping unchanged patches

Inside `StarView.Stream.run/2`, `only_changed: true` with an explicit `:key`
skips a patch whose HTML, selector, mode, namespace and view-transition
setting and SSE metadata all equal the last patch sent under that key on this stream.

    patch(conn, html, key: :orders, selector: "#orders", only_changed: true)

Only idempotent modes (`:outer`, `:inner`, `:replace`) are accepted, since
repeating an append, prepend, before, after or remove has a visible effect.
The comparison uses a SHA-256 digest. Each stream tracks up to 64 keys; later
keys always send. A new stream starts empty, and conns outside an active
`run/2` (such as event responses) always send. `format_patch/2` ignores these
options.

The stream only knows what it sent, not the browser's final DOM. Any other
element patch or removal on the same stream (including `execute_script/3`)
clears every remembered key, so the next keyed patch sends again. Event
responses, other streams, raw `StarView.send/4` events and browser code can
still change the DOM unseen: use `only_changed` only for a region this stream
owns exclusively. Give each key its own non-overlapping region; two keys that
target the same or nested elements can skip a patch the page needs.

# `remove`

```elixir
@spec remove(Plug.Conn.t(), String.t(), keyword()) :: Plug.Conn.t()
```

Sends an element removal patch.

