AshUi.Patch.Compiler (ash_ui v0.1.0)

Copy Markdown View Source

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).

Summary

Functions

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.

Uncached compile straight from the persisted view expression.

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

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).

Functions

cached_table(resource, view_or_opts \\ :view, opts \\ [])

@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(resource, view_or_opts \\ :view, opts \\ [])

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

Uncached compile straight from the persisted view expression.

patch_addressable?(node)

@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(resource, view_or_opts \\ :view, opts \\ [])

@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).