Typed event bus with Stream subscriptions, sticky events, event history, and scoped lifecycle
dart pub add philiprehberger_event_busTyped event bus with Stream subscriptions, sticky events, event history, and scoped lifecycle
Add to your pubspec.yaml:
dependencies:
philiprehberger_event_bus: ^0.4.0
Then run:
dart pub get
import 'package:philiprehberger_event_bus/philiprehberger_event_bus.dart';
final bus = EventBus();
bus.on<String>().listen((event) {
print('Received: $event');
});
bus.fire('hello');
class UserLoggedIn {
final String userId;
UserLoggedIn(this.userId);
}
bus.on<UserLoggedIn>().listen((event) {
print('User logged in: ${event.userId}');
});
bus.fire(UserLoggedIn('user-123'));
Sticky events are stored and replayed to new subscribers:
bus.fireSticky(UserLoggedIn('user-456'));
// New listener immediately receives the last sticky event
bus.on<UserLoggedIn>().listen((event) {
print('Got sticky: ${event.userId}');
});
// Retrieve the last sticky event directly
final last = bus.lastSticky<UserLoggedIn>();
// Clear when no longer needed
bus.clearSticky<UserLoggedIn>();
Listen for a single event and automatically unsubscribe:
final event = await bus.once<UserLoggedIn>();
print('Got one: ${event.userId}');
Store past events and replay them to new subscribers:
bus.enableHistory<String>(maxSize: 50);
bus.fire('first');
bus.fire('second');
// Retrieve stored events
print(bus.history<String>()); // ['first', 'second']
// New subscriber receives history then live events
bus.onWithHistory<String>().listen((event) {
print(event); // 'first', 'second', then any new events
});
// Clear stored events but keep collecting
bus.clearHistory<String>();
// Stop collecting history entirely
bus.disableHistory<String>();
Listen to all events regardless of type — useful for logging and debugging:
bus.onAny().listen((event) {
print('Event fired: $event');
});
bus.fire('hello');
bus.fire(42);
// Prints: Event fired: hello
// Prints: Event fired: 42
Check whether the bus has active listeners:
print(bus.hasListeners); // false
final sub = bus.on<String>().listen((_) {});
print(bus.hasListeners); // true
print(bus.listenerCount); // 1
sub.cancel();
print(bus.listenerCount); // 0
bus.dispose();
After calling dispose(), no more events can be fired or received.
| Method | Description |
|---|---|
fire<T>(T event) | Dispatch an event to all listeners of type T |
on<T>() | Subscribe to events of type T, returns Stream<T> |
onAny() | Subscribe to all events regardless of type, returns Stream<dynamic> |
once<T>() | Returns a Future<T> that completes with the next event, then auto-cancels |
fireSticky<T>(T event) | Dispatch a sticky event that replays to new subscribers |
lastSticky<T>() | Get the last sticky event of type T, or null |
clearSticky<T>() | Remove the stored sticky event of type T |
enableHistory<T>({int maxSize}) | Enable event history for type T with a max capacity |
history<T>() | Get stored events of type T as an unmodifiable list |
onWithHistory<T>() | Stream that emits stored history first, then live events |
clearHistory<T>() | Clear stored events of type T without disabling collection |
disableHistory<T>() | Stop collecting history for type T and discard stored events |
hasListeners | Whether any listeners are currently active |
listenerCount | Number of active stream subscriptions |
dispose() | Close the bus and release all resources |
dart pub get
dart analyze --fatal-infos
dart test
If you find this project useful: