# `AshUi.Patch.Compiler`
[🔗](https://github.com/hyperbob-labs/ash_ui/blob/main/lib/ash_ui/patch/compiler.ex#L1)

Compiles an AshUi resource's `:view` calculation into a
`AshUi.Patch.Table`: slots with stable addresses + a
field→slots propagation index + keyed list anchors + child tables for
nested `render(Resource, input)`.

Input is the SAME lowered view the segment compiler consumes
(`ViewConstructor.lower/1` over the persisted view expression) — one
authored calculation, two staged evaluations (full render, patch
emission).

# `cached_table`

```elixir
@spec cached_table(module(), atom() | keyword(), keyword()) :: AshUi.Patch.Table.t()
```

The memoized compiled patch table — the ONE table-cache API. Every
transport calls this instead of owning a private cache (socket maps,
per-target process-global terms, ad hoc test caches), so a table is
compiled at most once per (blueprint, view, target, navigation routes)
and a fat table can never ride a per-request closure. The memo itself
lives with the other compile-time contracts in `AshUi.Compiled`.

# `compile`

```elixir
@spec compile(module(), atom() | keyword(), keyword()) :: AshUi.Patch.Table.t()
```

Uncached compile straight from the persisted view expression.

# `patch_addressable?`

```elixir
@spec patch_addressable?(map()) :: boolean()
```

PATCH-ADDRESSABLE — the compile-time property that decides which elements
a runtime patch can target, and therefore which elements carry a runtime
id (morph selectors, reorder anchors, focus handles). An element is
patch-addressable when

  * its attr surface is dynamic (`element_attr_deps/1` != `:static`) — an
    attribute patch selects the element itself, or
  * it DIRECTLY owns a non-element dynamic child (a text/branch/each/child
    slot) — those patches select the nearest enclosing element.

Template and arm ROOTS are addressable by position (entry morphs and
branch-flip morphs target them) and are marked by the skeleton pass, not
by this predicate. Every other element — static wrappers and leaves — is
NOT addressable and must not spend id bytes: at collection scale the
per-element id was the single largest DOM/wire mass after binding keys,
and every marked element forces its whole attr region dynamic.

# `table`

```elixir
@spec table(module(), atom() | keyword(), keyword()) :: AshUi.Patch.Table.t()
```

The compiled patch table: read from the transformer-persisted artifact
when present (compile-time cost paid once, like compiled views), else
compiled on demand (pure).

---

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