HandlerRegistry
Overview
Section titled “Overview”HandlerRegistry is the internal data structure the bus uses to store registered handlers and to resolve them on dispatch. Most users do not construct one directly — createBus(...) owns one and routes bus.handle(...) / bus.unhandle(...) through to it. This page documents the methods for users reading the source or building bespoke tooling on top of the bus.
The registry’s distinguishing behaviour is the polymorphic ancestor walk on dispatch: handlersFor(typeName, context) walks every parent type recorded in the supplied IMessageTypeRegistry and returns the union of all handlers along that chain, deduplicating each handler instance and tolerating cycles in the parent graph.
Import
Section titled “Import”HandlerRegistry is exposed by the source tree but is not part of the published @serviceconnect/core surface. The class is reachable for testing and inspection at the source path packages/core/src/handlers/registry.ts.
Signature
Section titled “Signature”export class HandlerRegistry { constructor(typeRegistry: IMessageTypeRegistry); add<T extends Message>(typeName: string, handler: Handler<T>): void; remove<T extends Message>(typeName: string, handler: Handler<T>): void; isHandled(typeName: string): boolean; handlersFor( typeName: string, context: ConsumeContext, ): Array<(message: Message, context: ConsumeContext) => Promise<void>>;}Members
Section titled “Members”constructor(typeRegistry)— bind the registry to anIMessageTypeRegistry. The two are coupled:handlersForwalks the parent graph the type registry returns, so handlers registered against an ancestor type only fire if that ancestor is also registered there.add(typeName, handler)— append a handler to the list fortypeName. Multiple handlers per type are supported and dispatched in registration order. Accepts all threeHandlerforms (function, class, factory).remove(typeName, handler)— remove a previously registered handler. The handler reference must be the same function or class instance passed toadd; the factory form is matched on the wrapper object.isHandled(typeName)—trueif at least one handler is registered againsttypeName. Note this does not walk parents — it asks whether a direct handler exists.handlersFor(typeName, context)— return the resolved callables (one per registered handler) to invoke for an inbound message of typetypeName. Starts attypeNameand walks every parent returned by the underlyingIMessageTypeRegistry.parentsOf, including each handler instance at most once even when it’s registered against multiple ancestors. Cycles in the parent graph are tolerated via a visited-set. Factory-form handlers are constructed lazily with the suppliedConsumeContext.