void_signals library

High-performance signal reactivity library for Dart.

This library provides a reactive system based on signals, computed values, and effects. It is optimized for performance and designed to be the foundation for reactive state management in Dart applications.

Core Concepts

  • Signal: A reactive value that notifies subscribers when changed
  • Computed: A derived value that updates automatically
  • Effect: A side effect that runs when dependencies change
  • EffectScope: A container for grouping related effects

Example

import 'package:void_signals/void_signals.dart';

void main() {
  final count = signal(0);
  final doubled = computed((prev) => count() * 2);

  effect(() {
    print('Count: ${count()}, Doubled: ${doubled()}');
  });

  count(1); // Prints: Count: 1, Doubled: 2
}

Classes

AsyncComputed<T>
A computed value that handles async operations with proper dependency tracking.
AsyncData<T>
Data state with a value.
AsyncDataLike<T>
AsyncError<T>
Error state with an error and stack trace.
AsyncErrorLike<T>
AsyncErrorWithPrevious<T>
Error state that preserves the previous value.
AsyncLoading<T>
Loading state.
AsyncLoadingWithPrevious<T>
Loading state that preserves the previous value.
AsyncSignal<T>
A signal that handles async operations with proper error handling.
AsyncValue<T>
Represents the state of an asynchronous operation.
AsyncValueLike<T>
Light-weight AsyncValue-like types for Result conversion.
Computed<T>
A computed value that automatically updates when its dependencies change.
ComputedNode<T>
A computed node that derives its value from other reactive sources.
Effect
An effect that runs when its dependencies change.
EffectNode
An effect node that reacts to dependency changes.
EffectScope
A scope that manages a group of effects.
A link that keeps an effect or signal alive, preventing automatic disposal.
A link connecting a dependency to a subscriber in the reactive graph.
ReactiveNode
Base class for all reactive nodes in the signal graph.
Result<T>
Result type for signal operations that can fail.
ResultData<T>
A successful result containing a value.
ResultError<T>
An error result.
RetryConfig
Configuration for retry behavior.
ScopeNode
A scope node that manages a group of effects.
Signal<T>
A reactive signal that holds a value and notifies subscribers when changed.
SignalErrorHandler
Global error handler for signal operations.
SignalNode<T>
A signal node that holds a mutable value.
SignalSubscription<T>
Represents a subscription to a reactive value.
SignalSubscriptionImpl<T>
Implementation of SignalSubscription for Signal values.
StreamComputed<T>
A computed value that wraps a Stream with proper lifecycle management.
SubscriptionController
A controller for managing reactive subscriptions.

Enums

AsyncState
State of an async operation.

Mixins

SignalLifecycle
A mixin that provides lifecycle callbacks for reactive nodes.

Extension Types

ReactiveFlags
Reactive flags using extension type for zero-cost abstraction.

Extensions

AsyncComputedLifecycleExtension on AsyncComputed<T>
Extension for AsyncComputed to add lifecycle management.
AsyncComputedListExtension on List<AsyncComputed<T>>
Extension for working with multiple async computeds.
ComputedSubscriptionExtension on Computed<T>
Extension to add subscription capabilities to Computed.
FutureAsyncValueExtension on Future<T>
Safely awaits a Future, catching errors and returning an AsyncValue.
SafeComputedExtension on Computed<T>
Extension to add error-safe operations to Computed.
SafeSignalExtension on Signal<T>
Extension to add error-safe operations to Signal.
SignalSubscriptionExtension on Signal<T>
Extension to add subscription capabilities to Signal.

Functions

asyncComputed<T>(Future<T> compute()) AsyncComputed<T>
Creates an async computed value.
batch<T>(T fn()) → T
Batches multiple signal updates into a single flush.
combineAsync<R>(List<AsyncValue<Object?>> values, R combiner(List<Object?> values)) AsyncValue<R>
Combines multiple AsyncValues into one.
computed<T>(T getter(T? previousValue)) Computed<T>
Creates a new computed value with the given getter function.
computedFrom<T>(T getter()) Computed<T>
Creates a new computed value with a simple getter function.
effect(void fn()) Effect
Creates a new effect that runs the given function.
effectScope(void fn()) EffectScope
Creates a new effect scope.
endBatch() → void
getActiveSub() ReactiveNode?
getBatchDepth() int
isComputed(dynamic value) bool
Returns whether the given function is a computed.
isEffect(dynamic value) bool
Returns whether the given function is an effect.
isEffectScope(dynamic value) bool
Returns whether the given function is an effect scope.
isSignal(dynamic value) bool
Returns whether the given function is a signal.
retry<T>(Future<T> fn(), {RetryConfig config = RetryConfig.defaultConfig, void onRetry(Object error, int attempt)?}) Future<T>
Retries a function with exponential backoff.
retrySync<T>(T fn(), {RetryConfig config = RetryConfig.defaultConfig, void onRetry(Object error, int attempt)?}) → T
Retries a synchronous function.
runGuarded<T>(T fn()) Result<T>
Runs a function and catches any errors.
runGuardedAsync<T>(Future<T> fn()) Future<Result<T>>
Runs an async function and catches any errors.
setActiveSub(ReactiveNode? sub) ReactiveNode?
signal<T>(T value) Signal<T>
Creates a new reactive signal with the given initial value.
startBatch() → void
streamComputed<T>(Stream<T> createStream()) StreamComputed<T>
Creates a stream computed value.
trigger(void fn()) → void
Triggers all subscribers of the tracked dependencies.
untrack<T>(T fn()) → T
Runs a function without tracking dependencies.

Typedefs

DisposeCallback = void Function()
A callback that can be cancelled.