flowr_dart 4.0.2 copy "flowr_dart: ^4.0.2" to clipboard
flowr_dart: ^4.0.2 copied to clipboard

Pure Dart reactive state management primitives for FlowR, built on bloc with update, error handling, logging, and stream helpers.

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> {
  Counter({required int initialState}) : super(initialState);

  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(initialState: 0);
  await counter.incrementCounter();
  print('counter: ${counter.value}');

  counter.dispose();
}

Core APIs #

  • FlowB<E, S> is the bloc-native event-driven base class and extends Bloc<E, S>.
  • FlowR<T> is the method-driven base class and extends Cubit<T>.
  • FlowR<T>.stream uses Cubit's native Stream<T> semantics and does not replay the current state to new subscribers.
  • update reads the current value, runs an updater, catches failures, and calls put on success.
  • runCatching is available for non-state work that should share the same error and skip handling.
  • skpIf and skpNull throw SkipError, which stops the current flow without treating it as a failure.
  • autoDispose(subscription) cancels registered stream subscriptions when dispose is called.

FlowR follows bloc equality semantics: if value == currentValue, listeners are not notified. Prefer immutable state updates, for example update((old) => old.copyWith(...)).

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.

Stream helpers #

final names = counter.stream.distinctWith((count) => 'count: $count');
final evenValues = counter.stream.where((count) => count.isEven);
  • distinctBy filters events by the selected key.
  • distinctWith maps then de-duplicates mapped values.
  • distinctUnique filters duplicates across the whole stream history.

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
1
likes
160
points
536
downloads

Documentation

API reference

Publisher

verified publisherwyattcoder.top

Weekly Downloads

Pure Dart reactive state management primitives for FlowR, built on bloc with update, error handling, logging, and stream helpers.

Repository (GitHub)
View/report issues

Topics

#flowr #state-management #reactive #bloc

License

MIT (license)

Dependencies

async, bloc, logging, meta, slowly, stack_trace

More

Packages that depend on flowr_dart