@relaybus/kafka 0.3.0 → 0.4.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/cloudevents-codec.ts","../src/inbound-decoders.ts","../src/codecs.ts","../src/kafka-transport.ts"],"names":["recordTimestamp","STRUCTURED_MEDIA_TYPE","SPEC_VERSION","assertEventType","NonRetryableError"],"mappings":"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","file":"index.js","sourcesContent":["import { NonRetryableError, RelayBusError } from '@relaybus/core';\n\n/** A Kafka record that cannot be turned into an {@link EventEnvelope}. Never retried. */\nexport class InvalidKafkaMessageError extends RelayBusError {\n override name = 'InvalidKafkaMessageError';\n override readonly code: string = 'RELAYBUS_KAFKA_INVALID_MESSAGE';\n}\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 override readonly code: string = 'RELAYBUS_KAFKA_UNENCODABLE_EVENT';\n}\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 override readonly code: string = 'RELAYBUS_KAFKA_PUBLISH_TIMEOUT';\n}\n\n/** The transport was closed: it no longer publishes or subscribes. */\nexport class TransportClosedError extends RelayBusError {\n override name = 'TransportClosedError';\n override readonly code: string = 'RELAYBUS_KAFKA_TRANSPORT_CLOSED';\n}\n\n/** The consumer did not join its group within `startupTimeout`. */\nexport class GroupJoinTimeoutError extends RelayBusError {\n override name = 'GroupJoinTimeoutError';\n override readonly code: string = 'RELAYBUS_KAFKA_GROUP_JOIN_TIMEOUT';\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 override readonly code: string = 'RELAYBUS_KAFKA_HANDLER_FAILED';\n}\n","import { assertEventType, type EventEnvelope } from '@relaybus/core';\nimport { writeStructuredCloudEvent } from '@relaybus/core/internal';\nimport { InvalidKafkaMessageError, UnencodableEventError } from './errors.js';\nimport type { KafkaBytes, KafkaIncomingHeaders, KafkaOutgoingHeaders } from './kafka-client.js';\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';\n/** Name of the Kafka header that carries the media type of the record value. */\nexport const CONTENT_TYPE = 'content-type';\nconst JSON_MEDIA_TYPE = 'application/json';\nconst STRUCTURED_MEDIA_TYPE = 'application/cloudevents+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\n/** RFC 3339 years have four digits. */\nconst MAXIMUM_RFC3339_YEAR = 9999;\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\n/**\n * Encodes an envelope as a CloudEvents Kafka structured-mode record: the value\n * is one JSON document with the attributes and `data` (the payload), the\n * content type is `application/cloudevents+json`, the record key is the event\n * key. Event headers travel as record headers, escaped as in binary mode.\n */\nexport function encodeStructuredEnvelope(envelope: EventEnvelope): EncodedMessage {\n const value = writeStructuredCloudEvent(envelope, {\n time: formatTime(envelope),\n data: serializePayload(envelope),\n });\n const entries: [string, string][] = Object.entries(envelope.headers).map(\n ([name, headerValue]) => [escapeUserHeaderName(name), headerValue],\n );\n entries.push([CONTENT_TYPE, STRUCTURED_MEDIA_TYPE]);\n return { key: envelope.key, value, headers: Object.fromEntries(entries) };\n}\n\n/** The payload as JSON text; refuses a payload JSON cannot represent. */\nexport function serializePayload(envelope: EventEnvelope): string {\n return serializeJson(envelope, envelope.payload);\n}\n\n/** `value` (the payload or a body holding it) as JSON text, refusing what JSON cannot represent. */\nexport function serializeJson(envelope: EventEnvelope, value: unknown): string {\n let text: string | undefined;\n try {\n text = JSON.stringify(value);\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 (text === 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 text;\n}\n\n/** The occurredAt as RFC 3339 text; refuses an invalid date or a year outside 0..9999. */\nexport function formatTime(envelope: EventEnvelope): string {\n const year = envelope.occurredAt.getUTCFullYear();\n if (Number.isNaN(year) || year < 0 || year > MAXIMUM_RFC3339_YEAR) {\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\n/** Creates the error thrown for every malformed record. */\nexport function 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\n/** Reads headers strictly: a repeated header or a protocol header that is not UTF-8 is invalid. */\nexport function 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(\n name,\n decodeText(raw, { strict: PROTOCOL_HEADERS.has(name), label: `Header '${name}'` }),\n );\n }\n return headers;\n}\n\n/** Decodes header or value bytes as UTF-8; `strict` rejects invalid sequences. */\nexport function decodeText(\n raw: KafkaBytes | string,\n { strict, label }: { readonly strict: boolean; readonly label: string },\n): 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 time = readRecordTimestamp(recordTimestamp);\n if (time === undefined) {\n throw invalid(`${HEADER.time} is missing and the record has no usable timestamp`);\n }\n return time;\n}\n\n/** The record timestamp (epoch milliseconds in a string) as a date, or undefined when unusable. */\nexport function readRecordTimestamp(recordTimestamp: string | undefined): Date | undefined {\n const time = new Date(Number(recordTimestamp));\n return recordTimestamp === undefined || recordTimestamp === '' || Number.isNaN(time.getTime())\n ? undefined\n : time;\n}\n\n/** Parses an RFC 3339 timestamp; anything else is invalid. `label` names the attribute in the error. */\nexport function parseTime(text: string, label: string = HEADER.time): Date {\n const time = new Date(text);\n if (!RFC3339_PATTERN.test(text) || Number.isNaN(time.getTime())) {\n throw invalid(`${label} is not an RFC 3339 timestamp: '${text}'`);\n }\n return time;\n}\n\n/** Parses the record value as UTF-8 JSON; a missing value or invalid JSON is invalid. */\nexport function parsePayload(value: KafkaBytes | null): unknown {\n if (value === null) {\n throw invalid('Message has no value');\n }\n const text = decodeText(value, { strict: true, label: '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 = readRecordKey(recordKey);\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\n/** The record key as UTF-8 text, or null when the record has none. Invalid UTF-8 is invalid. */\nexport function readRecordKey(recordKey: KafkaBytes | null): string | null {\n return recordKey === null ? null : decodeText(recordKey, { strict: true, label: 'Message key' });\n}\n\n/** Headers that are not CloudEvents attributes, with escaped names restored. */\nexport function 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 { assertEventType, type EventEnvelope, type EventHeaders } from '@relaybus/core';\nimport { createCloudEventReaders, isJsonObject, mediaTypeOf } from '@relaybus/core/internal';\nimport {\n CONTENT_TYPE,\n collectUserHeaders,\n decodeEnvelope,\n invalid,\n parsePayload,\n parseTime,\n readHeaders,\n readRecordKey,\n readRecordTimestamp,\n type DecodableMessage,\n} from './cloudevents-codec.js';\nimport type { KafkaBytes, KafkaIncomingHeaders } from './kafka-client.js';\n\nconst { optionalAttribute, requiredAttribute, assertValidType, assertJsonDataContentType } =\n createCloudEventReaders(invalid);\n\n/** A consumed record as handed to a {@link KafkaMessageDecoder}. */\nexport interface KafkaInboundRecord extends DecodableMessage {\n readonly topic: string;\n readonly partition: number;\n readonly offset: string;\n}\n\n/**\n * The event a decoder extracted from a record. `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 topic, `key` with the record key (UTF-8),\n * `headers` with none, `correlationId` and `causationId` with null, and\n * `occurredAt` with the record timestamp.\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 record into an event, for topics written by producers that\n * do not use relaybus. Must be synchronous and free of side effects: it runs\n * again on every redelivery, so the same record must always give the same\n * event, above all the same `id`, which is what the inbox deduplicates on.\n *\n * Anything it throws marks the record as malformed: it goes to the transport's\n * `onInvalidMessage` policy (dead-letter by default) and the consumer moves on.\n * An event the bus then rejects (empty id, invalid type or time) is\n * dead-lettered the same way.\n */\nexport type KafkaMessageDecoder = (record: KafkaInboundRecord) => DecodedEvent;\n\n/** A plain JSON record, decoded for the extractor options of {@link plainJsonDecoder}. */\nexport interface PlainJsonRecord {\n readonly topic: string;\n readonly partition: number;\n readonly offset: string;\n /**\n * The record key as UTF-8 text, base64 when its bytes are not valid UTF-8\n * (for example a key written by Java's `LongSerializer`), null when absent.\n */\n readonly key: string | null;\n /**\n * Every record header as text: the last value of a repeated header; a value\n * that is not valid UTF-8 is left out.\n */\n readonly headers: EventHeaders;\n /** The record value parsed as JSON. */\n readonly payload: unknown;\n /** Record timestamp in epoch milliseconds. */\n readonly timestamp: string | undefined;\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 topic that carries one\n * kind of event, or an extractor such as `fromHeader('event-type')` or\n * `fromPayloadField('type')`. Required; a record without a type is invalid.\n */\n readonly type: string | ((record: PlainJsonRecord) => string | undefined);\n /**\n * Event id the inbox deduplicates on, for example `fromHeader('message-id')`.\n * Default, and fallback when the extractor finds none:\n * `kafka:<topic>:<partition>:<offset>`, which is stable across redeliveries\n * of the record. Prefer an id set by the producer when it may send the same\n * event twice: two sends are two offsets, so only a producer id dedupes them.\n */\n readonly id?: (record: PlainJsonRecord) => string | undefined;\n /** Ordering key. Default: the record key. When given, its result is final (undefined means no key). */\n readonly key?: (record: PlainJsonRecord) => string | null | undefined;\n /** Logical name of the producer. Default: the topic. */\n readonly source?: string | ((record: PlainJsonRecord) => string | undefined);\n /** When the event happened. Default: the record timestamp. */\n readonly occurredAt?: (record: PlainJsonRecord) => Date | undefined;\n}\n\nconst STRUCTURED_MEDIA_TYPE = 'application/cloudevents+json';\n/** Refuses invalid UTF-8 and keeps a leading BOM, so different header bytes never decode equal. */\nconst exactUtf8 = new TextDecoder('utf-8', { fatal: true, ignoreBOM: true });\nconst SPEC_VERSION = '1.0';\nconst SPEC_VERSION_HEADER = 'ce_specversion';\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 record in either content mode of the Kafka\n * protocol binding:\n * - structured (`content-type: application/cloudevents+json`): the value is\n * a JSON object with `specversion`, `id`, `type`, `source` and optionally\n * `time`, `subject` (the key, else the record key), `data` (the payload,\n * null when absent) and a JSON `datacontenttype`. `data_base64` is refused,\n * because relaybus payloads are JSON. Extension attributes with string\n * values (`traceparent`, ...) become event headers, as do the record\n * headers; `correlationid` and `causationid` fill their envelope fields.\n * - binary (anything else): exactly {@link decodeEnvelope}, the default decoder.\n *\n * @throws InvalidKafkaMessageError for a record that is neither.\n */\nexport function decodeCloudEvent(record: DecodableMessage): EventEnvelope {\n const headers = readHeaders(record.headers);\n if (mediaTypeOf(headers.get(CONTENT_TYPE)) !== STRUCTURED_MEDIA_TYPE) {\n return decodeEnvelope(record);\n }\n const body = parsePayload(record.value);\n if (!isJsonObject(body)) {\n throw invalid('A structured CloudEvent must be a JSON object');\n }\n if (body['specversion'] !== SPEC_VERSION) {\n throw invalid(`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 invalid('data_base64 is not supported: relaybus payloads are JSON, send them as data');\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') ?? readRecordKey(record.key),\n payload: Object.hasOwn(body, 'data') ? body['data'] : null,\n headers: { ...collectUserHeaders(headers), ...extensionAttributes(body) },\n correlationId: optionalAttribute(body, 'correlationid') ?? null,\n causationId: optionalAttribute(body, 'causationid') ?? null,\n occurredAt: time === undefined ? requireRecordTimestamp(record) : parseTime(time, 'time'),\n };\n}\n\n/**\n * Creates a decoder for records whose value is plain JSON, as written by a\n * service that does not use relaybus (a plain kafkajs producer, Spring Kafka's\n * `JsonSerializer`, a Go service): the value becomes the payload, the record\n * headers become event headers, and the options say where the event type and\n * id come from.\n *\n * A record that is a CloudEvent anyway (a `ce_specversion` header, or a\n * structured `application/cloudevents+json` value) is decoded with\n * {@link decodeCloudEvent} instead, so relaybus and foreign producers can share\n * a topic. A missing or non-JSON value, a missing or invalid type, and an\n * extractor returning anything but a string are invalid.\n *\n * ```ts\n * new KafkaTransport({\n * kafka,\n * groupId: 'billing',\n * decode: plainJsonDecoder({ type: fromHeader('event-type'), id: fromHeader('message-id') }),\n * });\n * ```\n *\n * @throws ConfigurationError when a fixed `type` is not a valid event type.\n */\nexport function plainJsonDecoder(options: PlainJsonDecoderOptions): KafkaMessageDecoder {\n if (typeof options.type === 'string') {\n assertEventType(options.type);\n }\n return (record) => {\n const headers = readHeadersLeniently(record.headers);\n if (\n record.headers?.[SPEC_VERSION_HEADER] !== undefined ||\n mediaTypeOf(headers[CONTENT_TYPE]) === STRUCTURED_MEDIA_TYPE\n ) {\n return decodeCloudEvent(record);\n }\n const plain: PlainJsonRecord = {\n topic: record.topic,\n partition: record.partition,\n offset: record.offset,\n key: readKeyLeniently(record.key),\n headers,\n payload: parsePayload(record.value),\n timestamp: record.timestamp,\n };\n const type = resolveText(options.type, { record: plain, name: 'type' });\n if (type === undefined) {\n throw invalid('Record has no event type: the type option found none');\n }\n assertValidType(type, 'The event type');\n return {\n id:\n resolveText(options.id, { record: plain, name: 'id' }) ??\n `kafka:${record.topic}:${record.partition}:${record.offset}`,\n type,\n source: resolveText(options.source, { record: plain, name: 'source' }) ?? record.topic,\n key:\n options.key === undefined\n ? plain.key\n : (resolveText(options.key, { record: plain, name: 'key' }) ?? null),\n payload: plain.payload,\n headers,\n correlationId: null,\n causationId: null,\n occurredAt: resolveOccurredAt(options.occurredAt, { plain, record }),\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, which would otherwise surface as\n * a retried `TypeError` instead of a malformed record.\n */\nexport function completeDecodedEvent(decoded: unknown, record: KafkaInboundRecord): EventEnvelope {\n if (typeof decoded !== 'object' || decoded === null) {\n throw invalid('The decoder must return an event object synchronously');\n }\n if ('then' in decoded) {\n observeRejection(decoded);\n throw invalid('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 ?? record.topic,\n key: event.key === undefined ? readRecordKey(record.key) : event.key,\n payload: event.payload,\n headers: event.headers ?? {},\n correlationId: event.correlationId ?? null,\n causationId: event.causationId ?? null,\n occurredAt: event.occurredAt ?? requireRecordTimestamp(record),\n };\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\nfunction requireRecordTimestamp(record: DecodableMessage): Date {\n const time = readRecordTimestamp(record.timestamp);\n if (time === undefined) {\n throw invalid('The event has no time and the record has no usable timestamp');\n }\n return time;\n}\n\n/**\n * Headers of a foreign record, never rejected: the last value of a repeated\n * header wins, and a value that is not valid UTF-8 is left out, because\n * replacing its bytes could make two different ids or types look equal.\n */\nexport function readHeadersLeniently(incoming: KafkaIncomingHeaders | undefined): EventHeaders {\n const entries: [string, string][] = [];\n for (const [name, raw] of Object.entries(incoming ?? {})) {\n const value = Array.isArray(raw)\n ? (raw as (KafkaBytes | string)[]).at(-1)\n : (raw as KafkaBytes | string | undefined);\n const text = value === undefined ? undefined : decodeUtf8OrUndefined(value);\n if (text !== undefined) {\n entries.push([name, text]);\n }\n }\n return Object.fromEntries(entries);\n}\n\nfunction decodeUtf8OrUndefined(value: KafkaBytes | string): string | undefined {\n if (typeof value === 'string') {\n return value;\n }\n try {\n return exactUtf8.decode(value);\n } catch {\n return undefined;\n }\n}\n\nfunction readKeyLeniently(key: KafkaBytes | null): string | null {\n if (key === null) {\n return null;\n }\n try {\n return readRecordKey(key);\n } catch {\n return Buffer.from(key).toString('base64');\n }\n}\n\nfunction resolveText<TValue extends string | null>(\n option: TValue | ((record: PlainJsonRecord) => TValue | undefined) | undefined,\n { record, name }: { readonly record: PlainJsonRecord; readonly name: string },\n): string | undefined {\n const value: unknown = typeof option === 'function' ? option(record) : option;\n if (value === undefined || value === null) {\n return undefined;\n }\n if (typeof value !== 'string') {\n observeRejection(value);\n throw invalid(`The ${name} option returned ${typeof value}, expected a string`);\n }\n return value.length === 0 ? undefined : value;\n}\n\nfunction resolveOccurredAt(\n option: PlainJsonDecoderOptions['occurredAt'],\n { plain, record }: { readonly plain: PlainJsonRecord; readonly record: KafkaInboundRecord },\n): Date {\n const value: unknown = option?.(plain);\n if (value === undefined) {\n return requireRecordTimestamp(record);\n }\n if (!(value instanceof Date) || Number.isNaN(value.getTime())) {\n observeRejection(value);\n throw invalid('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 {\n CONTENT_TYPE,\n decodeEnvelope,\n encodeEnvelope,\n encodeStructuredEnvelope,\n formatTime,\n invalid,\n parsePayload,\n serializeJson,\n} from './cloudevents-codec.js';\nimport { UnencodableEventError } from './errors.js';\nimport {\n decodeCloudEvent,\n readHeadersLeniently,\n type KafkaMessageDecoder,\n} from './inbound-decoders.js';\nimport type { KafkaOutgoingMessage } from './kafka-client.js';\n\n/** The record a codec produces for one event. `timestamp` is epoch milliseconds in a string. */\nexport type KafkaEncodedRecord = KafkaOutgoingMessage & { readonly timestamp?: string };\n\n/**\n * The wire format of a {@link KafkaTransport}: how an event becomes a record\n * (`encode`, on publish) and a consumed record becomes an event (`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 UnencodableEventError}. What `decode` throws marks the record\n * as malformed: it goes to `onInvalidMessage` (dead-letter by default) and the\n * consumer moves on. See {@link KafkaMessageDecoder} for the decode contract.\n */\nexport interface KafkaCodec {\n readonly encode: (envelope: EventEnvelope) => KafkaEncodedRecord;\n readonly decode: KafkaMessageDecoder;\n}\n\n/**\n * CloudEvents 1.0 binary content mode, the default: the value is the JSON\n * payload, the attributes travel as `ce_*` headers ({@link encodeEnvelope}).\n * Decoding is strict: any other record is malformed ({@link decodeEnvelope}).\n */\nexport const cloudEventsBinary: KafkaCodec = Object.freeze({\n encode: encodeEnvelope,\n decode: decodeEnvelope,\n});\n\n/**\n * CloudEvents 1.0 structured content mode: the value is one\n * `application/cloudevents+json` document with the attributes and `data`.\n * Decoding accepts structured and binary mode ({@link decodeCloudEvent}), so a\n * topic can move from one to the other while both are in flight.\n */\nexport const cloudEventsStructured: KafkaCodec = 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 `'record-position'`: a consumed\n * record gets `kafka:<topic>:<partition>:<offset>`, stable across redeliveries\n * but different for two sends of one event. Records relaybus writes carry the\n * event id in a `relaybus-event-id` header, which wins on read, so an outbox\n * retry that sends an event twice is still deduplicated.\n */\nexport type KafkaJsonEnvelopeMapping = JsonEnvelopeMapping<'record-position'>;\n\nconst RECORD_POSITION = 'record-position';\n/** Carries the event id of a record relaybus wrote under `'record-position'`. */\nconst EVENT_ID_HEADER = 'relaybus-event-id';\nconst DEFAULT_CONTENT_TYPE = 'application/json';\n\n/**\n * A JSON wire format declared by a mapping, in both directions: for topics\n * shared with services that wrap events in their own envelope\n * (`{ \"eventName\": ..., \"data\": {...} }`, MassTransit) or send the bare\n * payload. The record key is always the event key; when `occurredAt` is not\n * mapped, the record timestamp carries it. Event headers that are message\n * headers are written as they are, so a name the mapping uses for another\n * field is refused with {@link UnencodableEventError}, as are `content-type`\n * and `relaybus-event-id`.\n *\n * ```ts\n * codec: jsonEnvelope({\n * type: { body: 'eventName' },\n * id: { body: 'messageId' },\n * payload: { body: 'data' },\n * correlationId: { body: 'meta.correlationId' },\n * })\n * ```\n *\n * @throws ConfigurationError for an incomplete or self-overlapping mapping.\n */\nexport function jsonEnvelope(mapping: KafkaJsonEnvelopeMapping): KafkaCodec {\n const format = createJsonEnvelopeFormat(mapping, {\n transportIds: [RECORD_POSITION],\n failures: { invalid, unencodable: (reason) => new UnencodableEventError(reason) },\n });\n const contentType = mapping.contentType ?? DEFAULT_CONTENT_TYPE;\n const stampsTime = mapping.occurredAt === undefined;\n const ownHeaders = (envelope: EventEnvelope): Record<string, string> =>\n mapping.id === RECORD_POSITION\n ? { [CONTENT_TYPE]: contentType, [EVENT_ID_HEADER]: envelope.id }\n : { [CONTENT_TYPE]: contentType };\n return {\n encode: (envelope) => {\n assertRepresentable(envelope);\n const { body, headers } = format.write(envelope);\n const taken = [CONTENT_TYPE, EVENT_ID_HEADER].find((name) => Object.hasOwn(headers, name));\n if (taken !== undefined) {\n throw new UnencodableEventError(\n `Event ${envelope.id} has a header '${taken}', which the codec writes itself`,\n );\n }\n return {\n key: envelope.key,\n value: serializeJson(envelope, body),\n headers: { ...headers, ...ownHeaders(envelope) },\n ...(stampsTime ? { timestamp: recordTimestamp(envelope) } : {}),\n };\n },\n decode: (record) => {\n const { [EVENT_ID_HEADER]: eventId, ...headers } = withoutContentType(\n readHeadersLeniently(record.headers),\n );\n const fields = format.read({ body: parsePayload(record.value), headers });\n return {\n ...fields,\n id:\n fields.id ??\n (eventId === undefined || eventId === ''\n ? `kafka:${record.topic}:${record.partition}:${record.offset}`\n : eventId),\n };\n },\n };\n}\n\nfunction withoutContentType(headers: Readonly<Record<string, string>>): Record<string, string> {\n return Object.fromEntries(Object.entries(headers).filter(([name]) => name !== CONTENT_TYPE));\n}\n\n/** A payload JSON would drop from the body instead of refusing; nested ones fail when serialized. */\nfunction assertRepresentable(envelope: EventEnvelope): void {\n const kind = typeof envelope.payload;\n if (kind === 'undefined' || kind === 'function' || kind === 'symbol') {\n throw new UnencodableEventError(\n `Event ${envelope.id} has a payload that JSON cannot represent (undefined, a function or a symbol)`,\n );\n }\n}\n\n/** The occurredAt as the record timestamp, epoch milliseconds; refuses an invalid date. */\nfunction recordTimestamp(envelope: EventEnvelope): string {\n formatTime(envelope);\n return String(envelope.occurredAt.getTime());\n}\n","import {\n ConfigurationError,\n systemClock,\n NonRetryableError,\n toErrorInfo,\n toMilliseconds,\n type Duration,\n type EventEnvelope,\n type RelayBusLogger,\n type Transport,\n type TransportMessageHandler,\n type TransportSubscriptionHooks,\n} from '@relaybus/core';\nimport { assertPositiveInteger, schedule, type CancelTimer } from '@relaybus/core/internal';\nimport { decodeEnvelope, encodeEnvelope, toOutgoingHeaders } from './cloudevents-codec.js';\nimport { cloudEventsBinary, type KafkaCodec } from './codecs.js';\nimport {\n GroupJoinTimeoutError,\n HandlerFailedError,\n InvalidKafkaMessageError,\n PublishTimeoutError,\n TransportClosedError,\n} from './errors.js';\nimport { completeDecodedEvent, type KafkaMessageDecoder } from './inbound-decoders.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/** 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 /**\n * The wire format, both ways: how events become records and consumed records\n * become events. Default {@link cloudEventsBinary}: CloudEvents binary mode,\n * strict on read, so any other record is malformed and goes to\n * `onInvalidMessage`. {@link cloudEventsStructured} writes structured mode\n * and reads both, {@link jsonEnvelope} maps a JSON format of your own (an\n * envelope with the payload inside, or the bare payload), and an object with\n * `encode` and `decode` can do anything else. Whatever a non-default codec's\n * `decode` throws marks the record as malformed, never crashes the consumer.\n */\n readonly codec?: KafkaCodec;\n /**\n * How consumed records 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?: KafkaMessageDecoder;\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 * The `codec` option changes the wire format, for example to read and write\n * the JSON format of services that do not use relaybus.\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 system = 'kafka';\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 #codec: KafkaCodec;\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 = assertMaxInFlightRequests(\n options.maxInFlightRequests ?? DEFAULTS.maxInFlightRequests,\n );\n this.#producerConfig = options.producerConfig ?? {};\n this.#consumerConfig = options.consumerConfig ?? {};\n this.#invalidPolicy = options.onInvalidMessage ?? 'dead-letter';\n this.#codec = resolveCodec(options);\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 await this.#send(producer, {\n topic: destination,\n acks: -1,\n messages: [this.#codec.encode(envelope)],\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 // 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 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> =>\n this.#startConsumer(consumer, { destinations: [...destinations], onMessage, hooks });\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 {\n destinations,\n onMessage,\n hooks,\n }: {\n readonly destinations: string[];\n readonly onMessage: TransportMessageHandler;\n readonly hooks: TransportSubscriptionHooks | undefined;\n },\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({\n eachMessage: (payload) => this.#handleMessage(payload, { onMessage, hooks }),\n });\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 TransportClosedError(`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 TransportClosedError(`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 cancel: CancelTimer | undefined;\n const timeout = new Promise<never>((_resolve, reject) => {\n cancel = schedule(systemClock, {\n run: () => {\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 },\n delayMs: this.#settings.publishTimeoutMs,\n });\n });\n const sending = producer.send(record);\n sending.catch(() => undefined);\n try {\n await Promise.race([sending, timeout]);\n } finally {\n cancel?.();\n }\n }\n\n #connectedProducer(): Promise<KafkaProducerLike> {\n if (this.#state === 'closed') {\n return Promise.reject(new TransportClosedError(`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 {\n onMessage,\n hooks,\n }: {\n onMessage: TransportMessageHandler;\n hooks: TransportSubscriptionHooks | undefined;\n },\n ): Promise<void> {\n let envelope: EventEnvelope;\n try {\n envelope = this.#decodeRecord(payload);\n } catch (error) {\n // The default codec throws only InvalidKafkaMessageError for bad input; anything else is a bug.\n if (this.#codec === cloudEventsBinary && !(error instanceof InvalidKafkaMessageError)) {\n throw toHandlerFailure(error);\n }\n hooks?.onInvalidMessage({ destination: payload.topic, error });\n await this.#withRetries(payload, {\n method: 'handleInvalid',\n operation: () => this.#handleInvalid(payload, error),\n });\n return;\n }\n await this.#withRetries(payload, {\n method: 'deliver',\n operation: async () => {\n try {\n await onMessage(envelope, { destination: payload.topic });\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);\n }\n },\n });\n }\n\n #decodeRecord({ topic, partition, message }: KafkaEachMessagePayload): EventEnvelope {\n if (this.#codec === cloudEventsBinary) {\n return decodeEnvelope(message);\n }\n const record = {\n topic,\n partition,\n offset: message.offset,\n key: message.key,\n value: message.value,\n headers: message.headers,\n timestamp: message.timestamp,\n };\n return completeDecodedEvent(this.#codec.decode(record), record);\n }\n\n async #handleInvalid(payload: KafkaEachMessagePayload, error: unknown): Promise<void> {\n const { topic, partition, message } = payload;\n const { message: reason, name, code } = toErrorInfo(error);\n const location = `topic=${topic} partition=${partition} offset=${message.offset}`;\n const errorFields = `errorName=${name}${code === undefined ? '' : ` code=${code}`}`;\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} ${errorFields}`,\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 headers: Record<string, Buffer | string | (Buffer | string)[]> = {\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 'relaybus-error-name': name,\n };\n if (code === undefined) {\n delete headers['relaybus-error-code'];\n } else {\n headers['relaybus-error-code'] = code;\n }\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 },\n ],\n });\n this.#logger.error(\n `[KafkaTransport](handleInvalid) Dead-lettered malformed message | ${location} deadLetterTopic=${deadLetterTopic} reason=${reason} ${errorFields}`,\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, operation }: { readonly method: string; readonly 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](withRetries) Giving up for now, the record stays uncommitted and will be redelivered | operation=${method} ${location} attempts=${attempt} error=${reason}`,\n );\n throw toHandlerFailure(error);\n }\n this.#logger.warn(\n `[KafkaTransport](withRetries) Attempt failed, retrying | operation=${method} ${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 cancel();\n this.#sleepers.delete(wake);\n resolve();\n };\n const cancel = schedule(systemClock, { run: wake, delayMs: 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 cancel: CancelTimer | undefined;\n const promise = new Promise<void>((resolve, reject) => {\n this.#joinWaiter = { resolve, reject };\n cancel = schedule(systemClock, {\n run: () => {\n reject(\n new GroupJoinTimeoutError(\n `Consumer of transport '${this.name}' did not join group '${this.#groupId}' within ${this.#settings.startupTimeoutMs}ms`,\n ),\n );\n },\n delayMs: this.#settings.startupTimeoutMs,\n });\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 cancel?.();\n this.#joinWaiter = undefined;\n },\n };\n }\n}\n\n/** The codec of the options; the deprecated `decode` pairs with the default encoding. */\nfunction resolveCodec({ codec, decode }: KafkaTransportOptions): KafkaCodec {\n if (decode === undefined) {\n return codec ?? cloudEventsBinary;\n }\n if (codec !== undefined) {\n throw new ConfigurationError(\"Give 'codec' or the deprecated 'decode', not both\");\n }\n return { encode: encodeEnvelope, decode };\n}\n\nfunction resolveSettings(options: KafkaTransportOptions): Settings {\n const processing: KafkaProcessingOptions = options.processing ?? {};\n const maxAttempts = assertPositiveInteger(\n processing.maxAttempts ?? DEFAULTS.maxAttempts,\n 'processing.maxAttempts',\n );\n return {\n maxAttempts,\n initialBackoffMs: toMilliseconds(\n processing.initialBackoff ?? DEFAULTS.initialBackoff,\n 'processing.initialBackoff',\n ),\n maxBackoffMs: toMilliseconds(\n 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 processing.heartbeatInterval ?? DEFAULTS.heartbeatInterval,\n 'processing.heartbeatInterval',\n ),\n ),\n ...resolveRestartSettings(options.restart ?? {}),\n };\n}\n\nfunction resolveRestartSettings(\n restart: KafkaRestartOptions,\n): Pick<Settings, 'restartInitialBackoffMs' | 'restartMaxBackoffMs'> {\n return {\n restartInitialBackoffMs: toMilliseconds(\n restart.initialBackoff ?? DEFAULTS.restartInitialBackoff,\n 'restart.initialBackoff',\n ),\n restartMaxBackoffMs: toMilliseconds(\n restart.maxBackoff ?? DEFAULTS.restartMaxBackoff,\n 'restart.maxBackoff',\n ),\n };\n}\n\n/** Largest `maxInFlightRequests`. */\nconst MAXIMUM_IN_FLIGHT_REQUESTS = 5;\n\n/** Returns `value` when it is an integer from 1 to 5. */\nfunction assertMaxInFlightRequests(value: number): number {\n if (!Number.isInteger(value) || value < 1 || value > MAXIMUM_IN_FLIGHT_REQUESTS) {\n throw new ConfigurationError(\n `maxInFlightRequests must be an integer from 1 to 5, received ${value}`,\n );\n }\n return value;\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"]}
1
+ {"version":3,"sources":["../src/errors.ts","../src/cloudevents-codec.ts","../src/inbound-decoders.ts","../src/codecs.ts","../src/kafka-group-join.ts","../src/kafka-producer-session.ts","../src/kafka-client-dialects.ts","../src/kafka-settings.ts","../src/kafka-subscription-rules.ts","../src/kafka-records.ts","../src/wakeable-sleeps.ts","../src/kafka-transport.ts"],"names":["recordTimestamp","STRUCTURED_MEDIA_TYPE","SPEC_VERSION","assertEventType","schedule","systemClock","ConfigurationError","NonRetryableError","toErrorInfo"],"mappings":"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","file":"index.js","sourcesContent":["import { NonRetryableError, RelayBusError } from '@relaybus/core';\n\n/** A Kafka record that cannot be turned into an {@link EventEnvelope}. Never retried. */\nexport class InvalidKafkaMessageError extends RelayBusError {\n override name = 'InvalidKafkaMessageError';\n override readonly code: string = 'RELAYBUS_KAFKA_INVALID_MESSAGE';\n}\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 override readonly code: string = 'RELAYBUS_KAFKA_UNENCODABLE_EVENT';\n}\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 override readonly code: string = 'RELAYBUS_KAFKA_PUBLISH_TIMEOUT';\n}\n\n/** The transport was closed: it no longer publishes or subscribes. */\nexport class TransportClosedError extends RelayBusError {\n override name = 'TransportClosedError';\n override readonly code: string = 'RELAYBUS_KAFKA_TRANSPORT_CLOSED';\n}\n\n/** The consumer did not join its group within `startupTimeout`. */\nexport class GroupJoinTimeoutError extends RelayBusError {\n override name = 'GroupJoinTimeoutError';\n override readonly code: string = 'RELAYBUS_KAFKA_GROUP_JOIN_TIMEOUT';\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 override readonly code: string = 'RELAYBUS_KAFKA_HANDLER_FAILED';\n}\n","import { assertEventType, type EventEnvelope } from '@relaybus/core';\nimport { writeStructuredCloudEvent } from '@relaybus/core/internal';\nimport { InvalidKafkaMessageError, UnencodableEventError } from './errors.js';\nimport type { KafkaBytes, KafkaIncomingHeaders, KafkaOutgoingHeaders } from './kafka-client.js';\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';\n/** Name of the Kafka header that carries the media type of the record value. */\nexport const CONTENT_TYPE = 'content-type';\nconst JSON_MEDIA_TYPE = 'application/json';\nconst STRUCTURED_MEDIA_TYPE = 'application/cloudevents+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\n/** RFC 3339 years have four digits. */\nconst MAXIMUM_RFC3339_YEAR = 9999;\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\n/**\n * Encodes an envelope as a CloudEvents Kafka structured-mode record: the value\n * is one JSON document with the attributes and `data` (the payload), the\n * content type is `application/cloudevents+json`, the record key is the event\n * key. Event headers travel as record headers, escaped as in binary mode.\n */\nexport function encodeStructuredEnvelope(envelope: EventEnvelope): EncodedMessage {\n const value = writeStructuredCloudEvent(envelope, {\n time: formatTime(envelope),\n data: serializePayload(envelope),\n });\n const entries: [string, string][] = Object.entries(envelope.headers).map(\n ([name, headerValue]) => [escapeUserHeaderName(name), headerValue],\n );\n entries.push([CONTENT_TYPE, STRUCTURED_MEDIA_TYPE]);\n return { key: envelope.key, value, headers: Object.fromEntries(entries) };\n}\n\n/** The payload as JSON text; refuses a payload JSON cannot represent. */\nexport function serializePayload(envelope: EventEnvelope): string {\n return serializeJson(envelope, envelope.payload);\n}\n\n/** `value` (the payload or a body holding it) as JSON text, refusing what JSON cannot represent. */\nexport function serializeJson(envelope: EventEnvelope, value: unknown): string {\n let text: string | undefined;\n try {\n text = JSON.stringify(value);\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 (text === 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 text;\n}\n\n/** The occurredAt as RFC 3339 text; refuses an invalid date or a year outside 0..9999. */\nexport function formatTime(envelope: EventEnvelope): string {\n const year = envelope.occurredAt.getUTCFullYear();\n if (Number.isNaN(year) || year < 0 || year > MAXIMUM_RFC3339_YEAR) {\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\n/** Creates the error thrown for every malformed record. */\nexport function 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\n/** Reads headers strictly: a repeated header or a protocol header that is not UTF-8 is invalid. */\nexport function 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(\n name,\n decodeText(raw, { strict: PROTOCOL_HEADERS.has(name), label: `Header '${name}'` }),\n );\n }\n return headers;\n}\n\n/** Decodes header or value bytes as UTF-8; `strict` rejects invalid sequences. */\nexport function decodeText(\n raw: KafkaBytes | string,\n { strict, label }: { readonly strict: boolean; readonly label: string },\n): 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 time = readRecordTimestamp(recordTimestamp);\n if (time === undefined) {\n throw invalid(`${HEADER.time} is missing and the record has no usable timestamp`);\n }\n return time;\n}\n\n/** The record timestamp (epoch milliseconds in a string) as a date, or undefined when unusable. */\nexport function readRecordTimestamp(recordTimestamp: string | undefined): Date | undefined {\n const time = new Date(Number(recordTimestamp));\n return recordTimestamp === undefined || recordTimestamp === '' || Number.isNaN(time.getTime())\n ? undefined\n : time;\n}\n\n/** Parses an RFC 3339 timestamp; anything else is invalid. `label` names the attribute in the error. */\nexport function parseTime(text: string, label: string = HEADER.time): Date {\n const time = new Date(text);\n if (!RFC3339_PATTERN.test(text) || Number.isNaN(time.getTime())) {\n throw invalid(`${label} is not an RFC 3339 timestamp: '${text}'`);\n }\n return time;\n}\n\n/** Parses the record value as UTF-8 JSON; a missing value or invalid JSON is invalid. */\nexport function parsePayload(value: KafkaBytes | null): unknown {\n if (value === null) {\n throw invalid('Message has no value');\n }\n const text = decodeText(value, { strict: true, label: '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 = readRecordKey(recordKey);\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\n/** The record key as UTF-8 text, or null when the record has none. Invalid UTF-8 is invalid. */\nexport function readRecordKey(recordKey: KafkaBytes | null): string | null {\n return recordKey === null ? null : decodeText(recordKey, { strict: true, label: 'Message key' });\n}\n\n/** Headers that are not CloudEvents attributes, with escaped names restored. */\nexport function 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 { assertEventType, type EventEnvelope, type EventHeaders } from '@relaybus/core';\nimport {\n DecodedEventReader,\n createCloudEventReaders,\n isJsonObject,\n mediaTypeOf,\n observeRejection,\n} from '@relaybus/core/internal';\nimport {\n CONTENT_TYPE,\n collectUserHeaders,\n decodeEnvelope,\n invalid,\n parsePayload,\n parseTime,\n readHeaders,\n readRecordKey,\n readRecordTimestamp,\n type DecodableMessage,\n} from './cloudevents-codec.js';\nimport type { KafkaBytes, KafkaIncomingHeaders } from './kafka-client.js';\n\nconst { optionalAttribute, requiredAttribute, assertValidType, assertJsonDataContentType } =\n createCloudEventReaders(invalid);\n\n/** A consumed record as handed to a {@link KafkaMessageDecoder}. */\nexport interface KafkaInboundRecord extends DecodableMessage {\n readonly topic: string;\n readonly partition: number;\n readonly offset: string;\n}\n\n/**\n * The event a decoder extracted from a record. `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 topic, `key` with the record key (UTF-8),\n * `headers` with none, `correlationId` and `causationId` with null, and\n * `occurredAt` with the record timestamp.\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 record into an event, for topics written by producers that\n * do not use relaybus. Must be synchronous and free of side effects: it runs\n * again on every redelivery, so the same record must always give the same\n * event, above all the same `id`, which is what the inbox deduplicates on.\n *\n * Anything it throws marks the record as malformed: it goes to the transport's\n * `onInvalidMessage` policy (dead-letter by default) and the consumer moves on.\n * An event the bus then rejects (empty id, invalid type or time) is\n * dead-lettered the same way.\n */\nexport type KafkaMessageDecoder = (record: KafkaInboundRecord) => DecodedEvent;\n\n/** A plain JSON record, decoded for the extractor options of {@link plainJsonDecoder}. */\nexport interface PlainJsonRecord {\n readonly topic: string;\n readonly partition: number;\n readonly offset: string;\n /**\n * The record key as UTF-8 text, base64 when its bytes are not valid UTF-8\n * (for example a key written by Java's `LongSerializer`), null when absent.\n */\n readonly key: string | null;\n /**\n * Every record header as text: the last value of a repeated header; a value\n * that is not valid UTF-8 is left out.\n */\n readonly headers: EventHeaders;\n /** The record value parsed as JSON. */\n readonly payload: unknown;\n /** Record timestamp in epoch milliseconds. */\n readonly timestamp: string | undefined;\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 topic that carries one\n * kind of event, or an extractor such as `fromHeader('event-type')` or\n * `fromPayloadField('type')`. Required; a record without a type is invalid.\n */\n readonly type: string | ((record: PlainJsonRecord) => string | undefined);\n /**\n * Event id the inbox deduplicates on, for example `fromHeader('message-id')`.\n * Default, and fallback when the extractor finds none:\n * `kafka:<topic>:<partition>:<offset>`, which is stable across redeliveries\n * of the record. Prefer an id set by the producer when it may send the same\n * event twice: two sends are two offsets, so only a producer id dedupes them.\n */\n readonly id?: (record: PlainJsonRecord) => string | undefined;\n /** Ordering key. Default: the record key. When given, its result is final (undefined means no key). */\n readonly key?: (record: PlainJsonRecord) => string | null | undefined;\n /** Logical name of the producer. Default: the topic. */\n readonly source?: string | ((record: PlainJsonRecord) => string | undefined);\n /** When the event happened. Default: the record timestamp. */\n readonly occurredAt?: (record: PlainJsonRecord) => Date | undefined;\n}\n\nconst STRUCTURED_MEDIA_TYPE = 'application/cloudevents+json';\n/** Refuses invalid UTF-8 and keeps a leading BOM, so different header bytes never decode equal. */\nconst exactUtf8 = new TextDecoder('utf-8', { fatal: true, ignoreBOM: true });\nconst SPEC_VERSION = '1.0';\nconst SPEC_VERSION_HEADER = 'ce_specversion';\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 record in either content mode of the Kafka\n * protocol binding:\n * - structured (`content-type: application/cloudevents+json`): the value is\n * a JSON object with `specversion`, `id`, `type`, `source` and optionally\n * `time`, `subject` (the key, else the record key), `data` (the payload,\n * null when absent) and a JSON `datacontenttype`. `data_base64` is refused,\n * because relaybus payloads are JSON. Extension attributes with string\n * values (`traceparent`, ...) become event headers, as do the record\n * headers; `correlationid` and `causationid` fill their envelope fields.\n * - binary (anything else): exactly {@link decodeEnvelope}, the default decoder.\n *\n * @throws InvalidKafkaMessageError for a record that is neither.\n */\nexport function decodeCloudEvent(record: DecodableMessage): EventEnvelope {\n const headers = readHeaders(record.headers);\n if (mediaTypeOf(headers.get(CONTENT_TYPE)) !== STRUCTURED_MEDIA_TYPE) {\n return decodeEnvelope(record);\n }\n const body = parsePayload(record.value);\n if (!isJsonObject(body)) {\n throw invalid('A structured CloudEvent must be a JSON object');\n }\n if (body['specversion'] !== SPEC_VERSION) {\n throw invalid(`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 invalid('data_base64 is not supported: relaybus payloads are JSON, send them as data');\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') ?? readRecordKey(record.key),\n payload: Object.hasOwn(body, 'data') ? body['data'] : null,\n headers: { ...collectUserHeaders(headers), ...extensionAttributes(body) },\n correlationId: optionalAttribute(body, 'correlationid') ?? null,\n causationId: optionalAttribute(body, 'causationid') ?? null,\n occurredAt: time === undefined ? requireRecordTimestamp(record) : parseTime(time, 'time'),\n };\n}\n\n/**\n * Creates a decoder for records whose value is plain JSON, as written by a\n * service that does not use relaybus (a plain kafkajs producer, Spring Kafka's\n * `JsonSerializer`, a Go service): the value becomes the payload, the record\n * headers become event headers, and the options say where the event type and\n * id come from.\n *\n * A record that is a CloudEvent anyway (a `ce_specversion` header, or a\n * structured `application/cloudevents+json` value) is decoded with\n * {@link decodeCloudEvent} instead, so relaybus and foreign producers can share\n * a topic. A missing or non-JSON value, a missing or invalid type, and an\n * extractor returning anything but a string are invalid.\n *\n * ```ts\n * new KafkaTransport({\n * kafka,\n * groupId: 'billing',\n * decode: plainJsonDecoder({ type: fromHeader('event-type'), id: fromHeader('message-id') }),\n * });\n * ```\n *\n * @throws ConfigurationError when a fixed `type` is not a valid event type.\n */\nexport function plainJsonDecoder(options: PlainJsonDecoderOptions): KafkaMessageDecoder {\n if (typeof options.type === 'string') {\n assertEventType(options.type);\n }\n return (record) => {\n const headers = readHeadersLeniently(record.headers);\n if (\n record.headers?.[SPEC_VERSION_HEADER] !== undefined ||\n mediaTypeOf(headers[CONTENT_TYPE]) === STRUCTURED_MEDIA_TYPE\n ) {\n return decodeCloudEvent(record);\n }\n const plain = plainRecordOf(record, headers);\n const type = KAFKA_EVENTS.text(options.type, { plain, name: 'type' });\n if (type === undefined) {\n throw invalid('Record has no event type: the type option found none');\n }\n assertValidType(type, 'The event type');\n return {\n id:\n KAFKA_EVENTS.text(options.id, { plain, name: 'id' }) ??\n `kafka:${record.topic}:${record.partition}:${record.offset}`,\n type,\n source: KAFKA_EVENTS.text(options.source, { plain, name: 'source' }) ?? record.topic,\n key:\n options.key === undefined\n ? plain.key\n : (KAFKA_EVENTS.text(options.key, { plain, name: 'key' }) ?? null),\n payload: plain.payload,\n headers,\n correlationId: null,\n causationId: null,\n occurredAt: resolveOccurredAt(options.occurredAt, { plain, record }),\n };\n };\n}\n\n/** A record as the extractor options of {@link plainJsonDecoder} see it. */\nfunction plainRecordOf(record: KafkaInboundRecord, headers: EventHeaders): PlainJsonRecord {\n return {\n topic: record.topic,\n partition: record.partition,\n offset: record.offset,\n key: readKeyLeniently(record.key),\n headers,\n payload: parsePayload(record.value),\n timestamp: record.timestamp,\n };\n}\n\n/** The inbound plumbing of Kafka records: malformed records and the record's own defaults. */\nclass KafkaDecodedEvents extends DecodedEventReader<KafkaInboundRecord, PlainJsonRecord> {\n invalid(reason: string): Error {\n return invalid(reason);\n }\n\n /** The topic. */\n protected defaultSource(record: KafkaInboundRecord): string {\n return record.topic;\n }\n\n /** The record key as UTF-8 text. */\n protected defaultKey(record: KafkaInboundRecord): string | null {\n return readRecordKey(record.key);\n }\n\n /** The record timestamp; a record without a usable one is malformed. */\n protected defaultTime(record: KafkaInboundRecord): Date {\n return requireRecordTimestamp(record);\n }\n}\n\nconst KAFKA_EVENTS = new KafkaDecodedEvents();\n\n/**\n * Fills the fields a decoder left out (see {@link DecodedEvent}) and guards\n * against a decoder that returned no object, which would otherwise surface as\n * a retried `TypeError` instead of a malformed record.\n */\nexport function completeDecodedEvent(decoded: unknown, record: KafkaInboundRecord): EventEnvelope {\n return KAFKA_EVENTS.complete(decoded, record);\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\nfunction requireRecordTimestamp(record: DecodableMessage): Date {\n const time = readRecordTimestamp(record.timestamp);\n if (time === undefined) {\n throw invalid('The event has no time and the record has no usable timestamp');\n }\n return time;\n}\n\n/**\n * Headers of a foreign record, never rejected: the last value of a repeated\n * header wins, and a value that is not valid UTF-8 is left out, because\n * replacing its bytes could make two different ids or types look equal.\n */\nexport function readHeadersLeniently(incoming: KafkaIncomingHeaders | undefined): EventHeaders {\n const entries: [string, string][] = [];\n for (const [name, raw] of Object.entries(incoming ?? {})) {\n const value = Array.isArray(raw)\n ? (raw as (KafkaBytes | string)[]).at(-1)\n : (raw as KafkaBytes | string | undefined);\n const text = value === undefined ? undefined : decodeUtf8OrUndefined(value);\n if (text !== undefined) {\n entries.push([name, text]);\n }\n }\n return Object.fromEntries(entries);\n}\n\nfunction decodeUtf8OrUndefined(value: KafkaBytes | string): string | undefined {\n if (typeof value === 'string') {\n return value;\n }\n try {\n return exactUtf8.decode(value);\n } catch {\n return undefined;\n }\n}\n\nfunction readKeyLeniently(key: KafkaBytes | null): string | null {\n if (key === null) {\n return null;\n }\n try {\n return readRecordKey(key);\n } catch {\n return Buffer.from(key).toString('base64');\n }\n}\n\nfunction resolveOccurredAt(\n option: PlainJsonDecoderOptions['occurredAt'],\n { plain, record }: { readonly plain: PlainJsonRecord; readonly record: KafkaInboundRecord },\n): Date {\n const value: unknown = option?.(plain);\n if (value === undefined) {\n return requireRecordTimestamp(record);\n }\n if (!(value instanceof Date) || Number.isNaN(value.getTime())) {\n observeRejection(value);\n throw invalid('The occurredAt option returned no valid Date');\n }\n return value;\n}\n","import { ConfigurationError, type EventEnvelope } from '@relaybus/core';\nimport {\n createJsonEnvelopeFormat,\n type JsonEnvelopeFormat,\n type JsonEnvelopeMapping,\n} from '@relaybus/core/internal';\nimport {\n CONTENT_TYPE,\n decodeEnvelope,\n encodeEnvelope,\n encodeStructuredEnvelope,\n formatTime,\n invalid,\n parsePayload,\n serializeJson,\n} from './cloudevents-codec.js';\nimport { UnencodableEventError } from './errors.js';\nimport {\n decodeCloudEvent,\n readHeadersLeniently,\n type DecodedEvent,\n type KafkaInboundRecord,\n type KafkaMessageDecoder,\n} from './inbound-decoders.js';\nimport type { KafkaOutgoingMessage } from './kafka-client.js';\n\n/** The record a codec produces for one event. `timestamp` is epoch milliseconds in a string. */\nexport type KafkaEncodedRecord = KafkaOutgoingMessage & { readonly timestamp?: string };\n\n/**\n * The wire format of a {@link KafkaTransport}: how an event becomes a record\n * (`encode`, on publish) and a consumed record becomes an event (`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 UnencodableEventError}. What `decode` throws marks the record\n * as malformed: it goes to `onInvalidMessage` (dead-letter by default) and the\n * consumer moves on. See {@link KafkaMessageDecoder} for the decode contract.\n */\nexport interface KafkaCodec {\n readonly encode: (envelope: EventEnvelope) => KafkaEncodedRecord;\n readonly decode: KafkaMessageDecoder;\n}\n\n/**\n * CloudEvents 1.0 binary content mode, the default: the value is the JSON\n * payload, the attributes travel as `ce_*` headers ({@link encodeEnvelope}).\n * Decoding is strict: any other record is malformed ({@link decodeEnvelope}).\n */\nexport const cloudEventsBinary: KafkaCodec = Object.freeze({\n encode: encodeEnvelope,\n decode: decodeEnvelope,\n});\n\n/**\n * CloudEvents 1.0 structured content mode: the value is one\n * `application/cloudevents+json` document with the attributes and `data`.\n * Decoding accepts structured and binary mode ({@link decodeCloudEvent}), so a\n * topic can move from one to the other while both are in flight.\n */\nexport const cloudEventsStructured: KafkaCodec = 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 `'record-position'`: a consumed\n * record gets `kafka:<topic>:<partition>:<offset>`, stable across redeliveries\n * but different for two sends of one event. Records relaybus writes carry the\n * event id in a `relaybus-event-id` header, which wins on read, so an outbox\n * retry that sends an event twice is still deduplicated.\n */\nexport type KafkaJsonEnvelopeMapping = JsonEnvelopeMapping<'record-position'> & KafkaRecordOptions;\n\n/**\n * The record key of an event: `'event-key'` (the event key, default), `'none'` (no key) or a\n * function of the event. The event key itself, and with it the outbox's per-key order, is\n * unchanged: only the wire key differs. Records without a key are spread over partitions by the\n * producer, so the per-key order holds up to the broker but not across partitions.\n */\nexport type KafkaRecordKey = 'event-key' | 'none' | ((envelope: EventEnvelope) => string | null);\n\n/** Record-level choices of {@link jsonEnvelope} besides the mapping. */\nexport interface KafkaRecordOptions {\n /** Default `'event-key'`. */\n readonly recordKey?: KafkaRecordKey;\n /** Whether the record gets a `content-type` header. Default true. */\n readonly contentTypeHeader?: boolean;\n}\n\nconst RECORD_POSITION = 'record-position';\n/** Carries the event id of a record relaybus wrote under `'record-position'`. */\nconst EVENT_ID_HEADER = 'relaybus-event-id';\nconst DEFAULT_CONTENT_TYPE = 'application/json';\n\n/**\n * A JSON wire format declared by a mapping, in both directions: for topics\n * shared with services that wrap events in their own envelope\n * (`{ \"eventName\": ..., \"data\": {...} }`, MassTransit) or send the bare\n * payload. The record key is the event key unless `recordKey` says otherwise;\n * when `occurredAt` is not mapped, the record timestamp carries it. Event headers that are message\n * headers are written as they are, so a name the mapping uses for another\n * field is refused with {@link UnencodableEventError}, as are `content-type`\n * and `relaybus-event-id`.\n *\n * ```ts\n * codec: jsonEnvelope({\n * type: { body: 'eventName' },\n * id: { body: 'messageId' },\n * payload: { body: 'data' },\n * correlationId: { body: 'meta.correlationId' },\n * })\n * ```\n *\n * @throws ConfigurationError for an incomplete or self-overlapping mapping.\n */\nexport function jsonEnvelope(mapping: KafkaJsonEnvelopeMapping): KafkaCodec {\n const format = createJsonEnvelopeFormat(mapping, {\n transportIds: [RECORD_POSITION],\n failures: { invalid, unencodable: (reason) => new UnencodableEventError(reason) },\n });\n const contentType: Record<string, string> =\n mapping.contentTypeHeader === false\n ? {}\n : { [CONTENT_TYPE]: mapping.contentType ?? DEFAULT_CONTENT_TYPE };\n const stampsTime = mapping.occurredAt === undefined;\n const ownHeaders = (envelope: EventEnvelope): Record<string, string> =>\n mapping.id === RECORD_POSITION\n ? { ...contentType, [EVENT_ID_HEADER]: envelope.id }\n : contentType;\n const recordKey = resolveRecordKey(mapping.recordKey);\n return {\n encode: (envelope) => encodeJson(envelope, { format, stampsTime, ownHeaders, recordKey }),\n decode: (record) => decodeJson(record, format),\n };\n}\n\nfunction resolveRecordKey(\n recordKey: KafkaRecordKey | undefined,\n): (envelope: EventEnvelope) => string | null {\n if (recordKey === undefined || recordKey === 'event-key') {\n return (envelope) => envelope.key;\n }\n if (recordKey === 'none') {\n return () => null;\n }\n if (typeof recordKey === 'function') {\n return recordKey;\n }\n throw new ConfigurationError(\n `jsonEnvelope recordKey must be 'event-key', 'none' or a function, received '${String(recordKey)}'`,\n );\n}\n\n/** How {@link jsonEnvelope} writes: by the format, with its own headers, and the time as timestamp when unmapped. */\ntype JsonEncoding = {\n readonly format: JsonEnvelopeFormat;\n readonly stampsTime: boolean;\n readonly ownHeaders: (envelope: EventEnvelope) => Record<string, string>;\n readonly recordKey: (envelope: EventEnvelope) => string | null;\n};\n\nfunction encodeJson(\n envelope: EventEnvelope,\n { format, stampsTime, ownHeaders, recordKey }: JsonEncoding,\n): KafkaEncodedRecord {\n assertRepresentable(envelope);\n const { body, headers } = format.write(envelope);\n const taken = [CONTENT_TYPE, EVENT_ID_HEADER].find((name) => Object.hasOwn(headers, name));\n if (taken !== undefined) {\n throw new UnencodableEventError(\n `Event ${envelope.id} has a header '${taken}', which the codec writes itself`,\n );\n }\n return {\n key: recordKey(envelope),\n value: serializeJson(envelope, body),\n headers: { ...headers, ...ownHeaders(envelope) },\n ...(stampsTime ? { timestamp: recordTimestamp(envelope) } : {}),\n };\n}\n\nfunction decodeJson(record: KafkaInboundRecord, format: JsonEnvelopeFormat): DecodedEvent {\n const { [EVENT_ID_HEADER]: eventId, ...headers } = withoutContentType(\n readHeadersLeniently(record.headers),\n );\n const fields = format.read({ body: parsePayload(record.value), headers });\n return {\n ...fields,\n id:\n fields.id ??\n (eventId === undefined || eventId === ''\n ? `kafka:${record.topic}:${record.partition}:${record.offset}`\n : eventId),\n };\n}\n\nfunction withoutContentType(headers: Readonly<Record<string, string>>): Record<string, string> {\n return Object.fromEntries(Object.entries(headers).filter(([name]) => name !== CONTENT_TYPE));\n}\n\n/** A payload JSON would drop from the body instead of refusing; nested ones fail when serialized. */\nfunction assertRepresentable(envelope: EventEnvelope): void {\n const kind = typeof envelope.payload;\n if (kind === 'undefined' || kind === 'function' || kind === 'symbol') {\n throw new UnencodableEventError(\n `Event ${envelope.id} has a payload that JSON cannot represent (undefined, a function or a symbol)`,\n );\n }\n}\n\n/** The occurredAt as the record timestamp, epoch milliseconds; refuses an invalid date. */\nfunction recordTimestamp(envelope: EventEnvelope): string {\n formatTime(envelope);\n return String(envelope.occurredAt.getTime());\n}\n","import { systemClock } from '@relaybus/core';\nimport { schedule, type CancelTimer } from '@relaybus/core/internal';\nimport { GroupJoinTimeoutError, TransportClosedError } from './errors.js';\nimport type { KafkaConsumerLike, KafkaEachMessagePayload } from './kafka-client.js';\nimport type { KafkaSettings } from './kafka-settings.js';\n\n/** A wait for the consumer to join its group, and what ends it early. */\ntype GroupJoin = { readonly promise: Promise<void>; dispose(): void };\n\n/**\n * Waits, within the startup timeout, for the consumer to join its group: a start-up that cannot\n * consume fails loudly instead of looking healthy. A crash or a close ends the wait early.\n */\nexport class GroupJoinWatch {\n readonly #settings: KafkaSettings;\n #waiter: { resolve(): void; reject(error: unknown): void } | undefined;\n\n constructor(settings: KafkaSettings) {\n this.#settings = settings;\n }\n\n /** The consumer joined its group. */\n joined(): void {\n this.#waiter?.resolve();\n }\n\n /** The consumer crashed while it was joining. */\n failed(error: unknown): void {\n this.#waiter?.reject(error);\n }\n\n /** The transport closed while the consumer was joining. */\n closed(): void {\n this.#waiter?.reject(new TransportClosedError(`Transport '${this.#settings.name}' is closed`));\n }\n\n /** Connects and subscribes the consumer, runs it and resolves once it joined its group. */\n async start(\n consumer: KafkaConsumerLike,\n {\n topics,\n fromBeginning,\n eachMessage,\n }: {\n readonly topics: string[];\n readonly fromBeginning: boolean;\n readonly eachMessage: (payload: KafkaEachMessagePayload) => Promise<void>;\n },\n ): Promise<void> {\n await consumer.connect();\n await consumer.subscribe(this.#settings.dialect.subscription(topics, fromBeginning));\n const joined = this.#wait(consumer);\n try {\n await consumer.run({ eachMessage });\n await joined.promise;\n } finally {\n joined.dispose();\n }\n }\n\n #wait(consumer: KafkaConsumerLike): GroupJoin {\n if (!this.#settings.dialect.tracksMembership(consumer)) {\n return { promise: Promise.resolve(), dispose: () => undefined };\n }\n const { name, groupId, timings } = this.#settings;\n let cancel: CancelTimer | undefined;\n const promise = new Promise<void>((resolve, reject) => {\n this.#waiter = { resolve, reject };\n cancel = schedule(systemClock, {\n run: () => {\n reject(\n new GroupJoinTimeoutError(\n `Consumer of transport '${name}' did not join group '${groupId}' within ${timings.startupTimeoutMs}ms`,\n ),\n );\n },\n delayMs: timings.startupTimeoutMs,\n });\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 cancel?.();\n this.#waiter = undefined;\n },\n };\n }\n}\n","import { systemClock } from '@relaybus/core';\nimport { schedule, type CancelTimer } from '@relaybus/core/internal';\nimport { PublishTimeoutError, TransportClosedError } from './errors.js';\nimport type { KafkaProducerLike, KafkaProducerRecord } from './kafka-client.js';\nimport type { KafkaInjectedProducer } from './kafka-options.js';\nimport type { KafkaSettings } from './kafka-settings.js';\n\n/** A producer as the transport uses it once connected: it sends, and closing disconnects it. */\nexport type SessionProducer = Pick<KafkaProducerLike, 'send' | 'disconnect'>;\n\n/**\n * The idempotent producer of a transport: connected on first use (once, shared by concurrent\n * callers, again after a failed connect), and every send bounded by the publish timeout.\n */\nexport class KafkaProducerSession {\n readonly #settings: KafkaSettings;\n /** Whether the transport is closed: then nothing connects any more. */\n readonly #isClosed: () => boolean;\n #producer: Promise<SessionProducer> | undefined;\n #connected = false;\n\n constructor(settings: KafkaSettings, isClosed: () => boolean) {\n this.#settings = settings;\n this.#isClosed = isClosed;\n }\n\n /** True once the producer connected, until the transport closes. */\n get isConnected(): boolean {\n return this.#connected;\n }\n\n /** The producer opened so far, if any: what closing must disconnect. */\n get pending(): Promise<SessionProducer> | undefined {\n return this.#producer;\n }\n\n markClosed(): void {\n this.#connected = false;\n }\n\n connected(): Promise<SessionProducer> {\n if (this.#isClosed()) {\n return Promise.reject(\n new TransportClosedError(`Transport '${this.#settings.name}' is closed`),\n );\n }\n this.#producer ??= this.#open();\n return this.#producer;\n }\n\n /** Sends with the publish timeout; the late outcome of a timed-out send is ignored. */\n async send(producer: SessionProducer, record: KafkaProducerRecord): Promise<void> {\n const { name, timings } = this.#settings;\n let cancel: CancelTimer | undefined;\n const timeout = new Promise<never>((_resolve, reject) => {\n cancel = schedule(systemClock, {\n run: () => {\n reject(\n new PublishTimeoutError(\n `Transport '${name}' got no broker ack for topic '${record.topic}' within ${timings.publishTimeoutMs}ms`,\n ),\n );\n },\n delayMs: timings.publishTimeoutMs,\n });\n });\n const sending = producer.send(this.#settings.dialect.record(record));\n sending.catch(() => undefined);\n try {\n await Promise.race([sending, timeout]);\n } finally {\n cancel?.();\n }\n }\n\n async #open(): Promise<SessionProducer> {\n const { kafka, dialect, injectedProducer } = this.#settings;\n if (injectedProducer !== undefined) {\n this.#connected = true;\n return withoutLifecycle(injectedProducer);\n }\n const producer = kafka!.producer(dialect.producerConfig(this.#settings));\n try {\n await producer.connect();\n } catch (error) {\n this.#producer = undefined;\n throw error;\n }\n this.#connected = !this.#isClosed();\n return producer;\n }\n}\n\n/** The application's producer, with a disconnect that leaves it open. */\nfunction withoutLifecycle(producer: KafkaInjectedProducer): SessionProducer {\n return {\n send: (record) => producer.send(record),\n disconnect: () => Promise.resolve(),\n };\n}\n","import { ConfigurationError } from '@relaybus/core';\nimport type {\n KafkaConsumerConfig,\n KafkaConsumerEvent,\n KafkaConsumerLike,\n KafkaProducerConfig,\n KafkaProducerRecord,\n KafkaTopicPartition,\n} from './kafka-client.js';\nimport type { KafkaSettings } from './kafka-settings.js';\n\n/** The Kafka client a transport drives: `kafkajs`, or `@confluentinc/kafka-javascript`'s KafkaJS API. */\nexport type KafkaClientName = 'kafkajs' | 'confluent';\n\n/** What the transport does when the consumer's group membership changes. */\nexport interface MembershipListeners {\n joined(): void;\n rebalancing(): void;\n crashed(event: KafkaConsumerEvent): void;\n left(): void;\n}\n\n/**\n * How the transport talks to one client: where its settings go, what `subscribe` and `send`\n * accept and how the client reports group membership.\n */\nexport interface KafkaClientDialect {\n producerConfig(settings: KafkaSettings): KafkaProducerConfig;\n consumerConfig(settings: KafkaSettings, membership: MembershipListeners): KafkaConsumerConfig;\n subscription(\n topics: string[],\n fromBeginning: boolean,\n ): { topics: string[]; fromBeginning?: boolean };\n record(record: KafkaProducerRecord): KafkaProducerRecord;\n /** Whether the consumer reports joining its group, so start-up can wait for it. */\n tracksMembership(consumer: KafkaConsumerLike): boolean;\n /** Starts listening to the consumer's membership events, if it reports them as events. */\n observe(consumer: KafkaConsumerLike, membership: MembershipListeners): void;\n}\n\n/** kafkajs: settings at the top level, membership through instrumentation events. */\nconst KAFKAJS_DIALECT: KafkaClientDialect = {\n producerConfig: ({ producerConfig, maxInFlightRequests }) => ({\n ...producerConfig,\n idempotent: true,\n maxInFlightRequests,\n }),\n consumerConfig: ({ consumerConfig, groupId }) => ({ ...consumerConfig, groupId: groupId! }),\n subscription: (topics, fromBeginning) => ({ topics, fromBeginning }),\n record: (record) => record,\n tracksMembership: (consumer) =>\n consumer.on !== undefined && consumer.events?.GROUP_JOIN !== undefined,\n observe: (consumer, membership) => {\n if (!KAFKAJS_DIALECT.tracksMembership(consumer)) {\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, () => membership.joined());\n listen(names.REBALANCING, () => membership.rebalancing());\n listen(names.CRASH, (event) => membership.crashed(event));\n listen(names.STOP, () => membership.left());\n listen(names.DISCONNECT, () => membership.left());\n },\n};\n\n/** librdkafka's `rebalance_cb` codes: partitions assigned (the group is joined) and revoked. */\nconst ASSIGN_PARTITIONS = -175;\nconst REVOKE_PARTITIONS = -174;\n\n/** Arguments Confluent hands to `rebalance_cb`; the third carries the assignment functions. */\ntype RebalanceArguments = [{ readonly code: number }, readonly KafkaTopicPartition[], ...unknown[]];\n\n/** The user's settings with their own `kafkaJS` block, if any. */\ntype WithKafkaJsBlock = { readonly kafkaJS?: object; readonly rebalance_cb?: unknown };\n\n/**\n * Confluent's KafkaJS-compatible API: KafkaJS settings inside the `kafkaJS` block (it rejects\n * them at the top level), `fromBeginning` in the consumer config instead of `subscribe`, `acks`\n * on the producer instead of `send`, and membership through `rebalance_cb` (it has no\n * instrumentation events, and it never gives up on a consumer, so there is no crash to report).\n * The same settings are also given as librdkafka properties, which Confluent applies after the\n * `kafkaJS` block, so the user's librdkafka properties cannot override them either.\n */\nconst CONFLUENT_DIALECT: KafkaClientDialect = {\n producerConfig: ({ producerConfig, maxInFlightRequests }) => {\n const user = producerConfig as WithKafkaJsBlock;\n return {\n ...user,\n kafkaJS: { ...user.kafkaJS, idempotent: true, maxInFlightRequests, acks: -1 },\n 'enable.idempotence': true,\n 'max.in.flight': maxInFlightRequests,\n acks: -1,\n };\n },\n consumerConfig: ({ consumerConfig, groupId, fromBeginning }, membership) => {\n const user = consumerConfig as WithKafkaJsBlock;\n const userCallback =\n typeof user.rebalance_cb === 'function'\n ? (user.rebalance_cb as (...args: RebalanceArguments) => unknown)\n : undefined;\n return {\n ...user,\n kafkaJS: { ...user.kafkaJS, groupId: groupId!, fromBeginning },\n 'group.id': groupId!,\n 'auto.offset.reset': fromBeginning ? 'earliest' : 'latest',\n rebalance_cb: (...args: RebalanceArguments): unknown => {\n if (args[0].code === ASSIGN_PARTITIONS) {\n membership.joined();\n } else if (args[0].code === REVOKE_PARTITIONS) {\n membership.rebalancing();\n }\n return userCallback?.(...args);\n },\n };\n },\n subscription: (topics) => ({ topics }),\n record: ({ acks: _acks, ...record }) => record,\n tracksMembership: () => true,\n observe: () => undefined,\n};\n\n/** The dialect of `client`, kafkajs by default. */\nexport function clientDialect(client: KafkaClientName | undefined): KafkaClientDialect {\n if (client === undefined || client === 'kafkajs') {\n return KAFKAJS_DIALECT;\n }\n if (client === 'confluent') {\n return CONFLUENT_DIALECT;\n }\n throw new ConfigurationError(\n `Unknown Kafka client '${String(client)}'; use 'kafkajs' or 'confluent'`,\n );\n}\n","import { ConfigurationError, toErrorInfo, type RelayBusLogger } from '@relaybus/core';\nimport {\n BoundedInteger,\n ExponentialBackoff,\n Milliseconds,\n PositiveInteger,\n} from '@relaybus/core/internal';\nimport { encodeEnvelope } from './cloudevents-codec.js';\nimport { cloudEventsBinary, type KafkaCodec } from './codecs.js';\nimport { HandlerFailedError } from './errors.js';\nimport type { KafkaClientLike } from './kafka-client.js';\nimport { clientDialect, type KafkaClientDialect } from './kafka-client-dialects.js';\nimport type {\n InvalidMessagePolicy,\n KafkaInjectedProducer,\n KafkaProcessingOptions,\n KafkaRestartOptions,\n KafkaTransportOptions,\n} from './kafka-options.js';\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\n/** Largest `maxInFlightRequests`. */\nconst MAXIMUM_IN_FLIGHT_REQUESTS = 5;\n\n/** The timing of record processing and of the consumer restart loop. */\nexport interface KafkaTimings {\n readonly maxAttempts: number;\n readonly processingBackoff: ExponentialBackoff;\n readonly startupTimeoutMs: number;\n readonly publishTimeoutMs: number;\n readonly heartbeatIntervalMs: number;\n readonly restartBackoff: ExponentialBackoff;\n}\n\n/** Every option of a {@link KafkaTransport}, with its default, checked. */\nexport interface KafkaSettings {\n readonly name: string;\n /** Undefined only with an injected producer: then the transport cannot subscribe. */\n readonly kafka: KafkaClientLike | undefined;\n /** The application's own producer, which the transport never connects or disconnects. */\n readonly injectedProducer: KafkaInjectedProducer | undefined;\n /** How to talk to `kafka`: kafkajs or Confluent. */\n readonly dialect: KafkaClientDialect;\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 codec: KafkaCodec;\n readonly logger: RelayBusLogger;\n readonly timings: KafkaTimings;\n}\n\n/** Resolves the options of a transport, in the order they were always checked. */\nexport function resolveKafkaSettings(options: KafkaTransportOptions): KafkaSettings {\n return {\n name: options.name ?? DEFAULTS.name,\n kafka: options.kafka,\n injectedProducer: resolveInjectedProducer(options),\n dialect: clientDialect(options.client),\n groupId: options.groupId,\n fromBeginning: options.fromBeginning ?? true,\n maxInFlightRequests: BoundedInteger.of(\n options.maxInFlightRequests ?? DEFAULTS.maxInFlightRequests,\n { name: 'maxInFlightRequests', minimum: 1, maximum: MAXIMUM_IN_FLIGHT_REQUESTS },\n ),\n producerConfig: options.producerConfig ?? {},\n consumerConfig: options.consumerConfig ?? {},\n invalidPolicy: options.onInvalidMessage ?? 'dead-letter',\n codec: resolveCodec(options),\n logger: options.logger ?? console,\n timings: resolveTimings(options),\n };\n}\n\n/** The injected producer, refusing producer settings it would ignore and a transport with no producer. */\nfunction resolveInjectedProducer(\n options: KafkaTransportOptions,\n): KafkaInjectedProducer | undefined {\n const { producer, kafka, producerConfig, maxInFlightRequests } = options;\n if (producer === undefined) {\n if (kafka === undefined) {\n throw new ConfigurationError(\n \"Give 'kafka', or an already-connected 'producer' to publish with\",\n );\n }\n return undefined;\n }\n if (producerConfig !== undefined || maxInFlightRequests !== undefined) {\n throw new ConfigurationError(\n \"Give 'producerConfig' and 'maxInFlightRequests' to a producer you inject yourself\",\n );\n }\n return producer;\n}\n\n/** The codec of the options; the deprecated `decode` pairs with the default encoding. */\nfunction resolveCodec({ codec, decode }: KafkaTransportOptions): KafkaCodec {\n if (decode === undefined) {\n return codec ?? cloudEventsBinary;\n }\n if (codec !== undefined) {\n throw new ConfigurationError(\"Give 'codec' or the deprecated 'decode', not both\");\n }\n return { encode: encodeEnvelope, decode };\n}\n\nfunction resolveTimings(options: KafkaTransportOptions): KafkaTimings {\n const processing: KafkaProcessingOptions = options.processing ?? {};\n const maxAttempts = PositiveInteger.of(\n processing.maxAttempts ?? DEFAULTS.maxAttempts,\n 'processing.maxAttempts',\n );\n return {\n maxAttempts,\n processingBackoff: new ExponentialBackoff({\n initialMs: Milliseconds.of(\n processing.initialBackoff ?? DEFAULTS.initialBackoff,\n 'processing.initialBackoff',\n ),\n maxMs: Milliseconds.of(processing.maxBackoff ?? DEFAULTS.maxBackoff, 'processing.maxBackoff'),\n }),\n startupTimeoutMs: Milliseconds.of(\n options.startupTimeout ?? DEFAULTS.startupTimeout,\n 'startupTimeout',\n ),\n publishTimeoutMs: Milliseconds.of(\n options.publishTimeout ?? DEFAULTS.publishTimeout,\n 'publishTimeout',\n ),\n heartbeatIntervalMs: Math.max(\n 1,\n Milliseconds.of(\n processing.heartbeatInterval ?? DEFAULTS.heartbeatInterval,\n 'processing.heartbeatInterval',\n ),\n ),\n restartBackoff: resolveRestartBackoff(options.restart ?? {}),\n };\n}\n\nfunction resolveRestartBackoff(restart: KafkaRestartOptions): ExponentialBackoff {\n return new ExponentialBackoff({\n initialMs: Milliseconds.of(\n restart.initialBackoff ?? DEFAULTS.restartInitialBackoff,\n 'restart.initialBackoff',\n ),\n maxMs: Milliseconds.of(restart.maxBackoff ?? DEFAULTS.restartMaxBackoff, 'restart.maxBackoff'),\n });\n}\n\n/** The dead-letter topic for records of `sourceTopic`, or undefined when the policy does not use one. */\nexport function deadLetterTopicFor(\n policy: InvalidMessagePolicy,\n sourceTopic: string,\n): string | undefined {\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/**\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 */\nexport function toHandlerFailure(error: unknown): Error {\n const { name, message } = toErrorInfo(error);\n return new HandlerFailedError(`${name}: ${message}`);\n}\n","import { ConfigurationError } from '@relaybus/core';\nimport { TransportClosedError } from './errors.js';\nimport { deadLetterTopicFor, type KafkaSettings } from './kafka-settings.js';\n\n/** Where a transport is: before its one subscription, subscribed, or closed for good. */\nexport type KafkaTransportState = 'idle' | 'subscribed' | 'closed';\n\n/**\n * Refuses a subscription the transport cannot take: it is closed or subscribed already, it has\n * no group, no topic, or would consume its own dead-letter topic.\n */\nexport function assertCanSubscribe(\n state: KafkaTransportState,\n {\n settings,\n destinations,\n }: { readonly settings: KafkaSettings; readonly destinations: readonly string[] },\n): void {\n const { name, groupId, invalidPolicy, kafka } = settings;\n if (state === 'closed') {\n throw new TransportClosedError(`Transport '${name}' is closed`);\n }\n if (state === 'subscribed') {\n throw new ConfigurationError(\n `Transport '${name}' already subscribed; list every topic in one subscription or use one KafkaTransport per consumer group`,\n );\n }\n if (kafka === undefined) {\n throw new ConfigurationError(`Transport '${name}' needs 'kafka' to create its consumer`);\n }\n if (groupId === undefined || groupId.length === 0) {\n throw new ConfigurationError(`Transport '${name}' needs a groupId to subscribe`);\n }\n if (destinations.length === 0) {\n throw new ConfigurationError(`Transport '${name}' subscribed to no topics`);\n }\n for (const topic of destinations) {\n const deadLetterTopic = deadLetterTopicFor(invalidPolicy, 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","import type { EventEnvelope } from '@relaybus/core';\nimport { decodeEnvelope, toOutgoingHeaders } from './cloudevents-codec.js';\nimport { cloudEventsBinary, type KafkaCodec } from './codecs.js';\nimport { completeDecodedEvent, type KafkaInboundRecord } from './inbound-decoders.js';\nimport type { KafkaEachMessagePayload, KafkaProducerRecord } from './kafka-client.js';\n\n// What a consumed record becomes: an event, or a copy for its dead-letter topic.\n\n/** The event of a consumed record, by the transport's codec; throws for a malformed record. */\nexport function decodeRecord(\n codec: KafkaCodec,\n { topic, partition, message }: KafkaEachMessagePayload,\n): EventEnvelope {\n return decodeKafkaRecord(codec, {\n topic,\n partition,\n offset: message.offset,\n key: message.key,\n value: message.value,\n headers: message.headers,\n timestamp: message.timestamp,\n });\n}\n\n/**\n * The event a {@link KafkaTransport} with `codec` hands to the bus for `record`: the codec's\n * `decode`, with what it leaves out filled in (see `DecodedEvent`). Throws for a malformed\n * record. For codec contract tests (`kafkaCodecContract` of `@relaybus/testing`).\n */\nexport function decodeKafkaRecord(codec: KafkaCodec, record: KafkaInboundRecord): EventEnvelope {\n if (codec === cloudEventsBinary) {\n return decodeEnvelope(record);\n }\n return completeDecodedEvent(codec.decode(record), record);\n}\n\n/** A copy of a record for its dead-letter topic, with why and where it came from in its headers. */\nexport function deadLetterRecord(\n { topic, partition, message }: KafkaEachMessagePayload,\n {\n reason,\n name,\n code,\n deadLetterTopic,\n }: {\n readonly reason: string;\n readonly name: string;\n readonly code: string | undefined;\n readonly deadLetterTopic: string;\n },\n): KafkaProducerRecord {\n const headers: Record<string, Buffer | string | (Buffer | string)[]> = {\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 'relaybus-error-name': name,\n };\n if (code === undefined) {\n delete headers['relaybus-error-code'];\n } else {\n headers['relaybus-error-code'] = code;\n }\n return {\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 },\n ],\n };\n}\n","import { systemClock } from '@relaybus/core';\nimport { schedule } from '@relaybus/core/internal';\n\n/** Sleeps that a close ends at once, so no backoff outlives the transport. */\nexport class WakeableSleeps {\n readonly #sleepers = new Set<() => void>();\n\n sleep(milliseconds: number): Promise<void> {\n return new Promise((resolve) => {\n const wake = (): void => {\n cancel();\n this.#sleepers.delete(wake);\n resolve();\n };\n const cancel = schedule(systemClock, { run: wake, delayMs: milliseconds });\n this.#sleepers.add(wake);\n });\n }\n\n wakeAll(): void {\n for (const wake of this.#sleepers) {\n wake();\n }\n }\n\n /**\n * Sleeps `milliseconds` in slices of at most `sliceMs`, running `between` after each, until done\n * or `stopped`: a long backoff then never outlives the session timeout.\n */\n async sleepInSlices(\n milliseconds: number,\n {\n sliceMs,\n between,\n stopped,\n }: {\n readonly sliceMs: number;\n readonly between: () => Promise<void>;\n readonly stopped: () => boolean;\n },\n ): Promise<void> {\n let remaining = milliseconds;\n do {\n const slice = Math.min(remaining, sliceMs);\n await this.sleep(slice);\n await between();\n remaining -= slice;\n } while (remaining > 0 && !stopped());\n }\n}\n","import {\n NonRetryableError,\n toErrorInfo,\n type EventEnvelope,\n type TransportMessageHandler,\n type TransportSubscriptionHooks,\n} from '@relaybus/core';\nimport { SubscribingTransport, type TransportSubscription } from '@relaybus/core/internal';\nimport { cloudEventsBinary } from './codecs.js';\nimport { InvalidKafkaMessageError } from './errors.js';\nimport { GroupJoinWatch } from './kafka-group-join.js';\nimport type { MembershipListeners } from './kafka-client-dialects.js';\nimport type {\n KafkaConsumerEvent,\n KafkaConsumerLike,\n KafkaEachMessagePayload,\n} from './kafka-client.js';\nimport type { KafkaTransportOptions } from './kafka-options.js';\nimport { KafkaProducerSession } from './kafka-producer-session.js';\nimport {\n deadLetterTopicFor,\n resolveKafkaSettings,\n toHandlerFailure,\n type KafkaSettings,\n} from './kafka-settings.js';\nimport { assertCanSubscribe, type KafkaTransportState } from './kafka-subscription-rules.js';\nimport { decodeRecord, deadLetterRecord } from './kafka-records.js';\nimport { WakeableSleeps } from './wakeable-sleeps.js';\n\nexport type {\n InvalidKafkaMessage,\n InvalidMessagePolicy,\n KafkaInjectedProducer,\n KafkaProcessingOptions,\n KafkaRestartOptions,\n KafkaTransportOptions,\n} from './kafka-options.js';\n\n/** Where a consumed record goes, and what may hear about the records that cannot. */\ntype MessageRoute = {\n readonly onMessage: TransportMessageHandler;\n readonly hooks: TransportSubscriptionHooks | undefined;\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 * The `codec` option changes the wire format, for example to read and write\n * the JSON format of services that do not use relaybus.\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 codec's: the event key by default, so events\n * sharing a key land on one partition and keep their order; records 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 extends SubscribingTransport {\n readonly name: string;\n readonly system = 'kafka';\n readonly #settings: KafkaSettings;\n readonly #producer: KafkaProducerSession;\n readonly #groupJoin: GroupJoinWatch;\n readonly #sleeps = new WakeableSleeps();\n #state: KafkaTransportState = 'idle';\n #consumer: KafkaConsumerLike | undefined;\n #groupJoined = false;\n #consuming = false;\n #restartLoop: Promise<void> | undefined;\n readonly #stalledPartitions = new Set<string>();\n #startConsuming: (() => Promise<void>) | undefined;\n\n constructor(options: KafkaTransportOptions) {\n super();\n this.#settings = resolveKafkaSettings(options);\n this.name = this.#settings.name;\n this.#producer = new KafkaProducerSession(this.#settings, () => this.#state === 'closed');\n this.#groupJoin = new GroupJoinWatch(this.#settings);\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.#producer.isConnected) {\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.#producer.connected();\n }\n\n async publish(envelope: EventEnvelope, destination: string): Promise<void> {\n const producer = await this.#producer.connected();\n await this.#producer.send(producer, {\n topic: destination,\n acks: -1,\n messages: [this.#settings.codec.encode(envelope)],\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 protected openSubscription(subscription: TransportSubscription): Promise<void> {\n return this.#subscribe(subscription);\n }\n\n async #subscribe({ destinations, onMessage, hooks }: TransportSubscription): Promise<void> {\n assertCanSubscribe(this.#state, { settings: this.#settings, destinations });\n this.#state = 'subscribed';\n const { kafka, dialect, groupId } = this.#settings;\n const membership = this.#observeConsumer();\n const consumer = kafka!.consumer(dialect.consumerConfig(this.#settings, membership));\n this.#consumer = consumer;\n this.#groupJoined = !dialect.tracksMembership(consumer);\n dialect.observe(consumer, membership);\n const start = (): Promise<void> =>\n this.#groupJoin.start(consumer, {\n topics: [...destinations],\n fromBeginning: this.#settings.fromBeginning,\n eachMessage: (payload) => this.#handleMessage(payload, { onMessage, hooks }),\n });\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.#settings.logger.log(\n `[KafkaTransport](subscribe) Consuming | transport=${this.name} group=${groupId} topics=${destinations.join(',')}`,\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.pending;\n this.#groupJoined = false;\n this.#producer.markClosed();\n this.#sleeps.wakeAll();\n this.#groupJoin.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 async #handleMessage(payload: KafkaEachMessagePayload, route: MessageRoute): Promise<void> {\n let envelope: EventEnvelope;\n try {\n envelope = decodeRecord(this.#settings.codec, payload);\n } catch (error) {\n // The default codec throws only InvalidKafkaMessageError for bad input; anything else is a bug.\n if (\n this.#settings.codec === cloudEventsBinary &&\n !(error instanceof InvalidKafkaMessageError)\n ) {\n throw toHandlerFailure(error);\n }\n route.hooks?.onInvalidMessage({ destination: payload.topic, error });\n await this.#withRetries(payload, {\n method: 'handleInvalid',\n operation: () => this.#handleInvalid(payload, error),\n });\n return;\n }\n await this.#withRetries(payload, {\n method: 'deliver',\n operation: async () => {\n try {\n await route.onMessage(envelope, { destination: payload.topic });\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);\n }\n },\n });\n }\n\n async #handleInvalid(payload: KafkaEachMessagePayload, error: unknown): Promise<void> {\n const { topic, partition, message } = payload;\n const { message: reason, name, code } = toErrorInfo(error);\n const location = `topic=${topic} partition=${partition} offset=${message.offset}`;\n const errorFields = `errorName=${name}${code === undefined ? '' : ` code=${code}`}`;\n const policy = this.#settings.invalidPolicy;\n const deadLetterTopic = deadLetterTopicFor(policy, topic);\n if (policy === 'skip') {\n this.#settings.logger.error(\n `[KafkaTransport](handleInvalid) Skipping malformed message | ${location} reason=${reason} ${errorFields}`,\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 record = deadLetterRecord(payload, {\n reason,\n name,\n code,\n deadLetterTopic: deadLetterTopic!,\n });\n const producer = await this.#producer.connected();\n await this.#producer.send(producer, record);\n this.#settings.logger.error(\n `[KafkaTransport](handleInvalid) Dead-lettered malformed message | ${location} deadLetterTopic=${deadLetterTopic} reason=${reason} ${errorFields}`,\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, operation }: { readonly method: string; readonly operation: () => Promise<void> },\n ): Promise<void> {\n const { maxAttempts, processingBackoff } = this.#settings.timings;\n const { logger } = 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 logger.error(\n `[KafkaTransport](withRetries) Giving up for now, the record stays uncommitted and will be redelivered | operation=${method} ${location} attempts=${attempt} error=${reason}`,\n );\n throw toHandlerFailure(error);\n }\n logger.warn(\n `[KafkaTransport](withRetries) Attempt failed, retrying | operation=${method} ${location} attempt=${attempt} error=${reason}`,\n );\n await this.#sleeps.sleepInSlices(processingBackoff.delayFor(attempt), {\n sliceMs: this.#settings.timings.heartbeatIntervalMs,\n between: () => payload.heartbeat(),\n stopped: () => this.#state === 'closed',\n });\n }\n }\n }\n\n /** What the transport does when the consumer joins, rebalances, crashes or leaves its group. */\n #observeConsumer(): MembershipListeners {\n const { logger, groupId } = this.#settings;\n return {\n joined: () => {\n this.#groupJoined = true;\n this.#groupJoin.joined();\n logger.log(`[KafkaTransport](observeConsumer) Joined group | group=${groupId}`);\n },\n 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 logger.warn(`[KafkaTransport](observeConsumer) Rebalancing | group=${groupId}`);\n },\n crashed: (event) => this.#handleCrash(event),\n left: () => {\n this.#groupJoined = false;\n },\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.#settings.logger.error(\n `[KafkaTransport](handleCrash) Consumer crashed | group=${this.#settings.groupId} restart=${String(restart)} error=${toErrorInfo(error).message}`,\n );\n this.#groupJoin.failed(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 { logger, groupId, timings } = this.#settings;\n const consumer = this.#consumer!;\n for (let attempt = 1; this.#state === 'subscribed'; attempt += 1) {\n await this.#sleeps.sleep(timings.restartBackoff.delayFor(attempt));\n if (this.#state !== 'subscribed') {\n return;\n }\n await consumer.disconnect().catch(() => undefined);\n try {\n await this.#startConsuming!();\n logger.log(\n `[KafkaTransport](restartConsumer) Consumer restarted | group=${groupId} attempt=${attempt}`,\n );\n return;\n } catch (error) {\n logger.error(\n `[KafkaTransport](restartConsumer) Restart failed, will retry | group=${groupId} attempt=${attempt} error=${toErrorInfo(error).message}`,\n );\n }\n }\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@relaybus/kafka",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "Kafka transport for relaybus: forwards committed outbox events to Kafka topics (CloudEvents binding) and consumes them with an idempotent inbox, so events are not lost between database and Kafka.",
5
5
  "license": "MIT",
6
6
  "author": "Berkcan Şavur <berkcansavur@gmail.com>",
@@ -65,8 +65,8 @@
65
65
  },
66
66
  "peerDependencies": {
67
67
  "kafkajs": "^2.2.4",
68
- "@confluentinc/kafka-javascript": ">=1.0.0",
69
- "@relaybus/core": "^0.3.0"
68
+ "@confluentinc/kafka-javascript": "^1.11.0",
69
+ "@relaybus/core": "^0.4.0"
70
70
  },
71
71
  "peerDependenciesMeta": {
72
72
  "kafkajs": {
@@ -80,8 +80,9 @@
80
80
  "kafkajs": "2.2.4",
81
81
  "@testcontainers/kafka": "12.2.1",
82
82
  "testcontainers": "12.2.1",
83
- "@relaybus/testing": "0.3.0",
84
- "@relaybus/core": "0.3.0"
83
+ "@confluentinc/kafka-javascript": "1.11.0",
84
+ "@relaybus/core": "0.4.0",
85
+ "@relaybus/testing": "0.4.0"
85
86
  },
86
87
  "scripts": {
87
88
  "build": "tsup",