# `A2UICore.Validation.ComponentsUpdate`
[🔗](https://github.com/a2ui-elixir/a2ui/blob/v0.1.1/umbrella/apps/a2ui_core/lib/a2ui_core/validation/components_update.ex#L1)

Validates a batch of incoming components against the surface they
update, before any of them is committed.

The checks run in the reference's order and stop at the first group
that fails:

  1. ids are unique within the batch (`:integrity`, detail code
     `duplicate_id`);
  2. every component satisfies its catalog (`:validation`; the details
     of all failing components are reported together, and the message
     reads `Validation failed for component 'Type': path: message`);
  3. the *prospective* graph — the surface's components with the batch
     laid over them — satisfies the catalog's composition constraints,
     has its root, resolves every reference, and is acyclic and fully
     reachable (see `A2UICore.Validation.Topology`).

Which checks apply is decided by the `A2UICore.Validation.Config`.

From v1.0 a function call that names no `catalogId` runs in the
surface's default catalog; a component in another catalog is validated
with its `catalogId`, so the validator leaves those calls to the
processor's nested-call pass (`A2UICore.Validation.NestedCalls`).

# `catalog_for`
*since 0.1.0* 

```elixir
@type catalog_for() :: (A2UICore.State.Component.t() -&gt; A2UICore.Catalog.t() | nil)
```

Maps a component to the catalog it is validated against.

# `info`
*since 0.1.0* 

```elixir
@spec info(A2UICore.State.Component.t(), A2UICore.Catalog.t() | nil) ::
  A2UICore.State.Component.info() | nil
```

What a catalog knows about a component, in the shape
`A2UICore.Validation.Topology` consumes.

# `validate`
*since 0.1.0* 

```elixir
@spec validate(
  A2UICore.State.Components.t(),
  [A2UICore.State.Component.t()],
  catalog_for(),
  A2UICore.Validation.Config.t(),
  keyword()
) :: :ok | {:error, A2UICore.Error.t()}
```

Validates `incoming` against `existing`. Returns `:ok` or
`{:error, %A2UICore.Error{}}`; nothing is changed either way.

Options: `:default_catalog_id` — the surface's default catalog (`nil`
when it has none).

---

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