bloc_signals

A synchronous state management library bridging the Business Logic Component (BLoC) pattern with a reactive signals foundation (using Rody Davis's signals package version 7). For Flutter applications, use the bloc_signals_flutter package for UI bindings, dependency injection providers, and rebuild builders.

This library combines the architectural predictability of the BLoC pattern (events go in, states come out) with the synchronous, glitch-free, and highly precise reactivity of signals.


Features

  • โšก Synchronous & Glitch-Free: Eliminates microtask-queue latency. State updates propagate instantly inside the current execution frame.
  • ๐ŸŽฏ Fine-Grained Reactivity: Built directly on Rody Davis's signals v7 primitives.
  • ๐Ÿงน Lifecycle-Safe: Hooks into a SignalModel scope to automatically clean up downstream effects and subscriptions on .close().
  • ๐Ÿ” Global Observer: Register a BlocSignalObserver to log, monitor, and inspect all transitions and errors across your application.

Getting Started

Add the package to your pubspec.yaml:

dependencies:
  bloc_signals: ^0.1.0

Or run:

dart pub add bloc_signals

Usage

1. Define Events & States

Define the events your component can receive and the shape of the state it emits:

sealed class CounterEvent {}
class Increment extends CounterEvent {}
class Decrement extends CounterEvent {}

2. Implement the BlocSignal

Extend BlocSignal and override onEvent to handle incoming events and emit states synchronously:

import 'package:bloc_signals/bloc_signals.dart';

class CounterBloc extends BlocSignal<CounterEvent, int> {
  CounterBloc() : super(initialState: 0) {
    on<Increment>((event, emit) => emit(stateValue + 1));
    on<Decrement>((event, emit) => emit(stateValue - 1));
  }
}

3. Observe Globally

Set up a custom observer to track events and state transitions:

class ConsoleObserver extends BlocSignalObserver {
  @override
  void onEvent(BlocSignal<dynamic, dynamic> bloc, Object? event) {
    print('Event added: $event');
  }

  @override
  void onTransition(BlocSignal<dynamic, dynamic> bloc, Object? event, Object? state) {
    print('State transitioned to: $state');
  }
}

void main() {
  BlocSignalObserver.observer = ConsoleObserver();

  final bloc = CounterBloc();
  bloc.add(Increment()); // Triggers print: State transitioned to: 1
  bloc.close();
}

Integration with Flutter

If you are building a Flutter application, use bloc_signals_flutter for UI bindings, dependency injection providers, and rebuild builders.

For migration help from classic BLoC, check out our Migration Guide.


AI Coding Assistant Skills

This repository includes a pre-packaged AI Coding Skill representing all the best practices, lifecycle structures, and FAQs for using BlocSignal. If you develop with AI code assistants (like Gemini, Claude Code, or Cursor), you can install this skill globally or locally to guide your assistant's code generation:

npx ctx7@latest skills install RandalSchwartz/BlocSignal bloc-signals

Credits & Acknowledgements

This package is heavily inspired by and builds upon the original bloc library by Felix Angelov, combined with the reactive primitives of the signals library by Rody Davis.

Libraries

bloc_signals
A reactive state management library bridging the BLoC pattern with Rody Davis's signals (v7) primitives.