SignalsWatch
A unified, production-ready reactive framework for signals_flutter with auto-registering signal factories, lifecycle callbacks, debouncing, throttling, async helpers, and comprehensive debug tools.
Features
✅ Unified API
- Single class: All functionality in
SignalsWatch- signals, reactive widgets, registry, observer - Static factories:
SignalsWatch.signal<T>(),SignalsWatch.computed<T>()with auto-registration - Async helpers:
SignalsWatch.fromFuture<T>(),SignalsWatch.fromStream<T>()for reactive async values - Registry management: Track and dispose signals globally with
register(),disposeAll(),size - Selective observer:
initializeSignalsObserver()for debug logging of labeled signals only
🎯 Reactive Widget
- Multiple modes: Single signal, multiple signals, custom read function, selector pattern
- Lifecycle callbacks:
onInit,onValueUpdated,onAfterBuild,onDisposeat both signal and widget levels - Callback override precedence: Widget callbacks override signal callbacks
- Optional previous value: Callbacks can accept both current and previous values
- Effect replacement:
onValueUpdated(with optional previous value) replaces the need for creating a manualeffect(() { ... })insignals_flutterwhen you just want to react to changes of the watched signals. - StatelessWidget friendly: No need to write StatefulWidget boilerplate
⏱️ Timing Control
- Debouncing: Wait for changes to settle (e.g., search input)
- Throttling: Limit update frequency (e.g., scroll events)
🛡️ Error Handling
onError: Catch and handle read errorserrorBuilder: Custom error UI (defaults to red text)loadingBuilder: Custom loading UI (defaults to CircularProgressIndicator)
🔍 Debug & Development
- Selective observer: Log only labeled signals with
initializeSignalsObserver() - Auto-logging: Built-in
debugPrintfor lifecycle events - Debug labels: Name signals for easier tracking
🎨 Advanced Patterns
- Selector pattern: Only rebuild when selected part of value changes
- Transform with
.transform(): Transform signal values with error handling - Batch updates: Efficiently combine multiple signals
- Builder caching: Prevents redundant rebuilds
- Modular architecture: Clean separation of concerns with library parts
Installation
Add to your pubspec.yaml:
dependencies:
signals_watch: ^1.0.0
Quick Start
import 'package:flutter/material.dart';
import 'package:signals_watch/signals_watch.dart';
// Create auto-registered signals
final counter = SignalsWatch.signal(0);
final doubled = SignalsWatch.computed(() => counter.value * 2);
class MyWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
// Option 1: Fluent syntax
return counter.observe(
(value) => Text('$value'),
onValueUpdated: (value) => debugPrint('Counter: $value'),
);
// Option 2: Traditional syntax
return SignalsWatch<int>.fromSignal(
counter,
onValueUpdated: (value) => debugPrint('Counter: $value'),
builder: (value) => Text('$value'),
);
}
}
Examples
The example/ directory contains a comprehensive set of examples demonstrating the features of signals_watch. These include:
- Basic counter example
- Debounced search
- Conditional updates
- Selector pattern
- Combining multiple signals
- Transforming signal values
- Async handling with
fromFutureandfromStream - Debugging with labeled signals
Refer to the example/lib/main.dart file for detailed implementations.
License
MIT License - see LICENSE file for details.
Contributing
Contributions are welcome! Please open an issue or PR on GitHub.
Publishing
For first publish run:
dart pub get
dart pub publish --dry-run
dart pub publish
Update the version in pubspec.yaml and add a new section in CHANGELOG.md for subsequent releases.
Libraries
- main
- signals_watch
- A production-ready reactive widget for signals_flutter with lifecycle callbacks, debouncing, throttling, error handling, and more.