Metaclasses

Sourcing uses custom metaclasses (HOWs) to add introspection capabilities and auto-generate methods for projections and aggregations.

Metamodel::ProjectionHOW

Metaclass for projection classes. Inherits from Metamodel::ClassHOW and composes the Sourcing::Projection role.

method compose(Mu $proj, |)

Composes the projection class: adds Sourcing::Projection role, calls compose-projection-id, then nextsame.

method update($proj)

Resets and replays the aggregate from the event store:

  1. Creates a fresh instance to obtain default attribute values
  2. Resets all mutable attributes (preserving projection-id attributes)
  3. Fetches all events for the given identity from the store (from version -1)
  4. Applies each event via $proj.apply: $event
  5. Updates $!__current-version__ to total events applied minus one
  6. Stores updated cached data via $*SourcingConfig.store-cached-data

Returns: The new version ID after replaying all events.

Metamodel::AggregationHOW

Metaclass for aggregation classes. Extends ProjectionHOW and adds automatic command method generation.

method compose(Mu $aggregation, |)

Calls parent compose, adds Sourcing::Aggregation role, then for each handled event type generates a kebab-case method that creates and emits the event.

Metamodel::ProjectionIdContainer

Role providing projection ID introspection. Composed into ProjectionHOW.

MethodDescription
projection-idsReturns array of projection ID attributes
projection-id-namesReturns array of ID names without $! prefix
projection-id-pairs($proj)Returns Map of ID name to current value for given instance

Metamodel::EventHandlerContainer

Role providing event handler introspection. Composed into metaclasses.

MethodDescription
handled-events($proj)Returns array of event types handled by apply methods
handled-events-map($proj)Returns Hash mapping event type to ID mapping

Introspection Examples

# Get projection IDs
MyProjection.^projection-ids          # Array of attributes
MyProjection.^projection-id-names     # ('id',)
MyProjection.^projection-id-pairs($instance)  # Map.new(('id' => 42))

# Get handled events
MyProjection.^handled-events          # Array of event types
MyProjection.^handled-events-map      # Hash of type => mapping

See Also