icom/ framework

Events, without hidden execution.

PSR-14 synchronous dispatch with typed listeners and stable priority ordering.

Dispatch a typed event

example
use Icom\Events\{EventDispatcher, ListenerProvider};
final readonly class OrderPlaced {
    public function __construct(public string $orderId) {}
}
$listeners = new ListenerProvider();
$listeners->listen(OrderPlaced::class,
    static function (OrderPlaced $event): void { /* application action */ },
    priority: 10
);
$dispatcher = new EventDispatcher($listeners);
$dispatcher->dispatch(new OrderPlaced('order-123'));

Defined behavior

Listeners match the event class, parent classes and implemented interfaces. Higher priorities run first; equal priorities preserve registration order. Dispatch returns the same event object. A PSR StoppableEventInterface event stops further listeners when requested. Listener exceptions propagate to the caller and stop dispatch. Register listeners during bootstrap and keep shared closures free of request/user state.

Transactions and async delivery

These events execute immediately in the current process. They are not an after-commit hook or a durable message bus. If a database transaction rolls back, a listener’s external effects do not roll back with it. Use the built-in Outbox on the same scoped PDO transaction for durable job intent; see the Transactional outbox chapter. Queue payloads remain explicitly registered, separately dispatched jobs.

Developer preview — benchmark claims require reproducible evidence.

Explore the architecture