bloc_subject 0.4.1 copy "bloc_subject: ^0.4.1" to clipboard
bloc_subject: ^0.4.1 copied to clipboard

Reactive event based state management. Implementation of the Bloc pattern as an rxdart subject (BlocSubject).

Pub Version Dart Package Docs License: Apache 2.0 Build Status

bloc_subject #

bloc_subject is a Dart package that introduces the BlocSubject class, an extension of RxDart's BehaviorSubject with the powerful BLoC (Business Logic Component) pattern. It allows you to handle events and state changes in a reactive way, leveraging RxDart's stream manipulation capabilities while maintaining state and responding to events asynchronously.

sealed class AlphabetState {
  final int id;

  AlphabetState(this.id);
}

class A extends AlphabetState {
  A(super.id);
}

class B extends AlphabetState {
  B(super.id);
}

class C extends AlphabetState {
  C(super.id);
}

sealed class AlphabetEvent {}

class X implements AlphabetEvent {}

class Y implements AlphabetEvent {}

class Z implements AlphabetEvent {}

void main() async {
  int emitCount = 0;
  BlocSubject<AlphabetEvent, AlphabetState> subject = BlocSubject.seeded(A(emitCount),
      handler: (event, state) => switch (event) {
            X() => A(++emitCount),
            Y() => B(++emitCount),
            Z() => null,
          });
  final transformedStream = subject.stream
      .map((value) => switch (value) {
            A() => "A${value.id}",
            B() => "B${value.id}",
            C() => "C${value.id}",
          })
      .distinct();

  assert(subject.value is A);
  assert(await transformedStream.first == "A0");

  subject.addEvent(Y()); // Can process events and emit new states
  await Future.delayed(const Duration(milliseconds: 100));
  assert(subject.value is B);
  assert(await transformedStream.first == "B1");

  subject.addEvent(Z()); // If null is emitted from the handler, the state does not change/emit
  await Future.delayed(const Duration(milliseconds: 100));
  assert(subject.value is B);
  assert(await transformedStream.first == "B1");

  subject.add(C(1000)); // Still works like a regular `BehaviorSubject`
  assert(subject.value is C);
  assert(await transformedStream.first == "C1000");
}

Declaration Comparison To Bloc #

Bloc:

import 'package:bloc/bloc.dart';

void main(){
    final bloc = HomeBloc();
}

class HomeBloc extends Bloc<HomeEvent, HomeState> {

  final DocumentInfoRepository _documentInfoRepository = DI<DocumentInfoRepository>();
  late final StreamSubscription<(DocumentChange<Map<String, dynamic>>, DocumentInfo)>
      _documentInfoChangesStreamSubscription;

  HomeBloc() : super(HomeState()) {
    on<HomeEventAddedDocumentInfo>(_handleAddedDocumentInfo);
    on<HomeEventModifiedDocumentInfo>(_handleModifiedDocumentInfo);
    on<HomeEventRemovedDocumentInfo>(_handleRemovedDocumentInfo);
    on<HomeEventChangeCurrentDirectory>(_handleChangeCurrentDirectory);
    on<HomeEventSortOptionsChanged>(_handleSortOptionsChanged);
    on<HomeEventMoveSelected>(_handleMoveSelectedTo);
    on<HomeEventCreateFolder>(_handleCreateFolderAt);

    _documentInfoChangesStreamSubscription =
        _documentInfoRepository.userDocumentInfoChangeStream().listen((item) {
      final (event, doc) = item;
      switch (event.type) {
        case DocumentChangeType.added:
          add(HomeEventAddedDocumentInfo(doc));
          break;
        case DocumentChangeType.modified:
          add(HomeEventModifiedDocumentInfo(doc));
          break;
        case DocumentChangeType.removed:
          add(HomeEventRemovedDocumentInfo(doc));
          break;
      }
    });
  }

  @override
  Future<void> close() async {
    await _documentInfoChangesStreamSubscription.cancel();
    return super.close();
  }

  Future<void> _handleAddedDocumentInfo(HomeEventAddedDocumentInfo event, Emitter<HomeState> emit) async {
    ...
  }

  Future<void> _handleModifiedDocumentInfo(HomeEventModifiedDocumentInfo event, Emitter<HomeState> emit) async {
    ...
  }

  Future<void> _handleRemovedDocumentInfo(HomeEventRemovedDocumentInfo event, Emitter<HomeState> emit) async {
    ...
  }

  void _handleChangeCurrentDirectory(HomeEventChangeCurrentDirectory event, Emitter<HomeState> emit) {
    ...
  }

  void _handleSortOptionsChanged(HomeEventSortOptionsChanged event, Emitter<HomeState> emit) {
    ...
  }

  void _handleMoveSelectedTo(HomeEventMoveSelected event, Emitter<HomeState> emit) {
    ...
  }

  void _handleCreateFolderAt(HomeEventCreateFolder event, Emitter<HomeState> emit) {
    ...
  }
}

bloc_subject:

import 'package:bloc_subject/bloc_subject.dart';

void main() {
    final blocSubject = BlocSubject<HomeEvent, HomeState>.seeded(
        HomeState(),
        handler: (event, state) => switch (event) {
            HomeEventAddedDocumentInfo() => _handleAddedDocumentInfo(event, state),
            HomeEventModifiedDocumentInfo() => _handleModifiedDocumentInfo(event, state),
            HomeEventRemovedDocumentInfo() => _handleRemovedDocumentInfo(event, state),
            HomeEventChangeCurrentDirectory() => _handleChangeCurrentDirectory(event, state),
            HomeEventSortOptionsChanged() => _handleSortOptionsChanged(event, state),
            HomeEventMoveSelected() => _handleMoveSelectedTo(event, state),
            HomeEventCreateFolder() => _handleCreateFolderAt(event, state),
        },
        )..listenToEvents(DI<DocumentInfoRepository>().userDocumentInfoChangeStream().map((item) {
            final (event, doc) = item;
            return switch (event.type) {
                DocumentChangeType.added => HomeEventAddedDocumentInfo(doc),
                DocumentChangeType.modified => HomeEventModifiedDocumentInfo(doc),
                DocumentChangeType.removed => HomeEventRemovedDocumentInfo(doc),
            };
        }));
}

HomeState? _handleAddedDocumentInfo(HomeEventAddedDocumentInfo event, HomeState state) {
    ...
}

HomeState? _handleModifiedDocumentInfo(HomeEventModifiedDocumentInfo event, HomeState state) {
    ...
}

HomeState? _handleRemovedDocumentInfo(HomeEventRemovedDocumentInfo event, HomeState state) {
    ...
}

HomeState? _handleChangeCurrentDirectory(HomeEventChangeCurrentDirectory event, HomeState state) {
    ...
}

HomeState? _handleSortOptionsChanged(HomeEventSortOptionsChanged event, HomeState state) {
    ...
}

HomeState? _handleMoveSelectedTo(HomeEventMoveSelected event, HomeState state) {
    ...
}

HomeState? _handleCreateFolderAt(HomeEventCreateFolder event, HomeState state) {
    ...
}
1
likes
160
pub points
22%
popularity

Publisher

verified publishervoyver.com

Reactive event based state management. Implementation of the Bloc pattern as an rxdart subject (BlocSubject).

Repository (GitHub)
View/report issues

Topics

#bloc #rxdart #reactive-programming #streams #reactive

Documentation

API reference

License

Apache-2.0 (license)

Dependencies

rxdart

More

Packages that depend on bloc_subject