@zdavison/matador 4.0.3 → 4.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/matador.d.ts.map +1 -1
- package/dist/core/matador.js +4 -1
- package/dist/index.cjs +156 -16
- package/dist/index.cjs.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/pipeline/pipeline.d.ts +30 -2
- package/dist/pipeline/pipeline.d.ts.map +1 -1
- package/dist/pipeline/pipeline.js +65 -9
- package/dist/retry/index.d.ts +1 -1
- package/dist/retry/index.d.ts.map +1 -1
- package/dist/retry/policy.d.ts +27 -0
- package/dist/retry/policy.d.ts.map +1 -1
- package/dist/retry/standard-policy.d.ts +33 -2
- package/dist/retry/standard-policy.d.ts.map +1 -1
- package/dist/retry/standard-policy.js +73 -9
- package/dist/topology/types.d.ts +14 -0
- package/dist/topology/types.d.ts.map +1 -1
- package/dist/transport/rabbitmq/rabbitmq-transport.d.ts.map +1 -1
- package/dist/transport/rabbitmq/rabbitmq-transport.js +3 -0
- package/package.json +1 -1
- package/dist/checkpoint/context.test.d.ts +0 -2
- package/dist/checkpoint/context.test.d.ts.map +0 -1
- package/dist/checkpoint/context.test.js +0 -428
- package/dist/checkpoint/stores/stores.test.d.ts +0 -2
- package/dist/checkpoint/stores/stores.test.d.ts.map +0 -1
- package/dist/checkpoint/stores/stores.test.js +0 -146
- package/dist/codec/rabbitmq-codec.test.d.ts +0 -2
- package/dist/codec/rabbitmq-codec.test.d.ts.map +0 -1
- package/dist/codec/rabbitmq-codec.test.js +0 -428
- package/dist/core/fanout.test.d.ts +0 -2
- package/dist/core/fanout.test.d.ts.map +0 -1
- package/dist/core/fanout.test.js +0 -1970
- package/dist/core/matador.test.d.ts +0 -2
- package/dist/core/matador.test.d.ts.map +0 -1
- package/dist/core/matador.test.js +0 -813
- package/dist/core/shutdown.test.d.ts +0 -2
- package/dist/core/shutdown.test.d.ts.map +0 -1
- package/dist/core/shutdown.test.js +0 -599
- package/dist/errors/retry-errors.test.d.ts +0 -2
- package/dist/errors/retry-errors.test.d.ts.map +0 -1
- package/dist/errors/retry-errors.test.js +0 -136
- package/dist/pipeline/pipeline.test.d.ts +0 -2
- package/dist/pipeline/pipeline.test.d.ts.map +0 -1
- package/dist/pipeline/pipeline.test.js +0 -1124
- package/dist/retry/standard-policy.test.d.ts +0 -2
- package/dist/retry/standard-policy.test.d.ts.map +0 -1
- package/dist/retry/standard-policy.test.js +0 -196
- package/dist/schema/registry.test.d.ts +0 -2
- package/dist/schema/registry.test.d.ts.map +0 -1
- package/dist/schema/registry.test.js +0 -278
- package/dist/schema/types.test.d.ts +0 -2
- package/dist/schema/types.test.d.ts.map +0 -1
- package/dist/schema/types.test.js +0 -246
- package/dist/topology/builder.test.d.ts +0 -2
- package/dist/topology/builder.test.d.ts.map +0 -1
- package/dist/topology/builder.test.js +0 -547
- package/dist/transport/local/local-transport.test.d.ts +0 -2
- package/dist/transport/local/local-transport.test.d.ts.map +0 -1
- package/dist/transport/local/local-transport.test.js +0 -232
- package/dist/transport/multi/multi-transport.test.d.ts +0 -2
- package/dist/transport/multi/multi-transport.test.d.ts.map +0 -1
- package/dist/transport/multi/multi-transport.test.js +0 -322
- package/dist/transport/rabbitmq/rabbitmq-transport-reconnection.test.d.ts +0 -2
- package/dist/transport/rabbitmq/rabbitmq-transport-reconnection.test.d.ts.map +0 -1
- package/dist/transport/rabbitmq/rabbitmq-transport-reconnection.test.js +0 -149
- package/dist/transport/rabbitmq/rabbitmq-transport.test.d.ts +0 -2
- package/dist/transport/rabbitmq/rabbitmq-transport.test.d.ts.map +0 -1
- package/dist/transport/rabbitmq/rabbitmq-transport.test.js +0 -230
- package/dist/types/event.test.d.ts +0 -2
- package/dist/types/event.test.d.ts.map +0 -1
- package/dist/types/event.test.js +0 -130
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/errors/has-description.ts","../src/errors/retry-errors.ts","../src/errors/matador-errors.ts","../src/errors/checkpoint-errors.ts","../src/topology/types.ts","../src/topology/builder.ts","../src/types/common.ts","../src/types/envelope.ts","../src/types/event.ts","../src/types/subscriber.ts","../src/core/fanout.ts","../src/hooks/types.ts","../src/hooks/safe-hooks.ts","../src/core/shutdown.ts","../src/codec/codec.ts","../src/codec/json-codec.ts","../src/codec/rabbitmq-codec.ts","../src/checkpoint/context.ts","../src/checkpoint/stores/memory.ts","../src/checkpoint/stores/noop.ts","../src/pipeline/pipeline.ts","../src/retry/standard-policy.ts","../src/schema/types.ts","../src/schema/registry.ts","../src/core/matador.ts","../src/transport/capabilities.ts","../src/transport/connection-manager.ts","../src/transport/local/local-transport.ts","../src/transport/multi/multi-transport.ts","../src/transport/rabbitmq/rabbitmq-transport.ts"],"names":["assert","error","decision","eventClass","options","event","result","amqplib"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Interface for errors that provide a human-readable description.\n * The description explains what the error means and what actions\n * users should take when encountering it in logs/observability.\n */\nexport interface HasDescription {\n /**\n * Human-readable description of the error type.\n * Intended for logging and observability to help users understand\n * the error and determine appropriate remediation steps.\n */\n readonly description: string;\n}\n\n/**\n * Type guard to check if an error implements HasDescription.\n */\nexport function hasDescription(error: unknown): error is HasDescription {\n return (\n typeof error === 'object' &&\n error !== null &&\n 'description' in error &&\n typeof (error as HasDescription).description === 'string'\n );\n}\n","import assert from 'node:assert';\nimport type { Envelope } from '../types/envelope.js';\n\n/**\n * Base class for retry control errors.\n * These errors control the retry behavior of message processing.\n */\nexport abstract class RetryControlError extends Error {\n /**\n * Error class name for monitoring tools.\n */\n declare readonly name: string;\n\n /**\n * Human-readable description of the error and recommended actions.\n */\n abstract readonly description: string;\n\n constructor(message: string) {\n super(message);\n this.name = this.constructor.name;\n // Ensure name is preserved when serialized\n Object.defineProperty(this, 'name', {\n value: this.constructor.name,\n enumerable: true,\n configurable: false,\n writable: false,\n });\n }\n\n /**\n * Returns a serializable representation for logging/monitoring.\n */\n toJSON(): Record<string, unknown> {\n return {\n name: this.name,\n message: this.message,\n description: this.description,\n stack: this.stack,\n };\n }\n}\n\n/**\n * Forces retry regardless of subscriber idempotency setting.\n * Use when you know the operation is safe to retry.\n *\n * ACTION: Check subscriber code to understand why retry was forced.\n * This overrides default retry behavior based on idempotency settings.\n */\nexport class DoRetry extends RetryControlError {\n readonly description =\n 'A subscriber explicitly requested retry by throwing DoRetry. ' +\n 'ACTION: Check the subscriber code to understand why retry was forced. ' +\n 'This overrides the default retry behavior based on idempotency settings.';\n\n constructor(message = 'Forced retry requested') {\n super(message);\n }\n}\n\n/**\n * Prevents retry regardless of subscriber idempotency setting.\n * Use for permanent failures that should not be retried.\n *\n * ACTION: Check subscriber code to understand why retry was disabled.\n * Typically used for permanent failures like invalid data or business rule violations.\n */\nexport class DontRetry extends RetryControlError {\n readonly description =\n 'A subscriber explicitly prevented retry by throwing DontRetry. ' +\n 'ACTION: Check the subscriber code to understand why retry was disabled. ' +\n 'Typically used for permanent failures like invalid data or business rule violations. ' +\n 'The message will be sent to the dead-letter queue for manual review.';\n\n constructor(message = 'Retry explicitly disabled') {\n super(message);\n }\n}\n\n/**\n * Thrown by `assertEvent` in the event of a failed assertion.\n *\n * This error indicates that an event was in an unexpected state when it reached the subscriber.\n * Throwing this error will indicate to Matador NOT to retry the event - it will be sent\n * directly to the undeliverable dead-letter queue.\n *\n * Use `assertEvent` in your subscribers to assert properties about an event payload.\n * This is useful in scenarios where you would expect an event payload to contain a field\n * based on the types, but something unexpected caused it to not be present.\n *\n * @see assertEvent\n */\nexport class EventAssertionError extends Error {\n declare readonly name: string;\n\n readonly description =\n 'Thrown to indicate that an event was in an unexpected state when it reached the subscriber. ' +\n 'Throwing this error will indicate to Matador NOT to retry the event. ' +\n 'Matador does not throw this error directly - it is thrown by assertEvent, which you can ' +\n 'use in your subscribers to assert properties about an event. ' +\n 'This can be useful in scenarios where you would expect an event payload to contain a field ' +\n 'based on the types, but something unexpected caused it to not be present. ' +\n 'Using this instead of the NodeJS assert allows Matador to not retry the event subscriber.';\n\n /** The envelope that failed the assertion */\n readonly envelope: Envelope<unknown>;\n\n constructor(envelope: Envelope<unknown>, message: string) {\n super(message);\n this.name = 'EventAssertionError';\n this.envelope = envelope;\n Object.defineProperty(this, 'name', {\n value: 'EventAssertionError',\n enumerable: true,\n configurable: false,\n writable: false,\n });\n }\n\n toJSON(): Record<string, unknown> {\n return {\n name: this.name,\n message: this.message,\n description: this.description,\n envelope: this.envelope,\n stack: this.stack,\n };\n }\n}\n\n/**\n * Checks if an error forces a retry.\n */\nexport function isDoRetry(error: unknown): error is DoRetry {\n return error instanceof DoRetry;\n}\n\n/**\n * Checks if an error prevents retry.\n */\nexport function isDontRetry(error: unknown): error is DontRetry {\n return error instanceof DontRetry;\n}\n\n/**\n * Checks if an error is an assertion error (never retry).\n */\nexport function isAssertionError(error: unknown): error is EventAssertionError {\n return error instanceof EventAssertionError;\n}\n\n/**\n * Same as Node.js `assert`, but throws an `EventAssertionError` if the assertion fails.\n *\n * `EventAssertionError`s thrown within a subscriber do not cause the subscriber to be retried.\n * The event will be delivered to the undeliverable dead-letter queue instead.\n *\n * @see https://nodejs.org/api/assert.html#assertvalue-message\n * @param envelope - The envelope this assertion relates to.\n * @param value - The value to assert. If falsy, the assertion fails.\n * @param message - The message to include in the error if the assertion fails.\n * @throws {EventAssertionError} If the assertion fails.\n *\n * @example\n * ```typescript\n * const subscriber = createSubscriber<MyEvent>({\n * name: 'my-subscriber',\n * description: 'Processes MyEvent',\n * callback: async (envelope) => {\n * // Assert that userId exists - if not, event goes to DLQ without retry\n * assertEvent(envelope, envelope.data.userId, 'userId is required');\n * // ... rest of processing\n * },\n * });\n * ```\n */\nexport function assertEvent(\n envelope: Envelope<unknown>,\n value: unknown,\n message: string,\n): asserts value {\n try {\n assert(value, message);\n } catch {\n throw new EventAssertionError(envelope, message);\n }\n}\n","/**\n * Base class for all Matador errors.\n * All errors have a unique name that appears in monitoring tools (e.g., DataDog)\n * and a description explaining the error and actions to resolve it.\n *\n * The `name` property is automatically set to the class name for proper\n * identification in error monitoring and logging systems.\n */\nexport abstract class MatadorError extends Error {\n /**\n * Error class name (e.g., \"NotStartedError\", \"TransportNotConnectedError\").\n * This is preserved during serialization for error monitoring tools.\n */\n declare readonly name: string;\n\n /**\n * Human-readable description explaining what went wrong and\n * what ACTION the user should take to resolve the issue.\n */\n abstract readonly description: string;\n\n constructor(message: string) {\n super(message);\n this.name = this.constructor.name;\n // Ensure name is preserved when serialized\n Object.defineProperty(this, 'name', {\n value: this.constructor.name,\n enumerable: true,\n configurable: false,\n writable: false,\n });\n }\n\n /**\n * Returns a serializable representation for logging/monitoring.\n */\n toJSON(): Record<string, unknown> {\n return {\n name: this.name,\n message: this.message,\n description: this.description,\n stack: this.stack,\n };\n }\n}\n\n// ============================================================================\n// Lifecycle Errors\n// ============================================================================\n\n/**\n * Thrown when attempting to use Matador before calling start().\n */\nexport class NotStartedError extends MatadorError {\n readonly description =\n 'Matador has not been started. ' +\n 'ACTION: Call matador.start() before dispatching events or performing other operations. ' +\n 'Ensure start() completes successfully before using other methods.';\n\n constructor(operation = 'operation') {\n super(\n `Cannot perform ${operation}: Matador has not been started. Call start() first.`,\n );\n }\n}\n\n/**\n * Thrown when attempting to dispatch events during shutdown.\n */\nexport class ShutdownInProgressError extends MatadorError {\n readonly description =\n 'Matador is shutting down and will not accept new events. ' +\n 'ACTION: Do not dispatch events after calling shutdown(). ' +\n 'If you need to send events, do so before initiating shutdown. ' +\n 'Consider implementing a pre-shutdown event flush if needed.';\n\n constructor() {\n super('Cannot dispatch events: Matador is shutting down.');\n }\n}\n\n// ============================================================================\n// Transport Errors\n// ============================================================================\n\n/**\n * Thrown when a transport operation is attempted but the transport is not connected.\n */\nexport class TransportNotConnectedError extends MatadorError {\n readonly description =\n 'The transport is not connected to the message broker. ' +\n 'ACTION: Ensure the transport is connected by calling transport.connect() or matador.start(). ' +\n 'Check that the broker (e.g., RabbitMQ) is running and accessible. ' +\n 'Verify connection settings (URL, credentials, network access).';\n\n constructor(\n public readonly transportName: string,\n operation = 'operation',\n ) {\n super(\n `Cannot perform ${operation}: Transport \"${transportName}\" is not connected. Ensure connect() was called and the broker is accessible.`,\n );\n }\n}\n\n/**\n * Thrown when the transport has been closed (during shutdown).\n */\nexport class TransportClosedError extends MatadorError {\n readonly description =\n 'The transport has been closed and will not accept new operations. ' +\n 'ACTION: This typically occurs during application shutdown. ' +\n 'If unexpected, check for early shutdown triggers. ' +\n 'Events sent after transport closure will be lost.';\n\n constructor(public readonly transportName: string) {\n super(\n `Transport \"${transportName}\" has been closed and will not accept new operations.`,\n );\n }\n}\n\n/**\n * Thrown when all transports in a fallback chain fail.\n */\nexport class AllTransportsFailedError extends MatadorError {\n readonly description =\n 'All transports failed to send the message. ' +\n 'ACTION: Check the health of all configured transports (primary and fallbacks). ' +\n 'Review the errors array for specific failure reasons. ' +\n 'Ensure at least one transport is properly configured and reachable. ' +\n 'Consider adding a LocalTransport as a last-resort fallback.';\n\n constructor(\n public readonly queue: string,\n public readonly errors: readonly Error[],\n ) {\n super(\n `All transports failed to send message to queue \"${queue}\". ` +\n `Errors: ${errors.map((e) => e.message).join('; ')}`,\n );\n }\n}\n\n/**\n * Thrown when sending a message to the transport fails.\n */\nexport class TransportSendError extends MatadorError {\n readonly description =\n 'Failed to send a message through the transport. ' +\n 'ACTION: Check the underlying error for details. Common causes: ' +\n '(1) Transport disconnected during send, ' +\n '(2) Network issues between application and broker, ' +\n '(3) Broker rejected the message (size, permissions, queue limits). ' +\n 'The message was NOT delivered and should be retried or logged.';\n\n constructor(\n public readonly queue: string,\n public readonly cause: Error,\n ) {\n super(`Failed to send message to queue \"${queue}\": ${cause.message}`);\n }\n\n override toJSON(): Record<string, unknown> {\n return {\n ...super.toJSON(),\n queue: this.queue,\n cause: {\n name: this.cause.name,\n message: this.cause.message,\n },\n };\n }\n}\n\n/**\n * Thrown when send() completes but one or more subscriber publishes failed.\n * The `errors` array contains per-failure details: subscriber name, target queue, and underlying error.\n */\nexport class SomeSendError extends MatadorError {\n readonly description =\n 'One or more subscriber messages could not be published during send(). ' +\n 'ACTION: Inspect the `errors` array for per-failure details. ' +\n 'Each entry contains the subscriber name, target queue, and underlying error.';\n\n constructor(\n public readonly eventKey: string,\n public readonly errors: ReadonlyArray<{\n subscriberName: string;\n queue: string;\n error: Error;\n }>,\n ) {\n const summary = errors\n .map((e) => `${e.subscriberName} (${e.queue}): ${e.error.message}`)\n .join('; ');\n super(\n `send(\"${eventKey}\") failed for ${errors.length} subscriber(s): ${summary}`,\n );\n }\n}\n\n/**\n * Thrown when delayed messages are requested but the plugin is not available.\n */\nexport class DelayedMessagesNotSupportedError extends MatadorError {\n readonly description =\n 'Delayed messages were requested but the transport does not support them. ' +\n 'ACTION: For RabbitMQ, install the rabbitmq_delayed_message_exchange plugin. ' +\n 'Run: rabbitmq-plugins enable rabbitmq_delayed_message_exchange ' +\n 'Then restart RabbitMQ and reconnect. ' +\n 'Alternatively, remove delayMs from your event options if delays are not required.';\n\n constructor(public readonly transportName: string) {\n super(\n 'Delayed messages require the RabbitMQ delayed message exchange plugin. ' +\n 'Install rabbitmq_delayed_message_exchange or remove delayMs from event options.',\n );\n }\n}\n\n/**\n * Thrown when a LocalTransport is sent a message for a queue with no active\n * subscriber in the current process (e.g. the subscriber is a SubscriberStub\n * implemented in another service, or matador.start() hasn't subscribed yet).\n */\nexport class LocalTransportNoActiveSubscriberError extends MatadorError {\n readonly description =\n 'The LocalTransport has no active subscriber for this queue in the current process, ' +\n 'so it cannot guarantee delivery. ' +\n 'ACTION: If the subscriber is a SubscriberStub (implemented in another service), ' +\n 'the local transport can never deliver it locally — a distributed transport like ' +\n 'RabbitMQ is required. If the subscriber should run in this process, ensure ' +\n 'matador.start() has subscribed to this queue before sending.';\n\n constructor(public readonly queue: string) {\n super(\n `LocalTransport has no active subscriber for queue \"${queue}\"; message cannot be delivered.`,\n );\n }\n}\n\n// ============================================================================\n// Schema & Configuration Errors\n// ============================================================================\n\n/**\n * Thrown when an event is not registered in the schema.\n */\nexport class EventNotRegisteredError extends MatadorError {\n readonly description =\n 'The event type is not registered in the schema. ' +\n 'ACTION: Register the event using matador.register(EventClass, subscribers) before dispatching. ' +\n 'If this occurs during message consumption, it may indicate schema drift between services. ' +\n 'Ensure all services have matching schema registrations for shared events.';\n\n constructor(public readonly eventKey: string) {\n super(\n `Event \"${eventKey}\" is not registered in schema. Register it using matador.register(EventClass, subscribers).`,\n );\n }\n}\n\n/**\n * Thrown when a subscriber is not found for an event.\n */\nexport class SubscriberNotRegisteredError extends MatadorError {\n readonly description =\n 'The subscriber is not registered for this event in the schema. ' +\n 'ACTION: Ensure the subscriber is included in the registration for this event. ' +\n 'This may occur if: (1) The subscriber was removed from the schema but messages still exist, ' +\n '(2) Schema drift between producer and consumer services, ' +\n '(3) A deployment is in progress with different schema versions. ' +\n 'Check the dead-letter queue for affected messages.';\n\n constructor(\n public readonly subscriberName: string,\n public readonly eventKey?: string,\n ) {\n super(\n `Subscriber \"${subscriberName}\" is not registered${eventKey ? ` for event \"${eventKey}\"` : ''}. Check schema registration.`,\n );\n }\n}\n\n/**\n * Thrown when no subscribers exist for an event during fanout.\n */\nexport class NoSubscribersExistError extends MatadorError {\n readonly description =\n 'The event has no subscribers registered. ' +\n 'ACTION: Register at least one subscriber for this event type. ' +\n 'If subscribers were intentionally removed, consider also removing the event dispatch. ' +\n 'Events without subscribers are not useful and may indicate configuration issues.';\n\n constructor(public readonly eventKey: string) {\n super(\n `No subscribers registered for event \"${eventKey}\". Add subscribers using matador.register(EventClass, [subscriber1, subscriber2]).`,\n );\n }\n}\n\n/**\n * Thrown when the schema configuration is invalid.\n */\nexport class InvalidSchemaError extends MatadorError {\n readonly description =\n 'The schema configuration is invalid. ' +\n 'ACTION: Review the schema registration for issues. Common problems: ' +\n '(1) Duplicate subscriber names for the same event, ' +\n '(2) Missing required fields on event class (key, description), ' +\n '(3) Invalid alias configuration. ' +\n 'Check the cause property for specific details.';\n\n constructor(\n message: string,\n public readonly cause?: string,\n ) {\n super(`Invalid schema: ${message}${cause ? `. Cause: ${cause}` : ''}`);\n }\n}\n\n/**\n * Thrown when a subscriber is a stub but is being processed locally.\n */\nexport class SubscriberIsStubError extends MatadorError {\n readonly description =\n 'A SubscriberStub was registered in a consuming schema. ' +\n 'ACTION: SubscriberStubs should only be used in producer schemas to declare ' +\n 'that a subscriber exists in another service. ' +\n 'In the consumer service, provide a full Subscriber with a callback function. ' +\n 'Remove the stub from the consumer schema and add the actual implementation.';\n\n constructor(public readonly subscriberName: string) {\n super(\n `Subscriber \"${subscriberName}\" is a stub and cannot be processed locally. Replace with a full Subscriber implementation in the consumer schema.`,\n );\n }\n}\n\n// ============================================================================\n// Queue Errors\n// ============================================================================\n\n/**\n * Thrown when a subscriber's `targetQueue` or a `consumeFrom` entry references\n * a queue that was never declared in the topology.\n */\nexport class UnknownQueueReferenceError extends MatadorError {\n readonly description =\n 'A queue was referenced that is not declared in the topology. ' +\n 'Matador only routes to queues it knows about; an unknown reference would ' +\n 'otherwise be silently namespace-qualified and published to a queue nobody ' +\n 'consumes, losing the message. ' +\n 'ACTION: Declare the queue on the topology before referencing it. ' +\n 'For a Matador-owned queue use `.addQueue(name)`; for a foreign queue owned ' +\n 'by another service use `.addQueue({ name, exact: true })` so it is routed ' +\n 'to verbatim.';\n\n constructor(public readonly queueName: string) {\n super(\n `Queue reference \"${queueName}\" is not declared in the topology. Add it via .addQueue(name), or .addQueue({ name, exact: true }) for a foreign queue.`,\n );\n }\n}\n\n/**\n * Thrown when a queue is not found or not created.\n */\nexport class QueueNotFoundError extends MatadorError {\n readonly description =\n 'The specified queue does not exist or has not been created. ' +\n 'ACTION: Ensure the queue is defined in the topology configuration. ' +\n 'Call transport.applyTopology() or matador.start() to create queues. ' +\n 'Check that the queue name matches the topology definition.';\n\n constructor(public readonly queueName: string) {\n super(\n `Queue \"${queueName}\" not found. Ensure it is defined in topology and applyTopology() was called.`,\n );\n }\n}\n\n// ============================================================================\n// Event Validation Errors\n// ============================================================================\n\n/**\n * Thrown when an event is invalid or malformed.\n */\nexport class InvalidEventError extends MatadorError {\n readonly description =\n 'The event is invalid or missing required fields. ' +\n 'ACTION: Ensure the event has all required properties. ' +\n 'Common issues: missing targetSubscriber during processing, ' +\n 'null/undefined data when the event type requires data, ' +\n 'malformed event structure from codec decode failure.';\n\n constructor(\n message: string,\n public readonly cause?: string,\n ) {\n super(`Invalid event: ${message}${cause ? `. Cause: ${cause}` : ''}`);\n }\n}\n\n// ============================================================================\n// Message Processing Errors\n// ============================================================================\n\n/**\n * Thrown when a message has been redelivered too many times (poison message).\n */\nexport class MessageMaybePoisonedError extends MatadorError {\n readonly description =\n 'A message was redelivered multiple times without successful processing. ' +\n 'This usually indicates the message causes a crash or timeout during processing. ' +\n 'ACTION: (1) Check application logs for errors/crashes during message processing, ' +\n '(2) Inspect the message in the dead-letter queue for malformed data, ' +\n '(3) Review the subscriber code for bugs that cause crashes, ' +\n '(4) Consider increasing processing timeout if the operation is legitimately slow. ' +\n 'This message will NOT be retried to prevent crash loops.';\n\n constructor(\n public readonly eventId: string,\n public readonly deliveryCount: number,\n public readonly maxDeliveries: number,\n ) {\n super(\n `Message \"${eventId}\" delivered ${deliveryCount} times (max: ${maxDeliveries}). Possible poison message - will not be retried.`,\n );\n }\n}\n\n/**\n * Thrown when a non-idempotent message cannot be retried after redelivery.\n */\nexport class IdempotentMessageCannotRetryError extends MatadorError {\n readonly description =\n 'A non-idempotent subscriber received a redelivered message. ' +\n 'Retrying would risk duplicate side effects (e.g., double payments, duplicate emails). ' +\n 'ACTION: (1) Mark the subscriber as idempotent if it safely handles duplicates, ' +\n '(2) Implement idempotency keys in the subscriber logic, ' +\n '(3) Manually inspect and replay the message from the dead-letter queue after verification. ' +\n 'The message will be sent to the dead-letter queue for manual review.';\n\n constructor(\n public readonly eventId: string,\n public readonly subscriberName: string,\n ) {\n super(\n `Non-idempotent subscriber \"${subscriberName}\" cannot retry redelivered message \"${eventId}\". Mark subscriber as idempotent='yes' or implement idempotency handling.`,\n );\n }\n}\n\n// ============================================================================\n// Timeout Errors\n// ============================================================================\n\n/**\n * Thrown when an operation times out.\n */\nexport class TimeoutError extends MatadorError {\n readonly description =\n 'An operation timed out before completing. ' +\n 'ACTION: (1) Increase the timeout if the operation legitimately needs more time, ' +\n '(2) Optimize the operation to complete faster, ' +\n '(3) Check for deadlocks or blocking operations, ' +\n '(4) Verify external service dependencies are responsive.';\n\n constructor(\n public readonly operation: string,\n public readonly timeoutMs: number,\n ) {\n super(`Operation \"${operation}\" timed out after ${timeoutMs}ms.`);\n }\n}\n\n// ============================================================================\n// Type Guards\n// ============================================================================\n\nexport function isMatadorError(error: unknown): error is MatadorError {\n return error instanceof MatadorError;\n}\n\nexport function isNotStartedError(error: unknown): error is NotStartedError {\n return error instanceof NotStartedError;\n}\n\nexport function isTransportNotConnectedError(\n error: unknown,\n): error is TransportNotConnectedError {\n return error instanceof TransportNotConnectedError;\n}\n\nexport function isEventNotRegisteredError(\n error: unknown,\n): error is EventNotRegisteredError {\n return error instanceof EventNotRegisteredError;\n}\n\nexport function isSubscriberNotRegisteredError(\n error: unknown,\n): error is SubscriberNotRegisteredError {\n return error instanceof SubscriberNotRegisteredError;\n}\n\nexport function isUnknownQueueReferenceError(\n error: unknown,\n): error is UnknownQueueReferenceError {\n return error instanceof UnknownQueueReferenceError;\n}\n\nexport function isMessageMaybePoisonedError(\n error: unknown,\n): error is MessageMaybePoisonedError {\n return error instanceof MessageMaybePoisonedError;\n}\n\nexport function isIdempotentMessageCannotRetryError(\n error: unknown,\n): error is IdempotentMessageCannotRetryError {\n return error instanceof IdempotentMessageCannotRetryError;\n}\n","import { MatadorError } from './matador-errors.js';\n\n/**\n * Thrown when a duplicate io() key is used within a single subscriber execution.\n * Each io() call must have a unique key to prevent cache collisions.\n */\nexport class DuplicateIoKeyError extends MatadorError {\n readonly description =\n 'The same io() key was used multiple times in a single subscriber execution. ' +\n 'Each io() call must have a unique key to ensure correct checkpoint behavior. ' +\n 'ACTION: Ensure all io() keys are unique within the subscriber. ' +\n 'For dynamic operations (e.g., loops), include a unique identifier in the key ' +\n '(e.g., `process-item-${item.id}`).';\n\n constructor(\n public readonly key: string,\n public readonly subscriberName: string,\n ) {\n super(\n `Duplicate io key \"${key}\" in subscriber \"${subscriberName}\". Each io() call must have a unique key.`,\n );\n }\n}\n\n/**\n * Thrown when checkpoint store operations fail.\n */\nexport class CheckpointStoreError extends MatadorError {\n readonly description =\n 'A checkpoint store operation failed. This may cause issues with resumable subscribers. ' +\n 'ACTION: Check the underlying storage system (Redis, etc.) for connectivity issues. ' +\n 'The subscriber may re-execute operations that were already completed.';\n\n constructor(\n public readonly operation: 'get' | 'set' | 'delete',\n public readonly envelopeId: string,\n public readonly cause: Error,\n ) {\n super(\n `Checkpoint store ${operation} failed for envelope \"${envelopeId}\": ${cause.message}`,\n );\n }\n}\n\n/**\n * Type guard for DuplicateIoKeyError.\n */\nexport function isDuplicateIoKeyError(\n error: unknown,\n): error is DuplicateIoKeyError {\n return error instanceof DuplicateIoKeyError;\n}\n\n/**\n * Type guard for CheckpointStoreError.\n */\nexport function isCheckpointStoreError(\n error: unknown,\n): error is CheckpointStoreError {\n return error instanceof CheckpointStoreError;\n}\n","import { UnknownQueueReferenceError } from '../errors/matador-errors.js';\n\n/**\n * A prefix prepended to every default-derived broker resource name so\n * Matador-managed queues and exchanges are identifiable\n * (e.g. `matador.{namespace}.{queue}`).\n *\n * A string is prepended as `${prefix}.`; `null` or `undefined` disables\n * prefixing. Only applies to default names — a {@link TopologyNaming}\n * override fully owns its output and is never prefixed.\n *\n * @example 'matador'\n */\nexport type ResourcePrefix = string | null | undefined;\n\n/**\n * Transport-agnostic topology definition.\n * Matador owns the topology; transports translate and apply it.\n */\nexport interface Topology {\n /** Namespace prefix for all queues */\n readonly namespace: string;\n\n /** Work queues for processing events */\n readonly queues: readonly QueueDefinition[];\n\n /** Dead-letter queue configuration */\n readonly deadLetter: DeadLetterConfig;\n\n /** Retry queue configuration */\n readonly retry: RetryConfig;\n\n /**\n * Optional overrides for how broker resource names are derived.\n * Intended for migrations: lets an adopter keep pre-existing queue and\n * exchange names (e.g. from Matador v1) so a rolling deploy keeps using\n * the broker resources already in place.\n */\n readonly naming?: TopologyNaming | undefined;\n\n /**\n * Prefix prepended to every default-derived broker resource name so\n * Matador-managed queues and exchanges are identifiable\n * (e.g. `matador.{namespace}.{queue}`).\n *\n * `null` disables prefixing. Only applies to default names — a `naming`\n * override fully owns its output and is never prefixed.\n *\n * Topologies built via {@link TopologyBuilder} default this to `'matador'`.\n * When absent (e.g. a hand-built topology literal) no prefix is applied.\n *\n * @default 'matador'\n */\n readonly prefix?: ResourcePrefix;\n}\n\n/**\n * Strategy for deriving broker resource names.\n *\n * Each builder receives the namespace as an explicit argument and returns the\n * final name, so the namespace is always an input to the strategy — it is\n * never applied separately on top of the result. Provide only the builders you\n * want to override; the rest keep Matador's defaults:\n * - work queue: `${namespace}.${queueName}`\n * - main exchange: `${namespace}.exchange`\n * - dead-letter exchange: `${namespace}.dlx`\n * - delayed exchange: `${namespace}.delayed`\n *\n * Retry queues and DLQs have no builder of their own: they are derived from the\n * work-queue name (`<queue>.retry`, `<queue>.unhandled`, `<queue>.undeliverable`),\n * so overriding `queue` carries your prefix into them automatically.\n *\n * Intended for migrations: an adopter can keep pre-existing names (e.g. from\n * Matador v1) so a rolling deploy keeps using the broker resources already in\n * place instead of draining or dual-consuming.\n *\n * @example Keep Matador v1 names (`matador.{namespace}.{queue}`):\n * ```typescript\n * TopologyBuilder.create()\n * .withNamespace('myapp')\n * .withNaming({\n * queue: (ns, q) => `matador.${ns}.${q}`,\n * mainExchange: (ns) => `matador.${ns}`,\n * dlxExchange: (ns) => `matador.${ns}.dlx-undeliverable`,\n * dlxExchangeType: 'topic',\n * delayedExchange: (ns) => `matador.${ns}.delayed`,\n * })\n * ```\n */\nexport interface TopologyNaming {\n /**\n * Builds the qualified work-queue name from the namespace and queue name.\n * Retry queues and DLQs are derived from the result automatically\n * (`<queue>.retry`, `<queue>.unhandled`, `<queue>.undeliverable`).\n * Default builds `${namespace}.${queueName}`.\n */\n readonly queue?:\n | ((namespace: string, queueName: string) => string)\n | undefined;\n\n /** Builds the main exchange name. Default builds `${namespace}.exchange`. */\n readonly mainExchange?: ((namespace: string) => string) | undefined;\n\n /** Builds the dead-letter exchange name. Default builds `${namespace}.dlx`. */\n readonly dlxExchange?: ((namespace: string) => string) | undefined;\n\n /**\n * Exchange type used when asserting the dead-letter exchange.\n * Useful when an existing DLX was declared as `topic` — asserting it as\n * `direct` would fail with PRECONDITION_FAILED. Literal (non-wildcard)\n * binding keys behave identically on a topic exchange.\n * Default: `'direct'`.\n */\n readonly dlxExchangeType?: 'direct' | 'topic' | undefined;\n\n /** Builds the delayed-message exchange name. Default builds `${namespace}.delayed`. */\n readonly delayedExchange?: ((namespace: string) => string) | undefined;\n}\n\n/**\n * Individual queue definition.\n */\nexport interface QueueDefinition {\n /** Queue name (will be prefixed with namespace unless exact: true) */\n readonly name: string;\n\n /** Concurrency for this queue */\n readonly concurrency?: number | undefined;\n\n /** Consumer timeout in milliseconds */\n readonly consumerTimeout?: number | undefined;\n\n /** Enable priority support if transport allows */\n readonly priorities?: boolean | undefined;\n\n /**\n * When true, the queue name is used exactly as provided without any\n * modification. The namespace prefix will NOT be added, and no other\n * transformations will be applied. Use this for referencing external\n * queues that are not managed by Matador.\n */\n readonly exact?: boolean | undefined;\n\n /** Transport-specific queue options */\n readonly transport?: TransportQueueOptions | undefined;\n}\n\n/**\n * Transport-specific queue options.\n * Each transport can define its own options under its transport name key.\n */\nexport interface TransportQueueOptions {\n /** RabbitMQ-specific queue options */\n readonly rabbitmq?: RabbitMQQueueDefinition | undefined;\n}\n\n/**\n * RabbitMQ-specific queue definition options.\n */\nexport interface RabbitMQQueueDefinition {\n /**\n * Exact RabbitMQ queue assertion options.\n * When provided, these options completely replace all auto-computed defaults\n * (durable, x-queue-type, x-dead-letter-exchange, etc.).\n */\n readonly options?: RabbitMQQueueOptions | undefined;\n}\n\n/**\n * RabbitMQ queue assertion options.\n * Maps to amqplib's Options.AssertQueue.\n */\nexport interface RabbitMQQueueOptions {\n /** Queue survives broker restart */\n readonly durable?: boolean | undefined;\n\n /** Queue is deleted when last consumer unsubscribes */\n readonly autoDelete?: boolean | undefined;\n\n /** Queue can only be used by the declaring connection */\n readonly exclusive?: boolean | undefined;\n\n /** Exchange to which dead-lettered messages are sent */\n readonly deadLetterExchange?: string | undefined;\n\n /** Routing key for dead-lettered messages */\n readonly deadLetterRoutingKey?: string | undefined;\n\n /** Message TTL in milliseconds */\n readonly messageTtl?: number | undefined;\n\n /** Queue expires after this many milliseconds of non-use */\n readonly expires?: number | undefined;\n\n /** Maximum number of messages in the queue */\n readonly maxLength?: number | undefined;\n\n /** Maximum priority level (0-255) */\n readonly maxPriority?: number | undefined;\n\n /** Additional x-* arguments for RabbitMQ */\n readonly arguments?: Record<string, unknown> | undefined;\n}\n\n/**\n * Dead-letter queue configuration.\n */\nexport interface DeadLetterConfig {\n /** Unhandled events (schema mismatch) queue */\n readonly unhandled: DeadLetterQueueConfig;\n\n /** Undeliverable events (permanent failures) queue */\n readonly undeliverable: DeadLetterQueueConfig;\n}\n\n/**\n * Configuration for a specific dead-letter queue.\n */\nexport interface DeadLetterQueueConfig {\n /** Whether this DLQ is enabled */\n readonly enabled: boolean;\n\n /** Maximum number of messages in the DLQ */\n readonly maxLength?: number | undefined;\n}\n\n/**\n * Retry queue configuration.\n */\nexport interface RetryConfig {\n /** Enable retry queue with delay */\n readonly enabled: boolean;\n\n /** Default retry delay in milliseconds */\n readonly defaultDelayMs: number;\n\n /** Maximum retry delay in milliseconds */\n readonly maxDelayMs: number;\n}\n\n/**\n * Prepends a resource-name prefix unless it is disabled.\n * `null`/`undefined` mean no prefix; a string is prepended as `${prefix}.`.\n */\nexport function applyPrefix(prefix: ResourcePrefix, name: string): string {\n return prefix == null ? name : `${prefix}.${name}`;\n}\n\n/**\n * Gets the fully qualified work-queue name.\n * An optional naming strategy may override how the name is derived; otherwise\n * the default is `${namespace}.${queueName}`, optionally prefixed.\n */\nexport function getQualifiedQueueName(\n namespace: string,\n queueName: string,\n naming?: TopologyNaming,\n prefix?: ResourcePrefix,\n): string {\n return (\n naming?.queue?.(namespace, queueName) ??\n applyPrefix(prefix, `${namespace}.${queueName}`)\n );\n}\n\n/**\n * Gets the dead-letter queue name for a given queue.\n */\nexport function getDeadLetterQueueName(\n namespace: string,\n queueName: string,\n dlqType: 'unhandled' | 'undeliverable',\n naming?: TopologyNaming,\n prefix?: ResourcePrefix,\n): string {\n return `${getQualifiedQueueName(namespace, queueName, naming, prefix)}.${dlqType}`;\n}\n\n/**\n * Gets the retry queue name for a given queue.\n */\nexport function getRetryQueueName(\n namespace: string,\n queueName: string,\n naming?: TopologyNaming,\n prefix?: ResourcePrefix,\n): string {\n return `${getQualifiedQueueName(namespace, queueName, naming, prefix)}.retry`;\n}\n\n/**\n * Resolves the actual queue name for a given queue definition.\n * When exact: true, returns name as-is. Otherwise, returns the\n * namespace-qualified name (honoring any naming overrides and prefix).\n */\nexport function resolveQueueName(\n namespace: string,\n queueDef: QueueDefinition,\n naming?: TopologyNaming,\n prefix?: ResourcePrefix,\n): string {\n if (queueDef.exact) {\n return queueDef.name;\n }\n return getQualifiedQueueName(namespace, queueDef.name, naming, prefix);\n}\n\n/**\n * Finds the queue definition a local queue reference points at.\n */\nexport function findQueueDefinition(\n topology: Topology,\n queueName: string,\n): QueueDefinition | undefined {\n return topology.queues.find((q) => q.name === queueName);\n}\n\n/**\n * Resolves a local queue reference (a subscriber's `targetQueue` or a\n * `consumeFrom` entry) to the transport-level queue name.\n *\n * The reference must be declared in the topology via `.addQueue(...)`:\n * an exact queue resolves to its name as-is; a Matador-owned queue is\n * namespace-qualified (honoring any naming overrides). An undeclared\n * reference throws {@link UnknownQueueReferenceError} rather than being\n * silently qualified and routed to a queue nobody consumes.\n *\n * @throws UnknownQueueReferenceError if `queueName` is not in `topology.queues`.\n */\nexport function resolveTargetQueueName(\n topology: Topology,\n queueName: string,\n): string {\n const def = findQueueDefinition(topology, queueName);\n if (def === undefined) {\n throw new UnknownQueueReferenceError(queueName);\n }\n if (def.exact) {\n return def.name;\n }\n return getQualifiedQueueName(\n topology.namespace,\n queueName,\n topology.naming,\n topology.prefix,\n );\n}\n","import type { HasDescription } from '../errors/index.js';\nimport type {\n DeadLetterConfig,\n QueueDefinition,\n ResourcePrefix,\n RetryConfig,\n Topology,\n TopologyNaming,\n} from './types.js';\n\n/**\n * Options for adding a queue.\n * Excludes 'name' as that is provided as the first argument to addQueue.\n */\nexport type QueueOptions = Omit<QueueDefinition, 'name'>;\n\n/**\n * Type guard to check if the argument is a QueueDefinition object.\n */\nfunction isQueueDefinition(\n arg: string | QueueDefinition,\n): arg is QueueDefinition {\n return typeof arg === 'object' && arg !== null && 'name' in arg;\n}\n\n/**\n * Error thrown when topology validation fails.\n */\nexport class TopologyValidationError extends Error implements HasDescription {\n readonly description =\n 'The topology configuration is invalid. Check the issues array for ' +\n 'specific validation failures such as missing namespace, invalid queue ' +\n 'names, or conflicting settings. This error occurs during Matador ' +\n 'initialization and must be fixed in the configuration.';\n\n constructor(\n message: string,\n public readonly issues: readonly string[],\n ) {\n super(message);\n this.name = 'TopologyValidationError';\n }\n}\n\n/**\n * Fluent builder for creating Topology configurations.\n */\nexport class TopologyBuilder {\n /**\n * Creates a new TopologyBuilder instance.\n */\n static create(): TopologyBuilder {\n return new TopologyBuilder();\n }\n\n private namespace = '';\n private queues: QueueDefinition[] = [];\n private deadLetter: DeadLetterConfig = {\n unhandled: { enabled: true },\n undeliverable: { enabled: true },\n };\n private retry: RetryConfig = {\n enabled: true,\n defaultDelayMs: 1000,\n maxDelayMs: 300000, // 5 minutes\n };\n private naming: TopologyNaming | undefined;\n private prefix: ResourcePrefix = 'matador';\n\n /**\n * Sets the namespace prefix for all queues.\n */\n withNamespace(namespace: string): this {\n this.namespace = namespace;\n return this;\n }\n\n /**\n * Sets the prefix prepended to every default-derived broker resource name\n * (e.g. `matador.{namespace}.{queue}`), so Matador-managed queues and\n * exchanges are identifiable. Pass `null` to disable prefixing.\n *\n * Only applies to default names — a {@link withNaming} override fully owns\n * its output and is never prefixed.\n *\n * Pass `null` or `undefined` to disable prefixing.\n *\n * @default 'matador'\n * @example\n * TopologyBuilder.create().withNamespace('myapp') // matador.myapp.events\n * TopologyBuilder.create().withNamespace('myapp').withGlobalPrefix('acme') // acme.myapp.events\n * TopologyBuilder.create().withNamespace('myapp').withGlobalPrefix(null) // myapp.events\n */\n withGlobalPrefix(prefix: ResourcePrefix): this {\n this.prefix = prefix;\n return this;\n }\n\n /**\n * Overrides how broker resource names are derived.\n * Use during migrations to keep pre-existing queue/exchange names so a\n * rolling deploy keeps routing through the resources already declared on\n * the broker.\n * @see TopologyNaming\n */\n withNaming(naming: TopologyNaming): this {\n this.naming = naming;\n return this;\n }\n\n /**\n * Adds a queue to the topology.\n * @param definition - A complete QueueDefinition object\n */\n addQueue(definition: QueueDefinition): this;\n /**\n * Adds a queue to the topology.\n * @param name - Queue name\n * @param options - Queue options\n */\n addQueue(name: string, options?: QueueOptions): this;\n addQueue(\n nameOrDefinition: string | QueueDefinition,\n options: QueueOptions = {},\n ): this {\n if (isQueueDefinition(nameOrDefinition)) {\n this.queues.push(nameOrDefinition);\n } else {\n this.queues.push({ name: nameOrDefinition, ...options });\n }\n return this;\n }\n\n /**\n * Alias for addQueue().\n * @param definition - A complete QueueDefinition object\n */\n queue(definition: QueueDefinition): this;\n /**\n * Alias for addQueue().\n * @param name - Queue name\n * @param options - Queue options\n */\n queue(name: string, options?: QueueOptions): this;\n queue(\n nameOrDefinition: string | QueueDefinition,\n options: QueueOptions = {},\n ): this {\n if (isQueueDefinition(nameOrDefinition)) {\n return this.addQueue(nameOrDefinition);\n }\n return this.addQueue(nameOrDefinition, options);\n }\n\n /**\n * Configures dead-letter queue settings.\n */\n withDeadLetter(config: Partial<DeadLetterConfig>): this {\n this.deadLetter = {\n unhandled: config.unhandled ?? this.deadLetter.unhandled,\n undeliverable: config.undeliverable ?? this.deadLetter.undeliverable,\n };\n return this;\n }\n\n /**\n * Configures retry settings.\n */\n withRetry(config: Partial<RetryConfig>): this {\n this.retry = {\n enabled: config.enabled ?? this.retry.enabled,\n defaultDelayMs: config.defaultDelayMs ?? this.retry.defaultDelayMs,\n maxDelayMs: config.maxDelayMs ?? this.retry.maxDelayMs,\n };\n return this;\n }\n\n /**\n * Disables retry functionality.\n */\n withoutRetry(): this {\n this.retry = { ...this.retry, enabled: false };\n return this;\n }\n\n /**\n * Disables dead-letter queues.\n */\n withoutDeadLetter(): this {\n this.deadLetter = {\n unhandled: { enabled: false },\n undeliverable: { enabled: false },\n };\n return this;\n }\n\n /**\n * Validates the topology configuration.\n */\n validate(): readonly string[] {\n return [\n ...validateNamespace(this.namespace),\n ...validatePrefix(this.prefix),\n ...validateQueues(this.queues),\n ...validateRetry(this.retry),\n ...validateNaming(this.naming),\n ];\n }\n\n /**\n * Builds the topology configuration.\n * @throws TopologyValidationError if validation fails\n */\n build(): Topology {\n const issues = this.validate();\n if (issues.length > 0) {\n throw new TopologyValidationError(\n `Invalid topology: ${issues.join('; ')}`,\n issues,\n );\n }\n\n return {\n namespace: this.namespace,\n queues: [...this.queues],\n deadLetter: this.deadLetter,\n retry: this.retry,\n naming: this.naming,\n prefix: this.prefix,\n };\n }\n}\n\nconst IDENTIFIER_PATTERN = /^[a-zA-Z][a-zA-Z0-9_-]*$/;\n\nfunction validateNamespace(namespace: string): string[] {\n if (!namespace || namespace.trim() === '') {\n return ['Namespace is required'];\n }\n if (!IDENTIFIER_PATTERN.test(namespace)) {\n return [\n 'Namespace must start with a letter and contain only alphanumeric characters, underscores, and hyphens',\n ];\n }\n return [];\n}\n\nfunction validatePrefix(prefix: ResourcePrefix): string[] {\n // null/undefined explicitly disable prefixing.\n if (prefix == null) {\n return [];\n }\n if (prefix.trim() === '') {\n return ['Prefix must be a non-empty string, or null to disable prefixing'];\n }\n if (!IDENTIFIER_PATTERN.test(prefix)) {\n return [\n 'Prefix must start with a letter and contain only alphanumeric characters, underscores, and hyphens',\n ];\n }\n return [];\n}\n\nfunction validateQueueName(\n queue: QueueDefinition,\n seen: Set<string>,\n): string[] {\n if (!queue.name || queue.name.trim() === '') {\n return ['Queue name cannot be empty'];\n }\n if (!queue.exact && !IDENTIFIER_PATTERN.test(queue.name)) {\n return [\n `Queue name \"${queue.name}\" must start with a letter and contain only alphanumeric characters, underscores, and hyphens`,\n ];\n }\n if (seen.has(queue.name)) {\n return [`Duplicate queue name: \"${queue.name}\"`];\n }\n seen.add(queue.name);\n return [];\n}\n\nfunction validateQueueLimits(queue: QueueDefinition): string[] {\n const issues: string[] = [];\n if (queue.concurrency !== undefined && queue.concurrency < 1) {\n issues.push(`Queue \"${queue.name}\" concurrency must be at least 1`);\n }\n if (queue.consumerTimeout !== undefined && queue.consumerTimeout < 0) {\n issues.push(`Queue \"${queue.name}\" consumer timeout must be non-negative`);\n }\n return issues;\n}\n\nfunction validateQueues(queues: readonly QueueDefinition[]): string[] {\n const issues: string[] = [];\n if (queues.length === 0) {\n issues.push('At least one queue is required');\n }\n const seen = new Set<string>();\n for (const queue of queues) {\n issues.push(...validateQueueName(queue, seen));\n issues.push(...validateQueueLimits(queue));\n }\n return issues;\n}\n\nfunction validateNaming(naming: TopologyNaming | undefined): string[] {\n if (!naming) return [];\n const issues: string[] = [];\n for (const field of [\n 'queue',\n 'mainExchange',\n 'dlxExchange',\n 'delayedExchange',\n ] as const) {\n const value = naming[field];\n if (value !== undefined && typeof value !== 'function') {\n issues.push(`Naming override \"${field}\" must be a function`);\n }\n }\n if (\n naming.dlxExchangeType !== undefined &&\n naming.dlxExchangeType !== 'direct' &&\n naming.dlxExchangeType !== 'topic'\n ) {\n issues.push(\n `Naming override \"dlxExchangeType\" must be 'direct' or 'topic'`,\n );\n }\n return issues;\n}\n\nfunction validateRetry(retry: RetryConfig): string[] {\n if (!retry.enabled) return [];\n const issues: string[] = [];\n if (retry.defaultDelayMs < 0) {\n issues.push('Default retry delay must be non-negative');\n }\n if (retry.maxDelayMs < retry.defaultDelayMs) {\n issues.push(\n 'Max retry delay must be greater than or equal to default delay',\n );\n }\n return issues;\n}\n","/**\n * Delivery semantics for message processing.\n * - 'at-least-once': Acknowledge after processing (may redeliver on failure)\n * - 'at-most-once': Acknowledge before processing (no redelivery, may lose messages)\n */\nexport type DeliveryMode = 'at-least-once' | 'at-most-once';\n\n/**\n * Importance level for subscribers, used for monitoring and alerting prioritization.\n */\nexport type Importance =\n | 'can-ignore'\n | 'should-investigate'\n | 'must-investigate';\n\n/**\n * Idempotency declaration for subscribers.\n * - 'yes': Safe to retry on failure (subscriber handles duplicates)\n * - 'no': Not safe to retry, may cause duplicate side effects\n * - 'unknown': Idempotency not determined (default)\n * - 'resumable': Uses checkpoint-based idempotency via io() calls\n */\nexport type Idempotency = 'yes' | 'no' | 'unknown' | 'resumable';\n\n/**\n * Result of a validation operation.\n */\nexport interface ValidationResult {\n readonly valid: boolean;\n readonly errors: readonly ValidationError[];\n}\n\n/**\n * Individual validation error.\n */\nexport interface ValidationError {\n readonly path: string;\n readonly message: string;\n}\n\n/**\n * Creates a successful validation result.\n */\nexport function validResult(): ValidationResult {\n return { valid: true, errors: [] };\n}\n\n/**\n * Creates a failed validation result.\n */\nexport function invalidResult(errors: ValidationError[]): ValidationResult {\n return { valid: false, errors };\n}\n","import type { Importance } from './common.js';\nimport type { Event, EventStatic } from './event.js';\n\n/**\n * Message envelope containing the event data and routing/observability metadata.\n * This is the transport-agnostic message format used throughout Matador.\n */\nexport interface Envelope<T = unknown> {\n /** Unique message ID (UUID v4) */\n readonly id: string;\n\n /** The event data */\n readonly data: T;\n\n /** Routing, processing state, and observability metadata */\n readonly docket: Docket;\n}\n\n/**\n * Metadata associated with an envelope for routing, processing state, and observability.\n */\nexport interface Docket {\n // === Routing ===\n\n /** Event key for routing */\n readonly eventKey: string;\n\n /** Human-readable description of the event (for observability/logging) */\n readonly eventDescription?: string | undefined;\n\n /** Target subscriber name for 1:1 routing */\n readonly targetSubscriber: string;\n\n /** Original queue before any dead-letter routing */\n originalQueue?: string | undefined;\n\n /** Scheduled processing time for delayed messages (ISO 8601 string) */\n scheduledFor?: string | undefined;\n\n // === Processing State ===\n\n /**\n * Attempt counter managed by Matador (1-based).\n * Incremented on each retry. Used when transport doesn't track attempts.\n */\n attempts: number;\n\n /** When the envelope was first created (ISO 8601 string) */\n readonly createdAt: string;\n\n /** Error message from first failure (for debugging) */\n firstError?: string | undefined;\n\n /** Error message from most recent failure */\n lastError?: string | undefined;\n\n // === Observability ===\n\n /** Importance level for monitoring */\n readonly importance: Importance;\n\n /** Correlation ID for request tracing */\n readonly correlationId?: string | undefined;\n\n /**\n * Custom metadata provided by the application.\n * This is the merged result of universal metadata (from loadUniversalMetadata hook)\n * and event-specific metadata (from dispatch options). Event-specific metadata\n * overrides universal metadata when keys conflict.\n */\n readonly metadata?: Record<string, unknown> | undefined;\n}\n\n/**\n * Fields from Docket that can be specified when creating an envelope.\n */\ntype DocketCreateFields = Pick<\n Docket,\n | 'eventKey'\n | 'eventDescription'\n | 'targetSubscriber'\n | 'importance'\n | 'correlationId'\n>;\n\n/**\n * Options for creating an envelope.\n */\nexport interface CreateEnvelopeOptions<T> extends DocketCreateFields {\n /** Optional custom ID (defaults to UUID v4) */\n readonly id?: string | undefined;\n\n /** The event data */\n readonly data: T;\n\n /**\n * Event-specific metadata to include in the docket.\n * Will be merged with universal metadata, with these values taking precedence.\n */\n readonly metadata?: Record<string, unknown> | undefined;\n\n /**\n * Universal metadata loaded from the loadUniversalMetadata hook.\n * This is provided by the fanout engine, not by the caller.\n * @internal\n */\n readonly universalMetadata?: Record<string, unknown> | undefined;\n\n /** Delay processing by this many milliseconds */\n readonly delayMs?: number | undefined;\n}\n\n/**\n * Creates a new envelope with the provided options.\n */\nexport function createEnvelope<T>(\n options: CreateEnvelopeOptions<T>,\n): Envelope<T> {\n const now = new Date().toISOString();\n\n // Merge universal metadata with event-specific metadata\n // Event-specific metadata takes precedence\n const mergedMetadata =\n options.universalMetadata || options.metadata\n ? { ...options.universalMetadata, ...options.metadata }\n : undefined;\n\n return {\n id: options.id ?? crypto.randomUUID(),\n data: options.data,\n docket: {\n // Routing\n eventKey: options.eventKey,\n ...(options.eventDescription !== undefined && {\n eventDescription: options.eventDescription,\n }),\n targetSubscriber: options.targetSubscriber,\n ...(options.delayMs !== undefined &&\n options.delayMs > 0 && {\n scheduledFor: new Date(Date.now() + options.delayMs).toISOString(),\n }),\n // Processing state\n attempts: 1,\n createdAt: now,\n // Observability\n importance: options.importance,\n ...(options.correlationId !== undefined && {\n correlationId: options.correlationId,\n }),\n ...(mergedMetadata !== undefined && { metadata: mergedMetadata }),\n },\n };\n}\n\n/**\n * Options for creating a dummy envelope.\n * All fields are optional and will use sensible defaults if not provided.\n */\nexport interface CreateDummyEnvelopeOptions {\n readonly id?: string | undefined;\n readonly eventKey?: string | undefined;\n readonly eventDescription?: string | undefined;\n readonly targetSubscriber?: string | undefined;\n readonly importance?: Importance | undefined;\n readonly correlationId?: string | undefined;\n readonly metadata?: Record<string, unknown> | undefined;\n readonly delayMs?: number | undefined;\n}\n\n/**\n * Type helper to extract the data type from an Event, or return T as-is.\n */\ntype ExtractData<T> = T extends Event<infer D> ? D : T;\n\n/**\n * Checks if a value is a Matador Event (has data property and constructor with key).\n */\nfunction isEvent<T>(value: unknown): value is Event<T> {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'data' in value &&\n typeof (value.constructor as EventStatic).key === 'string'\n );\n}\n\n/**\n * Helper to create a test envelope for a given event instance or raw data.\n * Useful for unit testing subscriber callbacks directly.\n *\n * When passing an Event instance, the eventKey and eventDescription will be\n * automatically extracted from the event class (unless overridden in options).\n *\n * @example With raw data\n * ```typescript\n * const envelope = createDummyEnvelope({ userId: '123', email: 'test@example.com' });\n * ```\n *\n * @example With an Event instance\n * ```typescript\n * const event = new UserCreatedEvent({ userId: '123', email: 'test@example.com' });\n * const envelope = createDummyEnvelope(event);\n * // eventKey is automatically set to UserCreatedEvent.key\n * await mySubscriber.callback(envelope, event.data);\n * ```\n *\n * @example With options\n * ```typescript\n * const event = new UserCreatedEvent({ userId: '123', email: 'test@example.com' });\n * const envelope = createDummyEnvelope(event, {\n * metadata: { traceId: 'abc-123' },\n * correlationId: 'request-456',\n * });\n * ```\n */\nexport function createDummyEnvelope<T>(\n dataOrEvent: T,\n options?: CreateDummyEnvelopeOptions,\n): Envelope<ExtractData<T>> {\n let data: ExtractData<T>;\n let eventKey = options?.eventKey ?? 'dummy.event.key';\n let eventDescription = options?.eventDescription;\n\n if (isEvent(dataOrEvent)) {\n data = dataOrEvent.data as ExtractData<T>;\n const eventStatic = dataOrEvent.constructor as EventStatic;\n eventKey = options?.eventKey ?? eventStatic.key;\n eventDescription = options?.eventDescription ?? eventStatic.description;\n } else {\n data = dataOrEvent as ExtractData<T>;\n }\n\n return createEnvelope({\n data,\n eventKey,\n eventDescription,\n targetSubscriber: options?.targetSubscriber ?? 'dummy-subscriber',\n importance: options?.importance ?? 'can-ignore',\n id: options?.id,\n correlationId: options?.correlationId,\n metadata: options?.metadata,\n delayMs: options?.delayMs,\n });\n}\n","import type { Jsonifiable } from 'type-fest';\n\n/**\n * Unique event routing key type alias.\n */\nexport type EventKey = string;\n\n/**\n * JSON-serializable record type for metadata.\n * Uses type-fest's Jsonifiable which accepts:\n * - Primitives (string, number, boolean, null)\n * - Arrays of Jsonifiable values\n * - Objects with Jsonifiable values\n * - Objects with a toJSON() method\n */\nexport type JsonRecord = Record<string, Jsonifiable>;\n\n/**\n * Static properties required on Event classes for schema registration.\n */\nexport interface EventStatic<T = unknown> {\n /** Unique routing key for the event */\n readonly key: string;\n\n /** Human-readable description of the event */\n readonly description?: string;\n\n /** Alternative names/keys for backwards compatibility */\n readonly aliases?: readonly string[];\n\n /** Create an instance from data (for deserialization) */\n new (data: T): Event<T>;\n}\n\n/**\n * Base interface for all events.\n * Events represent something that happened in the system.\n */\nexport interface Event<T = unknown> {\n /** The event data/payload */\n readonly data: T;\n\n /** Event-specific metadata (merged with EventOptions metadata on dispatch) */\n readonly metadata?: JsonRecord | undefined;\n}\n\n/**\n * Options for dispatching an event.\n */\nexport interface EventOptions {\n /** Delay processing by this many milliseconds */\n readonly delayMs?: number | undefined;\n\n /** Correlation ID for request tracing */\n readonly correlationId?: string | undefined;\n\n /**\n * Event-specific metadata to include in the docket.\n * This metadata will be merged with:\n * 1. Event instance metadata (if defined on the event)\n * 2. Universal metadata from the loadUniversalMetadata hook\n * With EventOptions metadata taking precedence over event metadata,\n * and both taking precedence over universal metadata.\n */\n readonly metadata?: JsonRecord | undefined;\n\n /**\n * Whether to buffer this send for retry on reconnect if all transports fail.\n * When true (default), failed sends are held in memory and retried automatically\n * when the transport reconnects.\n * When false, failures are reported immediately in result.errors with no retry.\n *\n * @default true\n */\n readonly buffer?: boolean | undefined;\n\n /**\n * Whether to throw an error when a buffered failure is reported.\n * Only meaningful when buffer is true. When true, the send is buffered\n * for retry AND reported as an error so the caller is aware it failed.\n *\n * @default false\n */\n readonly throwOnBufferedFailure?: boolean | undefined;\n}\n\n/**\n * Abstract base class for creating Matador events.\n * Extend this class to define custom events.\n *\n * @example\n * ```typescript\n * class UserCreatedEvent extends MatadorEvent {\n * static readonly key = 'user.created'\n * static readonly description = 'Fired when a new user is created'\n *\n * constructor(\n * public data: { userId: string; email: string },\n * public metadata?: JsonRecord,\n * ) {\n * super()\n * }\n * }\n * ```\n */\nexport abstract class MatadorEvent<T = unknown> implements Event<T> {\n static readonly key: string;\n static readonly description?: string;\n static readonly aliases?: readonly string[];\n\n /** The event data/payload - must be defined by subclass */\n abstract readonly data: T;\n\n /** Event-specific metadata */\n readonly metadata?: JsonRecord | undefined;\n}\n\n/**\n * Type helper to extract the data type from an event class.\n */\nexport type EventData<E extends Event<unknown>> = E extends Event<infer T>\n ? T\n : never;\n\n/**\n * Type helper to get the event class type.\n */\nexport type EventClass<T = unknown> = EventStatic<T> &\n (new (\n data: T,\n ) => Event<T>);\n","import type { SubscriberContext } from '../checkpoint/index.js';\nimport type { Idempotency, Importance } from './common.js';\nimport type { Dispatcher } from './dispatcher.js';\nimport type { Envelope } from './envelope.js';\nimport type { MatadorEvent } from './event.js';\n\n/**\n * Context passed to subscriber callbacks.\n * Provides access to the Matador instance for sending additional events.\n */\nexport interface CallbackContext {\n /** Matador dispatcher for sending additional events from within a subscriber */\n readonly matador: Dispatcher;\n}\n\n/**\n * Helper type to get the envelope type for a subscriber callback.\n * Extracts the data type from a MatadorEvent and wraps it in an Envelope.\n *\n * @example\n * async callback(envelope: EnvelopeOf<MyEvent>) {\n * console.log(envelope.data.someField); // Type-safe access\n * }\n */\nexport type EnvelopeOf<T extends MatadorEvent> = Envelope<T['data']>;\n\n/**\n * Callback function executed when an event is received (standard subscribers).\n * Receives the full envelope containing id, data, and docket, plus a context\n * with access to the matador instance for sending additional events.\n *\n * The callback may optionally return a value, which will be included in the\n * onWorkerSuccess hook context for logging or observability purposes.\n */\nexport type StandardCallback<T = unknown> = (\n envelope: Envelope<T>,\n context: CallbackContext,\n) => Promise<unknown> | unknown | undefined;\n\n/**\n * Context for resumable subscriber callbacks.\n * Combines checkpoint operations (io, all) with matador access.\n */\nexport type ResumableCallbackContext = SubscriberContext & CallbackContext;\n\n/**\n * Callback function for resumable subscribers.\n * Receives the envelope and a context with io() for checkpointed operations\n * and matador for sending additional events.\n *\n * The callback may optionally return a value, which will be included in the\n * onWorkerSuccess hook context for logging or observability purposes.\n */\nexport type ResumableCallback<T = unknown> = (\n envelope: Envelope<T>,\n context: ResumableCallbackContext,\n) => Promise<unknown> | unknown | undefined;\n\n/**\n * Callback function executed when an event is received.\n * @deprecated Use StandardCallback or ResumableCallback instead.\n */\nexport type SubscriberCallback<T = unknown> = StandardCallback<T>;\n\n/**\n * Base configuration options shared by all subscriber types.\n */\nexport interface BaseSubscriberOptions {\n /** Human-readable description of what this subscriber does */\n readonly description: string;\n\n /** Route this subscriber's events to a specific queue */\n readonly targetQueue?: string | undefined;\n\n /** Importance level for monitoring and alerting */\n readonly importance?: Importance | undefined;\n\n /** Feature flag function to conditionally enable/disable the subscriber */\n readonly enabled?: (() => boolean | Promise<boolean>) | undefined;\n}\n\n/**\n * Options for standard (non-resumable) subscribers.\n */\nexport interface StandardSubscriberOptions extends BaseSubscriberOptions {\n /** Idempotency declaration for retry handling (non-resumable) */\n readonly idempotent?: 'yes' | 'no' | 'unknown' | undefined;\n}\n\n/**\n * Options for resumable subscribers that use io() for checkpointed operations.\n */\nexport interface ResumableSubscriberOptions extends BaseSubscriberOptions {\n /** Must be 'resumable' to enable checkpoint-based idempotency */\n readonly idempotent: 'resumable';\n}\n\n/**\n * Configuration options for a subscriber.\n * Discriminated union based on idempotent value.\n */\nexport type SubscriberOptions =\n | StandardSubscriberOptions\n | ResumableSubscriberOptions;\n\n/**\n * Standard subscriber definition with standard callback.\n */\nexport interface StandardSubscriber<T extends MatadorEvent>\n extends StandardSubscriberOptions {\n /** Human-readable name for the subscriber */\n readonly name: string;\n\n /** Callback function to execute when event is received */\n readonly callback: StandardCallback<T['data']>;\n}\n\n/**\n * Resumable subscriber definition with resumable callback.\n */\nexport interface ResumableSubscriber<T extends MatadorEvent>\n extends ResumableSubscriberOptions {\n /** Human-readable name for the subscriber */\n readonly name: string;\n\n /** Callback function with SubscriberContext for checkpointed operations */\n readonly callback: ResumableCallback<T['data']>;\n}\n\n/**\n * Full subscriber definition with callback (either standard or resumable).\n */\nexport type Subscriber<T extends MatadorEvent> =\n | StandardSubscriber<T>\n | ResumableSubscriber<T>;\n\n/**\n * Subscriber stub for multi-codebase scenarios where subscriber implementation\n * is in a remote service. Declares the subscriber contract without providing\n * the callback.\n */\nexport interface SubscriberStub\n extends Omit<StandardSubscriberOptions, 'description'> {\n /** Human-readable name for the subscriber */\n readonly name: string;\n\n /** Indicates this is a stub without implementation */\n readonly isStub: true;\n}\n\n/**\n * Union type for any subscriber definition (full or stub).\n * This is the type-erased version for use in collections and schema.\n * Uses `any` because Subscriber<T> is contravariant in T (callback parameter),\n * making it impossible to assign Subscriber<SpecificEvent> to Subscriber<MatadorEvent<unknown>>.\n */\n// biome-ignore lint/suspicious/noExplicitAny: Required for variance compatibility in heterogeneous collections\nexport type AnySubscriber = Subscriber<MatadorEvent<any>> | SubscriberStub;\n\n/**\n * Type guard to check if a subscriber is a stub.\n */\nexport function isSubscriberStub(\n subscriber: AnySubscriber,\n): subscriber is SubscriberStub {\n return 'isStub' in subscriber && subscriber.isStub === true;\n}\n\n/**\n * Type guard to check if a subscriber has a callback implementation.\n */\nexport function isSubscriber(\n subscriber: AnySubscriber,\n // biome-ignore lint/suspicious/noExplicitAny: Required for variance compatibility\n): subscriber is Subscriber<MatadorEvent<any>> {\n return 'callback' in subscriber && typeof subscriber.callback === 'function';\n}\n\n/**\n * Type guard to check if a subscriber is resumable.\n */\nexport function isResumableSubscriber(\n subscriber: AnySubscriber,\n // biome-ignore lint/suspicious/noExplicitAny: Required for variance compatibility\n): subscriber is ResumableSubscriber<MatadorEvent<any>> {\n return isSubscriber(subscriber) && subscriber.idempotent === 'resumable';\n}\n\n/**\n * Type guard to check if a subscriber is a standard (non-resumable) subscriber.\n */\nexport function isStandardSubscriber(\n subscriber: AnySubscriber,\n // biome-ignore lint/suspicious/noExplicitAny: Required for variance compatibility\n): subscriber is StandardSubscriber<MatadorEvent<any>> {\n return isSubscriber(subscriber) && subscriber.idempotent !== 'resumable';\n}\n\n/**\n * Input options for createSubscriber with standard callback.\n */\nexport interface CreateStandardSubscriberInput<T extends MatadorEvent> {\n readonly name: string;\n readonly description: string;\n readonly callback: StandardCallback<T['data']>;\n readonly idempotent?: 'yes' | 'no' | 'unknown' | undefined;\n readonly importance?: Importance | undefined;\n readonly targetQueue?: string | undefined;\n readonly enabled?: (() => boolean | Promise<boolean>) | undefined;\n}\n\n/**\n * Input options for createSubscriber with resumable callback.\n */\nexport interface CreateResumableSubscriberInput<T extends MatadorEvent> {\n readonly name: string;\n readonly description: string;\n readonly callback: ResumableCallback<T['data']>;\n readonly idempotent: 'resumable';\n readonly importance?: Importance | undefined;\n readonly targetQueue?: string | undefined;\n readonly enabled?: (() => boolean | Promise<boolean>) | undefined;\n}\n\n/**\n * Input options for createSubscriber (discriminated union).\n */\nexport type CreateSubscriberInput<T extends MatadorEvent> =\n | CreateStandardSubscriberInput<T>\n | CreateResumableSubscriberInput<T>;\n\n/**\n * Creates a subscriber definition.\n *\n * @example Standard subscriber\n * ```typescript\n * const subscriber = createSubscriber<MyEvent>({\n * name: 'my-subscriber',\n * description: 'Handles MyEvent by logging the data',\n * callback: async (envelope) => {\n * console.log(envelope.data);\n * },\n * });\n * ```\n *\n * @example Resumable subscriber with io()\n * ```typescript\n * const subscriber = createSubscriber<MyEvent>({\n * name: 'my-resumable-subscriber',\n * description: 'Processes MyEvent with checkpoint-based idempotency',\n * idempotent: 'resumable',\n * callback: async (envelope, { io }) => {\n * await io('step-1', () => doSomething());\n * },\n * });\n * ```\n */\nexport function createSubscriber<T extends MatadorEvent>(\n input: CreateSubscriberInput<T>,\n): Subscriber<T> {\n const base = {\n name: input.name,\n description: input.description,\n callback: input.callback,\n importance: input.importance ?? 'should-investigate',\n ...(input.targetQueue !== undefined && {\n targetQueue: input.targetQueue,\n }),\n ...(input.enabled !== undefined && { enabled: input.enabled }),\n };\n\n if (input.idempotent === 'resumable') {\n return {\n ...base,\n idempotent: 'resumable',\n callback: input.callback,\n } as ResumableSubscriber<T>;\n }\n\n return {\n ...base,\n idempotent: input.idempotent ?? 'unknown',\n callback: input.callback,\n } as StandardSubscriber<T>;\n}\n\n/**\n * Input options for createSubscriberStub.\n */\nexport interface CreateSubscriberStubInput {\n readonly name: string;\n readonly idempotent?: 'yes' | 'no' | 'unknown' | undefined;\n readonly importance?: Importance | undefined;\n readonly targetQueue?: string | undefined;\n readonly enabled?: (() => boolean | Promise<boolean>) | undefined;\n}\n\n/**\n * Creates a subscriber stub for remote implementations.\n *\n * @example\n * ```typescript\n * const stub = createSubscriberStub({\n * name: 'remote-analytics',\n * targetQueue: 'analytics-worker',\n * });\n * ```\n */\nexport function createSubscriberStub(\n input: CreateSubscriberStubInput,\n): SubscriberStub {\n return {\n name: input.name,\n isStub: true,\n idempotent: input.idempotent ?? 'unknown',\n importance: input.importance ?? 'should-investigate',\n ...(input.targetQueue !== undefined && {\n targetQueue: input.targetQueue,\n }),\n ...(input.enabled !== undefined && { enabled: input.enabled }),\n };\n}\n\n/**\n * Definition interface used by the pipeline (excludes event class reference).\n */\nexport interface SubscriberDefinition {\n readonly name: string;\n readonly description?: string | undefined;\n readonly idempotent: Idempotency;\n readonly importance: Importance;\n readonly targetQueue?: string | undefined;\n}\n","import { TransportSendError } from '../errors/index.js';\nimport type { SafeHooks } from '../hooks/index.js';\nimport type { SchemaRegistry } from '../schema/index.js';\nimport type { Topology } from '../topology/index.js';\nimport { resolveTargetQueueName } from '../topology/index.js';\nimport type { SendOptions, Transport } from '../transport/index.js';\nimport type {\n AnySubscriber,\n Envelope,\n Event,\n EventClass,\n EventOptions,\n} from '../types/index.js';\nimport { createEnvelope } from '../types/index.js';\n\n/**\n * Default number of consecutive flush failures tolerated within a single\n * flush pass before bailing out early and re-buffering the untried\n * remainder.\n */\nconst DEFAULT_MAX_CONSECUTIVE_FLUSH_FAILURES = 10;\n\n/**\n * A send that failed (all transports exhausted) and was held in-memory for retry on reconnect.\n */\ninterface BufferedSend {\n readonly queue: string;\n readonly envelope: Envelope;\n readonly sendOptions: SendOptions | undefined;\n readonly subscriberName: string;\n /** Number of retry attempts made since this was first buffered. */\n attempts: number;\n}\n\n/**\n * Configuration for the fanout engine.\n */\nexport interface FanoutConfig {\n readonly transport: Transport;\n readonly schema: SchemaRegistry;\n readonly hooks: SafeHooks;\n readonly topology: Topology;\n readonly defaultQueue: string;\n readonly maxRetryBufferSize?: number | undefined;\n\n /**\n * Maximum number of retry attempts for a buffered message before it's\n * dropped and reported via onEnqueueError, instead of being retried forever.\n *\n * @default undefined (no limit — retries until the buffer flushes successfully)\n */\n readonly maxRetryAttempts?: number | undefined;\n\n /**\n * How often (in ms) to attempt flushing the retry buffer, independent of\n * transport reconnect events. This covers the case where the transport\n * stays connected but an individual publish keeps failing (e.g. broker\n * nack, publish confirm timeout) — onConnected never fires again for\n * that, so nothing would otherwise retry it.\n *\n * @default 30000. Pass 0 to disable the interval and rely on\n * onConnected/manual flushes only.\n */\n readonly retryIntervalMs?: number | undefined;\n\n /**\n * Number of consecutive flush failures tolerated within a single flush\n * pass before bailing out early and re-buffering the untried remainder,\n * instead of retrying every buffered message against a broker that's\n * rejecting everything.\n *\n * @default 10. Pass 0 (or a negative number) to disable the breaker and\n * always attempt every buffered message on every flush pass.\n */\n readonly maxConsecutiveFlushFailures?: number | undefined;\n}\n\n/**\n * Result of sending an event.\n */\nexport interface SendResult {\n readonly eventKey: string;\n readonly subscribersSent: number;\n readonly subscribersSkipped: number;\n readonly errors: readonly SendError[];\n}\n\n/**\n * Error during send.\n */\nexport interface SendError {\n readonly subscriberName: string;\n readonly queue: string;\n readonly error: Error;\n}\n\n/**\n * Engine for fanning out events to subscribers.\n *\n * Handles:\n * 1. Getting subscribers from schema\n * 2. Filtering by enabled() hook\n * 3. Creating envelopes for each subscriber\n * 4. Sending to appropriate queues via transport\n */\nexport class FanoutEngine {\n private readonly transport: Transport;\n private readonly schema: SchemaRegistry;\n private readonly hooks: SafeHooks;\n private readonly topology: Topology;\n private readonly defaultQueue: string;\n private enqueuingCount = 0;\n private flushInFlightCount = 0;\n private readonly retryBuffer: BufferedSend[] = [];\n private readonly maxRetryBufferSize: number;\n private readonly maxRetryAttempts: number | undefined;\n private readonly maxConsecutiveFlushFailures: number;\n private readonly disposeOnConnected: (() => void) | undefined;\n private readonly retryTimer: ReturnType<typeof setInterval> | undefined;\n\n constructor(config: FanoutConfig) {\n this.transport = config.transport;\n this.schema = config.schema;\n this.hooks = config.hooks;\n this.topology = config.topology;\n this.defaultQueue = config.defaultQueue;\n this.maxRetryBufferSize = config.maxRetryBufferSize ?? 5000;\n this.maxRetryAttempts = config.maxRetryAttempts;\n const maxConsecutiveFlushFailures =\n config.maxConsecutiveFlushFailures ??\n DEFAULT_MAX_CONSECUTIVE_FLUSH_FAILURES;\n this.maxConsecutiveFlushFailures =\n maxConsecutiveFlushFailures > 0\n ? maxConsecutiveFlushFailures\n : Number.POSITIVE_INFINITY;\n\n // If the transport supports it, add a callback to flush the retry buffer when the transport reconnects\n // The returned value is a function to unsubscribe from the callback\n this.disposeOnConnected = this.transport.onConnected?.(() => {\n void this.flushRetryBuffer();\n });\n\n // Also flush periodically: onConnected only fires on connection-level\n // reconnects, so it never fires when the transport stays connected but\n // an individual publish keeps failing (e.g. broker nack, confirm timeout).\n const retryIntervalMs = config.retryIntervalMs ?? 30_000;\n if (retryIntervalMs > 0) {\n this.retryTimer = setInterval(() => {\n void this.flushRetryBuffer();\n }, retryIntervalMs);\n this.retryTimer.unref?.();\n }\n }\n\n dispose(): void {\n // Unsubscribe from the callback (that flushes the retry buffer when the transport reconnects)\n this.disposeOnConnected?.();\n clearInterval(this.retryTimer);\n }\n\n /**\n * Current count of events being enqueued.\n */\n get eventsBeingEnqueuedCount(): number {\n return this.enqueuingCount + this.flushInFlightCount;\n }\n\n /**\n * Sends an event to all registered subscribers.\n */\n async send<T>(\n eventClass: EventClass<T>,\n event: Event<T>,\n options: EventOptions = {},\n ): Promise<SendResult> {\n const eventKey = eventClass.key;\n const subscribers = this.schema.getSubscribers(eventKey);\n\n const errors: SendError[] = [];\n let sent = 0;\n let skipped = 0;\n\n // Load universal metadata\n const universalMetadata = await this.hooks.loadUniversalMetadata();\n\n // Merge event.metadata with options.metadata (options takes precedence)\n const mergedMetadata =\n event.metadata || options.metadata\n ? { ...event.metadata, ...options.metadata }\n : undefined;\n\n for (const subscriber of subscribers) {\n // Check if subscriber is enabled\n const enabled = await this.isSubscriberEnabled(subscriber);\n if (!enabled) {\n skipped++;\n continue;\n }\n\n // Determine target queue\n const targetQueue = subscriber.targetQueue ?? this.defaultQueue;\n const qualifiedQueue = resolveTargetQueueName(this.topology, targetQueue);\n\n // Create envelope\n const envelope = createEnvelope({\n eventKey,\n eventDescription: eventClass.description,\n targetSubscriber: subscriber.name,\n data: event.data,\n importance: subscriber.importance ?? 'should-investigate',\n correlationId: options.correlationId,\n metadata: mergedMetadata,\n universalMetadata,\n delayMs: options.delayMs,\n });\n\n // Send to transport\n const sendOptions: SendOptions | undefined =\n options.delayMs !== undefined ? { delay: options.delayMs } : undefined;\n\n this.enqueuingCount++;\n try {\n const usedTransport = await this.transport.send(\n qualifiedQueue,\n envelope,\n sendOptions,\n );\n sent++;\n\n await this.hooks.onEnqueueSuccess({\n envelope,\n queue: qualifiedQueue,\n transport: usedTransport,\n });\n } catch (error) {\n const cause = error instanceof Error ? error : new Error(String(error));\n const shouldBuffer = options.buffer !== false;\n\n if (shouldBuffer && this.retryBuffer.length < this.maxRetryBufferSize) {\n this.retryBuffer.push({\n queue: qualifiedQueue,\n envelope,\n sendOptions,\n subscriberName: subscriber.name,\n attempts: 0,\n });\n this.hooks.logger.warn(\n `[Matador] 🟡 Message for '${subscriber.name}' buffered for retry on reconnect.`,\n {\n queue: qualifiedQueue,\n subscriberName: subscriber.name,\n bufferSize: this.retryBuffer.length,\n maxBufferSize: this.maxRetryBufferSize,\n },\n );\n\n if (options.throwOnBufferedFailure) {\n const err = new TransportSendError(qualifiedQueue, cause);\n // By adding the error, the main Send in Matador will throw\n errors.push({\n subscriberName: subscriber.name,\n queue: qualifiedQueue,\n error: err,\n });\n await this.hooks.onEnqueueError({\n envelope,\n error: err,\n transport: this.transport.name,\n });\n }\n } else {\n if (shouldBuffer) {\n this.hooks.logger.error(\n `[Matador] 🔴 Retry buffer full (${this.maxRetryBufferSize}). Message for '${subscriber.name}' dropped and will not be retried.`,\n );\n }\n const err = new TransportSendError(qualifiedQueue, cause);\n errors.push({\n subscriberName: subscriber.name,\n queue: qualifiedQueue,\n error: err,\n });\n\n await this.hooks.onEnqueueError({\n envelope,\n error: err,\n transport: this.transport.name,\n });\n }\n } finally {\n this.enqueuingCount--;\n }\n }\n\n return {\n eventKey,\n subscribersSent: sent,\n subscribersSkipped: skipped,\n errors,\n };\n }\n\n /**\n * Attempts a single buffered item during a flush pass\n * @returns true if the attempt succeeded; false on failure\n */\n private async attemptFlushItem(item: BufferedSend): Promise<boolean> {\n this.enqueuingCount++;\n try {\n const usedTransport = await this.transport.send(\n item.queue,\n item.envelope,\n item.sendOptions,\n );\n await this.hooks.onEnqueueSuccess({\n envelope: item.envelope,\n queue: item.queue,\n transport: usedTransport,\n });\n return true;\n } catch (error) {\n await this.handleFlushFailure(item, error);\n return false;\n } finally {\n this.enqueuingCount--;\n }\n }\n\n /**\n * Flushes the retry buffer\n *\n * This is called when the transport reconnects, and is used to retry any messages that were buffered while the transport was disconnected\n */\n private async flushRetryBuffer(): Promise<void> {\n if (this.retryBuffer.length === 0) return;\n\n this.hooks.logger.info(\n `[Matador] ⏳ Flushing ${this.retryBuffer.length} buffered message(s)...`,\n );\n\n // Drain the buffer atomically so concurrent flush calls don't double-send.\n const toFlush = this.retryBuffer.splice(0);\n // Tracked separately from enqueuingCount so shutdown doesn't see a it falsely idle while items are being flushed\n this.flushInFlightCount += toFlush.length;\n let consecutiveFailures = 0;\n\n try {\n for (let i = 0; i < toFlush.length; i++) {\n const item = toFlush[i];\n if (!item) {\n this.flushInFlightCount--;\n continue;\n }\n\n const succeeded = await this.attemptFlushItem(item);\n this.flushInFlightCount--;\n\n // Small sleep to avoid overwhelming the transport\n // Random sleep to avoid thundering herd (between 0 and 10ms)\n const randomMs = Math.random() * 10;\n await new Promise((resolve) => setTimeout(resolve, randomMs));\n\n // A success means the transport is actually working, so it resets the consecutive failures streak\n consecutiveFailures = succeeded ? 0 : consecutiveFailures + 1;\n\n if (consecutiveFailures >= this.maxConsecutiveFlushFailures) {\n // A run of failures this long is more likely a connection-level issue (broker down, slow, rejecting everything)\n // So we stop early to avoid retrying 5k messages for nothing\n const untried = toFlush.slice(i + 1);\n this.flushInFlightCount -= untried.length;\n if (untried.length > 0) {\n await this.rebufferUntried(untried, consecutiveFailures);\n }\n break;\n }\n }\n } finally {\n this.flushInFlightCount = 0;\n }\n\n const remaining = this.retryBuffer.length;\n if (remaining > 0) {\n this.hooks.logger.warn(\n `[Matador] 🟡 ${remaining} buffered message(s) could not be flushed; will retry later.`,\n );\n } else {\n this.hooks.logger.info(\n '[Matador] 🟢 All buffered messages flushed successfully.',\n );\n }\n }\n\n /**\n * Re-buffers messages that were never attempted because a flush pass\n * stopped out early. Respects maxRetryBufferSize: concurrent sends can have\n * refilled the buffer while this flush was running, so anything beyond\n * remaining capacity is dropped and reported instead of silently growing\n * the buffer past its cap.\n */\n private async rebufferUntried(\n untried: BufferedSend[],\n consecutiveFailures: number,\n ): Promise<void> {\n const capacity = Math.max(\n 0,\n this.maxRetryBufferSize - this.retryBuffer.length,\n );\n const toRebuffer = untried.slice(0, capacity);\n const dropped = untried.slice(capacity);\n\n if (toRebuffer.length > 0) {\n this.retryBuffer.unshift(...toRebuffer);\n }\n\n const droppedSuffix =\n dropped.length > 0 ? `, ${dropped.length} dropped (buffer full).` : '.';\n this.hooks.logger.warn(\n `[Matador] 🟡 Stopping this flush pass after ${consecutiveFailures} consecutive failures; ${toRebuffer.length} untried message(s) re-buffered for the next attempt${droppedSuffix}`,\n );\n\n for (const item of dropped) {\n this.hooks.logger.error(\n `[Matador] 🔴 Retry buffer full (${this.maxRetryBufferSize}). Message for '${item.subscriberName}' dropped and will not be retried.`,\n );\n const err = new TransportSendError(\n item.queue,\n new Error('Retry buffer full'),\n );\n await this.hooks.onEnqueueError({\n envelope: item.envelope,\n error: err,\n transport: this.transport.name,\n });\n }\n }\n\n /**\n * Handles a failed flush attempt for a single buffered item: drops it once\n * maxRetryAttempts is exceeded, otherwise re-buffers it (unless the buffer\n * is full, in which case it's dropped too).\n */\n private async handleFlushFailure(\n item: BufferedSend,\n error: unknown,\n ): Promise<void> {\n item.attempts++;\n const cause = error instanceof Error ? error : new Error(String(error));\n const exceededAttempts =\n this.maxRetryAttempts !== undefined &&\n item.attempts >= this.maxRetryAttempts;\n\n if (\n !exceededAttempts &&\n this.retryBuffer.length < this.maxRetryBufferSize\n ) {\n // Re-buffer on failure; it will be retried on the next reconnect or flush interval.\n this.retryBuffer.push(item);\n return;\n }\n\n if (exceededAttempts) {\n this.hooks.logger.error(\n `[Matador] 🔴 Message for '${item.subscriberName}' exceeded max retry attempts (${this.maxRetryAttempts}) and will not be retried further.`,\n );\n }\n\n const err = new TransportSendError(item.queue, cause);\n await this.hooks.onEnqueueError({\n envelope: item.envelope,\n error: err,\n transport: this.transport.name,\n });\n }\n\n private async isSubscriberEnabled(\n subscriber: AnySubscriber,\n ): Promise<boolean> {\n if (!subscriber.enabled) {\n return true;\n }\n\n try {\n const result = await subscriber.enabled();\n return result;\n } catch {\n // If enabled check fails, consider it enabled\n return true;\n }\n }\n}\n","import type {\n CheckpointClearedContext,\n CheckpointHitContext,\n CheckpointLoadedContext,\n CheckpointMissContext,\n} from '../checkpoint/index.js';\nimport type { RetryDecision } from '../retry/index.js';\nimport type { ConnectionState, Transport } from '../transport/index.js';\nimport type { Envelope, SubscriberDefinition } from '../types/index.js';\n\n/**\n * Logger interface for Matador internal logging.\n */\nexport interface Logger {\n debug(message: string, ...args: unknown[]): void;\n info(message: string, ...args: unknown[]): void;\n warn(message: string, ...args: unknown[]): void;\n error(message: string, ...args: unknown[]): void;\n}\n\n/**\n * Default logger that uses console.\n */\nexport const consoleLogger: Logger = {\n debug: (message, ...args) => console.debug(message, ...args),\n info: (message, ...args) => console.info(message, ...args),\n warn: (message, ...args) => console.warn(message, ...args),\n error: (message, ...args) => console.error(message, ...args),\n};\n\n/**\n * Context for enqueue success hook.\n */\nexport interface EnqueueSuccessContext {\n readonly envelope: Envelope;\n readonly queue: string;\n /** The transport that was used (e.g., 'local', 'rabbitmq') */\n readonly transport: string;\n}\n\n/**\n * Context for transport fallback hook.\n */\nexport interface TransportFallbackContext {\n /** The envelope that was being sent */\n readonly envelope: Envelope;\n /** The queue the message was being sent to */\n readonly queue: string;\n /** The transport that failed */\n readonly failedTransport: Transport['name'];\n /** The transport that will be tried next */\n readonly nextTransport: Transport['name'];\n /** The error from the failed transport */\n readonly error: Error;\n}\n\n/**\n * Context for enqueue error hook.\n */\nexport interface EnqueueErrorContext {\n readonly envelope: Envelope;\n readonly error: Error;\n /** The transport that failed (e.g., 'local', 'rabbitmq') */\n readonly transport: string;\n}\n\n/**\n * Context for decode error hook.\n */\nexport interface DecodeErrorContext {\n readonly error: Error;\n readonly rawMessage: Uint8Array;\n readonly sourceQueue: string;\n /** The transport that received the message (e.g., 'local', 'rabbitmq') */\n readonly transport: string;\n}\n\n/**\n * Context for worker success hook.\n */\nexport interface WorkerSuccessContext {\n readonly envelope: Envelope;\n readonly subscriber: SubscriberDefinition;\n readonly result: unknown;\n readonly durationMs: number;\n /** The transport that received the message (e.g., 'local', 'rabbitmq') */\n readonly transport: string;\n}\n\n/**\n * Context for worker error hook.\n */\nexport interface WorkerErrorContext {\n readonly envelope: Envelope;\n readonly subscriber: SubscriberDefinition;\n readonly error: Error;\n readonly durationMs: number;\n readonly decision: RetryDecision;\n /** The transport that received the message (e.g., 'local', 'rabbitmq') */\n readonly transport: string;\n}\n\n/**\n * Execution function passed to onWorkerWrap for APM wrapping.\n */\nexport type WorkerExecuteFn = () => Promise<void>;\n\n/**\n * All available hooks for Matador.\n */\nexport interface MatadorHooks {\n /**\n * Logger for internal Matador logging.\n * Defaults to console logger if not provided.\n */\n logger?: Logger;\n\n /**\n * Called when an event is successfully enqueued.\n */\n onEnqueueSuccess?(context: EnqueueSuccessContext): void | Promise<void>;\n\n /**\n * Called when transport fallback occurs during send.\n * Only fires when using MultiTransport with fallbackEnabled=true.\n */\n onTransportFallback?(context: TransportFallbackContext): void | Promise<void>;\n\n /**\n * Called when enqueue fails completely.\n */\n onEnqueueError?(context: EnqueueErrorContext): void | Promise<void>;\n\n /**\n * Wraps entire worker processing (for APM context).\n * Must call execute() to run the actual processing.\n */\n onWorkerWrap?(\n envelope: Envelope,\n subscriber: SubscriberDefinition,\n execute: WorkerExecuteFn,\n ): Promise<void>;\n\n /**\n * Called before processing begins.\n */\n onWorkerBeforeProcess?(\n envelope: Envelope,\n subscriber: SubscriberDefinition,\n ): void | Promise<void>;\n\n /**\n * Called after successful processing.\n */\n onWorkerSuccess?(context: WorkerSuccessContext): void | Promise<void>;\n\n /**\n * Called after processing error.\n */\n onWorkerError?(context: WorkerErrorContext): void | Promise<void>;\n\n /**\n * Called when message decoding fails.\n */\n onDecodeError?(context: DecodeErrorContext): void | Promise<void>;\n\n /**\n * Called when transport connection state changes.\n */\n onConnectionStateChange?(state: ConnectionState): void | Promise<void>;\n\n /**\n * Loads universal metadata to add to all envelopes.\n */\n loadUniversalMetadata?():\n | Record<string, unknown>\n | Promise<Record<string, unknown>>;\n\n /**\n * Dynamic retry delay lookup.\n */\n getRetryDelay?(\n envelope: Envelope,\n attemptNumber: number,\n ): number | undefined | Promise<number | undefined>;\n\n /**\n * Dynamic max attempts lookup.\n */\n getAttempts?(\n envelope: Envelope,\n ): number | undefined | Promise<number | undefined>;\n\n /**\n * Dynamic max deliveries (poison threshold) lookup.\n */\n getMaxDeliveries?(\n envelope: Envelope,\n ): number | undefined | Promise<number | undefined>;\n\n // === Checkpoint Hooks (Resumable Subscribers) ===\n\n /**\n * Called when a checkpoint is loaded for a retry.\n * Only fires for resumable subscribers on retry attempts.\n */\n onCheckpointLoaded?(context: CheckpointLoadedContext): void | Promise<void>;\n\n /**\n * Called when an io() operation uses a cached value (checkpoint hit).\n * Useful for observability and metrics.\n */\n onCheckpointHit?(context: CheckpointHitContext): void | Promise<void>;\n\n /**\n * Called when an io() operation executes (cache miss).\n * Useful for observability and metrics.\n */\n onCheckpointMiss?(context: CheckpointMissContext): void | Promise<void>;\n\n /**\n * Called when a checkpoint is cleared.\n * Fires on successful completion or when moving to dead-letter queue.\n */\n onCheckpointCleared?(context: CheckpointClearedContext): void | Promise<void>;\n}\n","import type {\n CheckpointClearedContext,\n CheckpointHitContext,\n CheckpointLoadedContext,\n CheckpointMissContext,\n} from '../checkpoint/index.js';\nimport type { ConnectionState } from '../transport/index.js';\nimport type { Envelope, SubscriberDefinition } from '../types/index.js';\nimport {\n type DecodeErrorContext,\n type EnqueueErrorContext,\n type EnqueueSuccessContext,\n type Logger,\n type MatadorHooks,\n type WorkerErrorContext,\n type WorkerExecuteFn,\n type WorkerSuccessContext,\n consoleLogger,\n} from './types.js';\n\n/**\n * Wraps hooks with error handling to prevent hook errors from breaking processing.\n * All hooks become safe to call and will catch any errors internally.\n */\nexport class SafeHooks {\n private readonly hooks: MatadorHooks;\n\n /** The logger instance used by Matador. */\n readonly logger: Logger;\n\n constructor(hooks: MatadorHooks = {}) {\n this.hooks = hooks;\n this.logger = hooks.logger ?? consoleLogger;\n }\n\n async onEnqueueSuccess(context: EnqueueSuccessContext): Promise<void> {\n await this.safeCall('onEnqueueSuccess', () =>\n this.hooks.onEnqueueSuccess?.(context),\n );\n }\n\n async onEnqueueError(context: EnqueueErrorContext): Promise<void> {\n await this.safeCall('onEnqueueError', () =>\n this.hooks.onEnqueueError?.(context),\n );\n }\n\n async onWorkerWrap(\n envelope: Envelope,\n subscriber: SubscriberDefinition,\n execute: WorkerExecuteFn,\n ): Promise<void> {\n if (this.hooks.onWorkerWrap) {\n try {\n await this.hooks.onWorkerWrap(envelope, subscriber, execute);\n } catch (error) {\n this.logger.warn(\n '[Matador] 🟡 Hook onWorkerWrap threw an error',\n error,\n );\n // Still try to execute if wrap failed\n await execute();\n }\n } else {\n await execute();\n }\n }\n\n async onWorkerBeforeProcess(\n envelope: Envelope,\n subscriber: SubscriberDefinition,\n ): Promise<void> {\n await this.safeCall('onWorkerBeforeProcess', () =>\n this.hooks.onWorkerBeforeProcess?.(envelope, subscriber),\n );\n }\n\n async onWorkerSuccess(context: WorkerSuccessContext): Promise<void> {\n await this.safeCall('onWorkerSuccess', () =>\n this.hooks.onWorkerSuccess?.(context),\n );\n }\n\n async onWorkerError(context: WorkerErrorContext): Promise<void> {\n await this.safeCall('onWorkerError', () =>\n this.hooks.onWorkerError?.(context),\n );\n }\n\n async onDecodeError(context: DecodeErrorContext): Promise<void> {\n await this.safeCall('onDecodeError', () =>\n this.hooks.onDecodeError?.(context),\n );\n }\n\n async onConnectionStateChange(state: ConnectionState): Promise<void> {\n await this.safeCall('onConnectionStateChange', () =>\n this.hooks.onConnectionStateChange?.(state),\n );\n }\n\n async loadUniversalMetadata(): Promise<Record<string, unknown>> {\n if (!this.hooks.loadUniversalMetadata) {\n return {};\n }\n\n try {\n const result = await this.hooks.loadUniversalMetadata();\n return result ?? {};\n } catch (error) {\n this.logger.warn(\n '[Matador] 🟡 Hook loadUniversalMetadata threw an error',\n error,\n );\n return {};\n }\n }\n\n async getRetryDelay(\n envelope: Envelope,\n attemptNumber: number,\n ): Promise<number | undefined> {\n if (!this.hooks.getRetryDelay) {\n return undefined;\n }\n\n try {\n return await this.hooks.getRetryDelay(envelope, attemptNumber);\n } catch (error) {\n this.logger.warn('[Matador] 🟡 Hook getRetryDelay threw an error', error);\n return undefined;\n }\n }\n\n async getAttempts(envelope: Envelope): Promise<number | undefined> {\n if (!this.hooks.getAttempts) {\n return undefined;\n }\n\n try {\n return await this.hooks.getAttempts(envelope);\n } catch (error) {\n this.logger.warn('[Matador] 🟡 Hook getAttempts threw an error', error);\n return undefined;\n }\n }\n\n async getMaxDeliveries(envelope: Envelope): Promise<number | undefined> {\n if (!this.hooks.getMaxDeliveries) {\n return undefined;\n }\n\n try {\n return await this.hooks.getMaxDeliveries(envelope);\n } catch (error) {\n this.logger.warn(\n '[Matador] 🟡 Hook getMaxDeliveries threw an error',\n error,\n );\n return undefined;\n }\n }\n\n // === Checkpoint Hooks ===\n\n async onCheckpointLoaded(context: CheckpointLoadedContext): Promise<void> {\n await this.safeCall('onCheckpointLoaded', () =>\n this.hooks.onCheckpointLoaded?.(context),\n );\n }\n\n async onCheckpointHit(context: CheckpointHitContext): Promise<void> {\n await this.safeCall('onCheckpointHit', () =>\n this.hooks.onCheckpointHit?.(context),\n );\n }\n\n async onCheckpointMiss(context: CheckpointMissContext): Promise<void> {\n await this.safeCall('onCheckpointMiss', () =>\n this.hooks.onCheckpointMiss?.(context),\n );\n }\n\n async onCheckpointCleared(context: CheckpointClearedContext): Promise<void> {\n await this.safeCall('onCheckpointCleared', () =>\n this.hooks.onCheckpointCleared?.(context),\n );\n }\n\n private async safeCall(\n hookName: string,\n fn: () => void | Promise<void> | undefined,\n ): Promise<void> {\n try {\n await fn();\n } catch (error) {\n this.logger.warn(`[Matador] 🟡 Hook ${hookName} threw an error`, error);\n }\n }\n}\n","import { type Logger, consoleLogger } from '../hooks/index.js';\n\n/**\n * Shutdown state.\n */\nexport type ShutdownState =\n | 'running'\n | 'receive-stopped'\n | 'stopping-receive'\n | 'waiting-handlers'\n | 'stopping-enqueue'\n | 'disconnecting'\n | 'stopped';\n\n/**\n * Configuration for shutdown manager.\n */\nexport interface ShutdownConfig {\n /** Timeout for graceful shutdown in milliseconds */\n readonly gracefulShutdownTimeout: number;\n\n /** Polling interval when waiting for handlers to idle */\n readonly idlePollingInterval: number;\n\n /** Logger for shutdown events (defaults to console) */\n readonly logger: Logger;\n}\n\n/**\n * Default shutdown configuration.\n */\nexport const defaultShutdownConfig: ShutdownConfig = {\n gracefulShutdownTimeout: 30000,\n idlePollingInterval: 1000,\n logger: consoleLogger,\n};\n\n/**\n * Handler state tracking.\n */\nexport interface HandlersState {\n readonly eventsBeingProcessed: number;\n readonly eventsBeingEnqueued: number;\n readonly isIdle: boolean;\n}\n\n/**\n * Manages graceful shutdown of Matador.\n *\n * Shutdown sequence:\n * 1. Stop receiving new messages\n * 2. Wait for in-flight processing to complete\n * 3. Stop accepting new enqueue requests\n * 4. Disconnect transport\n */\nexport class ShutdownManager {\n private _state: ShutdownState = 'running';\n private readonly config: ShutdownConfig;\n private eventsBeingProcessed = 0;\n private acceptingEnqueue = true;\n\n constructor(\n private readonly getEnqueueCount: () => number,\n private readonly stopReceiving: () => Promise<void>,\n private readonly disconnectTransport: () => Promise<void>,\n config: Partial<ShutdownConfig> = {},\n ) {\n this.config = { ...defaultShutdownConfig, ...config };\n }\n\n /**\n * Current shutdown state.\n */\n get state(): ShutdownState {\n return this._state;\n }\n\n /**\n * Whether enqueue is currently allowed.\n */\n get isEnqueueAllowed(): boolean {\n return this.acceptingEnqueue;\n }\n\n /**\n * Gets current handler state.\n */\n getHandlersState(): HandlersState {\n const eventsBeingEnqueued = this.getEnqueueCount();\n return {\n eventsBeingProcessed: this.eventsBeingProcessed,\n eventsBeingEnqueued,\n isIdle: this.eventsBeingProcessed === 0 && eventsBeingEnqueued === 0,\n };\n }\n\n /**\n * Increment processing counter.\n */\n incrementProcessing(): void {\n this.eventsBeingProcessed++;\n }\n\n /**\n * Decrement processing counter.\n */\n decrementProcessing(): void {\n this.eventsBeingProcessed--;\n }\n\n /**\n * Stops receiving new messages without performing full shutdown.\n * After calling this, no new messages will be delivered from the transport.\n * The transport remains connected for later shutdown.\n *\n * Use this when you need to stop receiving before waiting for idle,\n * for example to coordinate waiting across multiple systems.\n *\n * @returns true if receiving was stopped, false if already stopped or shutting down\n */\n async publicStopReceiving(): Promise<boolean> {\n if (this._state !== 'running') {\n return false;\n }\n\n this._state = 'stopping-receive';\n await this.stopReceiving();\n this._state = 'receive-stopped';\n return true;\n }\n\n /**\n * Performs graceful shutdown.\n */\n async shutdown(): Promise<void> {\n // Allow shutdown from either 'running' or 'receive-stopped' states\n if (this._state !== 'running' && this._state !== 'receive-stopped') {\n return;\n }\n\n // 1. Stop receiving new messages (skip if already stopped)\n if (this._state === 'running') {\n this._state = 'stopping-receive';\n await this.stopReceiving();\n }\n\n // 2. Wait for handlers to idle\n this._state = 'waiting-handlers';\n await this.waitForIdle();\n\n // 3. Stop accepting new enqueue requests\n this._state = 'stopping-enqueue';\n this.acceptingEnqueue = false;\n\n // 4. Disconnect transport\n this._state = 'disconnecting';\n await this.disconnectTransport();\n\n this._state = 'stopped';\n }\n\n /**\n * Forcefully stops without waiting.\n */\n async forceStop(): Promise<void> {\n this.acceptingEnqueue = false;\n await this.stopReceiving();\n await this.disconnectTransport();\n this._state = 'stopped';\n }\n\n private async waitForIdle(): Promise<void> {\n const deadline = Date.now() + this.config.gracefulShutdownTimeout;\n\n while (!this.getHandlersState().isIdle) {\n if (Date.now() > deadline) {\n this.config.logger.warn(\n `[Matador] 🟡 Shutdown timeout reached with ${this.eventsBeingProcessed} events still processing`,\n );\n break;\n }\n\n await this.sleep(this.config.idlePollingInterval);\n }\n }\n\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n}\n","import type { HasDescription } from '../errors/index.js';\nimport type { Envelope } from '../types/index.js';\n\n/**\n * Codec interface for serializing/deserializing envelopes.\n */\nexport interface Codec {\n /**\n * Encodes an envelope to a buffer for transport.\n */\n encode(envelope: Envelope): Uint8Array;\n\n /**\n * Decodes a buffer back to an envelope.\n * @throws Error if the buffer is invalid or cannot be decoded\n */\n decode(buffer: Uint8Array): Envelope;\n\n /**\n * MIME content type for this codec.\n */\n readonly contentType: string;\n}\n\n/**\n * Error thrown when decoding fails.\n */\nexport class CodecDecodeError extends Error implements HasDescription {\n readonly description =\n 'Failed to decode a message from the transport. This typically indicates ' +\n 'corrupted data, incompatible codec versions, or messages from a different ' +\n 'system. Check the cause property for the underlying parsing error. ' +\n 'The message will be sent to the dead-letter queue for investigation.';\n\n constructor(\n message: string,\n public readonly cause?: unknown,\n ) {\n super(message);\n this.name = 'CodecDecodeError';\n }\n}\n","import type { Envelope } from '../types/index.js';\nimport type { Codec } from './codec.js';\nimport { CodecDecodeError } from './codec.js';\n\n/**\n * JSON codec for envelope serialization.\n * Uses standard JSON.stringify/parse with Date handling.\n */\nexport class JsonCodec implements Codec {\n readonly contentType = 'application/json';\n\n encode(envelope: Envelope): Uint8Array {\n const json = JSON.stringify(envelope);\n return new TextEncoder().encode(json);\n }\n\n decode(buffer: Uint8Array): Envelope {\n if (buffer.length === 0) {\n throw new CodecDecodeError('Cannot decode empty buffer');\n }\n\n let json: string;\n try {\n json = new TextDecoder('utf-8').decode(buffer);\n } catch (error) {\n throw new CodecDecodeError('Invalid UTF-8 encoding', error);\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(json);\n } catch (error) {\n throw new CodecDecodeError('Invalid JSON', error);\n }\n\n if (!this.isValidEnvelope(parsed)) {\n throw new CodecDecodeError('Invalid envelope structure');\n }\n\n return parsed;\n }\n\n private isValidEnvelope(value: unknown): value is Envelope {\n if (typeof value !== 'object' || value === null) {\n return false;\n }\n\n const envelope = value as Record<string, unknown>;\n\n // Required top-level fields\n if (typeof envelope.id !== 'string') return false;\n if (!('data' in envelope)) return false;\n if (typeof envelope.docket !== 'object' || envelope.docket === null)\n return false;\n\n // Validate docket (routing, processing state, observability)\n const docket = envelope.docket as Record<string, unknown>;\n // Routing\n if (typeof docket.eventKey !== 'string') return false;\n if (typeof docket.targetSubscriber !== 'string') return false;\n // Processing state\n if (typeof docket.attempts !== 'number') return false;\n if (typeof docket.createdAt !== 'string') return false;\n // Observability\n if (typeof docket.importance !== 'string') return false;\n\n return true;\n }\n}\n","import type { Docket, Envelope } from '../types/index.js';\nimport { CodecDecodeError } from './codec.js';\nimport type { EncodedMessage, HeaderAwareCodec } from './header-aware-codec.js';\n\n/**\n * Header names used by Matador in RabbitMQ messages.\n */\nconst HEADERS = {\n // Routing\n EVENT_KEY: 'x-matador-event-key',\n TARGET_SUBSCRIBER: 'x-matador-subscriber',\n SCHEDULED_FOR: 'x-matador-scheduled-for',\n ORIGINAL_QUEUE: 'x-matador-original-queue',\n\n // Processing state\n ATTEMPTS: 'x-matador-attempts',\n CREATED_AT: 'x-matador-created-at',\n FIRST_ERROR: 'x-matador-first-error',\n LAST_ERROR: 'x-matador-last-error',\n\n // Observability\n IMPORTANCE: 'x-matador-importance',\n CORRELATION_ID: 'x-matador-correlation-id',\n\n // v1 compatibility headers\n V1_EVENT_ID: 'x-event-id',\n V1_CORRELATION_ID: 'x-correlation-id',\n V1_USER_ID: 'x-user-id',\n} as const;\n\n/**\n * Body structure for v2 messages.\n * Only contains id, data, and optionally metadata (since it can be large).\n */\ninterface V2Body {\n readonly id: string;\n readonly data: unknown;\n readonly metadata?: Record<string, unknown>;\n}\n\n/**\n * v1 message format (for backwards compatibility).\n */\ninterface V1Body {\n key: string;\n data: unknown;\n metadata: unknown;\n universal?: {\n event_id?: string | null;\n user_id?: string | null;\n correlation_id?: string | null;\n [key: string]: unknown;\n };\n before?: unknown;\n options?: { delayMs?: number };\n targetSubscriber: string;\n}\n\n/**\n * RabbitMQ-specific codec that stores routing/metadata in headers.\n *\n * Benefits:\n * - No duplication between body and headers\n * - RabbitMQ can route/filter based on headers\n * - Smaller message body\n * - v1 message format compatibility built-in\n */\nexport class RabbitMQCodec implements HeaderAwareCodec {\n readonly contentType = 'application/json';\n\n encode(envelope: Envelope): EncodedMessage {\n const { docket } = envelope;\n\n // Body only contains id, data, and metadata (since metadata can be large)\n const body: V2Body = {\n id: envelope.id,\n data: envelope.data,\n ...(docket.metadata !== undefined && { metadata: docket.metadata }),\n };\n\n // All docket fields go in headers\n const headers: Record<string, unknown> = {\n // Routing\n [HEADERS.EVENT_KEY]: docket.eventKey,\n [HEADERS.TARGET_SUBSCRIBER]: docket.targetSubscriber,\n\n // Processing state\n [HEADERS.ATTEMPTS]: docket.attempts,\n [HEADERS.CREATED_AT]: docket.createdAt,\n\n // Observability\n [HEADERS.IMPORTANCE]: docket.importance,\n };\n\n // Optional fields\n if (docket.scheduledFor !== undefined) {\n headers[HEADERS.SCHEDULED_FOR] = docket.scheduledFor;\n }\n if (docket.originalQueue !== undefined) {\n headers[HEADERS.ORIGINAL_QUEUE] = docket.originalQueue;\n }\n if (docket.firstError !== undefined) {\n headers[HEADERS.FIRST_ERROR] = docket.firstError;\n }\n if (docket.lastError !== undefined) {\n headers[HEADERS.LAST_ERROR] = docket.lastError;\n }\n if (docket.correlationId !== undefined) {\n headers[HEADERS.CORRELATION_ID] = docket.correlationId;\n }\n\n return {\n body: new TextEncoder().encode(JSON.stringify(body)),\n headers,\n contentType: this.contentType,\n };\n }\n\n decode(body: Uint8Array, headers: Record<string, unknown>): Envelope {\n if (body.length === 0) {\n throw new CodecDecodeError('Cannot decode empty buffer');\n }\n\n let json: string;\n try {\n json = new TextDecoder('utf-8').decode(body);\n } catch (error) {\n throw new CodecDecodeError('Invalid UTF-8 encoding', error);\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(json);\n } catch (error) {\n throw new CodecDecodeError('Invalid JSON', error);\n }\n\n // Detect format: v1 has 'key' and 'targetSubscriber' at top level\n if (this.isV1Body(parsed)) {\n return this.decodeV1(parsed, headers);\n }\n\n // v2 format\n if (!this.isV2Body(parsed)) {\n throw new CodecDecodeError('Invalid message body structure');\n }\n\n return this.decodeV2(parsed, headers);\n }\n\n private isV1Body(value: unknown): value is V1Body {\n if (typeof value !== 'object' || value === null) return false;\n const obj = value as Record<string, unknown>;\n return (\n typeof obj.key === 'string' &&\n typeof obj.targetSubscriber === 'string' &&\n 'data' in obj &&\n !('payload' in obj)\n );\n }\n\n private isV2Body(value: unknown): value is V2Body {\n if (typeof value !== 'object' || value === null) return false;\n const obj = value as Record<string, unknown>;\n return (\n typeof obj.id === 'string' && 'data' in obj && !('key' in obj) // Distinguish from v1 which also has 'data'\n );\n }\n\n private decodeV2(body: V2Body, headers: Record<string, unknown>): Envelope {\n // Required headers\n const eventKey = this.requireStringHeader(headers, HEADERS.EVENT_KEY);\n const targetSubscriber = this.requireStringHeader(\n headers,\n HEADERS.TARGET_SUBSCRIBER,\n );\n const attempts = this.requireNumberHeader(headers, HEADERS.ATTEMPTS);\n const createdAt = this.requireStringHeader(headers, HEADERS.CREATED_AT);\n const importance = this.requireStringHeader(headers, HEADERS.IMPORTANCE);\n\n // Optional headers\n const scheduledFor = this.optionalStringHeader(\n headers,\n HEADERS.SCHEDULED_FOR,\n );\n const originalQueue = this.optionalStringHeader(\n headers,\n HEADERS.ORIGINAL_QUEUE,\n );\n const firstError = this.optionalStringHeader(headers, HEADERS.FIRST_ERROR);\n const lastError = this.optionalStringHeader(headers, HEADERS.LAST_ERROR);\n const correlationId = this.optionalStringHeader(\n headers,\n HEADERS.CORRELATION_ID,\n );\n\n const docket: Docket = {\n // Routing\n eventKey,\n targetSubscriber,\n ...(scheduledFor !== undefined && { scheduledFor }),\n ...(originalQueue !== undefined && { originalQueue }),\n // Processing state\n attempts,\n createdAt,\n ...(firstError !== undefined && { firstError }),\n ...(lastError !== undefined && { lastError }),\n // Observability\n importance: importance as Docket['importance'],\n ...(correlationId !== undefined && { correlationId }),\n ...(body.metadata !== undefined && { metadata: body.metadata }),\n };\n\n return {\n id: body.id,\n data: body.data,\n docket,\n };\n }\n\n /**\n * Decodes a v1 format message for backwards compatibility.\n * v1 format: { key, data, metadata, universal, targetSubscriber, ... }\n */\n private decodeV1(body: V1Body, headers: Record<string, unknown>): Envelope {\n const { event_id, user_id, correlation_id, ...otherUniversal } =\n body.universal ?? {};\n\n // Merge metadata: event metadata + remaining universal fields\n const mergedMetadata: Record<string, unknown> = {};\n if (body.metadata && typeof body.metadata === 'object') {\n Object.assign(mergedMetadata, body.metadata);\n }\n if (user_id !== undefined && user_id !== null) {\n mergedMetadata.user_id = user_id;\n }\n Object.assign(mergedMetadata, otherUniversal);\n\n // Try to get attempts from header (v1 also uses x-matador-attempts)\n const attempts =\n typeof headers[HEADERS.ATTEMPTS] === 'number'\n ? (headers[HEADERS.ATTEMPTS] as number)\n : 1;\n\n // Try to get importance from header\n const importance =\n typeof headers[HEADERS.IMPORTANCE] === 'string'\n ? (headers[HEADERS.IMPORTANCE] as string)\n : 'should-investigate';\n\n // Get correlation ID from either v1 or v2 header\n const correlationId =\n (headers[HEADERS.CORRELATION_ID] as string | undefined) ??\n (headers[HEADERS.V1_CORRELATION_ID] as string | undefined) ??\n correlation_id ??\n undefined;\n\n // Get event ID from v1 header or body\n const eventId =\n (headers[HEADERS.V1_EVENT_ID] as string | undefined) ??\n event_id ??\n crypto.randomUUID();\n\n const now = new Date().toISOString();\n\n // Calculate scheduledFor if delayMs was specified (though it's likely already passed)\n let scheduledFor: string | undefined;\n if (body.options?.delayMs) {\n scheduledFor = new Date(Date.now() + body.options.delayMs).toISOString();\n }\n\n const docket: Docket = {\n // Routing\n eventKey: body.key,\n targetSubscriber: body.targetSubscriber,\n ...(scheduledFor !== undefined && { scheduledFor }),\n // Processing state\n attempts,\n createdAt: now,\n // Observability\n importance: importance as Docket['importance'],\n ...(correlationId !== undefined && { correlationId }),\n ...(Object.keys(mergedMetadata).length > 0 && {\n metadata: mergedMetadata,\n }),\n };\n\n return {\n id: eventId,\n data: body.data,\n docket,\n };\n }\n\n private requireStringHeader(\n headers: Record<string, unknown>,\n name: string,\n ): string {\n const value = headers[name];\n if (value === undefined) {\n throw new CodecDecodeError(`Missing required header: ${name}`);\n }\n if (typeof value !== 'string') {\n throw new CodecDecodeError(\n `Header ${name} must be string, got ${typeof value}`,\n );\n }\n return value;\n }\n\n private requireNumberHeader(\n headers: Record<string, unknown>,\n name: string,\n ): number {\n const value = headers[name];\n if (value === undefined) {\n throw new CodecDecodeError(`Missing required header: ${name}`);\n }\n if (typeof value !== 'number') {\n throw new CodecDecodeError(\n `Header ${name} must be number, got ${typeof value}`,\n );\n }\n return value;\n }\n\n private optionalStringHeader(\n headers: Record<string, unknown>,\n name: string,\n ): string | undefined {\n const value = headers[name];\n if (value === undefined) return undefined;\n if (typeof value !== 'string') return undefined;\n return value;\n }\n}\n","import { DuplicateIoKeyError } from '../errors/index.js';\nimport type { Envelope, SubscriberDefinition } from '../types/index.js';\nimport type {\n Checkpoint,\n CheckpointHitContext,\n CheckpointMissContext,\n CheckpointStore,\n JsonSerializable,\n SubscriberContext,\n} from './types.js';\n\n/**\n * Hooks for observability during context operations.\n */\nexport interface ResumableContextHooks {\n onCheckpointHit?(context: CheckpointHitContext): void | Promise<void>;\n onCheckpointMiss?(context: CheckpointMissContext): void | Promise<void>;\n}\n\n/**\n * Configuration for creating a ResumableContext.\n */\nexport interface ResumableContextConfig {\n readonly store: CheckpointStore;\n readonly envelope: Envelope;\n readonly subscriber: SubscriberDefinition;\n readonly existingCheckpoint?: Checkpoint | undefined;\n readonly hooks?: ResumableContextHooks | undefined;\n}\n\n/**\n * Implementation of SubscriberContext that provides io() caching.\n *\n * On first execution, io() calls execute their lambdas and cache results.\n * On retry (when existingCheckpoint is provided), cached results are returned\n * without re-executing the lambda.\n */\nexport class ResumableContext implements SubscriberContext {\n private checkpoint: Checkpoint;\n private readonly usedKeys = new Set<string>();\n private readonly store: CheckpointStore;\n private readonly envelope: Envelope;\n private readonly subscriber: SubscriberDefinition;\n private readonly hooks: ResumableContextHooks | undefined;\n\n constructor(config: ResumableContextConfig) {\n this.store = config.store;\n this.envelope = config.envelope;\n this.subscriber = config.subscriber;\n this.hooks = config.hooks;\n\n this.checkpoint = config.existingCheckpoint ?? {\n envelopeId: config.envelope.id,\n subscriberName: config.subscriber.name,\n completedSteps: {},\n };\n }\n\n get attempt(): number {\n return this.envelope.docket.attempts;\n }\n\n get isRetry(): boolean {\n return this.attempt > 1;\n }\n\n async io<T extends JsonSerializable>(\n key: string,\n fn: () => Promise<T> | T,\n ): Promise<T> {\n // Validate key uniqueness within this execution\n if (this.usedKeys.has(key)) {\n throw new DuplicateIoKeyError(key, this.subscriber.name);\n }\n this.usedKeys.add(key);\n\n // Check cache first\n if (key in this.checkpoint.completedSteps) {\n await this.hooks?.onCheckpointHit?.({\n envelope: this.envelope,\n subscriber: this.subscriber,\n stepKey: key,\n });\n return this.checkpoint.completedSteps[key] as T;\n }\n\n // Notify cache miss\n await this.hooks?.onCheckpointMiss?.({\n envelope: this.envelope,\n subscriber: this.subscriber,\n stepKey: key,\n });\n\n // Execute the function - errors propagate, no caching on failure\n const result = await fn();\n\n // Cache the result\n this.checkpoint = {\n ...this.checkpoint,\n completedSteps: {\n ...this.checkpoint.completedSteps,\n [key]: result,\n },\n };\n\n // Persist checkpoint immediately (incremental persistence)\n await this.store.set(this.envelope.id, this.checkpoint);\n\n return result;\n }\n\n async all<\n T extends readonly [\n string,\n () => Promise<JsonSerializable> | JsonSerializable,\n ][],\n >(\n ops: T,\n ): Promise<{\n [K in keyof T]: T[K] extends [string, () => Promise<infer R>]\n ? R\n : T[K] extends [string, () => infer R]\n ? R\n : never;\n }> {\n // First, check for duplicates within this all() call\n const keysInThisCall = new Set<string>();\n for (const [key] of ops) {\n if (keysInThisCall.has(key)) {\n throw new DuplicateIoKeyError(key, this.subscriber.name);\n }\n keysInThisCall.add(key);\n }\n\n // Then validate against previously used keys\n for (const [key] of ops) {\n if (this.usedKeys.has(key)) {\n throw new DuplicateIoKeyError(key, this.subscriber.name);\n }\n }\n\n // Mark all keys as used\n for (const [key] of ops) {\n this.usedKeys.add(key);\n }\n\n // Execute all operations in parallel\n const results = await Promise.all(\n ops.map(async ([key, fn]) => {\n // Check cache first\n if (key in this.checkpoint.completedSteps) {\n await this.hooks?.onCheckpointHit?.({\n envelope: this.envelope,\n subscriber: this.subscriber,\n stepKey: key,\n });\n return this.checkpoint.completedSteps[key];\n }\n\n // Notify cache miss\n await this.hooks?.onCheckpointMiss?.({\n envelope: this.envelope,\n subscriber: this.subscriber,\n stepKey: key,\n });\n\n // Execute - errors propagate\n const result = await fn();\n\n // Cache individually (in local state, will persist after Promise.all)\n this.checkpoint = {\n ...this.checkpoint,\n completedSteps: {\n ...this.checkpoint.completedSteps,\n [key]: result,\n },\n };\n\n return result;\n }),\n );\n\n // Persist after all parallel operations complete\n await this.store.set(this.envelope.id, this.checkpoint);\n\n return results as {\n [K in keyof T]: T[K] extends [string, () => Promise<infer R>]\n ? R\n : T[K] extends [string, () => infer R]\n ? R\n : never;\n };\n }\n\n /**\n * Clears the checkpoint from storage.\n * Called after successful completion or dead-letter.\n */\n async clear(): Promise<void> {\n await this.store.delete(this.envelope.id);\n }\n\n /**\n * Gets the current checkpoint state.\n * Useful for debugging and testing.\n */\n getCheckpoint(): Checkpoint {\n return this.checkpoint;\n }\n\n /**\n * Gets the number of cached steps.\n */\n get cachedStepCount(): number {\n return Object.keys(this.checkpoint.completedSteps).length;\n }\n}\n","import type { Checkpoint, CheckpointStore } from '../types.js';\n\n/**\n * In-memory checkpoint store for testing and development.\n * Checkpoints are lost when the process restarts.\n *\n * For production use, implement a persistent store (e.g., RedisCheckpointStore).\n */\nexport class MemoryCheckpointStore implements CheckpointStore {\n private readonly checkpoints = new Map<string, Checkpoint>();\n\n async get(envelopeId: string): Promise<Checkpoint | undefined> {\n return this.checkpoints.get(envelopeId);\n }\n\n async set(envelopeId: string, checkpoint: Checkpoint): Promise<void> {\n this.checkpoints.set(envelopeId, checkpoint);\n }\n\n async delete(envelopeId: string): Promise<void> {\n this.checkpoints.delete(envelopeId);\n }\n\n /**\n * Gets the number of stored checkpoints.\n * Useful for testing.\n */\n get size(): number {\n return this.checkpoints.size;\n }\n\n /**\n * Clears all stored checkpoints.\n * Useful for testing.\n */\n clear(): void {\n this.checkpoints.clear();\n }\n\n /**\n * Gets all stored checkpoint IDs.\n * Useful for testing.\n */\n keys(): string[] {\n return [...this.checkpoints.keys()];\n }\n}\n","import type { Checkpoint, CheckpointStore } from '../types.js';\n\n/**\n * No-operation checkpoint store that doesn't persist anything.\n * Used when no checkpoint store is configured.\n *\n * With this store, resumable subscribers will work but checkpoints\n * won't persist across retries - all io() operations will re-execute.\n */\nexport class NoOpCheckpointStore implements CheckpointStore {\n async get(_envelopeId: string): Promise<Checkpoint | undefined> {\n return undefined;\n }\n\n async set(_envelopeId: string, _checkpoint: Checkpoint): Promise<void> {\n // No-op\n }\n\n async delete(_envelopeId: string): Promise<void> {\n // No-op\n }\n}\n","import type { Checkpoint, CheckpointStore } from '../checkpoint/index.js';\nimport { NoOpCheckpointStore, ResumableContext } from '../checkpoint/index.js';\nimport type { Codec } from '../codec/index.js';\nimport { CodecDecodeError } from '../codec/index.js';\nimport {\n SubscriberIsStubError,\n SubscriberNotRegisteredError,\n} from '../errors/index.js';\nimport type { SafeHooks } from '../hooks/index.js';\nimport type { RetryDecision, RetryPolicy } from '../retry/index.js';\nimport type { SchemaRegistry } from '../schema/index.js';\nimport type { MessageReceipt, Transport } from '../transport/index.js';\nimport type {\n CallbackContext,\n Dispatcher,\n Envelope,\n ResumableCallbackContext,\n SubscriberDefinition,\n} from '../types/index.js';\nimport { isResumableSubscriber } from '../types/index.js';\n\n/**\n * Configuration for the processing pipeline.\n */\nexport interface PipelineConfig {\n readonly transport: Transport;\n readonly schema: SchemaRegistry;\n readonly codec: Codec;\n readonly retryPolicy: RetryPolicy;\n readonly hooks: SafeHooks;\n /** Optional checkpoint store for resumable subscribers */\n readonly checkpointStore?: CheckpointStore | undefined;\n /** Dispatcher (matador) for sending events from subscriber callbacks */\n readonly dispatcher: Dispatcher;\n}\n\n/**\n * Result of pipeline processing.\n */\nexport interface ProcessResult {\n readonly success: boolean;\n readonly envelope?: Envelope | undefined;\n readonly subscriber?: SubscriberDefinition | undefined;\n readonly error?: Error | undefined;\n readonly decision?: RetryDecision | undefined;\n readonly durationMs: number;\n}\n\n/**\n * Processing pipeline for incoming messages.\n *\n * Handles the complete message lifecycle:\n * 1. Decode envelope from raw bytes\n * 2. Lookup subscriber from schema\n * 3. Execute subscriber callback with hooks\n * 4. Handle success/failure with retry policy\n */\nexport class ProcessingPipeline {\n private readonly transport: Transport;\n private readonly schema: SchemaRegistry;\n private readonly codec: Codec;\n private readonly retryPolicy: RetryPolicy;\n private readonly hooks: SafeHooks;\n private readonly checkpointStore: CheckpointStore;\n private readonly dispatcher: Dispatcher;\n\n constructor(config: PipelineConfig) {\n this.transport = config.transport;\n this.schema = config.schema;\n this.codec = config.codec;\n this.retryPolicy = config.retryPolicy;\n this.hooks = config.hooks;\n this.checkpointStore = config.checkpointStore ?? new NoOpCheckpointStore();\n this.dispatcher = config.dispatcher;\n }\n\n /**\n * Processes a raw message from the transport.\n */\n async process(\n rawMessage: Uint8Array,\n receipt: MessageReceipt,\n ): Promise<ProcessResult> {\n const startTime = performance.now();\n\n // 1. Decode envelope\n let envelope: Envelope;\n try {\n envelope = this.codec.decode(rawMessage);\n } catch (error) {\n const decodeError =\n error instanceof CodecDecodeError\n ? error\n : new CodecDecodeError('Unknown decode error', error);\n\n await this.transport.complete(receipt);\n await this.hooks.onDecodeError({\n error: decodeError,\n rawMessage,\n sourceQueue: receipt.sourceQueue,\n transport: receipt.sourceTransport,\n });\n\n return {\n success: false,\n error: decodeError,\n durationMs: performance.now() - startTime,\n };\n }\n\n // 2. Lookup subscriber from schema\n const subscriberDef = this.schema.getSubscriberDefinition(\n envelope.docket.eventKey,\n envelope.docket.targetSubscriber,\n );\n\n if (!subscriberDef) {\n const error = new SubscriberNotRegisteredError(\n envelope.docket.targetSubscriber,\n envelope.docket.eventKey,\n );\n\n // Retry unhandled messages (likely deployment timing issue)\n const decision = this.getUnhandledRetryDecision(envelope, receipt, error);\n await this.handleRetryDecision(receipt, envelope, decision);\n\n return {\n success: false,\n envelope,\n error,\n decision,\n durationMs: performance.now() - startTime,\n };\n }\n\n // Get executable subscriber\n const subscriber = this.schema.getExecutableSubscriber(\n envelope.docket.eventKey,\n envelope.docket.targetSubscriber,\n );\n\n if (!subscriber) {\n // Subscriber is a stub (remote implementation)\n const error = new SubscriberIsStubError(envelope.docket.targetSubscriber);\n\n // Retry stub messages (likely deployment timing issue)\n const decision = this.getUnhandledRetryDecision(envelope, receipt, error);\n await this.handleRetryDecision(receipt, envelope, decision);\n\n return {\n success: false,\n envelope,\n subscriber: subscriberDef,\n error,\n decision,\n durationMs: performance.now() - startTime,\n };\n }\n\n // 3. Execute subscriber callback with hooks\n let result: unknown;\n let error: Error | undefined;\n let context: ResumableContext | undefined;\n\n // For resumable subscribers, load existing checkpoint and create context\n const isResumable = isResumableSubscriber(subscriber);\n let existingCheckpoint: Checkpoint | undefined;\n\n if (isResumable) {\n existingCheckpoint = await this.checkpointStore.get(envelope.id);\n\n if (existingCheckpoint) {\n await this.hooks.onCheckpointLoaded?.({\n envelope,\n subscriber: subscriberDef,\n checkpoint: existingCheckpoint,\n cachedSteps: Object.keys(existingCheckpoint.completedSteps).length,\n });\n }\n\n context = new ResumableContext({\n store: this.checkpointStore,\n envelope,\n subscriber: subscriberDef,\n existingCheckpoint,\n hooks: {\n onCheckpointHit: (ctx) => this.hooks.onCheckpointHit?.(ctx),\n onCheckpointMiss: (ctx) => this.hooks.onCheckpointMiss?.(ctx),\n },\n });\n }\n\n // Create base callback context with matador dispatcher\n const callbackContext: CallbackContext = { matador: this.dispatcher };\n\n await this.hooks.onWorkerWrap(envelope, subscriberDef, async () => {\n await this.hooks.onWorkerBeforeProcess(envelope, subscriberDef);\n\n try {\n if (isResumable && context) {\n // Resumable subscriber: pass combined context (checkpoint + matador)\n // Cast needed because TypeScript can't narrow the union type based on isResumable\n const resumableCallback = subscriber.callback as (\n envelope: Envelope,\n context: ResumableCallbackContext,\n ) => Promise<void> | void;\n // Create combined context by binding class methods and adding matador\n const fullContext: ResumableCallbackContext = {\n io: context.io.bind(context),\n all: context.all.bind(context),\n attempt: context.attempt,\n isRetry: context.isRetry,\n matador: this.dispatcher,\n };\n result = await resumableCallback(envelope, fullContext);\n } else {\n // Standard subscriber: pass envelope and callback context\n const standardCallback = subscriber.callback as (\n envelope: Envelope,\n context: CallbackContext,\n ) => Promise<void> | void;\n result = await standardCallback(envelope, callbackContext);\n }\n } catch (e) {\n error = e instanceof Error ? e : new Error(String(e));\n }\n });\n\n const durationMs = performance.now() - startTime;\n\n // 4. Handle success\n if (!error) {\n // Clear checkpoint on success for resumable subscribers\n if (context) {\n await context.clear();\n await this.hooks.onCheckpointCleared?.({\n envelope,\n subscriber: subscriberDef,\n reason: 'success',\n });\n }\n\n await this.transport.complete(receipt);\n await this.hooks.onWorkerSuccess({\n envelope,\n subscriber: subscriberDef,\n result,\n durationMs,\n transport: receipt.sourceTransport,\n });\n\n return {\n success: true,\n envelope,\n subscriber: subscriberDef,\n durationMs,\n };\n }\n\n // 5. Handle failure - consult retry policy\n const decision = this.retryPolicy.shouldRetry({\n envelope,\n error,\n subscriber: subscriberDef,\n receipt,\n });\n\n // Update envelope with error info\n envelope.docket.lastError = error.message;\n envelope.docket.firstError ??= error.message;\n\n // Clear checkpoint on dead-letter (terminal state)\n if (decision.action === 'dead-letter' && context) {\n await context.clear();\n await this.hooks.onCheckpointCleared?.({\n envelope,\n subscriber: subscriberDef,\n reason: 'dead-letter',\n });\n }\n\n await this.handleRetryDecision(receipt, envelope, decision);\n\n await this.hooks.onWorkerError({\n envelope,\n subscriber: subscriberDef,\n error,\n durationMs,\n decision,\n transport: receipt.sourceTransport,\n });\n\n return {\n success: false,\n envelope,\n subscriber: subscriberDef,\n error,\n decision,\n durationMs,\n };\n }\n\n private async handleRetryDecision(\n receipt: MessageReceipt,\n envelope: Envelope,\n decision: RetryDecision,\n ): Promise<void> {\n switch (decision.action) {\n case 'retry': {\n // Increment attempts and schedule retry\n envelope.docket.attempts++;\n envelope.docket.scheduledFor = new Date(\n Date.now() + decision.delay,\n ).toISOString();\n\n await this.transport.send(receipt.sourceQueue, envelope, {\n delay: decision.delay,\n });\n await this.transport.complete(receipt);\n break;\n }\n\n case 'dead-letter': {\n await this.sendToDeadLetter(\n receipt,\n envelope,\n decision.queue,\n decision.reason,\n );\n break;\n }\n\n case 'discard': {\n await this.transport.complete(receipt);\n break;\n }\n }\n }\n\n private async sendToDeadLetter(\n receipt: MessageReceipt,\n envelope: Envelope,\n dlqName: string,\n reason: string,\n ): Promise<void> {\n envelope.docket.originalQueue ??= receipt.sourceQueue;\n\n if (this.transport.sendToDeadLetter) {\n await this.transport.sendToDeadLetter(receipt, dlqName, envelope, reason);\n } else {\n // Manual: send to DLQ then complete original\n const fullDlqName = `${receipt.sourceQueue}.${dlqName}`;\n await this.transport.send(fullDlqName, envelope);\n await this.transport.complete(receipt);\n }\n }\n\n /**\n * Gets retry decision for unhandled messages (subscriber not found).\n * Uses same retry policy logic but sends to 'unhandled' DLQ after max attempts.\n */\n private getUnhandledRetryDecision(\n envelope: Envelope,\n receipt: MessageReceipt,\n error: Error,\n ): RetryDecision {\n // Create a synthetic subscriber definition for retry policy\n const syntheticSubscriber: SubscriberDefinition = {\n name: envelope.docket.targetSubscriber,\n description: 'Synthetic subscriber for unhandled message retry',\n idempotent: 'yes', // Safe to retry unhandled messages\n importance: envelope.docket.importance ?? 'should-investigate',\n };\n\n const decision = this.retryPolicy.shouldRetry({\n envelope,\n error,\n subscriber: syntheticSubscriber,\n receipt,\n });\n\n // Override dead-letter queue to 'unhandled' instead of 'undeliverable'\n if (decision.action === 'dead-letter') {\n return {\n action: 'dead-letter',\n queue: 'unhandled',\n reason: decision.reason,\n };\n }\n\n return decision;\n }\n}\n","import {\n IdempotentMessageCannotRetryError,\n MessageMaybePoisonedError,\n isAssertionError,\n isDoRetry,\n isDontRetry,\n} from '../errors/index.js';\nimport type { RetryContext, RetryDecision, RetryPolicy } from './policy.js';\n\n/**\n * Configuration for the standard retry policy.\n */\nexport interface StandardRetryPolicyConfig {\n /** Maximum number of attempts before dead-lettering */\n readonly maxAttempts: number;\n\n /** Base delay between retries in milliseconds */\n readonly baseDelay: number;\n\n /** Maximum delay between retries in milliseconds */\n readonly maxDelay: number;\n\n /** Multiplier for exponential backoff */\n readonly backoffMultiplier: number;\n\n /**\n * Maximum native delivery count before considering message poisoned.\n * This prevents crash loops from messages that crash the worker.\n * Poison messages are sent directly to the dead-letter queue.\n * Default: 5\n */\n readonly maxDeliveries: number;\n}\n\n/**\n * Default configuration values.\n */\nexport const defaultRetryConfig: StandardRetryPolicyConfig = {\n maxAttempts: 3,\n baseDelay: 1000,\n maxDelay: 300000, // 5 minutes\n backoffMultiplier: 2,\n maxDeliveries: 5,\n};\n\n/**\n * Standard retry policy implementing Matador v1 behavior.\n *\n * Decision logic (in priority order):\n * 1. Poison message → dead-letter (prevent crash loops)\n * 2. EventAssertionError → dead-letter (never retry)\n * 3. DontRetry → dead-letter (explicit no-retry)\n * 4. DoRetry → retry if under max attempts\n * 5. Max attempts exceeded → dead-letter\n * 6. Non-idempotent subscriber on redelivery → dead-letter\n * 7. Default → retry with exponential backoff\n */\nexport class StandardRetryPolicy implements RetryPolicy {\n private readonly config: StandardRetryPolicyConfig;\n\n constructor(config: Partial<StandardRetryPolicyConfig> = {}) {\n this.config = { ...defaultRetryConfig, ...config };\n }\n\n shouldRetry(context: RetryContext): RetryDecision {\n const { envelope, error, subscriber, receipt } = context;\n const errorMessage = error.message;\n\n // 1. Poison message detection - prevent crash loops\n if (receipt.deliveryCount >= this.config.maxDeliveries) {\n const poisonError = new MessageMaybePoisonedError(\n envelope.id,\n receipt.deliveryCount,\n this.config.maxDeliveries,\n );\n return {\n action: 'dead-letter',\n queue: 'undeliverable',\n reason: poisonError.message,\n };\n }\n\n // 2. Assertion errors never retry\n if (isAssertionError(error)) {\n return {\n action: 'dead-letter',\n queue: 'undeliverable',\n reason: `assertion error: ${errorMessage}`,\n };\n }\n\n // 3. Explicit no-retry\n if (isDontRetry(error)) {\n return {\n action: 'dead-letter',\n queue: 'undeliverable',\n reason: errorMessage,\n };\n }\n\n // 4. Explicit retry request\n if (isDoRetry(error)) {\n if (receipt.attemptNumber >= this.config.maxAttempts) {\n return {\n action: 'dead-letter',\n queue: 'undeliverable',\n reason: `max attempts exceeded (${this.config.maxAttempts}) with forced retry`,\n };\n }\n return {\n action: 'retry',\n delay: this.getDelay(context),\n };\n }\n\n // 5. Max attempts exceeded\n if (receipt.attemptNumber >= this.config.maxAttempts) {\n return {\n action: 'dead-letter',\n queue: 'undeliverable',\n reason: `max attempts exceeded (${this.config.maxAttempts})`,\n };\n }\n\n // 6. Non-idempotent subscriber on redelivery\n // 'no' and 'unknown' are treated the same (safer default)\n if (\n receipt.redelivered &&\n (subscriber.idempotent === 'no' || subscriber.idempotent === 'unknown')\n ) {\n const idempotentError = new IdempotentMessageCannotRetryError(\n envelope.id,\n subscriber.name,\n );\n return {\n action: 'dead-letter',\n queue: 'undeliverable',\n reason: idempotentError.message,\n };\n }\n\n // 7. Default: retry with backoff\n return {\n action: 'retry',\n delay: this.getDelay(context),\n };\n }\n\n getDelay(context: RetryContext): number {\n const attempt = context.receipt.attemptNumber;\n const delay =\n this.config.baseDelay * this.config.backoffMultiplier ** (attempt - 1);\n return Math.min(delay, this.config.maxDelay);\n }\n}\n","import type {\n AnySubscriber,\n EventClass,\n MatadorEvent,\n Subscriber,\n SubscriberStub,\n} from '../types/index.js';\n\n/**\n * Type-safe schema entry for a single event type (object format).\n * The type parameter enforces that subscribers match the event type.\n */\nexport interface SchemaEntry<T extends MatadorEvent = MatadorEvent> {\n /** The event class */\n readonly eventClass: EventClass<T['data']>;\n\n /** Subscribers for this event */\n readonly subscribers: readonly (Subscriber<T> | SubscriberStub)[];\n}\n\n/**\n * Type-safe schema entry as a tuple: [EventClass, Subscribers[]]\n * The type parameter enforces that subscribers match the event type.\n *\n * @example\n * ```typescript\n * const entry: SchemaEntryTuple<UserCreatedEvent> = [\n * UserCreatedEvent,\n * [createSubscriber<UserCreatedEvent>('handler', async (env) => {})]\n * ];\n * ```\n */\nexport type SchemaEntryTuple<T extends MatadorEvent = MatadorEvent> = readonly [\n eventClass: EventClass<T['data']>,\n subscribers: readonly (Subscriber<T> | SubscriberStub)[],\n];\n\n/**\n * Creates a type-safe schema entry tuple.\n * Ensures that subscribers are compatible with the event class at compile time.\n *\n * @example\n * ```typescript\n * const schema = {\n * [UserCreatedEvent.key]: bind(UserCreatedEvent, [\n * createSubscriber<UserCreatedEvent>('send-email', async (env) => {\n * console.log(env.data.email); // Type-safe access\n * }),\n * ]),\n * } satisfies MatadorSchema;\n * ```\n */\nexport function bind<T extends MatadorEvent>(\n eventClass: EventClass<T['data']>,\n subscribers: readonly (Subscriber<T> | SubscriberStub)[],\n): SchemaEntryTuple<T> {\n return [eventClass, subscribers] as const;\n}\n\n/**\n * Minimal type for event class in schema storage.\n * Only requires the static `key` property for routing.\n * Constructor constraint is omitted to allow heterogeneous event types.\n */\nexport type AnyEventClass = {\n readonly key: string;\n // biome-ignore lint/suspicious/noExplicitAny: Required for variance compatibility in heterogeneous collections\n new (data: any): MatadorEvent;\n};\n\n/**\n * Runtime schema entry stored in MatadorSchema (object format).\n * Uses AnySubscriber and AnyEventClass to allow heterogeneous event types.\n * Type safety is enforced at definition time via `schemaEntry()` helper.\n */\nexport interface RuntimeSchemaEntry {\n readonly eventClass: AnyEventClass;\n readonly subscribers: readonly AnySubscriber[];\n}\n\n/**\n * Runtime schema tuple stored in MatadorSchema.\n * Uses AnySubscriber and AnyEventClass to allow heterogeneous event types.\n * Type safety is enforced at definition time via `schemaEntry()` helper.\n */\nexport type RuntimeSchemaEntryTuple = readonly [\n eventClass: AnyEventClass,\n subscribers: readonly AnySubscriber[],\n];\n\n/**\n * Matador schema mapping event keys to their definitions.\n * Supports both object format (SchemaEntry) and tuple format (SchemaEntryTuple).\n *\n * For type-safe schema definitions, use the `bind` helper function\n * which ensures subscribers are compatible with their event class.\n *\n * @example\n * ```typescript\n * // Type-safe with bind helper:\n * const schema = {\n * [UserCreatedEvent.key]: bind(UserCreatedEvent, [emailSubscriber]),\n * } satisfies MatadorSchema;\n *\n * // Or inline (less type-safe):\n * const schema: MatadorSchema = {\n * [UserCreatedEvent.key]: [UserCreatedEvent, [emailSubscriber]],\n * };\n * ```\n */\nexport type MatadorSchema = {\n readonly [eventKey: string]: RuntimeSchemaEntry | RuntimeSchemaEntryTuple;\n};\n\n/**\n * Type guard to check if a schema entry is in tuple format.\n */\nexport function isSchemaEntryTuple(\n entry: RuntimeSchemaEntry | RuntimeSchemaEntryTuple,\n): entry is RuntimeSchemaEntryTuple {\n return Array.isArray(entry);\n}\n\n/**\n * Options for schema registration.\n */\nexport interface RegisterOptions {\n /** Override existing registration if present */\n readonly override?: boolean;\n}\n\n/**\n * Result of schema validation.\n */\nexport interface SchemaValidationResult {\n readonly valid: boolean;\n readonly issues: readonly SchemaIssue[];\n}\n\n/**\n * Individual schema issue.\n */\nexport interface SchemaIssue {\n readonly severity: 'error' | 'warning';\n readonly eventKey: string;\n readonly message: string;\n}\n\n/**\n * Plugin definition for adding subscribers to multiple events.\n */\nexport interface SchemaPlugin {\n /** The subscriber to add to events */\n readonly subscriber: AnySubscriber;\n\n /** Event keys to exclude from this plugin */\n readonly exclusions?: readonly string[];\n}\n\n/**\n * Installs plugins (global subscribers) into a schema.\n * Each plugin subscriber is added to all events except those in its exclusions list.\n *\n * @param schema - The base schema to extend\n * @param plugins - Array of plugins to install\n * @returns A new schema with plugin subscribers added\n *\n * @example\n * ```typescript\n * const baseSchema: MatadorSchema = {\n * [UserCreatedEvent.key]: [UserCreatedEvent, [sendWelcomeEmail]],\n * [OrderPlacedEvent.key]: [OrderPlacedEvent, [processOrder]],\n * [ChatMessageSent.key]: [ChatMessageSent, [notifyRecipient]],\n * };\n *\n * const schema = installPlugins(baseSchema, [\n * {\n * subscriber: logToBigQuery,\n * exclusions: [ChatMessageSent.key], // Don't log chat messages\n * },\n * {\n * subscriber: trackAnalytics,\n * // No exclusions - added to all events\n * },\n * ]);\n * ```\n */\nexport function installPlugins(\n schema: MatadorSchema,\n plugins: readonly SchemaPlugin[],\n): MatadorSchema {\n const result: Record<string, RuntimeSchemaEntry | RuntimeSchemaEntryTuple> =\n {};\n\n for (const [eventKey, entry] of Object.entries(schema)) {\n // Get existing event class and subscribers\n const [eventClass, existingSubscribers] = isSchemaEntryTuple(entry)\n ? [entry[0], entry[1]]\n : [entry.eventClass, entry.subscribers];\n\n // Collect subscribers to add from plugins\n const pluginSubscribers: AnySubscriber[] = [];\n for (const plugin of plugins) {\n if (!plugin.exclusions?.includes(eventKey)) {\n pluginSubscribers.push(plugin.subscriber);\n }\n }\n\n // Create new entry with combined subscribers\n result[eventKey] = [\n eventClass,\n [...existingSubscribers, ...pluginSubscribers],\n ];\n }\n\n return result;\n}\n","import type { HasDescription } from '../errors/index.js';\nimport type {\n AnySubscriber,\n EventClass,\n MatadorEvent,\n Subscriber,\n SubscriberDefinition,\n} from '../types/index.js';\nimport { isSubscriber } from '../types/index.js';\nimport type {\n RegisterOptions,\n SchemaEntry,\n SchemaIssue,\n SchemaValidationResult,\n} from './types.js';\n\n/**\n * Error thrown when schema operations fail.\n */\nexport class SchemaError extends Error implements HasDescription {\n readonly description =\n 'A schema operation failed, such as registering a duplicate event or ' +\n 'conflicting alias. This is a configuration error that should be fixed ' +\n 'during development. Review the event and subscriber registrations to ' +\n 'resolve the conflict.';\n\n constructor(message: string) {\n super(message);\n this.name = 'SchemaError';\n }\n}\n\n/**\n * Registry for managing event-subscriber relationships.\n */\nexport class SchemaRegistry {\n private readonly entries = new Map<string, SchemaEntry>();\n private readonly aliases = new Map<string, string>();\n\n /**\n * Registers an event class with its subscribers.\n */\n register<T>(\n eventClass: EventClass<T>,\n subscribers: readonly AnySubscriber[],\n options: RegisterOptions = {},\n ): void {\n const key = eventClass.key;\n\n if (this.entries.has(key) && !options.override) {\n throw new SchemaError(`Event \"${key}\" is already registered`);\n }\n\n this.entries.set(key, {\n eventClass,\n subscribers,\n } as SchemaEntry);\n\n // Register aliases\n if (eventClass.aliases) {\n for (const alias of eventClass.aliases) {\n if (\n this.aliases.has(alias) &&\n this.aliases.get(alias) !== key &&\n !options.override\n ) {\n throw new SchemaError(\n `Alias \"${alias}\" is already registered for event \"${this.aliases.get(alias)}\"`,\n );\n }\n this.aliases.set(alias, key);\n }\n }\n }\n\n /**\n * Gets the event class for a given key.\n */\n getEventClass(key: string): EventClass | undefined {\n const entry = this.entries.get(key);\n if (entry) return entry.eventClass;\n\n // Check aliases\n const aliasKey = this.aliases.get(key);\n if (aliasKey) {\n return this.entries.get(aliasKey)?.eventClass;\n }\n\n return undefined;\n }\n\n /**\n * Gets all subscribers for an event key.\n */\n getSubscribers(eventKey: string): readonly AnySubscriber[] {\n const entry = this.getEntry(eventKey);\n return entry?.subscribers ?? [];\n }\n\n /**\n * Gets a specific subscriber by event key and subscriber name.\n */\n getSubscriber(\n eventKey: string,\n subscriberName: string,\n ): AnySubscriber | undefined {\n const subscribers = this.getSubscribers(eventKey);\n return subscribers.find((s) => s.name === subscriberName);\n }\n\n /**\n * Gets a subscriber definition for the pipeline.\n */\n getSubscriberDefinition(\n eventKey: string,\n subscriberName: string,\n ): SubscriberDefinition | undefined {\n const subscriber = this.getSubscriber(eventKey, subscriberName);\n if (!subscriber) return undefined;\n\n const def: SubscriberDefinition = {\n name: subscriber.name,\n idempotent: subscriber.idempotent ?? 'unknown',\n importance: subscriber.importance ?? 'should-investigate',\n ...('description' in subscriber &&\n subscriber.description !== undefined && {\n description: subscriber.description,\n }),\n };\n\n if (subscriber.targetQueue !== undefined) {\n (def as { targetQueue?: string }).targetQueue = subscriber.targetQueue;\n }\n\n return def;\n }\n\n /**\n * Gets a subscriber with callback for execution.\n */\n getExecutableSubscriber(\n eventKey: string,\n subscriberName: string,\n ): Subscriber<MatadorEvent<unknown>> | undefined {\n const subscriber = this.getSubscriber(eventKey, subscriberName);\n if (!subscriber || !isSubscriber(subscriber)) return undefined;\n return subscriber;\n }\n\n /**\n * Gets the event class by alias.\n */\n getEventByAlias(alias: string): EventClass | undefined {\n const key = this.aliases.get(alias);\n if (!key) return undefined;\n return this.entries.get(key)?.eventClass;\n }\n\n /**\n * Checks if an event key is registered.\n */\n hasEvent(key: string): boolean {\n return this.entries.has(key) || this.aliases.has(key);\n }\n\n /**\n * Gets all registered event keys.\n */\n getEventKeys(): readonly string[] {\n return [...this.entries.keys()];\n }\n\n /**\n * Validates the schema for issues.\n */\n validate(): SchemaValidationResult {\n const issues: SchemaIssue[] = [];\n\n for (const [key, entry] of this.entries) {\n // Check for duplicate subscriber names\n const names = new Set<string>();\n for (const subscriber of entry.subscribers) {\n if (names.has(subscriber.name)) {\n issues.push({\n severity: 'error',\n eventKey: key,\n message: `Duplicate subscriber name: \"${subscriber.name}\"`,\n });\n }\n names.add(subscriber.name);\n }\n\n // Check for subscribers without callbacks (stubs in consuming instance)\n const stubs = entry.subscribers.filter((s) => !isSubscriber(s));\n if (stubs.length === entry.subscribers.length && stubs.length > 0) {\n issues.push({\n severity: 'warning',\n eventKey: key,\n message: 'All subscribers are stubs, no local handlers',\n });\n }\n }\n\n return {\n valid: issues.filter((i) => i.severity === 'error').length === 0,\n issues,\n };\n }\n\n /**\n * Clears all registered entries.\n */\n clear(): void {\n this.entries.clear();\n this.aliases.clear();\n }\n\n private getEntry(eventKey: string): SchemaEntry | undefined {\n const entry = this.entries.get(eventKey);\n if (entry) return entry;\n\n const aliasKey = this.aliases.get(eventKey);\n if (aliasKey) {\n return this.entries.get(aliasKey);\n }\n\n return undefined;\n }\n}\n","import type { CheckpointStore } from '../checkpoint/index.js';\nimport type { Codec } from '../codec/index.js';\nimport { JsonCodec } from '../codec/index.js';\nimport {\n InvalidSchemaError,\n NotStartedError,\n ShutdownInProgressError,\n SomeSendError,\n} from '../errors/index.js';\nimport type { MatadorHooks } from '../hooks/index.js';\nimport { SafeHooks } from '../hooks/index.js';\nimport { ProcessingPipeline } from '../pipeline/index.js';\nimport type { RetryPolicy } from '../retry/index.js';\nimport { StandardRetryPolicy } from '../retry/index.js';\nimport type { MatadorSchema } from '../schema/index.js';\nimport { SchemaRegistry, isSchemaEntryTuple } from '../schema/index.js';\nimport type { Topology } from '../topology/index.js';\nimport {\n findQueueDefinition,\n resolveTargetQueueName,\n} from '../topology/index.js';\nimport type { Subscription, Transport } from '../transport/index.js';\nimport type {\n AnySubscriber,\n Dispatcher,\n Event,\n EventClass,\n EventOptions,\n} from '../types/index.js';\nimport type { SendResult } from './fanout.js';\nimport { FanoutEngine } from './fanout.js';\nimport type { HandlersState, ShutdownConfig } from './shutdown.js';\nimport { ShutdownManager } from './shutdown.js';\n\n/**\n * Configuration for Matador.\n */\nexport interface MatadorConfig {\n /** Transport for message delivery */\n readonly transport: Transport;\n\n /** Topology configuration */\n readonly topology: Topology;\n\n /** Event schema mapping event keys to event classes and subscribers */\n readonly schema: MatadorSchema;\n\n /** Queues to consume from (empty = no consumption) */\n readonly consumeFrom?: readonly string[] | undefined;\n\n /** Custom codec (defaults to JSON) */\n readonly codec?: Codec | undefined;\n\n /** Custom retry policy */\n readonly retryPolicy?: RetryPolicy | undefined;\n\n /** Shutdown configuration */\n readonly shutdownConfig?: Partial<ShutdownConfig> | undefined;\n\n /**\n * Checkpoint store for resumable subscribers.\n * Required for persisting io() results across retries.\n * If not provided, resumable subscribers will work but checkpoints\n * won't persist across retries.\n */\n readonly checkpointStore?: CheckpointStore | undefined;\n\n /**\n * Maximum number of in-memory buffered sends held for retry when the\n * transport is unavailable.\n *\n * @default 5000\n */\n readonly maxRetryBufferSize?: number | undefined;\n\n /**\n * Maximum number of retry attempts for a buffered message before it's\n * dropped and reported via onEnqueueError, instead of being retried forever.\n *\n * @default undefined (no limit — retries until the buffer flushes successfully)\n */\n readonly maxRetryAttempts?: number | undefined;\n\n /**\n * How often (in ms) to attempt flushing the retry buffer, independent of\n * transport reconnect events. Covers the case where the transport stays\n * connected but an individual publish keeps failing.\n *\n * @default 30000. Pass 0 to disable the interval and rely on\n * onConnected/manual flushes only.\n */\n readonly retryIntervalMs?: number | undefined;\n\n /**\n * Number of consecutive flush failures tolerated within a single flush\n * pass before bailing out early and re-buffering the untried remainder,\n * instead of retrying every buffered message against a broker that's\n * rejecting everything.\n *\n * @default 10. Pass 0 (or a negative number) to disable the breaker and\n * always attempt every buffered message on every flush pass.\n */\n readonly maxConsecutiveFlushFailures?: number | undefined;\n}\n\n/**\n * Matador - Transport-agnostic event processing library.\n *\n * Main orchestrator that wires together:\n * - Transport: Message delivery\n * - Schema: Event-subscriber registry\n * - Pipeline: Message processing\n * - Fanout: Event sending\n * - Shutdown: Graceful termination\n */\nexport class Matador implements Dispatcher {\n private readonly transport: Transport;\n private readonly topology: Topology;\n private readonly schema;\n private readonly codec: Codec;\n private readonly retryPolicy: RetryPolicy;\n private readonly hooks;\n private readonly pipeline;\n private readonly fanout;\n private readonly shutdownManager;\n private readonly consumeFrom: readonly string[];\n private readonly subscriptions: Subscription[] = [];\n private started = false;\n\n /**\n * Creates a new Matador instance.\n *\n * @param config - Static configuration (transport, topology, schema, etc.)\n * @param hooks - Lifecycle hooks for logging, monitoring, and dynamic configuration.\n * Passed separately to support NestJS dependency injection.\n */\n constructor(config: MatadorConfig, hooks?: MatadorHooks) {\n this.transport = config.transport;\n this.topology = config.topology;\n this.consumeFrom = config.consumeFrom ?? [];\n\n // Initialize components\n this.schema = new SchemaRegistry();\n this.codec = config.codec ?? new JsonCodec();\n this.retryPolicy = config.retryPolicy ?? new StandardRetryPolicy();\n this.hooks = new SafeHooks(hooks);\n\n // Register schema from config\n this.registerSchema(config.schema);\n\n // Create pipeline\n this.pipeline = new ProcessingPipeline({\n transport: this.transport,\n schema: this.schema,\n codec: this.codec,\n retryPolicy: this.retryPolicy,\n hooks: this.hooks,\n checkpointStore: config.checkpointStore,\n dispatcher: this,\n });\n\n // Create fanout engine\n const defaultQueue = this.topology.queues[0]?.name ?? 'default';\n this.fanout = new FanoutEngine({\n transport: this.transport,\n schema: this.schema,\n hooks: this.hooks,\n topology: this.topology,\n defaultQueue,\n maxRetryBufferSize: config.maxRetryBufferSize,\n maxRetryAttempts: config.maxRetryAttempts,\n retryIntervalMs: config.retryIntervalMs,\n maxConsecutiveFlushFailures: config.maxConsecutiveFlushFailures,\n });\n\n // Create shutdown manager\n this.shutdownManager = new ShutdownManager(\n () => this.fanout.eventsBeingEnqueuedCount,\n () => this.unsubscribeAll(),\n () => this.transport.disconnect(),\n config.shutdownConfig,\n );\n }\n\n /**\n * Registers an event class with its subscribers.\n */\n register<T>(\n eventClass: EventClass<T>,\n subscribers: readonly AnySubscriber[],\n ): this {\n this.schema.register(eventClass, subscribers);\n return this;\n }\n\n /**\n * Registers events from a schema object.\n * Supports both object format and tuple format entries.\n *\n * @example\n * ```typescript\n * // Tuple format\n * matador.registerSchema({\n * [UserCreatedEvent.key]: [UserCreatedEvent, [emailSubscriber]],\n * [OrderPlacedEvent.key]: [OrderPlacedEvent, [invoiceSubscriber]],\n * });\n *\n * // Object format\n * matador.registerSchema({\n * [UserCreatedEvent.key]: { eventClass: UserCreatedEvent, subscribers: [emailSubscriber] },\n * });\n * ```\n */\n registerSchema(schema: MatadorSchema): this {\n for (const entry of Object.values(schema)) {\n if (isSchemaEntryTuple(entry)) {\n // Tuple format: [EventClass, Subscriber[]]\n const [eventClass, subscribers] = entry;\n this.schema.register(eventClass, subscribers);\n } else {\n // Object format: { eventClass, subscribers }\n this.schema.register(entry.eventClass, entry.subscribers);\n }\n }\n return this;\n }\n\n /**\n * Starts Matador - connects transport and begins consuming.\n * This method is idempotent - calling it multiple times is safe.\n */\n async start(): Promise<void> {\n // Idempotent: if already started, just return\n if (this.started) {\n return;\n }\n\n // Validate schema\n const validation = this.schema.validate();\n if (!validation.valid) {\n const errors = validation.issues.filter((i) => i.severity === 'error');\n throw new InvalidSchemaError(\n 'Schema validation failed',\n errors.map((e) => e.message).join(', '),\n );\n }\n\n // Connect transport\n this.hooks.logger.info(\n `[Matador] ⏳ Starting backend '${this.transport.name}'...`,\n );\n await this.transport.connect();\n this.hooks.logger.info(\n `[Matador] 🟢 Backend '${this.transport.name}' started.`,\n );\n\n // Apply topology\n await this.transport.applyTopology(this.topology);\n\n // Subscribe to queues\n if (this.consumeFrom.length > 0) {\n this.hooks.logger.info(\n `[Matador] 🟢 Worker subscribing to '${this.consumeFrom.join(',')}'.`,\n );\n } else {\n this.hooks.logger.info(\n '[Matador] 🟡 Worker not subscribing to any queues (consumeFrom is empty).',\n );\n }\n\n for (const queueName of this.consumeFrom) {\n const qualifiedName = resolveTargetQueueName(this.topology, queueName);\n const queueDef = findQueueDefinition(this.topology, queueName);\n\n const subscription = await this.transport.subscribe(\n qualifiedName,\n async (envelope, receipt) => {\n this.shutdownManager.incrementProcessing();\n try {\n const rawMessage = this.codec.encode(envelope);\n await this.pipeline.process(rawMessage, receipt);\n } finally {\n this.shutdownManager.decrementProcessing();\n }\n },\n queueDef?.concurrency !== undefined\n ? { concurrency: queueDef.concurrency }\n : undefined,\n );\n\n this.subscriptions.push(subscription);\n }\n\n this.started = true;\n }\n\n /**\n * Sends an event to all registered subscribers.\n *\n * @example\n * ```typescript\n * // Pass the event class and data directly\n * await matador.send(UserCreatedEvent, { userId: '123' });\n *\n * // Or pass an event instance\n * const event = new UserCreatedEvent({ userId: '123' });\n * await matador.send(event);\n * ```\n */\n async send<T>(\n eventClass: EventClass<T>,\n data: T,\n options?: EventOptions,\n ): Promise<SendResult>;\n async send<T>(event: Event<T>, options?: EventOptions): Promise<SendResult>;\n async send<T>(\n eventOrClass: Event<T> | EventClass<T>,\n dataOrOptions?: T | EventOptions,\n maybeOptions?: EventOptions,\n ): Promise<SendResult> {\n if (!this.started) {\n throw new NotStartedError('send');\n }\n\n if (!this.shutdownManager.isEnqueueAllowed) {\n throw new ShutdownInProgressError();\n }\n\n // Determine if first arg is an event instance or event class\n const isEventClass =\n typeof eventOrClass === 'function' && 'key' in eventOrClass;\n\n if (isEventClass) {\n // Called as: send(EventClass, data, options?)\n const eventClass = eventOrClass as EventClass<T>;\n const data = dataOrOptions as T;\n const options = maybeOptions;\n const event = new eventClass(data);\n const result = await this.fanout.send(eventClass, event, options);\n if (result.errors.length > 0)\n throw new SomeSendError(result.eventKey, result.errors);\n return result;\n }\n // Called as: send(event, options?)\n const event = eventOrClass as Event<T>;\n const options = dataOrOptions as EventOptions | undefined;\n const eventClass = event.constructor as EventClass<T>;\n const result = await this.fanout.send(eventClass, event, options);\n if (result.errors.length > 0)\n throw new SomeSendError(result.eventKey, result.errors);\n return result;\n }\n\n /**\n * Gets current handler state.\n */\n getHandlersState(): HandlersState {\n return this.shutdownManager.getHandlersState();\n }\n\n /**\n * Checks if Matador is idle (no processing or enqueuing).\n */\n isIdle(): boolean {\n return this.shutdownManager.getHandlersState().isIdle;\n }\n\n /**\n * Waits for all handlers to become idle.\n */\n async waitForIdle(timeoutMs = 30000): Promise<boolean> {\n const deadline = Date.now() + timeoutMs;\n\n while (!this.isIdle()) {\n if (Date.now() > deadline) {\n return false;\n }\n await new Promise((resolve) => setTimeout(resolve, 100));\n }\n\n return true;\n }\n\n /**\n * Stops receiving new messages without performing full shutdown.\n * After calling this, no new messages will be delivered from RabbitMQ.\n * The transport remains connected for later shutdown.\n *\n * Use this when you need to coordinate shutdown across multiple systems:\n * 1. Call stopReceiving() to stop new message delivery\n * 2. Wait for both Matador and your other systems to idle\n * 3. Call shutdown() to disconnect (or let NestJS lifecycle handle it)\n *\n * @returns true if receiving was stopped, false if not started or already stopped\n */\n async stopReceiving(): Promise<boolean> {\n if (!this.started) {\n return false;\n }\n\n return this.shutdownManager.publicStopReceiving();\n }\n\n /**\n * Gracefully shuts down Matador.\n */\n async shutdown(): Promise<void> {\n if (!this.started) {\n return;\n }\n\n this.fanout.dispose();\n await this.shutdownManager.shutdown();\n this.started = false;\n }\n\n /**\n * Checks if transport is connected.\n */\n isConnected(): boolean {\n return this.transport.isConnected();\n }\n\n private async unsubscribeAll(): Promise<void> {\n for (const subscription of this.subscriptions) {\n await (subscription.pauseForShutdown ?? subscription.unsubscribe)();\n }\n this.subscriptions.length = 0;\n }\n}\n","import type { DeliveryMode } from '../types/index.js';\n\n/**\n * Describes the native capabilities of a transport.\n * Matador adapts its behavior based on these capabilities.\n */\nexport interface TransportCapabilities {\n /**\n * Delivery semantics the transport supports.\n * - 'at-least-once': Ack after processing (may redeliver on failure)\n * - 'at-most-once': Ack before processing (no redelivery, may lose messages)\n */\n readonly deliveryModes: readonly DeliveryMode[];\n\n /**\n * Transport can delay message delivery natively.\n * - true: Use transport's native delay (BullMQ, RabbitMQ with plugin)\n * - false: Matador handles via retry queue with TTL or external scheduler\n */\n readonly delayedMessages: boolean;\n\n /**\n * Transport can route failed messages to dead-letter queue natively.\n * - 'native': Transport handles DL routing (RabbitMQ DLX)\n * - 'manual': Matador must send() to DLQ then complete() original\n * - 'none': No DL support, Matador logs and discards\n */\n readonly deadLetterRouting: 'native' | 'manual' | 'none';\n\n /**\n * Transport tracks delivery/attempt count natively.\n * - true: Receipt includes accurate attemptNumber from transport\n * - false: Matador tracks attempts in envelope.docket.attempts field\n */\n readonly attemptTracking: boolean;\n\n /**\n * How transport handles concurrency.\n * - 'prefetch': Channel-based prefetch (RabbitMQ)\n * - 'worker': Worker concurrency setting (BullMQ)\n * - 'partition': Partition-based parallelism (Kafka)\n * - 'none': No concurrency control (Memory)\n */\n readonly concurrencyModel: 'prefetch' | 'worker' | 'partition' | 'none';\n\n /**\n * Message ordering guarantees.\n * - 'none': No ordering guarantee (most transports with multiple consumers)\n * - 'queue': Ordered within queue (single consumer scenarios)\n * - 'partition': Ordered within partition/key (Kafka)\n */\n readonly ordering: 'none' | 'queue' | 'partition';\n\n /**\n * Transport supports message priority.\n * - true: Higher priority messages processed first\n * - false: FIFO only\n */\n readonly priorities: boolean;\n}\n\n/**\n * Checks if the transport supports a specific delivery mode.\n */\nexport function supportsDeliveryMode(\n capabilities: TransportCapabilities,\n mode: DeliveryMode,\n): boolean {\n return capabilities.deliveryModes.includes(mode);\n}\n\n/**\n * Checks if the transport supports native delayed messages.\n */\nexport function supportsDelayedMessages(\n capabilities: TransportCapabilities,\n): boolean {\n return capabilities.delayedMessages;\n}\n\n/**\n * Checks if the transport has native dead-letter routing.\n */\nexport function hasNativeDeadLetter(\n capabilities: TransportCapabilities,\n): boolean {\n return capabilities.deadLetterRouting === 'native';\n}\n","/**\n * Connection state machine states.\n */\nexport type ConnectionState =\n | { readonly status: 'disconnected' }\n | { readonly status: 'connecting'; readonly attempt: number }\n | { readonly status: 'connected' }\n | {\n readonly status: 'reconnecting';\n readonly attempt: number;\n readonly lastError: Error;\n }\n | { readonly status: 'failed'; readonly error: Error };\n\n/**\n * Configuration for the connection manager.\n */\nexport interface ConnectionManagerConfig {\n /** Maximum reconnection attempts before giving up (0 = infinite) */\n readonly maxReconnectAttempts: number;\n\n /** Initial delay between reconnection attempts (ms) */\n readonly initialReconnectDelay: number;\n\n /** Maximum delay between reconnection attempts (ms) */\n readonly maxReconnectDelay: number;\n\n /** Backoff multiplier for reconnection delay */\n readonly backoffMultiplier: number;\n\n /** Heartbeat interval for connection health (ms), optional */\n readonly heartbeatInterval?: number;\n}\n\n/**\n * Default configuration values.\n */\nexport const defaultConnectionConfig: ConnectionManagerConfig = {\n maxReconnectAttempts: 0, // Infinite\n initialReconnectDelay: 1000,\n maxReconnectDelay: 30000,\n backoffMultiplier: 2,\n};\n\n/**\n * Callback for state change notifications.\n */\nexport type StateChangeCallback = (state: ConnectionState) => void;\n\n/**\n * Function that performs the actual connection.\n */\nexport type ConnectFn = () => Promise<void>;\n\n/**\n * Function that performs disconnection.\n */\nexport type DisconnectFn = () => Promise<void>;\n\n/**\n * Manages connection lifecycle with automatic reconnection.\n */\nexport class ConnectionManager {\n private _state: ConnectionState = { status: 'disconnected' };\n private readonly listeners: Set<StateChangeCallback> = new Set();\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n private readonly config: ConnectionManagerConfig;\n\n constructor(\n private readonly connectFn: ConnectFn,\n private readonly disconnectFn: DisconnectFn,\n config: Partial<ConnectionManagerConfig> = {},\n ) {\n this.config = { ...defaultConnectionConfig, ...config };\n }\n\n /**\n * Current connection state.\n */\n get state(): ConnectionState {\n return this._state;\n }\n\n /**\n * Whether currently connected.\n */\n isConnected(): boolean {\n return this._state.status === 'connected';\n }\n\n /**\n * Register a callback for connection state changes.\n */\n onStateChange(callback: StateChangeCallback): () => void {\n this.listeners.add(callback);\n return () => this.listeners.delete(callback);\n }\n\n /**\n * Attempt to establish connection.\n */\n async connect(): Promise<void> {\n if (this._state.status === 'connected') {\n return;\n }\n\n this.setState({ status: 'connecting', attempt: 1 });\n\n try {\n await this.connectFn();\n this.setState({ status: 'connected' });\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n await this.handleConnectionFailure(err, 1);\n }\n }\n\n /**\n * Gracefully disconnect.\n */\n async disconnect(): Promise<void> {\n this.clearReconnectTimer();\n\n if (this._state.status === 'disconnected') {\n return;\n }\n\n try {\n await this.disconnectFn();\n } finally {\n this.setState({ status: 'disconnected' });\n }\n }\n\n /**\n * Called by transport when connection is lost unexpectedly.\n */\n async handleConnectionLost(error: Error): Promise<void> {\n if (this._state.status === 'disconnected') {\n return;\n }\n\n this.setState({ status: 'reconnecting', attempt: 1, lastError: error });\n await this.attemptReconnect(1);\n }\n\n /**\n * Calculate delay for a given attempt using exponential backoff.\n */\n calculateDelay(attempt: number): number {\n const delay =\n this.config.initialReconnectDelay *\n this.config.backoffMultiplier ** (attempt - 1);\n return Math.min(delay, this.config.maxReconnectDelay);\n }\n\n private setState(state: ConnectionState): void {\n this._state = state;\n for (const listener of this.listeners) {\n try {\n listener(state);\n } catch {\n // Ignore listener errors\n }\n }\n }\n\n private async handleConnectionFailure(\n error: Error,\n attempt: number,\n ): Promise<void> {\n if (this.shouldGiveUp(attempt)) {\n this.setState({ status: 'failed', error });\n throw error;\n }\n\n this.setState({\n status: 'reconnecting',\n attempt: attempt + 1,\n lastError: error,\n });\n await this.attemptReconnect(attempt + 1);\n }\n\n private shouldGiveUp(attempt: number): boolean {\n return (\n this.config.maxReconnectAttempts > 0 &&\n attempt >= this.config.maxReconnectAttempts\n );\n }\n\n private async attemptReconnect(attempt: number): Promise<void> {\n const delay = this.calculateDelay(attempt);\n\n await new Promise<void>((resolve) => {\n this.reconnectTimer = setTimeout(resolve, delay);\n });\n\n if (this._state.status === 'disconnected') {\n return;\n }\n\n try {\n await this.connectFn();\n this.setState({ status: 'connected' });\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n await this.handleConnectionFailure(err, attempt);\n }\n }\n\n private clearReconnectTimer(): void {\n if (this.reconnectTimer !== null) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n }\n}\n","import {\n LocalTransportNoActiveSubscriberError,\n TransportNotConnectedError,\n} from '../../errors/index.js';\nimport { type Logger, consoleLogger } from '../../hooks/index.js';\nimport type { Topology } from '../../topology/types.js';\nimport { resolveQueueName } from '../../topology/types.js';\nimport type { Envelope } from '../../types/index.js';\nimport type { TransportCapabilities } from '../capabilities.js';\nimport type {\n MessageHandler,\n MessageReceipt,\n SendOptions,\n SubscribeOptions,\n Subscription,\n Transport,\n} from '../transport.js';\n\n/**\n * Capabilities of the LocalTransport.\n */\nconst localCapabilities: TransportCapabilities = {\n deliveryModes: ['at-least-once', 'at-most-once'],\n delayedMessages: true, // Implemented with setTimeout\n deadLetterRouting: 'manual',\n attemptTracking: false,\n concurrencyModel: 'none',\n ordering: 'queue',\n priorities: false,\n};\n\n/**\n * Internal message structure for the local queue.\n */\ninterface QueuedMessage {\n readonly envelope: Envelope;\n readonly id: string;\n completed: boolean;\n}\n\n/**\n * Internal subscription structure.\n */\ninterface ActiveSubscription {\n readonly handler: MessageHandler;\n readonly options: SubscribeOptions;\n active: boolean;\n}\n\n/**\n * Maximum number of completed message receipts to retain.\n * Oldest receipts are dropped once this limit is exceeded\n */\nconst MAX_COMPLETED_MESSAGES = 1000;\n\n/**\n * Local in-memory transport for testing and fallback.\n * Messages are stored in memory and delivered synchronously.\n */\nexport class LocalTransport implements Transport {\n readonly name = 'local';\n readonly capabilities = localCapabilities;\n\n private connected = false;\n private readonly queues = new Map<string, Map<string, QueuedMessage>>();\n private readonly subscriptions = new Map<string, ActiveSubscription[]>();\n private readonly completedMessages: MessageReceipt[] = [];\n private readonly delayedTimers = new Set<ReturnType<typeof setTimeout>>();\n private messageIdCounter = 0;\n private readonly logger: Logger;\n\n constructor(logger?: Logger) {\n this.logger = logger ?? consoleLogger;\n }\n\n async connect(): Promise<void> {\n this.connected = true;\n }\n\n async disconnect(): Promise<void> {\n // Cancel all delayed message timers\n for (const timer of this.delayedTimers) {\n clearTimeout(timer);\n }\n this.delayedTimers.clear();\n\n // Deactivate all subscriptions\n for (const subs of this.subscriptions.values()) {\n for (const sub of subs) {\n sub.active = false;\n }\n }\n\n this.connected = false;\n }\n\n isConnected(): boolean {\n return this.connected;\n }\n\n async applyTopology(topology: Topology): Promise<void> {\n if (!this.connected) {\n throw new TransportNotConnectedError(this.name, 'applyTopology');\n }\n\n // Initialize queues for the topology.\n // Note: Retry queues are not pre-created here because LocalTransport handles\n // retries by re-enqueueing messages with a delay to the original queue, matching\n // how the pipeline schedules retries via transport.send() with a delay option.\n for (const queueDef of topology.queues) {\n const queueName = resolveQueueName(\n topology.namespace,\n queueDef,\n topology.naming,\n topology.prefix,\n );\n if (!this.queues.has(queueName)) {\n this.queues.set(queueName, new Map());\n }\n }\n }\n\n async send(\n queue: string,\n envelope: Envelope,\n options?: SendOptions,\n ): Promise<Transport['name']> {\n if (!this.connected) {\n throw new TransportNotConnectedError(this.name, 'send');\n }\n\n // Handle delayed messages (non-blocking, like real transports)\n if (options?.delay !== undefined && options.delay > 0) {\n this.scheduleDelayedMessage(queue, envelope, options.delay);\n return this.name;\n }\n\n await this.enqueue(queue, envelope);\n return this.name;\n }\n\n /**\n * Schedules a message for delayed delivery.\n * Returns immediately (non-blocking) to match real transport behavior.\n */\n private scheduleDelayedMessage(\n queue: string,\n envelope: Envelope,\n delayMs: number,\n ): void {\n const timer = setTimeout(() => {\n this.delayedTimers.delete(timer);\n // Fire and forget - errors are logged in enqueue/deliverToSubscribers\n this.enqueue(queue, envelope).catch((error) => {\n this.logger.error(\n '[Matador] 🔴 Failed to enqueue delayed message',\n error,\n );\n });\n }, delayMs);\n this.delayedTimers.add(timer);\n }\n\n private async enqueue(queue: string, envelope: Envelope): Promise<void> {\n const subs = this.subscriptions.get(queue);\n if (!subs || subs.length === 0) {\n throw new LocalTransportNoActiveSubscriberError(queue);\n }\n\n await this.storeAndDeliver(queue, envelope);\n }\n\n /**\n * Stores a message and delivers it to any active subscribers, without\n * requiring one to be present. Dead-letter queues are meant to hold\n * messages for later manual inspection, so they don't need a live consumer.\n */\n private async storeAndDeliver(\n queue: string,\n envelope: Envelope,\n ): Promise<void> {\n const messages = this.getOrCreateQueue(queue);\n const messageId = `${++this.messageIdCounter}`;\n\n const queuedMessage: QueuedMessage = {\n envelope,\n id: messageId,\n completed: false,\n };\n\n messages.set(messageId, queuedMessage);\n\n await this.deliverToSubscribers(queue, queuedMessage);\n }\n\n private async deliverToSubscribers(\n queue: string,\n message: QueuedMessage,\n ): Promise<void> {\n const subs = this.subscriptions.get(queue) ?? [];\n\n for (const sub of subs) {\n if (!sub.active || message.completed) continue;\n\n const receipt: MessageReceipt = {\n handle: message,\n redelivered: false,\n attemptNumber: message.envelope.docket.attempts,\n deliveryCount: message.envelope.docket.attempts,\n sourceQueue: queue,\n sourceTransport: this.name,\n };\n\n try {\n await sub.handler(message.envelope, receipt);\n } catch (error) {\n // Handler errors should be caught in the pipeline\n this.logger.error(\n '[Matador] 🔴 Handler error in message processing',\n error,\n );\n }\n }\n }\n\n async subscribe(\n queue: string,\n handler: MessageHandler,\n options: SubscribeOptions = {},\n ): Promise<Subscription> {\n if (!this.connected) {\n throw new TransportNotConnectedError(this.name, 'subscribe');\n }\n\n const subscription: ActiveSubscription = {\n handler,\n options,\n active: true,\n };\n\n const subs = this.subscriptions.get(queue) ?? [];\n subs.push(subscription);\n this.subscriptions.set(queue, subs);\n\n // Deliver any pending messages\n const messages = this.queues.get(queue)?.values() ?? [];\n for (const message of messages) {\n if (message.completed) continue;\n await this.deliverToSubscribers(queue, message);\n }\n\n return {\n unsubscribe: async () => {\n subscription.active = false;\n const remaining = subs.filter((s) => s !== subscription);\n if (remaining.length > 0) {\n this.subscriptions.set(queue, remaining);\n } else {\n this.subscriptions.delete(queue);\n }\n },\n // No-op: LocalTransport is only ever fed from within the process\n // So, when shutting down, it needs to continue and handle new messages until the end\n // As, an ongoing message (before shutdown) could create new (local) messages\n pauseForShutdown: async () => {},\n get isActive() {\n return subscription.active;\n },\n };\n }\n\n async complete(receipt: MessageReceipt): Promise<void> {\n const message = receipt.handle as QueuedMessage;\n message.completed = true;\n this.completedMessages.push(receipt);\n if (this.completedMessages.length > MAX_COMPLETED_MESSAGES) {\n this.completedMessages.shift();\n }\n\n this.queues.get(receipt.sourceQueue)?.delete(message.id);\n }\n\n async sendToDeadLetter(\n receipt: MessageReceipt,\n dlqName: string,\n envelope: Envelope,\n _reason: string,\n ): Promise<void> {\n const dlqQueueName = `${receipt.sourceQueue}.${dlqName}`;\n await this.storeAndDeliver(dlqQueueName, envelope);\n await this.complete(receipt);\n }\n\n // Test helpers\n\n /**\n * Gets the current size of a queue.\n */\n getQueueSize(queue: string): number {\n return this.queues.get(queue)?.size ?? 0;\n }\n\n /**\n * Gets all completed message receipts.\n */\n getCompleted(): readonly MessageReceipt[] {\n return this.completedMessages;\n }\n\n /**\n * Gets pending (uncompleted) messages from a queue.\n */\n getPendingMessages(queue: string): readonly Envelope[] {\n const messages = this.queues.get(queue);\n if (!messages) return [];\n return Array.from(messages.values()).map((m) => m.envelope);\n }\n\n /**\n * Clears all state (for test isolation).\n */\n clear(): void {\n this.queues.clear();\n this.subscriptions.clear();\n this.completedMessages.length = 0;\n this.messageIdCounter = 0;\n\n for (const timer of this.delayedTimers) {\n clearTimeout(timer);\n }\n this.delayedTimers.clear();\n }\n\n /**\n * Receives one message from the queue without a subscription.\n * Useful for testing.\n */\n async receiveOne(\n queue: string,\n ): Promise<{ envelope: Envelope; receipt: MessageReceipt } | null> {\n const messages = this.queues.get(queue);\n if (!messages) return null;\n\n const pending = messages.values().next().value;\n if (!pending) return null;\n\n const receipt: MessageReceipt = {\n handle: pending,\n redelivered: false,\n attemptNumber: pending.envelope.docket.attempts,\n deliveryCount: pending.envelope.docket.attempts,\n sourceQueue: queue,\n sourceTransport: this.name,\n };\n\n return { envelope: pending.envelope, receipt };\n }\n\n private getOrCreateQueue(queue: string): Map<string, QueuedMessage> {\n let messages = this.queues.get(queue);\n if (!messages) {\n messages = new Map();\n this.queues.set(queue, messages);\n }\n return messages;\n }\n}\n","import { AllTransportsFailedError } from '../../errors/index.js';\nimport type { TransportFallbackContext } from '../../hooks/index.js';\nimport type { Topology } from '../../topology/types.js';\nimport type { Envelope } from '../../types/index.js';\nimport type { TransportCapabilities } from '../capabilities.js';\nimport type {\n MessageHandler,\n MessageReceipt,\n SendOptions,\n SubscribeOptions,\n Subscription,\n Transport,\n} from '../transport.js';\n\n/**\n * Symbol key used to store the source transport on wrapped receipts.\n */\nconst SOURCE_TRANSPORT = Symbol('sourceTransport');\n\n/**\n * Extracts the source transport from a tagged receipt.\n */\nfunction getSourceTransport(receipt: MessageReceipt): Transport | undefined {\n return (receipt as unknown as Record<symbol, Transport | undefined>)[\n SOURCE_TRANSPORT\n ];\n}\n\n/**\n * Configuration for MultiTransport.\n */\nexport interface MultiTransportConfig {\n /**\n * Ordered list of transports.\n * First transport is primary, rest are used as fallbacks when primary fails\n * (if fallback is enabled), or can be explicitly selected via the getDesiredBackend hook.\n */\n readonly transports: readonly Transport[];\n\n /**\n * Whether to automatically try fallback transports when the primary/selected fails.\n * When true (default), send() will try each transport in order until one succeeds.\n * When false, send() will only use the selected transport and throw immediately on failure.\n *\n * @default true\n */\n readonly fallbackEnabled?: boolean;\n}\n\n/**\n * Hooks for MultiTransport.\n */\nexport interface MultiTransportHooks {\n /**\n * Hook to dynamically select which backend to use.\n * Return the transport name (e.g., 'local', 'rabbitmq') or undefined to use primary.\n *\n * @example\n * ```typescript\n * getDesiredBackend: async () => {\n * if (process.env.SANDBOX === 'true') return 'local';\n * const backend = await runtimeConfig.get('events.backend');\n * return backend || 'rabbitmq';\n * }\n * ```\n */\n readonly getDesiredBackend?: () =>\n | string\n | undefined\n | Promise<string | undefined>;\n\n /**\n * Called when a fallback transport is used successfully after the selected one fails.\n * Only called when fallbackEnabled is true.\n */\n readonly onEnqueueFallback?: (context: TransportFallbackContext) => void;\n}\n\n/**\n * Computes merged capabilities from multiple transports.\n * Uses the most restrictive/conservative interpretation.\n */\nfunction mergeCapabilities(\n transports: readonly Transport[],\n): TransportCapabilities {\n const primary = transports[0];\n if (!primary) {\n throw new Error('At least one transport is required');\n }\n\n // For multi-transport scenarios, we use primary's capabilities since that's\n // what we'll use for subscriptions and most operations\n return primary.capabilities;\n}\n\n/**\n * A transport wrapper that manages multiple transports.\n *\n * Features:\n * - All transports are connected upfront\n * - send() tries transports in order until one succeeds (fallback behavior)\n * - Specific transport can be selected via getDesiredBackend hook\n * - Subscriptions are created on ALL transports\n *\n * @example\n * ```typescript\n * const transport = new MultiTransport(\n * { transports: [rabbitMQTransport, localTransport] },\n * { onEnqueueFallback: (ctx) => console.warn(`Fallback to ${ctx.nextTransport}`) },\n * );\n * ```\n */\nexport class MultiTransport implements Transport {\n readonly name: string;\n readonly capabilities: TransportCapabilities;\n readonly primary: Transport;\n\n /** All available transports, in order of preference (primary first). */\n readonly transports: readonly Transport[];\n\n /** Whether fallback to secondary transports is enabled. */\n readonly fallbackEnabled: boolean;\n\n private readonly hooks: MultiTransportHooks;\n private connected = false;\n\n constructor(config: MultiTransportConfig, hooks: MultiTransportHooks = {}) {\n const primary = config.transports[0];\n if (!primary) {\n throw new Error('At least one transport is required');\n }\n\n this.primary = primary;\n this.transports = config.transports;\n this.fallbackEnabled = config.fallbackEnabled ?? true;\n this.hooks = hooks;\n this.name = `multi(${this.transports.map((t) => t.name).join(',')})`;\n this.capabilities = mergeCapabilities(this.transports);\n }\n\n async connect(): Promise<void> {\n // Connect all transports in parallel\n await Promise.all(this.transports.map((t) => t.connect()));\n this.connected = true;\n }\n\n async disconnect(): Promise<void> {\n // Disconnect all transports in parallel\n await Promise.all(this.transports.map((t) => t.disconnect()));\n this.connected = false;\n }\n\n isConnected(): boolean {\n // Consider connected if primary is connected\n return this.connected && this.primary.isConnected();\n }\n\n /**\n * Registers a callback to fire each time the transport successfully (re)connects\n * @param callback - The callback to fire when the transport successfully (re)connects\n * @returns A function to unsubscribe from the callback\n */\n onConnected(callback: () => void): () => void {\n // This adds the callback on all transports that support it, and returns functions to unsubscribe from all transports\n const unsubFunctions = this.transports\n .map((t) => t.onConnected?.(callback))\n .filter(Boolean) as (() => void)[];\n\n // Return a function to unsubscribe from all transports\n return () => {\n for (const unsub of unsubFunctions) {\n unsub();\n }\n };\n }\n\n async applyTopology(topology: Topology): Promise<void> {\n // Apply topology to all transports so they're all ready\n await Promise.all(this.transports.map((t) => t.applyTopology(topology)));\n }\n\n async send(\n queue: string,\n envelope: Envelope,\n options?: SendOptions,\n ): Promise<Transport['name']> {\n // Determine which transport to use\n const selectedTransport = await this.selectTransport();\n\n // If fallback is disabled, only use selected transport\n if (!this.fallbackEnabled) {\n return selectedTransport.send(queue, envelope, options);\n }\n\n // Build transport order: selected first, then others\n const transportOrder = this.getTransportOrder(selectedTransport);\n\n const errors: Error[] = [];\n\n for (let i = 0; i < transportOrder.length; i++) {\n const transport = transportOrder[i];\n if (!transport) continue;\n try {\n return await transport.send(queue, envelope, options);\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n errors.push(err);\n\n // Notify about fallback before trying next transport\n const nextTransport = transportOrder[i + 1];\n if (nextTransport && this.hooks.onEnqueueFallback) {\n this.hooks.onEnqueueFallback({\n envelope,\n queue,\n failedTransport: transport.name,\n nextTransport: nextTransport.name,\n error: err,\n });\n }\n // Continue to next transport\n }\n }\n\n // All transports failed\n throw new AllTransportsFailedError(queue, errors);\n }\n\n /**\n * Selects the transport to use based on the getDesiredBackend hook.\n */\n private async selectTransport(): Promise<Transport> {\n if (!this.hooks.getDesiredBackend) {\n return this.primary;\n }\n\n try {\n const desiredBackend = await this.hooks.getDesiredBackend();\n if (!desiredBackend) {\n return this.primary;\n }\n\n const selected = this.transports.find((t) => t.name === desiredBackend);\n if (selected) {\n return selected;\n }\n\n // Desired backend not found, use primary\n return this.primary;\n } catch {\n // Hook threw, use primary\n return this.primary;\n }\n }\n\n /**\n * Returns transports in order, with the selected transport first.\n */\n private getTransportOrder(selected: Transport): readonly Transport[] {\n if (selected === this.primary) {\n return this.transports;\n }\n\n // Put selected first, then the rest (excluding selected)\n return [selected, ...this.transports.filter((t) => t !== selected)];\n }\n\n async subscribe(\n queue: string,\n handler: MessageHandler,\n options?: SubscribeOptions,\n ): Promise<Subscription> {\n // Subscribe on ALL transports so messages are processed regardless of\n // which transport they were enqueued to\n const subscriptions = await Promise.all(\n this.transports.map((transport) => {\n // Wrap handler to tag receipts with source transport\n const wrappedHandler: MessageHandler = (envelope, receipt) => {\n const taggedReceipt = Object.assign(receipt, {\n [SOURCE_TRANSPORT]: transport,\n });\n return handler(envelope, taggedReceipt);\n };\n return transport.subscribe(queue, wrappedHandler, options);\n }),\n );\n\n return {\n unsubscribe: async () => {\n await Promise.all(subscriptions.map((s) => s.unsubscribe()));\n },\n pauseForShutdown: async () => {\n await Promise.all(\n subscriptions.map((s) => (s.pauseForShutdown ?? s.unsubscribe)()),\n );\n },\n get isActive() {\n return subscriptions.some((s) => s.isActive);\n },\n };\n }\n\n async complete(receipt: MessageReceipt): Promise<void> {\n const transport = getSourceTransport(receipt) ?? this.primary;\n return transport.complete(receipt);\n }\n\n async sendToDeadLetter(\n receipt: MessageReceipt,\n dlqName: string,\n envelope: Envelope,\n reason: string,\n ): Promise<void> {\n const transport = getSourceTransport(receipt) ?? this.primary;\n if (transport.sendToDeadLetter) {\n return transport.sendToDeadLetter(receipt, dlqName, envelope, reason);\n }\n throw new Error('Transport does not support dead letter routing');\n }\n}\n","import type {\n Channel,\n ChannelModel,\n ConfirmChannel,\n ConsumeMessage,\n Options,\n} from 'amqplib';\nimport amqplib from 'amqplib';\nimport { RabbitMQCodec } from '../../codec/rabbitmq-codec.js';\nimport {\n DelayedMessagesNotSupportedError,\n TransportNotConnectedError,\n TransportSendError,\n} from '../../errors/index.js';\nimport { type Logger, consoleLogger } from '../../hooks/index.js';\nimport type { QueueDefinition, Topology } from '../../topology/types.js';\nimport {\n applyPrefix,\n getDeadLetterQueueName,\n getRetryQueueName,\n resolveQueueName,\n} from '../../topology/types.js';\nimport type { Envelope } from '../../types/index.js';\nimport type { TransportCapabilities } from '../capabilities.js';\nimport {\n ConnectionManager,\n type ConnectionManagerConfig,\n} from '../connection-manager.js';\nimport type {\n MessageHandler,\n MessageReceipt,\n SendOptions,\n SubscribeOptions,\n Subscription,\n Transport,\n} from '../transport.js';\n\n/**\n * Configuration options for the RabbitMQ transport.\n */\nexport interface RabbitMQTransportConfig {\n /** RabbitMQ connection URL */\n readonly url: string;\n\n /** Connection name displayed in RabbitMQ management UI */\n readonly connectionName: string;\n\n /** Connection manager configuration */\n readonly connection?: Partial<ConnectionManagerConfig> | undefined;\n\n /** Use quorum queues for durability (default: true) */\n readonly quorumQueues?: boolean | undefined;\n\n /** Default prefetch count per consumer (default: 10) */\n readonly defaultPrefetch?: number | undefined;\n\n /** Enable the delayed message exchange plugin if available (default: true) */\n readonly enableDelayedMessages?: boolean | undefined;\n\n /**\n * How long to wait for the broker to confirm a publish before failing,\n * in milliseconds (default: 5000).\n *\n * Publishes use a confirm channel: `send()` resolves only once the broker\n * acks the message, and rejects on nack or timeout, so callers can await\n * delivery confirmation rather than treating publishes as fire-and-forget.\n */\n readonly publishTimeoutMs?: number | undefined;\n\n /** Logger for transport events (defaults to console) */\n readonly logger?: Logger | undefined;\n}\n\n/**\n * Internal structure for tracking a queue's dedicated channel.\n */\ninterface QueueChannel {\n readonly channel: Channel;\n readonly consumers: ActiveConsumer[];\n}\n\n/**\n * Internal structure for tracking active consumers.\n */\ninterface ActiveConsumer {\n readonly consumerTag: string;\n readonly queue: string;\n active: boolean;\n}\n\n/**\n * Record of a subscribe() call\n * Stored so consumers can be recreated after a reconnect\n */\ninterface SubscriptionIntent {\n readonly queue: string;\n readonly handler: MessageHandler;\n readonly options: SubscribeOptions;\n /** False once the caller has unsubscribed - prevents replay on reconnect */\n active: boolean;\n /** The live consumer for this intent; replaced on each reconnect */\n currentConsumer: ActiveConsumer | null;\n}\n\n/**\n * Redacts credentials from an AMQP URL.\n * Replaces username and password with '****' regardless of their length.\n *\n * @example\n * redactAmqpUrl('amqp://user:pass@host:5672') // 'amqp://****:****@host:5672'\n */\nexport function redactAmqpUrl(url: string): string {\n const regex = /^(amqps?:\\/\\/)[^:]+:[^@]+@/;\n return url.replace(regex, '$1****:****@');\n}\n\n/**\n * RabbitMQ transport implementation using amqplib.\n */\nexport class RabbitMQTransport implements Transport {\n readonly name = 'rabbitmq';\n\n private _capabilities: TransportCapabilities = {\n deliveryModes: ['at-least-once'],\n delayedMessages: false,\n deadLetterRouting: 'native',\n attemptTracking: true,\n concurrencyModel: 'prefetch',\n ordering: 'none',\n priorities: true,\n };\n\n get capabilities(): TransportCapabilities {\n return this._capabilities;\n }\n\n private connection: ChannelModel | null = null;\n private publishChannel: ConfirmChannel | null = null;\n private readonly connectionManager: ConnectionManager;\n private readonly queueChannels = new Map<string, QueueChannel>();\n private readonly subscriptionIntents: SubscriptionIntent[] = [];\n private topology: Topology | null = null;\n private readonly codec = new RabbitMQCodec();\n\n private readonly config: Required<\n Omit<RabbitMQTransportConfig, 'connection' | 'logger'>\n > & {\n readonly connection: Partial<ConnectionManagerConfig>;\n };\n\n private readonly logger: Logger;\n private delayedExchangeAvailable = false;\n\n constructor(config: RabbitMQTransportConfig) {\n this.logger = config.logger ?? consoleLogger;\n this.config = {\n url: config.url,\n connectionName: config.connectionName,\n connection: config.connection ?? {},\n quorumQueues: config.quorumQueues ?? true,\n defaultPrefetch: config.defaultPrefetch ?? 10,\n enableDelayedMessages: config.enableDelayedMessages ?? true,\n publishTimeoutMs: config.publishTimeoutMs ?? 5000,\n };\n\n this.connectionManager = new ConnectionManager(\n () => this.doConnect(),\n () => this.doDisconnect(),\n this.config.connection,\n );\n }\n\n async connect(): Promise<void> {\n await this.connectionManager.connect();\n }\n\n async disconnect(): Promise<void> {\n await this.connectionManager.disconnect();\n }\n\n isConnected(): boolean {\n return this.connectionManager.isConnected();\n }\n\n /**\n * Registers a callback to fire each time the transport (here RabbitMQ) successfully (re)connects\n * @param callback - The callback to fire when the transport (here RabbitMQ) successfully (re)connects\n * @returns A function to unsubscribe from the callback\n */\n onConnected(callback: () => void): () => void {\n return this.connectionManager.onStateChange((state) => {\n if (state.status === 'connected') {\n callback();\n }\n });\n }\n\n async applyTopology(topology: Topology): Promise<void> {\n this.topology = topology;\n\n if (!this.publishChannel) {\n throw new TransportNotConnectedError(this.name, 'applyTopology');\n }\n\n const channel = this.publishChannel;\n\n // Create the main exchange for routing messages to queues\n const mainExchange = this.getMainExchangeName(topology);\n await channel.assertExchange(mainExchange, 'direct', { durable: true });\n\n // Create dead-letter exchange if DLQ is enabled\n const dlxExchange = this.getDLXExchangeName(topology);\n if (\n topology.deadLetter.unhandled.enabled ||\n topology.deadLetter.undeliverable.enabled\n ) {\n await channel.assertExchange(\n dlxExchange,\n topology.naming?.dlxExchangeType ?? 'direct',\n { durable: true },\n );\n }\n\n // Check for delayed message exchange plugin\n if (this.config.enableDelayedMessages) {\n await this.setupDelayedExchange(topology);\n }\n\n // Create work queues\n for (const queueDef of topology.queues) {\n await this.assertWorkQueue(channel, topology, queueDef);\n }\n\n // Create DLQs\n if (topology.deadLetter.unhandled.enabled) {\n await this.assertDeadLetterQueues(channel, topology, 'unhandled');\n }\n\n if (topology.deadLetter.undeliverable.enabled) {\n await this.assertDeadLetterQueues(channel, topology, 'undeliverable');\n }\n }\n\n async send(\n queue: string,\n envelope: Envelope,\n options?: SendOptions,\n ): Promise<Transport['name']> {\n if (!this.publishChannel || !this.topology) {\n throw new TransportNotConnectedError(this.name, 'send');\n }\n\n const encoded = this.codec.encode(envelope);\n const buffer = Buffer.from(encoded.body);\n\n const publishOptions: Options.Publish = {\n persistent: true,\n contentType: encoded.contentType,\n messageId: envelope.id,\n timestamp: Date.now(),\n headers: encoded.headers,\n };\n\n if (options?.priority !== undefined) {\n publishOptions.priority = options.priority;\n }\n\n // Handle delayed messages\n if (options?.delay !== undefined && options.delay > 0) {\n if (!this.delayedExchangeAvailable) {\n throw new DelayedMessagesNotSupportedError(this.name);\n }\n\n const delayedExchange = this.getDelayedExchangeName(this.topology);\n publishOptions.headers = {\n ...publishOptions.headers,\n 'x-delay': options.delay,\n };\n await this.confirmPublish(\n this.publishChannel,\n delayedExchange,\n queue,\n buffer,\n publishOptions,\n );\n return this.name;\n }\n\n // Transport-specific options\n if (options?.transport?.rabbitmq?.expiration !== undefined) {\n publishOptions.expiration = String(options.transport.rabbitmq.expiration);\n }\n\n if (options?.transport?.rabbitmq?.persistent !== undefined) {\n publishOptions.persistent = options.transport.rabbitmq.persistent;\n }\n\n const routingKey = options?.transport?.rabbitmq?.routingKey ?? queue;\n const exchange = this.getMainExchangeName(this.topology);\n\n await this.confirmPublish(\n this.publishChannel,\n exchange,\n routingKey,\n buffer,\n publishOptions,\n );\n return this.name;\n }\n\n async subscribe(\n queue: string,\n handler: MessageHandler,\n options: SubscribeOptions = {},\n ): Promise<Subscription> {\n if (!this.connection || !this.topology) {\n throw new TransportNotConnectedError(this.name, 'subscribe');\n }\n\n const intent: SubscriptionIntent = {\n queue,\n handler,\n options,\n active: true,\n currentConsumer: null,\n };\n\n this.subscriptionIntents.push(intent);\n await this.activateIntent(intent);\n\n const unsubscribe = async (): Promise<void> => {\n intent.active = false;\n\n const idx = this.subscriptionIntents.indexOf(intent);\n if (idx !== -1) this.subscriptionIntents.splice(idx, 1);\n\n const consumer = intent.currentConsumer;\n if (consumer) {\n consumer.active = false;\n const queueChannel = this.queueChannels.get(queue);\n if (queueChannel) {\n try {\n await queueChannel.channel.cancel(consumer.consumerTag);\n } catch {\n // Channel may already be closed\n }\n const cIdx = queueChannel.consumers.indexOf(consumer);\n if (cIdx !== -1) queueChannel.consumers.splice(cIdx, 1);\n if (queueChannel.consumers.length === 0) {\n try {\n await queueChannel.channel.close();\n } catch {\n // Ignore\n }\n this.queueChannels.delete(queue);\n }\n }\n intent.currentConsumer = null;\n }\n };\n\n return {\n unsubscribe,\n // Messages on this transport comes from outside (RabbitMQ), so, when shutting down, we need to unsubscribe directly\n // Otherwise, we could receive traffic forever, and an idle state would never be reached.\n pauseForShutdown: unsubscribe,\n get isActive() {\n return intent.active;\n },\n };\n }\n\n /**\n * Wires a single subscription intent to the current connection.\n * Called once on subscribe() and again after each reconnect.\n */\n private async activateIntent(intent: SubscriptionIntent): Promise<void> {\n const { queue, handler, options } = intent;\n const queueChannel = await this.getOrCreateQueueChannel(queue, options);\n const { channel } = queueChannel;\n\n const consumer: ActiveConsumer = {\n consumerTag: '',\n queue,\n active: true,\n };\n\n const { consumerTag } = await channel.consume(\n queue,\n async (msg: ConsumeMessage | null) => {\n if (!msg || !consumer.active) return;\n\n const attemptNumber = this.getAttemptNumber(msg);\n const receipt: MessageReceipt = {\n handle: { channel, msg },\n redelivered: msg.fields.redelivered,\n attemptNumber,\n deliveryCount: this.getDeliveryCount(msg, attemptNumber),\n sourceQueue: queue,\n sourceTransport: this.name,\n };\n\n try {\n const headers = (msg.properties.headers ?? {}) as Record<\n string,\n unknown\n >;\n const envelope = this.codec.decode(\n new Uint8Array(msg.content),\n headers,\n );\n await handler(envelope, receipt);\n } catch (error) {\n this.logger.error(\n '[Matador] 🔴 Handler error in message processing',\n error,\n );\n }\n },\n { noAck: false },\n );\n\n (consumer as { consumerTag: string }).consumerTag = consumerTag;\n queueChannel.consumers.push(consumer);\n intent.currentConsumer = consumer;\n }\n\n async complete(receipt: MessageReceipt): Promise<void> {\n const { channel, msg } = receipt.handle as {\n channel: Channel;\n msg: ConsumeMessage;\n };\n\n try {\n channel.ack(msg);\n } catch {\n // Channel may be closed, ignore\n }\n }\n\n async sendToDeadLetter(\n receipt: MessageReceipt,\n dlqName: string,\n envelope: Envelope,\n reason: string,\n ): Promise<void> {\n if (!this.publishChannel || !this.topology) {\n throw new TransportNotConnectedError(this.name, 'sendToDeadLetter');\n }\n\n // Add error info to envelope\n const dlqEnvelope: Envelope = {\n ...envelope,\n docket: {\n ...envelope.docket,\n lastError: reason,\n firstError: envelope.docket.firstError ?? reason,\n originalQueue: receipt.sourceQueue,\n },\n };\n\n const encoded = this.codec.encode(dlqEnvelope);\n const buffer = Buffer.from(encoded.body);\n const dlxExchange = this.getDLXExchangeName(this.topology);\n const dlqQueueName = `${receipt.sourceQueue}.${dlqName}`;\n\n const publishOptions: Options.Publish = {\n persistent: true,\n contentType: encoded.contentType,\n messageId: envelope.id,\n timestamp: Date.now(),\n headers: {\n ...encoded.headers,\n 'x-matador-dead-letter-reason': reason,\n },\n };\n\n await this.confirmPublish(\n this.publishChannel,\n dlxExchange,\n dlqQueueName,\n buffer,\n publishOptions,\n );\n\n // Complete the original message\n await this.complete(receipt);\n }\n\n /**\n * Publishes on the confirm channel and resolves once the broker\n * acknowledges the message, rejecting on broker nack, channel error, or\n * after `publishTimeoutMs` elapses without a confirm.\n *\n * Mirrors Matador v1's promise-wrapped amqplib publish callback to give\n * callers confirmed (at-least-once) delivery semantics.\n */\n private confirmPublish(\n channel: ConfirmChannel,\n exchange: string,\n routingKey: string,\n buffer: Buffer,\n options: Options.Publish,\n ): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n let timeout: NodeJS.Timeout | null = setTimeout(() => {\n timeout = null;\n reject(\n new TransportSendError(\n routingKey,\n new Error(\n `Publish not confirmed by broker within ${this.config.publishTimeoutMs}ms`,\n ),\n ),\n );\n }, this.config.publishTimeoutMs);\n\n channel.publish(exchange, routingKey, buffer, options, (err) => {\n if (timeout) {\n clearTimeout(timeout);\n } else {\n // Already timed out and rejected; nothing left to settle.\n return;\n }\n if (err) {\n reject(new TransportSendError(routingKey, err));\n } else {\n resolve();\n }\n });\n });\n }\n\n // Private methods\n\n /**\n * Gets or creates a dedicated channel for a queue subscription.\n *\n * We create separate channels per subscribed queue to enable independent\n * prefetch/concurrency control.\n */\n private async getOrCreateQueueChannel(\n queue: string,\n options: SubscribeOptions,\n ): Promise<QueueChannel> {\n const existing = this.queueChannels.get(queue);\n if (existing) {\n return existing;\n }\n\n if (!this.connection) {\n throw new TransportNotConnectedError(\n this.name,\n 'getOrCreateQueueChannel',\n );\n }\n\n // Create a dedicated channel for this queue to control prefetch independently\n const channel = await this.connection.createChannel();\n\n const prefetch =\n options.transport?.rabbitmq?.prefetch ??\n options.concurrency ??\n this.config.defaultPrefetch ??\n 10;\n\n await channel.prefetch(prefetch);\n\n const queueChannel: QueueChannel = {\n channel,\n consumers: [],\n };\n\n this.queueChannels.set(queue, queueChannel);\n\n return queueChannel;\n }\n\n private async doConnect(): Promise<void> {\n // Close any existing connection before opening a new one\n if (this.connection) {\n try {\n await this.connection.close();\n } catch {\n // Can happen if the connection is already closed\n }\n this.connection = null;\n this.publishChannel = null; // channels belong to the old connection\n }\n\n // Drop stale channel objects so getOrCreateQueueChannel opens fresh ones\n // on the new connection during intent replay below.\n this.queueChannels.clear();\n\n this.logger.info(\n `[Matador] ⏳ Connecting to RabbitMQ at '${redactAmqpUrl(this.config.url)}'.`,\n );\n const connection = await amqplib.connect(this.config.url, {\n clientProperties: { connection_name: this.config.connectionName },\n });\n this.connection = connection;\n\n // Handle connection errors - let ConnectionManager handle reconnection\n connection.on('error', (err: Error) => {\n this.logger.error('[Matador] 🔴 RabbitMQ connection error', err);\n });\n\n connection.on('close', () => {\n // Immediately deactivate all live consumers so any buffered messages\n // delivered on the dying connection are dropped rather than partially\n // processed (handler fires but ack silently fails on the dead channel).\n for (const queueChannel of this.queueChannels.values()) {\n for (const consumer of queueChannel.consumers) {\n consumer.active = false;\n }\n }\n this.connection = null;\n this.publishChannel = null;\n\n if (this.connectionManager.isConnected()) {\n // Unexpected close, trigger reconnection\n this.connectionManager.handleConnectionLost(\n new Error('Connection closed unexpectedly'),\n );\n }\n });\n\n try {\n // A confirm channel so publishes can await broker acknowledgement\n this.publishChannel = await connection.createConfirmChannel();\n\n // Handle publish channel errors to prevent unhandled error events\n this.publishChannel.on('error', (err: Error) => {\n this.logger.error('[Matador] 🔴 RabbitMQ publish channel error', err);\n });\n\n // Re-apply topology if we have one (reconnection scenario)\n if (this.topology) {\n await this.applyTopology(this.topology);\n // Recreate consumers for every active subscription on the new connection.\n for (const intent of this.subscriptionIntents) {\n await this.activateIntent(intent);\n }\n }\n } catch (err) {\n // Setup failed after the connection was opened - close it so that it doesn't leak\n try {\n await connection.close();\n } catch {\n // Ignore errors during cleanup\n }\n this.connection = null;\n this.publishChannel = null;\n throw err;\n }\n\n this.logger.info('[Matador] 🔌 Connected to RabbitMQ');\n }\n\n private async doDisconnect(): Promise<void> {\n // Cancel all consumers and close queue channels\n for (const queueChannel of this.queueChannels.values()) {\n for (const consumer of queueChannel.consumers) {\n consumer.active = false;\n try {\n await queueChannel.channel.cancel(consumer.consumerTag);\n } catch {\n // Ignore errors during cleanup\n }\n }\n try {\n await queueChannel.channel.close();\n } catch {\n // Ignore\n }\n }\n this.queueChannels.clear();\n\n // Close publish channel\n if (this.publishChannel) {\n try {\n await this.publishChannel.close();\n } catch {\n // Ignore\n }\n this.publishChannel = null;\n }\n\n // Close connection\n if (this.connection) {\n try {\n await this.connection.close();\n } catch {\n // Ignore\n }\n this.connection = null;\n }\n\n // Reset capabilities\n this.delayedExchangeAvailable = false;\n this._capabilities = {\n ...this._capabilities,\n delayedMessages: false,\n };\n }\n\n private async setupDelayedExchange(topology: Topology): Promise<void> {\n if (!this.connection) {\n return;\n }\n\n // Default to disabled\n this.delayedExchangeAvailable = false;\n\n const delayedExchange = this.getDelayedExchangeName(topology);\n const connection = this.connection;\n\n // Use a promise-based approach to ensure all error paths resolve cleanly\n // This prevents any error from propagating and affecting other channels\n return new Promise<void>((resolve) => {\n let resolved = false;\n const safeResolve = () => {\n if (!resolved) {\n resolved = true;\n resolve();\n }\n };\n\n connection\n .createChannel()\n .then((probeChannel) => {\n // Handle channel errors - this fires when RabbitMQ closes the channel\n probeChannel.on('error', () => {\n safeResolve();\n });\n\n // Handle channel close\n probeChannel.on('close', () => {\n safeResolve();\n });\n\n // Try to declare a delayed exchange\n // This will fail if the plugin is not installed\n probeChannel\n .assertExchange(delayedExchange, 'x-delayed-message', {\n durable: true,\n arguments: { 'x-delayed-type': 'direct' },\n })\n .then(() => {\n this.delayedExchangeAvailable = true;\n this._capabilities = {\n ...this._capabilities,\n delayedMessages: true,\n };\n this.logger.debug(\n '[Matador] 🔌 Delayed message exchange plugin detected',\n );\n // Close the probe channel gracefully\n probeChannel.close().catch(() => {});\n safeResolve();\n })\n .catch(() => {\n // assertExchange failed - plugin not available\n // Channel is already closed by RabbitMQ, no need to close\n this.logger.warn(\n '[Matador] 🟡 RabbitMQ delayed message exchange plugin not available. ' +\n 'Delayed messages will not be supported.',\n );\n safeResolve();\n });\n })\n .catch(() => {\n // Failed to create channel - shouldn't happen but handle it\n safeResolve();\n });\n });\n }\n\n private buildWorkQueueOptions(\n topology: Topology,\n queueDef: QueueDefinition,\n ): Options.AssertQueue {\n const queueOptions: Options.AssertQueue = {\n durable: true,\n arguments: {} as Record<string, unknown>,\n };\n\n if (this.config.quorumQueues && !queueDef.exact) {\n queueOptions.arguments['x-queue-type'] = 'quorum';\n }\n\n if (\n topology.deadLetter.unhandled.enabled ||\n topology.deadLetter.undeliverable.enabled\n ) {\n queueOptions.arguments['x-dead-letter-exchange'] =\n this.getDLXExchangeName(topology);\n }\n\n if (queueDef.priorities) {\n queueOptions.arguments['x-max-priority'] = 10;\n }\n\n if (queueDef.consumerTimeout) {\n queueOptions.arguments['x-consumer-timeout'] = queueDef.consumerTimeout;\n }\n\n return queueOptions;\n }\n\n private async assertWorkQueue(\n channel: Channel,\n topology: Topology,\n queueDef: QueueDefinition,\n ): Promise<void> {\n const queueName = resolveQueueName(\n topology.namespace,\n queueDef,\n topology.naming,\n topology.prefix,\n );\n\n const rabbitmqOptions = queueDef.transport?.rabbitmq?.options;\n const queueOptions =\n rabbitmqOptions ?? this.buildWorkQueueOptions(topology, queueDef);\n await channel.assertQueue(queueName, queueOptions);\n\n // Bind queue to main exchange\n const mainExchange = this.getMainExchangeName(topology);\n await channel.bindQueue(queueName, mainExchange, queueName);\n\n // Bind to delayed exchange if available\n if (this.delayedExchangeAvailable) {\n const delayedExchange = this.getDelayedExchangeName(topology);\n await channel.bindQueue(queueName, delayedExchange, queueName);\n }\n\n // Create retry queue if retry is enabled.\n // Skip exact:true queues - they are owned by another team (cross-namespace).\n // The retry queue derives its `x-dead-letter-exchange` from\n // `${topology.namespace}.exchange`, which would conflict if multiple\n // namespaces share the broker and the queue. This mirrors the existing\n // `if (queueDef.exact) continue` guard in `assertDeadLetterQueues`.\n if (topology.retry.enabled && !queueDef.exact) {\n await this.assertRetryQueue(channel, topology, queueDef);\n }\n }\n\n private async assertRetryQueue(\n channel: Channel,\n topology: Topology,\n queueDef: QueueDefinition,\n ): Promise<void> {\n const workQueueName = resolveQueueName(\n topology.namespace,\n queueDef,\n topology.naming,\n topology.prefix,\n );\n const retryQueueName = getRetryQueueName(\n topology.namespace,\n queueDef.name,\n topology.naming,\n topology.prefix,\n );\n const mainExchange = this.getMainExchangeName(topology);\n\n const retryQueueOptions: Options.AssertQueue = {\n durable: true,\n arguments: {\n 'x-dead-letter-exchange': mainExchange,\n 'x-dead-letter-routing-key': workQueueName,\n 'x-message-ttl': topology.retry.defaultDelayMs,\n } as Record<string, unknown>,\n };\n\n if (this.config.quorumQueues) {\n retryQueueOptions.arguments['x-queue-type'] = 'quorum';\n }\n\n await channel.assertQueue(retryQueueName, retryQueueOptions);\n await channel.bindQueue(retryQueueName, mainExchange, retryQueueName);\n }\n\n private async assertDeadLetterQueues(\n channel: Channel,\n topology: Topology,\n dlqType: 'unhandled' | 'undeliverable',\n ): Promise<void> {\n const dlxExchange = this.getDLXExchangeName(topology);\n const dlConfig = topology.deadLetter[dlqType];\n\n for (const queueDef of topology.queues) {\n if (queueDef.exact) continue;\n\n const dlqName = getDeadLetterQueueName(\n topology.namespace,\n queueDef.name,\n dlqType,\n topology.naming,\n topology.prefix,\n );\n\n const dlqOptions: Options.AssertQueue = {\n durable: true,\n arguments: {} as Record<string, unknown>,\n };\n\n if (dlConfig.maxLength) {\n dlqOptions.arguments['x-max-length'] = dlConfig.maxLength;\n }\n\n // DLQs follow the same quorum setting as work and retry queues, so a\n // broker node restart does not take the queue (and its messages) down\n // with it.\n if (this.config.quorumQueues) {\n dlqOptions.arguments['x-queue-type'] = 'quorum';\n }\n\n await channel.assertQueue(dlqName, dlqOptions);\n await channel.bindQueue(dlqName, dlxExchange, dlqName);\n }\n }\n\n private getMainExchangeName(topology: Topology): string {\n return (\n topology.naming?.mainExchange?.(topology.namespace) ??\n applyPrefix(topology.prefix, `${topology.namespace}.exchange`)\n );\n }\n\n private getDLXExchangeName(topology: Topology): string {\n return (\n topology.naming?.dlxExchange?.(topology.namespace) ??\n applyPrefix(topology.prefix, `${topology.namespace}.dlx`)\n );\n }\n\n private getDelayedExchangeName(topology: Topology): string {\n return (\n topology.naming?.delayedExchange?.(topology.namespace) ??\n applyPrefix(topology.prefix, `${topology.namespace}.delayed`)\n );\n }\n\n private getAttemptNumber(msg: ConsumeMessage): number {\n const headerValue = msg.properties.headers?.['x-matador-attempts'];\n if (typeof headerValue === 'number') {\n return headerValue;\n }\n // Check for x-death header (native DLX redelivery count)\n const xDeath = msg.properties.headers?.['x-death'];\n if (Array.isArray(xDeath) && xDeath.length > 0) {\n const deathCount = xDeath.reduce(\n (sum: number, death: { count?: number }) => sum + (death.count ?? 0),\n 0,\n );\n return deathCount + 1;\n }\n return 1;\n }\n\n /**\n * Gets the native delivery count for poison message detection.\n * This tracks how many times the message was delivered without acknowledgment,\n * which helps detect crash loops.\n */\n private getDeliveryCount(msg: ConsumeMessage, attemptNumber: number): number {\n // Check for explicit delivery count header (some RabbitMQ setups track this)\n const deliveryCount = msg.properties.headers?.['x-delivery-count'];\n if (typeof deliveryCount === 'number') {\n return deliveryCount;\n }\n\n // Check x-death header for dead-letter redelivery count\n const xDeath = msg.properties.headers?.['x-death'];\n if (Array.isArray(xDeath) && xDeath.length > 0) {\n const deathCount = xDeath.reduce(\n (sum: number, death: { count?: number }) => sum + (death.count ?? 0),\n 0,\n );\n // Add 1 because we're currently being delivered again\n return deathCount + 1;\n }\n\n // If redelivered flag is set but no other tracking, count as 2 (first + this delivery)\n if (msg.fields.redelivered) {\n return Math.max(2, attemptNumber);\n }\n\n // Default to attempt number\n return attemptNumber;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/errors/has-description.ts","../src/errors/retry-errors.ts","../src/errors/matador-errors.ts","../src/errors/checkpoint-errors.ts","../src/topology/types.ts","../src/topology/builder.ts","../src/types/common.ts","../src/types/envelope.ts","../src/types/event.ts","../src/types/subscriber.ts","../src/core/fanout.ts","../src/hooks/types.ts","../src/hooks/safe-hooks.ts","../src/core/shutdown.ts","../src/codec/codec.ts","../src/codec/json-codec.ts","../src/codec/rabbitmq-codec.ts","../src/checkpoint/context.ts","../src/checkpoint/stores/memory.ts","../src/checkpoint/stores/noop.ts","../src/pipeline/pipeline.ts","../src/retry/standard-policy.ts","../src/schema/types.ts","../src/schema/registry.ts","../src/core/matador.ts","../src/transport/capabilities.ts","../src/transport/connection-manager.ts","../src/transport/local/local-transport.ts","../src/transport/multi/multi-transport.ts","../src/transport/rabbitmq/rabbitmq-transport.ts"],"names":["assert","error","decision","eventClass","options","event","result","amqplib"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Interface for errors that provide a human-readable description.\n * The description explains what the error means and what actions\n * users should take when encountering it in logs/observability.\n */\nexport interface HasDescription {\n /**\n * Human-readable description of the error type.\n * Intended for logging and observability to help users understand\n * the error and determine appropriate remediation steps.\n */\n readonly description: string;\n}\n\n/**\n * Type guard to check if an error implements HasDescription.\n */\nexport function hasDescription(error: unknown): error is HasDescription {\n return (\n typeof error === 'object' &&\n error !== null &&\n 'description' in error &&\n typeof (error as HasDescription).description === 'string'\n );\n}\n","import assert from 'node:assert';\nimport type { Envelope } from '../types/envelope.js';\n\n/**\n * Base class for retry control errors.\n * These errors control the retry behavior of message processing.\n */\nexport abstract class RetryControlError extends Error {\n /**\n * Error class name for monitoring tools.\n */\n declare readonly name: string;\n\n /**\n * Human-readable description of the error and recommended actions.\n */\n abstract readonly description: string;\n\n constructor(message: string) {\n super(message);\n this.name = this.constructor.name;\n // Ensure name is preserved when serialized\n Object.defineProperty(this, 'name', {\n value: this.constructor.name,\n enumerable: true,\n configurable: false,\n writable: false,\n });\n }\n\n /**\n * Returns a serializable representation for logging/monitoring.\n */\n toJSON(): Record<string, unknown> {\n return {\n name: this.name,\n message: this.message,\n description: this.description,\n stack: this.stack,\n };\n }\n}\n\n/**\n * Forces retry regardless of subscriber idempotency setting.\n * Use when you know the operation is safe to retry.\n *\n * ACTION: Check subscriber code to understand why retry was forced.\n * This overrides default retry behavior based on idempotency settings.\n */\nexport class DoRetry extends RetryControlError {\n readonly description =\n 'A subscriber explicitly requested retry by throwing DoRetry. ' +\n 'ACTION: Check the subscriber code to understand why retry was forced. ' +\n 'This overrides the default retry behavior based on idempotency settings.';\n\n constructor(message = 'Forced retry requested') {\n super(message);\n }\n}\n\n/**\n * Prevents retry regardless of subscriber idempotency setting.\n * Use for permanent failures that should not be retried.\n *\n * ACTION: Check subscriber code to understand why retry was disabled.\n * Typically used for permanent failures like invalid data or business rule violations.\n */\nexport class DontRetry extends RetryControlError {\n readonly description =\n 'A subscriber explicitly prevented retry by throwing DontRetry. ' +\n 'ACTION: Check the subscriber code to understand why retry was disabled. ' +\n 'Typically used for permanent failures like invalid data or business rule violations. ' +\n 'The message will be sent to the dead-letter queue for manual review.';\n\n constructor(message = 'Retry explicitly disabled') {\n super(message);\n }\n}\n\n/**\n * Thrown by `assertEvent` in the event of a failed assertion.\n *\n * This error indicates that an event was in an unexpected state when it reached the subscriber.\n * Throwing this error will indicate to Matador NOT to retry the event - it will be sent\n * directly to the undeliverable dead-letter queue.\n *\n * Use `assertEvent` in your subscribers to assert properties about an event payload.\n * This is useful in scenarios where you would expect an event payload to contain a field\n * based on the types, but something unexpected caused it to not be present.\n *\n * @see assertEvent\n */\nexport class EventAssertionError extends Error {\n declare readonly name: string;\n\n readonly description =\n 'Thrown to indicate that an event was in an unexpected state when it reached the subscriber. ' +\n 'Throwing this error will indicate to Matador NOT to retry the event. ' +\n 'Matador does not throw this error directly - it is thrown by assertEvent, which you can ' +\n 'use in your subscribers to assert properties about an event. ' +\n 'This can be useful in scenarios where you would expect an event payload to contain a field ' +\n 'based on the types, but something unexpected caused it to not be present. ' +\n 'Using this instead of the NodeJS assert allows Matador to not retry the event subscriber.';\n\n /** The envelope that failed the assertion */\n readonly envelope: Envelope<unknown>;\n\n constructor(envelope: Envelope<unknown>, message: string) {\n super(message);\n this.name = 'EventAssertionError';\n this.envelope = envelope;\n Object.defineProperty(this, 'name', {\n value: 'EventAssertionError',\n enumerable: true,\n configurable: false,\n writable: false,\n });\n }\n\n toJSON(): Record<string, unknown> {\n return {\n name: this.name,\n message: this.message,\n description: this.description,\n envelope: this.envelope,\n stack: this.stack,\n };\n }\n}\n\n/**\n * Checks if an error forces a retry.\n */\nexport function isDoRetry(error: unknown): error is DoRetry {\n return error instanceof DoRetry;\n}\n\n/**\n * Checks if an error prevents retry.\n */\nexport function isDontRetry(error: unknown): error is DontRetry {\n return error instanceof DontRetry;\n}\n\n/**\n * Checks if an error is an assertion error (never retry).\n */\nexport function isAssertionError(error: unknown): error is EventAssertionError {\n return error instanceof EventAssertionError;\n}\n\n/**\n * Same as Node.js `assert`, but throws an `EventAssertionError` if the assertion fails.\n *\n * `EventAssertionError`s thrown within a subscriber do not cause the subscriber to be retried.\n * The event will be delivered to the undeliverable dead-letter queue instead.\n *\n * @see https://nodejs.org/api/assert.html#assertvalue-message\n * @param envelope - The envelope this assertion relates to.\n * @param value - The value to assert. If falsy, the assertion fails.\n * @param message - The message to include in the error if the assertion fails.\n * @throws {EventAssertionError} If the assertion fails.\n *\n * @example\n * ```typescript\n * const subscriber = createSubscriber<MyEvent>({\n * name: 'my-subscriber',\n * description: 'Processes MyEvent',\n * callback: async (envelope) => {\n * // Assert that userId exists - if not, event goes to DLQ without retry\n * assertEvent(envelope, envelope.data.userId, 'userId is required');\n * // ... rest of processing\n * },\n * });\n * ```\n */\nexport function assertEvent(\n envelope: Envelope<unknown>,\n value: unknown,\n message: string,\n): asserts value {\n try {\n assert(value, message);\n } catch {\n throw new EventAssertionError(envelope, message);\n }\n}\n","/**\n * Base class for all Matador errors.\n * All errors have a unique name that appears in monitoring tools (e.g., DataDog)\n * and a description explaining the error and actions to resolve it.\n *\n * The `name` property is automatically set to the class name for proper\n * identification in error monitoring and logging systems.\n */\nexport abstract class MatadorError extends Error {\n /**\n * Error class name (e.g., \"NotStartedError\", \"TransportNotConnectedError\").\n * This is preserved during serialization for error monitoring tools.\n */\n declare readonly name: string;\n\n /**\n * Human-readable description explaining what went wrong and\n * what ACTION the user should take to resolve the issue.\n */\n abstract readonly description: string;\n\n constructor(message: string) {\n super(message);\n this.name = this.constructor.name;\n // Ensure name is preserved when serialized\n Object.defineProperty(this, 'name', {\n value: this.constructor.name,\n enumerable: true,\n configurable: false,\n writable: false,\n });\n }\n\n /**\n * Returns a serializable representation for logging/monitoring.\n */\n toJSON(): Record<string, unknown> {\n return {\n name: this.name,\n message: this.message,\n description: this.description,\n stack: this.stack,\n };\n }\n}\n\n// ============================================================================\n// Lifecycle Errors\n// ============================================================================\n\n/**\n * Thrown when attempting to use Matador before calling start().\n */\nexport class NotStartedError extends MatadorError {\n readonly description =\n 'Matador has not been started. ' +\n 'ACTION: Call matador.start() before dispatching events or performing other operations. ' +\n 'Ensure start() completes successfully before using other methods.';\n\n constructor(operation = 'operation') {\n super(\n `Cannot perform ${operation}: Matador has not been started. Call start() first.`,\n );\n }\n}\n\n/**\n * Thrown when attempting to dispatch events during shutdown.\n */\nexport class ShutdownInProgressError extends MatadorError {\n readonly description =\n 'Matador is shutting down and will not accept new events. ' +\n 'ACTION: Do not dispatch events after calling shutdown(). ' +\n 'If you need to send events, do so before initiating shutdown. ' +\n 'Consider implementing a pre-shutdown event flush if needed.';\n\n constructor() {\n super('Cannot dispatch events: Matador is shutting down.');\n }\n}\n\n// ============================================================================\n// Transport Errors\n// ============================================================================\n\n/**\n * Thrown when a transport operation is attempted but the transport is not connected.\n */\nexport class TransportNotConnectedError extends MatadorError {\n readonly description =\n 'The transport is not connected to the message broker. ' +\n 'ACTION: Ensure the transport is connected by calling transport.connect() or matador.start(). ' +\n 'Check that the broker (e.g., RabbitMQ) is running and accessible. ' +\n 'Verify connection settings (URL, credentials, network access).';\n\n constructor(\n public readonly transportName: string,\n operation = 'operation',\n ) {\n super(\n `Cannot perform ${operation}: Transport \"${transportName}\" is not connected. Ensure connect() was called and the broker is accessible.`,\n );\n }\n}\n\n/**\n * Thrown when the transport has been closed (during shutdown).\n */\nexport class TransportClosedError extends MatadorError {\n readonly description =\n 'The transport has been closed and will not accept new operations. ' +\n 'ACTION: This typically occurs during application shutdown. ' +\n 'If unexpected, check for early shutdown triggers. ' +\n 'Events sent after transport closure will be lost.';\n\n constructor(public readonly transportName: string) {\n super(\n `Transport \"${transportName}\" has been closed and will not accept new operations.`,\n );\n }\n}\n\n/**\n * Thrown when all transports in a fallback chain fail.\n */\nexport class AllTransportsFailedError extends MatadorError {\n readonly description =\n 'All transports failed to send the message. ' +\n 'ACTION: Check the health of all configured transports (primary and fallbacks). ' +\n 'Review the errors array for specific failure reasons. ' +\n 'Ensure at least one transport is properly configured and reachable. ' +\n 'Consider adding a LocalTransport as a last-resort fallback.';\n\n constructor(\n public readonly queue: string,\n public readonly errors: readonly Error[],\n ) {\n super(\n `All transports failed to send message to queue \"${queue}\". ` +\n `Errors: ${errors.map((e) => e.message).join('; ')}`,\n );\n }\n}\n\n/**\n * Thrown when sending a message to the transport fails.\n */\nexport class TransportSendError extends MatadorError {\n readonly description =\n 'Failed to send a message through the transport. ' +\n 'ACTION: Check the underlying error for details. Common causes: ' +\n '(1) Transport disconnected during send, ' +\n '(2) Network issues between application and broker, ' +\n '(3) Broker rejected the message (size, permissions, queue limits). ' +\n 'The message was NOT delivered and should be retried or logged.';\n\n constructor(\n public readonly queue: string,\n public readonly cause: Error,\n ) {\n super(`Failed to send message to queue \"${queue}\": ${cause.message}`);\n }\n\n override toJSON(): Record<string, unknown> {\n return {\n ...super.toJSON(),\n queue: this.queue,\n cause: {\n name: this.cause.name,\n message: this.cause.message,\n },\n };\n }\n}\n\n/**\n * Thrown when send() completes but one or more subscriber publishes failed.\n * The `errors` array contains per-failure details: subscriber name, target queue, and underlying error.\n */\nexport class SomeSendError extends MatadorError {\n readonly description =\n 'One or more subscriber messages could not be published during send(). ' +\n 'ACTION: Inspect the `errors` array for per-failure details. ' +\n 'Each entry contains the subscriber name, target queue, and underlying error.';\n\n constructor(\n public readonly eventKey: string,\n public readonly errors: ReadonlyArray<{\n subscriberName: string;\n queue: string;\n error: Error;\n }>,\n ) {\n const summary = errors\n .map((e) => `${e.subscriberName} (${e.queue}): ${e.error.message}`)\n .join('; ');\n super(\n `send(\"${eventKey}\") failed for ${errors.length} subscriber(s): ${summary}`,\n );\n }\n}\n\n/**\n * Thrown when delayed messages are requested but the plugin is not available.\n */\nexport class DelayedMessagesNotSupportedError extends MatadorError {\n readonly description =\n 'Delayed messages were requested but the transport does not support them. ' +\n 'ACTION: For RabbitMQ, install the rabbitmq_delayed_message_exchange plugin. ' +\n 'Run: rabbitmq-plugins enable rabbitmq_delayed_message_exchange ' +\n 'Then restart RabbitMQ and reconnect. ' +\n 'Alternatively, remove delayMs from your event options if delays are not required.';\n\n constructor(public readonly transportName: string) {\n super(\n 'Delayed messages require the RabbitMQ delayed message exchange plugin. ' +\n 'Install rabbitmq_delayed_message_exchange or remove delayMs from event options.',\n );\n }\n}\n\n/**\n * Thrown when a LocalTransport is sent a message for a queue with no active\n * subscriber in the current process (e.g. the subscriber is a SubscriberStub\n * implemented in another service, or matador.start() hasn't subscribed yet).\n */\nexport class LocalTransportNoActiveSubscriberError extends MatadorError {\n readonly description =\n 'The LocalTransport has no active subscriber for this queue in the current process, ' +\n 'so it cannot guarantee delivery. ' +\n 'ACTION: If the subscriber is a SubscriberStub (implemented in another service), ' +\n 'the local transport can never deliver it locally — a distributed transport like ' +\n 'RabbitMQ is required. If the subscriber should run in this process, ensure ' +\n 'matador.start() has subscribed to this queue before sending.';\n\n constructor(public readonly queue: string) {\n super(\n `LocalTransport has no active subscriber for queue \"${queue}\"; message cannot be delivered.`,\n );\n }\n}\n\n// ============================================================================\n// Schema & Configuration Errors\n// ============================================================================\n\n/**\n * Thrown when an event is not registered in the schema.\n */\nexport class EventNotRegisteredError extends MatadorError {\n readonly description =\n 'The event type is not registered in the schema. ' +\n 'ACTION: Register the event using matador.register(EventClass, subscribers) before dispatching. ' +\n 'If this occurs during message consumption, it may indicate schema drift between services. ' +\n 'Ensure all services have matching schema registrations for shared events.';\n\n constructor(public readonly eventKey: string) {\n super(\n `Event \"${eventKey}\" is not registered in schema. Register it using matador.register(EventClass, subscribers).`,\n );\n }\n}\n\n/**\n * Thrown when a subscriber is not found for an event.\n */\nexport class SubscriberNotRegisteredError extends MatadorError {\n readonly description =\n 'The subscriber is not registered for this event in the schema. ' +\n 'ACTION: Ensure the subscriber is included in the registration for this event. ' +\n 'This may occur if: (1) The subscriber was removed from the schema but messages still exist, ' +\n '(2) Schema drift between producer and consumer services, ' +\n '(3) A deployment is in progress with different schema versions. ' +\n 'Check the dead-letter queue for affected messages.';\n\n constructor(\n public readonly subscriberName: string,\n public readonly eventKey?: string,\n ) {\n super(\n `Subscriber \"${subscriberName}\" is not registered${eventKey ? ` for event \"${eventKey}\"` : ''}. Check schema registration.`,\n );\n }\n}\n\n/**\n * Thrown when no subscribers exist for an event during fanout.\n */\nexport class NoSubscribersExistError extends MatadorError {\n readonly description =\n 'The event has no subscribers registered. ' +\n 'ACTION: Register at least one subscriber for this event type. ' +\n 'If subscribers were intentionally removed, consider also removing the event dispatch. ' +\n 'Events without subscribers are not useful and may indicate configuration issues.';\n\n constructor(public readonly eventKey: string) {\n super(\n `No subscribers registered for event \"${eventKey}\". Add subscribers using matador.register(EventClass, [subscriber1, subscriber2]).`,\n );\n }\n}\n\n/**\n * Thrown when the schema configuration is invalid.\n */\nexport class InvalidSchemaError extends MatadorError {\n readonly description =\n 'The schema configuration is invalid. ' +\n 'ACTION: Review the schema registration for issues. Common problems: ' +\n '(1) Duplicate subscriber names for the same event, ' +\n '(2) Missing required fields on event class (key, description), ' +\n '(3) Invalid alias configuration. ' +\n 'Check the cause property for specific details.';\n\n constructor(\n message: string,\n public readonly cause?: string,\n ) {\n super(`Invalid schema: ${message}${cause ? `. Cause: ${cause}` : ''}`);\n }\n}\n\n/**\n * Thrown when a subscriber is a stub but is being processed locally.\n */\nexport class SubscriberIsStubError extends MatadorError {\n readonly description =\n 'A SubscriberStub was registered in a consuming schema. ' +\n 'ACTION: SubscriberStubs should only be used in producer schemas to declare ' +\n 'that a subscriber exists in another service. ' +\n 'In the consumer service, provide a full Subscriber with a callback function. ' +\n 'Remove the stub from the consumer schema and add the actual implementation.';\n\n constructor(public readonly subscriberName: string) {\n super(\n `Subscriber \"${subscriberName}\" is a stub and cannot be processed locally. Replace with a full Subscriber implementation in the consumer schema.`,\n );\n }\n}\n\n// ============================================================================\n// Queue Errors\n// ============================================================================\n\n/**\n * Thrown when a subscriber's `targetQueue` or a `consumeFrom` entry references\n * a queue that was never declared in the topology.\n */\nexport class UnknownQueueReferenceError extends MatadorError {\n readonly description =\n 'A queue was referenced that is not declared in the topology. ' +\n 'Matador only routes to queues it knows about; an unknown reference would ' +\n 'otherwise be silently namespace-qualified and published to a queue nobody ' +\n 'consumes, losing the message. ' +\n 'ACTION: Declare the queue on the topology before referencing it. ' +\n 'For a Matador-owned queue use `.addQueue(name)`; for a foreign queue owned ' +\n 'by another service use `.addQueue({ name, exact: true })` so it is routed ' +\n 'to verbatim.';\n\n constructor(public readonly queueName: string) {\n super(\n `Queue reference \"${queueName}\" is not declared in the topology. Add it via .addQueue(name), or .addQueue({ name, exact: true }) for a foreign queue.`,\n );\n }\n}\n\n/**\n * Thrown when a queue is not found or not created.\n */\nexport class QueueNotFoundError extends MatadorError {\n readonly description =\n 'The specified queue does not exist or has not been created. ' +\n 'ACTION: Ensure the queue is defined in the topology configuration. ' +\n 'Call transport.applyTopology() or matador.start() to create queues. ' +\n 'Check that the queue name matches the topology definition.';\n\n constructor(public readonly queueName: string) {\n super(\n `Queue \"${queueName}\" not found. Ensure it is defined in topology and applyTopology() was called.`,\n );\n }\n}\n\n// ============================================================================\n// Event Validation Errors\n// ============================================================================\n\n/**\n * Thrown when an event is invalid or malformed.\n */\nexport class InvalidEventError extends MatadorError {\n readonly description =\n 'The event is invalid or missing required fields. ' +\n 'ACTION: Ensure the event has all required properties. ' +\n 'Common issues: missing targetSubscriber during processing, ' +\n 'null/undefined data when the event type requires data, ' +\n 'malformed event structure from codec decode failure.';\n\n constructor(\n message: string,\n public readonly cause?: string,\n ) {\n super(`Invalid event: ${message}${cause ? `. Cause: ${cause}` : ''}`);\n }\n}\n\n// ============================================================================\n// Message Processing Errors\n// ============================================================================\n\n/**\n * Thrown when a message has been redelivered too many times (poison message).\n */\nexport class MessageMaybePoisonedError extends MatadorError {\n readonly description =\n 'A message was redelivered multiple times without successful processing. ' +\n 'This usually indicates the message causes a crash or timeout during processing. ' +\n 'ACTION: (1) Check application logs for errors/crashes during message processing, ' +\n '(2) Inspect the message in the dead-letter queue for malformed data, ' +\n '(3) Review the subscriber code for bugs that cause crashes, ' +\n '(4) Consider increasing processing timeout if the operation is legitimately slow. ' +\n 'This message will NOT be retried to prevent crash loops.';\n\n constructor(\n public readonly eventId: string,\n public readonly deliveryCount: number,\n public readonly maxDeliveries: number,\n ) {\n super(\n `Message \"${eventId}\" delivered ${deliveryCount} times (max: ${maxDeliveries}). Possible poison message - will not be retried.`,\n );\n }\n}\n\n/**\n * Thrown when a non-idempotent message cannot be retried after redelivery.\n */\nexport class IdempotentMessageCannotRetryError extends MatadorError {\n readonly description =\n 'A non-idempotent subscriber received a redelivered message. ' +\n 'Retrying would risk duplicate side effects (e.g., double payments, duplicate emails). ' +\n 'ACTION: (1) Mark the subscriber as idempotent if it safely handles duplicates, ' +\n '(2) Implement idempotency keys in the subscriber logic, ' +\n '(3) Manually inspect and replay the message from the dead-letter queue after verification. ' +\n 'The message will be sent to the dead-letter queue for manual review.';\n\n constructor(\n public readonly eventId: string,\n public readonly subscriberName: string,\n ) {\n super(\n `Non-idempotent subscriber \"${subscriberName}\" cannot retry redelivered message \"${eventId}\". Mark subscriber as idempotent='yes' or implement idempotency handling.`,\n );\n }\n}\n\n// ============================================================================\n// Timeout Errors\n// ============================================================================\n\n/**\n * Thrown when an operation times out.\n */\nexport class TimeoutError extends MatadorError {\n readonly description =\n 'An operation timed out before completing. ' +\n 'ACTION: (1) Increase the timeout if the operation legitimately needs more time, ' +\n '(2) Optimize the operation to complete faster, ' +\n '(3) Check for deadlocks or blocking operations, ' +\n '(4) Verify external service dependencies are responsive.';\n\n constructor(\n public readonly operation: string,\n public readonly timeoutMs: number,\n ) {\n super(`Operation \"${operation}\" timed out after ${timeoutMs}ms.`);\n }\n}\n\n// ============================================================================\n// Type Guards\n// ============================================================================\n\nexport function isMatadorError(error: unknown): error is MatadorError {\n return error instanceof MatadorError;\n}\n\nexport function isNotStartedError(error: unknown): error is NotStartedError {\n return error instanceof NotStartedError;\n}\n\nexport function isTransportNotConnectedError(\n error: unknown,\n): error is TransportNotConnectedError {\n return error instanceof TransportNotConnectedError;\n}\n\nexport function isEventNotRegisteredError(\n error: unknown,\n): error is EventNotRegisteredError {\n return error instanceof EventNotRegisteredError;\n}\n\nexport function isSubscriberNotRegisteredError(\n error: unknown,\n): error is SubscriberNotRegisteredError {\n return error instanceof SubscriberNotRegisteredError;\n}\n\nexport function isUnknownQueueReferenceError(\n error: unknown,\n): error is UnknownQueueReferenceError {\n return error instanceof UnknownQueueReferenceError;\n}\n\nexport function isMessageMaybePoisonedError(\n error: unknown,\n): error is MessageMaybePoisonedError {\n return error instanceof MessageMaybePoisonedError;\n}\n\nexport function isIdempotentMessageCannotRetryError(\n error: unknown,\n): error is IdempotentMessageCannotRetryError {\n return error instanceof IdempotentMessageCannotRetryError;\n}\n","import { MatadorError } from './matador-errors.js';\n\n/**\n * Thrown when a duplicate io() key is used within a single subscriber execution.\n * Each io() call must have a unique key to prevent cache collisions.\n */\nexport class DuplicateIoKeyError extends MatadorError {\n readonly description =\n 'The same io() key was used multiple times in a single subscriber execution. ' +\n 'Each io() call must have a unique key to ensure correct checkpoint behavior. ' +\n 'ACTION: Ensure all io() keys are unique within the subscriber. ' +\n 'For dynamic operations (e.g., loops), include a unique identifier in the key ' +\n '(e.g., `process-item-${item.id}`).';\n\n constructor(\n public readonly key: string,\n public readonly subscriberName: string,\n ) {\n super(\n `Duplicate io key \"${key}\" in subscriber \"${subscriberName}\". Each io() call must have a unique key.`,\n );\n }\n}\n\n/**\n * Thrown when checkpoint store operations fail.\n */\nexport class CheckpointStoreError extends MatadorError {\n readonly description =\n 'A checkpoint store operation failed. This may cause issues with resumable subscribers. ' +\n 'ACTION: Check the underlying storage system (Redis, etc.) for connectivity issues. ' +\n 'The subscriber may re-execute operations that were already completed.';\n\n constructor(\n public readonly operation: 'get' | 'set' | 'delete',\n public readonly envelopeId: string,\n public readonly cause: Error,\n ) {\n super(\n `Checkpoint store ${operation} failed for envelope \"${envelopeId}\": ${cause.message}`,\n );\n }\n}\n\n/**\n * Type guard for DuplicateIoKeyError.\n */\nexport function isDuplicateIoKeyError(\n error: unknown,\n): error is DuplicateIoKeyError {\n return error instanceof DuplicateIoKeyError;\n}\n\n/**\n * Type guard for CheckpointStoreError.\n */\nexport function isCheckpointStoreError(\n error: unknown,\n): error is CheckpointStoreError {\n return error instanceof CheckpointStoreError;\n}\n","import { UnknownQueueReferenceError } from '../errors/matador-errors.js';\n\n/**\n * A prefix prepended to every default-derived broker resource name so\n * Matador-managed queues and exchanges are identifiable\n * (e.g. `matador.{namespace}.{queue}`).\n *\n * A string is prepended as `${prefix}.`; `null` or `undefined` disables\n * prefixing. Only applies to default names — a {@link TopologyNaming}\n * override fully owns its output and is never prefixed.\n *\n * @example 'matador'\n */\nexport type ResourcePrefix = string | null | undefined;\n\n/**\n * Transport-agnostic topology definition.\n * Matador owns the topology; transports translate and apply it.\n */\nexport interface Topology {\n /** Namespace prefix for all queues */\n readonly namespace: string;\n\n /** Work queues for processing events */\n readonly queues: readonly QueueDefinition[];\n\n /** Dead-letter queue configuration */\n readonly deadLetter: DeadLetterConfig;\n\n /** Retry queue configuration */\n readonly retry: RetryConfig;\n\n /**\n * Optional overrides for how broker resource names are derived.\n * Intended for migrations: lets an adopter keep pre-existing queue and\n * exchange names (e.g. from Matador v1) so a rolling deploy keeps using\n * the broker resources already in place.\n */\n readonly naming?: TopologyNaming | undefined;\n\n /**\n * Prefix prepended to every default-derived broker resource name so\n * Matador-managed queues and exchanges are identifiable\n * (e.g. `matador.{namespace}.{queue}`).\n *\n * `null` disables prefixing. Only applies to default names — a `naming`\n * override fully owns its output and is never prefixed.\n *\n * Topologies built via {@link TopologyBuilder} default this to `'matador'`.\n * When absent (e.g. a hand-built topology literal) no prefix is applied.\n *\n * @default 'matador'\n */\n readonly prefix?: ResourcePrefix;\n}\n\n/**\n * Strategy for deriving broker resource names.\n *\n * Each builder receives the namespace as an explicit argument and returns the\n * final name, so the namespace is always an input to the strategy — it is\n * never applied separately on top of the result. Provide only the builders you\n * want to override; the rest keep Matador's defaults:\n * - work queue: `${namespace}.${queueName}`\n * - main exchange: `${namespace}.exchange`\n * - dead-letter exchange: `${namespace}.dlx`\n * - delayed exchange: `${namespace}.delayed`\n *\n * Retry queues and DLQs have no builder of their own: they are derived from the\n * work-queue name (`<queue>.retry`, `<queue>.unhandled`, `<queue>.undeliverable`),\n * so overriding `queue` carries your prefix into them automatically.\n *\n * Intended for migrations: an adopter can keep pre-existing names (e.g. from\n * Matador v1) so a rolling deploy keeps using the broker resources already in\n * place instead of draining or dual-consuming.\n *\n * @example Keep Matador v1 names (`matador.{namespace}.{queue}`):\n * ```typescript\n * TopologyBuilder.create()\n * .withNamespace('myapp')\n * .withNaming({\n * queue: (ns, q) => `matador.${ns}.${q}`,\n * mainExchange: (ns) => `matador.${ns}`,\n * dlxExchange: (ns) => `matador.${ns}.dlx-undeliverable`,\n * dlxExchangeType: 'topic',\n * delayedExchange: (ns) => `matador.${ns}.delayed`,\n * })\n * ```\n */\nexport interface TopologyNaming {\n /**\n * Builds the qualified work-queue name from the namespace and queue name.\n * Retry queues and DLQs are derived from the result automatically\n * (`<queue>.retry`, `<queue>.unhandled`, `<queue>.undeliverable`).\n * Default builds `${namespace}.${queueName}`.\n */\n readonly queue?:\n | ((namespace: string, queueName: string) => string)\n | undefined;\n\n /** Builds the main exchange name. Default builds `${namespace}.exchange`. */\n readonly mainExchange?: ((namespace: string) => string) | undefined;\n\n /** Builds the dead-letter exchange name. Default builds `${namespace}.dlx`. */\n readonly dlxExchange?: ((namespace: string) => string) | undefined;\n\n /**\n * Exchange type used when asserting the dead-letter exchange.\n * Useful when an existing DLX was declared as `topic` — asserting it as\n * `direct` would fail with PRECONDITION_FAILED. Literal (non-wildcard)\n * binding keys behave identically on a topic exchange.\n * Default: `'direct'`.\n */\n readonly dlxExchangeType?: 'direct' | 'topic' | undefined;\n\n /** Builds the delayed-message exchange name. Default builds `${namespace}.delayed`. */\n readonly delayedExchange?: ((namespace: string) => string) | undefined;\n}\n\n/**\n * Individual queue definition.\n */\nexport interface QueueDefinition {\n /** Queue name (will be prefixed with namespace unless exact: true) */\n readonly name: string;\n\n /** Concurrency for this queue */\n readonly concurrency?: number | undefined;\n\n /** Consumer timeout in milliseconds */\n readonly consumerTimeout?: number | undefined;\n\n /** Enable priority support if transport allows */\n readonly priorities?: boolean | undefined;\n\n /**\n * Restricts the queue to one active consumer at a time.\n *\n * Only RabbitMQ supports this option, with the `x-single-active-consumer`\n * argument. Other transports ignore the option. RabbitMQ also ignores the\n * option when you set a custom `transport.rabbitmq.options` override on the\n * queue.\n *\n * With `concurrency: 1`, RabbitMQ delivers the queue in order, one message\n * at a time, to the active consumer.\n *\n * @default false\n */\n readonly singleActiveConsumer?: boolean | undefined;\n\n /**\n * When true, the queue name is used exactly as provided without any\n * modification. The namespace prefix will NOT be added, and no other\n * transformations will be applied. Use this for referencing external\n * queues that are not managed by Matador.\n */\n readonly exact?: boolean | undefined;\n\n /** Transport-specific queue options */\n readonly transport?: TransportQueueOptions | undefined;\n}\n\n/**\n * Transport-specific queue options.\n * Each transport can define its own options under its transport name key.\n */\nexport interface TransportQueueOptions {\n /** RabbitMQ-specific queue options */\n readonly rabbitmq?: RabbitMQQueueDefinition | undefined;\n}\n\n/**\n * RabbitMQ-specific queue definition options.\n */\nexport interface RabbitMQQueueDefinition {\n /**\n * Exact RabbitMQ queue assertion options.\n * When provided, these options completely replace all auto-computed defaults\n * (durable, x-queue-type, x-dead-letter-exchange, etc.).\n */\n readonly options?: RabbitMQQueueOptions | undefined;\n}\n\n/**\n * RabbitMQ queue assertion options.\n * Maps to amqplib's Options.AssertQueue.\n */\nexport interface RabbitMQQueueOptions {\n /** Queue survives broker restart */\n readonly durable?: boolean | undefined;\n\n /** Queue is deleted when last consumer unsubscribes */\n readonly autoDelete?: boolean | undefined;\n\n /** Queue can only be used by the declaring connection */\n readonly exclusive?: boolean | undefined;\n\n /** Exchange to which dead-lettered messages are sent */\n readonly deadLetterExchange?: string | undefined;\n\n /** Routing key for dead-lettered messages */\n readonly deadLetterRoutingKey?: string | undefined;\n\n /** Message TTL in milliseconds */\n readonly messageTtl?: number | undefined;\n\n /** Queue expires after this many milliseconds of non-use */\n readonly expires?: number | undefined;\n\n /** Maximum number of messages in the queue */\n readonly maxLength?: number | undefined;\n\n /** Maximum priority level (0-255) */\n readonly maxPriority?: number | undefined;\n\n /** Additional x-* arguments for RabbitMQ */\n readonly arguments?: Record<string, unknown> | undefined;\n}\n\n/**\n * Dead-letter queue configuration.\n */\nexport interface DeadLetterConfig {\n /** Unhandled events (schema mismatch) queue */\n readonly unhandled: DeadLetterQueueConfig;\n\n /** Undeliverable events (permanent failures) queue */\n readonly undeliverable: DeadLetterQueueConfig;\n}\n\n/**\n * Configuration for a specific dead-letter queue.\n */\nexport interface DeadLetterQueueConfig {\n /** Whether this DLQ is enabled */\n readonly enabled: boolean;\n\n /** Maximum number of messages in the DLQ */\n readonly maxLength?: number | undefined;\n}\n\n/**\n * Retry queue configuration.\n */\nexport interface RetryConfig {\n /** Enable retry queue with delay */\n readonly enabled: boolean;\n\n /** Default retry delay in milliseconds */\n readonly defaultDelayMs: number;\n\n /** Maximum retry delay in milliseconds */\n readonly maxDelayMs: number;\n}\n\n/**\n * Prepends a resource-name prefix unless it is disabled.\n * `null`/`undefined` mean no prefix; a string is prepended as `${prefix}.`.\n */\nexport function applyPrefix(prefix: ResourcePrefix, name: string): string {\n return prefix == null ? name : `${prefix}.${name}`;\n}\n\n/**\n * Gets the fully qualified work-queue name.\n * An optional naming strategy may override how the name is derived; otherwise\n * the default is `${namespace}.${queueName}`, optionally prefixed.\n */\nexport function getQualifiedQueueName(\n namespace: string,\n queueName: string,\n naming?: TopologyNaming,\n prefix?: ResourcePrefix,\n): string {\n return (\n naming?.queue?.(namespace, queueName) ??\n applyPrefix(prefix, `${namespace}.${queueName}`)\n );\n}\n\n/**\n * Gets the dead-letter queue name for a given queue.\n */\nexport function getDeadLetterQueueName(\n namespace: string,\n queueName: string,\n dlqType: 'unhandled' | 'undeliverable',\n naming?: TopologyNaming,\n prefix?: ResourcePrefix,\n): string {\n return `${getQualifiedQueueName(namespace, queueName, naming, prefix)}.${dlqType}`;\n}\n\n/**\n * Gets the retry queue name for a given queue.\n */\nexport function getRetryQueueName(\n namespace: string,\n queueName: string,\n naming?: TopologyNaming,\n prefix?: ResourcePrefix,\n): string {\n return `${getQualifiedQueueName(namespace, queueName, naming, prefix)}.retry`;\n}\n\n/**\n * Resolves the actual queue name for a given queue definition.\n * When exact: true, returns name as-is. Otherwise, returns the\n * namespace-qualified name (honoring any naming overrides and prefix).\n */\nexport function resolveQueueName(\n namespace: string,\n queueDef: QueueDefinition,\n naming?: TopologyNaming,\n prefix?: ResourcePrefix,\n): string {\n if (queueDef.exact) {\n return queueDef.name;\n }\n return getQualifiedQueueName(namespace, queueDef.name, naming, prefix);\n}\n\n/**\n * Finds the queue definition a local queue reference points at.\n */\nexport function findQueueDefinition(\n topology: Topology,\n queueName: string,\n): QueueDefinition | undefined {\n return topology.queues.find((q) => q.name === queueName);\n}\n\n/**\n * Resolves a local queue reference (a subscriber's `targetQueue` or a\n * `consumeFrom` entry) to the transport-level queue name.\n *\n * The reference must be declared in the topology via `.addQueue(...)`:\n * an exact queue resolves to its name as-is; a Matador-owned queue is\n * namespace-qualified (honoring any naming overrides). An undeclared\n * reference throws {@link UnknownQueueReferenceError} rather than being\n * silently qualified and routed to a queue nobody consumes.\n *\n * @throws UnknownQueueReferenceError if `queueName` is not in `topology.queues`.\n */\nexport function resolveTargetQueueName(\n topology: Topology,\n queueName: string,\n): string {\n const def = findQueueDefinition(topology, queueName);\n if (def === undefined) {\n throw new UnknownQueueReferenceError(queueName);\n }\n if (def.exact) {\n return def.name;\n }\n return getQualifiedQueueName(\n topology.namespace,\n queueName,\n topology.naming,\n topology.prefix,\n );\n}\n","import type { HasDescription } from '../errors/index.js';\nimport type {\n DeadLetterConfig,\n QueueDefinition,\n ResourcePrefix,\n RetryConfig,\n Topology,\n TopologyNaming,\n} from './types.js';\n\n/**\n * Options for adding a queue.\n * Excludes 'name' as that is provided as the first argument to addQueue.\n */\nexport type QueueOptions = Omit<QueueDefinition, 'name'>;\n\n/**\n * Type guard to check if the argument is a QueueDefinition object.\n */\nfunction isQueueDefinition(\n arg: string | QueueDefinition,\n): arg is QueueDefinition {\n return typeof arg === 'object' && arg !== null && 'name' in arg;\n}\n\n/**\n * Error thrown when topology validation fails.\n */\nexport class TopologyValidationError extends Error implements HasDescription {\n readonly description =\n 'The topology configuration is invalid. Check the issues array for ' +\n 'specific validation failures such as missing namespace, invalid queue ' +\n 'names, or conflicting settings. This error occurs during Matador ' +\n 'initialization and must be fixed in the configuration.';\n\n constructor(\n message: string,\n public readonly issues: readonly string[],\n ) {\n super(message);\n this.name = 'TopologyValidationError';\n }\n}\n\n/**\n * Fluent builder for creating Topology configurations.\n */\nexport class TopologyBuilder {\n /**\n * Creates a new TopologyBuilder instance.\n */\n static create(): TopologyBuilder {\n return new TopologyBuilder();\n }\n\n private namespace = '';\n private queues: QueueDefinition[] = [];\n private deadLetter: DeadLetterConfig = {\n unhandled: { enabled: true },\n undeliverable: { enabled: true },\n };\n private retry: RetryConfig = {\n enabled: true,\n defaultDelayMs: 1000,\n maxDelayMs: 300000, // 5 minutes\n };\n private naming: TopologyNaming | undefined;\n private prefix: ResourcePrefix = 'matador';\n\n /**\n * Sets the namespace prefix for all queues.\n */\n withNamespace(namespace: string): this {\n this.namespace = namespace;\n return this;\n }\n\n /**\n * Sets the prefix prepended to every default-derived broker resource name\n * (e.g. `matador.{namespace}.{queue}`), so Matador-managed queues and\n * exchanges are identifiable. Pass `null` to disable prefixing.\n *\n * Only applies to default names — a {@link withNaming} override fully owns\n * its output and is never prefixed.\n *\n * Pass `null` or `undefined` to disable prefixing.\n *\n * @default 'matador'\n * @example\n * TopologyBuilder.create().withNamespace('myapp') // matador.myapp.events\n * TopologyBuilder.create().withNamespace('myapp').withGlobalPrefix('acme') // acme.myapp.events\n * TopologyBuilder.create().withNamespace('myapp').withGlobalPrefix(null) // myapp.events\n */\n withGlobalPrefix(prefix: ResourcePrefix): this {\n this.prefix = prefix;\n return this;\n }\n\n /**\n * Overrides how broker resource names are derived.\n * Use during migrations to keep pre-existing queue/exchange names so a\n * rolling deploy keeps routing through the resources already declared on\n * the broker.\n * @see TopologyNaming\n */\n withNaming(naming: TopologyNaming): this {\n this.naming = naming;\n return this;\n }\n\n /**\n * Adds a queue to the topology.\n * @param definition - A complete QueueDefinition object\n */\n addQueue(definition: QueueDefinition): this;\n /**\n * Adds a queue to the topology.\n * @param name - Queue name\n * @param options - Queue options\n */\n addQueue(name: string, options?: QueueOptions): this;\n addQueue(\n nameOrDefinition: string | QueueDefinition,\n options: QueueOptions = {},\n ): this {\n if (isQueueDefinition(nameOrDefinition)) {\n this.queues.push(nameOrDefinition);\n } else {\n this.queues.push({ name: nameOrDefinition, ...options });\n }\n return this;\n }\n\n /**\n * Alias for addQueue().\n * @param definition - A complete QueueDefinition object\n */\n queue(definition: QueueDefinition): this;\n /**\n * Alias for addQueue().\n * @param name - Queue name\n * @param options - Queue options\n */\n queue(name: string, options?: QueueOptions): this;\n queue(\n nameOrDefinition: string | QueueDefinition,\n options: QueueOptions = {},\n ): this {\n if (isQueueDefinition(nameOrDefinition)) {\n return this.addQueue(nameOrDefinition);\n }\n return this.addQueue(nameOrDefinition, options);\n }\n\n /**\n * Configures dead-letter queue settings.\n */\n withDeadLetter(config: Partial<DeadLetterConfig>): this {\n this.deadLetter = {\n unhandled: config.unhandled ?? this.deadLetter.unhandled,\n undeliverable: config.undeliverable ?? this.deadLetter.undeliverable,\n };\n return this;\n }\n\n /**\n * Configures retry settings.\n */\n withRetry(config: Partial<RetryConfig>): this {\n this.retry = {\n enabled: config.enabled ?? this.retry.enabled,\n defaultDelayMs: config.defaultDelayMs ?? this.retry.defaultDelayMs,\n maxDelayMs: config.maxDelayMs ?? this.retry.maxDelayMs,\n };\n return this;\n }\n\n /**\n * Disables retry functionality.\n */\n withoutRetry(): this {\n this.retry = { ...this.retry, enabled: false };\n return this;\n }\n\n /**\n * Disables dead-letter queues.\n */\n withoutDeadLetter(): this {\n this.deadLetter = {\n unhandled: { enabled: false },\n undeliverable: { enabled: false },\n };\n return this;\n }\n\n /**\n * Validates the topology configuration.\n */\n validate(): readonly string[] {\n return [\n ...validateNamespace(this.namespace),\n ...validatePrefix(this.prefix),\n ...validateQueues(this.queues),\n ...validateRetry(this.retry),\n ...validateNaming(this.naming),\n ];\n }\n\n /**\n * Builds the topology configuration.\n * @throws TopologyValidationError if validation fails\n */\n build(): Topology {\n const issues = this.validate();\n if (issues.length > 0) {\n throw new TopologyValidationError(\n `Invalid topology: ${issues.join('; ')}`,\n issues,\n );\n }\n\n return {\n namespace: this.namespace,\n queues: [...this.queues],\n deadLetter: this.deadLetter,\n retry: this.retry,\n naming: this.naming,\n prefix: this.prefix,\n };\n }\n}\n\nconst IDENTIFIER_PATTERN = /^[a-zA-Z][a-zA-Z0-9_-]*$/;\n\nfunction validateNamespace(namespace: string): string[] {\n if (!namespace || namespace.trim() === '') {\n return ['Namespace is required'];\n }\n if (!IDENTIFIER_PATTERN.test(namespace)) {\n return [\n 'Namespace must start with a letter and contain only alphanumeric characters, underscores, and hyphens',\n ];\n }\n return [];\n}\n\nfunction validatePrefix(prefix: ResourcePrefix): string[] {\n // null/undefined explicitly disable prefixing.\n if (prefix == null) {\n return [];\n }\n if (prefix.trim() === '') {\n return ['Prefix must be a non-empty string, or null to disable prefixing'];\n }\n if (!IDENTIFIER_PATTERN.test(prefix)) {\n return [\n 'Prefix must start with a letter and contain only alphanumeric characters, underscores, and hyphens',\n ];\n }\n return [];\n}\n\nfunction validateQueueName(\n queue: QueueDefinition,\n seen: Set<string>,\n): string[] {\n if (!queue.name || queue.name.trim() === '') {\n return ['Queue name cannot be empty'];\n }\n if (!queue.exact && !IDENTIFIER_PATTERN.test(queue.name)) {\n return [\n `Queue name \"${queue.name}\" must start with a letter and contain only alphanumeric characters, underscores, and hyphens`,\n ];\n }\n if (seen.has(queue.name)) {\n return [`Duplicate queue name: \"${queue.name}\"`];\n }\n seen.add(queue.name);\n return [];\n}\n\nfunction validateQueueLimits(queue: QueueDefinition): string[] {\n const issues: string[] = [];\n if (queue.concurrency !== undefined && queue.concurrency < 1) {\n issues.push(`Queue \"${queue.name}\" concurrency must be at least 1`);\n }\n if (queue.consumerTimeout !== undefined && queue.consumerTimeout < 0) {\n issues.push(`Queue \"${queue.name}\" consumer timeout must be non-negative`);\n }\n return issues;\n}\n\nfunction validateQueues(queues: readonly QueueDefinition[]): string[] {\n const issues: string[] = [];\n if (queues.length === 0) {\n issues.push('At least one queue is required');\n }\n const seen = new Set<string>();\n for (const queue of queues) {\n issues.push(...validateQueueName(queue, seen));\n issues.push(...validateQueueLimits(queue));\n }\n return issues;\n}\n\nfunction validateNaming(naming: TopologyNaming | undefined): string[] {\n if (!naming) return [];\n const issues: string[] = [];\n for (const field of [\n 'queue',\n 'mainExchange',\n 'dlxExchange',\n 'delayedExchange',\n ] as const) {\n const value = naming[field];\n if (value !== undefined && typeof value !== 'function') {\n issues.push(`Naming override \"${field}\" must be a function`);\n }\n }\n if (\n naming.dlxExchangeType !== undefined &&\n naming.dlxExchangeType !== 'direct' &&\n naming.dlxExchangeType !== 'topic'\n ) {\n issues.push(\n `Naming override \"dlxExchangeType\" must be 'direct' or 'topic'`,\n );\n }\n return issues;\n}\n\nfunction validateRetry(retry: RetryConfig): string[] {\n if (!retry.enabled) return [];\n const issues: string[] = [];\n if (retry.defaultDelayMs < 0) {\n issues.push('Default retry delay must be non-negative');\n }\n if (retry.maxDelayMs < retry.defaultDelayMs) {\n issues.push(\n 'Max retry delay must be greater than or equal to default delay',\n );\n }\n return issues;\n}\n","/**\n * Delivery semantics for message processing.\n * - 'at-least-once': Acknowledge after processing (may redeliver on failure)\n * - 'at-most-once': Acknowledge before processing (no redelivery, may lose messages)\n */\nexport type DeliveryMode = 'at-least-once' | 'at-most-once';\n\n/**\n * Importance level for subscribers, used for monitoring and alerting prioritization.\n */\nexport type Importance =\n | 'can-ignore'\n | 'should-investigate'\n | 'must-investigate';\n\n/**\n * Idempotency declaration for subscribers.\n * - 'yes': Safe to retry on failure (subscriber handles duplicates)\n * - 'no': Not safe to retry, may cause duplicate side effects\n * - 'unknown': Idempotency not determined (default)\n * - 'resumable': Uses checkpoint-based idempotency via io() calls\n */\nexport type Idempotency = 'yes' | 'no' | 'unknown' | 'resumable';\n\n/**\n * Result of a validation operation.\n */\nexport interface ValidationResult {\n readonly valid: boolean;\n readonly errors: readonly ValidationError[];\n}\n\n/**\n * Individual validation error.\n */\nexport interface ValidationError {\n readonly path: string;\n readonly message: string;\n}\n\n/**\n * Creates a successful validation result.\n */\nexport function validResult(): ValidationResult {\n return { valid: true, errors: [] };\n}\n\n/**\n * Creates a failed validation result.\n */\nexport function invalidResult(errors: ValidationError[]): ValidationResult {\n return { valid: false, errors };\n}\n","import type { Importance } from './common.js';\nimport type { Event, EventStatic } from './event.js';\n\n/**\n * Message envelope containing the event data and routing/observability metadata.\n * This is the transport-agnostic message format used throughout Matador.\n */\nexport interface Envelope<T = unknown> {\n /** Unique message ID (UUID v4) */\n readonly id: string;\n\n /** The event data */\n readonly data: T;\n\n /** Routing, processing state, and observability metadata */\n readonly docket: Docket;\n}\n\n/**\n * Metadata associated with an envelope for routing, processing state, and observability.\n */\nexport interface Docket {\n // === Routing ===\n\n /** Event key for routing */\n readonly eventKey: string;\n\n /** Human-readable description of the event (for observability/logging) */\n readonly eventDescription?: string | undefined;\n\n /** Target subscriber name for 1:1 routing */\n readonly targetSubscriber: string;\n\n /** Original queue before any dead-letter routing */\n originalQueue?: string | undefined;\n\n /** Scheduled processing time for delayed messages (ISO 8601 string) */\n scheduledFor?: string | undefined;\n\n // === Processing State ===\n\n /**\n * Attempt counter managed by Matador (1-based).\n * Incremented on each retry. Used when transport doesn't track attempts.\n */\n attempts: number;\n\n /** When the envelope was first created (ISO 8601 string) */\n readonly createdAt: string;\n\n /** Error message from first failure (for debugging) */\n firstError?: string | undefined;\n\n /** Error message from most recent failure */\n lastError?: string | undefined;\n\n // === Observability ===\n\n /** Importance level for monitoring */\n readonly importance: Importance;\n\n /** Correlation ID for request tracing */\n readonly correlationId?: string | undefined;\n\n /**\n * Custom metadata provided by the application.\n * This is the merged result of universal metadata (from loadUniversalMetadata hook)\n * and event-specific metadata (from dispatch options). Event-specific metadata\n * overrides universal metadata when keys conflict.\n */\n readonly metadata?: Record<string, unknown> | undefined;\n}\n\n/**\n * Fields from Docket that can be specified when creating an envelope.\n */\ntype DocketCreateFields = Pick<\n Docket,\n | 'eventKey'\n | 'eventDescription'\n | 'targetSubscriber'\n | 'importance'\n | 'correlationId'\n>;\n\n/**\n * Options for creating an envelope.\n */\nexport interface CreateEnvelopeOptions<T> extends DocketCreateFields {\n /** Optional custom ID (defaults to UUID v4) */\n readonly id?: string | undefined;\n\n /** The event data */\n readonly data: T;\n\n /**\n * Event-specific metadata to include in the docket.\n * Will be merged with universal metadata, with these values taking precedence.\n */\n readonly metadata?: Record<string, unknown> | undefined;\n\n /**\n * Universal metadata loaded from the loadUniversalMetadata hook.\n * This is provided by the fanout engine, not by the caller.\n * @internal\n */\n readonly universalMetadata?: Record<string, unknown> | undefined;\n\n /** Delay processing by this many milliseconds */\n readonly delayMs?: number | undefined;\n}\n\n/**\n * Creates a new envelope with the provided options.\n */\nexport function createEnvelope<T>(\n options: CreateEnvelopeOptions<T>,\n): Envelope<T> {\n const now = new Date().toISOString();\n\n // Merge universal metadata with event-specific metadata\n // Event-specific metadata takes precedence\n const mergedMetadata =\n options.universalMetadata || options.metadata\n ? { ...options.universalMetadata, ...options.metadata }\n : undefined;\n\n return {\n id: options.id ?? crypto.randomUUID(),\n data: options.data,\n docket: {\n // Routing\n eventKey: options.eventKey,\n ...(options.eventDescription !== undefined && {\n eventDescription: options.eventDescription,\n }),\n targetSubscriber: options.targetSubscriber,\n ...(options.delayMs !== undefined &&\n options.delayMs > 0 && {\n scheduledFor: new Date(Date.now() + options.delayMs).toISOString(),\n }),\n // Processing state\n attempts: 1,\n createdAt: now,\n // Observability\n importance: options.importance,\n ...(options.correlationId !== undefined && {\n correlationId: options.correlationId,\n }),\n ...(mergedMetadata !== undefined && { metadata: mergedMetadata }),\n },\n };\n}\n\n/**\n * Options for creating a dummy envelope.\n * All fields are optional and will use sensible defaults if not provided.\n */\nexport interface CreateDummyEnvelopeOptions {\n readonly id?: string | undefined;\n readonly eventKey?: string | undefined;\n readonly eventDescription?: string | undefined;\n readonly targetSubscriber?: string | undefined;\n readonly importance?: Importance | undefined;\n readonly correlationId?: string | undefined;\n readonly metadata?: Record<string, unknown> | undefined;\n readonly delayMs?: number | undefined;\n}\n\n/**\n * Type helper to extract the data type from an Event, or return T as-is.\n */\ntype ExtractData<T> = T extends Event<infer D> ? D : T;\n\n/**\n * Checks if a value is a Matador Event (has data property and constructor with key).\n */\nfunction isEvent<T>(value: unknown): value is Event<T> {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'data' in value &&\n typeof (value.constructor as EventStatic).key === 'string'\n );\n}\n\n/**\n * Helper to create a test envelope for a given event instance or raw data.\n * Useful for unit testing subscriber callbacks directly.\n *\n * When passing an Event instance, the eventKey and eventDescription will be\n * automatically extracted from the event class (unless overridden in options).\n *\n * @example With raw data\n * ```typescript\n * const envelope = createDummyEnvelope({ userId: '123', email: 'test@example.com' });\n * ```\n *\n * @example With an Event instance\n * ```typescript\n * const event = new UserCreatedEvent({ userId: '123', email: 'test@example.com' });\n * const envelope = createDummyEnvelope(event);\n * // eventKey is automatically set to UserCreatedEvent.key\n * await mySubscriber.callback(envelope, event.data);\n * ```\n *\n * @example With options\n * ```typescript\n * const event = new UserCreatedEvent({ userId: '123', email: 'test@example.com' });\n * const envelope = createDummyEnvelope(event, {\n * metadata: { traceId: 'abc-123' },\n * correlationId: 'request-456',\n * });\n * ```\n */\nexport function createDummyEnvelope<T>(\n dataOrEvent: T,\n options?: CreateDummyEnvelopeOptions,\n): Envelope<ExtractData<T>> {\n let data: ExtractData<T>;\n let eventKey = options?.eventKey ?? 'dummy.event.key';\n let eventDescription = options?.eventDescription;\n\n if (isEvent(dataOrEvent)) {\n data = dataOrEvent.data as ExtractData<T>;\n const eventStatic = dataOrEvent.constructor as EventStatic;\n eventKey = options?.eventKey ?? eventStatic.key;\n eventDescription = options?.eventDescription ?? eventStatic.description;\n } else {\n data = dataOrEvent as ExtractData<T>;\n }\n\n return createEnvelope({\n data,\n eventKey,\n eventDescription,\n targetSubscriber: options?.targetSubscriber ?? 'dummy-subscriber',\n importance: options?.importance ?? 'can-ignore',\n id: options?.id,\n correlationId: options?.correlationId,\n metadata: options?.metadata,\n delayMs: options?.delayMs,\n });\n}\n","import type { Jsonifiable } from 'type-fest';\n\n/**\n * Unique event routing key type alias.\n */\nexport type EventKey = string;\n\n/**\n * JSON-serializable record type for metadata.\n * Uses type-fest's Jsonifiable which accepts:\n * - Primitives (string, number, boolean, null)\n * - Arrays of Jsonifiable values\n * - Objects with Jsonifiable values\n * - Objects with a toJSON() method\n */\nexport type JsonRecord = Record<string, Jsonifiable>;\n\n/**\n * Static properties required on Event classes for schema registration.\n */\nexport interface EventStatic<T = unknown> {\n /** Unique routing key for the event */\n readonly key: string;\n\n /** Human-readable description of the event */\n readonly description?: string;\n\n /** Alternative names/keys for backwards compatibility */\n readonly aliases?: readonly string[];\n\n /** Create an instance from data (for deserialization) */\n new (data: T): Event<T>;\n}\n\n/**\n * Base interface for all events.\n * Events represent something that happened in the system.\n */\nexport interface Event<T = unknown> {\n /** The event data/payload */\n readonly data: T;\n\n /** Event-specific metadata (merged with EventOptions metadata on dispatch) */\n readonly metadata?: JsonRecord | undefined;\n}\n\n/**\n * Options for dispatching an event.\n */\nexport interface EventOptions {\n /** Delay processing by this many milliseconds */\n readonly delayMs?: number | undefined;\n\n /** Correlation ID for request tracing */\n readonly correlationId?: string | undefined;\n\n /**\n * Event-specific metadata to include in the docket.\n * This metadata will be merged with:\n * 1. Event instance metadata (if defined on the event)\n * 2. Universal metadata from the loadUniversalMetadata hook\n * With EventOptions metadata taking precedence over event metadata,\n * and both taking precedence over universal metadata.\n */\n readonly metadata?: JsonRecord | undefined;\n\n /**\n * Whether to buffer this send for retry on reconnect if all transports fail.\n * When true (default), failed sends are held in memory and retried automatically\n * when the transport reconnects.\n * When false, failures are reported immediately in result.errors with no retry.\n *\n * @default true\n */\n readonly buffer?: boolean | undefined;\n\n /**\n * Whether to throw an error when a buffered failure is reported.\n * Only meaningful when buffer is true. When true, the send is buffered\n * for retry AND reported as an error so the caller is aware it failed.\n *\n * @default false\n */\n readonly throwOnBufferedFailure?: boolean | undefined;\n}\n\n/**\n * Abstract base class for creating Matador events.\n * Extend this class to define custom events.\n *\n * @example\n * ```typescript\n * class UserCreatedEvent extends MatadorEvent {\n * static readonly key = 'user.created'\n * static readonly description = 'Fired when a new user is created'\n *\n * constructor(\n * public data: { userId: string; email: string },\n * public metadata?: JsonRecord,\n * ) {\n * super()\n * }\n * }\n * ```\n */\nexport abstract class MatadorEvent<T = unknown> implements Event<T> {\n static readonly key: string;\n static readonly description?: string;\n static readonly aliases?: readonly string[];\n\n /** The event data/payload - must be defined by subclass */\n abstract readonly data: T;\n\n /** Event-specific metadata */\n readonly metadata?: JsonRecord | undefined;\n}\n\n/**\n * Type helper to extract the data type from an event class.\n */\nexport type EventData<E extends Event<unknown>> = E extends Event<infer T>\n ? T\n : never;\n\n/**\n * Type helper to get the event class type.\n */\nexport type EventClass<T = unknown> = EventStatic<T> &\n (new (\n data: T,\n ) => Event<T>);\n","import type { SubscriberContext } from '../checkpoint/index.js';\nimport type { Idempotency, Importance } from './common.js';\nimport type { Dispatcher } from './dispatcher.js';\nimport type { Envelope } from './envelope.js';\nimport type { MatadorEvent } from './event.js';\n\n/**\n * Context passed to subscriber callbacks.\n * Provides access to the Matador instance for sending additional events.\n */\nexport interface CallbackContext {\n /** Matador dispatcher for sending additional events from within a subscriber */\n readonly matador: Dispatcher;\n}\n\n/**\n * Helper type to get the envelope type for a subscriber callback.\n * Extracts the data type from a MatadorEvent and wraps it in an Envelope.\n *\n * @example\n * async callback(envelope: EnvelopeOf<MyEvent>) {\n * console.log(envelope.data.someField); // Type-safe access\n * }\n */\nexport type EnvelopeOf<T extends MatadorEvent> = Envelope<T['data']>;\n\n/**\n * Callback function executed when an event is received (standard subscribers).\n * Receives the full envelope containing id, data, and docket, plus a context\n * with access to the matador instance for sending additional events.\n *\n * The callback may optionally return a value, which will be included in the\n * onWorkerSuccess hook context for logging or observability purposes.\n */\nexport type StandardCallback<T = unknown> = (\n envelope: Envelope<T>,\n context: CallbackContext,\n) => Promise<unknown> | unknown | undefined;\n\n/**\n * Context for resumable subscriber callbacks.\n * Combines checkpoint operations (io, all) with matador access.\n */\nexport type ResumableCallbackContext = SubscriberContext & CallbackContext;\n\n/**\n * Callback function for resumable subscribers.\n * Receives the envelope and a context with io() for checkpointed operations\n * and matador for sending additional events.\n *\n * The callback may optionally return a value, which will be included in the\n * onWorkerSuccess hook context for logging or observability purposes.\n */\nexport type ResumableCallback<T = unknown> = (\n envelope: Envelope<T>,\n context: ResumableCallbackContext,\n) => Promise<unknown> | unknown | undefined;\n\n/**\n * Callback function executed when an event is received.\n * @deprecated Use StandardCallback or ResumableCallback instead.\n */\nexport type SubscriberCallback<T = unknown> = StandardCallback<T>;\n\n/**\n * Base configuration options shared by all subscriber types.\n */\nexport interface BaseSubscriberOptions {\n /** Human-readable description of what this subscriber does */\n readonly description: string;\n\n /** Route this subscriber's events to a specific queue */\n readonly targetQueue?: string | undefined;\n\n /** Importance level for monitoring and alerting */\n readonly importance?: Importance | undefined;\n\n /** Feature flag function to conditionally enable/disable the subscriber */\n readonly enabled?: (() => boolean | Promise<boolean>) | undefined;\n}\n\n/**\n * Options for standard (non-resumable) subscribers.\n */\nexport interface StandardSubscriberOptions extends BaseSubscriberOptions {\n /** Idempotency declaration for retry handling (non-resumable) */\n readonly idempotent?: 'yes' | 'no' | 'unknown' | undefined;\n}\n\n/**\n * Options for resumable subscribers that use io() for checkpointed operations.\n */\nexport interface ResumableSubscriberOptions extends BaseSubscriberOptions {\n /** Must be 'resumable' to enable checkpoint-based idempotency */\n readonly idempotent: 'resumable';\n}\n\n/**\n * Configuration options for a subscriber.\n * Discriminated union based on idempotent value.\n */\nexport type SubscriberOptions =\n | StandardSubscriberOptions\n | ResumableSubscriberOptions;\n\n/**\n * Standard subscriber definition with standard callback.\n */\nexport interface StandardSubscriber<T extends MatadorEvent>\n extends StandardSubscriberOptions {\n /** Human-readable name for the subscriber */\n readonly name: string;\n\n /** Callback function to execute when event is received */\n readonly callback: StandardCallback<T['data']>;\n}\n\n/**\n * Resumable subscriber definition with resumable callback.\n */\nexport interface ResumableSubscriber<T extends MatadorEvent>\n extends ResumableSubscriberOptions {\n /** Human-readable name for the subscriber */\n readonly name: string;\n\n /** Callback function with SubscriberContext for checkpointed operations */\n readonly callback: ResumableCallback<T['data']>;\n}\n\n/**\n * Full subscriber definition with callback (either standard or resumable).\n */\nexport type Subscriber<T extends MatadorEvent> =\n | StandardSubscriber<T>\n | ResumableSubscriber<T>;\n\n/**\n * Subscriber stub for multi-codebase scenarios where subscriber implementation\n * is in a remote service. Declares the subscriber contract without providing\n * the callback.\n */\nexport interface SubscriberStub\n extends Omit<StandardSubscriberOptions, 'description'> {\n /** Human-readable name for the subscriber */\n readonly name: string;\n\n /** Indicates this is a stub without implementation */\n readonly isStub: true;\n}\n\n/**\n * Union type for any subscriber definition (full or stub).\n * This is the type-erased version for use in collections and schema.\n * Uses `any` because Subscriber<T> is contravariant in T (callback parameter),\n * making it impossible to assign Subscriber<SpecificEvent> to Subscriber<MatadorEvent<unknown>>.\n */\n// biome-ignore lint/suspicious/noExplicitAny: Required for variance compatibility in heterogeneous collections\nexport type AnySubscriber = Subscriber<MatadorEvent<any>> | SubscriberStub;\n\n/**\n * Type guard to check if a subscriber is a stub.\n */\nexport function isSubscriberStub(\n subscriber: AnySubscriber,\n): subscriber is SubscriberStub {\n return 'isStub' in subscriber && subscriber.isStub === true;\n}\n\n/**\n * Type guard to check if a subscriber has a callback implementation.\n */\nexport function isSubscriber(\n subscriber: AnySubscriber,\n // biome-ignore lint/suspicious/noExplicitAny: Required for variance compatibility\n): subscriber is Subscriber<MatadorEvent<any>> {\n return 'callback' in subscriber && typeof subscriber.callback === 'function';\n}\n\n/**\n * Type guard to check if a subscriber is resumable.\n */\nexport function isResumableSubscriber(\n subscriber: AnySubscriber,\n // biome-ignore lint/suspicious/noExplicitAny: Required for variance compatibility\n): subscriber is ResumableSubscriber<MatadorEvent<any>> {\n return isSubscriber(subscriber) && subscriber.idempotent === 'resumable';\n}\n\n/**\n * Type guard to check if a subscriber is a standard (non-resumable) subscriber.\n */\nexport function isStandardSubscriber(\n subscriber: AnySubscriber,\n // biome-ignore lint/suspicious/noExplicitAny: Required for variance compatibility\n): subscriber is StandardSubscriber<MatadorEvent<any>> {\n return isSubscriber(subscriber) && subscriber.idempotent !== 'resumable';\n}\n\n/**\n * Input options for createSubscriber with standard callback.\n */\nexport interface CreateStandardSubscriberInput<T extends MatadorEvent> {\n readonly name: string;\n readonly description: string;\n readonly callback: StandardCallback<T['data']>;\n readonly idempotent?: 'yes' | 'no' | 'unknown' | undefined;\n readonly importance?: Importance | undefined;\n readonly targetQueue?: string | undefined;\n readonly enabled?: (() => boolean | Promise<boolean>) | undefined;\n}\n\n/**\n * Input options for createSubscriber with resumable callback.\n */\nexport interface CreateResumableSubscriberInput<T extends MatadorEvent> {\n readonly name: string;\n readonly description: string;\n readonly callback: ResumableCallback<T['data']>;\n readonly idempotent: 'resumable';\n readonly importance?: Importance | undefined;\n readonly targetQueue?: string | undefined;\n readonly enabled?: (() => boolean | Promise<boolean>) | undefined;\n}\n\n/**\n * Input options for createSubscriber (discriminated union).\n */\nexport type CreateSubscriberInput<T extends MatadorEvent> =\n | CreateStandardSubscriberInput<T>\n | CreateResumableSubscriberInput<T>;\n\n/**\n * Creates a subscriber definition.\n *\n * @example Standard subscriber\n * ```typescript\n * const subscriber = createSubscriber<MyEvent>({\n * name: 'my-subscriber',\n * description: 'Handles MyEvent by logging the data',\n * callback: async (envelope) => {\n * console.log(envelope.data);\n * },\n * });\n * ```\n *\n * @example Resumable subscriber with io()\n * ```typescript\n * const subscriber = createSubscriber<MyEvent>({\n * name: 'my-resumable-subscriber',\n * description: 'Processes MyEvent with checkpoint-based idempotency',\n * idempotent: 'resumable',\n * callback: async (envelope, { io }) => {\n * await io('step-1', () => doSomething());\n * },\n * });\n * ```\n */\nexport function createSubscriber<T extends MatadorEvent>(\n input: CreateSubscriberInput<T>,\n): Subscriber<T> {\n const base = {\n name: input.name,\n description: input.description,\n callback: input.callback,\n importance: input.importance ?? 'should-investigate',\n ...(input.targetQueue !== undefined && {\n targetQueue: input.targetQueue,\n }),\n ...(input.enabled !== undefined && { enabled: input.enabled }),\n };\n\n if (input.idempotent === 'resumable') {\n return {\n ...base,\n idempotent: 'resumable',\n callback: input.callback,\n } as ResumableSubscriber<T>;\n }\n\n return {\n ...base,\n idempotent: input.idempotent ?? 'unknown',\n callback: input.callback,\n } as StandardSubscriber<T>;\n}\n\n/**\n * Input options for createSubscriberStub.\n */\nexport interface CreateSubscriberStubInput {\n readonly name: string;\n readonly idempotent?: 'yes' | 'no' | 'unknown' | undefined;\n readonly importance?: Importance | undefined;\n readonly targetQueue?: string | undefined;\n readonly enabled?: (() => boolean | Promise<boolean>) | undefined;\n}\n\n/**\n * Creates a subscriber stub for remote implementations.\n *\n * @example\n * ```typescript\n * const stub = createSubscriberStub({\n * name: 'remote-analytics',\n * targetQueue: 'analytics-worker',\n * });\n * ```\n */\nexport function createSubscriberStub(\n input: CreateSubscriberStubInput,\n): SubscriberStub {\n return {\n name: input.name,\n isStub: true,\n idempotent: input.idempotent ?? 'unknown',\n importance: input.importance ?? 'should-investigate',\n ...(input.targetQueue !== undefined && {\n targetQueue: input.targetQueue,\n }),\n ...(input.enabled !== undefined && { enabled: input.enabled }),\n };\n}\n\n/**\n * Definition interface used by the pipeline (excludes event class reference).\n */\nexport interface SubscriberDefinition {\n readonly name: string;\n readonly description?: string | undefined;\n readonly idempotent: Idempotency;\n readonly importance: Importance;\n readonly targetQueue?: string | undefined;\n}\n","import { TransportSendError } from '../errors/index.js';\nimport type { SafeHooks } from '../hooks/index.js';\nimport type { SchemaRegistry } from '../schema/index.js';\nimport type { Topology } from '../topology/index.js';\nimport { resolveTargetQueueName } from '../topology/index.js';\nimport type { SendOptions, Transport } from '../transport/index.js';\nimport type {\n AnySubscriber,\n Envelope,\n Event,\n EventClass,\n EventOptions,\n} from '../types/index.js';\nimport { createEnvelope } from '../types/index.js';\n\n/**\n * Default number of consecutive flush failures tolerated within a single\n * flush pass before bailing out early and re-buffering the untried\n * remainder.\n */\nconst DEFAULT_MAX_CONSECUTIVE_FLUSH_FAILURES = 10;\n\n/**\n * A send that failed (all transports exhausted) and was held in-memory for retry on reconnect.\n */\ninterface BufferedSend {\n readonly queue: string;\n readonly envelope: Envelope;\n readonly sendOptions: SendOptions | undefined;\n readonly subscriberName: string;\n /** Number of retry attempts made since this was first buffered. */\n attempts: number;\n}\n\n/**\n * Configuration for the fanout engine.\n */\nexport interface FanoutConfig {\n readonly transport: Transport;\n readonly schema: SchemaRegistry;\n readonly hooks: SafeHooks;\n readonly topology: Topology;\n readonly defaultQueue: string;\n readonly maxRetryBufferSize?: number | undefined;\n\n /**\n * Maximum number of retry attempts for a buffered message before it's\n * dropped and reported via onEnqueueError, instead of being retried forever.\n *\n * @default undefined (no limit — retries until the buffer flushes successfully)\n */\n readonly maxRetryAttempts?: number | undefined;\n\n /**\n * How often (in ms) to attempt flushing the retry buffer, independent of\n * transport reconnect events. This covers the case where the transport\n * stays connected but an individual publish keeps failing (e.g. broker\n * nack, publish confirm timeout) — onConnected never fires again for\n * that, so nothing would otherwise retry it.\n *\n * @default 30000. Pass 0 to disable the interval and rely on\n * onConnected/manual flushes only.\n */\n readonly retryIntervalMs?: number | undefined;\n\n /**\n * Number of consecutive flush failures tolerated within a single flush\n * pass before bailing out early and re-buffering the untried remainder,\n * instead of retrying every buffered message against a broker that's\n * rejecting everything.\n *\n * @default 10. Pass 0 (or a negative number) to disable the breaker and\n * always attempt every buffered message on every flush pass.\n */\n readonly maxConsecutiveFlushFailures?: number | undefined;\n}\n\n/**\n * Result of sending an event.\n */\nexport interface SendResult {\n readonly eventKey: string;\n readonly subscribersSent: number;\n readonly subscribersSkipped: number;\n readonly errors: readonly SendError[];\n}\n\n/**\n * Error during send.\n */\nexport interface SendError {\n readonly subscriberName: string;\n readonly queue: string;\n readonly error: Error;\n}\n\n/**\n * Engine for fanning out events to subscribers.\n *\n * Handles:\n * 1. Getting subscribers from schema\n * 2. Filtering by enabled() hook\n * 3. Creating envelopes for each subscriber\n * 4. Sending to appropriate queues via transport\n */\nexport class FanoutEngine {\n private readonly transport: Transport;\n private readonly schema: SchemaRegistry;\n private readonly hooks: SafeHooks;\n private readonly topology: Topology;\n private readonly defaultQueue: string;\n private enqueuingCount = 0;\n private flushInFlightCount = 0;\n private readonly retryBuffer: BufferedSend[] = [];\n private readonly maxRetryBufferSize: number;\n private readonly maxRetryAttempts: number | undefined;\n private readonly maxConsecutiveFlushFailures: number;\n private readonly disposeOnConnected: (() => void) | undefined;\n private readonly retryTimer: ReturnType<typeof setInterval> | undefined;\n\n constructor(config: FanoutConfig) {\n this.transport = config.transport;\n this.schema = config.schema;\n this.hooks = config.hooks;\n this.topology = config.topology;\n this.defaultQueue = config.defaultQueue;\n this.maxRetryBufferSize = config.maxRetryBufferSize ?? 5000;\n this.maxRetryAttempts = config.maxRetryAttempts;\n const maxConsecutiveFlushFailures =\n config.maxConsecutiveFlushFailures ??\n DEFAULT_MAX_CONSECUTIVE_FLUSH_FAILURES;\n this.maxConsecutiveFlushFailures =\n maxConsecutiveFlushFailures > 0\n ? maxConsecutiveFlushFailures\n : Number.POSITIVE_INFINITY;\n\n // If the transport supports it, add a callback to flush the retry buffer when the transport reconnects\n // The returned value is a function to unsubscribe from the callback\n this.disposeOnConnected = this.transport.onConnected?.(() => {\n void this.flushRetryBuffer();\n });\n\n // Also flush periodically: onConnected only fires on connection-level\n // reconnects, so it never fires when the transport stays connected but\n // an individual publish keeps failing (e.g. broker nack, confirm timeout).\n const retryIntervalMs = config.retryIntervalMs ?? 30_000;\n if (retryIntervalMs > 0) {\n this.retryTimer = setInterval(() => {\n void this.flushRetryBuffer();\n }, retryIntervalMs);\n this.retryTimer.unref?.();\n }\n }\n\n dispose(): void {\n // Unsubscribe from the callback (that flushes the retry buffer when the transport reconnects)\n this.disposeOnConnected?.();\n clearInterval(this.retryTimer);\n }\n\n /**\n * Current count of events being enqueued.\n */\n get eventsBeingEnqueuedCount(): number {\n return this.enqueuingCount + this.flushInFlightCount;\n }\n\n /**\n * Sends an event to all registered subscribers.\n */\n async send<T>(\n eventClass: EventClass<T>,\n event: Event<T>,\n options: EventOptions = {},\n ): Promise<SendResult> {\n const eventKey = eventClass.key;\n const subscribers = this.schema.getSubscribers(eventKey);\n\n const errors: SendError[] = [];\n let sent = 0;\n let skipped = 0;\n\n // Load universal metadata\n const universalMetadata = await this.hooks.loadUniversalMetadata();\n\n // Merge event.metadata with options.metadata (options takes precedence)\n const mergedMetadata =\n event.metadata || options.metadata\n ? { ...event.metadata, ...options.metadata }\n : undefined;\n\n for (const subscriber of subscribers) {\n // Check if subscriber is enabled\n const enabled = await this.isSubscriberEnabled(subscriber);\n if (!enabled) {\n skipped++;\n continue;\n }\n\n // Determine target queue\n const targetQueue = subscriber.targetQueue ?? this.defaultQueue;\n const qualifiedQueue = resolveTargetQueueName(this.topology, targetQueue);\n\n // Create envelope\n const envelope = createEnvelope({\n eventKey,\n eventDescription: eventClass.description,\n targetSubscriber: subscriber.name,\n data: event.data,\n importance: subscriber.importance ?? 'should-investigate',\n correlationId: options.correlationId,\n metadata: mergedMetadata,\n universalMetadata,\n delayMs: options.delayMs,\n });\n\n // Send to transport\n const sendOptions: SendOptions | undefined =\n options.delayMs !== undefined ? { delay: options.delayMs } : undefined;\n\n this.enqueuingCount++;\n try {\n const usedTransport = await this.transport.send(\n qualifiedQueue,\n envelope,\n sendOptions,\n );\n sent++;\n\n await this.hooks.onEnqueueSuccess({\n envelope,\n queue: qualifiedQueue,\n transport: usedTransport,\n });\n } catch (error) {\n const cause = error instanceof Error ? error : new Error(String(error));\n const shouldBuffer = options.buffer !== false;\n\n if (shouldBuffer && this.retryBuffer.length < this.maxRetryBufferSize) {\n this.retryBuffer.push({\n queue: qualifiedQueue,\n envelope,\n sendOptions,\n subscriberName: subscriber.name,\n attempts: 0,\n });\n this.hooks.logger.warn(\n `[Matador] 🟡 Message for '${subscriber.name}' buffered for retry on reconnect.`,\n {\n queue: qualifiedQueue,\n subscriberName: subscriber.name,\n bufferSize: this.retryBuffer.length,\n maxBufferSize: this.maxRetryBufferSize,\n },\n );\n\n if (options.throwOnBufferedFailure) {\n const err = new TransportSendError(qualifiedQueue, cause);\n // By adding the error, the main Send in Matador will throw\n errors.push({\n subscriberName: subscriber.name,\n queue: qualifiedQueue,\n error: err,\n });\n await this.hooks.onEnqueueError({\n envelope,\n error: err,\n transport: this.transport.name,\n });\n }\n } else {\n if (shouldBuffer) {\n this.hooks.logger.error(\n `[Matador] 🔴 Retry buffer full (${this.maxRetryBufferSize}). Message for '${subscriber.name}' dropped and will not be retried.`,\n );\n }\n const err = new TransportSendError(qualifiedQueue, cause);\n errors.push({\n subscriberName: subscriber.name,\n queue: qualifiedQueue,\n error: err,\n });\n\n await this.hooks.onEnqueueError({\n envelope,\n error: err,\n transport: this.transport.name,\n });\n }\n } finally {\n this.enqueuingCount--;\n }\n }\n\n return {\n eventKey,\n subscribersSent: sent,\n subscribersSkipped: skipped,\n errors,\n };\n }\n\n /**\n * Attempts a single buffered item during a flush pass\n * @returns true if the attempt succeeded; false on failure\n */\n private async attemptFlushItem(item: BufferedSend): Promise<boolean> {\n this.enqueuingCount++;\n try {\n const usedTransport = await this.transport.send(\n item.queue,\n item.envelope,\n item.sendOptions,\n );\n await this.hooks.onEnqueueSuccess({\n envelope: item.envelope,\n queue: item.queue,\n transport: usedTransport,\n });\n return true;\n } catch (error) {\n await this.handleFlushFailure(item, error);\n return false;\n } finally {\n this.enqueuingCount--;\n }\n }\n\n /**\n * Flushes the retry buffer\n *\n * This is called when the transport reconnects, and is used to retry any messages that were buffered while the transport was disconnected\n */\n private async flushRetryBuffer(): Promise<void> {\n if (this.retryBuffer.length === 0) return;\n\n this.hooks.logger.info(\n `[Matador] ⏳ Flushing ${this.retryBuffer.length} buffered message(s)...`,\n );\n\n // Drain the buffer atomically so concurrent flush calls don't double-send.\n const toFlush = this.retryBuffer.splice(0);\n // Tracked separately from enqueuingCount so shutdown doesn't see a it falsely idle while items are being flushed\n this.flushInFlightCount += toFlush.length;\n let consecutiveFailures = 0;\n\n try {\n for (let i = 0; i < toFlush.length; i++) {\n const item = toFlush[i];\n if (!item) {\n this.flushInFlightCount--;\n continue;\n }\n\n const succeeded = await this.attemptFlushItem(item);\n this.flushInFlightCount--;\n\n // Small sleep to avoid overwhelming the transport\n // Random sleep to avoid thundering herd (between 0 and 10ms)\n const randomMs = Math.random() * 10;\n await new Promise((resolve) => setTimeout(resolve, randomMs));\n\n // A success means the transport is actually working, so it resets the consecutive failures streak\n consecutiveFailures = succeeded ? 0 : consecutiveFailures + 1;\n\n if (consecutiveFailures >= this.maxConsecutiveFlushFailures) {\n // A run of failures this long is more likely a connection-level issue (broker down, slow, rejecting everything)\n // So we stop early to avoid retrying 5k messages for nothing\n const untried = toFlush.slice(i + 1);\n this.flushInFlightCount -= untried.length;\n if (untried.length > 0) {\n await this.rebufferUntried(untried, consecutiveFailures);\n }\n break;\n }\n }\n } finally {\n this.flushInFlightCount = 0;\n }\n\n const remaining = this.retryBuffer.length;\n if (remaining > 0) {\n this.hooks.logger.warn(\n `[Matador] 🟡 ${remaining} buffered message(s) could not be flushed; will retry later.`,\n );\n } else {\n this.hooks.logger.info(\n '[Matador] 🟢 All buffered messages flushed successfully.',\n );\n }\n }\n\n /**\n * Re-buffers messages that were never attempted because a flush pass\n * stopped out early. Respects maxRetryBufferSize: concurrent sends can have\n * refilled the buffer while this flush was running, so anything beyond\n * remaining capacity is dropped and reported instead of silently growing\n * the buffer past its cap.\n */\n private async rebufferUntried(\n untried: BufferedSend[],\n consecutiveFailures: number,\n ): Promise<void> {\n const capacity = Math.max(\n 0,\n this.maxRetryBufferSize - this.retryBuffer.length,\n );\n const toRebuffer = untried.slice(0, capacity);\n const dropped = untried.slice(capacity);\n\n if (toRebuffer.length > 0) {\n this.retryBuffer.unshift(...toRebuffer);\n }\n\n const droppedSuffix =\n dropped.length > 0 ? `, ${dropped.length} dropped (buffer full).` : '.';\n this.hooks.logger.warn(\n `[Matador] 🟡 Stopping this flush pass after ${consecutiveFailures} consecutive failures; ${toRebuffer.length} untried message(s) re-buffered for the next attempt${droppedSuffix}`,\n );\n\n for (const item of dropped) {\n this.hooks.logger.error(\n `[Matador] 🔴 Retry buffer full (${this.maxRetryBufferSize}). Message for '${item.subscriberName}' dropped and will not be retried.`,\n );\n const err = new TransportSendError(\n item.queue,\n new Error('Retry buffer full'),\n );\n await this.hooks.onEnqueueError({\n envelope: item.envelope,\n error: err,\n transport: this.transport.name,\n });\n }\n }\n\n /**\n * Handles a failed flush attempt for a single buffered item: drops it once\n * maxRetryAttempts is exceeded, otherwise re-buffers it (unless the buffer\n * is full, in which case it's dropped too).\n */\n private async handleFlushFailure(\n item: BufferedSend,\n error: unknown,\n ): Promise<void> {\n item.attempts++;\n const cause = error instanceof Error ? error : new Error(String(error));\n const exceededAttempts =\n this.maxRetryAttempts !== undefined &&\n item.attempts >= this.maxRetryAttempts;\n\n if (\n !exceededAttempts &&\n this.retryBuffer.length < this.maxRetryBufferSize\n ) {\n // Re-buffer on failure; it will be retried on the next reconnect or flush interval.\n this.retryBuffer.push(item);\n return;\n }\n\n if (exceededAttempts) {\n this.hooks.logger.error(\n `[Matador] 🔴 Message for '${item.subscriberName}' exceeded max retry attempts (${this.maxRetryAttempts}) and will not be retried further.`,\n );\n }\n\n const err = new TransportSendError(item.queue, cause);\n await this.hooks.onEnqueueError({\n envelope: item.envelope,\n error: err,\n transport: this.transport.name,\n });\n }\n\n private async isSubscriberEnabled(\n subscriber: AnySubscriber,\n ): Promise<boolean> {\n if (!subscriber.enabled) {\n return true;\n }\n\n try {\n const result = await subscriber.enabled();\n return result;\n } catch {\n // If enabled check fails, consider it enabled\n return true;\n }\n }\n}\n","import type {\n CheckpointClearedContext,\n CheckpointHitContext,\n CheckpointLoadedContext,\n CheckpointMissContext,\n} from '../checkpoint/index.js';\nimport type { RetryDecision } from '../retry/index.js';\nimport type { ConnectionState, Transport } from '../transport/index.js';\nimport type { Envelope, SubscriberDefinition } from '../types/index.js';\n\n/**\n * Logger interface for Matador internal logging.\n */\nexport interface Logger {\n debug(message: string, ...args: unknown[]): void;\n info(message: string, ...args: unknown[]): void;\n warn(message: string, ...args: unknown[]): void;\n error(message: string, ...args: unknown[]): void;\n}\n\n/**\n * Default logger that uses console.\n */\nexport const consoleLogger: Logger = {\n debug: (message, ...args) => console.debug(message, ...args),\n info: (message, ...args) => console.info(message, ...args),\n warn: (message, ...args) => console.warn(message, ...args),\n error: (message, ...args) => console.error(message, ...args),\n};\n\n/**\n * Context for enqueue success hook.\n */\nexport interface EnqueueSuccessContext {\n readonly envelope: Envelope;\n readonly queue: string;\n /** The transport that was used (e.g., 'local', 'rabbitmq') */\n readonly transport: string;\n}\n\n/**\n * Context for transport fallback hook.\n */\nexport interface TransportFallbackContext {\n /** The envelope that was being sent */\n readonly envelope: Envelope;\n /** The queue the message was being sent to */\n readonly queue: string;\n /** The transport that failed */\n readonly failedTransport: Transport['name'];\n /** The transport that will be tried next */\n readonly nextTransport: Transport['name'];\n /** The error from the failed transport */\n readonly error: Error;\n}\n\n/**\n * Context for enqueue error hook.\n */\nexport interface EnqueueErrorContext {\n readonly envelope: Envelope;\n readonly error: Error;\n /** The transport that failed (e.g., 'local', 'rabbitmq') */\n readonly transport: string;\n}\n\n/**\n * Context for decode error hook.\n */\nexport interface DecodeErrorContext {\n readonly error: Error;\n readonly rawMessage: Uint8Array;\n readonly sourceQueue: string;\n /** The transport that received the message (e.g., 'local', 'rabbitmq') */\n readonly transport: string;\n}\n\n/**\n * Context for worker success hook.\n */\nexport interface WorkerSuccessContext {\n readonly envelope: Envelope;\n readonly subscriber: SubscriberDefinition;\n readonly result: unknown;\n readonly durationMs: number;\n /** The transport that received the message (e.g., 'local', 'rabbitmq') */\n readonly transport: string;\n}\n\n/**\n * Context for worker error hook.\n */\nexport interface WorkerErrorContext {\n readonly envelope: Envelope;\n readonly subscriber: SubscriberDefinition;\n readonly error: Error;\n readonly durationMs: number;\n readonly decision: RetryDecision;\n /** The transport that received the message (e.g., 'local', 'rabbitmq') */\n readonly transport: string;\n}\n\n/**\n * Execution function passed to onWorkerWrap for APM wrapping.\n */\nexport type WorkerExecuteFn = () => Promise<void>;\n\n/**\n * All available hooks for Matador.\n */\nexport interface MatadorHooks {\n /**\n * Logger for internal Matador logging.\n * Defaults to console logger if not provided.\n */\n logger?: Logger;\n\n /**\n * Called when an event is successfully enqueued.\n */\n onEnqueueSuccess?(context: EnqueueSuccessContext): void | Promise<void>;\n\n /**\n * Called when transport fallback occurs during send.\n * Only fires when using MultiTransport with fallbackEnabled=true.\n */\n onTransportFallback?(context: TransportFallbackContext): void | Promise<void>;\n\n /**\n * Called when enqueue fails completely.\n */\n onEnqueueError?(context: EnqueueErrorContext): void | Promise<void>;\n\n /**\n * Wraps entire worker processing (for APM context).\n * Must call execute() to run the actual processing.\n */\n onWorkerWrap?(\n envelope: Envelope,\n subscriber: SubscriberDefinition,\n execute: WorkerExecuteFn,\n ): Promise<void>;\n\n /**\n * Called before processing begins.\n */\n onWorkerBeforeProcess?(\n envelope: Envelope,\n subscriber: SubscriberDefinition,\n ): void | Promise<void>;\n\n /**\n * Called after successful processing.\n */\n onWorkerSuccess?(context: WorkerSuccessContext): void | Promise<void>;\n\n /**\n * Called after processing error.\n */\n onWorkerError?(context: WorkerErrorContext): void | Promise<void>;\n\n /**\n * Called when message decoding fails.\n */\n onDecodeError?(context: DecodeErrorContext): void | Promise<void>;\n\n /**\n * Called when transport connection state changes.\n */\n onConnectionStateChange?(state: ConnectionState): void | Promise<void>;\n\n /**\n * Loads universal metadata to add to all envelopes.\n */\n loadUniversalMetadata?():\n | Record<string, unknown>\n | Promise<Record<string, unknown>>;\n\n /**\n * Dynamic retry delay lookup.\n */\n getRetryDelay?(\n envelope: Envelope,\n attemptNumber: number,\n ): number | undefined | Promise<number | undefined>;\n\n /**\n * Dynamic max attempts lookup.\n */\n getAttempts?(\n envelope: Envelope,\n ): number | undefined | Promise<number | undefined>;\n\n /**\n * Dynamic max deliveries (poison threshold) lookup.\n */\n getMaxDeliveries?(\n envelope: Envelope,\n ): number | undefined | Promise<number | undefined>;\n\n // === Checkpoint Hooks (Resumable Subscribers) ===\n\n /**\n * Called when a checkpoint is loaded for a retry.\n * Only fires for resumable subscribers on retry attempts.\n */\n onCheckpointLoaded?(context: CheckpointLoadedContext): void | Promise<void>;\n\n /**\n * Called when an io() operation uses a cached value (checkpoint hit).\n * Useful for observability and metrics.\n */\n onCheckpointHit?(context: CheckpointHitContext): void | Promise<void>;\n\n /**\n * Called when an io() operation executes (cache miss).\n * Useful for observability and metrics.\n */\n onCheckpointMiss?(context: CheckpointMissContext): void | Promise<void>;\n\n /**\n * Called when a checkpoint is cleared.\n * Fires on successful completion or when moving to dead-letter queue.\n */\n onCheckpointCleared?(context: CheckpointClearedContext): void | Promise<void>;\n}\n","import type {\n CheckpointClearedContext,\n CheckpointHitContext,\n CheckpointLoadedContext,\n CheckpointMissContext,\n} from '../checkpoint/index.js';\nimport type { ConnectionState } from '../transport/index.js';\nimport type { Envelope, SubscriberDefinition } from '../types/index.js';\nimport {\n type DecodeErrorContext,\n type EnqueueErrorContext,\n type EnqueueSuccessContext,\n type Logger,\n type MatadorHooks,\n type WorkerErrorContext,\n type WorkerExecuteFn,\n type WorkerSuccessContext,\n consoleLogger,\n} from './types.js';\n\n/**\n * Wraps hooks with error handling to prevent hook errors from breaking processing.\n * All hooks become safe to call and will catch any errors internally.\n */\nexport class SafeHooks {\n private readonly hooks: MatadorHooks;\n\n /** The logger instance used by Matador. */\n readonly logger: Logger;\n\n constructor(hooks: MatadorHooks = {}) {\n this.hooks = hooks;\n this.logger = hooks.logger ?? consoleLogger;\n }\n\n async onEnqueueSuccess(context: EnqueueSuccessContext): Promise<void> {\n await this.safeCall('onEnqueueSuccess', () =>\n this.hooks.onEnqueueSuccess?.(context),\n );\n }\n\n async onEnqueueError(context: EnqueueErrorContext): Promise<void> {\n await this.safeCall('onEnqueueError', () =>\n this.hooks.onEnqueueError?.(context),\n );\n }\n\n async onWorkerWrap(\n envelope: Envelope,\n subscriber: SubscriberDefinition,\n execute: WorkerExecuteFn,\n ): Promise<void> {\n if (this.hooks.onWorkerWrap) {\n try {\n await this.hooks.onWorkerWrap(envelope, subscriber, execute);\n } catch (error) {\n this.logger.warn(\n '[Matador] 🟡 Hook onWorkerWrap threw an error',\n error,\n );\n // Still try to execute if wrap failed\n await execute();\n }\n } else {\n await execute();\n }\n }\n\n async onWorkerBeforeProcess(\n envelope: Envelope,\n subscriber: SubscriberDefinition,\n ): Promise<void> {\n await this.safeCall('onWorkerBeforeProcess', () =>\n this.hooks.onWorkerBeforeProcess?.(envelope, subscriber),\n );\n }\n\n async onWorkerSuccess(context: WorkerSuccessContext): Promise<void> {\n await this.safeCall('onWorkerSuccess', () =>\n this.hooks.onWorkerSuccess?.(context),\n );\n }\n\n async onWorkerError(context: WorkerErrorContext): Promise<void> {\n await this.safeCall('onWorkerError', () =>\n this.hooks.onWorkerError?.(context),\n );\n }\n\n async onDecodeError(context: DecodeErrorContext): Promise<void> {\n await this.safeCall('onDecodeError', () =>\n this.hooks.onDecodeError?.(context),\n );\n }\n\n async onConnectionStateChange(state: ConnectionState): Promise<void> {\n await this.safeCall('onConnectionStateChange', () =>\n this.hooks.onConnectionStateChange?.(state),\n );\n }\n\n async loadUniversalMetadata(): Promise<Record<string, unknown>> {\n if (!this.hooks.loadUniversalMetadata) {\n return {};\n }\n\n try {\n const result = await this.hooks.loadUniversalMetadata();\n return result ?? {};\n } catch (error) {\n this.logger.warn(\n '[Matador] 🟡 Hook loadUniversalMetadata threw an error',\n error,\n );\n return {};\n }\n }\n\n async getRetryDelay(\n envelope: Envelope,\n attemptNumber: number,\n ): Promise<number | undefined> {\n if (!this.hooks.getRetryDelay) {\n return undefined;\n }\n\n try {\n return await this.hooks.getRetryDelay(envelope, attemptNumber);\n } catch (error) {\n this.logger.warn('[Matador] 🟡 Hook getRetryDelay threw an error', error);\n return undefined;\n }\n }\n\n async getAttempts(envelope: Envelope): Promise<number | undefined> {\n if (!this.hooks.getAttempts) {\n return undefined;\n }\n\n try {\n return await this.hooks.getAttempts(envelope);\n } catch (error) {\n this.logger.warn('[Matador] 🟡 Hook getAttempts threw an error', error);\n return undefined;\n }\n }\n\n async getMaxDeliveries(envelope: Envelope): Promise<number | undefined> {\n if (!this.hooks.getMaxDeliveries) {\n return undefined;\n }\n\n try {\n return await this.hooks.getMaxDeliveries(envelope);\n } catch (error) {\n this.logger.warn(\n '[Matador] 🟡 Hook getMaxDeliveries threw an error',\n error,\n );\n return undefined;\n }\n }\n\n // === Checkpoint Hooks ===\n\n async onCheckpointLoaded(context: CheckpointLoadedContext): Promise<void> {\n await this.safeCall('onCheckpointLoaded', () =>\n this.hooks.onCheckpointLoaded?.(context),\n );\n }\n\n async onCheckpointHit(context: CheckpointHitContext): Promise<void> {\n await this.safeCall('onCheckpointHit', () =>\n this.hooks.onCheckpointHit?.(context),\n );\n }\n\n async onCheckpointMiss(context: CheckpointMissContext): Promise<void> {\n await this.safeCall('onCheckpointMiss', () =>\n this.hooks.onCheckpointMiss?.(context),\n );\n }\n\n async onCheckpointCleared(context: CheckpointClearedContext): Promise<void> {\n await this.safeCall('onCheckpointCleared', () =>\n this.hooks.onCheckpointCleared?.(context),\n );\n }\n\n private async safeCall(\n hookName: string,\n fn: () => void | Promise<void> | undefined,\n ): Promise<void> {\n try {\n await fn();\n } catch (error) {\n this.logger.warn(`[Matador] 🟡 Hook ${hookName} threw an error`, error);\n }\n }\n}\n","import { type Logger, consoleLogger } from '../hooks/index.js';\n\n/**\n * Shutdown state.\n */\nexport type ShutdownState =\n | 'running'\n | 'receive-stopped'\n | 'stopping-receive'\n | 'waiting-handlers'\n | 'stopping-enqueue'\n | 'disconnecting'\n | 'stopped';\n\n/**\n * Configuration for shutdown manager.\n */\nexport interface ShutdownConfig {\n /** Timeout for graceful shutdown in milliseconds */\n readonly gracefulShutdownTimeout: number;\n\n /** Polling interval when waiting for handlers to idle */\n readonly idlePollingInterval: number;\n\n /** Logger for shutdown events (defaults to console) */\n readonly logger: Logger;\n}\n\n/**\n * Default shutdown configuration.\n */\nexport const defaultShutdownConfig: ShutdownConfig = {\n gracefulShutdownTimeout: 30000,\n idlePollingInterval: 1000,\n logger: consoleLogger,\n};\n\n/**\n * Handler state tracking.\n */\nexport interface HandlersState {\n readonly eventsBeingProcessed: number;\n readonly eventsBeingEnqueued: number;\n readonly isIdle: boolean;\n}\n\n/**\n * Manages graceful shutdown of Matador.\n *\n * Shutdown sequence:\n * 1. Stop receiving new messages\n * 2. Wait for in-flight processing to complete\n * 3. Stop accepting new enqueue requests\n * 4. Disconnect transport\n */\nexport class ShutdownManager {\n private _state: ShutdownState = 'running';\n private readonly config: ShutdownConfig;\n private eventsBeingProcessed = 0;\n private acceptingEnqueue = true;\n\n constructor(\n private readonly getEnqueueCount: () => number,\n private readonly stopReceiving: () => Promise<void>,\n private readonly disconnectTransport: () => Promise<void>,\n config: Partial<ShutdownConfig> = {},\n ) {\n this.config = { ...defaultShutdownConfig, ...config };\n }\n\n /**\n * Current shutdown state.\n */\n get state(): ShutdownState {\n return this._state;\n }\n\n /**\n * Whether enqueue is currently allowed.\n */\n get isEnqueueAllowed(): boolean {\n return this.acceptingEnqueue;\n }\n\n /**\n * Gets current handler state.\n */\n getHandlersState(): HandlersState {\n const eventsBeingEnqueued = this.getEnqueueCount();\n return {\n eventsBeingProcessed: this.eventsBeingProcessed,\n eventsBeingEnqueued,\n isIdle: this.eventsBeingProcessed === 0 && eventsBeingEnqueued === 0,\n };\n }\n\n /**\n * Increment processing counter.\n */\n incrementProcessing(): void {\n this.eventsBeingProcessed++;\n }\n\n /**\n * Decrement processing counter.\n */\n decrementProcessing(): void {\n this.eventsBeingProcessed--;\n }\n\n /**\n * Stops receiving new messages without performing full shutdown.\n * After calling this, no new messages will be delivered from the transport.\n * The transport remains connected for later shutdown.\n *\n * Use this when you need to stop receiving before waiting for idle,\n * for example to coordinate waiting across multiple systems.\n *\n * @returns true if receiving was stopped, false if already stopped or shutting down\n */\n async publicStopReceiving(): Promise<boolean> {\n if (this._state !== 'running') {\n return false;\n }\n\n this._state = 'stopping-receive';\n await this.stopReceiving();\n this._state = 'receive-stopped';\n return true;\n }\n\n /**\n * Performs graceful shutdown.\n */\n async shutdown(): Promise<void> {\n // Allow shutdown from either 'running' or 'receive-stopped' states\n if (this._state !== 'running' && this._state !== 'receive-stopped') {\n return;\n }\n\n // 1. Stop receiving new messages (skip if already stopped)\n if (this._state === 'running') {\n this._state = 'stopping-receive';\n await this.stopReceiving();\n }\n\n // 2. Wait for handlers to idle\n this._state = 'waiting-handlers';\n await this.waitForIdle();\n\n // 3. Stop accepting new enqueue requests\n this._state = 'stopping-enqueue';\n this.acceptingEnqueue = false;\n\n // 4. Disconnect transport\n this._state = 'disconnecting';\n await this.disconnectTransport();\n\n this._state = 'stopped';\n }\n\n /**\n * Forcefully stops without waiting.\n */\n async forceStop(): Promise<void> {\n this.acceptingEnqueue = false;\n await this.stopReceiving();\n await this.disconnectTransport();\n this._state = 'stopped';\n }\n\n private async waitForIdle(): Promise<void> {\n const deadline = Date.now() + this.config.gracefulShutdownTimeout;\n\n while (!this.getHandlersState().isIdle) {\n if (Date.now() > deadline) {\n this.config.logger.warn(\n `[Matador] 🟡 Shutdown timeout reached with ${this.eventsBeingProcessed} events still processing`,\n );\n break;\n }\n\n await this.sleep(this.config.idlePollingInterval);\n }\n }\n\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n}\n","import type { HasDescription } from '../errors/index.js';\nimport type { Envelope } from '../types/index.js';\n\n/**\n * Codec interface for serializing/deserializing envelopes.\n */\nexport interface Codec {\n /**\n * Encodes an envelope to a buffer for transport.\n */\n encode(envelope: Envelope): Uint8Array;\n\n /**\n * Decodes a buffer back to an envelope.\n * @throws Error if the buffer is invalid or cannot be decoded\n */\n decode(buffer: Uint8Array): Envelope;\n\n /**\n * MIME content type for this codec.\n */\n readonly contentType: string;\n}\n\n/**\n * Error thrown when decoding fails.\n */\nexport class CodecDecodeError extends Error implements HasDescription {\n readonly description =\n 'Failed to decode a message from the transport. This typically indicates ' +\n 'corrupted data, incompatible codec versions, or messages from a different ' +\n 'system. Check the cause property for the underlying parsing error. ' +\n 'The message will be sent to the dead-letter queue for investigation.';\n\n constructor(\n message: string,\n public readonly cause?: unknown,\n ) {\n super(message);\n this.name = 'CodecDecodeError';\n }\n}\n","import type { Envelope } from '../types/index.js';\nimport type { Codec } from './codec.js';\nimport { CodecDecodeError } from './codec.js';\n\n/**\n * JSON codec for envelope serialization.\n * Uses standard JSON.stringify/parse with Date handling.\n */\nexport class JsonCodec implements Codec {\n readonly contentType = 'application/json';\n\n encode(envelope: Envelope): Uint8Array {\n const json = JSON.stringify(envelope);\n return new TextEncoder().encode(json);\n }\n\n decode(buffer: Uint8Array): Envelope {\n if (buffer.length === 0) {\n throw new CodecDecodeError('Cannot decode empty buffer');\n }\n\n let json: string;\n try {\n json = new TextDecoder('utf-8').decode(buffer);\n } catch (error) {\n throw new CodecDecodeError('Invalid UTF-8 encoding', error);\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(json);\n } catch (error) {\n throw new CodecDecodeError('Invalid JSON', error);\n }\n\n if (!this.isValidEnvelope(parsed)) {\n throw new CodecDecodeError('Invalid envelope structure');\n }\n\n return parsed;\n }\n\n private isValidEnvelope(value: unknown): value is Envelope {\n if (typeof value !== 'object' || value === null) {\n return false;\n }\n\n const envelope = value as Record<string, unknown>;\n\n // Required top-level fields\n if (typeof envelope.id !== 'string') return false;\n if (!('data' in envelope)) return false;\n if (typeof envelope.docket !== 'object' || envelope.docket === null)\n return false;\n\n // Validate docket (routing, processing state, observability)\n const docket = envelope.docket as Record<string, unknown>;\n // Routing\n if (typeof docket.eventKey !== 'string') return false;\n if (typeof docket.targetSubscriber !== 'string') return false;\n // Processing state\n if (typeof docket.attempts !== 'number') return false;\n if (typeof docket.createdAt !== 'string') return false;\n // Observability\n if (typeof docket.importance !== 'string') return false;\n\n return true;\n }\n}\n","import type { Docket, Envelope } from '../types/index.js';\nimport { CodecDecodeError } from './codec.js';\nimport type { EncodedMessage, HeaderAwareCodec } from './header-aware-codec.js';\n\n/**\n * Header names used by Matador in RabbitMQ messages.\n */\nconst HEADERS = {\n // Routing\n EVENT_KEY: 'x-matador-event-key',\n TARGET_SUBSCRIBER: 'x-matador-subscriber',\n SCHEDULED_FOR: 'x-matador-scheduled-for',\n ORIGINAL_QUEUE: 'x-matador-original-queue',\n\n // Processing state\n ATTEMPTS: 'x-matador-attempts',\n CREATED_AT: 'x-matador-created-at',\n FIRST_ERROR: 'x-matador-first-error',\n LAST_ERROR: 'x-matador-last-error',\n\n // Observability\n IMPORTANCE: 'x-matador-importance',\n CORRELATION_ID: 'x-matador-correlation-id',\n\n // v1 compatibility headers\n V1_EVENT_ID: 'x-event-id',\n V1_CORRELATION_ID: 'x-correlation-id',\n V1_USER_ID: 'x-user-id',\n} as const;\n\n/**\n * Body structure for v2 messages.\n * Only contains id, data, and optionally metadata (since it can be large).\n */\ninterface V2Body {\n readonly id: string;\n readonly data: unknown;\n readonly metadata?: Record<string, unknown>;\n}\n\n/**\n * v1 message format (for backwards compatibility).\n */\ninterface V1Body {\n key: string;\n data: unknown;\n metadata: unknown;\n universal?: {\n event_id?: string | null;\n user_id?: string | null;\n correlation_id?: string | null;\n [key: string]: unknown;\n };\n before?: unknown;\n options?: { delayMs?: number };\n targetSubscriber: string;\n}\n\n/**\n * RabbitMQ-specific codec that stores routing/metadata in headers.\n *\n * Benefits:\n * - No duplication between body and headers\n * - RabbitMQ can route/filter based on headers\n * - Smaller message body\n * - v1 message format compatibility built-in\n */\nexport class RabbitMQCodec implements HeaderAwareCodec {\n readonly contentType = 'application/json';\n\n encode(envelope: Envelope): EncodedMessage {\n const { docket } = envelope;\n\n // Body only contains id, data, and metadata (since metadata can be large)\n const body: V2Body = {\n id: envelope.id,\n data: envelope.data,\n ...(docket.metadata !== undefined && { metadata: docket.metadata }),\n };\n\n // All docket fields go in headers\n const headers: Record<string, unknown> = {\n // Routing\n [HEADERS.EVENT_KEY]: docket.eventKey,\n [HEADERS.TARGET_SUBSCRIBER]: docket.targetSubscriber,\n\n // Processing state\n [HEADERS.ATTEMPTS]: docket.attempts,\n [HEADERS.CREATED_AT]: docket.createdAt,\n\n // Observability\n [HEADERS.IMPORTANCE]: docket.importance,\n };\n\n // Optional fields\n if (docket.scheduledFor !== undefined) {\n headers[HEADERS.SCHEDULED_FOR] = docket.scheduledFor;\n }\n if (docket.originalQueue !== undefined) {\n headers[HEADERS.ORIGINAL_QUEUE] = docket.originalQueue;\n }\n if (docket.firstError !== undefined) {\n headers[HEADERS.FIRST_ERROR] = docket.firstError;\n }\n if (docket.lastError !== undefined) {\n headers[HEADERS.LAST_ERROR] = docket.lastError;\n }\n if (docket.correlationId !== undefined) {\n headers[HEADERS.CORRELATION_ID] = docket.correlationId;\n }\n\n return {\n body: new TextEncoder().encode(JSON.stringify(body)),\n headers,\n contentType: this.contentType,\n };\n }\n\n decode(body: Uint8Array, headers: Record<string, unknown>): Envelope {\n if (body.length === 0) {\n throw new CodecDecodeError('Cannot decode empty buffer');\n }\n\n let json: string;\n try {\n json = new TextDecoder('utf-8').decode(body);\n } catch (error) {\n throw new CodecDecodeError('Invalid UTF-8 encoding', error);\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(json);\n } catch (error) {\n throw new CodecDecodeError('Invalid JSON', error);\n }\n\n // Detect format: v1 has 'key' and 'targetSubscriber' at top level\n if (this.isV1Body(parsed)) {\n return this.decodeV1(parsed, headers);\n }\n\n // v2 format\n if (!this.isV2Body(parsed)) {\n throw new CodecDecodeError('Invalid message body structure');\n }\n\n return this.decodeV2(parsed, headers);\n }\n\n private isV1Body(value: unknown): value is V1Body {\n if (typeof value !== 'object' || value === null) return false;\n const obj = value as Record<string, unknown>;\n return (\n typeof obj.key === 'string' &&\n typeof obj.targetSubscriber === 'string' &&\n 'data' in obj &&\n !('payload' in obj)\n );\n }\n\n private isV2Body(value: unknown): value is V2Body {\n if (typeof value !== 'object' || value === null) return false;\n const obj = value as Record<string, unknown>;\n return (\n typeof obj.id === 'string' && 'data' in obj && !('key' in obj) // Distinguish from v1 which also has 'data'\n );\n }\n\n private decodeV2(body: V2Body, headers: Record<string, unknown>): Envelope {\n // Required headers\n const eventKey = this.requireStringHeader(headers, HEADERS.EVENT_KEY);\n const targetSubscriber = this.requireStringHeader(\n headers,\n HEADERS.TARGET_SUBSCRIBER,\n );\n const attempts = this.requireNumberHeader(headers, HEADERS.ATTEMPTS);\n const createdAt = this.requireStringHeader(headers, HEADERS.CREATED_AT);\n const importance = this.requireStringHeader(headers, HEADERS.IMPORTANCE);\n\n // Optional headers\n const scheduledFor = this.optionalStringHeader(\n headers,\n HEADERS.SCHEDULED_FOR,\n );\n const originalQueue = this.optionalStringHeader(\n headers,\n HEADERS.ORIGINAL_QUEUE,\n );\n const firstError = this.optionalStringHeader(headers, HEADERS.FIRST_ERROR);\n const lastError = this.optionalStringHeader(headers, HEADERS.LAST_ERROR);\n const correlationId = this.optionalStringHeader(\n headers,\n HEADERS.CORRELATION_ID,\n );\n\n const docket: Docket = {\n // Routing\n eventKey,\n targetSubscriber,\n ...(scheduledFor !== undefined && { scheduledFor }),\n ...(originalQueue !== undefined && { originalQueue }),\n // Processing state\n attempts,\n createdAt,\n ...(firstError !== undefined && { firstError }),\n ...(lastError !== undefined && { lastError }),\n // Observability\n importance: importance as Docket['importance'],\n ...(correlationId !== undefined && { correlationId }),\n ...(body.metadata !== undefined && { metadata: body.metadata }),\n };\n\n return {\n id: body.id,\n data: body.data,\n docket,\n };\n }\n\n /**\n * Decodes a v1 format message for backwards compatibility.\n * v1 format: { key, data, metadata, universal, targetSubscriber, ... }\n */\n private decodeV1(body: V1Body, headers: Record<string, unknown>): Envelope {\n const { event_id, user_id, correlation_id, ...otherUniversal } =\n body.universal ?? {};\n\n // Merge metadata: event metadata + remaining universal fields\n const mergedMetadata: Record<string, unknown> = {};\n if (body.metadata && typeof body.metadata === 'object') {\n Object.assign(mergedMetadata, body.metadata);\n }\n if (user_id !== undefined && user_id !== null) {\n mergedMetadata.user_id = user_id;\n }\n Object.assign(mergedMetadata, otherUniversal);\n\n // Try to get attempts from header (v1 also uses x-matador-attempts)\n const attempts =\n typeof headers[HEADERS.ATTEMPTS] === 'number'\n ? (headers[HEADERS.ATTEMPTS] as number)\n : 1;\n\n // Try to get importance from header\n const importance =\n typeof headers[HEADERS.IMPORTANCE] === 'string'\n ? (headers[HEADERS.IMPORTANCE] as string)\n : 'should-investigate';\n\n // Get correlation ID from either v1 or v2 header\n const correlationId =\n (headers[HEADERS.CORRELATION_ID] as string | undefined) ??\n (headers[HEADERS.V1_CORRELATION_ID] as string | undefined) ??\n correlation_id ??\n undefined;\n\n // Get event ID from v1 header or body\n const eventId =\n (headers[HEADERS.V1_EVENT_ID] as string | undefined) ??\n event_id ??\n crypto.randomUUID();\n\n const now = new Date().toISOString();\n\n // Calculate scheduledFor if delayMs was specified (though it's likely already passed)\n let scheduledFor: string | undefined;\n if (body.options?.delayMs) {\n scheduledFor = new Date(Date.now() + body.options.delayMs).toISOString();\n }\n\n const docket: Docket = {\n // Routing\n eventKey: body.key,\n targetSubscriber: body.targetSubscriber,\n ...(scheduledFor !== undefined && { scheduledFor }),\n // Processing state\n attempts,\n createdAt: now,\n // Observability\n importance: importance as Docket['importance'],\n ...(correlationId !== undefined && { correlationId }),\n ...(Object.keys(mergedMetadata).length > 0 && {\n metadata: mergedMetadata,\n }),\n };\n\n return {\n id: eventId,\n data: body.data,\n docket,\n };\n }\n\n private requireStringHeader(\n headers: Record<string, unknown>,\n name: string,\n ): string {\n const value = headers[name];\n if (value === undefined) {\n throw new CodecDecodeError(`Missing required header: ${name}`);\n }\n if (typeof value !== 'string') {\n throw new CodecDecodeError(\n `Header ${name} must be string, got ${typeof value}`,\n );\n }\n return value;\n }\n\n private requireNumberHeader(\n headers: Record<string, unknown>,\n name: string,\n ): number {\n const value = headers[name];\n if (value === undefined) {\n throw new CodecDecodeError(`Missing required header: ${name}`);\n }\n if (typeof value !== 'number') {\n throw new CodecDecodeError(\n `Header ${name} must be number, got ${typeof value}`,\n );\n }\n return value;\n }\n\n private optionalStringHeader(\n headers: Record<string, unknown>,\n name: string,\n ): string | undefined {\n const value = headers[name];\n if (value === undefined) return undefined;\n if (typeof value !== 'string') return undefined;\n return value;\n }\n}\n","import { DuplicateIoKeyError } from '../errors/index.js';\nimport type { Envelope, SubscriberDefinition } from '../types/index.js';\nimport type {\n Checkpoint,\n CheckpointHitContext,\n CheckpointMissContext,\n CheckpointStore,\n JsonSerializable,\n SubscriberContext,\n} from './types.js';\n\n/**\n * Hooks for observability during context operations.\n */\nexport interface ResumableContextHooks {\n onCheckpointHit?(context: CheckpointHitContext): void | Promise<void>;\n onCheckpointMiss?(context: CheckpointMissContext): void | Promise<void>;\n}\n\n/**\n * Configuration for creating a ResumableContext.\n */\nexport interface ResumableContextConfig {\n readonly store: CheckpointStore;\n readonly envelope: Envelope;\n readonly subscriber: SubscriberDefinition;\n readonly existingCheckpoint?: Checkpoint | undefined;\n readonly hooks?: ResumableContextHooks | undefined;\n}\n\n/**\n * Implementation of SubscriberContext that provides io() caching.\n *\n * On first execution, io() calls execute their lambdas and cache results.\n * On retry (when existingCheckpoint is provided), cached results are returned\n * without re-executing the lambda.\n */\nexport class ResumableContext implements SubscriberContext {\n private checkpoint: Checkpoint;\n private readonly usedKeys = new Set<string>();\n private readonly store: CheckpointStore;\n private readonly envelope: Envelope;\n private readonly subscriber: SubscriberDefinition;\n private readonly hooks: ResumableContextHooks | undefined;\n\n constructor(config: ResumableContextConfig) {\n this.store = config.store;\n this.envelope = config.envelope;\n this.subscriber = config.subscriber;\n this.hooks = config.hooks;\n\n this.checkpoint = config.existingCheckpoint ?? {\n envelopeId: config.envelope.id,\n subscriberName: config.subscriber.name,\n completedSteps: {},\n };\n }\n\n get attempt(): number {\n return this.envelope.docket.attempts;\n }\n\n get isRetry(): boolean {\n return this.attempt > 1;\n }\n\n async io<T extends JsonSerializable>(\n key: string,\n fn: () => Promise<T> | T,\n ): Promise<T> {\n // Validate key uniqueness within this execution\n if (this.usedKeys.has(key)) {\n throw new DuplicateIoKeyError(key, this.subscriber.name);\n }\n this.usedKeys.add(key);\n\n // Check cache first\n if (key in this.checkpoint.completedSteps) {\n await this.hooks?.onCheckpointHit?.({\n envelope: this.envelope,\n subscriber: this.subscriber,\n stepKey: key,\n });\n return this.checkpoint.completedSteps[key] as T;\n }\n\n // Notify cache miss\n await this.hooks?.onCheckpointMiss?.({\n envelope: this.envelope,\n subscriber: this.subscriber,\n stepKey: key,\n });\n\n // Execute the function - errors propagate, no caching on failure\n const result = await fn();\n\n // Cache the result\n this.checkpoint = {\n ...this.checkpoint,\n completedSteps: {\n ...this.checkpoint.completedSteps,\n [key]: result,\n },\n };\n\n // Persist checkpoint immediately (incremental persistence)\n await this.store.set(this.envelope.id, this.checkpoint);\n\n return result;\n }\n\n async all<\n T extends readonly [\n string,\n () => Promise<JsonSerializable> | JsonSerializable,\n ][],\n >(\n ops: T,\n ): Promise<{\n [K in keyof T]: T[K] extends [string, () => Promise<infer R>]\n ? R\n : T[K] extends [string, () => infer R]\n ? R\n : never;\n }> {\n // First, check for duplicates within this all() call\n const keysInThisCall = new Set<string>();\n for (const [key] of ops) {\n if (keysInThisCall.has(key)) {\n throw new DuplicateIoKeyError(key, this.subscriber.name);\n }\n keysInThisCall.add(key);\n }\n\n // Then validate against previously used keys\n for (const [key] of ops) {\n if (this.usedKeys.has(key)) {\n throw new DuplicateIoKeyError(key, this.subscriber.name);\n }\n }\n\n // Mark all keys as used\n for (const [key] of ops) {\n this.usedKeys.add(key);\n }\n\n // Execute all operations in parallel\n const results = await Promise.all(\n ops.map(async ([key, fn]) => {\n // Check cache first\n if (key in this.checkpoint.completedSteps) {\n await this.hooks?.onCheckpointHit?.({\n envelope: this.envelope,\n subscriber: this.subscriber,\n stepKey: key,\n });\n return this.checkpoint.completedSteps[key];\n }\n\n // Notify cache miss\n await this.hooks?.onCheckpointMiss?.({\n envelope: this.envelope,\n subscriber: this.subscriber,\n stepKey: key,\n });\n\n // Execute - errors propagate\n const result = await fn();\n\n // Cache individually (in local state, will persist after Promise.all)\n this.checkpoint = {\n ...this.checkpoint,\n completedSteps: {\n ...this.checkpoint.completedSteps,\n [key]: result,\n },\n };\n\n return result;\n }),\n );\n\n // Persist after all parallel operations complete\n await this.store.set(this.envelope.id, this.checkpoint);\n\n return results as {\n [K in keyof T]: T[K] extends [string, () => Promise<infer R>]\n ? R\n : T[K] extends [string, () => infer R]\n ? R\n : never;\n };\n }\n\n /**\n * Clears the checkpoint from storage.\n * Called after successful completion or dead-letter.\n */\n async clear(): Promise<void> {\n await this.store.delete(this.envelope.id);\n }\n\n /**\n * Gets the current checkpoint state.\n * Useful for debugging and testing.\n */\n getCheckpoint(): Checkpoint {\n return this.checkpoint;\n }\n\n /**\n * Gets the number of cached steps.\n */\n get cachedStepCount(): number {\n return Object.keys(this.checkpoint.completedSteps).length;\n }\n}\n","import type { Checkpoint, CheckpointStore } from '../types.js';\n\n/**\n * In-memory checkpoint store for testing and development.\n * Checkpoints are lost when the process restarts.\n *\n * For production use, implement a persistent store (e.g., RedisCheckpointStore).\n */\nexport class MemoryCheckpointStore implements CheckpointStore {\n private readonly checkpoints = new Map<string, Checkpoint>();\n\n async get(envelopeId: string): Promise<Checkpoint | undefined> {\n return this.checkpoints.get(envelopeId);\n }\n\n async set(envelopeId: string, checkpoint: Checkpoint): Promise<void> {\n this.checkpoints.set(envelopeId, checkpoint);\n }\n\n async delete(envelopeId: string): Promise<void> {\n this.checkpoints.delete(envelopeId);\n }\n\n /**\n * Gets the number of stored checkpoints.\n * Useful for testing.\n */\n get size(): number {\n return this.checkpoints.size;\n }\n\n /**\n * Clears all stored checkpoints.\n * Useful for testing.\n */\n clear(): void {\n this.checkpoints.clear();\n }\n\n /**\n * Gets all stored checkpoint IDs.\n * Useful for testing.\n */\n keys(): string[] {\n return [...this.checkpoints.keys()];\n }\n}\n","import type { Checkpoint, CheckpointStore } from '../types.js';\n\n/**\n * No-operation checkpoint store that doesn't persist anything.\n * Used when no checkpoint store is configured.\n *\n * With this store, resumable subscribers will work but checkpoints\n * won't persist across retries - all io() operations will re-execute.\n */\nexport class NoOpCheckpointStore implements CheckpointStore {\n async get(_envelopeId: string): Promise<Checkpoint | undefined> {\n return undefined;\n }\n\n async set(_envelopeId: string, _checkpoint: Checkpoint): Promise<void> {\n // No-op\n }\n\n async delete(_envelopeId: string): Promise<void> {\n // No-op\n }\n}\n","import type { Checkpoint, CheckpointStore } from '../checkpoint/index.js';\nimport { NoOpCheckpointStore, ResumableContext } from '../checkpoint/index.js';\nimport type { Codec } from '../codec/index.js';\nimport { CodecDecodeError } from '../codec/index.js';\nimport {\n SubscriberIsStubError,\n SubscriberNotRegisteredError,\n} from '../errors/index.js';\nimport type { SafeHooks } from '../hooks/index.js';\nimport type { RetryDecision, RetryPolicy } from '../retry/index.js';\nimport type { SchemaRegistry } from '../schema/index.js';\nimport type { MessageReceipt, Transport } from '../transport/index.js';\nimport type {\n CallbackContext,\n Dispatcher,\n Envelope,\n ResumableCallbackContext,\n SubscriberDefinition,\n} from '../types/index.js';\nimport { isResumableSubscriber } from '../types/index.js';\n\n/**\n * Configuration for the processing pipeline.\n */\nexport interface PipelineConfig {\n readonly transport: Transport;\n readonly schema: SchemaRegistry;\n readonly codec: Codec;\n readonly retryPolicy: RetryPolicy;\n readonly hooks: SafeHooks;\n /** Optional checkpoint store for resumable subscribers */\n readonly checkpointStore?: CheckpointStore | undefined;\n /** Dispatcher (matador) for sending events from subscriber callbacks */\n readonly dispatcher: Dispatcher;\n}\n\n/**\n * Result of pipeline processing.\n */\nexport interface ProcessResult {\n readonly success: boolean;\n readonly envelope?: Envelope | undefined;\n readonly subscriber?: SubscriberDefinition | undefined;\n readonly error?: Error | undefined;\n readonly decision?: RetryDecision | undefined;\n readonly durationMs: number;\n}\n\n/**\n * Processing pipeline for incoming messages.\n *\n * Handles the complete message lifecycle:\n * 1. Decode envelope from raw bytes\n * 2. Lookup subscriber from schema\n * 3. Pre-execution poison check (retry policy, before running the callback)\n * 4. Execute subscriber callback with hooks\n * 5. Handle success\n * 6. Handle failure with retry policy\n */\nexport class ProcessingPipeline {\n private readonly transport: Transport;\n private readonly schema: SchemaRegistry;\n private readonly codec: Codec;\n private readonly retryPolicy: RetryPolicy;\n private readonly hooks: SafeHooks;\n private readonly checkpointStore: CheckpointStore;\n private readonly dispatcher: Dispatcher;\n\n constructor(config: PipelineConfig) {\n this.transport = config.transport;\n this.schema = config.schema;\n this.codec = config.codec;\n this.retryPolicy = config.retryPolicy;\n this.hooks = config.hooks;\n this.checkpointStore = config.checkpointStore ?? new NoOpCheckpointStore();\n this.dispatcher = config.dispatcher;\n }\n\n /**\n * Processes a raw message from the transport.\n */\n async process(\n rawMessage: Uint8Array,\n receipt: MessageReceipt,\n ): Promise<ProcessResult> {\n const startTime = performance.now();\n\n // 1. Decode envelope\n let envelope: Envelope;\n try {\n envelope = this.codec.decode(rawMessage);\n } catch (error) {\n const decodeError =\n error instanceof CodecDecodeError\n ? error\n : new CodecDecodeError('Unknown decode error', error);\n\n await this.transport.complete(receipt);\n await this.hooks.onDecodeError({\n error: decodeError,\n rawMessage,\n sourceQueue: receipt.sourceQueue,\n transport: receipt.sourceTransport,\n });\n\n return {\n success: false,\n error: decodeError,\n durationMs: performance.now() - startTime,\n };\n }\n\n // 2. Lookup subscriber from schema\n const subscriberDef = this.schema.getSubscriberDefinition(\n envelope.docket.eventKey,\n envelope.docket.targetSubscriber,\n );\n\n if (!subscriberDef) {\n const error = new SubscriberNotRegisteredError(\n envelope.docket.targetSubscriber,\n envelope.docket.eventKey,\n );\n\n // Retry unhandled messages (likely deployment timing issue)\n const decision = this.getUnhandledRetryDecision(envelope, receipt, error);\n await this.handleRetryDecision(receipt, envelope, decision);\n\n return {\n success: false,\n envelope,\n error,\n decision,\n durationMs: performance.now() - startTime,\n };\n }\n\n // Get executable subscriber\n const subscriber = this.schema.getExecutableSubscriber(\n envelope.docket.eventKey,\n envelope.docket.targetSubscriber,\n );\n\n if (!subscriber) {\n // Subscriber is a stub (remote implementation)\n const error = new SubscriberIsStubError(envelope.docket.targetSubscriber);\n\n // Retry stub messages (likely deployment timing issue)\n const decision = this.getUnhandledRetryDecision(envelope, receipt, error);\n await this.handleRetryDecision(receipt, envelope, decision);\n\n return {\n success: false,\n envelope,\n subscriber: subscriberDef,\n error,\n decision,\n durationMs: performance.now() - startTime,\n };\n }\n\n const isResumable = isResumableSubscriber(subscriber);\n\n // 3. Pre-execution poison check, based on delivery metadata alone.\n //\n // Catches a message that's already known-poisoned (e.g. delivery count at/above the threshold)\n // before running the callback\n const shouldProcessResult = await this.handleShouldProcess(\n envelope,\n subscriberDef,\n isResumable,\n receipt,\n startTime,\n );\n // If the message is poisoned, return the result immediately\n if (!shouldProcessResult.success) {\n return shouldProcessResult;\n }\n\n // 4. Execute subscriber callback with hooks\n let result: unknown;\n let error: Error | undefined;\n let context: ResumableContext | undefined;\n let existingCheckpoint: Checkpoint | undefined;\n\n // For resumable subscribers, load existing checkpoint and create context\n if (isResumable) {\n existingCheckpoint = await this.checkpointStore.get(envelope.id);\n\n if (existingCheckpoint) {\n await this.hooks.onCheckpointLoaded?.({\n envelope,\n subscriber: subscriberDef,\n checkpoint: existingCheckpoint,\n cachedSteps: Object.keys(existingCheckpoint.completedSteps).length,\n });\n }\n\n context = new ResumableContext({\n store: this.checkpointStore,\n envelope,\n subscriber: subscriberDef,\n existingCheckpoint,\n hooks: {\n onCheckpointHit: (ctx) => this.hooks.onCheckpointHit?.(ctx),\n onCheckpointMiss: (ctx) => this.hooks.onCheckpointMiss?.(ctx),\n },\n });\n }\n\n // Create base callback context with matador dispatcher\n const callbackContext: CallbackContext = { matador: this.dispatcher };\n\n await this.hooks.onWorkerWrap(envelope, subscriberDef, async () => {\n await this.hooks.onWorkerBeforeProcess(envelope, subscriberDef);\n\n try {\n if (isResumable && context) {\n // Resumable subscriber: pass combined context (checkpoint + matador)\n // Cast needed because TypeScript can't narrow the union type based on isResumable\n const resumableCallback = subscriber.callback as (\n envelope: Envelope,\n context: ResumableCallbackContext,\n ) => Promise<void> | void;\n // Create combined context by binding class methods and adding matador\n const fullContext: ResumableCallbackContext = {\n io: context.io.bind(context),\n all: context.all.bind(context),\n attempt: context.attempt,\n isRetry: context.isRetry,\n matador: this.dispatcher,\n };\n result = await resumableCallback(envelope, fullContext);\n } else {\n // Standard subscriber: pass envelope and callback context\n const standardCallback = subscriber.callback as (\n envelope: Envelope,\n context: CallbackContext,\n ) => Promise<void> | void;\n result = await standardCallback(envelope, callbackContext);\n }\n } catch (e) {\n error = e instanceof Error ? e : new Error(String(e));\n }\n });\n\n const durationMs = performance.now() - startTime;\n\n // 5. Handle success\n if (!error) {\n // Clear checkpoint on success for resumable subscribers\n if (context) {\n await context.clear();\n await this.hooks.onCheckpointCleared?.({\n envelope,\n subscriber: subscriberDef,\n reason: 'success',\n });\n }\n\n await this.transport.complete(receipt);\n await this.hooks.onWorkerSuccess({\n envelope,\n subscriber: subscriberDef,\n result,\n durationMs,\n transport: receipt.sourceTransport,\n });\n\n return {\n success: true,\n envelope,\n subscriber: subscriberDef,\n durationMs,\n };\n }\n\n // 6. Handle failure - consult retry policy\n const decision = this.retryPolicy.shouldRetry({\n envelope,\n error,\n subscriber: subscriberDef,\n receipt,\n });\n\n return await this.handleFailure(\n error,\n decision,\n envelope,\n subscriberDef,\n isResumable,\n receipt,\n durationMs,\n );\n }\n\n /**\n * Runs the retry policy's pre-processing check.\n *\n * This returns a terminal `ProcessResult` if the message should be skipped (dead-lettered/discarded) without ever invoking the callback,\n * or a success result if shouldProcess passes and we should continue processing the message.\n * @param envelope - The message envelope\n * @param subscriberDef - The subscriber definition\n * @param isResumable - Whether the subscriber is resumable\n * @param receipt - The message receipt\n * @param startTime - The start time of the processing\n * @returns A `ProcessResult` indicating if we should continue with processing the message, or fail it preemptively\n */\n private async handleShouldProcess(\n envelope: Envelope,\n subscriberDef: SubscriberDefinition,\n isResumable: boolean,\n receipt: MessageReceipt,\n startTime: number,\n ): Promise<ProcessResult> {\n const decision = this.retryPolicy.shouldProcess({\n envelope,\n subscriber: subscriberDef,\n receipt,\n });\n\n // If shouldProcess passes, we can proceed with normal processing\n if (decision.action === 'process') {\n return {\n success: true,\n durationMs: 0,\n };\n }\n\n // Otherwise, the message needs to be handled accordingly (e.g. dead-lettered or discarded)\n\n const durationMs = performance.now() - startTime;\n const error = new Error(decision.reason);\n\n return await this.handleFailure(\n error,\n decision,\n envelope,\n subscriberDef,\n isResumable,\n receipt,\n durationMs,\n );\n }\n\n /**\n * Performs failure handling and cleanup based on retry decision (e.g. dead-letter).\n *\n * @param error - The error from the processing attempt\n * @param decision - The decision from executing the appropriate retry policy check\n * @param envelope - The message envelope\n * @param subscriberDef - The subscriber definition\n * @param isResumable - Whether the subscriber is resumable\n * @param receipt - The message receipt\n * @param durationMs - The duration of processing\n * @returns A `ProcessResult` indicating failure\n */\n private async handleFailure(\n error: Error,\n decision: RetryDecision,\n envelope: Envelope,\n subscriberDef: SubscriberDefinition,\n isResumable: boolean,\n receipt: MessageReceipt,\n durationMs: number,\n ): Promise<ProcessResult> {\n // Update envelope with error info\n envelope.docket.lastError = error.message;\n envelope.docket.firstError ??= error.message;\n\n // Clear checkpoint on dead-letter (terminal state)\n if (decision.action === 'dead-letter' && isResumable) {\n await this.checkpointStore.delete(envelope.id);\n await this.hooks.onCheckpointCleared?.({\n envelope,\n subscriber: subscriberDef,\n reason: 'dead-letter',\n });\n }\n\n await this.handleRetryDecision(receipt, envelope, decision);\n\n await this.hooks.onWorkerError({\n envelope,\n subscriber: subscriberDef,\n error,\n durationMs,\n decision,\n transport: receipt.sourceTransport,\n });\n\n return {\n success: false,\n envelope,\n subscriber: subscriberDef,\n error,\n decision,\n durationMs,\n };\n }\n\n private async handleRetryDecision(\n receipt: MessageReceipt,\n envelope: Envelope,\n decision: RetryDecision,\n ): Promise<void> {\n switch (decision.action) {\n case 'retry': {\n // Increment attempts and schedule retry\n envelope.docket.attempts++;\n envelope.docket.scheduledFor = new Date(\n Date.now() + decision.delay,\n ).toISOString();\n\n await this.transport.send(receipt.sourceQueue, envelope, {\n delay: decision.delay,\n });\n await this.transport.complete(receipt);\n break;\n }\n\n case 'dead-letter': {\n await this.sendToDeadLetter(\n receipt,\n envelope,\n decision.queue,\n decision.reason,\n );\n break;\n }\n\n case 'discard': {\n await this.transport.complete(receipt);\n break;\n }\n }\n }\n\n private async sendToDeadLetter(\n receipt: MessageReceipt,\n envelope: Envelope,\n dlqName: string,\n reason: string,\n ): Promise<void> {\n envelope.docket.originalQueue ??= receipt.sourceQueue;\n\n if (this.transport.sendToDeadLetter) {\n await this.transport.sendToDeadLetter(receipt, dlqName, envelope, reason);\n } else {\n // Manual: send to DLQ then complete original\n const fullDlqName = `${receipt.sourceQueue}.${dlqName}`;\n await this.transport.send(fullDlqName, envelope);\n await this.transport.complete(receipt);\n }\n }\n\n /**\n * Gets retry decision for unhandled messages (subscriber not found).\n * Uses same retry policy logic but sends to 'unhandled' DLQ after max attempts.\n */\n private getUnhandledRetryDecision(\n envelope: Envelope,\n receipt: MessageReceipt,\n error: Error,\n ): RetryDecision {\n // Create a synthetic subscriber definition for retry policy\n const syntheticSubscriber: SubscriberDefinition = {\n name: envelope.docket.targetSubscriber,\n description: 'Synthetic subscriber for unhandled message retry',\n idempotent: 'yes', // Safe to retry unhandled messages\n importance: envelope.docket.importance ?? 'should-investigate',\n };\n\n const decision = this.retryPolicy.shouldRetry({\n envelope,\n error,\n subscriber: syntheticSubscriber,\n receipt,\n });\n\n // Override dead-letter queue to 'unhandled' instead of 'undeliverable'\n if (decision.action === 'dead-letter') {\n return {\n action: 'dead-letter',\n queue: 'unhandled',\n reason: decision.reason,\n };\n }\n\n return decision;\n }\n}\n","import {\n IdempotentMessageCannotRetryError,\n MessageMaybePoisonedError,\n isAssertionError,\n isDoRetry,\n isDontRetry,\n} from '../errors/index.js';\nimport type { MessageReceipt } from '../transport/index.js';\nimport type { Envelope, SubscriberDefinition } from '../types/index.js';\nimport type {\n ProcessContext,\n ProcessDecision,\n RetryContext,\n RetryDecision,\n RetryPolicy,\n} from './policy.js';\n\n/**\n * Configuration for the standard retry policy.\n */\nexport interface StandardRetryPolicyConfig {\n /** Maximum number of attempts before dead-lettering */\n readonly maxAttempts: number;\n\n /** Base delay between retries in milliseconds */\n readonly baseDelay: number;\n\n /** Maximum delay between retries in milliseconds */\n readonly maxDelay: number;\n\n /** Multiplier for exponential backoff */\n readonly backoffMultiplier: number;\n\n /**\n * Maximum native delivery count before considering message poisoned.\n * This prevents crash loops from messages that crash the worker.\n * Poison messages are sent directly to the dead-letter queue.\n * Default: 5\n */\n readonly maxDeliveries: number;\n}\n\n/**\n * Default configuration values.\n */\nexport const defaultRetryConfig: StandardRetryPolicyConfig = {\n maxAttempts: 3,\n baseDelay: 1000,\n maxDelay: 300000, // 5 minutes\n backoffMultiplier: 2,\n maxDeliveries: 5,\n};\n\n/**\n * Standard retry policy implementing Matador v1 behavior.\n *\n * Decision logic (in priority order):\n * 1. Poison message → dead-letter (prevent crash loops)\n * 2. EventAssertionError → dead-letter (never retry)\n * 3. DontRetry → dead-letter (explicit no-retry)\n * 4. DoRetry → retry if under max attempts\n * 5. Max attempts exceeded → dead-letter\n * 6. Non-idempotent subscriber → dead-letter\n * 7. Default → retry with exponential backoff\n */\nexport class StandardRetryPolicy implements RetryPolicy {\n private readonly config: StandardRetryPolicyConfig;\n\n constructor(config: Partial<StandardRetryPolicyConfig> = {}) {\n this.config = { ...defaultRetryConfig, ...config };\n }\n\n /**\n * Check if the message should be dead-lettered before the subscriber callback is invoked.\n * This is needed when a subscriber crashes and the `shouldRetry` policy is never executed.\n *\n * Uses the same delivery-count threshold as `shouldRetry` poison check, so an\n * already-poisoned message is dead-lettered without ever running the callback again.\n *\n * Checks the subscriber idempotency setting to prevent processing when a previous attempt crashed.\n *\n * @param context - The shouldProcess context.\n * @returns A 'process' decision if subscriber processing should be attempted; a dead-letter decision otherwise.\n */\n shouldProcess(context: ProcessContext): ProcessDecision {\n // Poison message detection - prevent crash loops\n const poisonError = this.checkPoisoned(context.envelope, context.receipt);\n\n // If the message is poisoned, dead-letter it\n if (poisonError) {\n return {\n action: 'dead-letter',\n queue: 'undeliverable',\n reason: poisonError.message,\n };\n }\n\n // Non-idempotent subscriber on redelivery\n const idempotencyError = this.checkIdempotency(\n context.envelope,\n context.receipt,\n context.subscriber,\n );\n\n if (idempotencyError) {\n return {\n action: 'dead-letter',\n queue: 'undeliverable',\n reason: idempotencyError.message,\n };\n }\n\n // Allow processing to continue\n return { action: 'process' };\n }\n\n shouldRetry(context: RetryContext): RetryDecision {\n const { envelope, error, subscriber, receipt } = context;\n const errorMessage = error.message;\n\n // 1. Poison message detection - prevent crash loops\n const poisonError = this.checkPoisoned(envelope, receipt);\n\n // If the message is poisoned, dead-letter it\n if (poisonError) {\n return {\n action: 'dead-letter',\n queue: 'undeliverable',\n reason: poisonError.message,\n };\n }\n\n // 2. Assertion errors never retry\n if (isAssertionError(error)) {\n return {\n action: 'dead-letter',\n queue: 'undeliverable',\n reason: `assertion error: ${errorMessage}`,\n };\n }\n\n // 3. Explicit no-retry\n if (isDontRetry(error)) {\n return {\n action: 'dead-letter',\n queue: 'undeliverable',\n reason: errorMessage,\n };\n }\n\n // 4. Explicit retry request\n if (isDoRetry(error)) {\n if (receipt.attemptNumber >= this.config.maxAttempts) {\n return {\n action: 'dead-letter',\n queue: 'undeliverable',\n reason: `max attempts exceeded (${this.config.maxAttempts}) with forced retry`,\n };\n }\n return {\n action: 'retry',\n delay: this.getDelay(context),\n };\n }\n\n // 5. Max attempts exceeded\n if (receipt.attemptNumber >= this.config.maxAttempts) {\n return {\n action: 'dead-letter',\n queue: 'undeliverable',\n reason: `max attempts exceeded (${this.config.maxAttempts})`,\n };\n }\n\n // 6. Non-idempotent subscriber\n const idempotencyError = this.checkIdempotency(\n envelope,\n receipt,\n subscriber,\n error,\n );\n\n if (idempotencyError) {\n return {\n action: 'dead-letter',\n queue: 'undeliverable',\n reason: idempotencyError.message,\n };\n }\n\n // 7. Default: retry with backoff\n return {\n action: 'retry',\n delay: this.getDelay(context),\n };\n }\n\n getDelay(context: RetryContext): number {\n const attempt = context.receipt.attemptNumber;\n const delay =\n this.config.baseDelay * this.config.backoffMultiplier ** (attempt - 1);\n return Math.min(delay, this.config.maxDelay);\n }\n\n /**\n * Checks the native delivery count against the poison threshold\n *\n * @param envelope - The message envelope.\n * @param receipt - The message receipt.\n * @returns A MessageMaybePoisonedError if the message is poisoned; null otherwise\n */\n private checkPoisoned(\n envelope: Envelope,\n receipt: MessageReceipt,\n ): MessageMaybePoisonedError | null {\n if (receipt.deliveryCount >= this.config.maxDeliveries) {\n return new MessageMaybePoisonedError(\n envelope.id,\n receipt.deliveryCount,\n this.config.maxDeliveries,\n );\n }\n return null;\n }\n\n /**\n * Checks whether the subscriber allows retries based on its idempotency setting\n *\n * @param envelope - The message envelope.\n * @param receipt - The message receipt.\n * @param subscriber - The subscriber definition\n * @param error - The processing error, if it exists\n * @returns A IdempotentMessageCannotRetryError if the message is poisoned; null otherwise\n */\n private checkIdempotency(\n envelope: Envelope,\n receipt: MessageReceipt,\n subscriber: SubscriberDefinition,\n error?: Error,\n ): IdempotentMessageCannotRetryError | null {\n // 'no' and 'unknown' are treated the same (safer default)\n if (\n (error || receipt.redelivered) &&\n (subscriber.idempotent === 'no' || subscriber.idempotent === 'unknown')\n ) {\n return new IdempotentMessageCannotRetryError(\n envelope.id,\n subscriber.name,\n );\n }\n return null;\n }\n}\n","import type {\n AnySubscriber,\n EventClass,\n MatadorEvent,\n Subscriber,\n SubscriberStub,\n} from '../types/index.js';\n\n/**\n * Type-safe schema entry for a single event type (object format).\n * The type parameter enforces that subscribers match the event type.\n */\nexport interface SchemaEntry<T extends MatadorEvent = MatadorEvent> {\n /** The event class */\n readonly eventClass: EventClass<T['data']>;\n\n /** Subscribers for this event */\n readonly subscribers: readonly (Subscriber<T> | SubscriberStub)[];\n}\n\n/**\n * Type-safe schema entry as a tuple: [EventClass, Subscribers[]]\n * The type parameter enforces that subscribers match the event type.\n *\n * @example\n * ```typescript\n * const entry: SchemaEntryTuple<UserCreatedEvent> = [\n * UserCreatedEvent,\n * [createSubscriber<UserCreatedEvent>('handler', async (env) => {})]\n * ];\n * ```\n */\nexport type SchemaEntryTuple<T extends MatadorEvent = MatadorEvent> = readonly [\n eventClass: EventClass<T['data']>,\n subscribers: readonly (Subscriber<T> | SubscriberStub)[],\n];\n\n/**\n * Creates a type-safe schema entry tuple.\n * Ensures that subscribers are compatible with the event class at compile time.\n *\n * @example\n * ```typescript\n * const schema = {\n * [UserCreatedEvent.key]: bind(UserCreatedEvent, [\n * createSubscriber<UserCreatedEvent>('send-email', async (env) => {\n * console.log(env.data.email); // Type-safe access\n * }),\n * ]),\n * } satisfies MatadorSchema;\n * ```\n */\nexport function bind<T extends MatadorEvent>(\n eventClass: EventClass<T['data']>,\n subscribers: readonly (Subscriber<T> | SubscriberStub)[],\n): SchemaEntryTuple<T> {\n return [eventClass, subscribers] as const;\n}\n\n/**\n * Minimal type for event class in schema storage.\n * Only requires the static `key` property for routing.\n * Constructor constraint is omitted to allow heterogeneous event types.\n */\nexport type AnyEventClass = {\n readonly key: string;\n // biome-ignore lint/suspicious/noExplicitAny: Required for variance compatibility in heterogeneous collections\n new (data: any): MatadorEvent;\n};\n\n/**\n * Runtime schema entry stored in MatadorSchema (object format).\n * Uses AnySubscriber and AnyEventClass to allow heterogeneous event types.\n * Type safety is enforced at definition time via `schemaEntry()` helper.\n */\nexport interface RuntimeSchemaEntry {\n readonly eventClass: AnyEventClass;\n readonly subscribers: readonly AnySubscriber[];\n}\n\n/**\n * Runtime schema tuple stored in MatadorSchema.\n * Uses AnySubscriber and AnyEventClass to allow heterogeneous event types.\n * Type safety is enforced at definition time via `schemaEntry()` helper.\n */\nexport type RuntimeSchemaEntryTuple = readonly [\n eventClass: AnyEventClass,\n subscribers: readonly AnySubscriber[],\n];\n\n/**\n * Matador schema mapping event keys to their definitions.\n * Supports both object format (SchemaEntry) and tuple format (SchemaEntryTuple).\n *\n * For type-safe schema definitions, use the `bind` helper function\n * which ensures subscribers are compatible with their event class.\n *\n * @example\n * ```typescript\n * // Type-safe with bind helper:\n * const schema = {\n * [UserCreatedEvent.key]: bind(UserCreatedEvent, [emailSubscriber]),\n * } satisfies MatadorSchema;\n *\n * // Or inline (less type-safe):\n * const schema: MatadorSchema = {\n * [UserCreatedEvent.key]: [UserCreatedEvent, [emailSubscriber]],\n * };\n * ```\n */\nexport type MatadorSchema = {\n readonly [eventKey: string]: RuntimeSchemaEntry | RuntimeSchemaEntryTuple;\n};\n\n/**\n * Type guard to check if a schema entry is in tuple format.\n */\nexport function isSchemaEntryTuple(\n entry: RuntimeSchemaEntry | RuntimeSchemaEntryTuple,\n): entry is RuntimeSchemaEntryTuple {\n return Array.isArray(entry);\n}\n\n/**\n * Options for schema registration.\n */\nexport interface RegisterOptions {\n /** Override existing registration if present */\n readonly override?: boolean;\n}\n\n/**\n * Result of schema validation.\n */\nexport interface SchemaValidationResult {\n readonly valid: boolean;\n readonly issues: readonly SchemaIssue[];\n}\n\n/**\n * Individual schema issue.\n */\nexport interface SchemaIssue {\n readonly severity: 'error' | 'warning';\n readonly eventKey: string;\n readonly message: string;\n}\n\n/**\n * Plugin definition for adding subscribers to multiple events.\n */\nexport interface SchemaPlugin {\n /** The subscriber to add to events */\n readonly subscriber: AnySubscriber;\n\n /** Event keys to exclude from this plugin */\n readonly exclusions?: readonly string[];\n}\n\n/**\n * Installs plugins (global subscribers) into a schema.\n * Each plugin subscriber is added to all events except those in its exclusions list.\n *\n * @param schema - The base schema to extend\n * @param plugins - Array of plugins to install\n * @returns A new schema with plugin subscribers added\n *\n * @example\n * ```typescript\n * const baseSchema: MatadorSchema = {\n * [UserCreatedEvent.key]: [UserCreatedEvent, [sendWelcomeEmail]],\n * [OrderPlacedEvent.key]: [OrderPlacedEvent, [processOrder]],\n * [ChatMessageSent.key]: [ChatMessageSent, [notifyRecipient]],\n * };\n *\n * const schema = installPlugins(baseSchema, [\n * {\n * subscriber: logToBigQuery,\n * exclusions: [ChatMessageSent.key], // Don't log chat messages\n * },\n * {\n * subscriber: trackAnalytics,\n * // No exclusions - added to all events\n * },\n * ]);\n * ```\n */\nexport function installPlugins(\n schema: MatadorSchema,\n plugins: readonly SchemaPlugin[],\n): MatadorSchema {\n const result: Record<string, RuntimeSchemaEntry | RuntimeSchemaEntryTuple> =\n {};\n\n for (const [eventKey, entry] of Object.entries(schema)) {\n // Get existing event class and subscribers\n const [eventClass, existingSubscribers] = isSchemaEntryTuple(entry)\n ? [entry[0], entry[1]]\n : [entry.eventClass, entry.subscribers];\n\n // Collect subscribers to add from plugins\n const pluginSubscribers: AnySubscriber[] = [];\n for (const plugin of plugins) {\n if (!plugin.exclusions?.includes(eventKey)) {\n pluginSubscribers.push(plugin.subscriber);\n }\n }\n\n // Create new entry with combined subscribers\n result[eventKey] = [\n eventClass,\n [...existingSubscribers, ...pluginSubscribers],\n ];\n }\n\n return result;\n}\n","import type { HasDescription } from '../errors/index.js';\nimport type {\n AnySubscriber,\n EventClass,\n MatadorEvent,\n Subscriber,\n SubscriberDefinition,\n} from '../types/index.js';\nimport { isSubscriber } from '../types/index.js';\nimport type {\n RegisterOptions,\n SchemaEntry,\n SchemaIssue,\n SchemaValidationResult,\n} from './types.js';\n\n/**\n * Error thrown when schema operations fail.\n */\nexport class SchemaError extends Error implements HasDescription {\n readonly description =\n 'A schema operation failed, such as registering a duplicate event or ' +\n 'conflicting alias. This is a configuration error that should be fixed ' +\n 'during development. Review the event and subscriber registrations to ' +\n 'resolve the conflict.';\n\n constructor(message: string) {\n super(message);\n this.name = 'SchemaError';\n }\n}\n\n/**\n * Registry for managing event-subscriber relationships.\n */\nexport class SchemaRegistry {\n private readonly entries = new Map<string, SchemaEntry>();\n private readonly aliases = new Map<string, string>();\n\n /**\n * Registers an event class with its subscribers.\n */\n register<T>(\n eventClass: EventClass<T>,\n subscribers: readonly AnySubscriber[],\n options: RegisterOptions = {},\n ): void {\n const key = eventClass.key;\n\n if (this.entries.has(key) && !options.override) {\n throw new SchemaError(`Event \"${key}\" is already registered`);\n }\n\n this.entries.set(key, {\n eventClass,\n subscribers,\n } as SchemaEntry);\n\n // Register aliases\n if (eventClass.aliases) {\n for (const alias of eventClass.aliases) {\n if (\n this.aliases.has(alias) &&\n this.aliases.get(alias) !== key &&\n !options.override\n ) {\n throw new SchemaError(\n `Alias \"${alias}\" is already registered for event \"${this.aliases.get(alias)}\"`,\n );\n }\n this.aliases.set(alias, key);\n }\n }\n }\n\n /**\n * Gets the event class for a given key.\n */\n getEventClass(key: string): EventClass | undefined {\n const entry = this.entries.get(key);\n if (entry) return entry.eventClass;\n\n // Check aliases\n const aliasKey = this.aliases.get(key);\n if (aliasKey) {\n return this.entries.get(aliasKey)?.eventClass;\n }\n\n return undefined;\n }\n\n /**\n * Gets all subscribers for an event key.\n */\n getSubscribers(eventKey: string): readonly AnySubscriber[] {\n const entry = this.getEntry(eventKey);\n return entry?.subscribers ?? [];\n }\n\n /**\n * Gets a specific subscriber by event key and subscriber name.\n */\n getSubscriber(\n eventKey: string,\n subscriberName: string,\n ): AnySubscriber | undefined {\n const subscribers = this.getSubscribers(eventKey);\n return subscribers.find((s) => s.name === subscriberName);\n }\n\n /**\n * Gets a subscriber definition for the pipeline.\n */\n getSubscriberDefinition(\n eventKey: string,\n subscriberName: string,\n ): SubscriberDefinition | undefined {\n const subscriber = this.getSubscriber(eventKey, subscriberName);\n if (!subscriber) return undefined;\n\n const def: SubscriberDefinition = {\n name: subscriber.name,\n idempotent: subscriber.idempotent ?? 'unknown',\n importance: subscriber.importance ?? 'should-investigate',\n ...('description' in subscriber &&\n subscriber.description !== undefined && {\n description: subscriber.description,\n }),\n };\n\n if (subscriber.targetQueue !== undefined) {\n (def as { targetQueue?: string }).targetQueue = subscriber.targetQueue;\n }\n\n return def;\n }\n\n /**\n * Gets a subscriber with callback for execution.\n */\n getExecutableSubscriber(\n eventKey: string,\n subscriberName: string,\n ): Subscriber<MatadorEvent<unknown>> | undefined {\n const subscriber = this.getSubscriber(eventKey, subscriberName);\n if (!subscriber || !isSubscriber(subscriber)) return undefined;\n return subscriber;\n }\n\n /**\n * Gets the event class by alias.\n */\n getEventByAlias(alias: string): EventClass | undefined {\n const key = this.aliases.get(alias);\n if (!key) return undefined;\n return this.entries.get(key)?.eventClass;\n }\n\n /**\n * Checks if an event key is registered.\n */\n hasEvent(key: string): boolean {\n return this.entries.has(key) || this.aliases.has(key);\n }\n\n /**\n * Gets all registered event keys.\n */\n getEventKeys(): readonly string[] {\n return [...this.entries.keys()];\n }\n\n /**\n * Validates the schema for issues.\n */\n validate(): SchemaValidationResult {\n const issues: SchemaIssue[] = [];\n\n for (const [key, entry] of this.entries) {\n // Check for duplicate subscriber names\n const names = new Set<string>();\n for (const subscriber of entry.subscribers) {\n if (names.has(subscriber.name)) {\n issues.push({\n severity: 'error',\n eventKey: key,\n message: `Duplicate subscriber name: \"${subscriber.name}\"`,\n });\n }\n names.add(subscriber.name);\n }\n\n // Check for subscribers without callbacks (stubs in consuming instance)\n const stubs = entry.subscribers.filter((s) => !isSubscriber(s));\n if (stubs.length === entry.subscribers.length && stubs.length > 0) {\n issues.push({\n severity: 'warning',\n eventKey: key,\n message: 'All subscribers are stubs, no local handlers',\n });\n }\n }\n\n return {\n valid: issues.filter((i) => i.severity === 'error').length === 0,\n issues,\n };\n }\n\n /**\n * Clears all registered entries.\n */\n clear(): void {\n this.entries.clear();\n this.aliases.clear();\n }\n\n private getEntry(eventKey: string): SchemaEntry | undefined {\n const entry = this.entries.get(eventKey);\n if (entry) return entry;\n\n const aliasKey = this.aliases.get(eventKey);\n if (aliasKey) {\n return this.entries.get(aliasKey);\n }\n\n return undefined;\n }\n}\n","import type { CheckpointStore } from '../checkpoint/index.js';\nimport type { Codec } from '../codec/index.js';\nimport { JsonCodec } from '../codec/index.js';\nimport {\n InvalidSchemaError,\n NotStartedError,\n ShutdownInProgressError,\n SomeSendError,\n} from '../errors/index.js';\nimport type { MatadorHooks } from '../hooks/index.js';\nimport { SafeHooks } from '../hooks/index.js';\nimport { ProcessingPipeline } from '../pipeline/index.js';\nimport type { RetryPolicy } from '../retry/index.js';\nimport { StandardRetryPolicy } from '../retry/index.js';\nimport type { MatadorSchema } from '../schema/index.js';\nimport { SchemaRegistry, isSchemaEntryTuple } from '../schema/index.js';\nimport type { Topology } from '../topology/index.js';\nimport {\n findQueueDefinition,\n resolveTargetQueueName,\n} from '../topology/index.js';\nimport type { Subscription, Transport } from '../transport/index.js';\nimport type {\n AnySubscriber,\n Dispatcher,\n Event,\n EventClass,\n EventOptions,\n} from '../types/index.js';\nimport type { SendResult } from './fanout.js';\nimport { FanoutEngine } from './fanout.js';\nimport type { HandlersState, ShutdownConfig } from './shutdown.js';\nimport { ShutdownManager } from './shutdown.js';\n\n/**\n * Configuration for Matador.\n */\nexport interface MatadorConfig {\n /** Transport for message delivery */\n readonly transport: Transport;\n\n /** Topology configuration */\n readonly topology: Topology;\n\n /** Event schema mapping event keys to event classes and subscribers */\n readonly schema: MatadorSchema;\n\n /** Queues to consume from (empty = no consumption) */\n readonly consumeFrom?: readonly string[] | undefined;\n\n /** Custom codec (defaults to JSON) */\n readonly codec?: Codec | undefined;\n\n /** Custom retry policy */\n readonly retryPolicy?: RetryPolicy | undefined;\n\n /** Shutdown configuration */\n readonly shutdownConfig?: Partial<ShutdownConfig> | undefined;\n\n /**\n * Checkpoint store for resumable subscribers.\n * Required for persisting io() results across retries.\n * If not provided, resumable subscribers will work but checkpoints\n * won't persist across retries.\n */\n readonly checkpointStore?: CheckpointStore | undefined;\n\n /**\n * Maximum number of in-memory buffered sends held for retry when the\n * transport is unavailable.\n *\n * @default 5000\n */\n readonly maxRetryBufferSize?: number | undefined;\n\n /**\n * Maximum number of retry attempts for a buffered message before it's\n * dropped and reported via onEnqueueError, instead of being retried forever.\n *\n * @default undefined (no limit — retries until the buffer flushes successfully)\n */\n readonly maxRetryAttempts?: number | undefined;\n\n /**\n * How often (in ms) to attempt flushing the retry buffer, independent of\n * transport reconnect events. Covers the case where the transport stays\n * connected but an individual publish keeps failing.\n *\n * @default 30000. Pass 0 to disable the interval and rely on\n * onConnected/manual flushes only.\n */\n readonly retryIntervalMs?: number | undefined;\n\n /**\n * Number of consecutive flush failures tolerated within a single flush\n * pass before bailing out early and re-buffering the untried remainder,\n * instead of retrying every buffered message against a broker that's\n * rejecting everything.\n *\n * @default 10. Pass 0 (or a negative number) to disable the breaker and\n * always attempt every buffered message on every flush pass.\n */\n readonly maxConsecutiveFlushFailures?: number | undefined;\n}\n\n/**\n * Matador - Transport-agnostic event processing library.\n *\n * Main orchestrator that wires together:\n * - Transport: Message delivery\n * - Schema: Event-subscriber registry\n * - Pipeline: Message processing\n * - Fanout: Event sending\n * - Shutdown: Graceful termination\n */\nexport class Matador implements Dispatcher {\n private readonly transport: Transport;\n private readonly topology: Topology;\n private readonly schema;\n private readonly codec: Codec;\n private readonly retryPolicy: RetryPolicy;\n private readonly hooks;\n private readonly pipeline;\n private readonly fanout;\n private readonly shutdownManager;\n private readonly consumeFrom: readonly string[];\n private readonly subscriptions: Subscription[] = [];\n private started = false;\n\n /**\n * Creates a new Matador instance.\n *\n * @param config - Static configuration (transport, topology, schema, etc.)\n * @param hooks - Lifecycle hooks for logging, monitoring, and dynamic configuration.\n * Passed separately to support NestJS dependency injection.\n */\n constructor(config: MatadorConfig, hooks?: MatadorHooks) {\n this.transport = config.transport;\n this.topology = config.topology;\n this.consumeFrom = config.consumeFrom ?? [];\n\n // Initialize components\n this.schema = new SchemaRegistry();\n this.codec = config.codec ?? new JsonCodec();\n this.retryPolicy = config.retryPolicy ?? new StandardRetryPolicy();\n this.hooks = new SafeHooks(hooks);\n\n // Register schema from config\n this.registerSchema(config.schema);\n\n // Create pipeline\n this.pipeline = new ProcessingPipeline({\n transport: this.transport,\n schema: this.schema,\n codec: this.codec,\n retryPolicy: this.retryPolicy,\n hooks: this.hooks,\n checkpointStore: config.checkpointStore,\n dispatcher: this,\n });\n\n // Create fanout engine\n const defaultQueue = this.topology.queues[0]?.name ?? 'default';\n this.fanout = new FanoutEngine({\n transport: this.transport,\n schema: this.schema,\n hooks: this.hooks,\n topology: this.topology,\n defaultQueue,\n maxRetryBufferSize: config.maxRetryBufferSize,\n maxRetryAttempts: config.maxRetryAttempts,\n retryIntervalMs: config.retryIntervalMs,\n maxConsecutiveFlushFailures: config.maxConsecutiveFlushFailures,\n });\n\n // Create shutdown manager\n this.shutdownManager = new ShutdownManager(\n () => this.fanout.eventsBeingEnqueuedCount,\n () => this.unsubscribeAll(),\n () => this.transport.disconnect(),\n config.shutdownConfig,\n );\n }\n\n /**\n * Registers an event class with its subscribers.\n */\n register<T>(\n eventClass: EventClass<T>,\n subscribers: readonly AnySubscriber[],\n ): this {\n this.schema.register(eventClass, subscribers);\n return this;\n }\n\n /**\n * Registers events from a schema object.\n * Supports both object format and tuple format entries.\n *\n * @example\n * ```typescript\n * // Tuple format\n * matador.registerSchema({\n * [UserCreatedEvent.key]: [UserCreatedEvent, [emailSubscriber]],\n * [OrderPlacedEvent.key]: [OrderPlacedEvent, [invoiceSubscriber]],\n * });\n *\n * // Object format\n * matador.registerSchema({\n * [UserCreatedEvent.key]: { eventClass: UserCreatedEvent, subscribers: [emailSubscriber] },\n * });\n * ```\n */\n registerSchema(schema: MatadorSchema): this {\n for (const entry of Object.values(schema)) {\n if (isSchemaEntryTuple(entry)) {\n // Tuple format: [EventClass, Subscriber[]]\n const [eventClass, subscribers] = entry;\n this.schema.register(eventClass, subscribers);\n } else {\n // Object format: { eventClass, subscribers }\n this.schema.register(entry.eventClass, entry.subscribers);\n }\n }\n return this;\n }\n\n /**\n * Starts Matador - connects transport and begins consuming.\n * This method is idempotent - calling it multiple times is safe.\n */\n async start(): Promise<void> {\n // Idempotent: if already started, just return\n if (this.started) {\n return;\n }\n\n // Validate schema\n const validation = this.schema.validate();\n if (!validation.valid) {\n const errors = validation.issues.filter((i) => i.severity === 'error');\n throw new InvalidSchemaError(\n 'Schema validation failed',\n errors.map((e) => e.message).join(', '),\n );\n }\n\n // Connect transport\n this.hooks.logger.info(\n `[Matador] ⏳ Starting backend '${this.transport.name}'...`,\n );\n await this.transport.connect();\n this.hooks.logger.info(\n `[Matador] 🟢 Backend '${this.transport.name}' started.`,\n );\n\n // Apply topology\n await this.transport.applyTopology(this.topology);\n\n // Subscribe to queues\n if (this.consumeFrom.length > 0) {\n this.hooks.logger.info(\n `[Matador] 🟢 Worker subscribing to '${this.consumeFrom.join(',')}'.`,\n );\n } else {\n this.hooks.logger.info(\n '[Matador] 🟡 Worker not subscribing to any queues (consumeFrom is empty).',\n );\n }\n\n // Mark as started\n // Needed for the subscribe calls below, as we might start getting messages\n // that could send events before the code here finishes subscribing to all the queues\n this.started = true;\n\n for (const queueName of this.consumeFrom) {\n const qualifiedName = resolveTargetQueueName(this.topology, queueName);\n const queueDef = findQueueDefinition(this.topology, queueName);\n\n const subscription = await this.transport.subscribe(\n qualifiedName,\n async (envelope, receipt) => {\n this.shutdownManager.incrementProcessing();\n try {\n const rawMessage = this.codec.encode(envelope);\n await this.pipeline.process(rawMessage, receipt);\n } finally {\n this.shutdownManager.decrementProcessing();\n }\n },\n queueDef?.concurrency !== undefined\n ? { concurrency: queueDef.concurrency }\n : undefined,\n );\n\n this.subscriptions.push(subscription);\n }\n }\n\n /**\n * Sends an event to all registered subscribers.\n *\n * @example\n * ```typescript\n * // Pass the event class and data directly\n * await matador.send(UserCreatedEvent, { userId: '123' });\n *\n * // Or pass an event instance\n * const event = new UserCreatedEvent({ userId: '123' });\n * await matador.send(event);\n * ```\n */\n async send<T>(\n eventClass: EventClass<T>,\n data: T,\n options?: EventOptions,\n ): Promise<SendResult>;\n async send<T>(event: Event<T>, options?: EventOptions): Promise<SendResult>;\n async send<T>(\n eventOrClass: Event<T> | EventClass<T>,\n dataOrOptions?: T | EventOptions,\n maybeOptions?: EventOptions,\n ): Promise<SendResult> {\n if (!this.started) {\n throw new NotStartedError('send');\n }\n\n if (!this.shutdownManager.isEnqueueAllowed) {\n throw new ShutdownInProgressError();\n }\n\n // Determine if first arg is an event instance or event class\n const isEventClass =\n typeof eventOrClass === 'function' && 'key' in eventOrClass;\n\n if (isEventClass) {\n // Called as: send(EventClass, data, options?)\n const eventClass = eventOrClass as EventClass<T>;\n const data = dataOrOptions as T;\n const options = maybeOptions;\n const event = new eventClass(data);\n const result = await this.fanout.send(eventClass, event, options);\n if (result.errors.length > 0)\n throw new SomeSendError(result.eventKey, result.errors);\n return result;\n }\n // Called as: send(event, options?)\n const event = eventOrClass as Event<T>;\n const options = dataOrOptions as EventOptions | undefined;\n const eventClass = event.constructor as EventClass<T>;\n const result = await this.fanout.send(eventClass, event, options);\n if (result.errors.length > 0)\n throw new SomeSendError(result.eventKey, result.errors);\n return result;\n }\n\n /**\n * Gets current handler state.\n */\n getHandlersState(): HandlersState {\n return this.shutdownManager.getHandlersState();\n }\n\n /**\n * Checks if Matador is idle (no processing or enqueuing).\n */\n isIdle(): boolean {\n return this.shutdownManager.getHandlersState().isIdle;\n }\n\n /**\n * Waits for all handlers to become idle.\n */\n async waitForIdle(timeoutMs = 30000): Promise<boolean> {\n const deadline = Date.now() + timeoutMs;\n\n while (!this.isIdle()) {\n if (Date.now() > deadline) {\n return false;\n }\n await new Promise((resolve) => setTimeout(resolve, 100));\n }\n\n return true;\n }\n\n /**\n * Stops receiving new messages without performing full shutdown.\n * After calling this, no new messages will be delivered from RabbitMQ.\n * The transport remains connected for later shutdown.\n *\n * Use this when you need to coordinate shutdown across multiple systems:\n * 1. Call stopReceiving() to stop new message delivery\n * 2. Wait for both Matador and your other systems to idle\n * 3. Call shutdown() to disconnect (or let NestJS lifecycle handle it)\n *\n * @returns true if receiving was stopped, false if not started or already stopped\n */\n async stopReceiving(): Promise<boolean> {\n if (!this.started) {\n return false;\n }\n\n return this.shutdownManager.publicStopReceiving();\n }\n\n /**\n * Gracefully shuts down Matador.\n */\n async shutdown(): Promise<void> {\n if (!this.started) {\n return;\n }\n\n this.fanout.dispose();\n await this.shutdownManager.shutdown();\n this.started = false;\n }\n\n /**\n * Checks if transport is connected.\n */\n isConnected(): boolean {\n return this.transport.isConnected();\n }\n\n private async unsubscribeAll(): Promise<void> {\n for (const subscription of this.subscriptions) {\n await (subscription.pauseForShutdown ?? subscription.unsubscribe)();\n }\n this.subscriptions.length = 0;\n }\n}\n","import type { DeliveryMode } from '../types/index.js';\n\n/**\n * Describes the native capabilities of a transport.\n * Matador adapts its behavior based on these capabilities.\n */\nexport interface TransportCapabilities {\n /**\n * Delivery semantics the transport supports.\n * - 'at-least-once': Ack after processing (may redeliver on failure)\n * - 'at-most-once': Ack before processing (no redelivery, may lose messages)\n */\n readonly deliveryModes: readonly DeliveryMode[];\n\n /**\n * Transport can delay message delivery natively.\n * - true: Use transport's native delay (BullMQ, RabbitMQ with plugin)\n * - false: Matador handles via retry queue with TTL or external scheduler\n */\n readonly delayedMessages: boolean;\n\n /**\n * Transport can route failed messages to dead-letter queue natively.\n * - 'native': Transport handles DL routing (RabbitMQ DLX)\n * - 'manual': Matador must send() to DLQ then complete() original\n * - 'none': No DL support, Matador logs and discards\n */\n readonly deadLetterRouting: 'native' | 'manual' | 'none';\n\n /**\n * Transport tracks delivery/attempt count natively.\n * - true: Receipt includes accurate attemptNumber from transport\n * - false: Matador tracks attempts in envelope.docket.attempts field\n */\n readonly attemptTracking: boolean;\n\n /**\n * How transport handles concurrency.\n * - 'prefetch': Channel-based prefetch (RabbitMQ)\n * - 'worker': Worker concurrency setting (BullMQ)\n * - 'partition': Partition-based parallelism (Kafka)\n * - 'none': No concurrency control (Memory)\n */\n readonly concurrencyModel: 'prefetch' | 'worker' | 'partition' | 'none';\n\n /**\n * Message ordering guarantees.\n * - 'none': No ordering guarantee (most transports with multiple consumers)\n * - 'queue': Ordered within queue (single consumer scenarios)\n * - 'partition': Ordered within partition/key (Kafka)\n */\n readonly ordering: 'none' | 'queue' | 'partition';\n\n /**\n * Transport supports message priority.\n * - true: Higher priority messages processed first\n * - false: FIFO only\n */\n readonly priorities: boolean;\n}\n\n/**\n * Checks if the transport supports a specific delivery mode.\n */\nexport function supportsDeliveryMode(\n capabilities: TransportCapabilities,\n mode: DeliveryMode,\n): boolean {\n return capabilities.deliveryModes.includes(mode);\n}\n\n/**\n * Checks if the transport supports native delayed messages.\n */\nexport function supportsDelayedMessages(\n capabilities: TransportCapabilities,\n): boolean {\n return capabilities.delayedMessages;\n}\n\n/**\n * Checks if the transport has native dead-letter routing.\n */\nexport function hasNativeDeadLetter(\n capabilities: TransportCapabilities,\n): boolean {\n return capabilities.deadLetterRouting === 'native';\n}\n","/**\n * Connection state machine states.\n */\nexport type ConnectionState =\n | { readonly status: 'disconnected' }\n | { readonly status: 'connecting'; readonly attempt: number }\n | { readonly status: 'connected' }\n | {\n readonly status: 'reconnecting';\n readonly attempt: number;\n readonly lastError: Error;\n }\n | { readonly status: 'failed'; readonly error: Error };\n\n/**\n * Configuration for the connection manager.\n */\nexport interface ConnectionManagerConfig {\n /** Maximum reconnection attempts before giving up (0 = infinite) */\n readonly maxReconnectAttempts: number;\n\n /** Initial delay between reconnection attempts (ms) */\n readonly initialReconnectDelay: number;\n\n /** Maximum delay between reconnection attempts (ms) */\n readonly maxReconnectDelay: number;\n\n /** Backoff multiplier for reconnection delay */\n readonly backoffMultiplier: number;\n\n /** Heartbeat interval for connection health (ms), optional */\n readonly heartbeatInterval?: number;\n}\n\n/**\n * Default configuration values.\n */\nexport const defaultConnectionConfig: ConnectionManagerConfig = {\n maxReconnectAttempts: 0, // Infinite\n initialReconnectDelay: 1000,\n maxReconnectDelay: 30000,\n backoffMultiplier: 2,\n};\n\n/**\n * Callback for state change notifications.\n */\nexport type StateChangeCallback = (state: ConnectionState) => void;\n\n/**\n * Function that performs the actual connection.\n */\nexport type ConnectFn = () => Promise<void>;\n\n/**\n * Function that performs disconnection.\n */\nexport type DisconnectFn = () => Promise<void>;\n\n/**\n * Manages connection lifecycle with automatic reconnection.\n */\nexport class ConnectionManager {\n private _state: ConnectionState = { status: 'disconnected' };\n private readonly listeners: Set<StateChangeCallback> = new Set();\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n private readonly config: ConnectionManagerConfig;\n\n constructor(\n private readonly connectFn: ConnectFn,\n private readonly disconnectFn: DisconnectFn,\n config: Partial<ConnectionManagerConfig> = {},\n ) {\n this.config = { ...defaultConnectionConfig, ...config };\n }\n\n /**\n * Current connection state.\n */\n get state(): ConnectionState {\n return this._state;\n }\n\n /**\n * Whether currently connected.\n */\n isConnected(): boolean {\n return this._state.status === 'connected';\n }\n\n /**\n * Register a callback for connection state changes.\n */\n onStateChange(callback: StateChangeCallback): () => void {\n this.listeners.add(callback);\n return () => this.listeners.delete(callback);\n }\n\n /**\n * Attempt to establish connection.\n */\n async connect(): Promise<void> {\n if (this._state.status === 'connected') {\n return;\n }\n\n this.setState({ status: 'connecting', attempt: 1 });\n\n try {\n await this.connectFn();\n this.setState({ status: 'connected' });\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n await this.handleConnectionFailure(err, 1);\n }\n }\n\n /**\n * Gracefully disconnect.\n */\n async disconnect(): Promise<void> {\n this.clearReconnectTimer();\n\n if (this._state.status === 'disconnected') {\n return;\n }\n\n try {\n await this.disconnectFn();\n } finally {\n this.setState({ status: 'disconnected' });\n }\n }\n\n /**\n * Called by transport when connection is lost unexpectedly.\n */\n async handleConnectionLost(error: Error): Promise<void> {\n if (this._state.status === 'disconnected') {\n return;\n }\n\n this.setState({ status: 'reconnecting', attempt: 1, lastError: error });\n await this.attemptReconnect(1);\n }\n\n /**\n * Calculate delay for a given attempt using exponential backoff.\n */\n calculateDelay(attempt: number): number {\n const delay =\n this.config.initialReconnectDelay *\n this.config.backoffMultiplier ** (attempt - 1);\n return Math.min(delay, this.config.maxReconnectDelay);\n }\n\n private setState(state: ConnectionState): void {\n this._state = state;\n for (const listener of this.listeners) {\n try {\n listener(state);\n } catch {\n // Ignore listener errors\n }\n }\n }\n\n private async handleConnectionFailure(\n error: Error,\n attempt: number,\n ): Promise<void> {\n if (this.shouldGiveUp(attempt)) {\n this.setState({ status: 'failed', error });\n throw error;\n }\n\n this.setState({\n status: 'reconnecting',\n attempt: attempt + 1,\n lastError: error,\n });\n await this.attemptReconnect(attempt + 1);\n }\n\n private shouldGiveUp(attempt: number): boolean {\n return (\n this.config.maxReconnectAttempts > 0 &&\n attempt >= this.config.maxReconnectAttempts\n );\n }\n\n private async attemptReconnect(attempt: number): Promise<void> {\n const delay = this.calculateDelay(attempt);\n\n await new Promise<void>((resolve) => {\n this.reconnectTimer = setTimeout(resolve, delay);\n });\n\n if (this._state.status === 'disconnected') {\n return;\n }\n\n try {\n await this.connectFn();\n this.setState({ status: 'connected' });\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n await this.handleConnectionFailure(err, attempt);\n }\n }\n\n private clearReconnectTimer(): void {\n if (this.reconnectTimer !== null) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n }\n}\n","import {\n LocalTransportNoActiveSubscriberError,\n TransportNotConnectedError,\n} from '../../errors/index.js';\nimport { type Logger, consoleLogger } from '../../hooks/index.js';\nimport type { Topology } from '../../topology/types.js';\nimport { resolveQueueName } from '../../topology/types.js';\nimport type { Envelope } from '../../types/index.js';\nimport type { TransportCapabilities } from '../capabilities.js';\nimport type {\n MessageHandler,\n MessageReceipt,\n SendOptions,\n SubscribeOptions,\n Subscription,\n Transport,\n} from '../transport.js';\n\n/**\n * Capabilities of the LocalTransport.\n */\nconst localCapabilities: TransportCapabilities = {\n deliveryModes: ['at-least-once', 'at-most-once'],\n delayedMessages: true, // Implemented with setTimeout\n deadLetterRouting: 'manual',\n attemptTracking: false,\n concurrencyModel: 'none',\n ordering: 'queue',\n priorities: false,\n};\n\n/**\n * Internal message structure for the local queue.\n */\ninterface QueuedMessage {\n readonly envelope: Envelope;\n readonly id: string;\n completed: boolean;\n}\n\n/**\n * Internal subscription structure.\n */\ninterface ActiveSubscription {\n readonly handler: MessageHandler;\n readonly options: SubscribeOptions;\n active: boolean;\n}\n\n/**\n * Maximum number of completed message receipts to retain.\n * Oldest receipts are dropped once this limit is exceeded\n */\nconst MAX_COMPLETED_MESSAGES = 1000;\n\n/**\n * Local in-memory transport for testing and fallback.\n * Messages are stored in memory and delivered synchronously.\n */\nexport class LocalTransport implements Transport {\n readonly name = 'local';\n readonly capabilities = localCapabilities;\n\n private connected = false;\n private readonly queues = new Map<string, Map<string, QueuedMessage>>();\n private readonly subscriptions = new Map<string, ActiveSubscription[]>();\n private readonly completedMessages: MessageReceipt[] = [];\n private readonly delayedTimers = new Set<ReturnType<typeof setTimeout>>();\n private messageIdCounter = 0;\n private readonly logger: Logger;\n\n constructor(logger?: Logger) {\n this.logger = logger ?? consoleLogger;\n }\n\n async connect(): Promise<void> {\n this.connected = true;\n }\n\n async disconnect(): Promise<void> {\n // Cancel all delayed message timers\n for (const timer of this.delayedTimers) {\n clearTimeout(timer);\n }\n this.delayedTimers.clear();\n\n // Deactivate all subscriptions\n for (const subs of this.subscriptions.values()) {\n for (const sub of subs) {\n sub.active = false;\n }\n }\n\n this.connected = false;\n }\n\n isConnected(): boolean {\n return this.connected;\n }\n\n async applyTopology(topology: Topology): Promise<void> {\n if (!this.connected) {\n throw new TransportNotConnectedError(this.name, 'applyTopology');\n }\n\n // Initialize queues for the topology.\n // Note: Retry queues are not pre-created here because LocalTransport handles\n // retries by re-enqueueing messages with a delay to the original queue, matching\n // how the pipeline schedules retries via transport.send() with a delay option.\n for (const queueDef of topology.queues) {\n const queueName = resolveQueueName(\n topology.namespace,\n queueDef,\n topology.naming,\n topology.prefix,\n );\n if (!this.queues.has(queueName)) {\n this.queues.set(queueName, new Map());\n }\n }\n }\n\n async send(\n queue: string,\n envelope: Envelope,\n options?: SendOptions,\n ): Promise<Transport['name']> {\n if (!this.connected) {\n throw new TransportNotConnectedError(this.name, 'send');\n }\n\n // Handle delayed messages (non-blocking, like real transports)\n if (options?.delay !== undefined && options.delay > 0) {\n this.scheduleDelayedMessage(queue, envelope, options.delay);\n return this.name;\n }\n\n await this.enqueue(queue, envelope);\n return this.name;\n }\n\n /**\n * Schedules a message for delayed delivery.\n * Returns immediately (non-blocking) to match real transport behavior.\n */\n private scheduleDelayedMessage(\n queue: string,\n envelope: Envelope,\n delayMs: number,\n ): void {\n const timer = setTimeout(() => {\n this.delayedTimers.delete(timer);\n // Fire and forget - errors are logged in enqueue/deliverToSubscribers\n this.enqueue(queue, envelope).catch((error) => {\n this.logger.error(\n '[Matador] 🔴 Failed to enqueue delayed message',\n error,\n );\n });\n }, delayMs);\n this.delayedTimers.add(timer);\n }\n\n private async enqueue(queue: string, envelope: Envelope): Promise<void> {\n const subs = this.subscriptions.get(queue);\n if (!subs || subs.length === 0) {\n throw new LocalTransportNoActiveSubscriberError(queue);\n }\n\n await this.storeAndDeliver(queue, envelope);\n }\n\n /**\n * Stores a message and delivers it to any active subscribers, without\n * requiring one to be present. Dead-letter queues are meant to hold\n * messages for later manual inspection, so they don't need a live consumer.\n */\n private async storeAndDeliver(\n queue: string,\n envelope: Envelope,\n ): Promise<void> {\n const messages = this.getOrCreateQueue(queue);\n const messageId = `${++this.messageIdCounter}`;\n\n const queuedMessage: QueuedMessage = {\n envelope,\n id: messageId,\n completed: false,\n };\n\n messages.set(messageId, queuedMessage);\n\n await this.deliverToSubscribers(queue, queuedMessage);\n }\n\n private async deliverToSubscribers(\n queue: string,\n message: QueuedMessage,\n ): Promise<void> {\n const subs = this.subscriptions.get(queue) ?? [];\n\n for (const sub of subs) {\n if (!sub.active || message.completed) continue;\n\n const receipt: MessageReceipt = {\n handle: message,\n redelivered: false,\n attemptNumber: message.envelope.docket.attempts,\n deliveryCount: message.envelope.docket.attempts,\n sourceQueue: queue,\n sourceTransport: this.name,\n };\n\n try {\n await sub.handler(message.envelope, receipt);\n } catch (error) {\n // Handler errors should be caught in the pipeline\n this.logger.error(\n '[Matador] 🔴 Handler error in message processing',\n error,\n );\n }\n }\n }\n\n async subscribe(\n queue: string,\n handler: MessageHandler,\n options: SubscribeOptions = {},\n ): Promise<Subscription> {\n if (!this.connected) {\n throw new TransportNotConnectedError(this.name, 'subscribe');\n }\n\n const subscription: ActiveSubscription = {\n handler,\n options,\n active: true,\n };\n\n const subs = this.subscriptions.get(queue) ?? [];\n subs.push(subscription);\n this.subscriptions.set(queue, subs);\n\n // Deliver any pending messages\n const messages = this.queues.get(queue)?.values() ?? [];\n for (const message of messages) {\n if (message.completed) continue;\n await this.deliverToSubscribers(queue, message);\n }\n\n return {\n unsubscribe: async () => {\n subscription.active = false;\n const remaining = subs.filter((s) => s !== subscription);\n if (remaining.length > 0) {\n this.subscriptions.set(queue, remaining);\n } else {\n this.subscriptions.delete(queue);\n }\n },\n // No-op: LocalTransport is only ever fed from within the process\n // So, when shutting down, it needs to continue and handle new messages until the end\n // As, an ongoing message (before shutdown) could create new (local) messages\n pauseForShutdown: async () => {},\n get isActive() {\n return subscription.active;\n },\n };\n }\n\n async complete(receipt: MessageReceipt): Promise<void> {\n const message = receipt.handle as QueuedMessage;\n message.completed = true;\n this.completedMessages.push(receipt);\n if (this.completedMessages.length > MAX_COMPLETED_MESSAGES) {\n this.completedMessages.shift();\n }\n\n this.queues.get(receipt.sourceQueue)?.delete(message.id);\n }\n\n async sendToDeadLetter(\n receipt: MessageReceipt,\n dlqName: string,\n envelope: Envelope,\n _reason: string,\n ): Promise<void> {\n const dlqQueueName = `${receipt.sourceQueue}.${dlqName}`;\n await this.storeAndDeliver(dlqQueueName, envelope);\n await this.complete(receipt);\n }\n\n // Test helpers\n\n /**\n * Gets the current size of a queue.\n */\n getQueueSize(queue: string): number {\n return this.queues.get(queue)?.size ?? 0;\n }\n\n /**\n * Gets all completed message receipts.\n */\n getCompleted(): readonly MessageReceipt[] {\n return this.completedMessages;\n }\n\n /**\n * Gets pending (uncompleted) messages from a queue.\n */\n getPendingMessages(queue: string): readonly Envelope[] {\n const messages = this.queues.get(queue);\n if (!messages) return [];\n return Array.from(messages.values()).map((m) => m.envelope);\n }\n\n /**\n * Clears all state (for test isolation).\n */\n clear(): void {\n this.queues.clear();\n this.subscriptions.clear();\n this.completedMessages.length = 0;\n this.messageIdCounter = 0;\n\n for (const timer of this.delayedTimers) {\n clearTimeout(timer);\n }\n this.delayedTimers.clear();\n }\n\n /**\n * Receives one message from the queue without a subscription.\n * Useful for testing.\n */\n async receiveOne(\n queue: string,\n ): Promise<{ envelope: Envelope; receipt: MessageReceipt } | null> {\n const messages = this.queues.get(queue);\n if (!messages) return null;\n\n const pending = messages.values().next().value;\n if (!pending) return null;\n\n const receipt: MessageReceipt = {\n handle: pending,\n redelivered: false,\n attemptNumber: pending.envelope.docket.attempts,\n deliveryCount: pending.envelope.docket.attempts,\n sourceQueue: queue,\n sourceTransport: this.name,\n };\n\n return { envelope: pending.envelope, receipt };\n }\n\n private getOrCreateQueue(queue: string): Map<string, QueuedMessage> {\n let messages = this.queues.get(queue);\n if (!messages) {\n messages = new Map();\n this.queues.set(queue, messages);\n }\n return messages;\n }\n}\n","import { AllTransportsFailedError } from '../../errors/index.js';\nimport type { TransportFallbackContext } from '../../hooks/index.js';\nimport type { Topology } from '../../topology/types.js';\nimport type { Envelope } from '../../types/index.js';\nimport type { TransportCapabilities } from '../capabilities.js';\nimport type {\n MessageHandler,\n MessageReceipt,\n SendOptions,\n SubscribeOptions,\n Subscription,\n Transport,\n} from '../transport.js';\n\n/**\n * Symbol key used to store the source transport on wrapped receipts.\n */\nconst SOURCE_TRANSPORT = Symbol('sourceTransport');\n\n/**\n * Extracts the source transport from a tagged receipt.\n */\nfunction getSourceTransport(receipt: MessageReceipt): Transport | undefined {\n return (receipt as unknown as Record<symbol, Transport | undefined>)[\n SOURCE_TRANSPORT\n ];\n}\n\n/**\n * Configuration for MultiTransport.\n */\nexport interface MultiTransportConfig {\n /**\n * Ordered list of transports.\n * First transport is primary, rest are used as fallbacks when primary fails\n * (if fallback is enabled), or can be explicitly selected via the getDesiredBackend hook.\n */\n readonly transports: readonly Transport[];\n\n /**\n * Whether to automatically try fallback transports when the primary/selected fails.\n * When true (default), send() will try each transport in order until one succeeds.\n * When false, send() will only use the selected transport and throw immediately on failure.\n *\n * @default true\n */\n readonly fallbackEnabled?: boolean;\n}\n\n/**\n * Hooks for MultiTransport.\n */\nexport interface MultiTransportHooks {\n /**\n * Hook to dynamically select which backend to use.\n * Return the transport name (e.g., 'local', 'rabbitmq') or undefined to use primary.\n *\n * @example\n * ```typescript\n * getDesiredBackend: async () => {\n * if (process.env.SANDBOX === 'true') return 'local';\n * const backend = await runtimeConfig.get('events.backend');\n * return backend || 'rabbitmq';\n * }\n * ```\n */\n readonly getDesiredBackend?: () =>\n | string\n | undefined\n | Promise<string | undefined>;\n\n /**\n * Called when a fallback transport is used successfully after the selected one fails.\n * Only called when fallbackEnabled is true.\n */\n readonly onEnqueueFallback?: (context: TransportFallbackContext) => void;\n}\n\n/**\n * Computes merged capabilities from multiple transports.\n * Uses the most restrictive/conservative interpretation.\n */\nfunction mergeCapabilities(\n transports: readonly Transport[],\n): TransportCapabilities {\n const primary = transports[0];\n if (!primary) {\n throw new Error('At least one transport is required');\n }\n\n // For multi-transport scenarios, we use primary's capabilities since that's\n // what we'll use for subscriptions and most operations\n return primary.capabilities;\n}\n\n/**\n * A transport wrapper that manages multiple transports.\n *\n * Features:\n * - All transports are connected upfront\n * - send() tries transports in order until one succeeds (fallback behavior)\n * - Specific transport can be selected via getDesiredBackend hook\n * - Subscriptions are created on ALL transports\n *\n * @example\n * ```typescript\n * const transport = new MultiTransport(\n * { transports: [rabbitMQTransport, localTransport] },\n * { onEnqueueFallback: (ctx) => console.warn(`Fallback to ${ctx.nextTransport}`) },\n * );\n * ```\n */\nexport class MultiTransport implements Transport {\n readonly name: string;\n readonly capabilities: TransportCapabilities;\n readonly primary: Transport;\n\n /** All available transports, in order of preference (primary first). */\n readonly transports: readonly Transport[];\n\n /** Whether fallback to secondary transports is enabled. */\n readonly fallbackEnabled: boolean;\n\n private readonly hooks: MultiTransportHooks;\n private connected = false;\n\n constructor(config: MultiTransportConfig, hooks: MultiTransportHooks = {}) {\n const primary = config.transports[0];\n if (!primary) {\n throw new Error('At least one transport is required');\n }\n\n this.primary = primary;\n this.transports = config.transports;\n this.fallbackEnabled = config.fallbackEnabled ?? true;\n this.hooks = hooks;\n this.name = `multi(${this.transports.map((t) => t.name).join(',')})`;\n this.capabilities = mergeCapabilities(this.transports);\n }\n\n async connect(): Promise<void> {\n // Connect all transports in parallel\n await Promise.all(this.transports.map((t) => t.connect()));\n this.connected = true;\n }\n\n async disconnect(): Promise<void> {\n // Disconnect all transports in parallel\n await Promise.all(this.transports.map((t) => t.disconnect()));\n this.connected = false;\n }\n\n isConnected(): boolean {\n // Consider connected if primary is connected\n return this.connected && this.primary.isConnected();\n }\n\n /**\n * Registers a callback to fire each time the transport successfully (re)connects\n * @param callback - The callback to fire when the transport successfully (re)connects\n * @returns A function to unsubscribe from the callback\n */\n onConnected(callback: () => void): () => void {\n // This adds the callback on all transports that support it, and returns functions to unsubscribe from all transports\n const unsubFunctions = this.transports\n .map((t) => t.onConnected?.(callback))\n .filter(Boolean) as (() => void)[];\n\n // Return a function to unsubscribe from all transports\n return () => {\n for (const unsub of unsubFunctions) {\n unsub();\n }\n };\n }\n\n async applyTopology(topology: Topology): Promise<void> {\n // Apply topology to all transports so they're all ready\n await Promise.all(this.transports.map((t) => t.applyTopology(topology)));\n }\n\n async send(\n queue: string,\n envelope: Envelope,\n options?: SendOptions,\n ): Promise<Transport['name']> {\n // Determine which transport to use\n const selectedTransport = await this.selectTransport();\n\n // If fallback is disabled, only use selected transport\n if (!this.fallbackEnabled) {\n return selectedTransport.send(queue, envelope, options);\n }\n\n // Build transport order: selected first, then others\n const transportOrder = this.getTransportOrder(selectedTransport);\n\n const errors: Error[] = [];\n\n for (let i = 0; i < transportOrder.length; i++) {\n const transport = transportOrder[i];\n if (!transport) continue;\n try {\n return await transport.send(queue, envelope, options);\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n errors.push(err);\n\n // Notify about fallback before trying next transport\n const nextTransport = transportOrder[i + 1];\n if (nextTransport && this.hooks.onEnqueueFallback) {\n this.hooks.onEnqueueFallback({\n envelope,\n queue,\n failedTransport: transport.name,\n nextTransport: nextTransport.name,\n error: err,\n });\n }\n // Continue to next transport\n }\n }\n\n // All transports failed\n throw new AllTransportsFailedError(queue, errors);\n }\n\n /**\n * Selects the transport to use based on the getDesiredBackend hook.\n */\n private async selectTransport(): Promise<Transport> {\n if (!this.hooks.getDesiredBackend) {\n return this.primary;\n }\n\n try {\n const desiredBackend = await this.hooks.getDesiredBackend();\n if (!desiredBackend) {\n return this.primary;\n }\n\n const selected = this.transports.find((t) => t.name === desiredBackend);\n if (selected) {\n return selected;\n }\n\n // Desired backend not found, use primary\n return this.primary;\n } catch {\n // Hook threw, use primary\n return this.primary;\n }\n }\n\n /**\n * Returns transports in order, with the selected transport first.\n */\n private getTransportOrder(selected: Transport): readonly Transport[] {\n if (selected === this.primary) {\n return this.transports;\n }\n\n // Put selected first, then the rest (excluding selected)\n return [selected, ...this.transports.filter((t) => t !== selected)];\n }\n\n async subscribe(\n queue: string,\n handler: MessageHandler,\n options?: SubscribeOptions,\n ): Promise<Subscription> {\n // Subscribe on ALL transports so messages are processed regardless of\n // which transport they were enqueued to\n const subscriptions = await Promise.all(\n this.transports.map((transport) => {\n // Wrap handler to tag receipts with source transport\n const wrappedHandler: MessageHandler = (envelope, receipt) => {\n const taggedReceipt = Object.assign(receipt, {\n [SOURCE_TRANSPORT]: transport,\n });\n return handler(envelope, taggedReceipt);\n };\n return transport.subscribe(queue, wrappedHandler, options);\n }),\n );\n\n return {\n unsubscribe: async () => {\n await Promise.all(subscriptions.map((s) => s.unsubscribe()));\n },\n pauseForShutdown: async () => {\n await Promise.all(\n subscriptions.map((s) => (s.pauseForShutdown ?? s.unsubscribe)()),\n );\n },\n get isActive() {\n return subscriptions.some((s) => s.isActive);\n },\n };\n }\n\n async complete(receipt: MessageReceipt): Promise<void> {\n const transport = getSourceTransport(receipt) ?? this.primary;\n return transport.complete(receipt);\n }\n\n async sendToDeadLetter(\n receipt: MessageReceipt,\n dlqName: string,\n envelope: Envelope,\n reason: string,\n ): Promise<void> {\n const transport = getSourceTransport(receipt) ?? this.primary;\n if (transport.sendToDeadLetter) {\n return transport.sendToDeadLetter(receipt, dlqName, envelope, reason);\n }\n throw new Error('Transport does not support dead letter routing');\n }\n}\n","import type {\n Channel,\n ChannelModel,\n ConfirmChannel,\n ConsumeMessage,\n Options,\n} from 'amqplib';\nimport amqplib from 'amqplib';\nimport { RabbitMQCodec } from '../../codec/rabbitmq-codec.js';\nimport {\n DelayedMessagesNotSupportedError,\n TransportNotConnectedError,\n TransportSendError,\n} from '../../errors/index.js';\nimport { type Logger, consoleLogger } from '../../hooks/index.js';\nimport type { QueueDefinition, Topology } from '../../topology/types.js';\nimport {\n applyPrefix,\n getDeadLetterQueueName,\n getRetryQueueName,\n resolveQueueName,\n} from '../../topology/types.js';\nimport type { Envelope } from '../../types/index.js';\nimport type { TransportCapabilities } from '../capabilities.js';\nimport {\n ConnectionManager,\n type ConnectionManagerConfig,\n} from '../connection-manager.js';\nimport type {\n MessageHandler,\n MessageReceipt,\n SendOptions,\n SubscribeOptions,\n Subscription,\n Transport,\n} from '../transport.js';\n\n/**\n * Configuration options for the RabbitMQ transport.\n */\nexport interface RabbitMQTransportConfig {\n /** RabbitMQ connection URL */\n readonly url: string;\n\n /** Connection name displayed in RabbitMQ management UI */\n readonly connectionName: string;\n\n /** Connection manager configuration */\n readonly connection?: Partial<ConnectionManagerConfig> | undefined;\n\n /** Use quorum queues for durability (default: true) */\n readonly quorumQueues?: boolean | undefined;\n\n /** Default prefetch count per consumer (default: 10) */\n readonly defaultPrefetch?: number | undefined;\n\n /** Enable the delayed message exchange plugin if available (default: true) */\n readonly enableDelayedMessages?: boolean | undefined;\n\n /**\n * How long to wait for the broker to confirm a publish before failing,\n * in milliseconds (default: 5000).\n *\n * Publishes use a confirm channel: `send()` resolves only once the broker\n * acks the message, and rejects on nack or timeout, so callers can await\n * delivery confirmation rather than treating publishes as fire-and-forget.\n */\n readonly publishTimeoutMs?: number | undefined;\n\n /** Logger for transport events (defaults to console) */\n readonly logger?: Logger | undefined;\n}\n\n/**\n * Internal structure for tracking a queue's dedicated channel.\n */\ninterface QueueChannel {\n readonly channel: Channel;\n readonly consumers: ActiveConsumer[];\n}\n\n/**\n * Internal structure for tracking active consumers.\n */\ninterface ActiveConsumer {\n readonly consumerTag: string;\n readonly queue: string;\n active: boolean;\n}\n\n/**\n * Record of a subscribe() call\n * Stored so consumers can be recreated after a reconnect\n */\ninterface SubscriptionIntent {\n readonly queue: string;\n readonly handler: MessageHandler;\n readonly options: SubscribeOptions;\n /** False once the caller has unsubscribed - prevents replay on reconnect */\n active: boolean;\n /** The live consumer for this intent; replaced on each reconnect */\n currentConsumer: ActiveConsumer | null;\n}\n\n/**\n * Redacts credentials from an AMQP URL.\n * Replaces username and password with '****' regardless of their length.\n *\n * @example\n * redactAmqpUrl('amqp://user:pass@host:5672') // 'amqp://****:****@host:5672'\n */\nexport function redactAmqpUrl(url: string): string {\n const regex = /^(amqps?:\\/\\/)[^:]+:[^@]+@/;\n return url.replace(regex, '$1****:****@');\n}\n\n/**\n * RabbitMQ transport implementation using amqplib.\n */\nexport class RabbitMQTransport implements Transport {\n readonly name = 'rabbitmq';\n\n private _capabilities: TransportCapabilities = {\n deliveryModes: ['at-least-once'],\n delayedMessages: false,\n deadLetterRouting: 'native',\n attemptTracking: true,\n concurrencyModel: 'prefetch',\n ordering: 'none',\n priorities: true,\n };\n\n get capabilities(): TransportCapabilities {\n return this._capabilities;\n }\n\n private connection: ChannelModel | null = null;\n private publishChannel: ConfirmChannel | null = null;\n private readonly connectionManager: ConnectionManager;\n private readonly queueChannels = new Map<string, QueueChannel>();\n private readonly subscriptionIntents: SubscriptionIntent[] = [];\n private topology: Topology | null = null;\n private readonly codec = new RabbitMQCodec();\n\n private readonly config: Required<\n Omit<RabbitMQTransportConfig, 'connection' | 'logger'>\n > & {\n readonly connection: Partial<ConnectionManagerConfig>;\n };\n\n private readonly logger: Logger;\n private delayedExchangeAvailable = false;\n\n constructor(config: RabbitMQTransportConfig) {\n this.logger = config.logger ?? consoleLogger;\n this.config = {\n url: config.url,\n connectionName: config.connectionName,\n connection: config.connection ?? {},\n quorumQueues: config.quorumQueues ?? true,\n defaultPrefetch: config.defaultPrefetch ?? 10,\n enableDelayedMessages: config.enableDelayedMessages ?? true,\n publishTimeoutMs: config.publishTimeoutMs ?? 5000,\n };\n\n this.connectionManager = new ConnectionManager(\n () => this.doConnect(),\n () => this.doDisconnect(),\n this.config.connection,\n );\n }\n\n async connect(): Promise<void> {\n await this.connectionManager.connect();\n }\n\n async disconnect(): Promise<void> {\n await this.connectionManager.disconnect();\n }\n\n isConnected(): boolean {\n return this.connectionManager.isConnected();\n }\n\n /**\n * Registers a callback to fire each time the transport (here RabbitMQ) successfully (re)connects\n * @param callback - The callback to fire when the transport (here RabbitMQ) successfully (re)connects\n * @returns A function to unsubscribe from the callback\n */\n onConnected(callback: () => void): () => void {\n return this.connectionManager.onStateChange((state) => {\n if (state.status === 'connected') {\n callback();\n }\n });\n }\n\n async applyTopology(topology: Topology): Promise<void> {\n this.topology = topology;\n\n if (!this.publishChannel) {\n throw new TransportNotConnectedError(this.name, 'applyTopology');\n }\n\n const channel = this.publishChannel;\n\n // Create the main exchange for routing messages to queues\n const mainExchange = this.getMainExchangeName(topology);\n await channel.assertExchange(mainExchange, 'direct', { durable: true });\n\n // Create dead-letter exchange if DLQ is enabled\n const dlxExchange = this.getDLXExchangeName(topology);\n if (\n topology.deadLetter.unhandled.enabled ||\n topology.deadLetter.undeliverable.enabled\n ) {\n await channel.assertExchange(\n dlxExchange,\n topology.naming?.dlxExchangeType ?? 'direct',\n { durable: true },\n );\n }\n\n // Check for delayed message exchange plugin\n if (this.config.enableDelayedMessages) {\n await this.setupDelayedExchange(topology);\n }\n\n // Create work queues\n for (const queueDef of topology.queues) {\n await this.assertWorkQueue(channel, topology, queueDef);\n }\n\n // Create DLQs\n if (topology.deadLetter.unhandled.enabled) {\n await this.assertDeadLetterQueues(channel, topology, 'unhandled');\n }\n\n if (topology.deadLetter.undeliverable.enabled) {\n await this.assertDeadLetterQueues(channel, topology, 'undeliverable');\n }\n }\n\n async send(\n queue: string,\n envelope: Envelope,\n options?: SendOptions,\n ): Promise<Transport['name']> {\n if (!this.publishChannel || !this.topology) {\n throw new TransportNotConnectedError(this.name, 'send');\n }\n\n const encoded = this.codec.encode(envelope);\n const buffer = Buffer.from(encoded.body);\n\n const publishOptions: Options.Publish = {\n persistent: true,\n contentType: encoded.contentType,\n messageId: envelope.id,\n timestamp: Date.now(),\n headers: encoded.headers,\n };\n\n if (options?.priority !== undefined) {\n publishOptions.priority = options.priority;\n }\n\n // Handle delayed messages\n if (options?.delay !== undefined && options.delay > 0) {\n if (!this.delayedExchangeAvailable) {\n throw new DelayedMessagesNotSupportedError(this.name);\n }\n\n const delayedExchange = this.getDelayedExchangeName(this.topology);\n publishOptions.headers = {\n ...publishOptions.headers,\n 'x-delay': options.delay,\n };\n await this.confirmPublish(\n this.publishChannel,\n delayedExchange,\n queue,\n buffer,\n publishOptions,\n );\n return this.name;\n }\n\n // Transport-specific options\n if (options?.transport?.rabbitmq?.expiration !== undefined) {\n publishOptions.expiration = String(options.transport.rabbitmq.expiration);\n }\n\n if (options?.transport?.rabbitmq?.persistent !== undefined) {\n publishOptions.persistent = options.transport.rabbitmq.persistent;\n }\n\n const routingKey = options?.transport?.rabbitmq?.routingKey ?? queue;\n const exchange = this.getMainExchangeName(this.topology);\n\n await this.confirmPublish(\n this.publishChannel,\n exchange,\n routingKey,\n buffer,\n publishOptions,\n );\n return this.name;\n }\n\n async subscribe(\n queue: string,\n handler: MessageHandler,\n options: SubscribeOptions = {},\n ): Promise<Subscription> {\n if (!this.connection || !this.topology) {\n throw new TransportNotConnectedError(this.name, 'subscribe');\n }\n\n const intent: SubscriptionIntent = {\n queue,\n handler,\n options,\n active: true,\n currentConsumer: null,\n };\n\n this.subscriptionIntents.push(intent);\n await this.activateIntent(intent);\n\n const unsubscribe = async (): Promise<void> => {\n intent.active = false;\n\n const idx = this.subscriptionIntents.indexOf(intent);\n if (idx !== -1) this.subscriptionIntents.splice(idx, 1);\n\n const consumer = intent.currentConsumer;\n if (consumer) {\n consumer.active = false;\n const queueChannel = this.queueChannels.get(queue);\n if (queueChannel) {\n try {\n await queueChannel.channel.cancel(consumer.consumerTag);\n } catch {\n // Channel may already be closed\n }\n const cIdx = queueChannel.consumers.indexOf(consumer);\n if (cIdx !== -1) queueChannel.consumers.splice(cIdx, 1);\n if (queueChannel.consumers.length === 0) {\n try {\n await queueChannel.channel.close();\n } catch {\n // Ignore\n }\n this.queueChannels.delete(queue);\n }\n }\n intent.currentConsumer = null;\n }\n };\n\n return {\n unsubscribe,\n // Messages on this transport comes from outside (RabbitMQ), so, when shutting down, we need to unsubscribe directly\n // Otherwise, we could receive traffic forever, and an idle state would never be reached.\n pauseForShutdown: unsubscribe,\n get isActive() {\n return intent.active;\n },\n };\n }\n\n /**\n * Wires a single subscription intent to the current connection.\n * Called once on subscribe() and again after each reconnect.\n */\n private async activateIntent(intent: SubscriptionIntent): Promise<void> {\n const { queue, handler, options } = intent;\n const queueChannel = await this.getOrCreateQueueChannel(queue, options);\n const { channel } = queueChannel;\n\n const consumer: ActiveConsumer = {\n consumerTag: '',\n queue,\n active: true,\n };\n\n const { consumerTag } = await channel.consume(\n queue,\n async (msg: ConsumeMessage | null) => {\n if (!msg || !consumer.active) return;\n\n const attemptNumber = this.getAttemptNumber(msg);\n const receipt: MessageReceipt = {\n handle: { channel, msg },\n redelivered: msg.fields.redelivered,\n attemptNumber,\n deliveryCount: this.getDeliveryCount(msg, attemptNumber),\n sourceQueue: queue,\n sourceTransport: this.name,\n };\n\n try {\n const headers = (msg.properties.headers ?? {}) as Record<\n string,\n unknown\n >;\n const envelope = this.codec.decode(\n new Uint8Array(msg.content),\n headers,\n );\n await handler(envelope, receipt);\n } catch (error) {\n this.logger.error(\n '[Matador] 🔴 Handler error in message processing',\n error,\n );\n }\n },\n { noAck: false },\n );\n\n (consumer as { consumerTag: string }).consumerTag = consumerTag;\n queueChannel.consumers.push(consumer);\n intent.currentConsumer = consumer;\n }\n\n async complete(receipt: MessageReceipt): Promise<void> {\n const { channel, msg } = receipt.handle as {\n channel: Channel;\n msg: ConsumeMessage;\n };\n\n try {\n channel.ack(msg);\n } catch {\n // Channel may be closed, ignore\n }\n }\n\n async sendToDeadLetter(\n receipt: MessageReceipt,\n dlqName: string,\n envelope: Envelope,\n reason: string,\n ): Promise<void> {\n if (!this.publishChannel || !this.topology) {\n throw new TransportNotConnectedError(this.name, 'sendToDeadLetter');\n }\n\n // Add error info to envelope\n const dlqEnvelope: Envelope = {\n ...envelope,\n docket: {\n ...envelope.docket,\n lastError: reason,\n firstError: envelope.docket.firstError ?? reason,\n originalQueue: receipt.sourceQueue,\n },\n };\n\n const encoded = this.codec.encode(dlqEnvelope);\n const buffer = Buffer.from(encoded.body);\n const dlxExchange = this.getDLXExchangeName(this.topology);\n const dlqQueueName = `${receipt.sourceQueue}.${dlqName}`;\n\n const publishOptions: Options.Publish = {\n persistent: true,\n contentType: encoded.contentType,\n messageId: envelope.id,\n timestamp: Date.now(),\n headers: {\n ...encoded.headers,\n 'x-matador-dead-letter-reason': reason,\n },\n };\n\n await this.confirmPublish(\n this.publishChannel,\n dlxExchange,\n dlqQueueName,\n buffer,\n publishOptions,\n );\n\n // Complete the original message\n await this.complete(receipt);\n }\n\n /**\n * Publishes on the confirm channel and resolves once the broker\n * acknowledges the message, rejecting on broker nack, channel error, or\n * after `publishTimeoutMs` elapses without a confirm.\n *\n * Mirrors Matador v1's promise-wrapped amqplib publish callback to give\n * callers confirmed (at-least-once) delivery semantics.\n */\n private confirmPublish(\n channel: ConfirmChannel,\n exchange: string,\n routingKey: string,\n buffer: Buffer,\n options: Options.Publish,\n ): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n let timeout: NodeJS.Timeout | null = setTimeout(() => {\n timeout = null;\n reject(\n new TransportSendError(\n routingKey,\n new Error(\n `Publish not confirmed by broker within ${this.config.publishTimeoutMs}ms`,\n ),\n ),\n );\n }, this.config.publishTimeoutMs);\n\n channel.publish(exchange, routingKey, buffer, options, (err) => {\n if (timeout) {\n clearTimeout(timeout);\n } else {\n // Already timed out and rejected; nothing left to settle.\n return;\n }\n if (err) {\n reject(new TransportSendError(routingKey, err));\n } else {\n resolve();\n }\n });\n });\n }\n\n // Private methods\n\n /**\n * Gets or creates a dedicated channel for a queue subscription.\n *\n * We create separate channels per subscribed queue to enable independent\n * prefetch/concurrency control.\n */\n private async getOrCreateQueueChannel(\n queue: string,\n options: SubscribeOptions,\n ): Promise<QueueChannel> {\n const existing = this.queueChannels.get(queue);\n if (existing) {\n return existing;\n }\n\n if (!this.connection) {\n throw new TransportNotConnectedError(\n this.name,\n 'getOrCreateQueueChannel',\n );\n }\n\n // Create a dedicated channel for this queue to control prefetch independently\n const channel = await this.connection.createChannel();\n\n const prefetch =\n options.transport?.rabbitmq?.prefetch ??\n options.concurrency ??\n this.config.defaultPrefetch ??\n 10;\n\n await channel.prefetch(prefetch);\n\n const queueChannel: QueueChannel = {\n channel,\n consumers: [],\n };\n\n this.queueChannels.set(queue, queueChannel);\n\n return queueChannel;\n }\n\n private async doConnect(): Promise<void> {\n // Close any existing connection before opening a new one\n if (this.connection) {\n try {\n await this.connection.close();\n } catch {\n // Can happen if the connection is already closed\n }\n this.connection = null;\n this.publishChannel = null; // channels belong to the old connection\n }\n\n // Drop stale channel objects so getOrCreateQueueChannel opens fresh ones\n // on the new connection during intent replay below.\n this.queueChannels.clear();\n\n this.logger.info(\n `[Matador] ⏳ Connecting to RabbitMQ at '${redactAmqpUrl(this.config.url)}'.`,\n );\n const connection = await amqplib.connect(this.config.url, {\n clientProperties: { connection_name: this.config.connectionName },\n });\n this.connection = connection;\n\n // Handle connection errors - let ConnectionManager handle reconnection\n connection.on('error', (err: Error) => {\n this.logger.error('[Matador] 🔴 RabbitMQ connection error', err);\n });\n\n connection.on('close', () => {\n // Immediately deactivate all live consumers so any buffered messages\n // delivered on the dying connection are dropped rather than partially\n // processed (handler fires but ack silently fails on the dead channel).\n for (const queueChannel of this.queueChannels.values()) {\n for (const consumer of queueChannel.consumers) {\n consumer.active = false;\n }\n }\n this.connection = null;\n this.publishChannel = null;\n\n if (this.connectionManager.isConnected()) {\n // Unexpected close, trigger reconnection\n this.connectionManager.handleConnectionLost(\n new Error('Connection closed unexpectedly'),\n );\n }\n });\n\n try {\n // A confirm channel so publishes can await broker acknowledgement\n this.publishChannel = await connection.createConfirmChannel();\n\n // Handle publish channel errors to prevent unhandled error events\n this.publishChannel.on('error', (err: Error) => {\n this.logger.error('[Matador] 🔴 RabbitMQ publish channel error', err);\n });\n\n // Re-apply topology if we have one (reconnection scenario)\n if (this.topology) {\n await this.applyTopology(this.topology);\n // Recreate consumers for every active subscription on the new connection.\n for (const intent of this.subscriptionIntents) {\n await this.activateIntent(intent);\n }\n }\n } catch (err) {\n // Setup failed after the connection was opened - close it so that it doesn't leak\n try {\n await connection.close();\n } catch {\n // Ignore errors during cleanup\n }\n this.connection = null;\n this.publishChannel = null;\n throw err;\n }\n\n this.logger.info('[Matador] 🔌 Connected to RabbitMQ');\n }\n\n private async doDisconnect(): Promise<void> {\n // Cancel all consumers and close queue channels\n for (const queueChannel of this.queueChannels.values()) {\n for (const consumer of queueChannel.consumers) {\n consumer.active = false;\n try {\n await queueChannel.channel.cancel(consumer.consumerTag);\n } catch {\n // Ignore errors during cleanup\n }\n }\n try {\n await queueChannel.channel.close();\n } catch {\n // Ignore\n }\n }\n this.queueChannels.clear();\n\n // Close publish channel\n if (this.publishChannel) {\n try {\n await this.publishChannel.close();\n } catch {\n // Ignore\n }\n this.publishChannel = null;\n }\n\n // Close connection\n if (this.connection) {\n try {\n await this.connection.close();\n } catch {\n // Ignore\n }\n this.connection = null;\n }\n\n // Reset capabilities\n this.delayedExchangeAvailable = false;\n this._capabilities = {\n ...this._capabilities,\n delayedMessages: false,\n };\n }\n\n private async setupDelayedExchange(topology: Topology): Promise<void> {\n if (!this.connection) {\n return;\n }\n\n // Default to disabled\n this.delayedExchangeAvailable = false;\n\n const delayedExchange = this.getDelayedExchangeName(topology);\n const connection = this.connection;\n\n // Use a promise-based approach to ensure all error paths resolve cleanly\n // This prevents any error from propagating and affecting other channels\n return new Promise<void>((resolve) => {\n let resolved = false;\n const safeResolve = () => {\n if (!resolved) {\n resolved = true;\n resolve();\n }\n };\n\n connection\n .createChannel()\n .then((probeChannel) => {\n // Handle channel errors - this fires when RabbitMQ closes the channel\n probeChannel.on('error', () => {\n safeResolve();\n });\n\n // Handle channel close\n probeChannel.on('close', () => {\n safeResolve();\n });\n\n // Try to declare a delayed exchange\n // This will fail if the plugin is not installed\n probeChannel\n .assertExchange(delayedExchange, 'x-delayed-message', {\n durable: true,\n arguments: { 'x-delayed-type': 'direct' },\n })\n .then(() => {\n this.delayedExchangeAvailable = true;\n this._capabilities = {\n ...this._capabilities,\n delayedMessages: true,\n };\n this.logger.debug(\n '[Matador] 🔌 Delayed message exchange plugin detected',\n );\n // Close the probe channel gracefully\n probeChannel.close().catch(() => {});\n safeResolve();\n })\n .catch(() => {\n // assertExchange failed - plugin not available\n // Channel is already closed by RabbitMQ, no need to close\n this.logger.warn(\n '[Matador] 🟡 RabbitMQ delayed message exchange plugin not available. ' +\n 'Delayed messages will not be supported.',\n );\n safeResolve();\n });\n })\n .catch(() => {\n // Failed to create channel - shouldn't happen but handle it\n safeResolve();\n });\n });\n }\n\n private buildWorkQueueOptions(\n topology: Topology,\n queueDef: QueueDefinition,\n ): Options.AssertQueue {\n const queueOptions: Options.AssertQueue = {\n durable: true,\n arguments: {} as Record<string, unknown>,\n };\n\n if (this.config.quorumQueues && !queueDef.exact) {\n queueOptions.arguments['x-queue-type'] = 'quorum';\n }\n\n if (\n topology.deadLetter.unhandled.enabled ||\n topology.deadLetter.undeliverable.enabled\n ) {\n queueOptions.arguments['x-dead-letter-exchange'] =\n this.getDLXExchangeName(topology);\n }\n\n if (queueDef.priorities) {\n queueOptions.arguments['x-max-priority'] = 10;\n }\n\n if (queueDef.consumerTimeout) {\n queueOptions.arguments['x-consumer-timeout'] = queueDef.consumerTimeout;\n }\n\n if (queueDef.singleActiveConsumer) {\n queueOptions.arguments['x-single-active-consumer'] = true;\n }\n\n return queueOptions;\n }\n\n private async assertWorkQueue(\n channel: Channel,\n topology: Topology,\n queueDef: QueueDefinition,\n ): Promise<void> {\n const queueName = resolveQueueName(\n topology.namespace,\n queueDef,\n topology.naming,\n topology.prefix,\n );\n\n const rabbitmqOptions = queueDef.transport?.rabbitmq?.options;\n const queueOptions =\n rabbitmqOptions ?? this.buildWorkQueueOptions(topology, queueDef);\n await channel.assertQueue(queueName, queueOptions);\n\n // Bind queue to main exchange\n const mainExchange = this.getMainExchangeName(topology);\n await channel.bindQueue(queueName, mainExchange, queueName);\n\n // Bind to delayed exchange if available\n if (this.delayedExchangeAvailable) {\n const delayedExchange = this.getDelayedExchangeName(topology);\n await channel.bindQueue(queueName, delayedExchange, queueName);\n }\n\n // Create retry queue if retry is enabled.\n // Skip exact:true queues - they are owned by another team (cross-namespace).\n // The retry queue derives its `x-dead-letter-exchange` from\n // `${topology.namespace}.exchange`, which would conflict if multiple\n // namespaces share the broker and the queue. This mirrors the existing\n // `if (queueDef.exact) continue` guard in `assertDeadLetterQueues`.\n if (topology.retry.enabled && !queueDef.exact) {\n await this.assertRetryQueue(channel, topology, queueDef);\n }\n }\n\n private async assertRetryQueue(\n channel: Channel,\n topology: Topology,\n queueDef: QueueDefinition,\n ): Promise<void> {\n const workQueueName = resolveQueueName(\n topology.namespace,\n queueDef,\n topology.naming,\n topology.prefix,\n );\n const retryQueueName = getRetryQueueName(\n topology.namespace,\n queueDef.name,\n topology.naming,\n topology.prefix,\n );\n const mainExchange = this.getMainExchangeName(topology);\n\n const retryQueueOptions: Options.AssertQueue = {\n durable: true,\n arguments: {\n 'x-dead-letter-exchange': mainExchange,\n 'x-dead-letter-routing-key': workQueueName,\n 'x-message-ttl': topology.retry.defaultDelayMs,\n } as Record<string, unknown>,\n };\n\n if (this.config.quorumQueues) {\n retryQueueOptions.arguments['x-queue-type'] = 'quorum';\n }\n\n await channel.assertQueue(retryQueueName, retryQueueOptions);\n await channel.bindQueue(retryQueueName, mainExchange, retryQueueName);\n }\n\n private async assertDeadLetterQueues(\n channel: Channel,\n topology: Topology,\n dlqType: 'unhandled' | 'undeliverable',\n ): Promise<void> {\n const dlxExchange = this.getDLXExchangeName(topology);\n const dlConfig = topology.deadLetter[dlqType];\n\n for (const queueDef of topology.queues) {\n if (queueDef.exact) continue;\n\n const dlqName = getDeadLetterQueueName(\n topology.namespace,\n queueDef.name,\n dlqType,\n topology.naming,\n topology.prefix,\n );\n\n const dlqOptions: Options.AssertQueue = {\n durable: true,\n arguments: {} as Record<string, unknown>,\n };\n\n if (dlConfig.maxLength) {\n dlqOptions.arguments['x-max-length'] = dlConfig.maxLength;\n }\n\n // DLQs follow the same quorum setting as work and retry queues, so a\n // broker node restart does not take the queue (and its messages) down\n // with it.\n if (this.config.quorumQueues) {\n dlqOptions.arguments['x-queue-type'] = 'quorum';\n }\n\n await channel.assertQueue(dlqName, dlqOptions);\n await channel.bindQueue(dlqName, dlxExchange, dlqName);\n }\n }\n\n private getMainExchangeName(topology: Topology): string {\n return (\n topology.naming?.mainExchange?.(topology.namespace) ??\n applyPrefix(topology.prefix, `${topology.namespace}.exchange`)\n );\n }\n\n private getDLXExchangeName(topology: Topology): string {\n return (\n topology.naming?.dlxExchange?.(topology.namespace) ??\n applyPrefix(topology.prefix, `${topology.namespace}.dlx`)\n );\n }\n\n private getDelayedExchangeName(topology: Topology): string {\n return (\n topology.naming?.delayedExchange?.(topology.namespace) ??\n applyPrefix(topology.prefix, `${topology.namespace}.delayed`)\n );\n }\n\n private getAttemptNumber(msg: ConsumeMessage): number {\n const headerValue = msg.properties.headers?.['x-matador-attempts'];\n if (typeof headerValue === 'number') {\n return headerValue;\n }\n // Check for x-death header (native DLX redelivery count)\n const xDeath = msg.properties.headers?.['x-death'];\n if (Array.isArray(xDeath) && xDeath.length > 0) {\n const deathCount = xDeath.reduce(\n (sum: number, death: { count?: number }) => sum + (death.count ?? 0),\n 0,\n );\n return deathCount + 1;\n }\n return 1;\n }\n\n /**\n * Gets the native delivery count for poison message detection.\n * This tracks how many times the message was delivered without acknowledgment,\n * which helps detect crash loops.\n */\n private getDeliveryCount(msg: ConsumeMessage, attemptNumber: number): number {\n // Check for explicit delivery count header (some RabbitMQ setups track this)\n const deliveryCount = msg.properties.headers?.['x-delivery-count'];\n if (typeof deliveryCount === 'number') {\n return deliveryCount;\n }\n\n // Check x-death header for dead-letter redelivery count\n const xDeath = msg.properties.headers?.['x-death'];\n if (Array.isArray(xDeath) && xDeath.length > 0) {\n const deathCount = xDeath.reduce(\n (sum: number, death: { count?: number }) => sum + (death.count ?? 0),\n 0,\n );\n // Add 1 because we're currently being delivered again\n return deathCount + 1;\n }\n\n // If redelivered flag is set but no other tracking, count as 2 (first + this delivery)\n if (msg.fields.redelivered) {\n return Math.max(2, attemptNumber);\n }\n\n // Default to attempt number\n return attemptNumber;\n }\n}\n"]}
|