Bloc Bolt ⚡
A minimal, ultra-high-performance event-driven state management extension for the bloc ecosystem.
Bolt bridges the gap between Cubit and Bloc: it provides the strict event-driven contract and full observability of a Bloc, but delivers the raw performance of a Cubit by eliminating inbound StreamController and event-transformer overhead.
The Scaling Philosophy 📊
Not all state managers scale the same way. Bolt is highly optimized for real-world UI scenarios (1–5 active subscribers per screen via BlocBuilder/BlocListener), where it outperforms complex reactive graphs.
Architectural Insights: Why the lines cross?
- Bolt vs Bloc (10x - 2x speedup): By removing the inbound stream queue, Bolt reduces processing latency dramatically. The event is dispatched to
onEventinstantly and synchronously. - Bolt vs Cubit (The Event-Driven "Tax"): Bolt runs neck-and-neck with Cubit. Modern Dart VM compiles
sealedclass pattern matching down to highly optimized integer Jump Tables, making the event-driven routing virtually free.
Features
- Strict Event-Driven Contract: Keep your business logic isolated. UI only communicates via explicit events.
- Zero Inbound Overhead: No stream buffers or microtask delays between event dispatch and execution.
- Full Bloc Ecosystem Compatibility: Inherits from
BlocBase. Works seamlessly withBlocProvider,BlocBuilder, and your existingBlocObserver.
Quick Start
1. Define Events and State
Leverage modern Dart sealed classes for type-safe event payloads:
sealed class CounterEvent { const CounterEvent(); }
class Increment extends CounterEvent { const Increment(); }
class Decrement extends CounterEvent { const Decrement(); }
2. Create your Bolt Container
Implement the synchronous/asynchronous onEvent handler:
class CounterBolt extends Bolt<CounterEvent, int> {
CounterBolt() : super(0);
@override
void onEvent(CounterEvent event) {
switch (event) {
case Increment(): emit(state + 1);
case Decrement(): emit(state - 1);
}
}
}
3. Use in UI
final bolt = CounterBolt();
// Trigger via event contract
bolt.add(const Increment());
Error Handling
Bolt safely intercepts async errors within onEvent without blocking execution:
@override
Future<void> onEvent(CounterEvent event) async {
if (event is Decrement) {
await networkRepository.sync(); // CatchError is automatically hooked under the hood
emit(state - 1);
}
}
@override
Future<void> onEvent(CounterEvent event) async {
switch (event) {
case Decrement():
try {
await networkRepository.sync();
emit(state - 1);
} catch (error, stackTrace) {
// Handle locally or pass explicitly to BlocBase error stream
emit(CounterErrorState('Sync failed'));
addError(error, stackTrace);
}
}
}