The state of one UI surface: its identity, catalog selection, theme, data model and components.
A surface is plain data. Mutating operations return the updated
surface (and, where something observable happened, effects); nothing
is delivered by callback. The processor (A2UICore.Processor) is what
applies protocol messages to surfaces.
:id— the surface id, unique within a group.:catalog_id— the default catalog's id (niluntil resolved).:catalogs—%{catalog_id => catalog}available to the surface.:theme— theme properties (v0.9; empty under v1.0).:send_data_model— whether the renderer should attach this surface's data model to outbound action messages.:root_id— the entry component,"root"by default.:data_model— anA2UICore.State.DataModel.:components— anA2UICore.State.Components.:version— the protocol version the surface was created under.:metadata— free-form host data, never sent on the wire.
Summary
Functions
The surface's default catalog, or nil when it has none.
Builds the action event a component interaction produces, or nil
when payload is not an action.
Releases the surface's resources: detaches data-model subscriptions.
Reads from the surface's data model; see A2UICore.State.DataModel.get/2.
Creates a surface. Options: :catalog_id, :catalogs, :theme,
:send_data_model, :root_id, :data_model (a model or initial
data), :version, :metadata.
The surface's protocol version: its default catalog's, or, for a v1.0 surface without a default catalog, the version it was created under.
Replaces the surface's components.
The catalog an item on the surface runs in: the one catalog_id
names (nil names none; an empty string names a catalog too), else
the default catalog. subject describes the item in the error, as in
"Function call 'formatString'".
Writes into the surface's data model; see A2UICore.State.DataModel.set/3.
Types
@type t() :: %A2UICore.State.Surface{ catalog_id: String.t() | nil, catalogs: %{optional(String.t()) => term()}, components: A2UICore.State.Components.t(), data_model: A2UICore.State.DataModel.t(), id: String.t(), metadata: map(), root_id: String.t(), send_data_model: boolean(), theme: map(), version: String.t() | nil }
Functions
@spec default_catalog(t()) :: A2UICore.Catalog.t() | nil
The surface's default catalog, or nil when it has none.
@spec dispatch_action(t(), term(), String.t(), DateTime.t()) :: map() | nil
Builds the action event a component interaction produces, or nil
when payload is not an action.
payload is either an action object (%{"name" => …, "context" => …})
or %{"event" => %{…}}, optionally carrying a "catalogId". The
event has name, surfaceId, sourceComponentId, timestamp
(RFC 3339, UTC), context (empty when absent or not an object) and,
when present, catalogId and userMessage.
now is the event time; it defaults to the current UTC time and is
a parameter so callers and tests can keep the core deterministic.
iex> surface = A2UICore.State.Surface.new("main")
iex> now = ~U[2026-01-02 03:04:05Z]
iex> A2UICore.State.Surface.dispatch_action(surface, %{"name" => "save"}, "btn", now)
%{
"name" => "save",
"surfaceId" => "main",
"sourceComponentId" => "btn",
"timestamp" => "2026-01-02T03:04:05Z",
"context" => %{}
}
Releases the surface's resources: detaches data-model subscriptions.
@spec get_data(t(), term()) :: {:ok, term()} | {:error, A2UICore.Error.t()}
Reads from the surface's data model; see A2UICore.State.DataModel.get/2.
Creates a surface. Options: :catalog_id, :catalogs, :theme,
:send_data_model, :root_id, :data_model (a model or initial
data), :version, :metadata.
iex> surface = A2UICore.State.Surface.new("main", send_data_model: true)
iex> {surface.id, surface.root_id, surface.send_data_model}
{"main", "root", true}
The surface's protocol version: its default catalog's, or, for a v1.0 surface without a default catalog, the version it was created under.
@spec put_components(t(), A2UICore.State.Components.t()) :: t()
Replaces the surface's components.
@spec resolve_catalog(t(), String.t() | nil, String.t()) :: {:ok, A2UICore.Catalog.t()} | {:error, A2UICore.Error.t()}
The catalog an item on the surface runs in: the one catalog_id
names (nil names none; an empty string names a catalog too), else
the default catalog. subject describes the item in the error, as in
"Function call 'formatString'".
@spec set_data(t(), term(), term()) :: {:ok, t(), [A2UICore.State.DataModel.notification()]} | {:error, A2UICore.Error.t()}
Writes into the surface's data model; see A2UICore.State.DataModel.set/3.