Skip to content
Strata is pre-1.0. APIs, protocol, and storage format may change.

strata_component

Typed headless component contracts for Strata.

Definition(root, context, config, model, message, output) packages component metadata, config codecs, initial state, local updates, replicated event handling, and event-routing ownership. It does not own transport, persistence, presence, a runtime catalog, or a UI framework.

The package targets Erlang and JavaScript. Read the repository's component host contract in the Components and Bindings guide for host responsibilities.

Errors returned when building or operating on a component definition.

Errors include the component kind, root ID when known, and source document ID when relevant. Component code must return errors to the host; it must not drop invalid events or replace invalid state with an empty document.

pub type ComponentError {
InvalidDefinition(field: String, message: String)
InvalidConfig(kind: String, message: String)
InitialDocumentFailed(kind: String, message: String)
SchemaFailed(kind: String, root_id: String, document_id: String, error: schema.FieldError)
DocumentFailed(kind: String, root_id: String, document_id: String, error: strata_document.DocumentError)
NotOwned(kind: String, root_id: String, document_id: String)
InvalidState(kind: String, root_id: String, operation: String, state: String)
}

InvalidDefinition(field: String, message: String)

Section titled “InvalidDefinition(field: String, message: String)”

The definition constructor received an invalid metadata field.

InvalidConfig(kind: String, message: String)

Section titled “InvalidConfig(kind: String, message: String)”

The component's config decoder rejected the supplied value.

InitialDocumentFailed(kind: String, message: String)

Section titled “InitialDocumentFailed(kind: String, message: String)”

The initial_document function could not produce a valid root document.

SchemaFailed(kind: String, root_id: String, document_id: String, error: schema.FieldError)

Section titled “SchemaFailed(kind: String, root_id: String, document_id: String, error: schema.FieldError)”

A schema field read failed while applying a root or child snapshot.

DocumentFailed(kind: String, root_id: String, document_id: String, error: strata_document.DocumentError)

Section titled “DocumentFailed(kind: String, root_id: String, document_id: String, error: strata_document.DocumentError)”

A document merge failed while applying a root or child snapshot.

NotOwned(kind: String, root_id: String, document_id: String)

Section titled “NotOwned(kind: String, root_id: String, document_id: String)”

An event arrived for a document ID the instance does not claim for routing. This error does not describe server-side deletion ownership.

InvalidState(kind: String, root_id: String, operation: String, state: String)

Section titled “InvalidState(kind: String, root_id: String, operation: String, state: String)”

An operation was attempted in a lifecycle state that does not support it.

An opaque typed component definition.

Packages component metadata, config codecs, initial state factory, local update function, replicated event handler, and event-routing ownership query. Build with definition/9. Do not construct directly.

All six type parameters are preserved:

  • root is the phantom schema tag for the root document.
  • context is the host-local value threaded into every operation.
  • config is the persisted component configuration.
  • model is the headless runtime model.
  • message is the local message type.
  • output is the typed value emitted by update.
pub type Definition(a, b, c, d, e, f)

The result of initialising a component instance.

model is the initial headless model. commands are the Strata client commands — typically a single Join for the root document — that the host must send immediately after construction.

pub type Init(a) {
Init(model: a, commands: List(strata_client.Command))
}

The result of applying a replicated Strata event to the component model.

model is the updated model. commands are any follow-up Strata client commands (for example, Join when a remote delta reveals new child references). There are no typed outputs from this path; outputs belong to the local update path only.

pub type Receive(a) {
Receive(model: a, commands: List(strata_client.Command))
}

Lifecycle status of a component instance.

Loading lasts until the component decodes a usable root snapshot. Ready means the root snapshot is decoded and the component can serve operations. Failed means a decode or merge error moved the instance out of the normal path; the error is preserved for the host. Deleted means a root deleted event was received. These labels do not start retries, replay commands, or restart a model. The host must implement each recovery transition.

pub type Status {
Loading
Ready
Failed(ComponentError)
Deleted
}

The result of applying a local component message.

model is the updated model. commands are Strata client commands the host must send (for example, SendDelta after a write). outputs are typed values the host can observe. Outputs are absent from the replicated receive path.

pub type Update(a, b) {
Update(model: a, commands: List(strata_client.Command), outputs: List(b))
}

Decode a config value from a Dynamic using the component's config decoder.

pub fn decode_config(
Definition(a, b, c, d, e, f),
dynamic.Dynamic
) -> Result(c, ComponentError)

Build a typed component definition.

Returns Error(InvalidDefinition(...)) when kind is empty after trimming whitespace or when version is not a positive integer. All closures are stored verbatim; no runtime is started and no registry entry is created.

pub fn definition(
kind: String,
version: Int,
config_encoder: fn(a) -> json.Json,
config_decoder: fn(dynamic.Dynamic) -> Result(a, ComponentError),
initial_document: fn(b, a) -> Result(strata_document.Document(c), ComponentError),
init: fn(b, a, strata_document.DocId(c)) -> Result(Init(d), ComponentError),
update: fn(b, d, e) -> Result(Update(d, f), ComponentError),
receive: fn(b, d, strata_client.Event) -> Result(Receive(d), ComponentError),
owned_document_ids: fn(d) -> List(String)
) -> Result(Definition(c, b, a, d, e, f), ComponentError)

Encode a config value to JSON using the component's config encoder.

pub fn encode_config(
Definition(a, b, c, d, e, f),
c
) -> json.Json

Initialise a component instance from a context, config, and root document ID.

Returns Init(model, commands) where commands are the Strata client commands the host must send immediately (typically a single Join).

pub fn init(
Definition(a, b, c, d, e, f),
b,
c,
strata_document.DocId(a)
) -> Result(Init(d), ComponentError)

Produce the initial root document for a new component instance.

pub fn initial_document(
Definition(a, b, c, d, e, f),
b,
c
) -> Result(strata_document.Document(a), ComponentError)

Return the component's stable kind identifier.

pub fn kind(Definition(a, b, c, d, e, f)) -> String

Return the document IDs this instance claims for event routing.

Includes the root document and any child documents the component has created. The host uses this list to route incoming Strata events to the correct component instance. The generic core delegates this query without checking duplicates. The host must reject claims shared by different instances before committing a model change or sending its commands. These claims do not grant deletion authority.

pub fn owned_document_ids(
Definition(a, b, c, d, e, f),
d
) -> List(String)

Apply a replicated Strata event to the component model.

Returns Receive(model, commands). There are no typed outputs from this path; outputs are emitted only by update.

pub fn receive(
Definition(a, b, c, d, e, f),
b,
d,
strata_client.Event
) -> Result(Receive(d), ComponentError)

Apply a local component message and return the updated model, any Strata client commands, and any typed outputs.

pub fn update(
Definition(a, b, c, d, e, f),
b,
d,
e
) -> Result(Update(d, f), ComponentError)

Return the component's positive version number.

pub fn version(Definition(a, b, c, d, e, f)) -> Int