Package-level declarations
Types
A dispatched custom action, delivered as data.
The exception a handler throws to fail a dispatch with a payload: the value is validated against the action's declared failure type and bound to the failure root inside onFailure. Any other exception is a failure with no payload.
An asynchronous receiver of custom actions: one funnel per view. Normal return is success and the returned value, validated against the action's declared result type, binds the result root inside onSuccess; return null for actions declaring no result. Throwing is failure: a MilanoActionFailure carries the failure payload, validated against the declared failure type and bound to the failure root inside onFailure; any other exception is a failure with no payload. Completion-exactly-once holds by construction.
The closed set of typed errors the gate can throw, per the document model spec. Every error carries structured detail; the diagnostic message is non-normative.
One materialized child, ready to place in a layout.
The standard context source: create it with initial values, push updates from any thread.
Supplies and updates context values. Milano validates each change atomically; an invalid update is rejected whole and reported. subscribe returns a cancellation, invoked by the runtime at teardown so a source never retains callbacks for views that are gone.
The serialization seam: everything that touches a view's state runs through its dispatcher, one item at a time. The platform layer binds it to the main thread; the conformance harness injects a pump.
The instantiable root of the framework. An engine holds one configuration: the vocabulary, the registry, the default unknown-type policy, resource limits, the two observers, and the host function handler. It is immutable after creation and safe to share across threads. MilanoViewBuilders are obtained from an engine, so every MilanoView is traceable to exactly one configuration.
Engine-creation errors, per the vocabulary schema spec. These arise at engine creation only; they can never occur at the gate or later.
A host function call (expression spec, Host functions): the declared function's name and its evaluated arguments, in declared order, each already of its declared type.
The engine's synchronous resolver of host functions (contract 2.1), one for every view and every surface's declarations. Invoked on the thread evaluating the expression, during resolution and action evaluation: it must be fast, must not block, must not touch the view, and must be pure over its arguments (vocabulary schema spec, Function declarations). The value is validated against the declared returns; a mismatch or a thrown exception is an invalid function result, reported and replaced by the zero value of the return type. Returning null is the null value.
Milano SDK: a client-only, design-system-agnostic Document-Driven UI framework for Compose.
The common-code default: runs inline, serialized by the caller's thread. The Android source set supplies MilanoMainDispatcher, bound to the main thread; this default suits single-threaded hosts and tests.
The Android main-thread dispatcher, per the threading contract. Runs inline when already on the main thread, so renderer emissions are processed synchronously in FIFO order.
What a renderer receives: the node's resolved values, its materialized children, and the emission surface.
Engine-scoped observer: one integration point per engine for logging and telemetry. Every reported occurrence flows here.
One reported occurrence, delivered to the engine observer, tagged with the originating view. Kinds are the closed union defined by the runtime API spec.
The consumer-provided renderer for unknown component types under the placeholder policy. Receives the raw subtree as data, never as live children.
The binding from vocabulary component types to consumer renderers.
A consumer-provided renderer for one component type: receives the node, emits Compose UI. Invoked in composition on the main thread.
An asynchronous source of initial state values, awaited during building and validated against the document's declarations. Provider errors propagate to the build caller unchanged: they are host errors, not Milano errors.
A type from the document type system: bool, int, double, string, enum over named members, array of T, or record with named typed fields; each optionally optional.
An unknown node routed to the placeholder renderer.
How unknown component types are handled: engine default, per-view override.
One user interaction, delivered to the engine's user-interaction observer. Records pass everything through unredacted (payloads, action parameters, document metadata): Milano implements no tracker, the receiving host owns the data and decides what to do with it.
A receiver of user interactions: the engine's product-analytics stream, separate from MilanoObserver, which carries engine observability only.
The single representation for every value crossing a Milano boundary: resolved properties into renderers, event payloads out of them, action parameters into handlers, context and state values in from the host.
The built, guaranteed-renderable view: bound to one document at a time. Runtime semantics per the state and actions spec; everything mutable runs through the view's serial dispatcher.
The construction gate's public face: a MilanoView is created exclusively through a MilanoViewBuilder, obtained from a MilanoEngine.
Functions
The hosting container, for hosts that want the swap managed for them: presents the loading content immediately, awaits the build, replaces it with the MilanoView's content on success or the failure content on failure. Building starts once per composition lifetime; recompose a new MilanoHost to retry.
The quick path: one composable from raw document and vocabulary text. Engine, registry, and builder are created inside; declared state is synthesized as zero-values (overridable via state); engine and build failures both land in the failure content. Ideal for a first integration or a simple embed; real apps share one engine and use the builder overload.
Zero-values per declaration, overridden by supplied values. The zero is the contract's own (zeroValueOf), so a synthesized value is the same value an invalid function result of that type would produce. Enums are why that matters: this once took the alphabetically first member while the contract takes the first declared, so a preview could differ from the engine over the same declaration. Every value satisfies its declaration, so a provider built on this never fails the gate's data check. The quick path uses it; it is public for providers that have nothing better than a zero-value for some keys. The same function on every engine.
Creates a builder for one document given as raw bytes. The document-size limit is checked against these bytes exactly; the text is decoded as UTF-8.
Creates a builder for one document given as text.