Skip to main content

Crate omena_reactive

Crate omena_reactive 

Source
Expand description

Static reactive graph primitives for read-only control-plane observation.

The graph records values and effect receipts but performs no external effects. Callers retain authority over scheduling, persistence, and output. Input deposits made during a wave are deferred until the next wave.

Every node requires an explicit ChangePolicyV0. Omitting the policy is a compile-time error:

use omena_reactive::{ReactiveGraphBuilderV0, ReactiveStateV0, ReactiveValueV0};

let mut graph = ReactiveGraphBuilderV0::new();
graph.add_input(ReactiveStateV0::available(ReactiveValueV0::Counter(1)));

§Public API evolution contract

The public enums are non-exhaustive so downstream consumers must retain a future-variant branch. This protects variant-set growth; it does not make variant order, payload types, method signatures, serialized labels, or behavioral meaning compatible by itself.

Public enumProtected evolutionResidual contract
ReactiveValueV0New variants can be appended without breaking exhaustive downstream matches.Derived Ord makes declaration order observable; variants must be appended, and payload or ordering changes remain breaking.
ReactiveStateV0New availability states can be introduced.Existing payload types and propagation semantics remain contracts.
StabilizeStatusV0New stabilization outcomes can be introduced; its named-field variants are also non-exhaustive.Existing field types and the meaning of settled versus pending remain contracts.
ReactiveEngineErrorV0New engine failures can be introduced; named-field variants are also non-exhaustive.Existing error meaning, field types, and display text are not protected by the enum attribute.
DeltaFoldParityErrorV0New parity failures can be introduced; named-field variants are also non-exhaustive.Digest meaning, field types, and display text remain contracts.
ReactiveNodeKindV0New static node kinds can be introduced.Existing discriminant order and operation meaning remain contracts.
ReactiveGraphBuildErrorV0New construction failures can be introduced; named-field variants are also non-exhaustive.Existing field types and error meaning remain contracts.
ReactiveDivergenceClassV0New reviewed mismatch classes can be introduced.Machine IDs, taxonomy meaning, and ordering remain contracts.
ReactiveObservationPhaseV0New observation phases can be introduced.Existing phase meaning remains a behavioral contract.
ReactiveDivergenceDispositionV0New review dispositions can be introduced.Existing disposition meaning remains a behavioral contract.

ReactiveDivergenceClassV0::all returns a static slice rather than a fixed-size array. This keeps the const, allocation-free API while removing array length from the public signature when the taxonomy grows.

The six public structs have these construction dispositions:

Public structConstruction disposition
ReactiveUnavailableV0Public fields remain readable, but the non-exhaustive struct prevents external literals so fields may be added compatibly.
EffectReceiptV0Public fields remain readable, but the non-exhaustive struct prevents external literals so receipt metadata may grow.
ReactiveNodeIdV0All fields are crate-private; external construction is already impossible, so no struct attribute is needed.
ReactiveGraphBuilderV0All fields are private; callers construct it with new or Default.
ChangePolicyV0All fields are private; callers use the explicit policy constructors, and no Default is intentionally provided.
ReactiveEngineV0All fields are private; callers obtain an engine by building a graph.

Each example below is an external-consumer contract probe. It must remain a compile failure because an exhaustive downstream match would make adding a variant a breaking change.

use omena_reactive::ReactiveValueV0;

fn exhaustive(value: ReactiveValueV0) {
    match value {
        ReactiveValueV0::Unit => {}
        ReactiveValueV0::Bool(_) => {}
        ReactiveValueV0::Counter(_) => {}
        ReactiveValueV0::Text(_) => {}
        ReactiveValueV0::StringSet(_) => {}
        ReactiveValueV0::TextMap(_) => {}
        ReactiveValueV0::Tuple(_) => {}
        ReactiveValueV0::Digest(_) => {}
    }
}
use omena_reactive::ReactiveStateV0;

fn exhaustive(value: ReactiveStateV0) {
    match value {
        ReactiveStateV0::Available(_) => {}
        ReactiveStateV0::Unavailable(_) => {}
    }
}
use omena_reactive::StabilizeStatusV0;

fn exhaustive(value: StabilizeStatusV0) {
    match value {
        StabilizeStatusV0::Settled { .. } => {}
        StabilizeStatusV0::Pending { .. } => {}
    }
}
use omena_reactive::ReactiveEngineErrorV0;

fn exhaustive(value: ReactiveEngineErrorV0) {
    match value {
        ReactiveEngineErrorV0::InvalidNode { .. } => {}
        ReactiveEngineErrorV0::NodeDoesNotAcceptDeposits { .. } => {}
        ReactiveEngineErrorV0::ObserverMutationDuringWave => {}
        ReactiveEngineErrorV0::ZeroStepBudget => {}
    }
}
use omena_reactive::DeltaFoldParityErrorV0;

fn exhaustive(value: DeltaFoldParityErrorV0) {
    match value {
        DeltaFoldParityErrorV0::InvalidNode { .. } => {}
        DeltaFoldParityErrorV0::NotDeltaFold { .. } => {}
        DeltaFoldParityErrorV0::Diverged { .. } => {}
    }
}
use omena_reactive::ReactiveNodeKindV0;

fn exhaustive(value: ReactiveNodeKindV0) {
    match value {
        ReactiveNodeKindV0::Input => {}
        ReactiveNodeKindV0::Map => {}
        ReactiveNodeKindV0::Zip => {}
        ReactiveNodeKindV0::Switch => {}
        ReactiveNodeKindV0::DeltaFold => {}
        ReactiveNodeKindV0::AsyncResult => {}
        ReactiveNodeKindV0::EffectBoundary => {}
    }
}
use omena_reactive::ReactiveGraphBuildErrorV0;

fn exhaustive(value: ReactiveGraphBuildErrorV0) {
    match value {
        ReactiveGraphBuildErrorV0::EmptyChangePolicyName { .. } => {}
        ReactiveGraphBuildErrorV0::DuplicateDeltaKey { .. } => {}
        ReactiveGraphBuildErrorV0::ForeignNodeId { .. } => {}
    }
}
use omena_reactive::ReactiveDivergenceClassV0;

fn exhaustive(value: ReactiveDivergenceClassV0) {
    match value {
        ReactiveDivergenceClassV0::FlushConeClosureTiming => {}
        ReactiveDivergenceClassV0::MidWaveReadTiming => {}
    }
}
use omena_reactive::ReactiveObservationPhaseV0;

fn exhaustive(value: ReactiveObservationPhaseV0) {
    match value {
        ReactiveObservationPhaseV0::DuringWave => {}
        ReactiveObservationPhaseV0::Flush => {}
    }
}
use omena_reactive::ReactiveDivergenceDispositionV0;

fn exhaustive(value: ReactiveDivergenceDispositionV0) {
    match value {
        ReactiveDivergenceDispositionV0::BenignUntilFlush => {}
        ReactiveDivergenceDispositionV0::Blocker => {}
    }
}

Structs§

ChangePolicyV0
A named semantic equivalence relation used to decide whether a new node value should propagate.
EffectReceiptV0
ReactiveEngineV0
ReactiveGraphBuilderV0
ReactiveNodeIdV0
An append-only node index branded by the builder that minted it.
ReactiveUnavailableV0
A node-local failure. Unavailability propagates as data and never poisons unrelated nodes or the graph itself.

Enums§

DeltaFoldParityErrorV0
ReactiveDivergenceClassV0
Reviewed mismatch classes for observations made before a wave flushes.
ReactiveDivergenceDispositionV0
ReactiveEngineErrorV0
ReactiveGraphBuildErrorV0
ReactiveNodeKindV0
ReactiveObservationPhaseV0
ReactiveStateV0
The complete state of one node.
ReactiveValueV0
Values carried by the static graph.
StabilizeStatusV0

Type Aliases§

MapOperationV0
ZipOperationV0