Tether class abstract base

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:

  1. Data Plane (Bloom): Reactive nodes that evaluate and propagate state mutations downstream via the 2-Phase Push-Dirty / Lazy-Pull DAG.
  2. 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

  1. 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.
  2. Non-Propagating Invariant: Tethers never emit dirty invalidation pulses or newer versions downstream to parent watch scopes.
  3. 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