@relaybus/kafka 0.0.0-stage → 0.0.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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cloudevents-codec.ts","../src/kafka-transport.ts"],"names":["RelayBusError","NonRetryableError"],"mappings":"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","file":"index.js","sourcesContent":["import {\n NonRetryableError,\n RelayBusError,\n assertEventType,\n type EventEnvelope,\n} from '@relaybus/core';\nimport type { KafkaBytes, KafkaIncomingHeaders, KafkaOutgoingHeaders } from './kafka-client.js';\n\n/** A Kafka record that cannot be turned into an {@link EventEnvelope}. Never retried. */\nexport class InvalidKafkaMessageError extends RelayBusError {}\n\n/**\n * An event that cannot be written to Kafka: its payload is not representable as\n * JSON (`undefined`, a function, a symbol, a `BigInt`, a circular structure) or\n * its `occurredAt` is not an RFC 3339 instant (invalid date, year outside 0..9999).\n * Retrying cannot help, so it is a {@link NonRetryableError}.\n */\nexport class UnencodableEventError extends NonRetryableError {\n override name = 'UnencodableEventError';\n}\n\n/** The wire form of one event: a Kafka record in CloudEvents binary content mode. */\nexport interface EncodedMessage {\n readonly key: string | null;\n readonly value: string;\n readonly headers: Record<string, string>;\n}\n\n/** The parts of an incoming Kafka record the decoder reads. */\nexport interface DecodableMessage {\n readonly key: KafkaBytes | null;\n readonly value: KafkaBytes | null;\n readonly headers?: KafkaIncomingHeaders | undefined;\n /** Record timestamp in epoch milliseconds, used when `ce_time` is absent. */\n readonly timestamp?: string | undefined;\n}\n\nconst SPEC_VERSION = '1.0';\nconst CONTENT_TYPE = 'content-type';\nconst JSON_MEDIA_TYPE = 'application/json';\nconst CLOUDEVENTS_PREFIX = 'ce_';\nconst ESCAPE_PREFIX = 'x-relaybus-h-';\nconst RESERVED_PREFIXES = [CLOUDEVENTS_PREFIX, 'x-relaybus-'];\n\nconst HEADER = {\n specVersion: 'ce_specversion',\n id: 'ce_id',\n type: 'ce_type',\n source: 'ce_source',\n time: 'ce_time',\n subject: 'ce_subject',\n correlationId: 'ce_correlationid',\n causationId: 'ce_causationid',\n} as const;\n\nconst PROTOCOL_HEADERS: ReadonlySet<string> = new Set([...Object.values(HEADER), CONTENT_TYPE]);\n\nconst RFC3339_PATTERN = /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?(?:Z|[+-]\\d{2}:\\d{2})$/i;\n\nconst strictUtf8 = new TextDecoder('utf-8', { fatal: true });\nconst lenientUtf8 = new TextDecoder('utf-8');\n\n/**\n * Encodes an envelope as a CloudEvents Kafka binary-mode record: the value is\n * the JSON payload, the event attributes travel as `ce_*` headers.\n *\n * User headers that would collide with protocol names (`ce_*`, `content-type`,\n * `x-relaybus-*`) are stored under an `x-relaybus-h-` prefix and restored on\n * decode, so every header survives a round trip unchanged.\n */\nexport function encodeEnvelope(envelope: EventEnvelope): EncodedMessage {\n const value = serializePayload(envelope);\n const entries: [string, string][] = Object.entries(envelope.headers).map(\n ([name, headerValue]) => [escapeUserHeaderName(name), headerValue],\n );\n entries.push(\n [HEADER.specVersion, SPEC_VERSION],\n [HEADER.id, envelope.id],\n [HEADER.type, envelope.type],\n [HEADER.source, envelope.source],\n [HEADER.time, formatTime(envelope)],\n [CONTENT_TYPE, JSON_MEDIA_TYPE],\n );\n if (envelope.key !== null) {\n entries.push([HEADER.subject, envelope.key]);\n }\n if (envelope.correlationId !== null) {\n entries.push([HEADER.correlationId, envelope.correlationId]);\n }\n if (envelope.causationId !== null) {\n entries.push([HEADER.causationId, envelope.causationId]);\n }\n // fromEntries defines own properties, so a header named `__proto__` is kept as data.\n return { key: envelope.key, value, headers: Object.fromEntries(entries) };\n}\n\nfunction serializePayload(envelope: EventEnvelope): string {\n let value: string | undefined;\n try {\n value = JSON.stringify(envelope.payload);\n } catch (error) {\n throw new UnencodableEventError(\n `Event ${envelope.id} has a payload that JSON cannot represent: ${(error as Error).message}`,\n );\n }\n if (value === undefined) {\n throw new UnencodableEventError(\n `Event ${envelope.id} has a payload that JSON cannot represent (undefined, a function or a symbol)`,\n );\n }\n return value;\n}\n\nfunction formatTime(envelope: EventEnvelope): string {\n const year = envelope.occurredAt.getUTCFullYear();\n if (Number.isNaN(year) || year < 0 || year > 9999) {\n throw new UnencodableEventError(\n `Event ${envelope.id} has an occurredAt that is not an RFC 3339 instant (invalid date or year outside 0..9999)`,\n );\n }\n return envelope.occurredAt.toISOString();\n}\n\n/**\n * Decodes a Kafka record strictly: the CloudEvents attributes `ce_specversion`\n * (`1.0`), `ce_id`, `ce_type`, `ce_source`, a JSON `content-type` and a JSON\n * value are required. `ce_time` is optional in CloudEvents: when absent, the\n * Kafka record timestamp is used; when present it must be RFC 3339.\n *\n * @throws InvalidKafkaMessageError for anything else. It is the only error\n * thrown for malformed input, so callers can tell poison messages from bugs.\n */\nexport function decodeEnvelope(message: DecodableMessage): EventEnvelope {\n const headers = readHeaders(message.headers);\n if (headers.get(HEADER.specVersion) !== SPEC_VERSION) {\n throw invalid(`${HEADER.specVersion} must be '${SPEC_VERSION}'`);\n }\n const type = requireHeader(headers, HEADER.type);\n try {\n assertEventType(type);\n } catch (error) {\n throw invalid(`${HEADER.type} is not a valid event type: ${(error as Error).message}`);\n }\n assertJsonContentType(headers.get(CONTENT_TYPE));\n return {\n id: requireHeader(headers, HEADER.id),\n type,\n source: requireHeader(headers, HEADER.source),\n key: resolveKey(headers.get(HEADER.subject), message.key),\n payload: parsePayload(message.value),\n headers: collectUserHeaders(headers),\n correlationId: headers.get(HEADER.correlationId) ?? null,\n causationId: headers.get(HEADER.causationId) ?? null,\n occurredAt: resolveTime(headers.get(HEADER.time), message.timestamp),\n };\n}\n\nfunction invalid(reason: string): InvalidKafkaMessageError {\n return new InvalidKafkaMessageError(reason);\n}\n\nfunction escapeUserHeaderName(name: string): string {\n const lowered = name.toLowerCase();\n const reserved = lowered === CONTENT_TYPE || RESERVED_PREFIXES.some((p) => lowered.startsWith(p));\n return reserved ? `${ESCAPE_PREFIX}${name}` : name;\n}\n\nfunction readHeaders(incoming: KafkaIncomingHeaders | undefined): Map<string, string> {\n const headers = new Map<string, string>();\n for (const [name, raw] of Object.entries(incoming ?? {})) {\n if (raw === undefined) {\n continue;\n }\n if (typeof raw !== 'string' && !(raw instanceof Uint8Array)) {\n throw invalid(`Header '${name}' is repeated`);\n }\n headers.set(name, decodeText(raw, PROTOCOL_HEADERS.has(name), `Header '${name}'`));\n }\n return headers;\n}\n\nfunction decodeText(raw: KafkaBytes | string, strict: boolean, label: string): string {\n if (typeof raw === 'string') {\n return raw;\n }\n try {\n return (strict ? strictUtf8 : lenientUtf8).decode(raw);\n } catch {\n throw invalid(`${label} is not valid UTF-8`);\n }\n}\n\nfunction requireHeader(headers: Map<string, string>, name: string): string {\n const value = headers.get(name);\n if (value === undefined || value.length === 0) {\n throw invalid(`Header '${name}' is missing or empty`);\n }\n return value;\n}\n\nfunction assertJsonContentType(contentType: string | undefined): void {\n const mediaType = contentType?.split(';')[0]?.trim().toLowerCase();\n if (mediaType !== JSON_MEDIA_TYPE) {\n throw invalid(`${CONTENT_TYPE} must be '${JSON_MEDIA_TYPE}', received '${contentType ?? ''}'`);\n }\n}\n\nfunction resolveTime(text: string | undefined, recordTimestamp: string | undefined): Date {\n if (text !== undefined && text.length > 0) {\n return parseTime(text);\n }\n const milliseconds = Number(recordTimestamp);\n const time = new Date(milliseconds);\n if (recordTimestamp === undefined || recordTimestamp === '' || Number.isNaN(time.getTime())) {\n throw invalid(`${HEADER.time} is missing and the record has no usable timestamp`);\n }\n return time;\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 invalid(`${HEADER.time} is not an RFC 3339 timestamp: '${text}'`);\n }\n return time;\n}\n\nfunction parsePayload(value: KafkaBytes | null): unknown {\n if (value === null) {\n throw invalid('Message has no value');\n }\n const text = decodeText(value, true, 'Message value');\n try {\n return JSON.parse(text) as unknown;\n } catch {\n throw invalid('Message value is not valid JSON');\n }\n}\n\nfunction resolveKey(subject: string | undefined, recordKey: KafkaBytes | null): string | null {\n const keyText = recordKey === null ? null : decodeText(recordKey, true, 'Message key');\n if (subject !== undefined && keyText !== null && subject !== keyText) {\n throw invalid(`${HEADER.subject} does not match the message key`);\n }\n return subject ?? keyText;\n}\n\nfunction collectUserHeaders(headers: Map<string, string>): Record<string, string> {\n const entries: [string, string][] = [];\n for (const [name, value] of headers) {\n if (!PROTOCOL_HEADERS.has(name)) {\n entries.push([\n name.startsWith(ESCAPE_PREFIX) ? name.slice(ESCAPE_PREFIX.length) : name,\n value,\n ]);\n }\n }\n return Object.fromEntries(entries);\n}\n\n/** Converts incoming headers to what a producer accepts, keeping every value byte-for-byte. */\nexport function toOutgoingHeaders(\n incoming: KafkaIncomingHeaders | undefined,\n): KafkaOutgoingHeaders {\n const entries: [string, Buffer | string | (Buffer | string)[]][] = [];\n for (const [name, raw] of Object.entries(incoming ?? {})) {\n if (raw !== undefined) {\n entries.push([\n name,\n Array.isArray(raw)\n ? (raw as (KafkaBytes | string)[]).map(toBufferOrString)\n : toBufferOrString(raw as KafkaBytes | string),\n ]);\n }\n }\n return Object.fromEntries(entries);\n}\n\nfunction toBufferOrString(value: KafkaBytes | string): Buffer | string {\n return typeof value === 'string' ? value : Buffer.from(value);\n}\n","import {\n ConfigurationError,\n NonRetryableError,\n RelayBusError,\n toErrorInfo,\n toMilliseconds,\n type Duration,\n type EventEnvelope,\n type RelayBusLogger,\n type Transport,\n type TransportMessageHandler,\n} from '@relaybus/core';\nimport {\n InvalidKafkaMessageError,\n decodeEnvelope,\n encodeEnvelope,\n toOutgoingHeaders,\n} from './cloudevents-codec.js';\nimport type {\n KafkaClientLike,\n KafkaConsumerEvent,\n KafkaConsumerLike,\n KafkaEachMessagePayload,\n KafkaProducerLike,\n KafkaProducerRecord,\n} from './kafka-client.js';\n\n/** A record the transport refused to hand to the bus because it is malformed. */\nexport interface InvalidKafkaMessage {\n readonly topic: string;\n readonly partition: number;\n readonly offset: string;\n /** Why the record was rejected. */\n readonly reason: string;\n readonly key: Uint8Array | null;\n readonly value: Uint8Array | null;\n}\n\n/**\n * What to do with a record that cannot be processed for good (it cannot be\n * decoded, or the bus rejected it with a `NonRetryableError`):\n * - `'dead-letter'` (default): the original record is produced to\n * `<source topic>.dead` with `relaybus-invalid-reason`, `relaybus-source-topic`,\n * `relaybus-source-partition` and `relaybus-source-offset` headers added to the\n * original ones; the offset advances only after the broker acked the copy.\n * - `{ deadLetterTopic }`: same, with a fixed topic name or a function of the\n * source topic.\n * - a function: called with the record; if it rejects, the record is retried\n * like any other failure, so nothing is dropped unless the function returns.\n * - `'skip'`: log an error and drop the record. Explicit opt-in only.\n *\n * The dead-letter topic must exist or the broker must auto-create topics;\n * otherwise the send fails and the record stays uncommitted (nothing is lost).\n */\nexport type InvalidMessagePolicy =\n | 'dead-letter'\n | 'skip'\n | ((message: InvalidKafkaMessage) => void | Promise<void>)\n | { readonly deadLetterTopic: string | ((sourceTopic: string) => string) };\n\n/** `publish` did not get a broker ack within `publishTimeout`. The outbox retries it. */\nexport class PublishTimeoutError extends RelayBusError {\n override name = 'PublishTimeoutError';\n}\n\n/** A handler failure re-thrown to the Kafka client, stripped of anything that could make it fatal. */\nexport class HandlerFailedError extends RelayBusError {\n override name = 'HandlerFailedError';\n}\n\n/** Bounded in-process retries around the inbound handler (the bus's `receive`). */\nexport interface KafkaProcessingOptions {\n /** Attempts per delivery of a record before the error is handed to the client. Default 5. */\n readonly maxAttempts?: number;\n /** Delay before the second attempt; doubles each attempt. Default `'200ms'`. */\n readonly initialBackoff?: Duration;\n /** Upper bound of the delay between attempts. Default `'5s'`. */\n readonly maxBackoff?: Duration;\n /** Interval of the heartbeats sent while sleeping between attempts. Default `'1s'`. */\n readonly heartbeatInterval?: Duration;\n}\n\n/** Backoff of the consumer restart loop that runs after an unrecoverable crash. */\nexport interface KafkaRestartOptions {\n /** Delay before the second restart attempt; doubles each failure. Default `'1s'`. */\n readonly initialBackoff?: Duration;\n /** Upper bound of the delay between restart attempts. Default `'30s'`. */\n readonly maxBackoff?: Duration;\n}\n\nexport interface KafkaTransportOptions {\n /** A `kafkajs` `Kafka` or `@confluentinc/kafka-javascript` `KafkaJS.Kafka` instance. */\n readonly kafka: KafkaClientLike;\n /** Name referenced by routes and subscriptions. Default `'kafka'`. */\n readonly name?: string;\n /** Consumer group id. Required as soon as `subscribe` is used. */\n readonly groupId?: string;\n /**\n * Where a group without committed offsets starts. Default `true` (earliest),\n * so events published before the first start are not skipped.\n */\n readonly fromBeginning?: boolean;\n /** Producer `maxInFlightRequests`, 1 to 5. Default 1, which keeps retries from reordering a key. */\n readonly maxInFlightRequests?: number;\n /** Extra producer settings; `idempotent` and `maxInFlightRequests` always win. */\n readonly producerConfig?: object;\n /** Extra consumer settings; `groupId` always wins. */\n readonly consumerConfig?: object;\n readonly processing?: KafkaProcessingOptions;\n /** How long `subscribe` waits for the consumer group join before failing. Default `'30s'`. */\n readonly startupTimeout?: Duration;\n /** How long `publish` waits for the broker ack before rejecting. Default `'30s'`. */\n readonly publishTimeout?: Duration;\n readonly restart?: KafkaRestartOptions;\n /** Handling of records that cannot be processed for good. Default `'dead-letter'`. */\n readonly onInvalidMessage?: InvalidMessagePolicy;\n /** Default `console`. */\n readonly logger?: RelayBusLogger;\n}\n\nconst DEFAULTS = {\n name: 'kafka',\n maxInFlightRequests: 1,\n maxAttempts: 5,\n initialBackoff: '200ms',\n maxBackoff: '5s',\n startupTimeout: '30s',\n publishTimeout: '30s',\n heartbeatInterval: '1s',\n restartInitialBackoff: '1s',\n restartMaxBackoff: '30s',\n} as const;\n\ntype TransportState = 'idle' | 'subscribed' | 'closed';\n\ninterface Settings {\n readonly maxAttempts: number;\n readonly initialBackoffMs: number;\n readonly maxBackoffMs: number;\n readonly startupTimeoutMs: number;\n readonly publishTimeoutMs: number;\n readonly heartbeatIntervalMs: number;\n readonly restartInitialBackoffMs: number;\n readonly restartMaxBackoffMs: number;\n}\n\n/**\n * Kafka {@link Transport}. Events travel as CloudEvents binary-mode records\n * (`ce_*` headers, JSON value), so any CloudEvents-aware consumer can read them.\n *\n * Publishing: idempotent producer, `acks=-1`, resolves after the broker ack and\n * rejects with {@link PublishTimeoutError} after `publishTimeout`. A timed-out\n * send may still complete later; the outbox then retries it and the duplicate is\n * absorbed by the consumer's inbox dedup. The record key is the envelope key, so events sharing a key land on one\n * partition and keep their order; events without a key have no ordering.\n *\n * Subscribing: one consumer, one group, one `subscribe` call. `eachMessage`\n * awaits the handler; the client commits the offset only after it resolved. A\n * failing handler is retried in-process (bounded, with backoff) and then the\n * error is rethrown (as a {@link HandlerFailedError}, so the client never treats\n * it as fatal) and the client does not commit the offset and redelivers the\n * record. A record is therefore never skipped because of a handler failure; the\n * partition simply waits. Records that can never succeed (undecodable, or\n * rejected with a `NonRetryableError`) are dead-lettered instead. If the client\n * reports an unrecoverable crash anyway, the consumer run loop is restarted with\n * bounded backoff until the transport is closed.\n */\nexport class KafkaTransport implements Transport {\n readonly name: string;\n readonly #kafka: KafkaClientLike;\n readonly #groupId: string | undefined;\n readonly #fromBeginning: boolean;\n readonly #maxInFlightRequests: number;\n readonly #producerConfig: object;\n readonly #consumerConfig: object;\n readonly #invalidPolicy: InvalidMessagePolicy;\n readonly #logger: RelayBusLogger;\n readonly #settings: Settings;\n readonly #sleepers = new Set<() => void>();\n #state: TransportState = 'idle';\n #producer: Promise<KafkaProducerLike> | undefined;\n #consumer: KafkaConsumerLike | undefined;\n #groupJoined = false;\n #consuming = false;\n #producerConnected = false;\n #restartLoop: Promise<void> | undefined;\n readonly #stalledPartitions = new Set<string>();\n #startConsuming: (() => Promise<void>) | undefined;\n #joinWaiter: { resolve(): void; reject(error: unknown): void } | undefined;\n\n constructor(options: KafkaTransportOptions) {\n this.name = options.name ?? DEFAULTS.name;\n this.#kafka = options.kafka;\n this.#groupId = options.groupId;\n this.#fromBeginning = options.fromBeginning ?? true;\n this.#maxInFlightRequests = options.maxInFlightRequests ?? DEFAULTS.maxInFlightRequests;\n if (\n !Number.isInteger(this.#maxInFlightRequests) ||\n this.#maxInFlightRequests < 1 ||\n this.#maxInFlightRequests > 5\n ) {\n throw new ConfigurationError(\n `maxInFlightRequests must be an integer from 1 to 5, received ${this.#maxInFlightRequests}`,\n );\n }\n this.#producerConfig = options.producerConfig ?? {};\n this.#consumerConfig = options.consumerConfig ?? {};\n this.#invalidPolicy = options.onInvalidMessage ?? 'dead-letter';\n this.#logger = options.logger ?? console;\n this.#settings = resolveSettings(options);\n }\n\n /**\n * True while the consumer is joined to its group, not between a crash or\n * rebalance and the next join, and no partition is stalled on a record whose\n * handler keeps failing. Use it for readiness so a consumer that silently\n * stopped is noticed.\n */\n isConsuming(): boolean {\n return this.#state === 'subscribed' && this.#groupJoined && this.#stalledPartitions.size === 0;\n }\n\n /**\n * True once the producer is connected and, if the transport subscribed, the\n * consumer is consuming. False before `connect`, after `close` and while a\n * dead consumer is being restarted.\n */\n isReady(): boolean {\n if (this.#state === 'closed' || !this.#producerConnected) {\n return false;\n }\n return this.#state === 'idle' || this.isConsuming();\n }\n\n /** Connects the producer. Called by the bus on start; `publish` also connects on demand. */\n async connect(): Promise<void> {\n await this.#connectedProducer();\n }\n\n async publish(envelope: EventEnvelope, destination: string): Promise<void> {\n const producer = await this.#connectedProducer();\n const { key, value, headers } = encodeEnvelope(envelope);\n await this.#send(producer, {\n topic: destination,\n acks: -1,\n messages: [{ key, value, headers }],\n });\n }\n\n /**\n * Starts the consumer and resolves once it joined its group, so a start-up\n * that cannot consume fails loudly instead of looking healthy.\n *\n * @throws ConfigurationError when `groupId` is missing, `destinations` is empty\n * or the transport already subscribed (create one transport per subscription).\n */\n async subscribe(\n destinations: readonly string[],\n onMessage: TransportMessageHandler,\n ): Promise<void> {\n this.#assertCanSubscribe(destinations);\n this.#state = 'subscribed';\n const consumer = this.#kafka.consumer({ ...this.#consumerConfig, groupId: this.#groupId! });\n this.#consumer = consumer;\n this.#observeConsumer(consumer);\n const start = (): Promise<void> => this.#startConsumer(consumer, [...destinations], onMessage);\n this.#startConsuming = start;\n try {\n await start();\n } catch (error) {\n // A consumer left half-started would keep running (or retrying) with nobody watching it.\n await consumer.disconnect().catch(() => undefined);\n this.#groupJoined = false;\n this.#consumer = undefined;\n this.#state = 'idle';\n throw error;\n }\n this.#consuming = true;\n this.#logger.log(\n `[KafkaTransport](subscribe) Consuming | transport=${this.name} group=${this.#groupId} topics=${destinations.join(',')}`,\n );\n }\n\n async #startConsumer(\n consumer: KafkaConsumerLike,\n destinations: string[],\n onMessage: TransportMessageHandler,\n ): Promise<void> {\n await consumer.connect();\n await consumer.subscribe({ topics: destinations, fromBeginning: this.#fromBeginning });\n const joined = this.#waitForGroupJoin(consumer);\n try {\n await consumer.run({ eachMessage: (payload) => this.#handleMessage(payload, onMessage) });\n await joined.promise;\n } finally {\n joined.dispose();\n }\n }\n\n /** Stops consuming and disconnects the consumer and the producer. Safe to call twice. */\n async close(): Promise<void> {\n if (this.#state === 'closed') {\n return;\n }\n this.#state = 'closed';\n const pendingProducer = this.#producer;\n this.#groupJoined = false;\n this.#producerConnected = false;\n for (const wake of this.#sleepers) {\n wake();\n }\n this.#joinWaiter?.reject(new RelayBusError(`Transport '${this.name}' is closed`));\n await this.#restartLoop;\n const producer = await pendingProducer?.catch(() => undefined);\n const results = await Promise.allSettled([\n this.#consumer?.disconnect(),\n producer?.disconnect(),\n ]);\n const failure = results.find((result) => result.status === 'rejected');\n if (failure !== undefined) {\n throw failure.reason;\n }\n }\n\n #assertCanSubscribe(destinations: readonly string[]): void {\n if (this.#state === 'closed') {\n throw new RelayBusError(`Transport '${this.name}' is closed`);\n }\n if (this.#state === 'subscribed') {\n throw new ConfigurationError(\n `Transport '${this.name}' already subscribed; list every topic in one subscription or use one KafkaTransport per consumer group`,\n );\n }\n if (this.#groupId === undefined || this.#groupId.length === 0) {\n throw new ConfigurationError(`Transport '${this.name}' needs a groupId to subscribe`);\n }\n if (destinations.length === 0) {\n throw new ConfigurationError(`Transport '${this.name}' subscribed to no topics`);\n }\n for (const topic of destinations) {\n const deadLetterTopic = this.#deadLetterTopicFor(topic);\n if (deadLetterTopic !== undefined && destinations.includes(deadLetterTopic)) {\n throw new ConfigurationError(\n `Dead letter topic '${deadLetterTopic}' is also consumed, which would loop`,\n );\n }\n }\n }\n\n /** The dead-letter topic for records of `sourceTopic`, or undefined when the policy does not use one. */\n #deadLetterTopicFor(sourceTopic: string): string | undefined {\n const policy = this.#invalidPolicy;\n if (policy === 'dead-letter') {\n return `${sourceTopic}.dead`;\n }\n if (typeof policy === 'object') {\n const { deadLetterTopic } = policy;\n return typeof deadLetterTopic === 'function' ? deadLetterTopic(sourceTopic) : deadLetterTopic;\n }\n return undefined;\n }\n\n /** Sends with the publish timeout; the late outcome of a timed-out send is ignored. */\n async #send(producer: KafkaProducerLike, record: KafkaProducerRecord): Promise<void> {\n let timer: NodeJS.Timeout | undefined;\n const timeout = new Promise<never>((_resolve, reject) => {\n timer = setTimeout(() => {\n reject(\n new PublishTimeoutError(\n `Transport '${this.name}' got no broker ack for topic '${record.topic}' within ${this.#settings.publishTimeoutMs}ms`,\n ),\n );\n }, this.#settings.publishTimeoutMs);\n });\n const sending = producer.send(record);\n sending.catch(() => undefined);\n try {\n await Promise.race([sending, timeout]);\n } finally {\n clearTimeout(timer);\n }\n }\n\n #connectedProducer(): Promise<KafkaProducerLike> {\n if (this.#state === 'closed') {\n return Promise.reject(new RelayBusError(`Transport '${this.name}' is closed`));\n }\n this.#producer ??= this.#openProducer();\n return this.#producer;\n }\n\n async #openProducer(): Promise<KafkaProducerLike> {\n const producer = this.#kafka.producer({\n ...this.#producerConfig,\n idempotent: true,\n maxInFlightRequests: this.#maxInFlightRequests,\n });\n try {\n await producer.connect();\n } catch (error) {\n this.#producer = undefined;\n throw error;\n }\n this.#producerConnected = this.#state !== 'closed';\n return producer;\n }\n\n async #handleMessage(\n payload: KafkaEachMessagePayload,\n onMessage: TransportMessageHandler,\n ): Promise<void> {\n let envelope: EventEnvelope;\n try {\n envelope = decodeEnvelope(payload.message);\n } catch (error) {\n if (!(error instanceof InvalidKafkaMessageError)) {\n throw toHandlerFailure(error);\n }\n await this.#withRetries(payload, 'handleInvalid', () =>\n this.#handleInvalid(payload, error.message),\n );\n return;\n }\n await this.#withRetries(payload, 'deliver', async () => {\n try {\n await onMessage(envelope);\n } catch (error) {\n // The bus rejected the event for good; redelivering it would block the partition forever.\n if (!(error instanceof NonRetryableError)) {\n throw error;\n }\n await this.#handleInvalid(payload, error.message);\n }\n });\n }\n\n async #handleInvalid(payload: KafkaEachMessagePayload, reason: string): Promise<void> {\n const { topic, partition, message } = payload;\n const location = `topic=${topic} partition=${partition} offset=${message.offset}`;\n const policy = this.#invalidPolicy;\n const deadLetterTopic = this.#deadLetterTopicFor(topic);\n if (policy === 'skip') {\n this.#logger.error(\n `[KafkaTransport](handleInvalid) Skipping malformed message | ${location} reason=${reason}`,\n );\n } else if (typeof policy === 'function') {\n await policy({\n topic,\n partition,\n offset: message.offset,\n reason,\n key: message.key,\n value: message.value,\n });\n } else {\n const producer = await this.#connectedProducer();\n await this.#send(producer, {\n topic: deadLetterTopic!,\n acks: -1,\n messages: [\n {\n key: message.key === null ? null : Buffer.from(message.key),\n value: message.value === null ? null : Buffer.from(message.value),\n headers: {\n ...toOutgoingHeaders(message.headers),\n 'relaybus-invalid-reason': reason,\n 'relaybus-source-topic': topic,\n 'relaybus-source-partition': String(partition),\n 'relaybus-source-offset': message.offset,\n },\n },\n ],\n });\n this.#logger.error(\n `[KafkaTransport](handleInvalid) Dead-lettered malformed message | ${location} deadLetterTopic=${deadLetterTopic} reason=${reason}`,\n );\n }\n }\n\n /**\n * Runs `operation` up to `maxAttempts` times with exponential backoff. The\n * last error is rethrown so the client leaves the offset uncommitted and\n * redelivers the record; heartbeats between attempts keep the session alive.\n */\n async #withRetries(\n payload: KafkaEachMessagePayload,\n method: string,\n operation: () => Promise<void>,\n ): Promise<void> {\n const { maxAttempts, initialBackoffMs, maxBackoffMs } = this.#settings;\n const location = `topic=${payload.topic} partition=${payload.partition} offset=${payload.message.offset}`;\n const partitionKey = `${payload.topic}:${payload.partition}`;\n for (let attempt = 1; ; attempt += 1) {\n try {\n await operation();\n this.#stalledPartitions.delete(partitionKey);\n return;\n } catch (error) {\n const reason = toErrorInfo(error).message;\n if (attempt >= maxAttempts || this.#state === 'closed') {\n this.#stalledPartitions.add(partitionKey);\n this.#logger.error(\n `[KafkaTransport](${method}) Giving up for now, the record stays uncommitted and will be redelivered | ${location} attempts=${attempt} error=${reason}`,\n );\n throw toHandlerFailure(error);\n }\n this.#logger.warn(\n `[KafkaTransport](${method}) Attempt failed, retrying | ${location} attempt=${attempt} error=${reason}`,\n );\n await this.#sleepWithHeartbeats(\n Math.min(initialBackoffMs * 2 ** (attempt - 1), maxBackoffMs),\n payload,\n );\n }\n }\n }\n\n /** Sleeps in slices and heartbeats after each, so a long backoff never outlives the session timeout. */\n async #sleepWithHeartbeats(\n milliseconds: number,\n payload: KafkaEachMessagePayload,\n ): Promise<void> {\n let remaining = milliseconds;\n do {\n const slice = Math.min(remaining, this.#settings.heartbeatIntervalMs);\n await this.#sleep(slice);\n await payload.heartbeat();\n remaining -= slice;\n } while (remaining > 0 && this.#state !== 'closed');\n }\n\n #sleep(milliseconds: number): Promise<void> {\n return new Promise((resolve) => {\n const wake = (): void => {\n clearTimeout(timer);\n this.#sleepers.delete(wake);\n resolve();\n };\n const timer = setTimeout(wake, milliseconds);\n this.#sleepers.add(wake);\n });\n }\n\n /** Whether the client exposes the instrumentation needed to follow the group membership. */\n #tracksMembership(consumer: KafkaConsumerLike): boolean {\n return consumer.on !== undefined && consumer.events?.GROUP_JOIN !== undefined;\n }\n\n #observeConsumer(consumer: KafkaConsumerLike): void {\n if (!this.#tracksMembership(consumer)) {\n this.#groupJoined = true;\n return;\n }\n const names = consumer.events!;\n const listen = (\n name: string | undefined,\n listener: (event: KafkaConsumerEvent) => void,\n ): void => {\n if (name !== undefined) {\n consumer.on!(name, listener);\n }\n };\n listen(names.GROUP_JOIN, () => {\n this.#groupJoined = true;\n this.#joinWaiter?.resolve();\n this.#logger.log(`[KafkaTransport](observeConsumer) Joined group | group=${this.#groupId}`);\n });\n listen(names.REBALANCING, () => {\n this.#groupJoined = false;\n // The partition assignment is about to change; a stall is re-detected if it persists.\n this.#stalledPartitions.clear();\n this.#logger.warn(`[KafkaTransport](observeConsumer) Rebalancing | group=${this.#groupId}`);\n });\n listen(names.CRASH, (event) => this.#handleCrash(event));\n listen(names.STOP, () => {\n this.#groupJoined = false;\n });\n listen(names.DISCONNECT, () => {\n this.#groupJoined = false;\n });\n }\n\n #handleCrash(event: KafkaConsumerEvent): void {\n const { error, restart } = (event.payload ?? {}) as { error?: unknown; restart?: unknown };\n this.#groupJoined = false;\n this.#logger.error(\n `[KafkaTransport](handleCrash) Consumer crashed | group=${this.#groupId} restart=${String(restart)} error=${toErrorInfo(error).message}`,\n );\n this.#joinWaiter?.reject(error);\n if (restart === false && this.#consuming && this.#restartLoop === undefined) {\n this.#restartLoop = this.#restartConsumer().finally(() => {\n this.#restartLoop = undefined;\n });\n }\n }\n\n /**\n * The client gave up on the consumer (`restart=false`): reconnect it and run\n * again, with bounded backoff, until it joined or the transport closed.\n */\n async #restartConsumer(): Promise<void> {\n const { restartInitialBackoffMs, restartMaxBackoffMs } = this.#settings;\n const consumer = this.#consumer!;\n for (let attempt = 1; this.#state === 'subscribed'; attempt += 1) {\n await this.#sleep(\n Math.min(restartInitialBackoffMs * 2 ** (attempt - 1), restartMaxBackoffMs),\n );\n if (this.#state !== 'subscribed') {\n return;\n }\n await consumer.disconnect().catch(() => undefined);\n try {\n await this.#startConsuming!();\n this.#logger.log(\n `[KafkaTransport](restartConsumer) Consumer restarted | group=${this.#groupId} attempt=${attempt}`,\n );\n return;\n } catch (error) {\n this.#logger.error(\n `[KafkaTransport](restartConsumer) Restart failed, will retry | group=${this.#groupId} attempt=${attempt} error=${toErrorInfo(error).message}`,\n );\n }\n }\n }\n\n #waitForGroupJoin(consumer: KafkaConsumerLike): { promise: Promise<void>; dispose(): void } {\n if (!this.#tracksMembership(consumer)) {\n return { promise: Promise.resolve(), dispose: () => undefined };\n }\n let timer: NodeJS.Timeout | undefined;\n const promise = new Promise<void>((resolve, reject) => {\n this.#joinWaiter = { resolve, reject };\n timer = setTimeout(() => {\n reject(\n new RelayBusError(\n `Consumer of transport '${this.name}' did not join group '${this.#groupId}' within ${this.#settings.startupTimeoutMs}ms`,\n ),\n );\n }, this.#settings.startupTimeoutMs);\n });\n // The rejection may land while `run` is still pending; the caller awaits it afterwards.\n promise.catch(() => undefined);\n return {\n promise,\n dispose: () => {\n clearTimeout(timer);\n this.#joinWaiter = undefined;\n },\n };\n }\n}\n\nfunction resolveSettings(options: KafkaTransportOptions): Settings {\n const maxAttempts = options.processing?.maxAttempts ?? DEFAULTS.maxAttempts;\n if (!Number.isInteger(maxAttempts) || maxAttempts < 1) {\n throw new ConfigurationError(\n `processing.maxAttempts must be a positive integer, received ${maxAttempts}`,\n );\n }\n return {\n maxAttempts,\n initialBackoffMs: toMilliseconds(\n options.processing?.initialBackoff ?? DEFAULTS.initialBackoff,\n 'processing.initialBackoff',\n ),\n maxBackoffMs: toMilliseconds(\n options.processing?.maxBackoff ?? DEFAULTS.maxBackoff,\n 'processing.maxBackoff',\n ),\n startupTimeoutMs: toMilliseconds(\n options.startupTimeout ?? DEFAULTS.startupTimeout,\n 'startupTimeout',\n ),\n publishTimeoutMs: toMilliseconds(\n options.publishTimeout ?? DEFAULTS.publishTimeout,\n 'publishTimeout',\n ),\n heartbeatIntervalMs: Math.max(\n 1,\n toMilliseconds(\n options.processing?.heartbeatInterval ?? DEFAULTS.heartbeatInterval,\n 'processing.heartbeatInterval',\n ),\n ),\n restartInitialBackoffMs: toMilliseconds(\n options.restart?.initialBackoff ?? DEFAULTS.restartInitialBackoff,\n 'restart.initialBackoff',\n ),\n restartMaxBackoffMs: toMilliseconds(\n options.restart?.maxBackoff ?? DEFAULTS.restartMaxBackoff,\n 'restart.maxBackoff',\n ),\n };\n}\n\n/**\n * Wraps a failure in a fresh error before it goes back to the Kafka client.\n * kafkajs classifies errors by type and cause chain: a handler that throws a\n * `TypeError` would be marked unrecoverable and kill the consumer for good.\n * The wrapper carries the original name and message but no `cause`.\n */\nfunction toHandlerFailure(error: unknown): Error {\n const { name, message } = toErrorInfo(error);\n return new HandlerFailedError(`${name}: ${message}`);\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,77 @@
1
1
  {
2
2
  "name": "@relaybus/kafka",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "0.0.0",
4
+ "description": "Apache Kafka transport for relaybus: publish committed events to topics and consume them with idempotent inbox semantics.",
5
+ "license": "MIT",
6
+ "author": "Berkcan Şavur <berkcansavur@gmail.com>",
7
+ "homepage": "https://github.com/berkcansavur/relaybus#readme",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/berkcansavur/relaybus.git",
11
+ "directory": "packages/kafka"
12
+ },
13
+ "bugs": "https://github.com/berkcansavur/relaybus/issues",
14
+ "keywords": [
15
+ "relaybus",
16
+ "event-bus",
17
+ "outbox",
18
+ "kafka",
19
+ "kafkajs",
20
+ "confluent",
21
+ "transport"
22
+ ],
23
+ "type": "module",
24
+ "sideEffects": false,
25
+ "main": "./dist/index.cjs",
26
+ "module": "./dist/index.js",
27
+ "types": "./dist/index.d.ts",
28
+ "exports": {
29
+ ".": {
30
+ "import": {
31
+ "types": "./dist/index.d.ts",
32
+ "default": "./dist/index.js"
33
+ },
34
+ "require": {
35
+ "types": "./dist/index.d.cts",
36
+ "default": "./dist/index.cjs"
37
+ }
38
+ },
39
+ "./package.json": "./package.json"
40
+ },
41
+ "files": [
42
+ "dist",
43
+ "README.md",
44
+ "LICENSE"
45
+ ],
46
+ "engines": {
47
+ "node": ">=22.12.0"
48
+ },
49
+ "publishConfig": {
50
+ "access": "public",
51
+ "provenance": true
52
+ },
53
+ "peerDependencies": {
54
+ "kafkajs": "^2.2.4",
55
+ "@confluentinc/kafka-javascript": ">=1.0.0",
56
+ "@relaybus/core": "^0.0.0"
57
+ },
58
+ "peerDependenciesMeta": {
59
+ "kafkajs": {
60
+ "optional": true
61
+ },
62
+ "@confluentinc/kafka-javascript": {
63
+ "optional": true
64
+ }
65
+ },
66
+ "devDependencies": {
67
+ "kafkajs": "2.2.4",
68
+ "@testcontainers/kafka": "12.2.1",
69
+ "testcontainers": "12.2.1",
70
+ "@relaybus/core": "0.0.0",
71
+ "@relaybus/testing": "0.0.0"
72
+ },
73
+ "scripts": {
74
+ "build": "tsup",
75
+ "typecheck": "tsc -p tsconfig.build.json --noEmit"
76
+ }
6
77
  }