signals_watch 1.0.0
signals_watch: ^1.0.0 copied to clipboard
A production-ready reactive widget for signals_flutter with lifecycle callbacks, debouncing, throttling, error handling, async helpers, and registry management.
1.0.0 #
Stable Release #
- First stable release of
signals_watch. - Includes all features from previous versions, such as:
- Signal-level lifecycle callbacks (
onInit,onValueUpdated,onDispose). - Fluent APIs for observing signals (
.observe(),.selectObserve()). - Timing controls (
debounce,throttle). - Error handling with
onErroranderrorBuilder. - Async helpers (
fromFuture,fromStream). - Debugging tools (
debugLabel,SelectiveSignalsObserver).
- Signal-level lifecycle callbacks (
- Comprehensive examples and test coverage.
- Documentation updated to reflect all features.
0.4.0 - 2025-11-18 #
Added #
.transform()extension onReadonlySignal<T>for transforming signal values with error handling- Perfect for transformations that might throw exceptions (validation, parsing, computed values)
- Includes all SignalsWatch features: error handling, debouncing, lifecycle callbacks, etc.
- Example:
mySignal.transform((v) => v * 2, builder: (result) => Text('$result'), errorBuilder: ...)
Changed #
- Enhanced error handling documentation with clearer examples
- Added import comment for
kDebugModeusage
0.3.1 - 2025-11-17 #
Fixed/Docs #
- Update README to document v0.3.0 signal-level lifecycle callbacks, widget override precedence, and reset API
- Example app: add trailing commas and minor formatting fixes to satisfy analyzer lints (no behavior changes)
- No functional code changes in library APIs
0.3.0 - 2025-11-17 #
Added #
- Signal-level lifecycle callbacks for all signal types (signal, computed, fromFuture, fromStream)
- Widget-level callbacks now override signal-level callbacks with proper precedence
.reset()method on signals to restore initial value and trigger callbacks- Async helpers now forward lifecycle callbacks consistently
- Internal metadata registry for initial values and callbacks
Changed #
- Documentation updated to reflect lifecycle callbacks, overrides, and reset API
- Example app updated to use the observer initializer and fluent APIs
0.2.1 - 2025-11-17 #
Maintenance #
- Republish after sensitive file cleanup and doc corrections. No code changes.
Changelog #
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
0.2.0 - 2025-11-17 #
Added #
- Fluent API extensions for more ergonomic syntax:
.observe()extension onReadonlySignal<T>- watch any signal (regular, computed, fromFuture, fromStream).selectObserve()extension onReadonlySignal<T>- selector pattern with efficient updates.observe()extension onList<ReadonlySignal<dynamic>>- combine multiple signals
- Comprehensive test coverage for all new extension methods (28 tests total)
- Example app updated to demonstrate fluent syntax
Design Decisions #
- Named
.observe()to avoid conflict withsignals_flutter's existing.watch()extension - Named
.selectObserve()to avoid conflict withsignals' existing.select()extension - All original constructors remain available for backward compatibility
- Fluent API is purely additive syntax sugar
Examples #
// Single signal - fluent syntax
counter.observe((value) => Text('$value'))
// Selector pattern - only rebuilds when age changes
user.selectObserve(
(u) => (u as User).age,
(age) => Text('Age: $age'),
)
// Multiple signals - combines values
[firstName, lastName].observe(
combine: (values) => '${values[0]} ${values[1]}',
builder: (fullName) => Text(fullName),
)
0.1.0 - 2025-11-16 #
Added #
- Initial preview release with unified
SignalsWatchclass - Unified API: All functionality consolidated into a single
SignalsWatchclass - 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:
register(),unregister(),size,disposeAll()for signal lifecycle - Selective observer:
initializeSelectiveObserver()for debug logging of labeled signals only - 4 constructor patterns:
- Default constructor with custom
readfunction .fromSignal()for single signals.fromSignals()for batch updates from multiple signals.select()for selector pattern
- Default constructor with custom
- Lifecycle callbacks:
onInit- Called once on initializationonValueUpdated- Called when value changesonAfterBuild- Called post-frame after every buildonDispose- Called when widget is disposed
- Flexible callback signatures supporting both
(T)and(T, T?)patterns - Conditional updates:
shouldRebuild- Control when widget rebuildsshouldNotify- Control when callbacks fire- Custom
equals- Custom equality checking
- Timing control:
debounce- Wait after last change before updatingthrottle- Minimum time between updates
- Error handling:
onError- Error callbackerrorBuilder- Custom error UI (defaults to red text)loadingBuilder- Custom loading UI (defaults to CircularProgressIndicator)
- Debug tools:
debugLabel- Label for loggingdebugPrint- Auto-log all lifecycle eventsSelectiveSignalsObserver- Track only labeled signals globally
- Production-ready safety:
- Timer cancellation on dispose
- Mounted checks before callbacks
- Assertions preventing misuse (debounce+throttle, empty signals list)
- Try-catch in dispose to prevent exceptions
- Modular architecture:
- Library parts for readability (registry, observer, async, core widget)
- Single public API surface via
SignalsWatchclass - Private implementation details hidden
- Comprehensive documentation and examples
- StatelessWidget-friendly API
Design Decisions #
- Unified class approach: All features consolidated into
SignalsWatchfor simplicity - Static factories:
signal()andcomputed()replace standalone functions, auto-register for cleanup - Modular parts: Code split into logical parts while maintaining single public API
- Auto-registration: All created signals tracked automatically with cleanup on dispose
- Used
Function.apply()to support flexible callback signatures - Timers check
mountedstate before executing callbacks - Dispose method uses try-catch to prevent dispose exceptions
- Assertions added to prevent common mistakes at compile time
[Unreleased] #
Planned #
- Animation support with
AnimationControllerintegration - More comprehensive test coverage
- Performance benchmarks
- Additional async utilities (retries, caching, etc.)