An event sourcing and domain event modeling framework for Dart with code generation support.
Continuum provides a comprehensive event sourcing framework for Dart applications, organized into a four-layer architecture:
| Layer | Package | Purpose |
|---|---|---|
| 0 | continuum |
Core types: annotations, events, identity, dispatch registries |
| 0 | continuum_generator |
Code generator for operation and event boilerplate |
| 1 | continuum_uow |
Unit of Work session engine: sessions, transactional runner, commit handler |
| 2 | continuum_event_sourcing |
Event sourcing persistence: event stores, serialization, projections |
| 2 | continuum_state |
State-based persistence: REST/DB adapter-driven target persistence |
| 3 | continuum_store_memory |
In-memory EventStore for testing |
| 3 | continuum_store_hive |
Hive-backed EventStore for local persistence |
| 3 | continuum_store_sembast |
Sembast-backed EventStore for cross-platform persistence |
Additional tooling:
continuum_lints— Custom lint rules for aggregates and projections
Choose the packages for your use case:
Event sourcing (local persistence):
dependencies:
continuum: latest
continuum_event_sourcing: latest
continuum_store_memory: latest # or continuum_store_hive / continuum_store_sembast
dev_dependencies:
build_runner: ^2.4.0
continuum_generator: latestState-based (backend-authoritative):
dependencies:
continuum: latest
continuum_state: latest
dev_dependencies:
build_runner: ^2.4.0
continuum_generator: latestEvent-driven mutation only (no persistence):
dependencies:
continuum: latest
dev_dependencies:
build_runner: ^2.4.0
continuum_generator: latestimport 'package:continuum/continuum.dart';
part 'shopping_cart.g.dart';
@OperationTarget()
class ShoppingCart with _$ShoppingCartEventHandlers {
String id;
List<String> items;
ShoppingCart._({required this.id, required this.items});
static ShoppingCart createFromCartCreated(CartCreated event) {
return ShoppingCart._(id: event.cartId, items: []);
}
@override
void applyItemAdded(ItemAdded event) {
items.add(event.productId);
}
}
@OperationFor(type: ShoppingCart, key: 'cart.created', creation: true)
class CartCreated implements ContinuumEvent {
final String cartId;
CartCreated({
required this.cartId,
EventId? eventId,
DateTime? occurredOn,
Map<String, Object?> metadata = const {},
}) : id = eventId ?? EventId.fromUlid(),
occurredOn = occurredOn ?? DateTime.now(),
metadata = Map<String, Object?>.unmodifiable(metadata);
@override
final EventId id;
@override
final DateTime occurredOn;
@override
final Map<String, Object?> metadata;
}dart run build_runner buildimport 'package:continuum_event_sourcing/continuum_event_sourcing.dart';
import 'package:continuum_store_memory/continuum_store_memory.dart';
import 'continuum.g.dart';
final store = EventSourcingStore(
eventStore: InMemoryEventStore(),
targets: $aggregateList,
);
final session = store.openSession();
await session.applyAsync<ShoppingCart>(
StreamId('cart-123'),
CartCreated(cartId: 'cart-123'),
);
await session.applyAsync<ShoppingCart>(
StreamId('cart-123'),
ItemAdded(productId: 'product-abc'),
);
await session.saveChangesAsync();import 'package:continuum_state/continuum_state.dart';
import 'continuum.g.dart';
final store = StateBasedStore(
adapters: {ShoppingCart: CartApiAdapter(httpClient)},
targets: $aggregateList,
);
final session = store.openSession();
await session.applyAsync<ShoppingCart>(
StreamId('cart-123'),
CartCreated(cartId: 'cart-123'),
);
await session.saveChangesAsync(); // Adapter persists to backendCore library providing annotations (@OperationTarget, @OperationFor, @Projection), event contracts (ContinuumEvent), identity types (EventId, StreamId), dispatch registries, EventApplicationMode, and core exceptions.
Code generator that produces event handling mixins, factory dispatchers, serialization registries, and the auto-discovered $aggregateList.
Unit of Work session engine: Session, SessionBase, SessionStore, TransactionalRunner, CommitHandler, TrackedEntity, and UoW exceptions. Shared by both event sourcing and state-based persistence.
Event sourcing persistence: EventSourcingStore, EventStore, AtomicEventStore, JSON serialization, projections (single-stream, multi-stream, inline, async), and the event-sourcing SessionImpl.
State-based persistence: StateBasedStore, StateBasedSession, AggregatePersistenceAdapter for REST APIs, databases, and GraphQL backends. Same session contract as event sourcing.
In-memory EventStore implementation for testing and development.
Hive-backed EventStore implementation for local persistence.
Sembast-backed EventStore implementation for cross-platform local persistence.
Custom lint rules for operation targets and projections.
MIT