Architecture
Sourcing is built on Raku's powerful metaprogramming capabilities. It uses custom metaclasses, roles, and traits to provide a declarative API for event sourcing.
Component Diagram
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Sourcing.rakumod β
β (exports: sourcing, traits, EXPORTHOW/DECLARE) β
βββββββββββββββββ¬βββββββββββββββββββββββ¬ββββββββββββββββββββ
β β
βΌ βΌ
ββββββββββββββββββββ ββββββββββββββββββββββββββββ
β Roles β β Metamodel/ β
β - Projection β β - ProjectionHOW β
β - Aggregation β β - AggregationHOW β
β - ProjectionId β β - ProjectionIdContainer β
β - ProjectionIdMapβ β - EventHandlerContainer β
ββββββββββββββββββββ ββββββββββββββββββββββββββββ
β
βΌ
ββββββββββββββββββββββββββββ
β Sourcing/ β
β - Plugin β
β - Plugin::Memory β
β - ProjectionStorage β
β - X::OptimisticLocked β
ββββββββββββββββββββββββββββ
Runtime Flow
Command βββΊ Aggregation βββΊ emit(event) βββΊ Plugin (Event Store)
β β
β validates β appends to @!events
β enforces invariants β broadcasts on Supply
βΌ βΌ
(state from events) ProjectionStorage
β
routes events
βΌ
βββββββββββ΄ββββββββββ
β β
Projection 1 Projection 2
(dashboard) (analytics)
Key Design Decisions
| Decision | Rationale |
|---|---|
| Metaclass-based | Custom HOWs add introspection capabilities and auto-generate methods |
| Role composition | Functionality is composed through roles for flexibility |
| Trait-driven | Raku's trait_mod:<is> enables declarative configuration |
| Supply-based streaming | Raku's Supply provides reactive event distribution |
| Plugin architecture | Storage backends are pluggable (Memory, future: SQLite, PostgreSQL) |
File Structure
lib/
βββ Sourcing.rakumod # Main module, exports, traits
βββ Sourcing/
β βββ Projection.rakumod # Role for projections
β βββ Aggregation.rakumod # Marker role for aggregations
β βββ ProjectionId.rakumod # Role for ID attributes
β βββ ProjectionIdMap.rakumod # Role for ID mapping
β βββ ProjectionStorage.rakumod # Event router / registry
β βββ Plugin.rakumod # Abstract plugin interface
β βββ Plugin/
β β βββ Memory.rakumod # In-memory implementation
β βββ X/
β βββ OptimisticLocked.rakumod # Exception class
βββ Metamodel/
βββ ProjectionHOW.rakumod # Metaclass for projections
βββ AggregationHOW.rakumod # Metaclass for aggregations
βββ ProjectionIdContainer.rakumod # ID introspection
βββ EventHandlerContainer.rakumod # Event handler introspection
Next Steps
- Dive into Projections β the read model
- Dive into Aggregations β the write model
- Follow the Quick Start Guide