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
flowchart TD
subgraph Sourcing["Sourcing.rakumod"]
S1[exports: sourcing, traits, EXPORTHOW/DECLARE for metaclasses]
end
subgraph Roles["Roles/"]
R1[Projection]
R2[Aggregation]
R3[ProjectionId]
R4[ProjectionIdMap]
end
subgraph Metamodel["Metamodel/"]
M1[ProjectionHOW]
M2[AggregationHOW]
M3[SagaHOW]
M4[ProjectionIdContainer]
M5[EventHandlerContainer]
end
subgraph SourcingLib["Sourcing::"]
L1[Plugin]
L2[Plugin::Memory]
L3[ProjectionStorage]
L4[X::OptimisticLocked]
end
Sourcing --> Roles
Sourcing --> Metamodel
Roles --> SourcingLib
Runtime Flow
flowchart TD
CMD[Command] --> AGG[Aggregation]
AGG --> EMIT[emit event]
EMIT --> PLUGIN[Plugin Event Store]
PLUGIN -->|appends| PS[ProjectionStorage]
PLUGIN -->|broadcasts| PS
PS --> P1[Projection 1
dashboard] PS --> P2[Projection 2
analytics]
dashboard] PS --> P2[Projection 2
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 plugin implementation
│ ├── 📁 X/
│ │ └── 📄 OptimisticLocked.rakumod # Exception class
│ └── 📁 Saga/
│ └── 📄 Events.rakumod # Internal event classes
├── 📁 Metamodel/
│ ├── 📄 ProjectionHOW.rakumod # Metaclass for projections
│ ├── 📄 AggregationHOW.rakumod # Metaclass for aggregations
│ ├── 📄 ProjectionIdContainer.rakumod # ID introspection
│ ├── 📄 EventHandlerContainer.rakumod # Event handling
│ └── 📄 SagaHOW.rakumod # Metaclass for sagas
└── 📁 Sourcing/
└── 📁 X/
└── 📄 OptimisticLocked.rakumod # Exception
Next Steps
- Dive into Projections — the read model
- Dive into Aggregations — the write model
- Follow the Quick Start Guide