BloomState<T> class abstract interface

The universal reactive state protocol in the Bloom framework.

Implemented by all state-bearing entities:

Note that Bloom itself does not implement BloomState directly; instead, it exposes an untracked live view via BloomUntracked.state or scoped tracking via BloomVia.state.

Guarantees consistent state interrogation (BloomState.phase, BloomState.data, BloomState.hasData, BloomState.isEmpty, BloomState.emptyReason, BloomState.hasError, BloomState.error, BloomState.stackTrace) and declarative pattern matching via exhaustive Dart 3 switch on BloomState.phase.

System Architectural Flow

1. 3-State Finite State Machine

                    ┌────────────────────────────────────────┐
                    │   BloomState<T> 3-State State Machine  │
                    └────────────────────────────────────────┘
                           │ (Initial uninitialized / late)
                           ▼
                    ┌──────────────┐         Value Resolved        ┌──────────────┐
                    │    EMPTY     │ ────────────────────────────> │     DATA     │ (hasData == true)
                    │  (isEmpty)   │ <──────────────────────────── │  (payload:T) │
                    └──────┬───────┘       .empty([reason])        └──────┬───────┘
                           │                                              │
                           │ .setError()                      .setError() │
                           ▼                                              ▼
                    ┌─────────────────────────────────────────────────────────────┐
                    │                            ERROR                            │ (hasError == true)
                    │              (payload: Object, [StackTrace])                │
                    └─────────────────────────────────────────────────────────────┘

2. Explicit Dependency Registration vs. Raw Reads

[computed / Effect.via Scope]
            │ (Injected BloomVia parameter)
            ▼
     via(sourceBloom)         ──>  [Registers Source Edge & Returns Payload T]

[Outside Derivation Scope / Raw Read]
            │
     untracked(sourceBloom)   ──>  [Pure Direct Field Dereference (Zero Tracking Overhead)]

Key Invariants & Architectural Benefits

  1. Zero-Overhead Raw Reads & Explicit Tracking: Reading via untracked or BloomUntracked.state directly on a node is a pure field dereference with zero tracking overhead and no dynamic tracking stack penalty. Reactive derivations explicitly declare dependencies via the injected BloomVia parameter (via(node)).
  2. 3-State Exclusivity: A BloomState entity is strictly in one of three mutually exclusive states:
  3. Sound Fail-Fast Extraction: Reading BloomState.data while in Empty or Error state throws BloomSnapshotExtractionException. Use BloomState.dataOrNull, BloomState.dataOrElse, or native Dart 3 switch (state.phase) for safe exhaustive pattern matching.

Warning (Anti-Pattern Prevention):

BAD:

// [Anti-Pattern] Reading untracked without via() bypasses dependency registration
final badComputed = computed((via) {
  return untracked(count.bloom) * 2; // count is NOT tracked!
});

GOOD:

// [Recommended] Explicitly register dependencies through via()
final goodComputed = computed((via) {
  return via(count.bloom) * 2; // Dynamically and explicitly registered
});

Examples

final count = blooming(0);
final doubled = computed((via) => via(count.bloom) * 2);

print(untracked(doubled)); // 0
count.data = 5;
print(untracked(doubled)); // 10
Implementers

Properties

data → T
Extracts the underlying data synchronously from this node or state.
no setter
dataOrNull → T?
Safely extracts the underlying data, returning null if not in a hasData state.
no setter
emptyReason → Object?
The optional reason explaining why this state is empty, or null if unspecified or not empty.
no setter
error → Object
Extracts the underlying exception or failure object from an error state.
no setter
hasData → bool
Whether this state contains a valid, extractable data payload.
no setter
hasError → bool
Whether this state is in a corrupted state containing an error or exception.
no setter
hashCode → int
The hash code for this object.
no setterinherited
isEmpty → bool
Whether this state is in an uninitialized or dormant state.
no setter
phase → BloomPhase
The operational phase (BloomPhase.valid, BloomPhase.empty, or BloomPhase.error) of this state.
no setter
runtimeType → Type
A representation of the runtime type of the object.
no setterinherited
snapshot → BloomSnapshot<T>
The underlying snapshot representing this entity's current state.
no setter
stackTrace → StackTrace
Extracts the call stack trace at the point of failure from an error state.
no setter

Methods

dataOrElse(T fallback()) → T
Safely extracts the underlying data, returning the result of fallback if not in a hasData state.
equals(covariant BloomState<T> other, [bool equals(T previous, T next)?]) → bool
Determines if this state is equivalent to other using an optional custom equals comparator.
noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
toString() → String
A string representation of this object.
inherited

Operators

operator ==(Object other) → bool
The equality operator.
inherited