continuum_event_sourcing 5.3.0
continuum_event_sourcing: ^5.3.0 copied to clipboard
Event sourcing persistence strategy for Continuum — event store, serialization, projections, and aggregate replay.
Changelog #
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[Unreleased] #
5.3.0 - 2026-02-21 #
Added #
- Added
deleteAsync(StreamId)toSessionfor marking aggregates for deletion within a unit of work. No prior load is required — the stream ID alone is sufficient. - Added
deleteAsync(StreamId)toTargetPersistenceAdapterfor physical entity deletion in state-based persistence. - Added
softDeleteStreamAsync(StreamId)toEventStorefor tombstone-based stream deletion in event sourcing. StateBasedSession.saveChangesAsyncnow processes deletion-marked entities by callingadapter.deleteAsyncand removing them from the identity map.- Event sourcing
SessionImpl.saveChangesAsyncnow soft-deletes marked streams viaEventStore.softDeleteStreamAsync, writing a tombstone flag instead of rejecting deletion. InMemoryEventStore,HiveEventStore, andSembastEventStoreimplementsoftDeleteStreamAsync— soft-deleted streams are excluded fromloadStreamAsyncandgetStreamIdsByAggregateTypeAsyncbut their events are retained for auditability.InMemoryPersistenceAdapter,HivePersistenceAdapter, andSembastPersistenceAdapternow implementdeleteAsync.
5.2.0 - 2026-02-20 #
Added #
- Added
@OperationTarget()and@OperationFor(...)annotations incontinuumto support operation-driven mutation without requiringAggregateRoot.
Changed #
continuum_generatornow discovers operation targets via@OperationTarget()(and still supportsAggregateRootas a legacy marker).continuum_lintsnow applies missing-handler and missing-creation-factory checks to@OperationTarget()classes.EventSourcingStoreandStateBasedStorenow accepttargets:instead ofaggregates:(withaggregates:kept as a deprecated alias).- State-based persistence now prefers
TargetPersistenceAdapter<T>;AggregatePersistenceAdapter<T>remains as a deprecated alias for backward compatibility.
Fixed #
- Example
abstract_interface_targets.dartis now discoverable by codegen by marking its target types with@OperationTarget().
Deprecated #
- Deprecated
@AggregateEvent(...)in favor of operation-oriented annotations.
5.1.0 - 2026-02-20 #
Added #
- New example
example/lib/store_state_based_transactional.dartdemonstratingStateBasedStorewithTransactionalRunnerand a REST API adapter. - New example
example/lib/store_state_based_local_db.dartdemonstratingStateBasedStorewith a local key-value database adapter. InMemoryPersistenceAdapterincontinuum_store_memory— a ready-madeAggregatePersistenceAdapterbacked by a plainMap, suitable for testing and development.HivePersistenceAdapterincontinuum_store_hive— a ready-madeAggregatePersistenceAdapterbacked by a HiveBox<String>, for local persistence.SembastPersistenceAdapterincontinuum_store_sembast— a ready-madeAggregatePersistenceAdapterbacked by a Sembast store, for local persistence.
Removed #
- Removed obsolete hybrid examples from the
example/package. The following example files and their helper DTOs were removed because the recommended pattern is now demonstrated inexample/lib/store_state_based_transactional.dart:example/lib/hybrid_optimistic_creation.dartexample/lib/hybrid_profile_edit.dartexample/lib/hybrid_multi_step_form.dartexample/lib/hybrid/backend_api.dartexample/lib/hybrid/dtos.dart
5.0.0 - 2026-02-19 #
Breaking Changes #
- BREAKING: Extracted
continuum_uowpackage — Unit of Work session engine (Session,SessionBase,TransactionalRunner,CommitHandler,TrackedEntity, UoW exceptions). Previously part ofcontinuum. - BREAKING: Extracted
continuum_event_sourcingpackage — event sourcing persistence (EventSourcingStore,EventStore,AtomicEventStore, serialization, projections,SessionImpl). Previously part ofcontinuum. - BREAKING: Extracted
continuum_statepackage — state-based persistence (StateBasedStore,StateBasedSession,AggregatePersistenceAdapter, adapter exceptions). Previously part ofcontinuum. - BREAKING:
continuumcore now only exports Layer 0 types (annotations, events, identity,Operation,EventApplicationMode,EventRegistry,GeneratedAggregate, dispatch registries, core exceptions). - BREAKING: Store implementations (
continuum_store_memory,continuum_store_hive,continuum_store_sembast) now depend oncontinuum_event_sourcinginstead ofcontinuumfor persistence types. - BREAKING:
Session.saveChangesAsyncnow returnsFuture<List<Operation>>instead ofFuture<void>, providing the list of committed operations in application order. - BREAKING:
CommitHandler.onCommitAsyncnow acceptsList<Operation> committedOperationsparameter instead of taking no arguments. The handler is not called when no operations were committed. - Migration: Update imports to reference the new packages —
package:continuum_uow/continuum_uow.dartfor session types,package:continuum_event_sourcing/continuum_event_sourcing.dartfor event sourcing types,package:continuum_state/continuum_state.dartfor state-based types. - Backward-compatible typedefs are available in
continuum_uowto ease migration.
Added #
- State-Based Store: A complete persistence mode for backend-authoritative applications. Instead of persisting events to an event store, aggregates are loaded and saved through
AggregatePersistenceAdapterinstances that communicate with your backend (REST API, GraphQL, database, etc.):StateBasedStore: Store implementation backed by adapter map (one adapter per aggregate type)StateBasedSession: Session implementation delegating to adapters for load/save operationsAggregatePersistenceAdapter<TAggregate>: Interface definingfetchAsyncandpersistAsyncoperationsSessionBase: Abstract base class extracting shared session logic (identity map, event application, 3-path detection) for reuse acrossSessionImplandStateBasedSessionPartialSaveException: Reports partial failures when saving multiple streams atomicallyTransientAdapterException: Base exception for retriable adapter failuresPermanentAdapterException: Base exception for non-retriable adapter failures- Sessions support the same
applyAsync/saveChangesAsynccontract asEventSourcingStore - Supports concurrency retry via
maxRetriesparameter (adapter must throwConcurrencyException) - Events exist only in memory as domain objects and are never serialized
- Sembast EventStore (
continuum_store_sembast): Sembast-backedEventStoreimplementation providing persistent local storage using Sembast. SupportsAtomicEventStoreandProjectionEventStoreinterfaces. Pure Dart solution that works on all platforms (mobile, desktop, web viasembast_web). - Concurrency retry on
saveChangesAsync:ContinuumSession.saveChangesAsyncnow accepts an optionalmaxRetriesparameter (default0, fully backward-compatible). When aConcurrencyExceptionis detected and retries remain, the session automatically reloads conflicting streams from the store, reconstructs fresh aggregates, re-applies pending events on top of the latest state, and retries the save. This prevents silent event loss when multiple workflows modify the same aggregate concurrently. - State-Based Store documentation: Added comprehensive documentation and examples for
StateBasedStore:- New example:
example/lib/store_state_based.dartdemonstratesStateBasedStorewithAggregatePersistenceAdapter - README: Added "State-Based Store" section under "Core Concepts" with construction patterns and adapter implementation examples
- README: Updated Mode 3 quick-start snippet to use
StateBasedStoreinstead of manual backend wiring - Example index: Added STATE-BASED PERSISTENCE section for state-based examples
- New example:
4.1.0 - 2026-01-22 #
Added #
- Projection System: A comprehensive read-model projection framework with automatic event-driven updates.
Projection<TReadModel, TKey>: Base class for event-driven read model maintenance.SingleStreamProjection<TReadModel>: Projections that follow a single aggregate stream.MultiStreamProjection<TReadModel, TKey>: Projections that aggregate across multiple streams.ProjectionRegistry: Central registry for projection registration and lookup.ReadModelStore<TReadModel, TKey>: Storage abstraction for read models withInMemoryReadModelStoreimplementation.ProjectionPositionStore: Tracks projection progress withInMemoryProjectionPositionStoreimplementation.InlineProjectionExecutor: Synchronous execution for strongly-consistent projections.AsyncProjectionExecutor: Asynchronous execution for eventually-consistent projections.PollingProjectionProcessor: Background processor for async projections.ProjectionEventStore: Interface for event stores that support projection queries.
EventSourcingStorenow accepts an optionalprojectionsparameter to enable automatic inline projection execution.InMemoryEventStoreandHiveEventStorenow implementProjectionEventStorefor projection support.
Fixed #
continuum_missing_apply_handlersno longer requiresapply<Event>(...)handlers for creation events marked with@AggregateEvent(creation: true).- Fix
ContinuumEventcontract so core compilation succeeds (restoring requiredid,occurredOn, andmetadatafields). - Fix
ContinuumEvent.metadatatyping to match examples/generator fixtures (Map<String, Object?>). - Stabilize
continuum_generatortests in CI by falling back to.dart_tool/package_config.jsonwhenIsolate.packageConfigis unavailable. - Run
melos run testwith--concurrency 1to reduce workspace test flakiness.
4.0.0 - 2026-01-14 #
Breaking Changes #
- BREAKING: Creation events are classified via
@AggregateEvent(creation: true)(no longer inferred from aggregatecreate*methods).
Added #
- Added
creationflag to@AggregateEventfor explicit creation-event declaration. - Generator now validates that each creation event has a matching
createFrom<Event>static factory on the aggregate. - Added a lint that warns when an
@Aggregate()class is missing requiredcreateFrom<Event>(...)factories for creation events. - Added a Quick Fix action to implement missing
createFrom<Event>(...)factory stubs. - Updated the example package to show both missing apply handlers and missing creation factories warnings.
3.2.0 - 2026-01-14 #
Added #
- Added a custom lint rule that reports when a non-abstract
@Aggregate()class mixes in the generated_$<Aggregate>EventHandlersbut does not implement all requiredapply<Event>(...)methods. - Added a Quick Fix action to implement missing
apply<Event>(...)handler stubs. - Added a runnable example package under
example/showing the lint in action.
3.1.1 - 2026-01-13 #
Fixed #
- Aggregate event discovery now scans all libraries in the package, so mutation apply methods and dispatch cases are generated even when the aggregate library does not import the event library (the aggregate still must import the event type for compilation).
3.1.0 - 2026-01-13 #
3.0.0 - 2026-01-12 #
Breaking Changes #
- BREAKING:
ContinuumEventnow implementsZooperDomainEventfor better integration with other Zooper packages.
Fixed #
JsonEventSerializer.deserializenow always includes ametadatakey (empty when no stored metadata) in the payload passed tofromJson.- Code generation now emits
ContinuumEventforapplyEvent(...),replayEvents(...), andcreateFromEvent(...)(instead of the non-existentDomainEvent).
2.0.0 - 2026-01-08 #
Breaking Changes #
- BREAKING: Renamed
@Eventannotation to@AggregateEventto avoid naming conflicts with user code. - BREAKING: Renamed
ofAggregate:parameter toof:in@AggregateEventannotation. - BREAKING: Renamed
DomainEventclass toContinuumEventto avoid naming conflicts. - BREAKING: Renamed
Sessioninterface toContinuumSessionto avoid naming conflicts. - BREAKING: Renamed
StoredEvent.fromDomainEvent()toStoredEvent.fromContinuumEvent(). - BREAKING: Updated all parameter names from
domainEventtocontinuumEvent.
Other Changes #
- Updated generator implementation for analyzer 8 API changes.
- Updated generator dependencies for
source_gen ^4.0.0(includinganalyzerandbuild).
1.0.0 #
- Initial release with event sourcing core functionality.
- Added
@Aggregate()and@Event()annotations for code generation. - Added strong types:
EventId,StreamId. - Added persistence interfaces and store implementations.
- Added exception types for error handling.