Skip to content
Ocean-Atlasv0.1.0Canonical Knowledge

Component DSL Reference

The @component section defines a logical grouping of FSMs and their connections.

Components are reusable domain units of behavior. They compose multiple behavioral elements and connect their inputs and outputs into a larger logical flow.

A component may:

  • expose typed input ports;
  • expose typed output ports;
  • use FSMs;
  • use nested components;
  • use reusable expressions;
  • connect inputs and outputs between those elements;
  • optionally transform data between connections using mapper expressions.

Components are stateless containers of behavior.

State is owned and managed by the FSMs or other stateful elements used inside the component.

Implementation status: @component is currently a designed DSL capability and has not yet been implemented. Syntax and semantics described in this document may be refined during implementation.


General structure:

@component
<ComponentName>
input : <name1:DataType1> & <name2:DataType2> & ...
output : <name1:DataType1> & <name2:DataType2> & ...
use expression <ExpressionName>
use fsm <FSMName> as <alias>
use component <ComponentName> as <alias>
connect <source> -> <target>

A component may define multiple FSMs, expressions, nested components, and connections.


A component is defined by its name followed by its ports, used elements, and connections.

Example:

@component
OrderFlow
input : orderRequest:OrderRequest & shipmentConfirmed:ShipmentEvent
output : orderCreated:OrderCreatedEvent & emailTriggered:EmailTrigger
use fsm OrderFSM as order
use fsm ShippingFSM as shipping
connect orderRequest -> order.create
connect shipmentConfirmed -> shipping.ship
connect order.output.created -> shipping.orderCreated
connect shipping.sendEmail -> emailTriggered
connect order.created -> orderCreated

A component name follows the same naming convention as an Ocean datatype name.

Examples:

OrderFlow
CheckoutFlow
PaymentFlow

A component may expose one or more typed input ports.

Syntax:

input : <name>:<Datatype>

Multiple inputs are separated using &.

Example:

input : orderRequest:OrderRequest & shipmentConfirmed:ShipmentEvent

Each input consists of:

  • an input name;
  • an Ocean datatype.

Input names follow Ocean field naming conventions.

Input types must resolve to valid Ocean datatypes.

Component inputs may be connected to:

  • FSM inputs;
  • nested component inputs.

A component may expose one or more typed output ports.

Syntax:

output : <name>:<Datatype>

Multiple outputs are separated using &.

Example:

output : orderCreated:OrderCreatedEvent & emailTriggered:EmailTrigger

Each output consists of:

  • an output name;
  • an Ocean datatype.

Output names follow Ocean field naming conventions.

Output types must resolve to valid Ocean datatypes.

Component outputs receive values from internal FSMs or nested components.


A component may use one or more FSMs.

Syntax:

use fsm <FSMName> as <alias>

Example:

use fsm OrderFSM as order

The alias provides the local name used when referencing the FSM inside the component. The as <alias> clause is mandatory for every use fsm declaration.

Example:

connect orderRequest -> order.create

Multiple FSMs may be used:

use fsm OrderFSM as order
use fsm ShippingFSM as shipping

Aliases should be unique within the component.


A component may compose other components.

Syntax:

use component <ComponentName> as <alias>

Example:

use component AuditFlow as audit

The alias is used to reference the nested component’s inputs and outputs. The as <alias> clause is mandatory for every use component declaration.

Example:

connect order.created -> audit.record

Nested components allow larger behavioral structures to be composed from smaller reusable components.

Components remain stateless containers; state continues to be owned by the stateful elements inside them.


A component may use reusable expressions.

Syntax:

use expression <ExpressionName>

Example:

use expression IsValidCard

Expressions may be used where transformation or reusable logic is required within component connections.

The exact mapper and expression invocation syntax may be refined during implementation.


Connections define how data or signals flow between component ports and internal elements.

Basic syntax:

connect <source> -> <target>

Example:

connect orderRequest -> order.create

Another example:

connect order.created -> orderCreated

Connections are explicit.

This makes the internal composition and data flow of a component visible in the DSL rather than being hidden in implementation code.


Supported connection directions include:

  • Component input → FSM input
  • Component input → nested Component input
  • FSM output → FSM input
  • FSM output → nested Component input
  • nested Component output → FSM input
  • nested Component output → nested Component input
  • FSM output → Component output
  • nested Component output → Component output

Examples:

connect orderRequest -> order.create
connect shipmentConfirmed -> shipping.ship
connect order.output.created -> shipping.orderCreated
connect shipping.sendEmail -> emailTriggered

A source may connect to multiple targets where required.

Connections are typed.

Without an explicit mapper, the source and target must have compatible datatypes.


FSM inputs and outputs are referenced through their local aliases.

Conceptually:

<alias>.<port>

or, where the FSM exposes structured output references:

<alias>.output.<port>

Examples from the current design include:

order.create
order.created
order.output.created
shipping.ship
shipping.sendEmail

Component-level inputs and outputs are referenced directly by their declared names:

orderRequest
shipmentConfirmed
orderCreated
emailTriggered

The exact normalized port-reference model may be refined when @component is implemented.


A connection may require transformation when the source and target datatypes are not directly compatible.

The current design allows an expression or mapper to perform this conversion.

Conceptually:

connect <source> -> <target> : <Mapper>

Example:

connect orderApi.createOrder -> flow.create : MyMapper

The mapper transforms the source value into the datatype expected by the target.

The exact mapper syntax is not yet finalized and may change during implementation.

Until then, the normative semantic rule is:

  • directly compatible source and target types may be connected without a mapper;
  • incompatible types require an explicit transformation;
  • transformations should use reusable Ocean expressions or mapper definitions rather than implicit conversion.

A source may connect to multiple targets where required.

Conceptually:

connect <source> -> <target1>, <target2>, ...

This allows one output or input signal to feed multiple downstream elements.

Example conceptually:

connect order.created -> shipping.orderCreated, audit.orderCreated

The exact syntax for multiple-target connections may be refined during implementation.

Each target must be type-compatible with the source or use an appropriate mapper.


A component does not own persistent or in-memory state itself.

Its responsibility is composition.

State belongs to the stateful elements used by the component, such as FSMs.

Conceptually:

Component
├── inputs
├── FSMs / nested Components / Expressions
├── connections
└── outputs

This separation allows:

  • FSMs to own state and state transitions;
  • expressions to own reusable logic;
  • components to own composition and behavioral flow.

@component
OrderFlow
input : orderRequest:OrderRequest & shipmentConfirmed:ShipmentEvent
output : orderCreated:OrderCreatedEvent & emailTriggered:EmailTrigger
use fsm OrderFSM as order
use fsm ShippingFSM as shipping
connect orderRequest -> order.create
connect shipmentConfirmed -> shipping.ship
connect order.output.created -> shipping.orderCreated
connect shipping.sendEmail -> emailTriggered
connect order.created -> orderCreated

This example demonstrates:

  • component inputs;
  • component outputs;
  • multiple FSMs;
  • local FSM aliases;
  • input-to-FSM connections;
  • FSM-to-FSM connections;
  • FSM-to-component-output connections;
  • explicit behavioral composition.

A @component file may import reusable definitions from the Ocean Repository.

Supported imported item types include:

  • datatype;
  • expression;
  • fsm;
  • component.

Example:

@component
@import datatype O.domain.payment.CardInfo@1.2.0 as CardInfo
@import expression O.std.validation.IsValidCard@1.0.0 as IsValidCard
@import fsm O.std.payment.PaymentFSM@2.1.0 as PaymentFSM
@import component O.common.logging.AuditFlow@1.0.0 as AuditFlow
CheckoutFlow
input : request:CardInfo
output : result:PaymentResult
use fsm PaymentFSM as fsm
use component AuditFlow as logger
connect request -> fsm.start
connect fsm.done -> logger.audit
connect logger.done -> result

Imported items are available through their aliases and behave according to the same rules as locally available definitions.

Every imported datatype, expression, FSM, or component requires an explicit as <alias> clause and must be referenced through that alias.

Reusable definitions may also be made available through the supported Ocean include mechanism.


The current design identifies additional component capabilities that may be introduced later.

One candidate is a timer or periodic signaling component that emits signals according to a configured interval.

This capability is not currently part of the canonical @component syntax and should be defined separately when its semantics and implementation are designed.

Other syntax details that may be refined during implementation include:

  • mapper syntax;
  • multiple-target connection syntax;
  • normalized FSM port references;
  • component-to-component connection semantics;
  • validation rules for cyclic component composition.

The intended rules are:

  • A component file starts with @component.
  • A component is a stateless composition unit.
  • Component names follow Ocean datatype naming conventions.
  • Input and output names follow Ocean field naming conventions.
  • Inputs and outputs use valid Ocean datatypes.
  • A component may use multiple FSMs.
  • A component may use nested components.
  • A component may use reusable expressions.
  • Every use fsm and use component declaration requires an explicit alias.
  • FSMs and nested components are referenced through local aliases.
  • Aliases must be unique within a component.
  • Connections explicitly define data or signal flow.
  • Connections are typed.
  • Direct connections require compatible source and target datatypes.
  • Incompatible datatypes require an explicit transformation.
  • A source may connect to multiple targets where supported.
  • State is managed by FSMs or other stateful elements, not by the component itself.
  • Imported datatypes, expressions, FSMs, and components require explicit aliases.
  • Imported definitions may be used according to their DSL type.

Because @component is not yet implemented, syntax marked as conceptual may be refined during implementation.


The @component DSL is related to:

  • dsl.datatype — defines the datatypes used by component inputs, outputs, and connections.
  • dsl.fsm — defines the stateful behavioral units composed by components.
  • dsl.expression — defines reusable logic and transformations that may be used by components and connection mappers.
  • dsl.import — defines the mechanism for importing selected definitions from the Ocean Repository.
  • dsl.include — defines the mechanism for including reusable definitions from the Ocean Repository.

These semantic relationships are declared in the document metadata.