@relaybus/rabbitmq 0.1.0 → 0.3.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/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/errors.ts","../src/abortable-sleep.ts","../src/connection-supervisor.ts","../src/redelivery.ts","../src/options.ts","../src/topology.ts","../src/json-payload.ts","../src/wire-format.ts","../src/queue-consumer.ts","../src/serial-queue.ts","../src/rabbitmq-transport.ts"],"names":["ConfigurationError","toErrorInfo","delayMs","computeRetryDelay"],"mappings":"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","file":"index.js","sourcesContent":["import { NonRetryableError, RelayBusError } from '@relaybus/core';\n\n/**\n * The broker cannot take or confirm a message right now: the transport is not\n * connected, was closed, lost its channel, or the confirm did not arrive in time.\n * Always retryable; the outbox keeps the delivery and tries again.\n */\nexport class RabbitMqUnavailableError extends RelayBusError {}\n\n/** The broker negatively acknowledged a published message. Retryable. */\nexport class RabbitMqPublishRejectedError extends RelayBusError {}\n\n/**\n * The broker accepted the message but no queue is bound to its routing key, so\n * it would have been discarded. Retryable: it succeeds once a consumer binds.\n */\nexport class UnroutableMessageError extends RelayBusError {}\n\n/** A received message is not a valid relaybus CloudEvent. It is dead-lettered. */\nexport class MalformedMessageError extends RelayBusError {}\n\n/**\n * The payload of an event cannot be represented as JSON without losing or\n * changing data (`undefined`, functions, symbols, BigInt, NaN, Infinity, Dates,\n * Maps, class instances, cycles). Never retried: the payload will not change.\n */\nexport class UnserializablePayloadError extends NonRetryableError {\n override name = 'UnserializablePayloadError';\n}\n\n/**\n * A value exceeds a protocol limit of AMQP 0-9-1, for example an event id or a\n * routing key longer than the 255 bytes of a short string. Never retried.\n */\nexport class AmqpLimitExceededError extends NonRetryableError {\n override name = 'AmqpLimitExceededError';\n}\n","/** Resolves after `milliseconds`, or as soon as `signal` aborts (immediately when it already has). Never rejects. */\nexport function abortableSleep(milliseconds: number, signal: AbortSignal): Promise<void> {\n if (signal.aborted) {\n return Promise.resolve();\n }\n return new Promise((resolve) => {\n const finish = (): void => {\n clearTimeout(timer);\n signal.removeEventListener('abort', finish);\n resolve();\n };\n const timer = setTimeout(finish, milliseconds);\n signal.addEventListener('abort', finish, { once: true });\n });\n}\n","import {\n computeRetryDelay,\n toErrorInfo,\n type RelayBusLogger,\n type RetryPolicy,\n} from '@relaybus/core';\nimport { abortableSleep } from './abortable-sleep.js';\nimport type { AmqpConnection } from './amqp-types.js';\nimport { RabbitMqUnavailableError } from './errors.js';\n\nexport interface ConnectionSupervisorSettings {\n readonly connect: () => Promise<AmqpConnection>;\n /** Backoff between attempts, or undefined to never reconnect. */\n readonly reconnect: RetryPolicy | undefined;\n /** Creates channels and topology on a fresh connection. A rejection discards the connection. */\n readonly onConnected: (connection: AmqpConnection) => Promise<void>;\n /** The connection is gone or was discarded: drop everything that referenced it. */\n readonly onDisconnected: () => void;\n readonly logger: RelayBusLogger;\n readonly random: () => number;\n}\n\n/**\n * Owns the broker connection. amqplib does not reconnect, so after a connection\n * loss this class retries with capped, jittered backoff until `onConnected`\n * succeeds, and `close` stops it. It reports ready only once `onConnected` has\n * finished, so callers never use half-built channels.\n */\nexport class ConnectionSupervisor {\n readonly #settings: ConnectionSupervisorSettings;\n readonly #stop = new AbortController();\n #current: AmqpConnection | undefined;\n #ready = false;\n #started = false;\n #closed = false;\n #reconnecting: Promise<void> | undefined;\n\n constructor(settings: ConnectionSupervisorSettings) {\n this.#settings = settings;\n }\n\n /** True while a connection is open and `onConnected` has completed for it. */\n isConnected(): boolean {\n return this.#ready;\n }\n\n /**\n * Connects once. When that fails it rejects if `failOnError`, otherwise it\n * resolves and keeps trying in the background. Does nothing when already started.\n */\n async start(failOnError: boolean): Promise<void> {\n if (this.#started) {\n return;\n }\n if (this.#closed) {\n throw new RabbitMqUnavailableError('[ConnectionSupervisor](start) Transport is closed');\n }\n try {\n await this.#establish();\n this.#started = true;\n } catch (error) {\n if (failOnError) {\n throw error;\n }\n this.#settings.logger.warn(\n `[ConnectionSupervisor](start) Broker unreachable, retrying in the background | error=${toErrorInfo(error).message}`,\n );\n this.#started = true;\n this.#startReconnecting();\n }\n }\n\n /**\n * Drops the current connection because one of its channels failed, then\n * reconnects. Closing the channel alone would leave topology half-restored.\n */\n recover(reason: string): void {\n const connection = this.#current;\n if (connection === undefined) {\n return;\n }\n this.#handleLoss(connection, reason);\n connection.close().catch(() => undefined);\n }\n\n /**\n * Stops reconnecting, runs `beforeDisconnect` while the connection is still\n * open (to drain consumers) and closes the connection.\n */\n async close(beforeDisconnect: () => Promise<void>): Promise<void> {\n this.#closed = true;\n this.#stop.abort();\n await this.#reconnecting;\n try {\n await beforeDisconnect();\n } finally {\n const connection = this.#current;\n this.#current = undefined;\n this.#ready = false;\n await connection?.close().catch(() => undefined);\n }\n }\n\n async #establish(): Promise<void> {\n const connection = await this.#settings.connect();\n connection.on('error', (error: Error) => {\n this.#settings.logger.warn(\n `[ConnectionSupervisor](establish) Connection error | error=${error.message}`,\n );\n });\n connection.on('close', (error?: Error) => {\n this.#handleLoss(connection, error?.message ?? 'closed by peer');\n });\n this.#current = connection;\n try {\n await this.#settings.onConnected(connection);\n if (this.#current !== connection) {\n throw new RabbitMqUnavailableError(\n 'Connection was lost while the topology was being set up',\n );\n }\n } catch (error) {\n await this.#discard(connection);\n throw error;\n }\n this.#ready = true;\n }\n\n async #discard(connection: AmqpConnection): Promise<void> {\n if (this.#current === connection) {\n this.#current = undefined;\n }\n this.#settings.onDisconnected();\n await connection.close().catch(() => undefined);\n }\n\n #handleLoss(connection: AmqpConnection, reason: string): void {\n if (connection !== this.#current) {\n return;\n }\n this.#current = undefined;\n this.#ready = false;\n this.#settings.logger.warn(\n `[ConnectionSupervisor](handleLoss) Connection lost | reason=${reason}`,\n );\n this.#settings.onDisconnected();\n this.#startReconnecting();\n }\n\n #startReconnecting(): void {\n if (\n this.#settings.reconnect === undefined ||\n this.#closed ||\n !this.#started ||\n this.#reconnecting !== undefined\n ) {\n return;\n }\n const policy = this.#settings.reconnect;\n this.#reconnecting = this.#reconnectUntilConnected(policy).finally(() => {\n this.#reconnecting = undefined;\n });\n }\n\n async #reconnectUntilConnected(policy: RetryPolicy): Promise<void> {\n for (let attempt = 1; !this.#closed; attempt += 1) {\n const delayMs = computeRetryDelay(policy, attempt, this.#settings.random);\n this.#settings.logger.log(\n `[ConnectionSupervisor](reconnect) Reconnecting | attempt=${attempt} delayMs=${delayMs}`,\n );\n await abortableSleep(delayMs, this.#stop.signal);\n if (this.#closed) {\n return;\n }\n try {\n await this.#establish();\n this.#settings.logger.log(\n `[ConnectionSupervisor](reconnect) Reconnected | attempt=${attempt}`,\n );\n return;\n } catch (error) {\n this.#settings.logger.warn(\n `[ConnectionSupervisor](reconnect) Attempt failed | attempt=${attempt} error=${toErrorInfo(error).message}`,\n );\n }\n }\n }\n}\n","import { ConfigurationError, type RetryPolicy } from '@relaybus/core';\nimport type { AmqpMessage, AmqpPublishOptions } from './amqp-types.js';\n\n/** Number of delayed redeliveries a message went through. Set on every retry copy. */\nexport const REDELIVERIES_HEADER = 'x-relaybus-redeliveries';\n/** Epoch milliseconds of the first failure that needed a delayed redelivery. */\nexport const FIRST_FAILURE_HEADER = 'x-relaybus-first-failure-at';\n/** Why a message was moved to the dead-letter queue by the consumer. */\nexport const DEAD_LETTER_REASON_HEADER = 'x-relaybus-dead-letter-reason';\n\nconst RELAYBUS_STATE_HEADERS: readonly string[] = [REDELIVERIES_HEADER, FIRST_FAILURE_HEADER];\n/** Counters the broker stamps on its own redeliveries; they must not travel in a copy. */\nconst BROKER_COUNTER_HEADERS: readonly string[] = ['x-delivery-count', 'x-acquired-count'];\nconst MAXIMUM_LADDER_TIERS = 16;\n\n/**\n * The fixed delays of the retry queues, ascending: the policy's delay grown by\n * its factor until the cap. Each tier is its own queue with a queue-level TTL,\n * so messages in one queue always expire in arrival order; one queue with\n * mixed per-message TTLs would let a long delay hold back shorter ones.\n *\n * @throws {ConfigurationError} the policy has no usable delays or too many tiers\n */\nexport function buildRetryLadder(policy: RetryPolicy): readonly number[] {\n if (policy.initialDelayMs < 1) {\n throw new ConfigurationError('redelivery.initialDelay must be at least 1ms');\n }\n const tiers: number[] = [];\n let delay = policy.initialDelayMs;\n for (;;) {\n const tier = Math.round(Math.min(delay, policy.maxDelayMs));\n tiers.push(tier);\n if (tier >= policy.maxDelayMs || policy.factor === 1) {\n return tiers;\n }\n if (tiers.length === MAXIMUM_LADDER_TIERS) {\n throw new ConfigurationError(\n `redelivery needs more than ${MAXIMUM_LADDER_TIERS} retry queues; raise redelivery.factor or lower redelivery.maxDelay`,\n );\n }\n delay *= policy.factor;\n }\n}\n\n/**\n * Maps a jittered delay onto the ladder. A delay between two tiers goes to the\n * upper one with the probability that keeps the expected delay equal to\n * `delayMs`, so jitter still spreads a cohort of failures across tiers.\n */\nexport function chooseRetryTier(\n ladder: readonly number[],\n delayMs: number,\n random: () => number,\n): number {\n const upperIndex = ladder.findIndex((tier) => tier >= delayMs);\n if (upperIndex === -1) {\n return ladder.at(-1)!;\n }\n if (upperIndex === 0) {\n return ladder[0]!;\n }\n const lower = ladder[upperIndex - 1]!;\n const upper = ladder[upperIndex]!;\n return random() < (delayMs - lower) / (upper - lower) ? upper : lower;\n}\n\n/** Reads a non-negative integer that a copy carries as a header (string or number). */\nexport function readCounterHeader(message: AmqpMessage, name: string): number | undefined {\n // A message that decoded has headers: `cloudEvents:specversion` is required.\n const value = message.properties.headers![name];\n const parsed = typeof value === 'string' && /^\\d+$/.test(value) ? Number(value) : value;\n return typeof parsed === 'number' && Number.isSafeInteger(parsed) && parsed >= 0\n ? parsed\n : undefined;\n}\n\n/**\n * A byte-faithful copy of a received message for publishing to another queue:\n * same body and properties, headers carried over except the broker's delivery\n * counters and relaybus' own redelivery state, then `headerChanges` applied.\n */\nexport function copyForRepublish(\n message: AmqpMessage,\n headerChanges: Readonly<Record<string, string>>,\n): { content: Buffer; options: AmqpPublishOptions } {\n const { properties } = message;\n const headers: Record<string, unknown> = { ...properties.headers };\n for (const name of [\n ...RELAYBUS_STATE_HEADERS,\n DEAD_LETTER_REASON_HEADER,\n ...BROKER_COUNTER_HEADERS,\n ]) {\n delete headers[name];\n }\n Object.assign(headers, headerChanges);\n return {\n content: message.content,\n options: {\n contentType:\n typeof properties.contentType === 'string' ? properties.contentType : 'application/json',\n persistent: true,\n ...(typeof properties.messageId === 'string' ? { messageId: properties.messageId } : {}),\n ...(typeof properties.type === 'string' ? { type: properties.type } : {}),\n ...(typeof properties.appId === 'string' ? { appId: properties.appId } : {}),\n ...(typeof properties.correlationId === 'string'\n ? { correlationId: properties.correlationId }\n : {}),\n ...(typeof properties.timestamp === 'number' ? { timestamp: properties.timestamp } : {}),\n headers,\n },\n };\n}\n","import {\n ConfigurationError,\n createRetryPolicy,\n toMilliseconds,\n type Duration,\n type RelayBusLogger,\n type RetryPolicy,\n type RetryPolicyOptions,\n} from '@relaybus/core';\nimport type { AmqpConnection } from './amqp-types.js';\nimport { buildRetryLadder } from './redelivery.js';\n\n/** Connection settings accepted by `amqplib.connect`, given as an object instead of a URL. */\nexport interface BrokerConnectionSettings {\n readonly protocol?: string;\n readonly hostname?: string;\n readonly port?: number;\n readonly username?: string;\n readonly password?: string;\n readonly vhost?: string;\n /** Seconds. See \"Operational notes\" in the README for the heartbeat defaults of each amqplib version. */\n readonly heartbeat?: number;\n}\n\n/** Backoff between reconnect attempts. Attempts are unlimited. */\nexport type ReconnectOptions = Pick<\n RetryPolicyOptions,\n 'initialDelay' | 'factor' | 'maxDelay' | 'jitter'\n>;\n\n/**\n * Delayed redelivery of messages whose handler keeps failing. Each failed\n * delivery goes to a retry queue and returns to the main queue after a growing\n * delay, so an outage of the handler's dependency is waited out instead of\n * burning through delivery attempts.\n */\nexport type RedeliveryOptions = Pick<\n RetryPolicyOptions,\n 'initialDelay' | 'factor' | 'maxDelay' | 'jitter'\n> & {\n /**\n * How long a message may keep failing, counted from its first delayed\n * redelivery, before it is dead-lettered. Default `'1h'`.\n */\n readonly maxAge?: Duration;\n};\n\nexport interface RabbitMqTransportOptions {\n /** Name referenced by routes and subscriptions. Default `'rabbitmq'`. */\n readonly name?: string;\n /**\n * Broker location, for example `amqp://user:pass@host:5672/vhost?heartbeat=30`.\n * Give exactly one of `url` and `connect`.\n */\n readonly url?: string | BrokerConnectionSettings;\n /**\n * Opens one connection. Called again after every connection loss. Use it for\n * TLS options, custom credentials or an alternative amqplib instance.\n */\n readonly connect?: () => Promise<AmqpConnection>;\n /** Topic exchange events are published to. Durable, created when missing. Default `'relaybus'`. */\n readonly exchange?: string;\n /**\n * Unacknowledged messages the consumer holds, which is also its concurrency.\n * Default 50, or 1 when `ordered`.\n */\n readonly prefetch?: number;\n /** Prefix of derived queue names. Default `'relaybus'`. */\n readonly queuePrefix?: string;\n /**\n * Consumer group: services sharing it share one queue and split the messages,\n * services with different groups each receive every message. The queue is\n * `<queuePrefix>.<consumerGroup>`. Required when subscribing, unless `queue` is set.\n */\n readonly consumerGroup?: string;\n /** Explicit queue name. Overrides `queuePrefix` and `consumerGroup`. */\n readonly queue?: string;\n /** Exchange poison messages are dead-lettered to. Default `'<exchange>.dead'`. */\n readonly deadLetterExchange?: string;\n /** Queue that keeps dead-lettered messages for inspection. Default `'<queue>.dead'`. */\n readonly deadLetterQueue?: string;\n /**\n * Quorum queue `x-delivery-limit`: deliveries after which the broker itself\n * dead-letters a message. Failing handlers do not consume it (they use\n * `redelivery`); it only stops a message that crashes the consumer or its\n * channel again and again. Default 10.\n */\n readonly deliveryLimit?: number;\n /**\n * Handler attempts on the same delivery, with backoff, before the message is\n * scheduled for delayed redelivery. Absorbs short blips without a broker round\n * trip. Default: 3 attempts, 200 ms initial delay, factor 2, 5 s cap, equal jitter.\n */\n readonly handlerRetry?: RetryPolicyOptions;\n /**\n * Delayed redelivery after `handlerRetry` is spent. Default: 2 s initial\n * delay, factor 2, 5 min cap, equal jitter, dead-lettered after 1 h of\n * failing (about 18 redeliveries). Delays are quantized to the retry queues,\n * one per step of the exponential ladder (9 queues with the defaults).\n * Ignored when `ordered`, where the same delays are waited in place.\n */\n readonly redelivery?: RedeliveryOptions;\n /**\n * Consume the queue strictly in order: a single active consumer across all\n * replicas, one message at a time, a failing message is retried in place\n * (blocking the queue) instead of being delayed. Needed when\n * `EventEnvelope.key` order matters; costs throughput, because one handler\n * runs at a time. Default false: handlers run concurrently and a delayed\n * redelivery overtakes later messages, so order is not preserved.\n */\n readonly ordered?: boolean;\n /** Reconnect backoff, or `false` to never reconnect. Default: 500 ms initial, factor 2, 30 s cap, equal jitter. */\n readonly reconnect?: ReconnectOptions | false;\n /**\n * When true (default) `connect()` rejects if the broker is unreachable, which\n * fails startup. When false it resolves and keeps trying in the background.\n */\n readonly failOnConnectError?: boolean;\n /**\n * When false (default) a message that no queue is bound to makes `publish`\n * reject. When true it resolves and the broker silently discards the message.\n */\n readonly allowUnroutable?: boolean;\n /** How long `publish` waits for the broker confirm. Default `'30s'`. */\n readonly publishTimeout?: Duration;\n /** How long `close` waits for running handlers. Default `'30s'`. */\n readonly shutdownTimeout?: Duration;\n /** Default: `console`. */\n readonly logger?: RelayBusLogger;\n /** Random source for jitter. Default `Math.random`. Intended for tests. */\n readonly random?: () => number;\n}\n\nexport interface ResolvedTransportSettings {\n readonly name: string;\n readonly connect: () => Promise<AmqpConnection>;\n readonly exchange: string;\n readonly prefetch: number;\n readonly queuePrefix: string;\n readonly consumerGroup: string | undefined;\n readonly queue: string | undefined;\n readonly deadLetterExchange: string;\n readonly deadLetterQueue: string | undefined;\n readonly deliveryLimit: number;\n readonly handlerRetry: RetryPolicy;\n readonly redelivery: RetryPolicy;\n /** Fixed delays of the retry queues; empty when `ordered`. */\n readonly retryLadder: readonly number[];\n readonly redeliveryMaxAgeMs: number;\n readonly ordered: boolean;\n readonly reconnect: RetryPolicy | undefined;\n readonly failOnConnectError: boolean;\n readonly allowUnroutable: boolean;\n readonly publishTimeoutMs: number;\n readonly shutdownTimeoutMs: number;\n readonly logger: RelayBusLogger;\n readonly random: () => number;\n}\n\nconst DEFAULT_HANDLER_RETRY: RetryPolicy = {\n attempts: 3,\n initialDelayMs: 200,\n factor: 2,\n maxDelayMs: 5_000,\n jitter: 'equal',\n retryIf: undefined,\n};\n\nconst DEFAULT_REDELIVERY: RetryPolicy = {\n attempts: Number.POSITIVE_INFINITY,\n initialDelayMs: 2_000,\n factor: 2,\n maxDelayMs: 300_000,\n jitter: 'equal',\n retryIf: undefined,\n};\n\nconst DEFAULT_REDELIVERY_MAX_AGE = '1h';\n\nconst DEFAULT_RECONNECT: RetryPolicy = {\n attempts: 1,\n initialDelayMs: 500,\n factor: 2,\n maxDelayMs: 30_000,\n jitter: 'equal',\n retryIf: undefined,\n};\n\n/** Validates the options and applies defaults. Throws `ConfigurationError`. */\nexport function resolveSettings(options: RabbitMqTransportOptions): ResolvedTransportSettings {\n const exchange = nonEmpty(options.exchange ?? 'relaybus', 'exchange');\n const failOnConnectError = options.failOnConnectError ?? true;\n if (!failOnConnectError && options.reconnect === false) {\n throw new ConfigurationError(\n 'failOnConnectError=false needs reconnect enabled, otherwise the transport would never connect',\n );\n }\n const ordered = options.ordered ?? false;\n const prefetch = positiveInteger(options.prefetch ?? (ordered ? 1 : 50), 'prefetch');\n if (ordered && prefetch !== 1) {\n throw new ConfigurationError(`ordered consumption needs prefetch 1, received ${prefetch}`);\n }\n const redelivery = createRetryPolicy(options.redelivery, DEFAULT_REDELIVERY);\n return {\n name: nonEmpty(options.name ?? 'rabbitmq', 'name'),\n connect: resolveConnect(options),\n exchange,\n prefetch,\n queuePrefix: nonEmpty(options.queuePrefix ?? 'relaybus', 'queuePrefix'),\n consumerGroup: optionalNonEmpty(options.consumerGroup, 'consumerGroup'),\n queue: optionalNonEmpty(options.queue, 'queue'),\n deadLetterExchange: nonEmpty(\n options.deadLetterExchange ?? `${exchange}.dead`,\n 'deadLetterExchange',\n ),\n deadLetterQueue: optionalNonEmpty(options.deadLetterQueue, 'deadLetterQueue'),\n deliveryLimit: positiveInteger(options.deliveryLimit ?? 10, 'deliveryLimit'),\n handlerRetry: createRetryPolicy(options.handlerRetry, DEFAULT_HANDLER_RETRY),\n redelivery,\n retryLadder: ordered ? [] : buildRetryLadder(redelivery),\n redeliveryMaxAgeMs: positiveDuration(\n options.redelivery?.maxAge ?? DEFAULT_REDELIVERY_MAX_AGE,\n 'redelivery.maxAge',\n ),\n ordered,\n reconnect: resolveReconnect(options.reconnect),\n failOnConnectError,\n allowUnroutable: options.allowUnroutable ?? false,\n publishTimeoutMs: positiveDuration(options.publishTimeout ?? '30s', 'publishTimeout'),\n shutdownTimeoutMs: toMilliseconds(options.shutdownTimeout ?? '30s', 'shutdownTimeout'),\n logger: options.logger ?? console,\n random: options.random ?? Math.random,\n };\n}\n\n/** `<queuePrefix>.<consumerGroup>`, or the explicit queue name. */\nexport function resolveQueueName(settings: ResolvedTransportSettings): string {\n if (settings.queue !== undefined) {\n return settings.queue;\n }\n if (settings.consumerGroup === undefined) {\n throw new ConfigurationError(\n `Transport '${settings.name}' needs 'consumerGroup' or 'queue' to subscribe`,\n );\n }\n return `${settings.queuePrefix}.${settings.consumerGroup}`;\n}\n\nfunction resolveConnect(options: RabbitMqTransportOptions): () => Promise<AmqpConnection> {\n const { url, connect } = options;\n if ((url === undefined) === (connect === undefined)) {\n throw new ConfigurationError(\"Give exactly one of 'url' and 'connect'\");\n }\n if (connect !== undefined) {\n return connect;\n }\n return async () => {\n const amqplib = await import('amqplib');\n return amqplib.connect(url!);\n };\n}\n\nfunction resolveReconnect(\n reconnect: ReconnectOptions | false | undefined,\n): RetryPolicy | undefined {\n if (reconnect === false) {\n return undefined;\n }\n return createRetryPolicy({ ...reconnect, attempts: 1 }, DEFAULT_RECONNECT);\n}\n\nfunction nonEmpty(value: string, name: string): string {\n if (value.length === 0) {\n throw new ConfigurationError(`${name} must not be empty`);\n }\n return value;\n}\n\nfunction optionalNonEmpty(value: string | undefined, name: string): string | undefined {\n return value === undefined ? undefined : nonEmpty(value, name);\n}\n\nfunction positiveInteger(value: number, name: string): number {\n if (!Number.isInteger(value) || value < 1) {\n throw new ConfigurationError(`${name} must be a positive integer, received ${value}`);\n }\n return value;\n}\n\nfunction positiveDuration(value: Duration, name: string): number {\n const milliseconds = toMilliseconds(value, name);\n if (milliseconds === 0) {\n throw new ConfigurationError(`${name} must be greater than zero`);\n }\n return milliseconds;\n}\n","import type { AmqpChannel } from './amqp-types.js';\n\n/** Names of the broker objects a subscribing transport owns. */\nexport interface ConsumerTopology {\n readonly exchange: string;\n readonly queue: string;\n readonly deadLetterExchange: string;\n readonly deadLetterQueue: string;\n readonly deliveryLimit: number;\n /** Single active consumer, so the queue is consumed strictly in order. */\n readonly ordered: boolean;\n /** TTLs of the retry queues, ascending; empty when ordered. */\n readonly retryDelaysMs: readonly number[];\n /** Routing-key patterns the queue is bound with. */\n readonly destinations: readonly string[];\n}\n\n/** Name of the retry queue that holds messages for `delayMs` before returning them to `queue`. */\nexport function retryQueueName(queue: string, delayMs: number): string {\n return `${queue}.retry.${delayMs}`;\n}\n\n/** Declares the durable topic exchange events are published to. Idempotent. */\nexport async function assertExchange(channel: AmqpChannel, exchange: string): Promise<void> {\n await channel.assertExchange(exchange, 'topic', { durable: true });\n}\n\n/**\n * Declares the consumer side, all durable quorum queues and idempotent:\n *\n * - the main queue with a dead-letter exchange, `x-dead-letter-strategy`\n * `at-least-once` (which requires `x-overflow` `reject-publish`),\n * `x-delivery-limit` as a backstop for crash loops, and optionally\n * `x-single-active-consumer`; bound to the topic exchange once per destination;\n * - one retry queue per delay tier: a queue-level `x-message-ttl`, expired\n * messages dead-lettered through the default exchange back to the main queue;\n * - a direct dead-letter exchange and the dead-letter queue, bound with the main\n * queue's name as routing key.\n *\n * Declaring an existing queue with different arguments makes the broker close\n * the channel (`PRECONDITION_FAILED`); see the README for migrating a queue\n * created by an older version or with other options.\n */\nexport async function assertConsumerTopology(\n channel: AmqpChannel,\n topology: ConsumerTopology,\n): Promise<void> {\n await assertExchange(channel, topology.exchange);\n await channel.assertExchange(topology.deadLetterExchange, 'direct', { durable: true });\n await channel.assertQueue(topology.deadLetterQueue, {\n durable: true,\n arguments: { 'x-queue-type': 'quorum' },\n });\n await channel.bindQueue(topology.deadLetterQueue, topology.deadLetterExchange, topology.queue);\n for (const delayMs of topology.retryDelaysMs) {\n await channel.assertQueue(retryQueueName(topology.queue, delayMs), {\n durable: true,\n arguments: {\n 'x-queue-type': 'quorum',\n 'x-message-ttl': delayMs,\n 'x-dead-letter-exchange': '',\n 'x-dead-letter-routing-key': topology.queue,\n 'x-dead-letter-strategy': 'at-least-once',\n 'x-overflow': 'reject-publish',\n },\n });\n }\n await channel.assertQueue(topology.queue, {\n durable: true,\n arguments: {\n 'x-queue-type': 'quorum',\n 'x-delivery-limit': topology.deliveryLimit,\n 'x-dead-letter-exchange': topology.deadLetterExchange,\n 'x-dead-letter-routing-key': topology.queue,\n 'x-dead-letter-strategy': 'at-least-once',\n 'x-overflow': 'reject-publish',\n ...(topology.ordered ? { 'x-single-active-consumer': true } : {}),\n },\n });\n for (const destination of topology.destinations) {\n await channel.bindQueue(topology.queue, topology.exchange, destination);\n }\n}\n","import { UnserializablePayloadError } from './errors.js';\n\n/**\n * Throws {@link UnserializablePayloadError} unless `JSON.stringify` represents\n * `payload` faithfully. Only `null`, strings, booleans, finite numbers, arrays\n * and plain objects built from those are accepted. Everything `JSON.stringify`\n * would silently drop (`undefined`, functions, symbols, symbol keys, array holes),\n * convert (NaN and Infinity to `null`, Dates to strings, Maps and Sets to `{}`,\n * class instances to their own properties) or reject late (BigInt, cycles) is\n * refused up front, naming the offending path.\n */\nexport function assertJsonPayload(payload: unknown, eventId: string): void {\n visit(payload, '$', new Set(), eventId);\n}\n\nfunction visit(value: unknown, path: string, ancestors: Set<object>, eventId: string): void {\n switch (typeof value) {\n case 'string':\n case 'boolean':\n return;\n case 'number':\n if (!Number.isFinite(value)) {\n throw refuse(eventId, path, `is ${value}, which JSON turns into null`);\n }\n return;\n case 'object':\n if (value !== null) {\n visitObject(value, path, ancestors, eventId);\n }\n return;\n default:\n throw refuse(eventId, path, `is ${typeof value}, which JSON cannot represent`);\n }\n}\n\nfunction visitObject(value: object, path: string, ancestors: Set<object>, eventId: string): void {\n if (ancestors.has(value)) {\n throw refuse(eventId, path, 'is a circular reference');\n }\n ancestors.add(value);\n if (Array.isArray(value)) {\n for (let index = 0; index < value.length; index += 1) {\n if (!(index in value)) {\n throw refuse(eventId, `${path}[${index}]`, 'is an array hole, which JSON turns into null');\n }\n visit(value[index], `${path}[${index}]`, ancestors, eventId);\n }\n } else {\n const prototype = Object.getPrototypeOf(value) as object | null;\n if (prototype !== Object.prototype && prototype !== null) {\n throw refuse(eventId, path, 'is not a plain object (class instance, Date, Map or Set)');\n }\n if (Object.getOwnPropertySymbols(value).length > 0) {\n throw refuse(eventId, path, 'has a symbol key, which JSON drops');\n }\n for (const key of Object.keys(value)) {\n visit((value as Record<string, unknown>)[key], `${path}.${key}`, ancestors, eventId);\n }\n }\n ancestors.delete(value);\n}\n\nfunction refuse(eventId: string, path: string, reason: string): UnserializablePayloadError {\n return new UnserializablePayloadError(\n `Event ${eventId} has a payload JSON cannot represent faithfully: ${path} ${reason}`,\n );\n}\n","import type { EventEnvelope, EventHeaders } from '@relaybus/core';\nimport type { AmqpMessage, AmqpPublishOptions } from './amqp-types.js';\nimport { AmqpLimitExceededError, MalformedMessageError } from './errors.js';\nimport { assertJsonPayload } from './json-payload.js';\n\n/**\n * Wire format: CloudEvents 1.0 in binary content mode, following the CloudEvents\n * AMQP protocol binding adapted to RabbitMQ's AMQP 0-9-1.\n *\n * - Body: the JSON-encoded payload (`contentType` `application/json`).\n * - Headers `cloudEvents:specversion`, `cloudEvents:id`, `cloudEvents:type`,\n * `cloudEvents:source`, `cloudEvents:time` (RFC 3339, millisecond precision),\n * `cloudEvents:datacontenttype`, and when present `cloudEvents:subject` (the\n * key) and the extension attributes `cloudEvents:causationid` and\n * `cloudEvents:correlationid`.\n * - AMQP properties mirror the same values for broker tooling: `messageId`,\n * `type`, `appId` (source), `correlationId`, `timestamp` (seconds), plus\n * `deliveryMode` 2 (persistent).\n * - Event headers travel as `relaybus:<name>` message headers, so they cannot\n * collide with CloudEvents attributes or broker headers such as `x-death`.\n *\n * On receive the `cloudEvents:` headers win; the AMQP properties are the\n * fallback for events produced by other CloudEvents libraries (the AMQP\n * timestamp only when `cloudEvents:time` is absent; a present but malformed\n * time is rejected).\n *\n * AMQP 0-9-1 short strings (message properties, header names, routing keys) are\n * limited to 255 bytes. The event id, a header name or a routing key beyond\n * that is refused with {@link AmqpLimitExceededError}, because the event could\n * never be published. The `type`, `appId` and `correlationId` mirrors are\n * skipped when they do not fit; the `cloudEvents:` headers always carry them.\n */\nconst ATTRIBUTE_PREFIX = 'cloudEvents:';\nconst EVENT_HEADER_PREFIX = 'relaybus:';\nconst SPEC_VERSION = '1.0';\nconst JSON_CONTENT_TYPE = 'application/json';\nconst SHORT_STRING_LIMIT_BYTES = 255;\nconst RFC3339_PATTERN = /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?(?:Z|[+-]\\d{2}:\\d{2})$/i;\n\n/** A serialized event, ready for `channel.publish`. */\nexport interface EncodedMessage {\n readonly content: Buffer;\n readonly options: AmqpPublishOptions;\n}\n\n/**\n * Serializes an envelope.\n *\n * @throws {UnserializablePayloadError} the payload is not representable as JSON\n * @throws {AmqpLimitExceededError} the id or a header name exceeds 255 bytes\n */\nexport function encodeEnvelope(envelope: EventEnvelope): EncodedMessage {\n assertJsonPayload(envelope.payload, envelope.id);\n assertShortString('Event id', envelope.id);\n const headers: Record<string, string> = {\n [`${ATTRIBUTE_PREFIX}specversion`]: SPEC_VERSION,\n [`${ATTRIBUTE_PREFIX}id`]: envelope.id,\n [`${ATTRIBUTE_PREFIX}type`]: envelope.type,\n [`${ATTRIBUTE_PREFIX}source`]: envelope.source,\n [`${ATTRIBUTE_PREFIX}time`]: envelope.occurredAt.toISOString(),\n [`${ATTRIBUTE_PREFIX}datacontenttype`]: JSON_CONTENT_TYPE,\n };\n if (envelope.key !== null) {\n headers[`${ATTRIBUTE_PREFIX}subject`] = envelope.key;\n }\n if (envelope.causationId !== null) {\n headers[`${ATTRIBUTE_PREFIX}causationid`] = envelope.causationId;\n }\n if (envelope.correlationId !== null) {\n headers[`${ATTRIBUTE_PREFIX}correlationid`] = envelope.correlationId;\n }\n for (const [name, value] of Object.entries(envelope.headers)) {\n assertShortString(\n `Header name '${EVENT_HEADER_PREFIX}${name}'`,\n `${EVENT_HEADER_PREFIX}${name}`,\n );\n headers[`${EVENT_HEADER_PREFIX}${name}`] = value;\n }\n return {\n content: Buffer.from(JSON.stringify(envelope.payload), 'utf8'),\n options: {\n contentType: JSON_CONTENT_TYPE,\n persistent: true,\n messageId: envelope.id,\n timestamp: Math.floor(envelope.occurredAt.getTime() / 1_000),\n ...mirror('type', envelope.type),\n ...mirror('appId', envelope.source),\n ...(envelope.correlationId === null ? {} : mirror('correlationId', envelope.correlationId)),\n headers,\n },\n };\n}\n\n/**\n * Throws {@link AmqpLimitExceededError} when `value` does not fit an AMQP short\n * string (255 bytes of UTF-8), which amqplib would otherwise reject on every\n * attempt.\n */\nexport function assertShortString(label: string, value: string): void {\n const bytes = Buffer.byteLength(value, 'utf8');\n if (bytes > SHORT_STRING_LIMIT_BYTES) {\n throw new AmqpLimitExceededError(\n `${label} is ${bytes} bytes, above the AMQP limit of ${SHORT_STRING_LIMIT_BYTES} bytes`,\n );\n }\n}\n\nfunction mirror<TName extends 'type' | 'appId' | 'correlationId'>(\n name: TName,\n value: string,\n): { [Name in TName]?: string } {\n return Buffer.byteLength(value, 'utf8') > SHORT_STRING_LIMIT_BYTES\n ? {}\n : ({ [name]: value } as { [Name in TName]?: string });\n}\n\n/** Rebuilds an envelope. Throws {@link MalformedMessageError} when the message is not a relaybus event. */\nexport function decodeEnvelope(message: AmqpMessage): EventEnvelope {\n const { properties } = message;\n const attributes = properties.headers ?? {};\n if (attributes[`${ATTRIBUTE_PREFIX}specversion`] !== SPEC_VERSION) {\n throw new MalformedMessageError(\n `Message is not a CloudEvents ${SPEC_VERSION} event (header ${ATTRIBUTE_PREFIX}specversion)`,\n );\n }\n return {\n id: required('id', text(attributes[`${ATTRIBUTE_PREFIX}id`]) ?? text(properties.messageId)),\n type: required('type', text(attributes[`${ATTRIBUTE_PREFIX}type`]) ?? text(properties.type)),\n source: required(\n 'source',\n text(attributes[`${ATTRIBUTE_PREFIX}source`]) ?? text(properties.appId),\n ),\n key: text(attributes[`${ATTRIBUTE_PREFIX}subject`]) ?? null,\n payload: parsePayload(message.content),\n headers: extractEventHeaders(attributes),\n correlationId:\n text(attributes[`${ATTRIBUTE_PREFIX}correlationid`]) ??\n text(properties.correlationId) ??\n null,\n causationId: text(attributes[`${ATTRIBUTE_PREFIX}causationid`]) ?? null,\n occurredAt: parseTime(attributes[`${ATTRIBUTE_PREFIX}time`], properties.timestamp),\n };\n}\n\nfunction extractEventHeaders(attributes: Readonly<Record<string, unknown>>): EventHeaders {\n const headers: Record<string, string> = {};\n for (const [name, value] of Object.entries(attributes)) {\n if (name.startsWith(EVENT_HEADER_PREFIX) && typeof value === 'string') {\n // defineProperty, because assigning `__proto__` would set the prototype and lose the header.\n Object.defineProperty(headers, name.slice(EVENT_HEADER_PREFIX.length), {\n value,\n enumerable: true,\n writable: true,\n configurable: true,\n });\n }\n }\n return headers;\n}\n\nfunction parsePayload(content: Buffer): unknown {\n try {\n return JSON.parse(content.toString('utf8')) as unknown;\n } catch {\n throw new MalformedMessageError('Message body is not valid JSON');\n }\n}\n\nfunction parseTime(rawTime: unknown, timestampSeconds: unknown): Date {\n if (rawTime === undefined) {\n const fallback =\n typeof timestampSeconds === 'number' ? new Date(timestampSeconds * 1_000) : undefined;\n if (fallback === undefined || Number.isNaN(fallback.getTime())) {\n throw new MalformedMessageError('Message has no valid time (header cloudEvents:time)');\n }\n return fallback;\n }\n const occurredAt =\n typeof rawTime === 'string' && RFC3339_PATTERN.test(rawTime) ? new Date(rawTime) : undefined;\n if (occurredAt === undefined || Number.isNaN(occurredAt.getTime())) {\n throw new MalformedMessageError(\n 'Message time (header cloudEvents:time) is not an RFC 3339 timestamp',\n );\n }\n return occurredAt;\n}\n\nfunction text(value: unknown): string | undefined {\n return typeof value === 'string' ? value : undefined;\n}\n\nfunction required(attribute: string, value: string | undefined): string {\n if (value === undefined || value.length === 0) {\n throw new MalformedMessageError(\n `Message has no ${attribute} (header ${ATTRIBUTE_PREFIX}${attribute})`,\n );\n }\n return value;\n}\n","import {\n computeRetryDelay,\n isRetryableError,\n toErrorInfo,\n type EventEnvelope,\n type RelayBusLogger,\n type RetryPolicy,\n type TransportMessageHandler,\n} from '@relaybus/core';\nimport { abortableSleep } from './abortable-sleep.js';\nimport type { AmqpChannel, AmqpMessage, AmqpPublishOptions } from './amqp-types.js';\nimport { RabbitMqUnavailableError } from './errors.js';\nimport {\n DEAD_LETTER_REASON_HEADER,\n FIRST_FAILURE_HEADER,\n REDELIVERIES_HEADER,\n chooseRetryTier,\n copyForRepublish,\n readCounterHeader,\n} from './redelivery.js';\nimport { retryQueueName } from './topology.js';\nimport { decodeEnvelope } from './wire-format.js';\n\n/** Publishes a message and resolves only after the broker confirmed it was routed to a queue. */\nexport type ConfirmedRepublish = (\n exchange: string,\n routingKey: string,\n content: Buffer,\n options: AmqpPublishOptions,\n) => Promise<void>;\n\nexport interface QueueConsumerSettings {\n readonly queue: string;\n readonly prefetch: number;\n readonly handlerRetry: RetryPolicy;\n /** Backoff between delayed redeliveries. */\n readonly redelivery: RetryPolicy;\n /** Delays of the retry queues, ascending. Unused when ordered. */\n readonly retryLadder: readonly number[];\n /** A message failing for longer than this is dead-lettered. */\n readonly redeliveryMaxAgeMs: number;\n /** Retry in place instead of through the retry queues, so order is kept. */\n readonly ordered: boolean;\n readonly deadLetterExchange: string;\n readonly shutdownTimeoutMs: number;\n readonly onMessage: TransportMessageHandler;\n /** The consumer's channel closed or the broker cancelled the consumer. */\n readonly onConsumerLost: (reason: string) => void;\n /** Publishes to another queue on a confirm channel; rejects when the copy is not confirmed. */\n readonly republish: ConfirmedRepublish;\n readonly logger: RelayBusLogger;\n readonly random: () => number;\n}\n\ntype Settlement = 'ack' | 'requeue' | 'dead-letter';\n\n/**\n * Consumes one queue with manual acknowledgements.\n *\n * A message is acknowledged only after the handler resolved. When the handler\n * fails it is first retried on the same delivery with short backoff\n * (`handlerRetry`). If that does not help, a copy goes to the retry queue whose\n * TTL matches the next backoff step, and the original is acknowledged only\n * after the broker confirmed the copy; the copy returns to the main queue when\n * its TTL expires. This waits out a long outage of the handler's dependency.\n *\n * Malformed messages, non-retryable errors and messages that kept failing for\n * `redeliveryMaxAgeMs` go to the dead-letter exchange through a confirmed copy\n * (carrying the reason, without retry state, so a replay starts fresh) and the\n * original is acknowledged afterwards. If a copy cannot be confirmed the\n * original is requeued or rejected without requeue, which makes the broker\n * dead-letter it; it is never acknowledged unprocessed, so nothing is lost.\n *\n * In ordered mode nothing is moved: the failing message is retried in place with\n * the same backoff, holding the queue.\n */\nexport class QueueConsumer {\n readonly #settings: QueueConsumerSettings;\n readonly #inFlight = new Set<Promise<void>>();\n readonly #stopping = new AbortController();\n #channel: AmqpChannel | undefined;\n #consumerTag: string | undefined;\n\n constructor(settings: QueueConsumerSettings) {\n this.#settings = settings;\n }\n\n /** True while a consumer is registered on a live channel. */\n isActive(): boolean {\n return this.#consumerTag !== undefined;\n }\n\n /**\n * Starts consuming on a channel whose topology is already declared.\n *\n * @throws {RabbitMqUnavailableError} the channel closed while it was being set up\n */\n async attach(channel: AmqpChannel): Promise<void> {\n let closedDuringSetup = false;\n channel.on('error', (error: Error) => {\n this.#settings.logger.warn(\n `[QueueConsumer](attach) Channel error | queue=${this.#settings.queue} error=${error.message}`,\n );\n });\n channel.on('close', () => {\n closedDuringSetup = true;\n if (this.#channel === channel) {\n this.#channel = undefined;\n this.#consumerTag = undefined;\n this.#settings.onConsumerLost('consumer channel closed');\n }\n });\n await channel.prefetch(this.#settings.prefetch);\n const { consumerTag } = await channel.consume(\n this.#settings.queue,\n (message) => this.#receive(channel, message),\n { noAck: false },\n );\n if (closedDuringSetup) {\n throw new RabbitMqUnavailableError(\n `[QueueConsumer](attach) Consumer channel closed while the consumer was being set up | queue=${this.#settings.queue}`,\n );\n }\n this.#channel = channel;\n this.#consumerTag = consumerTag;\n }\n\n /** Forgets the channel without closing it, because its connection is gone. */\n detach(): void {\n this.#channel = undefined;\n this.#consumerTag = undefined;\n }\n\n /**\n * Stops taking messages, aborts pending handler backoff (those messages are\n * requeued), waits up to the shutdown timeout for running handlers, then\n * closes the channel. Unacknowledged messages return to the queue.\n */\n async stop(): Promise<void> {\n this.#stopping.abort();\n const channel = this.#channel;\n const consumerTag = this.#consumerTag;\n this.#channel = undefined;\n this.#consumerTag = undefined;\n if (channel !== undefined && consumerTag !== undefined) {\n await channel.cancel(consumerTag).catch((error: unknown) => {\n this.#settings.logger.warn(\n `[QueueConsumer](stop) Could not cancel consumer | queue=${this.#settings.queue} error=${toErrorInfo(error).message}`,\n );\n });\n }\n await this.#awaitInFlight();\n await channel?.close().catch(() => undefined);\n }\n\n async #awaitInFlight(): Promise<void> {\n if (this.#inFlight.size === 0) {\n return;\n }\n const timeout = new AbortController();\n const timedOut = abortableSleep(this.#settings.shutdownTimeoutMs, timeout.signal);\n await Promise.race([Promise.allSettled([...this.#inFlight]), timedOut]);\n timeout.abort();\n }\n\n #receive(channel: AmqpChannel, message: AmqpMessage | null): void {\n if (message === null) {\n this.#consumerTag = undefined;\n this.#settings.onConsumerLost('consumer cancelled by the broker');\n return;\n }\n const task: Promise<void> = this.#process(channel, message).finally(() => {\n this.#inFlight.delete(task);\n });\n this.#inFlight.add(task);\n }\n\n async #process(channel: AmqpChannel, message: AmqpMessage): Promise<void> {\n const { queue, handlerRetry } = this.#settings;\n let envelope: EventEnvelope;\n try {\n envelope = decodeEnvelope(message);\n } catch (error) {\n this.#settings.logger.error(\n `[QueueConsumer](process) Dead-lettering malformed message | queue=${queue} routingKey=${message.fields.routingKey} error=${toErrorInfo(error).message}`,\n );\n await this.#deadLetter(channel, message, 'malformed message');\n return;\n }\n let redeliveries = readCounterHeader(message, REDELIVERIES_HEADER) ?? 0;\n let firstFailureAt = readCounterHeader(message, FIRST_FAILURE_HEADER);\n for (let attempt = 1; ; attempt += 1) {\n try {\n await this.#settings.onMessage(envelope);\n this.#settle(channel, message, 'ack');\n return;\n } catch (error) {\n const failure = `queue=${queue} eventId=${envelope.id} attempt=${attempt} error=${toErrorInfo(error).message}`;\n if (!isRetryableError(handlerRetry, error)) {\n this.#settings.logger.error(\n `[QueueConsumer](process) Dead-lettering message the handler cannot process | ${failure}`,\n );\n await this.#deadLetter(channel, message, 'non-retryable handler error');\n return;\n }\n if (attempt < handlerRetry.attempts) {\n const delayMs = computeRetryDelay(handlerRetry, attempt, this.#settings.random);\n this.#settings.logger.warn(\n `[QueueConsumer](process) Handler failed, retrying | ${failure} delayMs=${delayMs}`,\n );\n if (await this.#interrupted(delayMs)) {\n this.#settle(channel, message, 'requeue');\n return;\n }\n continue;\n }\n redeliveries += 1;\n const now = Date.now();\n firstFailureAt ??= now;\n const delayMs = this.#redeliveryDelay(redeliveries);\n if (now + delayMs - firstFailureAt > this.#settings.redeliveryMaxAgeMs) {\n this.#settings.logger.error(\n `[QueueConsumer](process) Dead-lettering message that kept failing | ${failure} redeliveries=${redeliveries - 1} failingForMs=${now - firstFailureAt} maxAgeMs=${this.#settings.redeliveryMaxAgeMs}`,\n );\n await this.#deadLetter(channel, message, 'redelivery window exhausted');\n return;\n }\n this.#settings.logger.warn(\n `[QueueConsumer](process) Handler attempts spent, retrying later | ${failure} redeliveries=${redeliveries} delayMs=${delayMs}`,\n );\n if (!this.#settings.ordered) {\n await this.#redeliverLater(channel, message, delayMs, redeliveries, firstFailureAt);\n return;\n }\n if (await this.#interrupted(delayMs)) {\n this.#settle(channel, message, 'requeue');\n return;\n }\n }\n }\n }\n\n /** The backoff before the next delayed redelivery: a retry queue's TTL, or an exact wait when ordered. */\n #redeliveryDelay(redeliveries: number): number {\n const { redelivery, retryLadder, ordered, random } = this.#settings;\n const delayMs = computeRetryDelay(redelivery, redeliveries, random);\n return ordered ? delayMs : chooseRetryTier(retryLadder, delayMs, random);\n }\n\n /** Sleeps; true when the consumer is stopping, so the caller must give the message back. */\n async #interrupted(delayMs: number): Promise<boolean> {\n await abortableSleep(delayMs, this.#stopping.signal);\n return this.#stopping.signal.aborted;\n }\n\n /**\n * Parks a copy in the retry queue of `delayMs` and acknowledges the original\n * only once the broker confirmed the copy. When the copy cannot be confirmed\n * the original is requeued after the same delay, so it is neither lost nor\n * hot-looped.\n */\n async #redeliverLater(\n channel: AmqpChannel,\n message: AmqpMessage,\n delayMs: number,\n redeliveries: number,\n firstFailureAt: number,\n ): Promise<void> {\n const { content, options } = copyForRepublish(message, {\n [REDELIVERIES_HEADER]: String(redeliveries),\n [FIRST_FAILURE_HEADER]: String(firstFailureAt),\n });\n try {\n await this.#settings.republish(\n '',\n retryQueueName(this.#settings.queue, delayMs),\n content,\n options,\n );\n } catch (error) {\n this.#settings.logger.warn(\n `[QueueConsumer](redeliverLater) Could not park the message in the retry queue, requeueing it | queue=${this.#settings.queue} delayMs=${delayMs} error=${toErrorInfo(error).message}`,\n );\n await this.#interrupted(delayMs);\n this.#settle(channel, message, 'requeue');\n return;\n }\n this.#settle(channel, message, 'ack');\n }\n\n /**\n * Moves the message to the dead-letter queue through a confirmed copy that\n * carries the reason and no retry state. If the copy cannot be confirmed the\n * message is rejected without requeue, which makes the broker dead-letter it\n * (at-least-once), so it still ends up in the dead-letter queue.\n */\n async #deadLetter(channel: AmqpChannel, message: AmqpMessage, reason: string): Promise<void> {\n const { content, options } = copyForRepublish(message, {\n [DEAD_LETTER_REASON_HEADER]: reason,\n });\n try {\n await this.#settings.republish(\n this.#settings.deadLetterExchange,\n this.#settings.queue,\n content,\n options,\n );\n } catch (error) {\n this.#settings.logger.warn(\n `[QueueConsumer](deadLetter) Could not publish to the dead-letter exchange, leaving it to the broker | queue=${this.#settings.queue} error=${toErrorInfo(error).message}`,\n );\n this.#settle(channel, message, 'dead-letter');\n return;\n }\n this.#settle(channel, message, 'ack');\n }\n\n #settle(channel: AmqpChannel, message: AmqpMessage, settlement: Settlement): void {\n try {\n if (settlement === 'ack') {\n channel.ack(message);\n } else {\n channel.nack(message, false, settlement === 'requeue');\n }\n } catch (error) {\n // The channel is gone; the broker redelivers the message and the inbox drops the duplicate.\n this.#settings.logger.warn(\n `[QueueConsumer](settle) Could not ${settlement} message, the broker will redeliver it | queue=${this.#settings.queue} error=${toErrorInfo(error).message}`,\n );\n }\n }\n}\n","/** Runs async tasks one after another, in submission order, even when one fails. */\nexport class SerialQueue {\n #tail: Promise<unknown> = Promise.resolve();\n\n run<TResult>(task: () => Promise<TResult>): Promise<TResult> {\n const result = this.#tail.then(task);\n this.#tail = result.catch(() => undefined);\n return result;\n }\n}\n","import {\n ConfigurationError,\n toErrorInfo,\n type EventEnvelope,\n type Transport,\n type TransportMessageHandler,\n} from '@relaybus/core';\nimport type {\n AmqpConfirmChannel,\n AmqpConnection,\n AmqpMessage,\n AmqpPublishOptions,\n} from './amqp-types.js';\nimport { ConnectionSupervisor } from './connection-supervisor.js';\nimport {\n RabbitMqPublishRejectedError,\n RabbitMqUnavailableError,\n UnroutableMessageError,\n} from './errors.js';\nimport {\n resolveQueueName,\n resolveSettings,\n type RabbitMqTransportOptions,\n type ResolvedTransportSettings,\n} from './options.js';\nimport { QueueConsumer } from './queue-consumer.js';\nimport { SerialQueue } from './serial-queue.js';\nimport { assertConsumerTopology, assertExchange, type ConsumerTopology } from './topology.js';\nimport { assertShortString, encodeEnvelope } from './wire-format.js';\n\n/** Publisher channel plus the broker returns not yet matched with their confirm. */\ninterface Publisher {\n readonly channel: AmqpConfirmChannel;\n readonly unroutable: Map<string, number>;\n /** Set when the channel closed, also while the transport was still being set up. */\n closed: boolean;\n}\n\ninterface LiveConnection {\n readonly connection: AmqpConnection;\n readonly publisher: Publisher;\n}\n\ninterface Subscription {\n readonly topology: ConsumerTopology;\n readonly consumer: QueueConsumer;\n}\n\n/** amqplib reports a negative acknowledgement with this exact message. */\nconst NACK_MESSAGE = 'message nacked';\n\n/**\n * RabbitMQ {@link Transport} built on amqplib.\n *\n * Publishing: each event goes to a durable topic exchange as a persistent,\n * mandatory message with the destination as routing key. `publish` resolves\n * only after the broker confirmed it was persisted and routed to a queue, and\n * rejects when the transport is disconnected, the broker nacks, the message is\n * unroutable or no confirm arrives in time. It never drops a message silently,\n * so the outbox retries the delivery.\n *\n * Subscribing: one durable quorum queue per consumer group, bound to the\n * destinations (routing-key patterns such as `orders.*`). A message is\n * acknowledged only after the handler resolved. A failing handler is retried\n * on the same delivery, then through retry queues with growing delays (see\n * `redelivery`), and finally dead-lettered after the retry window; poison\n * messages are dead-lettered at once. Nothing is lost on the way.\n *\n * Reconnection: after a connection or channel loss the transport reconnects\n * with capped, jittered backoff and restores channels, topology and the\n * consumer. Events published meanwhile are rejected, and therefore retried by\n * the outbox, rather than buffered in memory.\n */\nexport class RabbitMqTransport implements Transport {\n readonly name: string;\n readonly #settings: ResolvedTransportSettings;\n readonly #supervisor: ConnectionSupervisor;\n /** Serializes topology work so a subscription never races a reconnect. */\n readonly #topologyWork = new SerialQueue();\n #live: LiveConnection | undefined;\n #subscription: Subscription | undefined;\n #closed = false;\n\n constructor(options: RabbitMqTransportOptions) {\n this.#settings = resolveSettings(options);\n this.name = this.#settings.name;\n this.#supervisor = new ConnectionSupervisor({\n connect: this.#settings.connect,\n reconnect: this.#settings.reconnect,\n onConnected: (connection) => this.#establishChannels(connection),\n onDisconnected: () => this.#forgetConnection(),\n logger: this.#settings.logger,\n random: this.#settings.random,\n });\n }\n\n /**\n * True while the connection is open and publishing and consuming are set up.\n * Use it for readiness probes.\n */\n isConnected(): boolean {\n return this.#supervisor.isConnected();\n }\n\n /**\n * True when the transport can publish and, once subscribed, is consuming: the\n * connection is up, its channels are open and the consumer is registered. False while reconnecting and after a cancelled consumer.\n */\n isReady(): boolean {\n return (\n this.#supervisor.isConnected() &&\n this.#live !== undefined &&\n (this.#subscription === undefined || this.#subscription.consumer.isActive())\n );\n }\n\n /** Connects to the broker. Rejects when it is unreachable unless `failOnConnectError` is false. */\n async connect(): Promise<void> {\n await this.#supervisor.start(this.#settings.failOnConnectError);\n }\n\n /**\n * Publishes to the exchange with `destination` as routing key and resolves\n * after the broker confirmed the message.\n *\n * @throws {UnserializablePayloadError} the payload is not representable as JSON (never retried)\n * @throws {AmqpLimitExceededError} the event id, a header name or `destination` exceeds 255 bytes (never retried)\n * @throws {RabbitMqUnavailableError} not connected, channel lost, or confirm timed out\n * @throws {RabbitMqPublishRejectedError} the broker nacked the message\n * @throws {UnroutableMessageError} no queue is bound to `destination` (unless `allowUnroutable`)\n */\n async publish(envelope: EventEnvelope, destination: string): Promise<void> {\n assertShortString('Destination (routing key)', destination);\n const { content, options } = encodeEnvelope(envelope);\n await this.#publishConfirmed(\n this.#settings.exchange,\n destination,\n content,\n options,\n !this.#settings.allowUnroutable,\n );\n }\n\n async #publishConfirmed(\n exchange: string,\n routingKey: string,\n content: Buffer,\n options: AmqpPublishOptions,\n mandatory: boolean,\n ): Promise<void> {\n const publisher = this.#live?.publisher;\n const eventId = options.messageId ?? 'unknown';\n if (publisher === undefined) {\n throw new RabbitMqUnavailableError(\n `[RabbitMqTransport](publish) Not connected to the broker | transport=${this.name} destination=${routingKey}`,\n );\n }\n const returnKey = unroutableKey(options.messageId, routingKey);\n await new Promise<void>((resolve, reject) => {\n const timer = setTimeout(() => {\n reject(\n new RabbitMqUnavailableError(\n `[RabbitMqTransport](publish) No broker confirm within ${this.#settings.publishTimeoutMs}ms | transport=${this.name} eventId=${eventId} destination=${routingKey}`,\n ),\n );\n }, this.#settings.publishTimeoutMs);\n const onConfirm = (error: Error | null | undefined): void => {\n clearTimeout(timer);\n const returned = takeUnroutable(publisher.unroutable, returnKey);\n if (error) {\n reject(this.#toPublishError(error, eventId, routingKey));\n } else if (returned) {\n reject(\n new UnroutableMessageError(\n `[RabbitMqTransport](publish) No queue is bound to the routing key | transport=${this.name} eventId=${eventId} destination=${routingKey}`,\n ),\n );\n } else {\n resolve();\n }\n };\n try {\n publisher.channel.publish(\n exchange,\n routingKey,\n content,\n { ...options, mandatory },\n onConfirm,\n );\n } catch (error) {\n clearTimeout(timer);\n reject(this.#toPublishError(error, eventId, routingKey));\n }\n });\n }\n\n /**\n * Binds one durable quorum queue to `destinations` and delivers its messages\n * to `onMessage`. Call it once per transport; give each subscription its own\n * transport instance, with its own `name` and `consumerGroup`.\n */\n async subscribe(\n destinations: readonly string[],\n onMessage: TransportMessageHandler,\n ): Promise<void> {\n if (this.#subscription !== undefined) {\n throw new ConfigurationError(\n `Transport '${this.name}' already has a subscription; create another transport for another consumer group`,\n );\n }\n if (destinations.length === 0) {\n throw new ConfigurationError(`Transport '${this.name}' needs at least one destination`);\n }\n const queue = resolveQueueName(this.#settings);\n const subscription: Subscription = {\n topology: {\n exchange: this.#settings.exchange,\n queue,\n deadLetterExchange: this.#settings.deadLetterExchange,\n deadLetterQueue: this.#settings.deadLetterQueue ?? `${queue}.dead`,\n deliveryLimit: this.#settings.deliveryLimit,\n ordered: this.#settings.ordered,\n retryDelaysMs: this.#settings.retryLadder,\n destinations,\n },\n consumer: new QueueConsumer({\n queue,\n prefetch: this.#settings.prefetch,\n handlerRetry: this.#settings.handlerRetry,\n redelivery: this.#settings.redelivery,\n retryLadder: this.#settings.retryLadder,\n redeliveryMaxAgeMs: this.#settings.redeliveryMaxAgeMs,\n ordered: this.#settings.ordered,\n deadLetterExchange: this.#settings.deadLetterExchange,\n republish: (exchange, routingKey, content, options) =>\n this.#publishConfirmed(exchange, routingKey, content, options, true),\n shutdownTimeoutMs: this.#settings.shutdownTimeoutMs,\n onMessage,\n onConsumerLost: (reason) => this.#supervisor.recover(reason),\n logger: this.#settings.logger,\n random: this.#settings.random,\n }),\n };\n await this.#topologyWork.run(async () => {\n this.#subscription = subscription;\n if (this.#live !== undefined) {\n await this.#startConsuming(this.#live.connection, subscription);\n }\n });\n }\n\n /**\n * Stops consuming, waits up to `shutdownTimeout` for running handlers\n * (messages still being retried go back to the queue), then closes the\n * channels and the connection.\n */\n async close(): Promise<void> {\n if (this.#closed) {\n return;\n }\n this.#closed = true;\n await this.#supervisor.close(() =>\n this.#topologyWork.run(async () => {\n const live = this.#live;\n this.#live = undefined;\n await this.#subscription?.consumer.stop();\n await live?.publisher.channel.close().catch(() => undefined);\n }),\n );\n }\n\n async #establishChannels(connection: AmqpConnection): Promise<void> {\n await this.#topologyWork.run(async () => {\n const channel = await connection.createConfirmChannel();\n const publisher: Publisher = { channel, unroutable: new Map(), closed: false };\n channel.on('error', (error: Error) => {\n this.#settings.logger.warn(\n `[RabbitMqTransport](establishChannels) Publisher channel error | transport=${this.name} error=${error.message}`,\n );\n });\n channel.on('close', () => {\n publisher.closed = true;\n if (this.#live?.publisher === publisher) {\n this.#supervisor.recover('publisher channel closed');\n }\n });\n channel.on('return', (message: AmqpMessage) => {\n recordUnroutable(\n publisher.unroutable,\n unroutableKey(message.properties.messageId, message.fields.routingKey),\n );\n });\n await assertExchange(channel, this.#settings.exchange);\n if (this.#subscription !== undefined) {\n await this.#startConsuming(connection, this.#subscription);\n }\n if (publisher.closed) {\n // The close came before `live` was set, so nothing reacted to it.\n throw new RabbitMqUnavailableError(\n `[RabbitMqTransport](establishChannels) Publisher channel closed while the transport was being set up | transport=${this.name}`,\n );\n }\n this.#live = { connection, publisher };\n });\n }\n\n async #startConsuming(connection: AmqpConnection, subscription: Subscription): Promise<void> {\n const channel = await connection.createChannel();\n await assertConsumerTopology(channel, subscription.topology);\n await subscription.consumer.attach(channel);\n }\n\n #forgetConnection(): void {\n this.#live = undefined;\n this.#subscription?.consumer.detach();\n }\n\n #toPublishError(error: unknown, eventId: string, destination: string): Error {\n const { message } = toErrorInfo(error);\n const detail = `transport=${this.name} eventId=${eventId} destination=${destination} error=${message}`;\n return message === NACK_MESSAGE\n ? new RabbitMqPublishRejectedError(\n `[RabbitMqTransport](publish) Broker nacked the message | ${detail}`,\n { cause: error },\n )\n : new RabbitMqUnavailableError(`[RabbitMqTransport](publish) Publish failed | ${detail}`, {\n cause: error,\n });\n }\n}\n\nfunction unroutableKey(messageId: unknown, routingKey: string): string {\n return `${String(messageId)}\\n${routingKey}`;\n}\n\nfunction recordUnroutable(unroutable: Map<string, number>, key: string): void {\n unroutable.set(key, (unroutable.get(key) ?? 0) + 1);\n}\n\nfunction takeUnroutable(unroutable: Map<string, number>, key: string): boolean {\n const count = unroutable.get(key);\n if (count === undefined) {\n return false;\n }\n if (count === 1) {\n unroutable.delete(key);\n } else {\n unroutable.set(key, count - 1);\n }\n return true;\n}\n"]}
1
+ {"version":3,"sources":["../src/errors.ts","../src/abortable-sleep.ts","../src/connection-supervisor.ts","../src/json-payload.ts","../src/wire-format.ts","../src/inbound-decoders.ts","../src/codecs.ts","../src/redelivery.ts","../src/options.ts","../src/topology.ts","../src/queue-consumer.ts","../src/serial-queue.ts","../src/rabbitmq-transport.ts"],"names":["MILLISECONDS_PER_SECOND","SPEC_VERSION","parseTime","text","ConfigurationError","toErrorInfo","computeRetryDelay","error","schedule","systemClock"],"mappings":"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","file":"index.js","sourcesContent":["import { NonRetryableError, RelayBusError } from '@relaybus/core';\n\n/**\n * The broker cannot take or confirm a message right now: the transport is not\n * connected, was closed, lost its channel, or the confirm did not arrive in time.\n * Always retryable; the outbox keeps the delivery and tries again.\n */\nexport class RabbitMqUnavailableError extends RelayBusError {\n override name = 'RabbitMqUnavailableError';\n override readonly code: string = 'RELAYBUS_RABBITMQ_UNAVAILABLE';\n}\n\n/** The broker negatively acknowledged a published message. Retryable. */\nexport class RabbitMqPublishRejectedError extends RelayBusError {\n override name = 'RabbitMqPublishRejectedError';\n override readonly code: string = 'RELAYBUS_RABBITMQ_PUBLISH_REJECTED';\n}\n\n/**\n * The broker accepted the message but no queue is bound to its routing key, so\n * it would have been discarded. Retryable: it succeeds once a consumer binds.\n */\nexport class UnroutableMessageError extends RelayBusError {\n override name = 'UnroutableMessageError';\n override readonly code: string = 'RELAYBUS_RABBITMQ_UNROUTABLE_MESSAGE';\n}\n\n/** A received message is not a valid relaybus CloudEvent. It is dead-lettered. */\nexport class MalformedMessageError extends RelayBusError {\n override name = 'MalformedMessageError';\n override readonly code: string = 'RELAYBUS_RABBITMQ_MALFORMED_MESSAGE';\n}\n\n/**\n * The payload of an event cannot be represented as JSON without losing or\n * changing data (`undefined`, functions, symbols, BigInt, NaN, Infinity, Dates,\n * Maps, class instances, cycles). Never retried: the payload will not change.\n */\nexport class UnserializablePayloadError extends NonRetryableError {\n override name = 'UnserializablePayloadError';\n override readonly code: string = 'RELAYBUS_RABBITMQ_UNSERIALIZABLE_PAYLOAD';\n}\n\n/**\n * A value exceeds a protocol limit of AMQP 0-9-1, for example an event id or a\n * routing key longer than the 255 bytes of a short string. Never retried.\n */\nexport class AmqpLimitExceededError extends NonRetryableError {\n override name = 'AmqpLimitExceededError';\n override readonly code: string = 'RELAYBUS_RABBITMQ_AMQP_LIMIT_EXCEEDED';\n}\n\n/**\n * An event the configured codec cannot write: a header name the format\n * reserves, or a type a fixed-type route does not carry. Never retried.\n */\nexport class RabbitMqUnencodableEventError extends NonRetryableError {\n override name = 'RabbitMqUnencodableEventError';\n override readonly code: string = 'RELAYBUS_RABBITMQ_UNENCODABLE_EVENT';\n}\n","import { systemClock } from '@relaybus/core';\nimport { schedule } from '@relaybus/core/internal';\n\n/** Resolves after `milliseconds`, or as soon as `signal` aborts (immediately when it already has). Never rejects. */\nexport function abortableSleep(milliseconds: number, signal: AbortSignal): Promise<void> {\n if (signal.aborted) {\n return Promise.resolve();\n }\n return new Promise((resolve) => {\n const finish = (): void => {\n cancel();\n signal.removeEventListener('abort', finish);\n resolve();\n };\n const cancel = schedule(systemClock, { run: finish, delayMs: milliseconds });\n signal.addEventListener('abort', finish, { once: true });\n });\n}\n","import {\n computeRetryDelay,\n toErrorInfo,\n type RelayBusLogger,\n type RetryPolicy,\n} from '@relaybus/core';\nimport { abortableSleep } from './abortable-sleep.js';\nimport type { AmqpConnection } from './amqp-types.js';\nimport { RabbitMqUnavailableError } from './errors.js';\nimport type { ConnectOptions } from './options.js';\n\nexport interface ConnectionSupervisorSettings {\n readonly connect: (options: ConnectOptions) => Promise<AmqpConnection>;\n /** Backoff between attempts, or undefined to never reconnect. */\n readonly reconnect: RetryPolicy | undefined;\n /** Creates channels and topology on a fresh connection. A rejection discards the connection. */\n readonly onConnected: (connection: AmqpConnection) => Promise<void>;\n /** The connection is gone or was discarded: drop everything that referenced it. */\n readonly onDisconnected: () => void;\n readonly logger: RelayBusLogger;\n readonly random: () => number;\n}\n\n/**\n * Owns the broker connection. amqplib does not reconnect, so after a connection\n * loss this class retries with capped, jittered backoff until `onConnected`\n * succeeds, and `close` stops it. It reports ready only once `onConnected` has\n * finished, so callers never use half-built channels.\n */\nexport class ConnectionSupervisor {\n readonly #settings: ConnectionSupervisorSettings;\n readonly #stop = new AbortController();\n /** Aborted by `forceClose`: destroys a socket that is still connecting. */\n readonly #force = new AbortController();\n /** Resolves on `forceClose`: closing stops waiting for the broker. */\n readonly #forcing = new Promise<void>((resolve) => {\n this.#force.signal.addEventListener('abort', () => resolve(), { once: true });\n });\n #current: AmqpConnection | undefined;\n /** Connections being closed, until their closing handshake finishes. */\n readonly #closing = new Set<AmqpConnection>();\n /** Set by `forceClose`: connections are cut instead of closed. */\n #forced = false;\n #ready = false;\n #started = false;\n #closed = false;\n #reconnecting: Promise<void> | undefined;\n\n constructor(settings: ConnectionSupervisorSettings) {\n this.#settings = settings;\n }\n\n /** True while a connection is open and `onConnected` has completed for it. */\n isConnected(): boolean {\n return this.#ready;\n }\n\n /**\n * Connects once. When that fails it rejects if `failOnError`, otherwise it\n * resolves and keeps trying in the background. Does nothing when already started.\n */\n async start(failOnError: boolean): Promise<void> {\n if (this.#started) {\n return;\n }\n if (this.#closed) {\n throw new RabbitMqUnavailableError('[ConnectionSupervisor](start) Transport is closed');\n }\n try {\n await this.#establish();\n this.#started = true;\n } catch (error) {\n if (failOnError) {\n throw error;\n }\n this.#settings.logger.warn(\n `[ConnectionSupervisor](start) Broker unreachable, retrying in the background | error=${toErrorInfo(error).message}`,\n );\n this.#started = true;\n this.#startReconnecting();\n }\n }\n\n /**\n * Drops the current connection because one of its channels failed, then\n * reconnects. Closing the channel alone would leave topology half-restored.\n */\n recover(reason: string): void {\n const connection = this.#current;\n if (connection === undefined) {\n return;\n }\n this.#handleLoss(connection, reason);\n void this.#closeConnection(connection);\n }\n\n /**\n * Stops reconnecting, runs `beforeDisconnect` while the connection is still\n * open (to drain consumers) and closes the connection.\n */\n async close(beforeDisconnect: () => Promise<void>): Promise<void> {\n this.#closed = true;\n this.#stop.abort();\n // Once forced, nothing waits for the broker: draining and the closing handshake are cut short.\n await Promise.race([this.#reconnecting, this.#forcing]);\n try {\n await Promise.race([beforeDisconnect(), this.#forcing]);\n } finally {\n const connection = this.#current;\n this.#current = undefined;\n this.#ready = false;\n if (connection !== undefined) {\n await this.#closeConnection(connection);\n }\n }\n }\n\n /**\n * Stops reconnecting and cuts every connection, open or closing, without the closing handshake. A\n * connection that finishes opening afterwards is cut at once.\n */\n forceClose(): void {\n this.#closed = true;\n this.#forced = true;\n this.#stop.abort();\n this.#force.abort();\n for (const connection of [this.#current, ...this.#closing]) {\n if (connection !== undefined) {\n destroySocket(connection);\n }\n }\n }\n\n /** Closes a connection, which `forceClose` can cut until the broker answered; cuts it once forced. */\n async #closeConnection(connection: AmqpConnection): Promise<void> {\n if (this.#forced) {\n destroySocket(connection);\n return;\n }\n this.#closing.add(connection);\n await connection.close().catch(() => undefined);\n this.#closing.delete(connection);\n }\n\n async #establish(): Promise<void> {\n const connection = await this.#settings.connect({ signal: this.#force.signal });\n // Before anything can cut it: an 'error' nobody listens to would crash the process.\n connection.on('error', (error: Error) => {\n this.#settings.logger.warn(\n `[ConnectionSupervisor](establish) Connection error | error=${error.message}`,\n );\n });\n if (this.#closed) {\n // Opened after the transport closed: nobody would use or close it.\n await this.#closeConnection(connection);\n throw new RabbitMqUnavailableError('[ConnectionSupervisor](establish) Transport is closed');\n }\n connection.on('close', (error?: Error) => {\n this.#handleLoss(connection, error?.message ?? 'closed by peer');\n });\n this.#current = connection;\n try {\n await this.#settings.onConnected(connection);\n if (this.#current !== connection) {\n throw new RabbitMqUnavailableError(\n 'Connection was lost while the topology was being set up',\n );\n }\n } catch (error) {\n await this.#discard(connection);\n throw error;\n }\n this.#ready = true;\n }\n\n async #discard(connection: AmqpConnection): Promise<void> {\n if (this.#current === connection) {\n this.#current = undefined;\n }\n this.#settings.onDisconnected();\n await this.#closeConnection(connection);\n }\n\n #handleLoss(connection: AmqpConnection, reason: string): void {\n if (connection !== this.#current) {\n return;\n }\n this.#current = undefined;\n this.#ready = false;\n this.#settings.logger.warn(\n `[ConnectionSupervisor](handleLoss) Connection lost | reason=${reason}`,\n );\n this.#settings.onDisconnected();\n this.#startReconnecting();\n }\n\n #startReconnecting(): void {\n if (\n this.#settings.reconnect === undefined ||\n this.#closed ||\n !this.#started ||\n this.#reconnecting !== undefined\n ) {\n return;\n }\n const policy = this.#settings.reconnect;\n this.#reconnecting = this.#reconnectUntilConnected(policy).finally(() => {\n this.#reconnecting = undefined;\n });\n }\n\n async #reconnectUntilConnected(policy: RetryPolicy): Promise<void> {\n for (let attempt = 1; !this.#closed; attempt += 1) {\n const delayMs = computeRetryDelay(policy, attempt, this.#settings.random);\n this.#settings.logger.log(\n `[ConnectionSupervisor](reconnectUntilConnected) Reconnecting | attempt=${attempt} delayMs=${delayMs}`,\n );\n await abortableSleep(delayMs, this.#stop.signal);\n if (this.#closed) {\n return;\n }\n try {\n await this.#establish();\n this.#settings.logger.log(\n `[ConnectionSupervisor](reconnectUntilConnected) Reconnected | attempt=${attempt}`,\n );\n return;\n } catch (error) {\n this.#settings.logger.warn(\n `[ConnectionSupervisor](reconnectUntilConnected) Attempt failed | attempt=${attempt} error=${toErrorInfo(error).message}`,\n );\n }\n }\n }\n}\n\n/**\n * Destroys the socket under an amqplib connection (the channel model keeps it in fields its types\n * omit). With an error, so amqplib sees a socket error and runs its terminal cleanup: it stops\n * heartbeating, fails pending channel operations and emits `close`.\n */\nfunction destroySocket(connection: AmqpConnection): void {\n const model = connection as {\n readonly connection?: { readonly stream?: { destroy(error: Error): void } };\n };\n model.connection?.stream?.destroy(\n new RabbitMqUnavailableError('Connection cut: the shutdown deadline passed'),\n );\n}\n","import { UnserializablePayloadError } from './errors.js';\n\n/**\n * Throws {@link UnserializablePayloadError} unless `JSON.stringify` represents\n * `payload` faithfully. Only `null`, strings, booleans, finite numbers, arrays\n * and plain objects built from those are accepted. Everything `JSON.stringify`\n * would silently drop (`undefined`, functions, symbols, symbol keys, array holes),\n * convert (NaN and Infinity to `null`, Dates to strings, Maps and Sets to `{}`,\n * class instances to their own properties) or reject late (BigInt, cycles) is\n * refused up front, naming the offending path.\n */\nexport function assertJsonPayload(payload: unknown, eventId: string): void {\n visit(payload, { path: '$', ancestors: new Set(), eventId });\n}\n\nfunction visit(\n value: unknown,\n {\n path,\n ancestors,\n eventId,\n }: { readonly path: string; readonly ancestors: Set<object>; readonly eventId: string },\n): void {\n switch (typeof value) {\n case 'string':\n case 'boolean':\n return;\n case 'number':\n if (!Number.isFinite(value)) {\n throw refuse(eventId, { path, reason: `is ${value}, which JSON turns into null` });\n }\n return;\n case 'object':\n if (value !== null) {\n visitObject(value, { path, ancestors, eventId });\n }\n return;\n default:\n throw refuse(eventId, { path, reason: `is ${typeof value}, which JSON cannot represent` });\n }\n}\n\nfunction visitObject(\n value: object,\n {\n path,\n ancestors,\n eventId,\n }: { readonly path: string; readonly ancestors: Set<object>; readonly eventId: string },\n): void {\n if (ancestors.has(value)) {\n throw refuse(eventId, { path, reason: 'is a circular reference' });\n }\n ancestors.add(value);\n if (Array.isArray(value)) {\n for (let index = 0; index < value.length; index += 1) {\n if (!(index in value)) {\n throw refuse(eventId, {\n path: `${path}[${index}]`,\n reason: 'is an array hole, which JSON turns into null',\n });\n }\n visit(value[index], { path: `${path}[${index}]`, ancestors, eventId });\n }\n } else {\n const prototype = Object.getPrototypeOf(value) as object | null;\n if (prototype !== Object.prototype && prototype !== null) {\n throw refuse(eventId, {\n path,\n reason: 'is not a plain object (class instance, Date, Map or Set)',\n });\n }\n if (Object.getOwnPropertySymbols(value).length > 0) {\n throw refuse(eventId, { path, reason: 'has a symbol key, which JSON drops' });\n }\n for (const key of Object.keys(value)) {\n visit((value as Record<string, unknown>)[key], {\n path: `${path}.${key}`,\n ancestors,\n eventId,\n });\n }\n }\n ancestors.delete(value);\n}\n\nfunction refuse(\n eventId: string,\n { path, reason }: { readonly path: string; readonly reason: string },\n): UnserializablePayloadError {\n return new UnserializablePayloadError(\n `Event ${eventId} has a payload JSON cannot represent faithfully: ${path} ${reason}`,\n );\n}\n","import type { EventEnvelope, EventHeaders } from '@relaybus/core';\nimport { writeStructuredCloudEvent } from '@relaybus/core/internal';\nimport type { AmqpMessage, AmqpPublishOptions } from './amqp-types.js';\nimport {\n AmqpLimitExceededError,\n MalformedMessageError,\n RabbitMqUnencodableEventError,\n} from './errors.js';\nimport { assertJsonPayload } from './json-payload.js';\n\n/** AMQP `timestamp` properties count seconds. */\nconst MILLISECONDS_PER_SECOND = 1_000;\n\n/**\n * Wire format: CloudEvents 1.0 in binary content mode, following the CloudEvents\n * AMQP protocol binding adapted to RabbitMQ's AMQP 0-9-1.\n *\n * - Body: the JSON-encoded payload (`contentType` `application/json`).\n * - Headers `cloudEvents:specversion`, `cloudEvents:id`, `cloudEvents:type`,\n * `cloudEvents:source`, `cloudEvents:time` (RFC 3339, millisecond precision),\n * `cloudEvents:datacontenttype`, and when present `cloudEvents:subject` (the\n * key) and the extension attributes `cloudEvents:causationid` and\n * `cloudEvents:correlationid`.\n * - AMQP properties mirror the same values for broker tooling: `messageId`,\n * `type`, `appId` (source), `correlationId`, `timestamp` (seconds), plus\n * `deliveryMode` 2 (persistent).\n * - Event headers travel as `relaybus:<name>` message headers, so they cannot\n * collide with CloudEvents attributes or broker headers such as `x-death`.\n *\n * On receive the `cloudEvents:` headers win; the AMQP properties are the\n * fallback for events produced by other CloudEvents libraries (the AMQP\n * timestamp only when `cloudEvents:time` is absent; a present but malformed\n * time is rejected).\n *\n * AMQP 0-9-1 short strings (message properties, header names, routing keys) are\n * limited to 255 bytes. The event id, a header name or a routing key beyond\n * that is refused with {@link AmqpLimitExceededError}, because the event could\n * never be published. The `type`, `appId` and `correlationId` mirrors are\n * skipped when they do not fit; the `cloudEvents:` headers always carry them.\n */\nconst ATTRIBUTE_PREFIX = 'cloudEvents:';\nconst EVENT_HEADER_PREFIX = 'relaybus:';\nconst SPEC_VERSION = '1.0';\nconst JSON_CONTENT_TYPE = 'application/json';\nconst STRUCTURED_CONTENT_TYPE = 'application/cloudevents+json';\n/** Header name prefixes the broker or the transport own; an event header there would be lost on read. */\nconst RESERVED_HEADER_PREFIXES = ['x-death', 'x-first-death-', 'x-last-death-', 'x-relaybus-'];\nconst SHORT_STRING_LIMIT_BYTES = 255;\n/** RFC 3339 date-time, the format of the CloudEvents `time` attribute. */\nexport const RFC3339_PATTERN =\n /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?(?:Z|[+-]\\d{2}:\\d{2})$/i;\n\n/** A serialized event, ready for `channel.publish`. */\nexport interface EncodedMessage {\n readonly content: Buffer;\n readonly options: AmqpPublishOptions;\n}\n\n/**\n * Serializes an envelope.\n *\n * @throws {UnserializablePayloadError} the payload is not representable as JSON\n * @throws {AmqpLimitExceededError} the id or a header name exceeds 255 bytes\n */\nexport function encodeEnvelope(envelope: EventEnvelope): EncodedMessage {\n assertJsonPayload(envelope.payload, envelope.id);\n assertShortString('Event id', envelope.id);\n const headers: Record<string, string> = {\n [`${ATTRIBUTE_PREFIX}specversion`]: SPEC_VERSION,\n [`${ATTRIBUTE_PREFIX}id`]: envelope.id,\n [`${ATTRIBUTE_PREFIX}type`]: envelope.type,\n [`${ATTRIBUTE_PREFIX}source`]: envelope.source,\n [`${ATTRIBUTE_PREFIX}time`]: envelope.occurredAt.toISOString(),\n [`${ATTRIBUTE_PREFIX}datacontenttype`]: JSON_CONTENT_TYPE,\n };\n if (envelope.key !== null) {\n headers[`${ATTRIBUTE_PREFIX}subject`] = envelope.key;\n }\n if (envelope.causationId !== null) {\n headers[`${ATTRIBUTE_PREFIX}causationid`] = envelope.causationId;\n }\n if (envelope.correlationId !== null) {\n headers[`${ATTRIBUTE_PREFIX}correlationid`] = envelope.correlationId;\n }\n for (const [name, value] of Object.entries(envelope.headers)) {\n assertShortString(\n `Header name '${EVENT_HEADER_PREFIX}${name}'`,\n `${EVENT_HEADER_PREFIX}${name}`,\n );\n headers[`${EVENT_HEADER_PREFIX}${name}`] = value;\n }\n return {\n content: Buffer.from(JSON.stringify(envelope.payload), 'utf8'),\n options: {\n contentType: JSON_CONTENT_TYPE,\n persistent: true,\n messageId: envelope.id,\n timestamp: Math.floor(envelope.occurredAt.getTime() / MILLISECONDS_PER_SECOND),\n ...mirror('type', envelope.type),\n ...mirror('appId', envelope.source),\n ...(envelope.correlationId === null ? {} : mirror('correlationId', envelope.correlationId)),\n headers,\n },\n };\n}\n\n/**\n * Serializes an envelope in CloudEvents structured content mode: the body is\n * one `application/cloudevents+json` document with the attributes and `data`.\n * The AMQP properties are those of binary mode; event headers travel as\n * message headers under their own names, as structured-mode readers expect.\n *\n * @throws {UnserializablePayloadError} the payload is not representable as JSON\n * @throws {AmqpLimitExceededError} the id or a header name exceeds 255 bytes\n * @throws {RabbitMqUnencodableEventError} a header name the broker or the transport reserves\n */\nexport function encodeStructuredEnvelope(envelope: EventEnvelope): EncodedMessage {\n assertJsonPayload(envelope.payload, envelope.id);\n assertShortString('Event id', envelope.id);\n const document = writeStructuredCloudEvent(envelope, {\n time: envelope.occurredAt.toISOString(),\n data: JSON.stringify(envelope.payload),\n });\n return {\n content: Buffer.from(document, 'utf8'),\n options: {\n ...messageProperties(envelope),\n contentType: STRUCTURED_CONTENT_TYPE,\n headers: plainHeaders(envelope, envelope.headers),\n },\n };\n}\n\n/** The AMQP properties every relaybus format writes; `contentType` and `headers` are the format's own. */\nexport function messageProperties(\n envelope: EventEnvelope,\n): Omit<AmqpPublishOptions, 'headers' | 'contentType'> {\n return {\n persistent: true,\n messageId: envelope.id,\n timestamp: Math.floor(envelope.occurredAt.getTime() / MILLISECONDS_PER_SECOND),\n ...mirror('type', envelope.type),\n ...mirror('appId', envelope.source),\n ...(envelope.correlationId === null ? {} : mirror('correlationId', envelope.correlationId)),\n };\n}\n\n/**\n * Message headers under their own names, for formats read by other services.\n * A name the broker or the transport reserves is refused, because the reader\n * would drop it; a name beyond 255 bytes is refused by AMQP.\n */\nexport function plainHeaders(\n envelope: EventEnvelope,\n headers: EventHeaders,\n): Record<string, string> {\n for (const name of Object.keys(headers)) {\n if (RESERVED_HEADER_PREFIXES.some((prefix) => name.startsWith(prefix))) {\n throw new RabbitMqUnencodableEventError(\n `Event ${envelope.id} has a header '${name}', a name the broker or the transport reserves`,\n );\n }\n assertShortString(`Header name '${name}'`, name);\n }\n return Object.fromEntries(Object.entries(headers));\n}\n\n/**\n * Throws {@link AmqpLimitExceededError} when `value` does not fit an AMQP short\n * string (255 bytes of UTF-8), which amqplib would otherwise reject on every\n * attempt.\n */\nexport function assertShortString(label: string, value: string): void {\n const bytes = Buffer.byteLength(value, 'utf8');\n if (bytes > SHORT_STRING_LIMIT_BYTES) {\n throw new AmqpLimitExceededError(\n `${label} is ${bytes} bytes, above the AMQP limit of ${SHORT_STRING_LIMIT_BYTES} bytes`,\n );\n }\n}\n\nfunction mirror<TName extends 'type' | 'appId' | 'correlationId'>(\n name: TName,\n value: string,\n): { [Name in TName]?: string } {\n return Buffer.byteLength(value, 'utf8') > SHORT_STRING_LIMIT_BYTES\n ? {}\n : ({ [name]: value } as { [Name in TName]?: string });\n}\n\n/** Rebuilds an envelope. Throws {@link MalformedMessageError} when the message is not a relaybus event. */\nexport function decodeEnvelope(message: AmqpMessage): EventEnvelope {\n const { properties } = message;\n const attributes = properties.headers ?? {};\n if (attributes[`${ATTRIBUTE_PREFIX}specversion`] !== SPEC_VERSION) {\n throw new MalformedMessageError(\n `Message is not a CloudEvents ${SPEC_VERSION} event (header ${ATTRIBUTE_PREFIX}specversion)`,\n );\n }\n return {\n id: required('id', text(attributes[`${ATTRIBUTE_PREFIX}id`]) ?? text(properties.messageId)),\n type: required('type', text(attributes[`${ATTRIBUTE_PREFIX}type`]) ?? text(properties.type)),\n source: required(\n 'source',\n text(attributes[`${ATTRIBUTE_PREFIX}source`]) ?? text(properties.appId),\n ),\n key: text(attributes[`${ATTRIBUTE_PREFIX}subject`]) ?? null,\n payload: parsePayload(message.content),\n headers: extractEventHeaders(attributes),\n correlationId:\n text(attributes[`${ATTRIBUTE_PREFIX}correlationid`]) ??\n text(properties.correlationId) ??\n null,\n causationId: text(attributes[`${ATTRIBUTE_PREFIX}causationid`]) ?? null,\n occurredAt: parseTime(attributes[`${ATTRIBUTE_PREFIX}time`], properties.timestamp),\n };\n}\n\nfunction extractEventHeaders(attributes: Readonly<Record<string, unknown>>): EventHeaders {\n const headers: Record<string, string> = {};\n for (const [name, value] of Object.entries(attributes)) {\n if (name.startsWith(EVENT_HEADER_PREFIX) && typeof value === 'string') {\n // defineProperty, because assigning `__proto__` would set the prototype and lose the header.\n Object.defineProperty(headers, name.slice(EVENT_HEADER_PREFIX.length), {\n value,\n enumerable: true,\n writable: true,\n configurable: true,\n });\n }\n }\n return headers;\n}\n\nfunction parsePayload(content: Buffer): unknown {\n try {\n return JSON.parse(content.toString('utf8')) as unknown;\n } catch {\n throw new MalformedMessageError('Message body is not valid JSON');\n }\n}\n\nfunction parseTime(rawTime: unknown, timestampSeconds: unknown): Date {\n if (rawTime === undefined) {\n const fallback =\n typeof timestampSeconds === 'number'\n ? new Date(timestampSeconds * MILLISECONDS_PER_SECOND)\n : undefined;\n if (fallback === undefined || Number.isNaN(fallback.getTime())) {\n throw new MalformedMessageError('Message has no valid time (header cloudEvents:time)');\n }\n return fallback;\n }\n const occurredAt =\n typeof rawTime === 'string' && RFC3339_PATTERN.test(rawTime) ? new Date(rawTime) : undefined;\n if (occurredAt === undefined || Number.isNaN(occurredAt.getTime())) {\n throw new MalformedMessageError(\n 'Message time (header cloudEvents:time) is not an RFC 3339 timestamp',\n );\n }\n return occurredAt;\n}\n\nfunction text(value: unknown): string | undefined {\n return typeof value === 'string' ? value : undefined;\n}\n\nfunction required(attribute: string, value: string | undefined): string {\n if (value === undefined || value.length === 0) {\n throw new MalformedMessageError(\n `Message has no ${attribute} (header ${ATTRIBUTE_PREFIX}${attribute})`,\n );\n }\n return value;\n}\n","import { assertEventType, type EventEnvelope, type EventHeaders } from '@relaybus/core';\nimport { createCloudEventReaders, isJsonObject, mediaTypeOf } from '@relaybus/core/internal';\nimport type { AmqpMessage, AmqpMessageProperties } from './amqp-types.js';\nimport { MalformedMessageError } from './errors.js';\nimport { RFC3339_PATTERN, decodeEnvelope } from './wire-format.js';\n\n/** AMQP `timestamp` properties count seconds. */\nconst MILLISECONDS_PER_SECOND = 1_000;\n\nconst { optionalAttribute, requiredAttribute, assertValidType, assertJsonDataContentType } =\n createCloudEventReaders((reason) => new MalformedMessageError(reason));\n\n/**\n * The event a decoder extracted from a message. `id`, `type` and `payload` are\n * required; every other field may be left out and is then filled by the\n * transport: `source` with the `appId` property (else the routing key), `key`\n * with null, `headers` with none, `correlationId` and `causationId` with null,\n * and `occurredAt` with the `timestamp` property (else the time of receipt).\n */\nexport interface DecodedEvent {\n readonly id: string;\n readonly type: string;\n readonly payload: unknown;\n readonly source?: string;\n readonly key?: string | null;\n readonly headers?: EventHeaders;\n readonly correlationId?: string | null;\n readonly causationId?: string | null;\n readonly occurredAt?: Date;\n}\n\n/**\n * Turns a consumed message into an event, for queues fed by producers that do\n * not use relaybus. Must be synchronous and free of side effects: it runs again\n * on every redelivery, so the same message must always give the same event,\n * above all the same `id`, which is what the inbox deduplicates on.\n *\n * Anything it throws marks the message as malformed: it is dead-lettered and\n * the consumer moves on. An event the bus then rejects (empty id, invalid type\n * or time) is dead-lettered the same way.\n */\nexport type RabbitMqMessageDecoder = (message: AmqpMessage) => DecodedEvent;\n\n/** A plain JSON message, decoded for the extractor options of {@link plainJsonDecoder}. */\nexport interface PlainJsonMessage {\n readonly routingKey: string;\n /** The AMQP properties as delivered (`messageId`, `type`, `appId`, `timestamp`, ...). */\n readonly properties: AmqpMessageProperties;\n /**\n * The message headers with string values, without the broker's and the\n * transport's own (`x-death`, `x-first-death-*`, `x-last-death-*`, `x-relaybus-*`).\n */\n readonly headers: EventHeaders;\n /** The body parsed as JSON. */\n readonly payload: unknown;\n}\n\n/** Options of {@link plainJsonDecoder}. Extractors returning undefined or `''` select the default. */\nexport interface PlainJsonDecoderOptions {\n /**\n * Event type handlers subscribe to: a fixed name for a queue that carries one\n * kind of event, or an extractor such as `fromHeader('event-type')`,\n * `fromPayloadField('type')` or `(message) => message.properties.type`.\n * Required; a message without a type is malformed.\n */\n readonly type: string | ((message: PlainJsonMessage) => string | undefined);\n /**\n * Event id the inbox deduplicates on. Default, and fallback when the\n * extractor finds none: the `messageId` property, which survives\n * redeliveries. A message with neither is malformed, because AMQP has no\n * other identity that is stable across redeliveries; give producers a\n * `messageId` (Spring AMQP can generate one with `setCreateMessageIds(true)`).\n */\n readonly id?: (message: PlainJsonMessage) => string | undefined;\n /** Ordering key. Default: none. */\n readonly key?: (message: PlainJsonMessage) => string | null | undefined;\n /** Logical name of the producer. Default: the `appId` property, else the routing key. */\n readonly source?: string | ((message: PlainJsonMessage) => string | undefined);\n /** When the event happened. Default: the `timestamp` property, else the time of receipt. */\n readonly occurredAt?: (message: PlainJsonMessage) => Date | undefined;\n}\n\nconst STRUCTURED_MEDIA_TYPE = 'application/cloudevents+json';\nconst strictUtf8 = new TextDecoder('utf-8', { fatal: true });\nconst SPEC_VERSION = '1.0';\nconst SPEC_VERSION_HEADER = 'cloudEvents:specversion';\n/** Headers the broker or this transport add on their own; never event headers. */\nconst INTERNAL_HEADER_PREFIXES = ['x-relaybus-', 'x-first-death-', 'x-last-death-'];\n/** Attributes of a structured event that map to envelope fields rather than headers. */\nconst STRUCTURED_ATTRIBUTES: ReadonlySet<string> = new Set([\n 'specversion',\n 'id',\n 'type',\n 'source',\n 'time',\n 'subject',\n 'datacontenttype',\n 'dataschema',\n 'data',\n 'data_base64',\n 'correlationid',\n 'causationid',\n]);\n\n/**\n * Decodes a CloudEvents 1.0 message in either content mode:\n * - structured (`contentType` property `application/cloudevents+json`): the\n * body is a JSON object with `specversion`, `id`, `type`, `source` and\n * optionally `time` (else the `timestamp` property, else the time of\n * receipt), `subject` (the key), `data` (the payload, null when absent) and\n * a JSON `datacontenttype`. `data_base64` is refused, because relaybus\n * payloads are JSON. Extension attributes with string values (`traceparent`,\n * ...) become event headers, as do the string message headers;\n * `correlationid` and `causationid` fill their envelope fields.\n * - binary (anything else): exactly the default decoder, `cloudEvents:*`\n * headers with the AMQP properties as fallback.\n *\n * @throws MalformedMessageError for a message that is neither.\n */\nexport function decodeCloudEvent(message: AmqpMessage): EventEnvelope {\n if (mediaTypeOf(message.properties.contentType) !== STRUCTURED_MEDIA_TYPE) {\n return decodeEnvelope(message);\n }\n const body = parseJsonBody(message.content);\n if (!isJsonObject(body)) {\n throw new MalformedMessageError('A structured CloudEvent must be a JSON object');\n }\n if (body['specversion'] !== SPEC_VERSION) {\n throw new MalformedMessageError(`specversion must be '${SPEC_VERSION}'`);\n }\n const type = requiredAttribute(body, 'type');\n assertValidType(type, 'type');\n assertJsonDataContentType(optionalAttribute(body, 'datacontenttype'));\n if (Object.hasOwn(body, 'data_base64')) {\n throw new MalformedMessageError(\n 'data_base64 is not supported: relaybus payloads are JSON, send them as data',\n );\n }\n const time = optionalAttribute(body, 'time');\n return {\n id: requiredAttribute(body, 'id'),\n type,\n source: requiredAttribute(body, 'source'),\n key: optionalAttribute(body, 'subject') ?? null,\n payload: Object.hasOwn(body, 'data') ? body['data'] : null,\n headers: { ...readForeignHeaders(message.properties), ...extensionAttributes(body) },\n correlationId: optionalAttribute(body, 'correlationid') ?? null,\n causationId: optionalAttribute(body, 'causationid') ?? null,\n occurredAt: time === undefined ? propertyTimeOrNow(message.properties) : parseTime(time),\n };\n}\n\n/**\n * Creates a decoder for messages whose body is plain JSON, as published by a\n * service that does not use relaybus (plain amqplib, Spring AMQP's\n * `Jackson2JsonMessageConverter`, a Go or Python service): the body becomes the\n * payload, the string headers become event headers, and the options say where\n * the event type and id come from.\n *\n * A message that is a CloudEvent anyway (a `cloudEvents:specversion` header,\n * or a structured `application/cloudevents+json` body) is decoded with\n * {@link decodeCloudEvent} instead, so relaybus and foreign producers can feed\n * one queue. A body that is not JSON, a missing or invalid type, a missing id\n * and an extractor returning anything but a string are malformed.\n *\n * ```ts\n * new RabbitMqTransport({\n * url,\n * consumerGroup: 'billing',\n * decode: plainJsonDecoder({ type: (message) => message.properties.type as string }),\n * });\n * ```\n *\n * @throws ConfigurationError when a fixed `type` is not a valid event type.\n */\nexport function plainJsonDecoder(options: PlainJsonDecoderOptions): RabbitMqMessageDecoder {\n if (typeof options.type === 'string') {\n assertEventType(options.type);\n }\n return (message) => {\n const { properties } = message;\n if (\n properties.headers?.[SPEC_VERSION_HEADER] !== undefined ||\n mediaTypeOf(properties.contentType) === STRUCTURED_MEDIA_TYPE\n ) {\n return decodeCloudEvent(message);\n }\n const plain: PlainJsonMessage = {\n routingKey: message.fields.routingKey,\n properties,\n headers: readForeignHeaders(properties),\n payload: parseJsonBody(message.content),\n };\n const type = resolveText(options.type, { message: plain, name: 'type' });\n if (type === undefined) {\n throw new MalformedMessageError('Message has no event type: the type option found none');\n }\n assertValidType(type, 'The event type');\n const id =\n resolveText(options.id, { message: plain, name: 'id' }) ?? nonEmptyText(properties.messageId);\n if (id === undefined) {\n throw new MalformedMessageError(\n 'Message has no id: set the messageId property on the producer or configure the id option',\n );\n }\n return {\n id,\n type,\n source:\n resolveText(options.source, { message: plain, name: 'source' }) ?? defaultSource(message),\n key: resolveText(options.key, { message: plain, name: 'key' }) ?? null,\n payload: plain.payload,\n headers: plain.headers,\n correlationId: null,\n causationId: null,\n occurredAt: resolveOccurredAt(options.occurredAt, plain),\n };\n };\n}\n\n/**\n * Fills the fields a decoder left out (see {@link DecodedEvent}) and guards\n * against a decoder that returned no object.\n */\nexport function completeDecodedEvent(decoded: unknown, message: AmqpMessage): EventEnvelope {\n if (typeof decoded !== 'object' || decoded === null) {\n throw new MalformedMessageError('The decoder must return an event object synchronously');\n }\n if ('then' in decoded) {\n observeRejection(decoded);\n throw new MalformedMessageError('The decoder must return an event object synchronously');\n }\n const event = decoded as DecodedEvent;\n return {\n id: event.id,\n type: event.type,\n source: event.source ?? defaultSource(message),\n key: event.key ?? null,\n payload: event.payload,\n headers: event.headers ?? {},\n correlationId: event.correlationId ?? null,\n causationId: event.causationId ?? null,\n occurredAt: event.occurredAt ?? propertyTimeOrNow(message.properties),\n };\n}\n\n/** Parses the body as UTF-8 JSON, refusing invalid UTF-8 instead of replacing it. */\nexport function parseJsonBody(content: Buffer): unknown {\n let text: string;\n try {\n text = strictUtf8.decode(content);\n } catch {\n throw new MalformedMessageError('Message body is not valid UTF-8');\n }\n try {\n return JSON.parse(text) as unknown;\n } catch {\n throw new MalformedMessageError('Message body is not valid JSON');\n }\n}\n\nexport function nonEmptyText(value: unknown): string | undefined {\n return typeof value === 'string' && value.length > 0 ? value : undefined;\n}\n\nfunction defaultSource(message: AmqpMessage): string {\n return nonEmptyText(message.properties.appId) ?? message.fields.routingKey;\n}\n\nfunction parseTime(text: string): Date {\n const time = new Date(text);\n if (!RFC3339_PATTERN.test(text) || Number.isNaN(time.getTime())) {\n throw new MalformedMessageError(`time is not an RFC 3339 timestamp: '${text}'`);\n }\n return time;\n}\n\n/** The `timestamp` property (seconds), else the time of receipt. */\nfunction propertyTimeOrNow(properties: AmqpMessageProperties): Date {\n const { timestamp } = properties;\n return typeof timestamp === 'number' && Number.isFinite(timestamp)\n ? new Date(timestamp * MILLISECONDS_PER_SECOND)\n : new Date();\n}\n\nfunction extensionAttributes(body: Record<string, unknown>): Record<string, string> {\n return Object.fromEntries(\n Object.entries(body).filter(\n (entry): entry is [string, string] =>\n !STRUCTURED_ATTRIBUTES.has(entry[0]) && typeof entry[1] === 'string',\n ),\n );\n}\n\nexport function readForeignHeaders(properties: AmqpMessageProperties): Record<string, string> {\n return Object.fromEntries(\n Object.entries(properties.headers ?? {}).filter(\n (entry): entry is [string, string] =>\n typeof entry[1] === 'string' &&\n !INTERNAL_HEADER_PREFIXES.some((prefix) => entry[0].startsWith(prefix)),\n ),\n );\n}\n\nfunction resolveText<TValue extends string | null>(\n option: TValue | ((message: PlainJsonMessage) => TValue | undefined) | undefined,\n { message, name }: { readonly message: PlainJsonMessage; readonly name: string },\n): string | undefined {\n const value: unknown = typeof option === 'function' ? option(message) : option;\n if (value === undefined || value === null) {\n return undefined;\n }\n if (typeof value !== 'string') {\n observeRejection(value);\n throw new MalformedMessageError(\n `The ${name} option returned ${typeof value}, expected a string`,\n );\n }\n return value.length === 0 ? undefined : value;\n}\n\nfunction resolveOccurredAt(\n option: PlainJsonDecoderOptions['occurredAt'],\n message: PlainJsonMessage,\n): Date {\n const value: unknown = option?.(message);\n if (value === undefined) {\n return propertyTimeOrNow(message.properties);\n }\n if (!(value instanceof Date) || Number.isNaN(value.getTime())) {\n observeRejection(value);\n throw new MalformedMessageError('The occurredAt option returned no valid Date');\n }\n return value;\n}\n\n/**\n * Observes the rejection of a promise an async decoder or extractor returned by\n * mistake: the value is refused as malformed, and an unobserved rejection would\n * otherwise crash the process.\n */\nfunction observeRejection(value: unknown): void {\n if (typeof value === 'object' && value !== null && 'then' in value) {\n Promise.resolve(value).catch(() => undefined);\n }\n}\n","import type { EventEnvelope } from '@relaybus/core';\nimport { createJsonEnvelopeFormat, type JsonEnvelopeMapping } from '@relaybus/core/internal';\nimport type { AmqpMessage } from './amqp-types.js';\nimport { MalformedMessageError, RabbitMqUnencodableEventError } from './errors.js';\nimport {\n decodeCloudEvent,\n nonEmptyText,\n parseJsonBody,\n readForeignHeaders,\n type RabbitMqMessageDecoder,\n} from './inbound-decoders.js';\nimport { assertJsonPayload } from './json-payload.js';\nimport {\n assertShortString,\n decodeEnvelope,\n encodeEnvelope,\n encodeStructuredEnvelope,\n messageProperties,\n plainHeaders,\n type EncodedMessage,\n} from './wire-format.js';\n\n/**\n * The wire format of a {@link RabbitMqTransport}: how an event becomes a\n * message (`encode`, on publish) and a consumed message becomes an event\n * (`decode`).\n *\n * Both must be synchronous and free of side effects. What `encode` throws\n * fails the publish: the outbox retries it, unless it is a `NonRetryableError`\n * such as {@link RabbitMqUnencodableEventError}. Give every message a\n * `messageId`: the transport matches broker returns of unroutable messages by\n * it. What `decode` throws marks the message as malformed: it is\n * dead-lettered and the consumer moves on. See {@link RabbitMqMessageDecoder}\n * for the decode contract.\n */\nexport interface RabbitMqCodec {\n readonly encode: (envelope: EventEnvelope) => EncodedMessage;\n readonly decode: RabbitMqMessageDecoder;\n}\n\n/**\n * CloudEvents 1.0 binary content mode, the default: the body is the JSON\n * payload, the attributes travel as `cloudEvents:*` headers mirrored in the\n * AMQP properties. Decoding is strict: any other message is malformed.\n */\nexport const cloudEventsBinary: RabbitMqCodec = Object.freeze({\n encode: encodeEnvelope,\n decode: decodeEnvelope,\n});\n\n/**\n * CloudEvents 1.0 structured content mode: the body is one\n * `application/cloudevents+json` document with the attributes and `data`.\n * Decoding accepts structured and binary mode ({@link decodeCloudEvent}).\n * Event headers travel under their own names; names starting with `x-death`,\n * `x-first-death-`, `x-last-death-` or `x-relaybus-` are refused.\n */\nexport const cloudEventsStructured: RabbitMqCodec = Object.freeze({\n encode: encodeStructuredEnvelope,\n decode: decodeCloudEvent,\n});\n\n/**\n * Where each value of a JSON message lives, for {@link jsonEnvelope}. Besides\n * `{ body }` and `{ header }`, the id may be `'message-id-property'`: the\n * AMQP `messageId` property, which the codec always writes and which survives\n * redeliveries; a message without one is malformed.\n */\nexport type RabbitMqJsonEnvelopeMapping = JsonEnvelopeMapping<'message-id-property'>;\n\nconst MESSAGE_ID_PROPERTY = 'message-id-property';\nconst DEFAULT_CONTENT_TYPE = 'application/json';\n\n/**\n * A JSON wire format declared by a mapping, in both directions: for queues\n * shared with services that wrap events in their own envelope\n * (`{ \"eventName\": ..., \"data\": {...} }`, MassTransit) or send the bare\n * payload. Every message also gets the AMQP properties of binary mode:\n * `messageId` (the event id), `type`, `appId` (the source), `correlationId`,\n * `timestamp` (seconds) and `persistent`. Event\n * headers that are message headers are written as they are, so a name the\n * mapping uses for another field, or one the broker reserves, is refused\n * with {@link RabbitMqUnencodableEventError}.\n *\n * ```ts\n * codec: jsonEnvelope({\n * type: { body: 'eventName' },\n * id: 'message-id-property',\n * payload: { body: 'data' },\n * })\n * ```\n *\n * @throws ConfigurationError for an incomplete or self-overlapping mapping.\n */\nexport function jsonEnvelope(mapping: RabbitMqJsonEnvelopeMapping): RabbitMqCodec {\n const format = createJsonEnvelopeFormat(mapping, {\n transportIds: [MESSAGE_ID_PROPERTY],\n failures: {\n invalid: (reason) => new MalformedMessageError(reason),\n unencodable: (reason) => new RabbitMqUnencodableEventError(reason),\n },\n });\n const contentType = mapping.contentType ?? DEFAULT_CONTENT_TYPE;\n return {\n encode: (envelope) => {\n assertJsonPayload(envelope.payload, envelope.id);\n assertShortString('Event id', envelope.id);\n const { body, headers } = format.write(envelope);\n return {\n content: Buffer.from(JSON.stringify(body), 'utf8'),\n options: {\n ...messageProperties(envelope),\n contentType,\n headers: plainHeaders(envelope, headers),\n },\n };\n },\n decode: (message) => {\n const fields = format.read({\n body: parseJsonBody(message.content),\n headers: readForeignHeaders(message.properties),\n });\n return { ...fields, id: fields.id ?? requireMessageId(message) };\n },\n };\n}\n\nfunction requireMessageId(message: AmqpMessage): string {\n const id = nonEmptyText(message.properties.messageId);\n if (id === undefined) {\n throw new MalformedMessageError('Message has no id: the messageId property is missing');\n }\n return id;\n}\n","import { ConfigurationError, type RetryPolicy } from '@relaybus/core';\nimport type { AmqpMessage, AmqpPublishOptions } from './amqp-types.js';\n\n/** Number of delayed redeliveries a message went through. Set on every retry copy. */\nexport const REDELIVERIES_HEADER = 'x-relaybus-redeliveries';\n/** Epoch milliseconds of the first failure that needed a delayed redelivery. */\nexport const FIRST_FAILURE_HEADER = 'x-relaybus-first-failure-at';\n/** Why a message was moved to the dead-letter queue by the consumer. */\nexport const DEAD_LETTER_REASON_HEADER = 'x-relaybus-dead-letter-reason';\n/** Class name of the error that dead-lettered a message, such as `MalformedMessageError`. */\nexport const DEAD_LETTER_ERROR_NAME_HEADER = 'x-relaybus-dead-letter-error-name';\n/** Stable code of that error, such as `RELAYBUS_RABBITMQ_MALFORMED_MESSAGE`; absent for non-relaybus errors. */\nexport const DEAD_LETTER_ERROR_CODE_HEADER = 'x-relaybus-dead-letter-error-code';\n/**\n * The routing key a message was originally published with. Set on retry copies,\n * which travel through the default exchange and return with the queue name as\n * routing key, so decoders still see the original one.\n */\nexport const ORIGINAL_ROUTING_KEY_HEADER = 'x-relaybus-routing-key';\n\nconst RELAYBUS_STATE_HEADERS: readonly string[] = [REDELIVERIES_HEADER, FIRST_FAILURE_HEADER];\n/** Counters the broker stamps on its own redeliveries; they must not travel in a copy. */\nconst BROKER_COUNTER_HEADERS: readonly string[] = ['x-delivery-count', 'x-acquired-count'];\nconst MAXIMUM_LADDER_TIERS = 16;\n\n/**\n * The fixed delays of the retry queues, ascending: the policy's delay grown by\n * its factor until the cap. Each tier is its own queue with a queue-level TTL,\n * so messages in one queue always expire in arrival order; one queue with\n * mixed per-message TTLs would let a long delay hold back shorter ones.\n *\n * @throws {ConfigurationError} the policy has no usable delays or too many tiers\n */\nexport function buildRetryLadder(policy: RetryPolicy): readonly number[] {\n if (policy.initialDelayMs < 1) {\n throw new ConfigurationError('redelivery.initialDelay must be at least 1ms');\n }\n const tiers: number[] = [];\n let delay = policy.initialDelayMs;\n for (;;) {\n const tier = Math.round(Math.min(delay, policy.maxDelayMs));\n tiers.push(tier);\n if (tier >= policy.maxDelayMs || policy.factor === 1) {\n return tiers;\n }\n if (tiers.length === MAXIMUM_LADDER_TIERS) {\n throw new ConfigurationError(\n `redelivery needs more than ${MAXIMUM_LADDER_TIERS} retry queues; raise redelivery.factor or lower redelivery.maxDelay`,\n );\n }\n delay *= policy.factor;\n }\n}\n\n/**\n * Maps a jittered delay onto the ladder. A delay between two tiers goes to the\n * upper one with the probability that keeps the expected delay equal to\n * `delayMs`, so jitter still spreads a cohort of failures across tiers.\n */\nexport function chooseRetryTier(\n ladder: readonly number[],\n { delayMs, random }: { readonly delayMs: number; readonly random: () => number },\n): number {\n const upperIndex = ladder.findIndex((tier) => tier >= delayMs);\n if (upperIndex === -1) {\n return ladder.at(-1)!;\n }\n if (upperIndex === 0) {\n return ladder[0]!;\n }\n const lower = ladder[upperIndex - 1]!;\n const upper = ladder[upperIndex]!;\n return random() < (delayMs - lower) / (upper - lower) ? upper : lower;\n}\n\n/** Reads a non-negative integer that a copy carries as a header (string or number). */\nexport function readCounterHeader(message: AmqpMessage, name: string): number | undefined {\n // A message decoded by a custom decoder (plain JSON, structured mode) may have no headers.\n const value = message.properties.headers?.[name];\n const parsed = typeof value === 'string' && /^\\d+$/.test(value) ? Number(value) : value;\n return typeof parsed === 'number' && Number.isSafeInteger(parsed) && parsed >= 0\n ? parsed\n : undefined;\n}\n\n/**\n * A byte-faithful copy of a received message for publishing to another queue:\n * same body and properties, headers carried over except the broker's delivery\n * counters and relaybus' own redelivery state, then `headerChanges` applied.\n */\nexport function copyForRepublish(\n message: AmqpMessage,\n headerChanges: Readonly<Record<string, string>>,\n): { content: Buffer; options: AmqpPublishOptions } {\n const { properties } = message;\n const headers: Record<string, unknown> = { ...properties.headers };\n for (const name of [\n ...RELAYBUS_STATE_HEADERS,\n DEAD_LETTER_REASON_HEADER,\n DEAD_LETTER_ERROR_NAME_HEADER,\n DEAD_LETTER_ERROR_CODE_HEADER,\n ...BROKER_COUNTER_HEADERS,\n ]) {\n delete headers[name];\n }\n Object.assign(headers, headerChanges);\n return {\n content: message.content,\n options: {\n contentType:\n typeof properties.contentType === 'string' ? properties.contentType : 'application/json',\n persistent: true,\n ...(typeof properties.messageId === 'string' ? { messageId: properties.messageId } : {}),\n ...(typeof properties.type === 'string' ? { type: properties.type } : {}),\n ...(typeof properties.appId === 'string' ? { appId: properties.appId } : {}),\n ...(typeof properties.correlationId === 'string'\n ? { correlationId: properties.correlationId }\n : {}),\n ...(typeof properties.timestamp === 'number' ? { timestamp: properties.timestamp } : {}),\n headers,\n },\n };\n}\n\n/** The routing key the message was published with: the original one for a retry copy. */\nexport function originalRoutingKey(message: AmqpMessage): string {\n const original = message.properties.headers?.[ORIGINAL_ROUTING_KEY_HEADER];\n return typeof original === 'string' ? original : message.fields.routingKey;\n}\n\n/** The message as first published: a retry copy gets its original routing key back. */\nexport function withOriginalRoutingKey(message: AmqpMessage): AmqpMessage {\n const routingKey = originalRoutingKey(message);\n return routingKey === message.fields.routingKey\n ? message\n : { ...message, fields: { ...message.fields, routingKey } };\n}\n","import {\n ConfigurationError,\n createRetryPolicy,\n toMilliseconds,\n type Duration,\n type EventEnvelope,\n type RelayBusLogger,\n type RetryPolicy,\n type RetryPolicyOptions,\n} from '@relaybus/core';\nimport { assertPositiveInteger } from '@relaybus/core/internal';\nimport type { AmqpConnection, AmqpMessage } from './amqp-types.js';\nimport { cloudEventsBinary, type RabbitMqCodec } from './codecs.js';\nimport { completeDecodedEvent, type RabbitMqMessageDecoder } from './inbound-decoders.js';\nimport { buildRetryLadder } from './redelivery.js';\nimport { decodeEnvelope, encodeEnvelope, type EncodedMessage } from './wire-format.js';\n\n/** Connection settings accepted by `amqplib.connect`, given as an object instead of a URL. */\nexport interface BrokerConnectionSettings {\n readonly protocol?: string;\n readonly hostname?: string;\n readonly port?: number;\n readonly username?: string;\n readonly password?: string;\n readonly vhost?: string;\n /** Seconds. See \"Operational notes\" in the README for the heartbeat defaults of each amqplib version. */\n readonly heartbeat?: number;\n}\n\n/** Backoff between reconnect attempts. Attempts are unlimited. */\nexport type ReconnectOptions = Pick<\n RetryPolicyOptions,\n 'initialDelay' | 'factor' | 'maxDelay' | 'jitter'\n>;\n\n/**\n * Delayed redelivery of messages whose handler keeps failing. Each failed\n * delivery goes to a retry queue and returns to the main queue after a growing\n * delay, so an outage of the handler's dependency is waited out instead of\n * burning through delivery attempts.\n */\nexport type RedeliveryOptions = Pick<\n RetryPolicyOptions,\n 'initialDelay' | 'factor' | 'maxDelay' | 'jitter'\n> & {\n /**\n * How long a message may keep failing, counted from its first delayed\n * redelivery, before it is dead-lettered. Default `'1h'`.\n */\n readonly maxAge?: Duration;\n};\n\nexport interface RabbitMqTransportOptions {\n /** Name referenced by routes and subscriptions. Default `'rabbitmq'`. */\n readonly name?: string;\n /**\n * Broker location, for example `amqp://user:pass@host:5672/vhost?heartbeat=30`.\n * Give exactly one of `url` and `connect`.\n */\n readonly url?: string | BrokerConnectionSettings;\n /**\n * Opens one connection. Called again after every connection loss. Use it for\n * TLS options, custom credentials or an alternative amqplib instance. `signal` aborts when a\n * shutdown runs past its deadline: pass it on (`amqplib.connect(url, { signal })`) so a broker\n * that never answers the handshake cannot hold the socket open.\n */\n readonly connect?: (options: ConnectOptions) => Promise<AmqpConnection>;\n /** Topic exchange events are published to. Durable, created when missing. Default `'relaybus'`. */\n readonly exchange?: string;\n /**\n * Unacknowledged messages the consumer holds, which is also its concurrency.\n * Default 50, or 1 when `ordered`.\n */\n readonly prefetch?: number;\n /** Prefix of derived queue names. Default `'relaybus'`. */\n readonly queuePrefix?: string;\n /**\n * Consumer group: services sharing it share one queue and split the messages,\n * services with different groups each receive every message. The queue is\n * `<queuePrefix>.<consumerGroup>`. Required when subscribing, unless `queue` is set.\n */\n readonly consumerGroup?: string;\n /** Explicit queue name. Overrides `queuePrefix` and `consumerGroup`. */\n readonly queue?: string;\n /** Exchange poison messages are dead-lettered to. Default `'<exchange>.dead'`. */\n readonly deadLetterExchange?: string;\n /** Queue that keeps dead-lettered messages for inspection. Default `'<queue>.dead'`. */\n readonly deadLetterQueue?: string;\n /**\n * Quorum queue `x-delivery-limit`: deliveries after which the broker itself\n * dead-letters a message. Failing handlers do not consume it (they use\n * `redelivery`); it only stops a message that crashes the consumer or its\n * channel again and again. Default 10.\n */\n readonly deliveryLimit?: number;\n /**\n * Handler attempts on the same delivery, with backoff, before the message is\n * scheduled for delayed redelivery. Absorbs short blips without a broker round\n * trip. Default: 3 attempts, 200 ms initial delay, factor 2, 5 s cap, equal jitter.\n */\n readonly handlerRetry?: RetryPolicyOptions;\n /**\n * Delayed redelivery after `handlerRetry` is spent. Default: 2 s initial\n * delay, factor 2, 5 min cap, equal jitter, dead-lettered after 1 h of\n * failing (about 18 redeliveries). Delays are quantized to the retry queues,\n * one per step of the exponential ladder (9 queues with the defaults).\n * Ignored when `ordered`, where the same delays are waited in place.\n */\n readonly redelivery?: RedeliveryOptions;\n /**\n * Consume the queue strictly in order: a single active consumer across all\n * replicas, one message at a time, a failing message is retried in place\n * (blocking the queue) instead of being delayed. Needed when\n * `EventEnvelope.key` order matters; costs throughput, because one handler\n * runs at a time. Default false: handlers run concurrently and a delayed\n * redelivery overtakes later messages, so order is not preserved.\n */\n readonly ordered?: boolean;\n /** Reconnect backoff, or `false` to never reconnect. Default: 500 ms initial, factor 2, 30 s cap, equal jitter. */\n readonly reconnect?: ReconnectOptions | false;\n /**\n * When true (default) `connect()` rejects if the broker is unreachable, which\n * fails startup. When false it resolves and keeps trying in the background.\n */\n readonly failOnConnectError?: boolean;\n /**\n * When false (default) a message that no queue is bound to makes `publish`\n * reject. When true it resolves and the broker silently discards the message.\n */\n readonly allowUnroutable?: boolean;\n /** How long `publish` waits for the broker confirm. Default `'30s'`. */\n readonly publishTimeout?: Duration;\n /** How long `close` waits for running handlers. Default `'30s'`. */\n readonly shutdownTimeout?: Duration;\n /**\n * The wire format, both ways: how events become messages and consumed\n * messages become events. Default {@link cloudEventsBinary}: CloudEvents\n * binary mode (`cloudEvents:*` headers, AMQP properties as fallback), any\n * other message is malformed and dead-lettered. {@link cloudEventsStructured}\n * writes structured mode and reads both, {@link jsonEnvelope} maps a JSON\n * format of your own (an envelope with the payload inside, or the bare\n * payload), and an object with `encode` and `decode` can do anything else.\n * Whatever `decode` throws marks the message as malformed: it is\n * dead-lettered, the consumer keeps running.\n */\n readonly codec?: RabbitMqCodec;\n /**\n * How consumed messages become events; events are still written in\n * CloudEvents binary mode.\n *\n * @deprecated Use `codec`: `decode: fn` is `codec: { encode: encodeEnvelope, decode: fn }`.\n * Giving both `decode` and `codec` is a configuration error.\n */\n readonly decode?: RabbitMqMessageDecoder;\n /** Default: `console`. */\n readonly logger?: RelayBusLogger;\n /** Random source for jitter. Default `Math.random`. Intended for tests. */\n readonly random?: () => number;\n}\n\n/** What `connect` gets for each connection it opens. */\nexport interface ConnectOptions {\n /** Aborted when a shutdown runs past its deadline; destroys a socket still connecting. */\n readonly signal: AbortSignal;\n}\n\nexport interface ResolvedTransportSettings {\n readonly name: string;\n readonly connect: (options: ConnectOptions) => Promise<AmqpConnection>;\n readonly exchange: string;\n readonly prefetch: number;\n readonly queuePrefix: string;\n readonly consumerGroup: string | undefined;\n readonly queue: string | undefined;\n readonly deadLetterExchange: string;\n readonly deadLetterQueue: string | undefined;\n readonly deliveryLimit: number;\n readonly handlerRetry: RetryPolicy;\n readonly redelivery: RetryPolicy;\n /** Fixed delays of the retry queues; empty when `ordered`. */\n readonly retryLadder: readonly number[];\n readonly redeliveryMaxAgeMs: number;\n readonly ordered: boolean;\n readonly reconnect: RetryPolicy | undefined;\n readonly failOnConnectError: boolean;\n readonly allowUnroutable: boolean;\n readonly publishTimeoutMs: number;\n readonly shutdownTimeoutMs: number;\n /** Turns an event into the message to publish. */\n readonly encode: (envelope: EventEnvelope) => EncodedMessage;\n /** Turns a consumed message into a complete envelope; throws for a malformed one. */\n readonly decode: (message: AmqpMessage) => EventEnvelope;\n readonly logger: RelayBusLogger;\n readonly random: () => number;\n}\n\n/** Default `prefetch` when not ordered. */\nconst DEFAULT_PREFETCH = 50;\n/** Default `deliveryLimit`. */\nconst DEFAULT_DELIVERY_LIMIT = 10;\n\nconst DEFAULT_HANDLER_RETRY: RetryPolicy = {\n attempts: 3,\n initialDelayMs: 200,\n factor: 2,\n maxDelayMs: 5_000,\n jitter: 'equal',\n retryIf: undefined,\n};\n\nconst DEFAULT_REDELIVERY: RetryPolicy = {\n attempts: Number.POSITIVE_INFINITY,\n initialDelayMs: 2_000,\n factor: 2,\n maxDelayMs: 300_000,\n jitter: 'equal',\n retryIf: undefined,\n};\n\nconst DEFAULT_REDELIVERY_MAX_AGE = '1h';\n\nconst DEFAULT_RECONNECT: RetryPolicy = {\n attempts: 1,\n initialDelayMs: 500,\n factor: 2,\n maxDelayMs: 30_000,\n jitter: 'equal',\n retryIf: undefined,\n};\n\n/** Validates the options and applies defaults. Throws `ConfigurationError`. */\nexport function resolveSettings(options: RabbitMqTransportOptions): ResolvedTransportSettings {\n const basics = resolveBasics(options);\n return {\n ...resolveTopology(options, basics),\n ...resolveRetries(options, basics),\n ...resolveRuntime(options, basics),\n };\n}\n\n/** The settings the others depend on, checked first: exchange, connect behaviour, ordering, prefetch, redelivery. */\ntype BasicSettings = Pick<\n ResolvedTransportSettings,\n 'exchange' | 'failOnConnectError' | 'ordered' | 'prefetch' | 'redelivery'\n>;\n\nfunction resolveBasics(options: RabbitMqTransportOptions): BasicSettings {\n const exchange = nonEmpty(options.exchange ?? 'relaybus', 'exchange');\n const failOnConnectError = options.failOnConnectError ?? true;\n if (!failOnConnectError && options.reconnect === false) {\n throw new ConfigurationError(\n 'failOnConnectError=false needs reconnect enabled, otherwise the transport would never connect',\n );\n }\n const ordered = options.ordered ?? false;\n const prefetch = assertPositiveInteger(\n options.prefetch ?? (ordered ? 1 : DEFAULT_PREFETCH),\n 'prefetch',\n );\n if (ordered && prefetch !== 1) {\n throw new ConfigurationError(`ordered consumption needs prefetch 1, received ${prefetch}`);\n }\n const redelivery = createRetryPolicy(options.redelivery, DEFAULT_REDELIVERY);\n return { exchange, failOnConnectError, ordered, prefetch, redelivery };\n}\n\n/** Names, connection, exchanges and queues. */\nfunction resolveTopology(\n options: RabbitMqTransportOptions,\n { exchange, prefetch }: BasicSettings,\n): Pick<\n ResolvedTransportSettings,\n | 'name'\n | 'connect'\n | 'exchange'\n | 'prefetch'\n | 'queuePrefix'\n | 'consumerGroup'\n | 'queue'\n | 'deadLetterExchange'\n | 'deadLetterQueue'\n | 'deliveryLimit'\n> {\n return {\n name: nonEmpty(options.name ?? 'rabbitmq', 'name'),\n connect: resolveConnect(options),\n exchange,\n prefetch,\n queuePrefix: nonEmpty(options.queuePrefix ?? 'relaybus', 'queuePrefix'),\n consumerGroup: optionalNonEmpty(options.consumerGroup, 'consumerGroup'),\n queue: optionalNonEmpty(options.queue, 'queue'),\n deadLetterExchange: nonEmpty(\n options.deadLetterExchange ?? `${exchange}.dead`,\n 'deadLetterExchange',\n ),\n deadLetterQueue: optionalNonEmpty(options.deadLetterQueue, 'deadLetterQueue'),\n deliveryLimit: assertPositiveInteger(\n options.deliveryLimit ?? DEFAULT_DELIVERY_LIMIT,\n 'deliveryLimit',\n ),\n };\n}\n\n/** Handler retries, delayed redelivery and its retry queues. */\nfunction resolveRetries(\n options: RabbitMqTransportOptions,\n { ordered, redelivery }: BasicSettings,\n): Pick<\n ResolvedTransportSettings,\n 'handlerRetry' | 'redelivery' | 'retryLadder' | 'redeliveryMaxAgeMs' | 'ordered'\n> {\n return {\n handlerRetry: createRetryPolicy(options.handlerRetry, DEFAULT_HANDLER_RETRY),\n redelivery,\n retryLadder: ordered ? [] : buildRetryLadder(redelivery),\n redeliveryMaxAgeMs: positiveDuration(\n options.redelivery?.maxAge ?? DEFAULT_REDELIVERY_MAX_AGE,\n 'redelivery.maxAge',\n ),\n ordered,\n };\n}\n\n/** Reconnection, timeouts, the codec and the injected logger and randomness. */\nfunction resolveRuntime(\n options: RabbitMqTransportOptions,\n { failOnConnectError }: BasicSettings,\n): Pick<\n ResolvedTransportSettings,\n | 'reconnect'\n | 'failOnConnectError'\n | 'allowUnroutable'\n | 'publishTimeoutMs'\n | 'shutdownTimeoutMs'\n | 'encode'\n | 'decode'\n | 'logger'\n | 'random'\n> {\n return {\n reconnect: resolveReconnect(options.reconnect),\n failOnConnectError,\n allowUnroutable: options.allowUnroutable ?? false,\n publishTimeoutMs: positiveDuration(options.publishTimeout ?? '30s', 'publishTimeout'),\n shutdownTimeoutMs: toMilliseconds(options.shutdownTimeout ?? '30s', 'shutdownTimeout'),\n ...resolveCodec(options),\n logger: options.logger ?? console,\n random: options.random ?? Math.random,\n };\n}\n\n/** `<queuePrefix>.<consumerGroup>`, or the explicit queue name. */\nexport function resolveQueueName(settings: ResolvedTransportSettings): string {\n if (settings.queue !== undefined) {\n return settings.queue;\n }\n if (settings.consumerGroup === undefined) {\n throw new ConfigurationError(\n `Transport '${settings.name}' needs 'consumerGroup' or 'queue' to subscribe`,\n );\n }\n return `${settings.queuePrefix}.${settings.consumerGroup}`;\n}\n\n/** The codec of the options; the deprecated `decode` pairs with the default encoding. */\nfunction resolveCodec({\n codec,\n decode,\n}: RabbitMqTransportOptions): Pick<ResolvedTransportSettings, 'encode' | 'decode'> {\n if (decode !== undefined && codec !== undefined) {\n throw new ConfigurationError(\"Give 'codec' or the deprecated 'decode', not both\");\n }\n const chosen =\n decode === undefined ? (codec ?? cloudEventsBinary) : { encode: encodeEnvelope, decode };\n if (chosen === cloudEventsBinary) {\n return { encode: encodeEnvelope, decode: decodeEnvelope };\n }\n return {\n encode: chosen.encode,\n decode: (message) => completeDecodedEvent(chosen.decode(message), message),\n };\n}\n\nfunction resolveConnect(\n options: RabbitMqTransportOptions,\n): (options: ConnectOptions) => Promise<AmqpConnection> {\n const { url, connect } = options;\n if ((url === undefined) === (connect === undefined)) {\n throw new ConfigurationError(\"Give exactly one of 'url' and 'connect'\");\n }\n if (connect !== undefined) {\n return connect;\n }\n return async ({ signal }) => {\n const amqplib = await import('amqplib');\n // amqplib hands its socket options to net.connect / tls.connect, which take a signal; its types omit it.\n const socketOptions = { signal } as unknown as Parameters<typeof amqplib.connect>[1];\n return amqplib.connect(url!, socketOptions);\n };\n}\n\nfunction resolveReconnect(\n reconnect: ReconnectOptions | false | undefined,\n): RetryPolicy | undefined {\n if (reconnect === false) {\n return undefined;\n }\n return createRetryPolicy({ ...reconnect, attempts: 1 }, DEFAULT_RECONNECT);\n}\n\nfunction nonEmpty(value: string, name: string): string {\n if (value.length === 0) {\n throw new ConfigurationError(`${name} must not be empty`);\n }\n return value;\n}\n\nfunction optionalNonEmpty(value: string | undefined, name: string): string | undefined {\n return value === undefined ? undefined : nonEmpty(value, name);\n}\n\nfunction positiveDuration(value: Duration, name: string): number {\n const milliseconds = toMilliseconds(value, name);\n if (milliseconds === 0) {\n throw new ConfigurationError(`${name} must be greater than zero`);\n }\n return milliseconds;\n}\n","import type { AmqpChannel } from './amqp-types.js';\n\n/** Names of the broker objects a subscribing transport owns. */\nexport interface ConsumerTopology {\n readonly exchange: string;\n readonly queue: string;\n readonly deadLetterExchange: string;\n readonly deadLetterQueue: string;\n readonly deliveryLimit: number;\n /** Single active consumer, so the queue is consumed strictly in order. */\n readonly ordered: boolean;\n /** TTLs of the retry queues, ascending; empty when ordered. */\n readonly retryDelaysMs: readonly number[];\n /** Routing-key patterns the queue is bound with. */\n readonly destinations: readonly string[];\n}\n\n/** Name of the retry queue that holds messages for `delayMs` before returning them to `queue`. */\nexport function retryQueueName(queue: string, delayMs: number): string {\n return `${queue}.retry.${delayMs}`;\n}\n\n/** Declares the durable topic exchange events are published to. Idempotent. */\nexport async function assertExchange(channel: AmqpChannel, exchange: string): Promise<void> {\n await channel.assertExchange(exchange, 'topic', { durable: true });\n}\n\n/**\n * Declares the consumer side, all durable quorum queues and idempotent:\n *\n * - the main queue with a dead-letter exchange, `x-dead-letter-strategy`\n * `at-least-once` (which requires `x-overflow` `reject-publish`),\n * `x-delivery-limit` as a backstop for crash loops, and optionally\n * `x-single-active-consumer`; bound to the topic exchange once per destination;\n * - one retry queue per delay tier: a queue-level `x-message-ttl`, expired\n * messages dead-lettered through the default exchange back to the main queue;\n * - a direct dead-letter exchange and the dead-letter queue, bound with the main\n * queue's name as routing key.\n *\n * Declaring an existing queue with different arguments makes the broker close\n * the channel (`PRECONDITION_FAILED`); see the README for migrating a queue\n * created by an older version or with other options.\n */\nexport async function assertConsumerTopology(\n channel: AmqpChannel,\n topology: ConsumerTopology,\n): Promise<void> {\n await assertExchange(channel, topology.exchange);\n await channel.assertExchange(topology.deadLetterExchange, 'direct', { durable: true });\n await channel.assertQueue(topology.deadLetterQueue, {\n durable: true,\n arguments: { 'x-queue-type': 'quorum' },\n });\n await channel.bindQueue(topology.deadLetterQueue, topology.deadLetterExchange, topology.queue);\n for (const delayMs of topology.retryDelaysMs) {\n await channel.assertQueue(retryQueueName(topology.queue, delayMs), {\n durable: true,\n arguments: {\n 'x-queue-type': 'quorum',\n 'x-message-ttl': delayMs,\n 'x-dead-letter-exchange': '',\n 'x-dead-letter-routing-key': topology.queue,\n 'x-dead-letter-strategy': 'at-least-once',\n 'x-overflow': 'reject-publish',\n },\n });\n }\n await channel.assertQueue(topology.queue, {\n durable: true,\n arguments: {\n 'x-queue-type': 'quorum',\n 'x-delivery-limit': topology.deliveryLimit,\n 'x-dead-letter-exchange': topology.deadLetterExchange,\n 'x-dead-letter-routing-key': topology.queue,\n 'x-dead-letter-strategy': 'at-least-once',\n 'x-overflow': 'reject-publish',\n ...(topology.ordered ? { 'x-single-active-consumer': true } : {}),\n },\n });\n for (const destination of topology.destinations) {\n await channel.bindQueue(topology.queue, topology.exchange, destination);\n }\n}\n","import {\n computeRetryDelay,\n isRetryableError,\n toErrorInfo,\n type EventEnvelope,\n type RelayBusLogger,\n type RetryPolicy,\n type TransportMessageHandler,\n type TransportSubscriptionHooks,\n} from '@relaybus/core';\nimport { abortableSleep } from './abortable-sleep.js';\nimport type { AmqpChannel, AmqpMessage, AmqpPublishOptions } from './amqp-types.js';\nimport { RabbitMqUnavailableError } from './errors.js';\nimport {\n DEAD_LETTER_ERROR_CODE_HEADER,\n DEAD_LETTER_ERROR_NAME_HEADER,\n DEAD_LETTER_REASON_HEADER,\n FIRST_FAILURE_HEADER,\n ORIGINAL_ROUTING_KEY_HEADER,\n REDELIVERIES_HEADER,\n chooseRetryTier,\n copyForRepublish,\n originalRoutingKey,\n readCounterHeader,\n withOriginalRoutingKey,\n} from './redelivery.js';\nimport { retryQueueName } from './topology.js';\n\n/** Publishes a message and resolves only after the broker confirmed it was routed to a queue. */\nexport type ConfirmedRepublish = (\n destination: { readonly exchange: string; readonly routingKey: string },\n copy: { readonly content: Buffer; readonly options: AmqpPublishOptions },\n) => Promise<void>;\n\nexport interface QueueConsumerSettings {\n readonly queue: string;\n readonly prefetch: number;\n readonly handlerRetry: RetryPolicy;\n /** Backoff between delayed redeliveries. */\n readonly redelivery: RetryPolicy;\n /** Delays of the retry queues, ascending. Unused when ordered. */\n readonly retryLadder: readonly number[];\n /** A message failing for longer than this is dead-lettered. */\n readonly redeliveryMaxAgeMs: number;\n /** Retry in place instead of through the retry queues, so order is kept. */\n readonly ordered: boolean;\n readonly deadLetterExchange: string;\n readonly shutdownTimeoutMs: number;\n readonly onMessage: TransportMessageHandler;\n /** Told of each message `decode` rejected; undefined when nobody observes them. */\n readonly onInvalidMessage?: TransportSubscriptionHooks['onInvalidMessage'];\n /** Turns a message into an envelope; anything it throws dead-letters the message as malformed. */\n readonly decode: (message: AmqpMessage) => EventEnvelope;\n /** The consumer's channel closed or the broker cancelled the consumer. */\n readonly onConsumerLost: (reason: string) => void;\n /** Publishes to another queue on a confirm channel; rejects when the copy is not confirmed. */\n readonly republish: ConfirmedRepublish;\n readonly logger: RelayBusLogger;\n readonly random: () => number;\n}\n\ntype Settlement = 'ack' | 'requeue' | 'dead-letter';\n\n/** A message being processed, with the redelivery state its retries carry. */\ntype ProcessedMessage = {\n readonly channel: AmqpChannel;\n readonly message: AmqpMessage;\n readonly envelope: EventEnvelope;\n redeliveries: number;\n firstFailureAt: number | undefined;\n};\n\n/** A message to park in a retry queue, with the retry state its copy carries. */\ntype RedeliverLaterInput = {\n readonly message: AmqpMessage;\n readonly delayMs: number;\n readonly redeliveries: number;\n readonly firstFailureAt: number;\n};\n\n/** A message to move to the dead-letter queue and the error that sent it there. */\ntype DeadLetterInput = {\n readonly message: AmqpMessage;\n readonly reason: string;\n readonly error: unknown;\n};\n\n/**\n * Consumes one queue with manual acknowledgements.\n *\n * A message is acknowledged only after the handler resolved. When the handler\n * fails it is first retried on the same delivery with short backoff\n * (`handlerRetry`). If that does not help, a copy goes to the retry queue whose\n * TTL matches the next backoff step, and the original is acknowledged only\n * after the broker confirmed the copy; the copy returns to the main queue when\n * its TTL expires. This waits out a long outage of the handler's dependency.\n *\n * Malformed messages, non-retryable errors and messages that kept failing for\n * `redeliveryMaxAgeMs` go to the dead-letter exchange through a confirmed copy\n * (carrying the reason, without retry state, so a replay starts fresh) and the\n * original is acknowledged afterwards. If a copy cannot be confirmed the\n * original is requeued or rejected without requeue, which makes the broker\n * dead-letter it; it is never acknowledged unprocessed, so nothing is lost.\n *\n * In ordered mode nothing is moved: the failing message is retried in place with\n * the same backoff, holding the queue.\n */\nexport class QueueConsumer {\n readonly #settings: QueueConsumerSettings;\n readonly #inFlight = new Set<Promise<void>>();\n readonly #stopping = new AbortController();\n #channel: AmqpChannel | undefined;\n #consumerTag: string | undefined;\n\n constructor(settings: QueueConsumerSettings) {\n this.#settings = settings;\n }\n\n /** True while a consumer is registered on a live channel. */\n isActive(): boolean {\n return this.#consumerTag !== undefined;\n }\n\n /**\n * Starts consuming on a channel whose topology is already declared.\n *\n * @throws {RabbitMqUnavailableError} the channel closed while it was being set up\n */\n async attach(channel: AmqpChannel): Promise<void> {\n let closedDuringSetup = false;\n channel.on('error', (error: Error) => {\n this.#settings.logger.warn(\n `[QueueConsumer](attach) Channel error | queue=${this.#settings.queue} error=${error.message}`,\n );\n });\n channel.on('close', () => {\n closedDuringSetup = true;\n if (this.#channel === channel) {\n this.#channel = undefined;\n this.#consumerTag = undefined;\n this.#settings.onConsumerLost('consumer channel closed');\n }\n });\n await channel.prefetch(this.#settings.prefetch);\n const { consumerTag } = await channel.consume(\n this.#settings.queue,\n (message) => this.#receive(channel, message),\n { noAck: false },\n );\n if (closedDuringSetup) {\n throw new RabbitMqUnavailableError(\n `[QueueConsumer](attach) Consumer channel closed while the consumer was being set up | queue=${this.#settings.queue}`,\n );\n }\n this.#channel = channel;\n this.#consumerTag = consumerTag;\n }\n\n /** Forgets the channel without closing it, because its connection is gone. */\n detach(): void {\n this.#channel = undefined;\n this.#consumerTag = undefined;\n }\n\n /**\n * Stops taking messages, aborts pending handler backoff (those messages are\n * requeued), waits up to the shutdown timeout for running handlers, then\n * closes the channel. Unacknowledged messages return to the queue.\n */\n async stop(): Promise<void> {\n this.#stopping.abort();\n const channel = this.#channel;\n const consumerTag = this.#consumerTag;\n this.#channel = undefined;\n this.#consumerTag = undefined;\n if (channel !== undefined && consumerTag !== undefined) {\n await channel.cancel(consumerTag).catch((error: unknown) => {\n this.#settings.logger.warn(\n `[QueueConsumer](stop) Could not cancel consumer | queue=${this.#settings.queue} error=${toErrorInfo(error).message}`,\n );\n });\n }\n await this.#awaitInFlight();\n await channel?.close().catch(() => undefined);\n }\n\n async #awaitInFlight(): Promise<void> {\n if (this.#inFlight.size === 0) {\n return;\n }\n const timeout = new AbortController();\n const timedOut = abortableSleep(this.#settings.shutdownTimeoutMs, timeout.signal);\n await Promise.race([Promise.allSettled([...this.#inFlight]), timedOut]);\n timeout.abort();\n }\n\n #receive(channel: AmqpChannel, message: AmqpMessage | null): void {\n if (message === null) {\n this.#consumerTag = undefined;\n this.#settings.onConsumerLost('consumer cancelled by the broker');\n return;\n }\n const task: Promise<void> = this.#process(channel, message).finally(() => {\n this.#inFlight.delete(task);\n });\n this.#inFlight.add(task);\n }\n\n async #process(channel: AmqpChannel, message: AmqpMessage): Promise<void> {\n const decoded = await this.#decodeOrDeadLetter(channel, message);\n if (decoded === undefined) {\n return;\n }\n const { envelope } = decoded;\n const delivery: ProcessedMessage = {\n channel,\n message,\n envelope,\n redeliveries: readCounterHeader(message, REDELIVERIES_HEADER) ?? 0,\n firstFailureAt: readCounterHeader(message, FIRST_FAILURE_HEADER),\n };\n for (let attempt = 1; ; attempt += 1) {\n try {\n await this.#settings.onMessage(envelope, { destination: message.fields.routingKey });\n this.#settle(channel, { message, settlement: 'ack' });\n return;\n } catch (error) {\n if ((await this.#afterFailure(delivery, { attempt, error })) === 'settled') {\n return;\n }\n }\n }\n }\n\n /** The event of `message`, or undefined after dead-lettering a message that is not one. */\n async #decodeOrDeadLetter(\n channel: AmqpChannel,\n message: AmqpMessage,\n ): Promise<{ readonly envelope: EventEnvelope } | undefined> {\n try {\n return { envelope: this.#settings.decode(withOriginalRoutingKey(message)) };\n } catch (error) {\n this.#settings.logger.error(\n `[QueueConsumer](decodeOrDeadLetter) Dead-lettering malformed message | queue=${this.#settings.queue} routingKey=${message.fields.routingKey} ${describeError(error)}`,\n );\n this.#settings.onInvalidMessage?.({ destination: message.fields.routingKey, error });\n await this.#deadLetter(channel, { message, reason: 'malformed message', error });\n return undefined;\n }\n }\n\n /**\n * Decides what follows a failed attempt: dead-letter a non-retryable error, retry on the same\n * delivery while local attempts remain, else redeliver later. `retry` runs the handler again.\n */\n async #afterFailure(\n delivery: ProcessedMessage,\n { attempt, error }: { readonly attempt: number; readonly error: unknown },\n ): Promise<'retry' | 'settled'> {\n const { channel, message, envelope } = delivery;\n const { queue, handlerRetry } = this.#settings;\n const failure = `queue=${queue} eventId=${envelope.id} attempt=${attempt} ${describeError(error)}`;\n if (!isRetryableError(handlerRetry, error)) {\n this.#settings.logger.error(\n `[QueueConsumer](afterFailure) Dead-lettering message the handler cannot process | ${failure}`,\n );\n await this.#deadLetter(channel, {\n message,\n reason: 'non-retryable handler error',\n error,\n });\n return 'settled';\n }\n if (attempt < handlerRetry.attempts) {\n const delayMs = computeRetryDelay(handlerRetry, attempt, this.#settings.random);\n this.#settings.logger.warn(\n `[QueueConsumer](afterFailure) Handler failed, retrying | ${failure} delayMs=${delayMs}`,\n );\n return this.#waitOrRequeue(delivery, delayMs);\n }\n return this.#afterSpentAttempts(delivery, { failure, error });\n }\n\n /**\n * The local attempts are spent: dead-letter a message that kept failing past `redeliveryMaxAgeMs`,\n * else park it in a retry queue, or, when ordered, wait and retry it in place.\n */\n async #afterSpentAttempts(\n delivery: ProcessedMessage,\n { failure, error }: { readonly failure: string; readonly error: unknown },\n ): Promise<'retry' | 'settled'> {\n const { channel, message } = delivery;\n delivery.redeliveries += 1;\n const now = Date.now();\n delivery.firstFailureAt ??= now;\n const { redeliveries, firstFailureAt } = delivery;\n const delayMs = this.#redeliveryDelay(redeliveries);\n if (now + delayMs - firstFailureAt > this.#settings.redeliveryMaxAgeMs) {\n this.#settings.logger.error(\n `[QueueConsumer](afterSpentAttempts) Dead-lettering message that kept failing | ${failure} redeliveries=${redeliveries - 1} failingForMs=${now - firstFailureAt} maxAgeMs=${this.#settings.redeliveryMaxAgeMs}`,\n );\n await this.#deadLetter(channel, {\n message,\n reason: 'redelivery window exhausted',\n error,\n });\n return 'settled';\n }\n this.#settings.logger.warn(\n `[QueueConsumer](afterSpentAttempts) Handler attempts spent, retrying later | ${failure} redeliveries=${redeliveries} delayMs=${delayMs}`,\n );\n if (!this.#settings.ordered) {\n await this.#redeliverLater(channel, { message, delayMs, redeliveries, firstFailureAt });\n return 'settled';\n }\n return this.#waitOrRequeue(delivery, delayMs);\n }\n\n /** Waits `delayMs` before the next attempt; requeues instead when the consumer stops meanwhile. */\n async #waitOrRequeue(delivery: ProcessedMessage, delayMs: number): Promise<'retry' | 'settled'> {\n if (await this.#interrupted(delayMs)) {\n this.#settle(delivery.channel, { message: delivery.message, settlement: 'requeue' });\n return 'settled';\n }\n return 'retry';\n }\n\n /** The backoff before the next delayed redelivery: a retry queue's TTL, or an exact wait when ordered. */\n #redeliveryDelay(redeliveries: number): number {\n const { redelivery, retryLadder, ordered, random } = this.#settings;\n const delayMs = computeRetryDelay(redelivery, redeliveries, random);\n return ordered ? delayMs : chooseRetryTier(retryLadder, { delayMs, random });\n }\n\n /** Sleeps; true when the consumer is stopping, so the caller must give the message back. */\n async #interrupted(delayMs: number): Promise<boolean> {\n await abortableSleep(delayMs, this.#stopping.signal);\n return this.#stopping.signal.aborted;\n }\n\n /**\n * Parks a copy in the retry queue of `delayMs` and acknowledges the original\n * only once the broker confirmed the copy. When the copy cannot be confirmed\n * the original is requeued after the same delay, so it is neither lost nor\n * hot-looped.\n */\n async #redeliverLater(channel: AmqpChannel, input: RedeliverLaterInput): Promise<void> {\n const { message, delayMs, redeliveries, firstFailureAt } = input;\n const { content, options } = copyForRepublish(message, {\n [REDELIVERIES_HEADER]: String(redeliveries),\n [FIRST_FAILURE_HEADER]: String(firstFailureAt),\n [ORIGINAL_ROUTING_KEY_HEADER]: originalRoutingKey(message),\n });\n try {\n await this.#settings.republish(\n { exchange: '', routingKey: retryQueueName(this.#settings.queue, delayMs) },\n { content, options },\n );\n } catch (error) {\n this.#settings.logger.warn(\n `[QueueConsumer](redeliverLater) Could not park the message in the retry queue, requeueing it | queue=${this.#settings.queue} delayMs=${delayMs} error=${toErrorInfo(error).message}`,\n );\n await this.#interrupted(delayMs);\n this.#settle(channel, { message, settlement: 'requeue' });\n return;\n }\n this.#settle(channel, { message, settlement: 'ack' });\n }\n\n /**\n * Moves the message to the dead-letter queue through a confirmed copy that\n * carries the reason and no retry state. If the copy cannot be confirmed the\n * message is rejected without requeue, which makes the broker dead-letter it\n * (at-least-once), so it still ends up in the dead-letter queue.\n */\n async #deadLetter(channel: AmqpChannel, input: DeadLetterInput): Promise<void> {\n const { message, reason, error } = input;\n const { name, code } = toErrorInfo(error);\n const { content, options } = copyForRepublish(message, {\n [DEAD_LETTER_REASON_HEADER]: reason,\n [DEAD_LETTER_ERROR_NAME_HEADER]: name,\n ...(code === undefined ? {} : { [DEAD_LETTER_ERROR_CODE_HEADER]: code }),\n });\n try {\n await this.#settings.republish(\n { exchange: this.#settings.deadLetterExchange, routingKey: this.#settings.queue },\n { content, options },\n );\n } catch (error) {\n this.#settings.logger.warn(\n `[QueueConsumer](deadLetter) Could not publish to the dead-letter exchange, leaving it to the broker | queue=${this.#settings.queue} error=${toErrorInfo(error).message}`,\n );\n this.#settle(channel, { message, settlement: 'dead-letter' });\n return;\n }\n this.#settle(channel, { message, settlement: 'ack' });\n }\n\n #settle(\n channel: AmqpChannel,\n { message, settlement }: { readonly message: AmqpMessage; readonly settlement: Settlement },\n ): void {\n try {\n if (settlement === 'ack') {\n channel.ack(message);\n } else {\n channel.nack(message, false, settlement === 'requeue');\n }\n } catch (error) {\n // The channel is gone; the broker redelivers the message and the inbox drops the duplicate.\n this.#settings.logger.warn(\n `[QueueConsumer](settle) Could not ${settlement} message, the broker will redeliver it | queue=${this.#settings.queue} error=${toErrorInfo(error).message}`,\n );\n }\n }\n}\n\n/** Log fields of an error: its message, class name and, for relaybus errors, its code. */\nfunction describeError(error: unknown): string {\n const { message, name, code } = toErrorInfo(error);\n return `error=${message} errorName=${name}${code === undefined ? '' : ` code=${code}`}`;\n}\n","/** Runs async tasks one after another, in submission order, even when one fails. */\nexport class SerialQueue {\n #tail: Promise<unknown> = Promise.resolve();\n\n run<TResult>(task: () => Promise<TResult>): Promise<TResult> {\n const result = this.#tail.then(task);\n this.#tail = result.catch(() => undefined);\n return result;\n }\n}\n","import {\n ConfigurationError,\n systemClock,\n toErrorInfo,\n type CloseOptions,\n type EventEnvelope,\n type Transport,\n type TransportMessageHandler,\n type TransportSubscriptionHooks,\n} from '@relaybus/core';\nimport { schedule } from '@relaybus/core/internal';\nimport type {\n AmqpConfirmChannel,\n AmqpConnection,\n AmqpMessage,\n AmqpPublishOptions,\n} from './amqp-types.js';\nimport { ConnectionSupervisor } from './connection-supervisor.js';\nimport {\n RabbitMqPublishRejectedError,\n RabbitMqUnavailableError,\n UnroutableMessageError,\n} from './errors.js';\nimport {\n resolveQueueName,\n resolveSettings,\n type RabbitMqTransportOptions,\n type ResolvedTransportSettings,\n} from './options.js';\nimport { QueueConsumer } from './queue-consumer.js';\nimport { SerialQueue } from './serial-queue.js';\nimport { assertConsumerTopology, assertExchange, type ConsumerTopology } from './topology.js';\nimport { assertShortString } from './wire-format.js';\n\n/** Publisher channel plus the broker returns not yet matched with their confirm. */\ninterface Publisher {\n readonly channel: AmqpConfirmChannel;\n readonly unroutable: Map<string, number>;\n /** Set when the channel closed, also while the transport was still being set up. */\n closed: boolean;\n}\n\ninterface LiveConnection {\n readonly connection: AmqpConnection;\n readonly publisher: Publisher;\n}\n\ninterface Subscription {\n readonly topology: ConsumerTopology;\n readonly consumer: QueueConsumer;\n}\n\n/** amqplib reports a negative acknowledgement with this exact message. */\nconst NACK_MESSAGE = 'message nacked';\n\n/** One message to publish and wait for the broker's confirm. */\ntype PublishConfirmedInput = {\n readonly exchange: string;\n readonly routingKey: string;\n readonly content: Buffer;\n readonly options: AmqpPublishOptions;\n /** Ask the broker to return the message when no queue is bound to its routing key. */\n readonly mandatory: boolean;\n};\n\n/**\n * RabbitMQ {@link Transport} built on amqplib.\n *\n * Publishing: each event goes to a durable topic exchange as a persistent,\n * mandatory message with the destination as routing key. `publish` resolves\n * only after the broker confirmed it was persisted and routed to a queue, and\n * rejects when the transport is disconnected, the broker nacks, the message is\n * unroutable or no confirm arrives in time. It never drops a message silently,\n * so the outbox retries the delivery.\n *\n * Subscribing: one durable quorum queue per consumer group, bound to the\n * destinations (routing-key patterns such as `orders.*`). A message is\n * acknowledged only after the handler resolved. A failing handler is retried\n * on the same delivery, then through retry queues with growing delays (see\n * `redelivery`), and finally dead-lettered after the retry window; poison\n * messages are dead-lettered at once. Nothing is lost on the way.\n *\n * Reconnection: after a connection or channel loss the transport reconnects\n * with capped, jittered backoff and restores channels, topology and the\n * consumer. Events published meanwhile are rejected, and therefore retried by\n * the outbox, rather than buffered in memory.\n */\nexport class RabbitMqTransport implements Transport {\n readonly name: string;\n readonly system = 'rabbitmq';\n readonly #settings: ResolvedTransportSettings;\n readonly #supervisor: ConnectionSupervisor;\n /** Serializes topology work so a subscription never races a reconnect. */\n readonly #topologyWork = new SerialQueue();\n #live: LiveConnection | undefined;\n #subscription: Subscription | undefined;\n #closing: Promise<void> | undefined;\n\n constructor(options: RabbitMqTransportOptions) {\n this.#settings = resolveSettings(options);\n this.name = this.#settings.name;\n this.#supervisor = new ConnectionSupervisor({\n connect: this.#settings.connect,\n reconnect: this.#settings.reconnect,\n onConnected: (connection) => this.#establishChannels(connection),\n onDisconnected: () => this.#forgetConnection(),\n logger: this.#settings.logger,\n random: this.#settings.random,\n });\n }\n\n /**\n * True while the connection is open and publishing and consuming are set up.\n * Use it for readiness probes.\n */\n isConnected(): boolean {\n return this.#supervisor.isConnected();\n }\n\n /**\n * True when the transport can publish and, once subscribed, is consuming: the\n * connection is up, its channels are open and the consumer is registered. False while reconnecting and after a cancelled consumer.\n */\n isReady(): boolean {\n return (\n this.#supervisor.isConnected() &&\n this.#live !== undefined &&\n (this.#subscription === undefined || this.#subscription.consumer.isActive())\n );\n }\n\n /** Connects to the broker. Rejects when it is unreachable unless `failOnConnectError` is false. */\n async connect(): Promise<void> {\n await this.#supervisor.start(this.#settings.failOnConnectError);\n }\n\n /**\n * Publishes to the exchange with `destination` as routing key and resolves\n * after the broker confirmed the message.\n *\n * @throws {UnserializablePayloadError} the payload is not representable as JSON (never retried)\n * @throws {AmqpLimitExceededError} the event id, a header name or `destination` exceeds 255 bytes (never retried)\n * @throws {RabbitMqUnavailableError} not connected, channel lost, or confirm timed out\n * @throws {RabbitMqPublishRejectedError} the broker nacked the message\n * @throws {UnroutableMessageError} no queue is bound to `destination` (unless `allowUnroutable`)\n * @throws whatever the `codec`'s `encode` throws, such as {@link RabbitMqUnencodableEventError}\n */\n async publish(envelope: EventEnvelope, destination: string): Promise<void> {\n assertShortString('Destination (routing key)', destination);\n const { content, options } = this.#settings.encode(envelope);\n await this.#publishConfirmed({\n exchange: this.#settings.exchange,\n routingKey: destination,\n content,\n options,\n mandatory: !this.#settings.allowUnroutable,\n });\n }\n\n async #publishConfirmed(input: PublishConfirmedInput): Promise<void> {\n const { exchange, routingKey, content, options, mandatory } = input;\n const publisher = this.#live?.publisher;\n const eventId = options.messageId ?? 'unknown';\n if (publisher === undefined) {\n throw new RabbitMqUnavailableError(\n `[RabbitMqTransport](publish) Not connected to the broker | transport=${this.name} destination=${routingKey}`,\n );\n }\n const returnKey = unroutableKey(options.messageId, routingKey);\n await new Promise<void>((resolve, reject) => {\n const cancelTimeout = schedule(systemClock, {\n run: () => {\n reject(\n new RabbitMqUnavailableError(\n `[RabbitMqTransport](publish) No broker confirm within ${this.#settings.publishTimeoutMs}ms | transport=${this.name} eventId=${eventId} destination=${routingKey}`,\n ),\n );\n },\n delayMs: this.#settings.publishTimeoutMs,\n });\n const onConfirm = (error: Error | null | undefined): void => {\n cancelTimeout();\n const returned = takeUnroutable(publisher.unroutable, returnKey);\n if (error) {\n reject(this.#toPublishError(error, { eventId, destination: routingKey }));\n } else if (returned) {\n reject(\n new UnroutableMessageError(\n `[RabbitMqTransport](publish) No queue is bound to the routing key | transport=${this.name} eventId=${eventId} destination=${routingKey}`,\n ),\n );\n } else {\n resolve();\n }\n };\n try {\n publisher.channel.publish(\n exchange,\n routingKey,\n content,\n { ...options, mandatory },\n onConfirm,\n );\n } catch (error) {\n cancelTimeout();\n reject(this.#toPublishError(error, { eventId, destination: routingKey }));\n }\n });\n }\n\n /**\n * Binds one durable quorum queue to `destinations` and delivers its messages\n * to `onMessage`. Call it once per transport; give each subscription its own\n * transport instance, with its own `name` and `consumerGroup`.\n */\n // eslint-disable-next-line relaybus/max-two-params -- the Transport.subscribe signature\n async subscribe(\n destinations: readonly string[],\n onMessage: TransportMessageHandler,\n hooks?: TransportSubscriptionHooks,\n ): Promise<void> {\n if (this.#subscription !== undefined) {\n throw new ConfigurationError(\n `Transport '${this.name}' already has a subscription; create another transport for another consumer group`,\n );\n }\n if (destinations.length === 0) {\n throw new ConfigurationError(`Transport '${this.name}' needs at least one destination`);\n }\n const queue = resolveQueueName(this.#settings);\n const subscription: Subscription = {\n topology: {\n exchange: this.#settings.exchange,\n queue,\n deadLetterExchange: this.#settings.deadLetterExchange,\n deadLetterQueue: this.#settings.deadLetterQueue ?? `${queue}.dead`,\n deliveryLimit: this.#settings.deliveryLimit,\n ordered: this.#settings.ordered,\n retryDelaysMs: this.#settings.retryLadder,\n destinations,\n },\n consumer: new QueueConsumer({\n queue,\n prefetch: this.#settings.prefetch,\n handlerRetry: this.#settings.handlerRetry,\n redelivery: this.#settings.redelivery,\n retryLadder: this.#settings.retryLadder,\n redeliveryMaxAgeMs: this.#settings.redeliveryMaxAgeMs,\n ordered: this.#settings.ordered,\n deadLetterExchange: this.#settings.deadLetterExchange,\n republish: ({ exchange, routingKey }, { content, options }) =>\n this.#publishConfirmed({ exchange, routingKey, content, options, mandatory: true }),\n shutdownTimeoutMs: this.#settings.shutdownTimeoutMs,\n onMessage,\n ...(hooks === undefined ? {} : { onInvalidMessage: hooks.onInvalidMessage }),\n decode: this.#settings.decode,\n onConsumerLost: (reason) => this.#supervisor.recover(reason),\n logger: this.#settings.logger,\n random: this.#settings.random,\n }),\n };\n await this.#topologyWork.run(async () => {\n this.#subscription = subscription;\n if (this.#live !== undefined) {\n await this.#startConsuming(this.#live.connection, subscription);\n }\n });\n }\n\n /**\n * Stops consuming, waits up to `shutdownTimeout` for running handlers\n * (messages still being retried go back to the queue), then closes the\n * channels and the connection. Once `options.signal` aborts (the bus shutdown deadline passed),\n * the connection's socket is destroyed instead of waiting for the broker.\n */\n async close(options: CloseOptions = {}): Promise<void> {\n const { signal } = options;\n const force = (): void => this.#supervisor.forceClose();\n if (signal?.aborted === true) {\n force();\n }\n signal?.addEventListener('abort', force, { once: true });\n try {\n // A second call shares the work of the first, and its signal can still cut the connection.\n this.#closing ??= this.#supervisor.close(() =>\n this.#topologyWork.run(async () => {\n const live = this.#live;\n this.#live = undefined;\n await this.#subscription?.consumer.stop();\n await live?.publisher.channel.close().catch(() => undefined);\n }),\n );\n await this.#closing;\n } finally {\n signal?.removeEventListener('abort', force);\n }\n }\n\n async #establishChannels(connection: AmqpConnection): Promise<void> {\n await this.#topologyWork.run(async () => {\n const channel = await connection.createConfirmChannel();\n const publisher: Publisher = { channel, unroutable: new Map(), closed: false };\n channel.on('error', (error: Error) => {\n this.#settings.logger.warn(\n `[RabbitMqTransport](establishChannels) Publisher channel error | transport=${this.name} error=${error.message}`,\n );\n });\n channel.on('close', () => {\n publisher.closed = true;\n if (this.#live?.publisher === publisher) {\n this.#supervisor.recover('publisher channel closed');\n }\n });\n channel.on('return', (message: AmqpMessage) => {\n recordUnroutable(\n publisher.unroutable,\n unroutableKey(message.properties.messageId, message.fields.routingKey),\n );\n });\n await assertExchange(channel, this.#settings.exchange);\n if (this.#subscription !== undefined) {\n await this.#startConsuming(connection, this.#subscription);\n }\n if (publisher.closed) {\n // The close came before `live` was set, so nothing reacted to it.\n throw new RabbitMqUnavailableError(\n `[RabbitMqTransport](establishChannels) Publisher channel closed while the transport was being set up | transport=${this.name}`,\n );\n }\n this.#live = { connection, publisher };\n });\n }\n\n async #startConsuming(connection: AmqpConnection, subscription: Subscription): Promise<void> {\n const channel = await connection.createChannel();\n await assertConsumerTopology(channel, subscription.topology);\n await subscription.consumer.attach(channel);\n }\n\n #forgetConnection(): void {\n this.#live = undefined;\n this.#subscription?.consumer.detach();\n }\n\n #toPublishError(\n error: unknown,\n { eventId, destination }: { readonly eventId: string; readonly destination: string },\n ): Error {\n const { message } = toErrorInfo(error);\n const detail = `transport=${this.name} eventId=${eventId} destination=${destination} error=${message}`;\n return message === NACK_MESSAGE\n ? new RabbitMqPublishRejectedError(\n `[RabbitMqTransport](publish) Broker nacked the message | ${detail}`,\n { cause: error },\n )\n : new RabbitMqUnavailableError(`[RabbitMqTransport](publish) Publish failed | ${detail}`, {\n cause: error,\n });\n }\n}\n\nfunction unroutableKey(messageId: unknown, routingKey: string): string {\n return `${String(messageId)}\\n${routingKey}`;\n}\n\nfunction recordUnroutable(unroutable: Map<string, number>, key: string): void {\n unroutable.set(key, (unroutable.get(key) ?? 0) + 1);\n}\n\nfunction takeUnroutable(unroutable: Map<string, number>, key: string): boolean {\n const count = unroutable.get(key);\n if (count === undefined) {\n return false;\n }\n if (count === 1) {\n unroutable.delete(key);\n } else {\n unroutable.set(key, count - 1);\n }\n return true;\n}\n"]}