Top-level declarative lifecycle-bound entity in the Bloom reactive DAG.
A Tether represents a non-propagating lifecycle node whose active state is strictly governed by enclosing tracking scopes via BloomVia.tether.
Architectural Separation of Concerns
In the Bloom framework, reactivity is organized across two decoupled planes:
- Data Plane (Bloom): Reactive nodes that evaluate and propagate state mutations downstream via the 2-Phase Push-Dirty / Lazy-Pull DAG.
- Lifecycle Plane (Tether): Declarative entities (such as side-effects, resource cleanups, or stream listeners) whose activation, deactivation, and epoch sweeping are bound directly to an enclosing reactive scope.
System Architectural Flow
[Enclosing Scope (computed / terminal)]
│
▼ (via.tether(tetherNode))
[Tether Node (e.g. Effect)]
│
├─► Scope activates ──► Tether activates (allocates / listens)
├─► Scope deactivates ──► Tether deactivates (dormant / releases)
└─► Non-propagating ──► Never emits dirty pulses upstream
Key Invariants & Architectural Benefits
- Subscriber-Driven Dormancy: A Tether is automatically activated when its enclosing scope activates, and deactivated (dormant) when the scope becomes dormant or is swept during dynamic epoch pruning.
- Non-Propagating Invariant: Tethers never emit dirty invalidation pulses or newer versions downstream to parent watch scopes.
- 1-Pass Dynamic Epoch Pruning: Tethers declared in inactive conditional branches are automatically detached and swept in a single pass at the end of the evaluation turn.
Examples
final loggingEffect = Effect([userId.bloom], () {
analytics.logEvent('user_updated');
});
final userDashboard = computed((via) {
// Binds the lifecycle of loggingEffect to the active lifetime of this computed node:
via.tether(loggingEffect);
return 'Dashboard for ${via(userId.bloom)}';
});
- Implemented types
- Available extensions
Properties
- debugCreationLocation → String?
-
Available on T, provided by the TetherDebugExtension extension
The exact code location where this tether was instantiated in debug mode.no setter - debugLabel ↔ String?
-
Available on T, provided by the TetherDebugExtension extension
A developer-defined label to identify this tether in debug mode.getter/setter pair - hashCode → int
-
The hash code for this object.
no setterinherited
- isActive → bool
-
Whether the node is currently active (connected to a downstream terminal).
no setterinherited
- runtimeType → Type
-
A representation of the runtime type of the object.
no setterinherited
Methods
-
debugTrace(
[String? label, int traceCount = 5]) → void -
Available on T, provided by the TetherDebugExtension extension
Captures the current stack trace and assigns an optional label to this tether. -
noSuchMethod(
Invocation invocation) → dynamic -
Invoked when a nonexistent method or property is accessed.
inherited
-
toString(
) → String -
A string representation of this object.
inherited
-
withDebugLabel(
String label) → T -
Available on T, provided by the TetherDebugExtension extension
Assigns a developer-defined debug label and returns this tether.
Operators
-
operator ==(
Object other) → bool -
The equality operator.
inherited