gpslab/domain-event
54.3
Adequate · 21 September 2026
1.1k
lines of production code
PHP
primary language
4
measurements over time
What this system is
This system is a domain event library designed for building the domain layer of DDD applications. It provides a flexible event bus architecture that supports both immediate dispatch and asynchronous queue-based processing. The library enables aggregates to raise domain events, discover listeners via direct bindings or containers, and route events to memory, Redis, or AMQP queues with configurable serialization.
How it got here
2016 — Domain event architecture and aggregation
5 changes.
The project established its core domain event infrastructure, introducing abstractions for event aggregation and raising mechanisms. This period focused on defining the library's architecture, including a refactored event bus and queue system, alongside initial test coverage and dependency management.
2017 — Event bus and queue architecture refactoring
11 changes.
This period focused on a comprehensive refactoring of the event bus and queue systems, introducing new interfaces and implementations for event publishing, subscription, and listener discovery. The changes standardized how events are routed and processed, supporting both in-memory and external backends like Redis and AMQP. Extensive test coverage was added to validate the new abstractions and ensure correct behavior across different queue and listener configurations.
Features
Add AMQP and Redis queue implementations for event subscription
The queue subscription system now supports multiple backends. A new AMQP implementation (AMQPSubscribeEventQueue) allows subscribing to event queues via RabbitMQ, while a Redis-based implementation (PredisSubscribeEventQueue) enables subscription via Redis Pub/Sub. Both implementations support registering and unregistering multiple handlers, allowing applications to react to events from different message brokers.
src/Queue/Subscribe · high confidence
Added in-memory and Redis-backed pull event queue implementations
The codebase now includes a PullEventQueue interface and two concrete implementations: a MemoryPullEventQueue for in-memory event handling and a PredisPullEventQueue that persists events to a Redis queue using a serializer. This enables consumers to pull events from either a memory-based or Redis-backed queue, supporting both lightweight testing and scalable production scenarios.
src/Queue/Pull · high confidence
Introduce EventQueue interface for event publishing
A new EventQueue interface is added to the Queue component, defining a publish method for sending events to a queue. This provides an abstraction for event publishing, replacing the previous push-based approach in the queue system.
src/Queue · high confidence
Introduce Subscriber interface for event listeners
A new Subscriber interface is introduced in the Listener component, requiring event subscribers to implement a static subscribedEvents() method that returns an array of event names and their corresponding handler methods. This standardizes how listeners declare the events they subscribe to, enabling more robust event routing and discovery within the application.
src/Listener · high confidence
Introduce domain event aggregation and raising mechanisms
Added new abstractions for domain event handling: an Event interface, an AggregateEvents interface, and traits (AggregateEventsTrait, AggregateEventsRaiseInSelfTrait) along with their corresponding abstract classes (AbstractAggregateEvents, AbstractAggregateEventsRaiseInSelf). This enables aggregates to both collect and immediately raise domain events, with the raise-in-self variant automatically invoking a corresponding handler method (e.g., onEventName) if it exists on the aggregate.
src/Aggregator · high confidence
Introduce queue serializer abstraction and Symfony integration
Added a new \Serializer\ interface and a \SymfonySerializer\ implementation in the queue serialization layer. The \SymfonySerializer\ wraps the Symfony Serializer component to handle serializing and deserializing queue events using the 'predis' format by default, providing a concrete, framework-specific way to handle queue data transformation.
src/Queue/Serializer · medium confidence
New event listener locators for direct binding and container integration
Introduced three new classes in the event system: an \EventListenerLocator\ interface defining the contract for retrieving listeners, a \DirectBindingEventListenerLocator\ for registering callable listeners directly, and a \ContainerEventListenerLocator\ that resolves listeners from a PSR-11 container. Additionally, a \SymfonyContainerEventListenerLocator\ was added to support Symfony's \ContainerAwareInterface\ for tighter integration with the Symfony dependency injection container. These changes provide a more flexible and extensible way to discover and register event listeners.
src/Listener/Locator · high confidence
Behavioural changes
Major refactoring of event bus, locators, and queues
This release introduces significant breaking changes to the library's architecture. The event bus system has been refactored: the generic \EventBus\ and \Bus\ classes are removed or renamed to \ListenerLocatedEventBus\, and methods like \push()\ are renamed to \publish()\. Event listener locators have been restructured; for example, \ContainerAwareLocator\ is now \SymfonyContainerEventListenerLocator\, and \NamedEventLocator\ is now \DirectBindingEventListenerLocator\, both of which no longer use event name resolvers to find listeners. Queue implementations have been split into pull and subscribe types, with \MemoryUniqueEventQueue\ and \PredisUniqueEventQueue\ removed in favor of new interfaces and classes in the \GpsLab\\Domain\\Event\\Queue\ namespace. Several classes and interfaces related to name resolution, switching, and invalid events have been removed.
(repo-wide) · high confidence
Refactored event bus architecture with new implementations
The event bus system has been refactored to introduce two new concrete implementations: ListenerLocatedEventBus, which dispatches events to registered listeners, and QueueEventBus, which queues events for later processing. Both implement the new EventBus interface. The previous implementation, QueueEventBus, has been removed from the codebase along with the unused publisher bus. The old EventBus class and its interface have been replaced by the new structure, marking the old methods and classes as deprecated or removed.
src/Bus · medium confidence
Test coverage
Add unit tests for event listener locators; Added test bootstrap file; Added test fixtures for event handling and subscribers; Added tests for queue implementations; Added unit tests for event aggregation behavior; Added unit tests for the event bus implementations.
Dependencies
Initial release of the Domain Event library
The project introduces a new library for creating the domain layer of DDD applications, defining its structure and dependencies. It requires PHP 5.5 or higher and includes development dependencies for testing and static analysis, specifically adding support for Redis via Predis, AMQP via php-amqplib, and various Symfony components (dependency-injection, serializer) alongside PSR interfaces.
(dependencies) · medium confidence
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
How this codebase got here
Score
- CAI 57 → 54 (-2.5)
- Rubric changed (rubric-2026.08.19 → rubric-2026.09.15) — scores are not directly comparable.
Lenses
- Code Health 100 → 99 (-0.5)
- Architecture 69 → 69 (+0.0)
- Maturity 46 → 46 (+0.0)
- Readiness 50 → 43 (-6.9)
- Security 100 → 100 (+0.0)
Resolved (7)
- Coverage not included — suite not readable by the collector
- Dependency hygiene not measured — dependency manifest found but not parsed for hygiene
- Duplicated block (11 lines × 2) (src/Listener/Locator/ContainerEventListenerLocator.php)
- LLM evaluation failed
- No exposed public API
- Test reliability not included
- dormant codebase — no living knowledge left to concentrate
New (12)
- Documentation: no architecture or design documentation (docs/listener/locator/symfony_container.md)
- Documentation: no installation or build instructions (README.md)
- Documentation: no installation or build instructions (docs/queue/pull/predis.md)
- Duplicated block (11 lines × 2) (src/Listener/Locator/ContainerEventListenerLocator.php)
- Duplicated block (5 lines × 2) (src/Listener/Locator/ContainerEventListenerLocator.php)
- Duplicated block (9 lines × 2) (src/Listener/Locator/ContainerEventListenerLocator.php)
- Duplicated block (9 lines × 3) (src/Queue/Subscribe/AMQPSubscribeEventQueue.php)
- Inconsistent parameter naming and type for service identification. ContainerEventListenerLocator uses service (likely an object or ID) while SymfonyContainerEventListenerLocator uses service_name (explicitly a string/name). This suggests a difference in how the underlying container is expected to resolve the service, but the API surface is inconsistent. A caller might expect service to be a string in one and an object in another, or vice versa.
- No assertions: testPublish (tests/Bus/QueueEventBusTest.php)
- No assertions: testPullAndPublish (tests/Bus/QueueEventBusTest.php)
- No dependency advisory monitoring
- Redundant naming across base class and traits. The method pullEvents exists on the concrete class AggregateEvents and is also defined in two traits (AggregateEventsTrait and AggregateEventsRaiseInSelfTrait). While traits are reusable, having the same method name on the concrete implementation and its constituent traits creates confusion about ownership and inheritance hierarchy. It is unclear if the traits are meant to be used independently or if the concrete class is just a composition of them.
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
Survey your own repository
gpslab/domain-event was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.
About this page
- The score is its most recent published measurement, taken on 21 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
- Measured at commit afa1ee7ace1ce176f2afdc728d93a191d0093a68 — the exact code this score is about.
- Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
- Measured by watchdog.canine.dev using codehealth-analyzer preprod-fa71c66cabd8.