flowr_dart 2.13.0
flowr_dart: ^2.13.0 copied to clipboard
Base FlowR library for pure Dart
FlowR Dart #
State management based on Reactive programming for pure Dart.
Install #
dart pub add flowr_dart
Tip
If you are using Flutter, it is highly recommended to use the flowr package, which provides MVVM support and Flutter-specific features.
Getting started #
import 'package:flowr_dart/flowr_dart.dart';
class Counter extends FlowR<int> {
@override
final int initValue;
Counter({required this.initValue});
incrementCounter() => update((old) {
logger('incrementCounter: $old');
return old + 1;
});
incrementSlowly() => update(
(old) async {
await Future<void>.delayed(const Duration(milliseconds: 300));
return old + 1;
},
mutexTag: 'counter',
);
}
Future<void> main() async {
Logger.root.level = Level.INFO;
Logger.root.onRecord.listen(LoggableMx.devLogRecordPrinter);
final counter = Counter(initValue: 0);
await counter.incrementCounter();
print('counter: ${counter.value}');
counter.dispose();
}
Core APIs #
FlowR<T>stores the current value in aValueStream<T>.updatereads the current value, runs an updater, catches failures, and callsputon success.runCatchingis available for non-state work that should share the same error and skip handling.skpIfandskpNullthrowSkipError, which stops the current flow without treating it as a failure.autoDispose(subscription)cancels registered stream subscriptions whendisposeis called.
Concurrency #
update and runCatching can be scheduled with:
debounceTag: wait until calls stop, then run the last call.throttleTag: run at most once during the configured window.mutexTag: run immediately and ignore overlapping calls with the same tag.slowlyMs: window size in milliseconds for debounce and throttle.
Tags are scoped to the FlowR instance. Use stable tag values for each independent action.
ValueStream helpers #
final names = counter.stream.distinctWith((count) => 'count: $count');
final evenValues = counter.stream.whereValue((count) => count.isEven);
mapValuemaps both stream events and synchronousvalueaccess.distinctBykeeps the latest emitted value for the selected key.distinctWithmaps then de-duplicates mapped values.whereValuekeeps the latest value that passed the filter. If no value has passed yet,hasValueisfalse,valueOrNullisnull, andvaluethrows.
Logging #
FlowR uses package:logging. Configure the root logger once in your app:
Logger.root.level = Level.INFO;
Logger.root.onRecord.listen(LoggableMx.devLogRecordPrinter);
Set Logger.root.level = Level.FINE to see normal put, debounce, throttle, mutex, and SkipError logs.
Disposal #
Call dispose when a FlowR instance is no longer used. This closes the state subject, cancels subscriptions registered through autoDispose, and disposes pending debounce, throttle, or mutex timers.
Run example #
Demo FlowR: for dart main.dart
# From workspace root
dart run examples/example/lib/main.dart