kafka-crab-js 2.1.0-beta.1 → 2.1.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/README.md +1 -1
- package/dist/index.cjs +0 -16
- package/dist/index.cjs.map +2 -2
- package/dist/index.js +0 -16
- package/dist/index.js.map +2 -2
- package/dist/streams/base-kafka-stream-readable.d.ts +0 -6
- package/js-binding.cjs +52 -52
- package/js-binding.d.ts +92 -0
- package/js-binding.js +52 -52
- package/package.json +8 -8
package/README.md
CHANGED
|
@@ -61,7 +61,7 @@ This major version includes important breaking changes that improve API consiste
|
|
|
61
61
|
- **After**: `consumer.subscribe([{ topic: 'my-topic', createTopic: true }])`
|
|
62
62
|
|
|
63
63
|
2. **Stream Lifecycle Management**:
|
|
64
|
-
- Stream consumers now properly implement Node.js stream lifecycle methods (`_destroy()
|
|
64
|
+
- Stream consumers now properly implement Node.js stream lifecycle methods (`_destroy()`)
|
|
65
65
|
- **Memory leak prevention**: Streams now automatically disconnect Kafka consumers during destruction
|
|
66
66
|
- Better resource cleanup ensures no hanging connections or memory leaks
|
|
67
67
|
- Error handling during stream destruction is improved with proper error propagation
|
package/dist/index.cjs
CHANGED
|
@@ -685,14 +685,6 @@ var BaseKafkaStreamReadable = class extends import_node_stream.Readable {
|
|
|
685
685
|
* @private
|
|
686
686
|
*/
|
|
687
687
|
_destroy(error, callback) {
|
|
688
|
-
try {
|
|
689
|
-
this.push(null);
|
|
690
|
-
} catch {
|
|
691
|
-
}
|
|
692
|
-
try {
|
|
693
|
-
this.emit("end");
|
|
694
|
-
} catch {
|
|
695
|
-
}
|
|
696
688
|
try {
|
|
697
689
|
this.kafkaConsumer.unsubscribe();
|
|
698
690
|
} catch {
|
|
@@ -704,14 +696,6 @@ var BaseKafkaStreamReadable = class extends import_node_stream.Readable {
|
|
|
704
696
|
callback(combinedError);
|
|
705
697
|
});
|
|
706
698
|
}
|
|
707
|
-
/**
|
|
708
|
-
* Called when the stream is finishing (no more data will be written)
|
|
709
|
-
* Ensures proper cleanup when stream ends normally
|
|
710
|
-
* @private
|
|
711
|
-
*/
|
|
712
|
-
_final(callback) {
|
|
713
|
-
this.kafkaConsumer.disconnect().then(() => callback()).catch((error) => callback(error));
|
|
714
|
-
}
|
|
715
699
|
};
|
|
716
700
|
|
|
717
701
|
// js-src/streams/kafka-batch-stream-readable.ts
|
package/dist/index.cjs.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../js-src/index.ts", "../js-src/kafka-client.ts", "../js-src/otel/instrumentation.ts", "../js-src/otel/constants.ts", "../js-src/otel/types.ts", "../js-src/otel/utils.ts", "../js-src/streams/base-kafka-stream-readable.ts", "../js-src/streams/kafka-batch-stream-readable.ts", "../js-src/streams/kafka-stream-readable.ts"],
|
|
4
|
-
"sourcesContent": ["export type {\n ConsumerConfiguration,\n KafkaConfiguration,\n KafkaCrabError,\n KafkaEvent,\n KafkaEventPayload,\n Message,\n MessageProducer,\n OffsetModel,\n PartitionOffset,\n ProducerConfiguration,\n ProducerRecord,\n RecordMetadata,\n TopicPartition,\n TopicPartitionConfig,\n} from '../js-binding.js'\n\nexport {\n CommitMode,\n KafkaClientConfig,\n KafkaConsumer,\n KafkaEventName,\n KafkaProducer,\n PartitionPosition,\n SecurityProtocol,\n} from '../js-binding.js'\nexport { KafkaClient } from './kafka-client.js'\nexport { BaseKafkaStreamReadable } from './streams/base-kafka-stream-readable.js'\nexport { KafkaBatchStreamReadable } from './streams/kafka-batch-stream-readable.js'\nexport { KafkaStreamReadable } from './streams/kafka-stream-readable.js'\n\nexport type { KafkaClientConfiguration, StreamConsumerConfiguration } from './kafka-client.js'\n\n// OpenTelemetry exports\nexport type {\n BatchOtelContext,\n InstrumentedMessage,\n InstrumentedProducerRecord,\n KafkaOtelContext,\n KafkaOtelInstrumentationConfig,\n MessageHookFn,\n ProducerHookFn,\n TopicFilterFn,\n} from './otel/types.js'\n\nexport { getKafkaInstrumentation, KafkaCrabInstrumentation, resetKafkaInstrumentation } from './otel/instrumentation.js'\n\nexport { KAFKA_OPERATION_TYPES, KAFKA_SEMANTIC_CONVENTIONS, PACKAGE_INFO } from './otel/constants.js'\n", "import { context, type Span } from '@opentelemetry/api'\nimport type { ReadableOptions } from 'node:stream'\nimport {\n type ConsumerConfiguration,\n KafkaClientConfig,\n type KafkaConfiguration,\n type KafkaConsumer,\n type KafkaProducer,\n type ProducerConfiguration,\n} from '../js-binding.js'\n\nimport { getKafkaInstrumentation } from './otel/instrumentation.js'\nimport type { KafkaOtelContext, KafkaOtelInstrumentationConfig } from './otel/types.js'\nimport { KafkaBatchStreamReadable } from './streams/kafka-batch-stream-readable.js'\nimport { KafkaStreamReadable } from './streams/kafka-stream-readable.js'\n\nexport interface StreamConsumerConfiguration extends ConsumerConfiguration {\n batchSize?: number // Default 1 (single mode), > 1 enables batch mode\n batchTimeout?: number // Default 100ms, only used when batchSize > 1\n streamOptions?: ReadableOptions\n}\n\nexport interface KafkaClientConfiguration extends KafkaConfiguration {\n otel?: KafkaOtelInstrumentationConfig | false // OTEL configuration or false to disable\n}\n\n/**\n * KafkaClient class\n */\nexport class KafkaClient {\n private readonly kafkaClientConfig: KafkaClientConfig\n private readonly _otelEnabled: boolean\n private readonly _otelContext: KafkaOtelContext\n\n /**\n * Creates a KafkaClient instance\n * @throws {Error} If the configuration is invalid\n */\n constructor(private readonly kafkaConfiguration: KafkaClientConfiguration) {\n // Extract OTEL configuration\n const { otel, ...kafkaConfig } = kafkaConfiguration\n this.kafkaClientConfig = new KafkaClientConfig(kafkaConfig)\n\n // Initialize OTEL instrumentation\n this._otelEnabled = otel !== false && otel !== null\n if (this._otelEnabled && typeof otel === 'object') {\n const instrumentation = getKafkaInstrumentation(otel)\n this._otelContext = instrumentation.createOtelContext()\n } else if (this._otelEnabled) {\n const instrumentation = getKafkaInstrumentation()\n this._otelContext = instrumentation.createOtelContext()\n } else {\n this._otelContext = this._createDisabledOtelContext()\n }\n }\n\n /**\n * Get the OpenTelemetry context for this client\n * @returns {KafkaOtelContext} The OTEL context\n */\n get otel(): KafkaOtelContext {\n return this._otelContext\n }\n\n /**\n * Creates a KafkaProducer instance\n * @param {ProducerConfiguration} [producerConfiguration] - Optional producer configuration\n * @returns {KafkaProducer} A KafkaProducer instance\n */\n createProducer(producerConfiguration?: ProducerConfiguration) {\n const producer = producerConfiguration\n ? this.kafkaClientConfig.createProducer(producerConfiguration)\n : this.kafkaClientConfig.createProducer({})\n\n // Instrument producer if OTEL is enabled\n if (this._otelEnabled && this._otelContext.enabled) {\n return this._instrumentProducer(producer)\n }\n\n return producer\n }\n\n /**\n * Creates a KafkaConsumer instance\n * @param {ConsumerConfiguration} consumerConfiguration - Consumer configuration\n * @returns {KafkaConsumer} A KafkaConsumer instance\n * @throws {Error} If the configuration is invalid\n */\n createConsumer(consumerConfiguration: ConsumerConfiguration) {\n const consumer = this.kafkaClientConfig.createConsumer(consumerConfiguration)\n\n // Instrument consumer if OTEL is enabled\n if (this._otelEnabled && this._otelContext.enabled) {\n return KafkaClient._instrumentConsumer(consumer, consumerConfiguration.groupId)\n }\n\n return consumer\n }\n\n /**\n * Creates a stream consumer instance\n * @param {StreamConsumerConfiguration} streamConfiguration - Stream consumer configuration including batch mode and stream options\n * @returns {KafkaStreamReadable | KafkaBatchStreamReadable} A stream consumer instance\n * @throws {Error} If the configuration is invalid\n */\n createStreamConsumer(\n streamConfiguration: StreamConsumerConfiguration,\n ): KafkaStreamReadable | KafkaBatchStreamReadable {\n const { batchSize, batchTimeout, streamOptions, ...consumerConfiguration } = streamConfiguration\n const kafkaConsumer = this.kafkaClientConfig.createConsumer(consumerConfiguration)\n const instrumentedConsumer = this._otelEnabled && this._otelContext.enabled\n ? KafkaClient._instrumentConsumer(kafkaConsumer, consumerConfiguration.groupId)\n : kafkaConsumer\n const opts = streamOptions ?? { objectMode: true }\n\n // Return appropriate class based on batch configuration\n if (batchSize && batchSize > 1) {\n return new KafkaBatchStreamReadable({ kafkaConsumer: instrumentedConsumer, batchSize, batchTimeout, ...opts })\n }\n\n return new KafkaStreamReadable({ kafkaConsumer: instrumentedConsumer, ...opts })\n }\n\n private _instrumentProducer(producer: KafkaProducer) {\n const instrumentation = getKafkaInstrumentation()\n const originalSend = producer.send.bind(producer)\n\n producer.send = instrumentation.instrumentProducerSend(\n originalSend,\n this.kafkaConfiguration.clientId,\n )\n\n return producer\n }\n\n private static _instrumentConsumer(consumer: KafkaConsumer, groupId?: string) {\n const instrumentation = getKafkaInstrumentation()\n const originalRecv = consumer.recv.bind(consumer)\n const originalRecvBatch = consumer.recvBatch.bind(consumer)\n\n consumer.recv = instrumentation.instrumentConsumerReceive(originalRecv, groupId)\n consumer.recvBatch = instrumentation.instrumentBatchReceive(originalRecvBatch, groupId)\n\n return consumer\n }\n\n // eslint-disable-next-line class-methods-use-this\n private _createDisabledOtelContext(): KafkaOtelContext {\n // Provide safe no-op implementations so callers can still invoke methods without guarding\n return {\n enabled: false,\n span: null,\n tracer: null,\n context: context.active(),\n inject: () => {\n /* no-op */\n },\n extract: () => context.active(),\n startSpan: () => null,\n endSpan: (span?: Span | null) => {\n if (span && typeof span.end === 'function') {\n span.end()\n }\n },\n }\n }\n}\n", "import { type Attributes, context, diag, type Span, trace, type Tracer } from '@opentelemetry/api'\n\nimport type { KafkaConsumer, KafkaProducer, Message, ProducerRecord, RecordMetadata } from '../../js-binding.js'\nimport { PACKAGE_INFO } from './constants.js'\nimport {\n DEFAULT_OTEL_CONFIG,\n type KafkaOtelContext,\n type KafkaOtelInstrumentationConfig,\n type TracerProvider,\n} from './types.js'\nimport {\n createBatchSpan,\n createConsumerSpan,\n createProducerSpan,\n extractTraceContext,\n getTracer,\n injectTraceContext,\n normalizeHeadersToBuffer,\n setSpanStatus,\n shouldIgnoreTopic,\n} from './utils.js'\n\nexport class KafkaCrabInstrumentation {\n private _kafkaTracer: Tracer | null = null\n private _kafkaConfig: KafkaOtelInstrumentationConfig\n private _enabled = false\n\n constructor(config: KafkaOtelInstrumentationConfig = {}) {\n this._kafkaConfig = { ...DEFAULT_OTEL_CONFIG, ...config }\n }\n\n public get kafkaConfig(): KafkaOtelInstrumentationConfig {\n return this._kafkaConfig\n }\n\n public get kafkaTracer(): Tracer | null {\n return this._kafkaTracer\n }\n\n public updateConfig(config: KafkaOtelInstrumentationConfig): void {\n this._kafkaConfig = { ...this._kafkaConfig, ...config }\n }\n\n public setTracerProvider(provider: TracerProvider): void {\n this._kafkaTracer = provider.getTracer(PACKAGE_INFO.NAME, PACKAGE_INFO.VERSION)\n }\n\n public enable(): void {\n this._kafkaTracer = getTracer(PACKAGE_INFO.NAME, PACKAGE_INFO.VERSION)\n this._enabled = true\n\n if (this._kafkaConfig?.registerOnInitialization && this._kafkaTracer) {\n diag.debug('Kafka OTEL instrumentation enabled')\n }\n }\n\n public disable(): void {\n this._kafkaTracer = null\n this._enabled = false\n diag.debug('Kafka OTEL instrumentation disabled')\n }\n\n public isEnabled(): boolean {\n return this._enabled && this._kafkaTracer !== null\n }\n\n public createOtelContext(): KafkaOtelContext {\n if (!this.isEnabled()) {\n return this._createDisabledContext()\n }\n\n return {\n enabled: true,\n span: trace.getActiveSpan() || null,\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n tracer: this._kafkaTracer!,\n context: context.active(),\n inject: (carrier, spanToInject?: Span) => {\n if (spanToInject) {\n const spanContext = trace.setSpan(context.active(), spanToInject)\n injectTraceContext(carrier, spanContext)\n return\n }\n\n const activeSpan = trace.getActiveSpan()\n if (activeSpan) {\n const spanContext = trace.setSpan(context.active(), activeSpan)\n injectTraceContext(carrier, spanContext)\n } else {\n injectTraceContext(carrier, context.active())\n }\n },\n extract: (carrier) => extractTraceContext(carrier),\n startSpan: (name, attributes: Attributes = {}) => {\n if (!this._kafkaTracer) {\n throw new Error('Tracer not available')\n }\n const span = this._kafkaTracer.startSpan(name, { attributes })\n return span\n },\n endSpan: (span, error) => {\n if (!span) {\n return\n }\n setSpanStatus(span, error)\n span.end()\n },\n }\n }\n\n public instrumentProducerSend(\n originalSend: Function,\n clientId?: string,\n ): (producerRecord: ProducerRecord) => Promise<RecordMetadata[]> {\n if (!this.isEnabled()) {\n return originalSend as (producerRecord: ProducerRecord) => Promise<RecordMetadata[]>\n }\n\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const instrumentation = this\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const tracer = this._kafkaTracer!\n\n return async function instrumentedSend(this: KafkaProducer, record: ProducerRecord | ProducerRecord[]) {\n if (!record) {\n return originalSend.call(this, record as ProducerRecord)\n }\n\n const callerContext = context.active()\n\n const isArrayInput = Array.isArray(record)\n const records = isArrayInput ? record : [record]\n\n if (records.length === 0) {\n return originalSend.call(this, isArrayInput ? records : (record as ProducerRecord))\n }\n\n const allIgnored = records.every((currentRecord) =>\n shouldIgnoreTopic(currentRecord.topic, instrumentation._kafkaConfig.ignoreTopics)\n )\n\n if (allIgnored) {\n return originalSend.call(this, isArrayInput ? records : records[0])\n }\n\n const spans: Span[] = []\n const spanMetadata: { span: Span; record: ProducerRecord }[] = []\n\n const instrumentedRecords = records.map((currentRecord) => {\n if (!currentRecord || shouldIgnoreTopic(currentRecord.topic, instrumentation._kafkaConfig.ignoreTopics)) {\n return currentRecord\n }\n\n const span = createProducerSpan(tracer, currentRecord, 'send', callerContext)\n\n if (!span) {\n return currentRecord\n }\n\n if (clientId) {\n span.setAttributes({ 'messaging.client.id': clientId })\n }\n\n spans.push(span)\n spanMetadata.push({ span, record: currentRecord })\n\n const spanContext = trace.setSpan(callerContext, span)\n\n const instrumentedRecord: ProducerRecord = {\n ...currentRecord,\n messages: (currentRecord.messages ?? []).map(message => {\n const originalHeaders = { ...message.headers }\n const injectedHeaders = injectTraceContext(originalHeaders, spanContext)\n const normalizedHeaders = normalizeHeadersToBuffer(injectedHeaders)\n\n return {\n ...message,\n headers: normalizedHeaders,\n }\n }),\n }\n\n if (instrumentation._kafkaConfig.producerHook) {\n try {\n context.with(spanContext, () => {\n instrumentation._kafkaConfig.producerHook?.(span, currentRecord)\n })\n } catch (error) {\n diag.warn('Producer hook failed:', error)\n }\n }\n\n return instrumentedRecord\n })\n\n const payload = isArrayInput ? instrumentedRecords : instrumentedRecords[0]\n\n try {\n const result = await context.with(callerContext, async () => originalSend.call(this, payload as ProducerRecord))\n\n const metadataArray = Array.isArray(result) ? result : []\n for (let idx = 0; idx < spanMetadata.length; idx++) {\n const { span } = spanMetadata[idx]\n const metadata = metadataArray[idx]\n if (metadata) {\n if (metadata.partition !== undefined) {\n span.setAttribute('messaging.kafka.partition', metadata.partition)\n }\n if (metadata.offset !== undefined) {\n span.setAttribute('messaging.kafka.offset', metadata.offset)\n }\n }\n setSpanStatus(span, metadata?.error ? new Error(metadata.error.message) : undefined)\n span.end()\n }\n\n if (instrumentation._kafkaConfig.producerHook && metadataArray.length) {\n const [first] = spanMetadata\n if (first) {\n try {\n instrumentation._kafkaConfig.producerHook(first.span, first.record, metadataArray[0])\n } catch (error) {\n diag.warn('Producer hook failed with metadata:', error)\n }\n }\n }\n\n return result\n } catch (error) {\n for (const span of spans) {\n setSpanStatus(span, error instanceof Error ? error : new Error(String(error)))\n span.end()\n }\n throw error\n }\n }\n }\n\n public instrumentConsumerReceive(originalReceive: Function, groupId?: string): () => Promise<Message | null> {\n if (!this.isEnabled()) {\n return originalReceive as () => Promise<Message | null>\n }\n\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const instrumentation = this\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const tracer = this._kafkaTracer!\n\n return async function instrumentedReceive(this: KafkaConsumer) {\n const message = await originalReceive.call(this)\n\n if (!message) {\n return message\n }\n\n if (shouldIgnoreTopic(message.topic, instrumentation._kafkaConfig.ignoreTopics)) {\n return message\n }\n\n const parentContext = extractTraceContext(message.headers || {}) || context.active()\n const span = createConsumerSpan(tracer, message, 'process', parentContext)\n\n if (span) {\n const spanCtx = trace.setSpan(parentContext, span)\n\n context.with(spanCtx, () => {\n if (groupId) {\n span.setAttributes({ 'messaging.consumer.group.name': groupId })\n }\n\n if (instrumentation._kafkaConfig.messageHook) {\n try {\n instrumentation._kafkaConfig.messageHook(span, message)\n } catch (error) {\n diag.warn('Message hook failed:', error)\n }\n }\n\n setSpanStatus(span)\n })\n\n span.end()\n }\n\n return message\n }\n }\n\n public instrumentBatchReceive(\n originalBatchReceive: Function,\n groupId?: string,\n ): (size: number, timeoutMs: number) => Promise<Message[]> {\n if (!this.isEnabled() || !this._kafkaConfig.enableBatchInstrumentation) {\n return originalBatchReceive as (size: number, timeoutMs: number) => Promise<Message[]>\n }\n\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const instrumentation = this\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const tracer = this._kafkaTracer!\n\n return async function instrumentedBatchReceive(this: KafkaConsumer, size: number, timeoutMs: number) {\n const messages = await originalBatchReceive.call(this, size, timeoutMs)\n\n if (!Array.isArray(messages) || messages.length === 0) {\n return messages\n }\n\n const instrumentedMessages = messages.filter((message: Message) =>\n !shouldIgnoreTopic(message.topic, instrumentation._kafkaConfig.ignoreTopics)\n )\n\n if (instrumentedMessages.length === 0) {\n return messages\n }\n\n const [firstMessage] = instrumentedMessages\n const parentContext = extractTraceContext(firstMessage.headers || {}) || context.active()\n const batchSpan = createBatchSpan(\n tracer,\n instrumentedMessages.length,\n firstMessage.topic,\n 'batch_process',\n parentContext,\n )\n\n if (batchSpan) {\n if (groupId) {\n batchSpan.setAttributes({ 'messaging.consumer.group.name': groupId })\n }\n\n try {\n for (const message of instrumentedMessages) {\n const msgParentContext = extractTraceContext(message.headers || {}) || parentContext\n const messageSpan = createConsumerSpan(tracer, message, 'process', msgParentContext)\n\n if (messageSpan) {\n const messageSpanContext = trace.setSpan(msgParentContext || context.active(), messageSpan)\n context.with(messageSpanContext, () => {\n messageSpan.setAttributes({\n 'messaging.batch.message_count': instrumentedMessages.length,\n })\n\n if (instrumentation._kafkaConfig.messageHook) {\n try {\n instrumentation._kafkaConfig.messageHook(messageSpan, message)\n } catch (error) {\n diag.warn('Message hook failed:', error)\n }\n }\n\n setSpanStatus(messageSpan)\n })\n messageSpan.end()\n }\n }\n\n setSpanStatus(batchSpan)\n } catch (error) {\n setSpanStatus(batchSpan, error instanceof Error ? error : new Error(String(error)))\n } finally {\n batchSpan.end()\n }\n }\n\n return messages\n }\n }\n\n // eslint-disable-next-line class-methods-use-this\n private _createDisabledContext(): KafkaOtelContext {\n return {\n enabled: false,\n span: null,\n tracer: null,\n context: context.active(),\n inject: () => {\n /* no-op */\n },\n extract: () => context.active(),\n startSpan: () => null,\n endSpan: () => {\n /* no-op */\n },\n }\n }\n}\n\n// Singleton instance for global use\nlet globalInstrumentation: KafkaCrabInstrumentation | null = null\n\nexport function getKafkaInstrumentation(config?: KafkaOtelInstrumentationConfig): KafkaCrabInstrumentation {\n if (!globalInstrumentation) {\n globalInstrumentation = new KafkaCrabInstrumentation(config)\n globalInstrumentation.enable()\n } else if (config) {\n globalInstrumentation.updateConfig(config)\n }\n return globalInstrumentation\n}\n\nexport function resetKafkaInstrumentation(): void {\n if (globalInstrumentation) {\n globalInstrumentation.disable()\n globalInstrumentation = null\n }\n}\n", "// OpenTelemetry semantic conventions for Kafka messaging\nexport const KAFKA_SEMANTIC_CONVENTIONS = {\n // Messaging system attributes (https://opentelemetry.io/docs/specs/semconv/messaging/messaging-spans/)\n MESSAGING_SYSTEM: 'messaging.system',\n MESSAGING_DESTINATION_NAME: 'messaging.destination.name',\n MESSAGING_DESTINATION_KIND: 'messaging.destination.kind',\n MESSAGING_OPERATION_NAME: 'messaging.operation.name',\n MESSAGING_OPERATION_TYPE: 'messaging.operation.type',\n MESSAGING_CLIENT_ID: 'messaging.client.id',\n MESSAGING_MESSAGE_ID: 'messaging.message.id',\n MESSAGING_MESSAGE_BODY_SIZE: 'messaging.message.body.size',\n MESSAGING_BATCH_MESSAGE_COUNT: 'messaging.batch.message_count',\n\n // Kafka-specific attributes\n MESSAGING_KAFKA_OFFSET: 'messaging.kafka.offset',\n MESSAGING_KAFKA_PARTITION: 'messaging.kafka.partition',\n MESSAGING_KAFKA_MESSAGE_KEY: 'messaging.kafka.message.key',\n MESSAGING_KAFKA_CONSUMER_GROUP: 'messaging.kafka.consumer.group',\n MESSAGING_KAFKA_TOMBSTONE: 'messaging.kafka.tombstone',\n\n // Consumer-specific attributes\n MESSAGING_CONSUMER_GROUP_NAME: 'messaging.consumer.group.name',\n} as const\n\n// Operation types\nexport const KAFKA_OPERATION_TYPES = {\n SEND: 'send',\n RECEIVE: 'receive',\n PROCESS: 'process',\n BATCH_RECEIVE: 'batch_receive',\n BATCH_PROCESS: 'batch_process',\n} as const\n\n// Span names\nexport const KAFKA_SPAN_NAMES = {\n PRODUCER_SEND: (topic: string) => `${topic} send`,\n CONSUMER_RECEIVE: (topic: string) => `${topic} receive`,\n CONSUMER_PROCESS: (topic: string) => `${topic} process`,\n BATCH_RECEIVE: 'kafka batch receive',\n BATCH_PROCESS: (topic: string) => `${topic} batch process`,\n} as const\n\n// Default values\nexport const KAFKA_DEFAULTS = {\n MESSAGING_SYSTEM: 'kafka',\n DESTINATION_KIND: 'topic',\n BATCH_TIMEOUT_MS: 1000,\n} as const\n\n// Package information\nexport const PACKAGE_INFO = {\n NAME: 'kafka-crab-js',\n VERSION: '2.1.0', // Should match package.json\n} as const\n", "import type { Attributes, Context, Span, Tracer } from '@opentelemetry/api'\nimport type { Message, ProducerRecord, RecordMetadata } from '../../js-binding.js'\n\n// InstrumentationConfig interface (simplified from @opentelemetry/instrumentation)\nexport interface InstrumentationConfig {\n enabled?: boolean\n}\n\n// OpenTelemetry TracerProvider interface\nexport interface TracerProvider {\n getTracer(name: string, version?: string, options?: unknown): Tracer\n}\n\n// Use the actual types from js-binding instead of custom interfaces\n// This avoids type compatibility issues with the real implementations\n\n// Configuration interface for Kafka OTEL instrumentation\nexport interface KafkaOtelInstrumentationConfig extends InstrumentationConfig {\n // Service name for telemetry (defaults to OTEL_SERVICE_NAME env var or 'kafka-client')\n serviceName?: string\n\n // Whether to register instrumentation automatically on initialization\n registerOnInitialization?: boolean\n\n // Function to filter topics from instrumentation\n ignoreTopics?: string[] | ((topic: string) => boolean)\n\n // Custom hook called for each message/span\n messageHook?: (span: Span, message: Message) => void\n\n // Custom hook called for producer operations\n producerHook?: (span: Span, record: ProducerRecord, metadata?: RecordMetadata) => void\n\n // Whether to capture message payloads as span attributes (security sensitive)\n captureMessagePayload?: boolean\n\n // Maximum size of message payload to capture (in bytes)\n maxPayloadSize?: number\n\n // Whether to capture message headers as span attributes\n captureMessageHeaders?: boolean\n\n // Whether to enable batch operation instrumentation\n enableBatchInstrumentation?: boolean\n}\n\n// OpenTelemetry context interface exposed by clients\nexport interface KafkaOtelContext {\n // Whether OTEL is enabled for this client\n enabled: boolean\n\n // Current active span (if any)\n span: Span | null\n\n // Tracer instance for creating spans\n tracer: Tracer | null\n\n // Current OTEL context\n context: Context | null\n\n // Inject trace context into carrier (e.g., Kafka headers)\n inject: (carrier: Record<string, string | string[] | undefined>) => void\n\n // Extract trace context from carrier (e.g., Kafka headers)\n extract: (carrier: Record<string, string | string[] | undefined>) => Context\n\n // Create a child span with proper context\n startSpan: (name: string, attributes?: Attributes) => Span | null\n\n // End a span with proper status handling\n endSpan: (span: Span | null | undefined, error?: Error) => void\n}\n\n// Enhanced message interface with OTEL context\nexport interface InstrumentedMessage extends Message {\n // Extracted OTEL context from message headers\n otelContext?: Context\n\n // Optional span created for this message\n span?: Span\n}\n\n// Enhanced producer record with OTEL context injection\nexport interface InstrumentedProducerRecord extends ProducerRecord {\n // Headers will be automatically injected with trace context\n headers?: Record<string, string | string[] | undefined>\n\n // Optional span for tracking this record\n span?: Span\n}\n\n// Batch processing context\nexport interface BatchOtelContext {\n // Parent span for the entire batch\n batchSpan: Span\n\n // Individual message spans within the batch\n messageSpans: Span[]\n\n // Batch size for telemetry\n batchSize: number\n\n // Processing start time\n startTime: number\n}\n\n// Hook function signatures\nexport type MessageHookFn = (span: Span, message: Message) => void\nexport type ProducerHookFn = (span: Span, record: ProducerRecord, metadata?: RecordMetadata) => void\nexport type TopicFilterFn = (topic: string) => boolean\n\n// Configuration defaults\nexport const DEFAULT_OTEL_CONFIG: Required<\n Pick<\n KafkaOtelInstrumentationConfig,\n | 'serviceName'\n | 'registerOnInitialization'\n | 'captureMessagePayload'\n | 'maxPayloadSize'\n | 'captureMessageHeaders'\n | 'enableBatchInstrumentation'\n >\n> = {\n serviceName: process.env.OTEL_SERVICE_NAME || 'kafka-client',\n registerOnInitialization: true,\n captureMessagePayload: false,\n maxPayloadSize: 1024,\n captureMessageHeaders: true,\n enableBatchInstrumentation: true,\n} as const\n", "import {\n type Attributes,\n type Context,\n context,\n propagation,\n type Span,\n SpanKind,\n SpanStatusCode,\n trace,\n type Tracer,\n} from '@opentelemetry/api'\nimport type { Message, ProducerRecord } from '../../js-binding.js'\nimport { KAFKA_DEFAULTS, KAFKA_SEMANTIC_CONVENTIONS } from './constants.js'\n\n// Safely get tracer\nexport function getTracer(name: string, version?: string) {\n return trace.getTracer(name, version)\n}\n\n// Set span status based on error\nexport function setSpanStatus(span: Span, error?: Error): void {\n if (error) {\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: error.message,\n })\n span.recordException(error)\n } else {\n span.setStatus({ code: SpanStatusCode.OK })\n }\n}\n\n// Extract common Kafka attributes from message\nexport function getMessageAttributes(message: Message, operation: string): Attributes {\n const attributes: Attributes = {\n [KAFKA_SEMANTIC_CONVENTIONS.MESSAGING_SYSTEM]: KAFKA_DEFAULTS.MESSAGING_SYSTEM,\n [KAFKA_SEMANTIC_CONVENTIONS.MESSAGING_DESTINATION_NAME]: message.topic,\n [KAFKA_SEMANTIC_CONVENTIONS.MESSAGING_DESTINATION_KIND]: KAFKA_DEFAULTS.DESTINATION_KIND,\n [KAFKA_SEMANTIC_CONVENTIONS.MESSAGING_OPERATION_NAME]: operation,\n [KAFKA_SEMANTIC_CONVENTIONS.MESSAGING_KAFKA_PARTITION]: message.partition,\n [KAFKA_SEMANTIC_CONVENTIONS.MESSAGING_KAFKA_OFFSET]: message.offset,\n }\n\n // Add optional attributes if present\n if (message.key !== null && message.key !== undefined) {\n attributes[KAFKA_SEMANTIC_CONVENTIONS.MESSAGING_KAFKA_MESSAGE_KEY] = typeof message.key === 'string'\n ? message.key\n : String(message.key)\n }\n\n if (message.payload) {\n let payloadSize: number\n if (Buffer.isBuffer(message.payload)) {\n payloadSize = message.payload.length\n } else if (typeof message.payload === 'string') {\n payloadSize = Buffer.byteLength(message.payload, 'utf8')\n } else {\n payloadSize = JSON.stringify(message.payload).length\n }\n attributes[KAFKA_SEMANTIC_CONVENTIONS.MESSAGING_MESSAGE_BODY_SIZE] = payloadSize\n }\n\n return attributes\n}\n\n// Extract common Kafka attributes from producer record\nexport function getProducerRecordAttributes(record: ProducerRecord, operation: string): Attributes {\n const attributes: Attributes = {\n [KAFKA_SEMANTIC_CONVENTIONS.MESSAGING_SYSTEM]: KAFKA_DEFAULTS.MESSAGING_SYSTEM,\n [KAFKA_SEMANTIC_CONVENTIONS.MESSAGING_DESTINATION_NAME]: record.topic,\n [KAFKA_SEMANTIC_CONVENTIONS.MESSAGING_DESTINATION_KIND]: KAFKA_DEFAULTS.DESTINATION_KIND,\n [KAFKA_SEMANTIC_CONVENTIONS.MESSAGING_OPERATION_NAME]: operation,\n }\n\n // Add message count\n if (record.messages && record.messages.length > 0) {\n attributes[KAFKA_SEMANTIC_CONVENTIONS.MESSAGING_BATCH_MESSAGE_COUNT] = record.messages.length\n\n // Use first message for key and payload size\n const [firstMessage] = record.messages\n\n // Add key if present\n if (firstMessage.key !== null && firstMessage.key !== undefined) {\n attributes[KAFKA_SEMANTIC_CONVENTIONS.MESSAGING_KAFKA_MESSAGE_KEY] = Buffer.isBuffer(firstMessage.key)\n ? firstMessage.key.toString()\n : String(firstMessage.key)\n }\n\n // Add payload size if present\n if (firstMessage.payload) {\n let payloadSize: number\n if (Buffer.isBuffer(firstMessage.payload)) {\n payloadSize = firstMessage.payload.length\n } else if (typeof firstMessage.payload === 'string') {\n payloadSize = Buffer.byteLength(firstMessage.payload, 'utf8')\n } else {\n payloadSize = JSON.stringify(firstMessage.payload).length\n }\n attributes[KAFKA_SEMANTIC_CONVENTIONS.MESSAGING_MESSAGE_BODY_SIZE] = payloadSize\n }\n }\n\n return attributes\n}\n\n// Convert Buffer headers to string headers for trace context injection\nfunction convertBufferHeaders(\n bufferHeaders: Record<string, Buffer> = {},\n): Record<string, string | string[] | undefined> {\n const stringHeaders: Record<string, string | string[] | undefined> = {}\n for (const [key, value] of Object.entries(bufferHeaders)) {\n stringHeaders[key] = value.toString('utf8')\n }\n return stringHeaders\n}\n\n// Convert string headers back to Buffer headers\nfunction convertToBufferHeaders(stringHeaders: Record<string, string | string[] | undefined>): Record<string, Buffer> {\n const bufferHeaders: Record<string, Buffer> = {}\n for (const [key, value] of Object.entries(stringHeaders)) {\n if (value !== undefined) {\n const stringValue = Array.isArray(value) ? value.join(',') : value\n bufferHeaders[key] = Buffer.from(stringValue, 'utf8')\n }\n }\n return bufferHeaders\n}\n\nexport type KafkaHeaderValue = Buffer | string | string[] | undefined\nexport type KafkaHeaderCarrier = Record<string, KafkaHeaderValue>\n\n// Inject trace context into Kafka headers (works with both string and Buffer headers)\nexport function injectTraceContext(\n headers: KafkaHeaderCarrier = {},\n ctx?: Context,\n): KafkaHeaderCarrier {\n const activeContext = ctx || context.active()\n const headerEntries = Object.entries(headers)\n const hasBufferValues = headerEntries.some(([, value]) => Buffer.isBuffer(value))\n\n // Convert Buffer headers to string headers if needed\n if (hasBufferValues) {\n const bufferCarrier = headers as Record<string, Buffer>\n const stringHeaders = convertBufferHeaders(bufferCarrier)\n\n propagation.inject(activeContext, stringHeaders, {\n set: (carrier: Record<string, string | string[] | undefined>, key: string, value: string) => {\n carrier[key] = value\n },\n })\n\n const bufferHeaders = convertToBufferHeaders(stringHeaders)\n\n for (const [key, value] of Object.entries(bufferHeaders)) {\n bufferCarrier[key] = value\n }\n\n return bufferCarrier\n }\n\n const stringCarrier = headers as Record<string, string | string[] | undefined>\n\n propagation.inject(activeContext, stringCarrier, {\n set: (carrier: Record<string, string | string[] | undefined>, key: string, value: string) => {\n carrier[key] = value\n },\n })\n\n // Preserve original string-based carrier for callers expecting strings\n return stringCarrier\n}\n\n// Normalize any header carrier into Buffer headers for Kafka bindings\nexport function normalizeHeadersToBuffer(headers: KafkaHeaderCarrier): Record<string, Buffer> {\n const bufferHeaders: Record<string, Buffer> = {}\n\n for (const [key, value] of Object.entries(headers)) {\n if (value !== undefined) {\n if (Buffer.isBuffer(value)) {\n bufferHeaders[key] = value\n } else if (Array.isArray(value)) {\n bufferHeaders[key] = Buffer.from(value.join(','), 'utf8')\n } else {\n bufferHeaders[key] = Buffer.from(value, 'utf8')\n }\n }\n }\n\n return bufferHeaders\n}\n\n// Extract trace context from Kafka headers\nexport function extractTraceContext(\n headers: Record<string, string | string[] | undefined> = {},\n): Context {\n return propagation.extract(context.active(), headers, {\n get: (carrier: Record<string, string | string[] | undefined>, key: string) => {\n const value = carrier[key]\n const singleValue = Array.isArray(value) ? value[0] : value\n\n if (Buffer.isBuffer(singleValue)) {\n return singleValue.toString('utf8')\n }\n\n return singleValue\n },\n keys: (carrier: Record<string, string | string[] | undefined>) => Object.keys(carrier),\n })\n}\n\n// Check if topic should be ignored based on filter configuration\nexport function shouldIgnoreTopic(\n topic: string,\n ignoreTopics?: string[] | ((topic: string) => boolean),\n): boolean {\n if (!ignoreTopics) {\n return false\n }\n\n if (Array.isArray(ignoreTopics)) {\n return ignoreTopics.includes(topic)\n }\n\n if (typeof ignoreTopics === 'function') {\n try {\n return ignoreTopics(topic)\n } catch {\n // If filter function throws, don't ignore the topic\n return false\n }\n }\n\n return false\n}\n\n// Create span for producer operation\nexport function createProducerSpan(\n tracer: Tracer,\n record: ProducerRecord,\n operation = 'send',\n parentContext?: Context,\n): Span | null {\n if (!tracer) {\n return null\n }\n const parent = parentContext ?? context.active()\n\n const spanName = `${record.topic} ${operation}`\n const attributes = getProducerRecordAttributes(record, operation)\n\n const spanOptions = {\n kind: SpanKind.PRODUCER,\n attributes,\n }\n\n return tracer.startSpan(spanName, spanOptions, parent)\n}\n\n// Create span for consumer operation\nexport function createConsumerSpan(\n tracer: Tracer,\n message: Message,\n operation = 'process',\n parentContext?: Context,\n): Span | null {\n if (!tracer) {\n return null\n }\n\n const spanName = `${message.topic} ${operation}`\n const attributes = getMessageAttributes(message, operation)\n\n const spanOptions = {\n kind: SpanKind.CONSUMER,\n attributes,\n }\n\n // Start span with parent context if provided\n if (parentContext) {\n return tracer.startSpan(spanName, spanOptions, parentContext)\n }\n\n return tracer.startSpan(spanName, spanOptions)\n}\n\n// Create batch span for batch operations\nexport function createBatchSpan(\n tracer: Tracer,\n batchSize: number,\n topic?: string,\n operation = 'batch_process',\n parentContext?: Context,\n): Span | null {\n if (!tracer) {\n return null\n }\n\n const spanName = topic ? `${topic} ${operation}` : `kafka ${operation}`\n const attributes: Attributes = {\n [KAFKA_SEMANTIC_CONVENTIONS.MESSAGING_SYSTEM]: KAFKA_DEFAULTS.MESSAGING_SYSTEM,\n [KAFKA_SEMANTIC_CONVENTIONS.MESSAGING_OPERATION_NAME]: operation,\n [KAFKA_SEMANTIC_CONVENTIONS.MESSAGING_BATCH_MESSAGE_COUNT]: batchSize,\n }\n\n if (topic) {\n attributes[KAFKA_SEMANTIC_CONVENTIONS.MESSAGING_DESTINATION_NAME] = topic\n attributes[KAFKA_SEMANTIC_CONVENTIONS.MESSAGING_DESTINATION_KIND] = KAFKA_DEFAULTS.DESTINATION_KIND\n }\n\n const spanOptions = {\n kind: SpanKind.CONSUMER,\n attributes,\n }\n\n if (parentContext) {\n return tracer.startSpan(spanName, spanOptions, parentContext)\n }\n\n return tracer.startSpan(spanName, spanOptions)\n}\n", "import { Readable, type ReadableOptions } from 'node:stream'\n\nimport type { CommitMode, KafkaConsumer, Message, OffsetModel, TopicPartitionConfig } from '../../js-binding.js'\n\nexport interface KafkaStreamReadableOptions extends ReadableOptions<Readable> {\n kafkaConsumer: KafkaConsumer\n}\n\n/**\n * Abstract base class for Kafka stream readers\n * @extends Readable\n */\nexport abstract class BaseKafkaStreamReadable extends Readable {\n private _kafkaConsumer: KafkaConsumer\n\n /**\n * Creates a BaseKafkaStreamReadable instance\n */\n constructor(\n streamOptions: KafkaStreamReadableOptions,\n ) {\n const { kafkaConsumer, ...opts } = streamOptions\n\n super(opts)\n\n if (!kafkaConsumer) {\n throw new Error('A valid KafkaConsumer instance is required.')\n }\n\n this._kafkaConsumer = kafkaConsumer\n }\n\n get kafkaConsumer(): KafkaConsumer {\n return this._kafkaConsumer\n }\n\n /**\n * Checks if the stream is currently paused\n * @returns {boolean} True if the stream is paused\n */\n isPaused(): boolean {\n return this.readableFlowing === false\n }\n\n /**\n * Subscribes to topics\n */\n async subscribe(topics: string | Array<TopicPartitionConfig>) {\n if (!topics || (Array.isArray(topics) && topics.length === 0)) {\n throw new Error('Topics must be a non-empty string or array.')\n }\n await this.kafkaConsumer.subscribe(topics)\n }\n\n seek(topic: string, partition: number, offsetModel: OffsetModel, timeout?: number) {\n this.kafkaConsumer.seek(topic, partition, offsetModel, timeout)\n }\n\n async commit(topic: string, partition: number, offset: number, commitMode: CommitMode) {\n return this.kafkaConsumer.commit(topic, partition, offset, commitMode)\n }\n\n /**\n * Commits the offset for a message.\n * This is a convenience method that automatically increments the offset by 1.\n * The offset committed is `message.offset + 1` since Kafka expects the next offset to be consumed.\n * @param message - The message to commit\n * @param commitMode - The commit mode ('Sync' or 'Async')\n */\n async commitMessage(message: Message, commitMode: CommitMode) {\n return this.kafkaConsumer.commitMessage(message, commitMode)\n }\n\n /**\n * Unsubscribe from topics\n */\n unsubscribe() {\n this.kafkaConsumer.unsubscribe()\n }\n\n /**\n * Disconnects the Kafka consumer\n */\n async disconnect() {\n await this.kafkaConsumer.disconnect()\n }\n\n /**\n * Returns the raw Kafka consumer\n * @returns {KafkaConsumer} The Kafka consumer instance\n */\n rawConsumer() {\n return this.kafkaConsumer\n }\n\n /**\n * Called when the stream is being destroyed\n * Ensures proper cleanup of the Kafka consumer\n * @private\n */\n _destroy(error: Error | null, callback: (error?: Error | null) => void): void {\n // Signal end-of-stream to ensure 'end' listeners fire even when destroyed early\n try {\n this.push(null)\n } catch {\n // ignore if already ended\n }\n try {\n this.emit('end')\n } catch {\n // ignore if already emitted\n }\n // Always unsubscribe first to stop receiving messages\n try {\n this.kafkaConsumer.unsubscribe()\n } catch {\n // Silently ignore unsubscribe errors during cleanup - they're non-critical\n // Common when consumer is already disconnected or in invalid state\n }\n\n // Disconnect the consumer\n this.kafkaConsumer\n .disconnect()\n .then(() => {\n // Success: pass through the original error (if any)\n callback(error)\n })\n // eslint-disable-next-line unicorn/catch-error-name\n .catch((disconnectError) => {\n // Failed to disconnect: combine errors\n const combinedError = error\n ? new Error(`Stream error: ${error.message}; Disconnect error: ${disconnectError.message}`)\n : disconnectError\n callback(combinedError)\n })\n }\n\n /**\n * Called when the stream is finishing (no more data will be written)\n * Ensures proper cleanup when stream ends normally\n * @private\n */\n _final(callback: (error?: Error | null) => void): void {\n // For readable streams, _final is called when we push(null)\n // Ensure consumer is properly cleaned up\n this.kafkaConsumer\n .disconnect()\n .then(() => callback())\n .catch((error) => callback(error))\n }\n\n /**\n * Abstract method that must be implemented by concrete classes\n * @private\n */\n abstract _read(): void\n}\n", "import type { Message } from '../../js-binding.js'\nimport { BaseKafkaStreamReadable, type KafkaStreamReadableOptions } from './base-kafka-stream-readable.js'\n\n// Constants for batch configuration\nconst DEFAULT_BATCH_TIMEOUT = 1000\n\nexport interface KafkaBatchStreamReadableOptions extends KafkaStreamReadableOptions {\n batchSize: number\n batchTimeout?: number\n}\n\n/**\n * KafkaBatchStreamReadable class for batch message processing\n * @extends BaseKafkaStreamReadable\n */\nexport class KafkaBatchStreamReadable extends BaseKafkaStreamReadable {\n private pendingMessages: Message[] = []\n private readonly batchSize: number\n private readonly batchTimeout: number\n\n /**\n * Creates a KafkaBatchStreamReadable instance\n */\n constructor(\n streamOptions: KafkaBatchStreamReadableOptions,\n ) {\n const { batchSize, batchTimeout = DEFAULT_BATCH_TIMEOUT, ...opts } = streamOptions\n\n // Set highWaterMark to batch size for optimal performance\n opts.highWaterMark = Math.max(batchSize, opts.highWaterMark || 16)\n\n super({ ...streamOptions, ...opts })\n this.batchSize = batchSize\n this.batchTimeout = batchTimeout\n }\n\n /**\n * Gets current batch configuration\n * @returns {object} Current batch settings\n */\n getBatchConfig(): { batchSize: number; batchTimeout: number } {\n return {\n batchSize: this.batchSize,\n batchTimeout: this.batchTimeout,\n }\n }\n\n /**\n * Internal method called by the Readable stream to fetch batch messages\n * @private\n */\n async _read() {\n if (this.destroyed) {\n return\n }\n try {\n // First, push any pending messages\n while (this.pendingMessages.length > 0) {\n const message = this.pendingMessages.shift()\n if (!this.push(message)) {\n return // Backpressure, wait for next _read()\n }\n }\n\n // Fetch new batch if no pending messages\n const messages = await this.kafkaConsumer.recvBatch(this.batchSize, this.batchTimeout)\n\n if (messages.length === 0) {\n // No data this poll; schedule another read instead of ending the stream\n if (!this.destroyed) {\n setImmediate(() => this._read())\n }\n return\n }\n\n // Try to push messages, buffer remainder\n for (let idx = 0; idx < messages.length; idx++) {\n if (!this.push(messages[idx])) {\n // Buffer remaining messages\n this.pendingMessages = messages.slice(idx + 1)\n break\n }\n }\n } catch (error) {\n // Use destroy() instead of emit('error') to properly terminate the stream\n this.destroy(error instanceof Error ? error : new Error(String(error)))\n }\n }\n}\n", "import { BaseKafkaStreamReadable } from './base-kafka-stream-readable.js'\n\n/**\n * KafkaStreamReadable class for single message processing\n * @extends BaseKafkaStreamReadable\n */\nexport class KafkaStreamReadable extends BaseKafkaStreamReadable {\n /**\n * Internal method called by the Readable stream to fetch single messages\n * @private\n */\n async _read() {\n try {\n const message = await this.kafkaConsumer.recv()\n if (message) {\n this.push(message)\n } else {\n this.push(null) // No more data, end of stream\n }\n } catch (error) {\n if (error instanceof Error) {\n this.destroy(error)\n } else {\n this.destroy(new Error(`Unknown error: ${String(error)}`))\n }\n }\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["export type {\n ConsumerConfiguration,\n KafkaConfiguration,\n KafkaCrabError,\n KafkaEvent,\n KafkaEventPayload,\n Message,\n MessageProducer,\n OffsetModel,\n PartitionOffset,\n ProducerConfiguration,\n ProducerRecord,\n RecordMetadata,\n TopicPartition,\n TopicPartitionConfig,\n} from '../js-binding.js'\n\nexport {\n CommitMode,\n KafkaClientConfig,\n KafkaConsumer,\n KafkaEventName,\n KafkaProducer,\n PartitionPosition,\n SecurityProtocol,\n} from '../js-binding.js'\nexport { KafkaClient } from './kafka-client.js'\nexport { BaseKafkaStreamReadable } from './streams/base-kafka-stream-readable.js'\nexport { KafkaBatchStreamReadable } from './streams/kafka-batch-stream-readable.js'\nexport { KafkaStreamReadable } from './streams/kafka-stream-readable.js'\n\nexport type { KafkaClientConfiguration, StreamConsumerConfiguration } from './kafka-client.js'\n\n// OpenTelemetry exports\nexport type {\n BatchOtelContext,\n InstrumentedMessage,\n InstrumentedProducerRecord,\n KafkaOtelContext,\n KafkaOtelInstrumentationConfig,\n MessageHookFn,\n ProducerHookFn,\n TopicFilterFn,\n} from './otel/types.js'\n\nexport { getKafkaInstrumentation, KafkaCrabInstrumentation, resetKafkaInstrumentation } from './otel/instrumentation.js'\n\nexport { KAFKA_OPERATION_TYPES, KAFKA_SEMANTIC_CONVENTIONS, PACKAGE_INFO } from './otel/constants.js'\n", "import { context, type Span } from '@opentelemetry/api'\nimport type { ReadableOptions } from 'node:stream'\nimport {\n type ConsumerConfiguration,\n KafkaClientConfig,\n type KafkaConfiguration,\n type KafkaConsumer,\n type KafkaProducer,\n type ProducerConfiguration,\n} from '../js-binding.js'\n\nimport { getKafkaInstrumentation } from './otel/instrumentation.js'\nimport type { KafkaOtelContext, KafkaOtelInstrumentationConfig } from './otel/types.js'\nimport { KafkaBatchStreamReadable } from './streams/kafka-batch-stream-readable.js'\nimport { KafkaStreamReadable } from './streams/kafka-stream-readable.js'\n\nexport interface StreamConsumerConfiguration extends ConsumerConfiguration {\n batchSize?: number // Default 1 (single mode), > 1 enables batch mode\n batchTimeout?: number // Default 100ms, only used when batchSize > 1\n streamOptions?: ReadableOptions\n}\n\nexport interface KafkaClientConfiguration extends KafkaConfiguration {\n otel?: KafkaOtelInstrumentationConfig | false // OTEL configuration or false to disable\n}\n\n/**\n * KafkaClient class\n */\nexport class KafkaClient {\n private readonly kafkaClientConfig: KafkaClientConfig\n private readonly _otelEnabled: boolean\n private readonly _otelContext: KafkaOtelContext\n\n /**\n * Creates a KafkaClient instance\n * @throws {Error} If the configuration is invalid\n */\n constructor(private readonly kafkaConfiguration: KafkaClientConfiguration) {\n // Extract OTEL configuration\n const { otel, ...kafkaConfig } = kafkaConfiguration\n this.kafkaClientConfig = new KafkaClientConfig(kafkaConfig)\n\n // Initialize OTEL instrumentation\n this._otelEnabled = otel !== false && otel !== null\n if (this._otelEnabled && typeof otel === 'object') {\n const instrumentation = getKafkaInstrumentation(otel)\n this._otelContext = instrumentation.createOtelContext()\n } else if (this._otelEnabled) {\n const instrumentation = getKafkaInstrumentation()\n this._otelContext = instrumentation.createOtelContext()\n } else {\n this._otelContext = this._createDisabledOtelContext()\n }\n }\n\n /**\n * Get the OpenTelemetry context for this client\n * @returns {KafkaOtelContext} The OTEL context\n */\n get otel(): KafkaOtelContext {\n return this._otelContext\n }\n\n /**\n * Creates a KafkaProducer instance\n * @param {ProducerConfiguration} [producerConfiguration] - Optional producer configuration\n * @returns {KafkaProducer} A KafkaProducer instance\n */\n createProducer(producerConfiguration?: ProducerConfiguration) {\n const producer = producerConfiguration\n ? this.kafkaClientConfig.createProducer(producerConfiguration)\n : this.kafkaClientConfig.createProducer({})\n\n // Instrument producer if OTEL is enabled\n if (this._otelEnabled && this._otelContext.enabled) {\n return this._instrumentProducer(producer)\n }\n\n return producer\n }\n\n /**\n * Creates a KafkaConsumer instance\n * @param {ConsumerConfiguration} consumerConfiguration - Consumer configuration\n * @returns {KafkaConsumer} A KafkaConsumer instance\n * @throws {Error} If the configuration is invalid\n */\n createConsumer(consumerConfiguration: ConsumerConfiguration) {\n const consumer = this.kafkaClientConfig.createConsumer(consumerConfiguration)\n\n // Instrument consumer if OTEL is enabled\n if (this._otelEnabled && this._otelContext.enabled) {\n return KafkaClient._instrumentConsumer(consumer, consumerConfiguration.groupId)\n }\n\n return consumer\n }\n\n /**\n * Creates a stream consumer instance\n * @param {StreamConsumerConfiguration} streamConfiguration - Stream consumer configuration including batch mode and stream options\n * @returns {KafkaStreamReadable | KafkaBatchStreamReadable} A stream consumer instance\n * @throws {Error} If the configuration is invalid\n */\n createStreamConsumer(\n streamConfiguration: StreamConsumerConfiguration,\n ): KafkaStreamReadable | KafkaBatchStreamReadable {\n const { batchSize, batchTimeout, streamOptions, ...consumerConfiguration } = streamConfiguration\n const kafkaConsumer = this.kafkaClientConfig.createConsumer(consumerConfiguration)\n const instrumentedConsumer = this._otelEnabled && this._otelContext.enabled\n ? KafkaClient._instrumentConsumer(kafkaConsumer, consumerConfiguration.groupId)\n : kafkaConsumer\n const opts = streamOptions ?? { objectMode: true }\n\n // Return appropriate class based on batch configuration\n if (batchSize && batchSize > 1) {\n return new KafkaBatchStreamReadable({ kafkaConsumer: instrumentedConsumer, batchSize, batchTimeout, ...opts })\n }\n\n return new KafkaStreamReadable({ kafkaConsumer: instrumentedConsumer, ...opts })\n }\n\n private _instrumentProducer(producer: KafkaProducer) {\n const instrumentation = getKafkaInstrumentation()\n const originalSend = producer.send.bind(producer)\n\n producer.send = instrumentation.instrumentProducerSend(\n originalSend,\n this.kafkaConfiguration.clientId,\n )\n\n return producer\n }\n\n private static _instrumentConsumer(consumer: KafkaConsumer, groupId?: string) {\n const instrumentation = getKafkaInstrumentation()\n const originalRecv = consumer.recv.bind(consumer)\n const originalRecvBatch = consumer.recvBatch.bind(consumer)\n\n consumer.recv = instrumentation.instrumentConsumerReceive(originalRecv, groupId)\n consumer.recvBatch = instrumentation.instrumentBatchReceive(originalRecvBatch, groupId)\n\n return consumer\n }\n\n // eslint-disable-next-line class-methods-use-this\n private _createDisabledOtelContext(): KafkaOtelContext {\n // Provide safe no-op implementations so callers can still invoke methods without guarding\n return {\n enabled: false,\n span: null,\n tracer: null,\n context: context.active(),\n inject: () => {\n /* no-op */\n },\n extract: () => context.active(),\n startSpan: () => null,\n endSpan: (span?: Span | null) => {\n if (span && typeof span.end === 'function') {\n span.end()\n }\n },\n }\n }\n}\n", "import { type Attributes, context, diag, type Span, trace, type Tracer } from '@opentelemetry/api'\n\nimport type { KafkaConsumer, KafkaProducer, Message, ProducerRecord, RecordMetadata } from '../../js-binding.js'\nimport { PACKAGE_INFO } from './constants.js'\nimport {\n DEFAULT_OTEL_CONFIG,\n type KafkaOtelContext,\n type KafkaOtelInstrumentationConfig,\n type TracerProvider,\n} from './types.js'\nimport {\n createBatchSpan,\n createConsumerSpan,\n createProducerSpan,\n extractTraceContext,\n getTracer,\n injectTraceContext,\n normalizeHeadersToBuffer,\n setSpanStatus,\n shouldIgnoreTopic,\n} from './utils.js'\n\nexport class KafkaCrabInstrumentation {\n private _kafkaTracer: Tracer | null = null\n private _kafkaConfig: KafkaOtelInstrumentationConfig\n private _enabled = false\n\n constructor(config: KafkaOtelInstrumentationConfig = {}) {\n this._kafkaConfig = { ...DEFAULT_OTEL_CONFIG, ...config }\n }\n\n public get kafkaConfig(): KafkaOtelInstrumentationConfig {\n return this._kafkaConfig\n }\n\n public get kafkaTracer(): Tracer | null {\n return this._kafkaTracer\n }\n\n public updateConfig(config: KafkaOtelInstrumentationConfig): void {\n this._kafkaConfig = { ...this._kafkaConfig, ...config }\n }\n\n public setTracerProvider(provider: TracerProvider): void {\n this._kafkaTracer = provider.getTracer(PACKAGE_INFO.NAME, PACKAGE_INFO.VERSION)\n }\n\n public enable(): void {\n this._kafkaTracer = getTracer(PACKAGE_INFO.NAME, PACKAGE_INFO.VERSION)\n this._enabled = true\n\n if (this._kafkaConfig?.registerOnInitialization && this._kafkaTracer) {\n diag.debug('Kafka OTEL instrumentation enabled')\n }\n }\n\n public disable(): void {\n this._kafkaTracer = null\n this._enabled = false\n diag.debug('Kafka OTEL instrumentation disabled')\n }\n\n public isEnabled(): boolean {\n return this._enabled && this._kafkaTracer !== null\n }\n\n public createOtelContext(): KafkaOtelContext {\n if (!this.isEnabled()) {\n return this._createDisabledContext()\n }\n\n return {\n enabled: true,\n span: trace.getActiveSpan() || null,\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n tracer: this._kafkaTracer!,\n context: context.active(),\n inject: (carrier, spanToInject?: Span) => {\n if (spanToInject) {\n const spanContext = trace.setSpan(context.active(), spanToInject)\n injectTraceContext(carrier, spanContext)\n return\n }\n\n const activeSpan = trace.getActiveSpan()\n if (activeSpan) {\n const spanContext = trace.setSpan(context.active(), activeSpan)\n injectTraceContext(carrier, spanContext)\n } else {\n injectTraceContext(carrier, context.active())\n }\n },\n extract: (carrier) => extractTraceContext(carrier),\n startSpan: (name, attributes: Attributes = {}) => {\n if (!this._kafkaTracer) {\n throw new Error('Tracer not available')\n }\n const span = this._kafkaTracer.startSpan(name, { attributes })\n return span\n },\n endSpan: (span, error) => {\n if (!span) {\n return\n }\n setSpanStatus(span, error)\n span.end()\n },\n }\n }\n\n public instrumentProducerSend(\n originalSend: Function,\n clientId?: string,\n ): (producerRecord: ProducerRecord) => Promise<RecordMetadata[]> {\n if (!this.isEnabled()) {\n return originalSend as (producerRecord: ProducerRecord) => Promise<RecordMetadata[]>\n }\n\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const instrumentation = this\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const tracer = this._kafkaTracer!\n\n return async function instrumentedSend(this: KafkaProducer, record: ProducerRecord | ProducerRecord[]) {\n if (!record) {\n return originalSend.call(this, record as ProducerRecord)\n }\n\n const callerContext = context.active()\n\n const isArrayInput = Array.isArray(record)\n const records = isArrayInput ? record : [record]\n\n if (records.length === 0) {\n return originalSend.call(this, isArrayInput ? records : (record as ProducerRecord))\n }\n\n const allIgnored = records.every((currentRecord) =>\n shouldIgnoreTopic(currentRecord.topic, instrumentation._kafkaConfig.ignoreTopics)\n )\n\n if (allIgnored) {\n return originalSend.call(this, isArrayInput ? records : records[0])\n }\n\n const spans: Span[] = []\n const spanMetadata: { span: Span; record: ProducerRecord }[] = []\n\n const instrumentedRecords = records.map((currentRecord) => {\n if (!currentRecord || shouldIgnoreTopic(currentRecord.topic, instrumentation._kafkaConfig.ignoreTopics)) {\n return currentRecord\n }\n\n const span = createProducerSpan(tracer, currentRecord, 'send', callerContext)\n\n if (!span) {\n return currentRecord\n }\n\n if (clientId) {\n span.setAttributes({ 'messaging.client.id': clientId })\n }\n\n spans.push(span)\n spanMetadata.push({ span, record: currentRecord })\n\n const spanContext = trace.setSpan(callerContext, span)\n\n const instrumentedRecord: ProducerRecord = {\n ...currentRecord,\n messages: (currentRecord.messages ?? []).map(message => {\n const originalHeaders = { ...message.headers }\n const injectedHeaders = injectTraceContext(originalHeaders, spanContext)\n const normalizedHeaders = normalizeHeadersToBuffer(injectedHeaders)\n\n return {\n ...message,\n headers: normalizedHeaders,\n }\n }),\n }\n\n if (instrumentation._kafkaConfig.producerHook) {\n try {\n context.with(spanContext, () => {\n instrumentation._kafkaConfig.producerHook?.(span, currentRecord)\n })\n } catch (error) {\n diag.warn('Producer hook failed:', error)\n }\n }\n\n return instrumentedRecord\n })\n\n const payload = isArrayInput ? instrumentedRecords : instrumentedRecords[0]\n\n try {\n const result = await context.with(callerContext, async () => originalSend.call(this, payload as ProducerRecord))\n\n const metadataArray = Array.isArray(result) ? result : []\n for (let idx = 0; idx < spanMetadata.length; idx++) {\n const { span } = spanMetadata[idx]\n const metadata = metadataArray[idx]\n if (metadata) {\n if (metadata.partition !== undefined) {\n span.setAttribute('messaging.kafka.partition', metadata.partition)\n }\n if (metadata.offset !== undefined) {\n span.setAttribute('messaging.kafka.offset', metadata.offset)\n }\n }\n setSpanStatus(span, metadata?.error ? new Error(metadata.error.message) : undefined)\n span.end()\n }\n\n if (instrumentation._kafkaConfig.producerHook && metadataArray.length) {\n const [first] = spanMetadata\n if (first) {\n try {\n instrumentation._kafkaConfig.producerHook(first.span, first.record, metadataArray[0])\n } catch (error) {\n diag.warn('Producer hook failed with metadata:', error)\n }\n }\n }\n\n return result\n } catch (error) {\n for (const span of spans) {\n setSpanStatus(span, error instanceof Error ? error : new Error(String(error)))\n span.end()\n }\n throw error\n }\n }\n }\n\n public instrumentConsumerReceive(originalReceive: Function, groupId?: string): () => Promise<Message | null> {\n if (!this.isEnabled()) {\n return originalReceive as () => Promise<Message | null>\n }\n\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const instrumentation = this\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const tracer = this._kafkaTracer!\n\n return async function instrumentedReceive(this: KafkaConsumer) {\n const message = await originalReceive.call(this)\n\n if (!message) {\n return message\n }\n\n if (shouldIgnoreTopic(message.topic, instrumentation._kafkaConfig.ignoreTopics)) {\n return message\n }\n\n const parentContext = extractTraceContext(message.headers || {}) || context.active()\n const span = createConsumerSpan(tracer, message, 'process', parentContext)\n\n if (span) {\n const spanCtx = trace.setSpan(parentContext, span)\n\n context.with(spanCtx, () => {\n if (groupId) {\n span.setAttributes({ 'messaging.consumer.group.name': groupId })\n }\n\n if (instrumentation._kafkaConfig.messageHook) {\n try {\n instrumentation._kafkaConfig.messageHook(span, message)\n } catch (error) {\n diag.warn('Message hook failed:', error)\n }\n }\n\n setSpanStatus(span)\n })\n\n span.end()\n }\n\n return message\n }\n }\n\n public instrumentBatchReceive(\n originalBatchReceive: Function,\n groupId?: string,\n ): (size: number, timeoutMs: number) => Promise<Message[]> {\n if (!this.isEnabled() || !this._kafkaConfig.enableBatchInstrumentation) {\n return originalBatchReceive as (size: number, timeoutMs: number) => Promise<Message[]>\n }\n\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const instrumentation = this\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const tracer = this._kafkaTracer!\n\n return async function instrumentedBatchReceive(this: KafkaConsumer, size: number, timeoutMs: number) {\n const messages = await originalBatchReceive.call(this, size, timeoutMs)\n\n if (!Array.isArray(messages) || messages.length === 0) {\n return messages\n }\n\n const instrumentedMessages = messages.filter((message: Message) =>\n !shouldIgnoreTopic(message.topic, instrumentation._kafkaConfig.ignoreTopics)\n )\n\n if (instrumentedMessages.length === 0) {\n return messages\n }\n\n const [firstMessage] = instrumentedMessages\n const parentContext = extractTraceContext(firstMessage.headers || {}) || context.active()\n const batchSpan = createBatchSpan(\n tracer,\n instrumentedMessages.length,\n firstMessage.topic,\n 'batch_process',\n parentContext,\n )\n\n if (batchSpan) {\n if (groupId) {\n batchSpan.setAttributes({ 'messaging.consumer.group.name': groupId })\n }\n\n try {\n for (const message of instrumentedMessages) {\n const msgParentContext = extractTraceContext(message.headers || {}) || parentContext\n const messageSpan = createConsumerSpan(tracer, message, 'process', msgParentContext)\n\n if (messageSpan) {\n const messageSpanContext = trace.setSpan(msgParentContext || context.active(), messageSpan)\n context.with(messageSpanContext, () => {\n messageSpan.setAttributes({\n 'messaging.batch.message_count': instrumentedMessages.length,\n })\n\n if (instrumentation._kafkaConfig.messageHook) {\n try {\n instrumentation._kafkaConfig.messageHook(messageSpan, message)\n } catch (error) {\n diag.warn('Message hook failed:', error)\n }\n }\n\n setSpanStatus(messageSpan)\n })\n messageSpan.end()\n }\n }\n\n setSpanStatus(batchSpan)\n } catch (error) {\n setSpanStatus(batchSpan, error instanceof Error ? error : new Error(String(error)))\n } finally {\n batchSpan.end()\n }\n }\n\n return messages\n }\n }\n\n // eslint-disable-next-line class-methods-use-this\n private _createDisabledContext(): KafkaOtelContext {\n return {\n enabled: false,\n span: null,\n tracer: null,\n context: context.active(),\n inject: () => {\n /* no-op */\n },\n extract: () => context.active(),\n startSpan: () => null,\n endSpan: () => {\n /* no-op */\n },\n }\n }\n}\n\n// Singleton instance for global use\nlet globalInstrumentation: KafkaCrabInstrumentation | null = null\n\nexport function getKafkaInstrumentation(config?: KafkaOtelInstrumentationConfig): KafkaCrabInstrumentation {\n if (!globalInstrumentation) {\n globalInstrumentation = new KafkaCrabInstrumentation(config)\n globalInstrumentation.enable()\n } else if (config) {\n globalInstrumentation.updateConfig(config)\n }\n return globalInstrumentation\n}\n\nexport function resetKafkaInstrumentation(): void {\n if (globalInstrumentation) {\n globalInstrumentation.disable()\n globalInstrumentation = null\n }\n}\n", "// OpenTelemetry semantic conventions for Kafka messaging\nexport const KAFKA_SEMANTIC_CONVENTIONS = {\n // Messaging system attributes (https://opentelemetry.io/docs/specs/semconv/messaging/messaging-spans/)\n MESSAGING_SYSTEM: 'messaging.system',\n MESSAGING_DESTINATION_NAME: 'messaging.destination.name',\n MESSAGING_DESTINATION_KIND: 'messaging.destination.kind',\n MESSAGING_OPERATION_NAME: 'messaging.operation.name',\n MESSAGING_OPERATION_TYPE: 'messaging.operation.type',\n MESSAGING_CLIENT_ID: 'messaging.client.id',\n MESSAGING_MESSAGE_ID: 'messaging.message.id',\n MESSAGING_MESSAGE_BODY_SIZE: 'messaging.message.body.size',\n MESSAGING_BATCH_MESSAGE_COUNT: 'messaging.batch.message_count',\n\n // Kafka-specific attributes\n MESSAGING_KAFKA_OFFSET: 'messaging.kafka.offset',\n MESSAGING_KAFKA_PARTITION: 'messaging.kafka.partition',\n MESSAGING_KAFKA_MESSAGE_KEY: 'messaging.kafka.message.key',\n MESSAGING_KAFKA_CONSUMER_GROUP: 'messaging.kafka.consumer.group',\n MESSAGING_KAFKA_TOMBSTONE: 'messaging.kafka.tombstone',\n\n // Consumer-specific attributes\n MESSAGING_CONSUMER_GROUP_NAME: 'messaging.consumer.group.name',\n} as const\n\n// Operation types\nexport const KAFKA_OPERATION_TYPES = {\n SEND: 'send',\n RECEIVE: 'receive',\n PROCESS: 'process',\n BATCH_RECEIVE: 'batch_receive',\n BATCH_PROCESS: 'batch_process',\n} as const\n\n// Span names\nexport const KAFKA_SPAN_NAMES = {\n PRODUCER_SEND: (topic: string) => `${topic} send`,\n CONSUMER_RECEIVE: (topic: string) => `${topic} receive`,\n CONSUMER_PROCESS: (topic: string) => `${topic} process`,\n BATCH_RECEIVE: 'kafka batch receive',\n BATCH_PROCESS: (topic: string) => `${topic} batch process`,\n} as const\n\n// Default values\nexport const KAFKA_DEFAULTS = {\n MESSAGING_SYSTEM: 'kafka',\n DESTINATION_KIND: 'topic',\n BATCH_TIMEOUT_MS: 1000,\n} as const\n\n// Package information\nexport const PACKAGE_INFO = {\n NAME: 'kafka-crab-js',\n VERSION: '2.1.0', // Should match package.json\n} as const\n", "import type { Attributes, Context, Span, Tracer } from '@opentelemetry/api'\nimport type { Message, ProducerRecord, RecordMetadata } from '../../js-binding.js'\n\n// InstrumentationConfig interface (simplified from @opentelemetry/instrumentation)\nexport interface InstrumentationConfig {\n enabled?: boolean\n}\n\n// OpenTelemetry TracerProvider interface\nexport interface TracerProvider {\n getTracer(name: string, version?: string, options?: unknown): Tracer\n}\n\n// Use the actual types from js-binding instead of custom interfaces\n// This avoids type compatibility issues with the real implementations\n\n// Configuration interface for Kafka OTEL instrumentation\nexport interface KafkaOtelInstrumentationConfig extends InstrumentationConfig {\n // Service name for telemetry (defaults to OTEL_SERVICE_NAME env var or 'kafka-client')\n serviceName?: string\n\n // Whether to register instrumentation automatically on initialization\n registerOnInitialization?: boolean\n\n // Function to filter topics from instrumentation\n ignoreTopics?: string[] | ((topic: string) => boolean)\n\n // Custom hook called for each message/span\n messageHook?: (span: Span, message: Message) => void\n\n // Custom hook called for producer operations\n producerHook?: (span: Span, record: ProducerRecord, metadata?: RecordMetadata) => void\n\n // Whether to capture message payloads as span attributes (security sensitive)\n captureMessagePayload?: boolean\n\n // Maximum size of message payload to capture (in bytes)\n maxPayloadSize?: number\n\n // Whether to capture message headers as span attributes\n captureMessageHeaders?: boolean\n\n // Whether to enable batch operation instrumentation\n enableBatchInstrumentation?: boolean\n}\n\n// OpenTelemetry context interface exposed by clients\nexport interface KafkaOtelContext {\n // Whether OTEL is enabled for this client\n enabled: boolean\n\n // Current active span (if any)\n span: Span | null\n\n // Tracer instance for creating spans\n tracer: Tracer | null\n\n // Current OTEL context\n context: Context | null\n\n // Inject trace context into carrier (e.g., Kafka headers)\n inject: (carrier: Record<string, string | string[] | undefined>) => void\n\n // Extract trace context from carrier (e.g., Kafka headers)\n extract: (carrier: Record<string, string | string[] | undefined>) => Context\n\n // Create a child span with proper context\n startSpan: (name: string, attributes?: Attributes) => Span | null\n\n // End a span with proper status handling\n endSpan: (span: Span | null | undefined, error?: Error) => void\n}\n\n// Enhanced message interface with OTEL context\nexport interface InstrumentedMessage extends Message {\n // Extracted OTEL context from message headers\n otelContext?: Context\n\n // Optional span created for this message\n span?: Span\n}\n\n// Enhanced producer record with OTEL context injection\nexport interface InstrumentedProducerRecord extends ProducerRecord {\n // Headers will be automatically injected with trace context\n headers?: Record<string, string | string[] | undefined>\n\n // Optional span for tracking this record\n span?: Span\n}\n\n// Batch processing context\nexport interface BatchOtelContext {\n // Parent span for the entire batch\n batchSpan: Span\n\n // Individual message spans within the batch\n messageSpans: Span[]\n\n // Batch size for telemetry\n batchSize: number\n\n // Processing start time\n startTime: number\n}\n\n// Hook function signatures\nexport type MessageHookFn = (span: Span, message: Message) => void\nexport type ProducerHookFn = (span: Span, record: ProducerRecord, metadata?: RecordMetadata) => void\nexport type TopicFilterFn = (topic: string) => boolean\n\n// Configuration defaults\nexport const DEFAULT_OTEL_CONFIG: Required<\n Pick<\n KafkaOtelInstrumentationConfig,\n | 'serviceName'\n | 'registerOnInitialization'\n | 'captureMessagePayload'\n | 'maxPayloadSize'\n | 'captureMessageHeaders'\n | 'enableBatchInstrumentation'\n >\n> = {\n serviceName: process.env.OTEL_SERVICE_NAME || 'kafka-client',\n registerOnInitialization: true,\n captureMessagePayload: false,\n maxPayloadSize: 1024,\n captureMessageHeaders: true,\n enableBatchInstrumentation: true,\n} as const\n", "import {\n type Attributes,\n type Context,\n context,\n propagation,\n type Span,\n SpanKind,\n SpanStatusCode,\n trace,\n type Tracer,\n} from '@opentelemetry/api'\nimport type { Message, ProducerRecord } from '../../js-binding.js'\nimport { KAFKA_DEFAULTS, KAFKA_SEMANTIC_CONVENTIONS } from './constants.js'\n\n// Safely get tracer\nexport function getTracer(name: string, version?: string) {\n return trace.getTracer(name, version)\n}\n\n// Set span status based on error\nexport function setSpanStatus(span: Span, error?: Error): void {\n if (error) {\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: error.message,\n })\n span.recordException(error)\n } else {\n span.setStatus({ code: SpanStatusCode.OK })\n }\n}\n\n// Extract common Kafka attributes from message\nexport function getMessageAttributes(message: Message, operation: string): Attributes {\n const attributes: Attributes = {\n [KAFKA_SEMANTIC_CONVENTIONS.MESSAGING_SYSTEM]: KAFKA_DEFAULTS.MESSAGING_SYSTEM,\n [KAFKA_SEMANTIC_CONVENTIONS.MESSAGING_DESTINATION_NAME]: message.topic,\n [KAFKA_SEMANTIC_CONVENTIONS.MESSAGING_DESTINATION_KIND]: KAFKA_DEFAULTS.DESTINATION_KIND,\n [KAFKA_SEMANTIC_CONVENTIONS.MESSAGING_OPERATION_NAME]: operation,\n [KAFKA_SEMANTIC_CONVENTIONS.MESSAGING_KAFKA_PARTITION]: message.partition,\n [KAFKA_SEMANTIC_CONVENTIONS.MESSAGING_KAFKA_OFFSET]: message.offset,\n }\n\n // Add optional attributes if present\n if (message.key !== null && message.key !== undefined) {\n attributes[KAFKA_SEMANTIC_CONVENTIONS.MESSAGING_KAFKA_MESSAGE_KEY] = typeof message.key === 'string'\n ? message.key\n : String(message.key)\n }\n\n if (message.payload) {\n let payloadSize: number\n if (Buffer.isBuffer(message.payload)) {\n payloadSize = message.payload.length\n } else if (typeof message.payload === 'string') {\n payloadSize = Buffer.byteLength(message.payload, 'utf8')\n } else {\n payloadSize = JSON.stringify(message.payload).length\n }\n attributes[KAFKA_SEMANTIC_CONVENTIONS.MESSAGING_MESSAGE_BODY_SIZE] = payloadSize\n }\n\n return attributes\n}\n\n// Extract common Kafka attributes from producer record\nexport function getProducerRecordAttributes(record: ProducerRecord, operation: string): Attributes {\n const attributes: Attributes = {\n [KAFKA_SEMANTIC_CONVENTIONS.MESSAGING_SYSTEM]: KAFKA_DEFAULTS.MESSAGING_SYSTEM,\n [KAFKA_SEMANTIC_CONVENTIONS.MESSAGING_DESTINATION_NAME]: record.topic,\n [KAFKA_SEMANTIC_CONVENTIONS.MESSAGING_DESTINATION_KIND]: KAFKA_DEFAULTS.DESTINATION_KIND,\n [KAFKA_SEMANTIC_CONVENTIONS.MESSAGING_OPERATION_NAME]: operation,\n }\n\n // Add message count\n if (record.messages && record.messages.length > 0) {\n attributes[KAFKA_SEMANTIC_CONVENTIONS.MESSAGING_BATCH_MESSAGE_COUNT] = record.messages.length\n\n // Use first message for key and payload size\n const [firstMessage] = record.messages\n\n // Add key if present\n if (firstMessage.key !== null && firstMessage.key !== undefined) {\n attributes[KAFKA_SEMANTIC_CONVENTIONS.MESSAGING_KAFKA_MESSAGE_KEY] = Buffer.isBuffer(firstMessage.key)\n ? firstMessage.key.toString()\n : String(firstMessage.key)\n }\n\n // Add payload size if present\n if (firstMessage.payload) {\n let payloadSize: number\n if (Buffer.isBuffer(firstMessage.payload)) {\n payloadSize = firstMessage.payload.length\n } else if (typeof firstMessage.payload === 'string') {\n payloadSize = Buffer.byteLength(firstMessage.payload, 'utf8')\n } else {\n payloadSize = JSON.stringify(firstMessage.payload).length\n }\n attributes[KAFKA_SEMANTIC_CONVENTIONS.MESSAGING_MESSAGE_BODY_SIZE] = payloadSize\n }\n }\n\n return attributes\n}\n\n// Convert Buffer headers to string headers for trace context injection\nfunction convertBufferHeaders(\n bufferHeaders: Record<string, Buffer> = {},\n): Record<string, string | string[] | undefined> {\n const stringHeaders: Record<string, string | string[] | undefined> = {}\n for (const [key, value] of Object.entries(bufferHeaders)) {\n stringHeaders[key] = value.toString('utf8')\n }\n return stringHeaders\n}\n\n// Convert string headers back to Buffer headers\nfunction convertToBufferHeaders(stringHeaders: Record<string, string | string[] | undefined>): Record<string, Buffer> {\n const bufferHeaders: Record<string, Buffer> = {}\n for (const [key, value] of Object.entries(stringHeaders)) {\n if (value !== undefined) {\n const stringValue = Array.isArray(value) ? value.join(',') : value\n bufferHeaders[key] = Buffer.from(stringValue, 'utf8')\n }\n }\n return bufferHeaders\n}\n\nexport type KafkaHeaderValue = Buffer | string | string[] | undefined\nexport type KafkaHeaderCarrier = Record<string, KafkaHeaderValue>\n\n// Inject trace context into Kafka headers (works with both string and Buffer headers)\nexport function injectTraceContext(\n headers: KafkaHeaderCarrier = {},\n ctx?: Context,\n): KafkaHeaderCarrier {\n const activeContext = ctx || context.active()\n const headerEntries = Object.entries(headers)\n const hasBufferValues = headerEntries.some(([, value]) => Buffer.isBuffer(value))\n\n // Convert Buffer headers to string headers if needed\n if (hasBufferValues) {\n const bufferCarrier = headers as Record<string, Buffer>\n const stringHeaders = convertBufferHeaders(bufferCarrier)\n\n propagation.inject(activeContext, stringHeaders, {\n set: (carrier: Record<string, string | string[] | undefined>, key: string, value: string) => {\n carrier[key] = value\n },\n })\n\n const bufferHeaders = convertToBufferHeaders(stringHeaders)\n\n for (const [key, value] of Object.entries(bufferHeaders)) {\n bufferCarrier[key] = value\n }\n\n return bufferCarrier\n }\n\n const stringCarrier = headers as Record<string, string | string[] | undefined>\n\n propagation.inject(activeContext, stringCarrier, {\n set: (carrier: Record<string, string | string[] | undefined>, key: string, value: string) => {\n carrier[key] = value\n },\n })\n\n // Preserve original string-based carrier for callers expecting strings\n return stringCarrier\n}\n\n// Normalize any header carrier into Buffer headers for Kafka bindings\nexport function normalizeHeadersToBuffer(headers: KafkaHeaderCarrier): Record<string, Buffer> {\n const bufferHeaders: Record<string, Buffer> = {}\n\n for (const [key, value] of Object.entries(headers)) {\n if (value !== undefined) {\n if (Buffer.isBuffer(value)) {\n bufferHeaders[key] = value\n } else if (Array.isArray(value)) {\n bufferHeaders[key] = Buffer.from(value.join(','), 'utf8')\n } else {\n bufferHeaders[key] = Buffer.from(value, 'utf8')\n }\n }\n }\n\n return bufferHeaders\n}\n\n// Extract trace context from Kafka headers\nexport function extractTraceContext(\n headers: Record<string, string | string[] | undefined> = {},\n): Context {\n return propagation.extract(context.active(), headers, {\n get: (carrier: Record<string, string | string[] | undefined>, key: string) => {\n const value = carrier[key]\n const singleValue = Array.isArray(value) ? value[0] : value\n\n if (Buffer.isBuffer(singleValue)) {\n return singleValue.toString('utf8')\n }\n\n return singleValue\n },\n keys: (carrier: Record<string, string | string[] | undefined>) => Object.keys(carrier),\n })\n}\n\n// Check if topic should be ignored based on filter configuration\nexport function shouldIgnoreTopic(\n topic: string,\n ignoreTopics?: string[] | ((topic: string) => boolean),\n): boolean {\n if (!ignoreTopics) {\n return false\n }\n\n if (Array.isArray(ignoreTopics)) {\n return ignoreTopics.includes(topic)\n }\n\n if (typeof ignoreTopics === 'function') {\n try {\n return ignoreTopics(topic)\n } catch {\n // If filter function throws, don't ignore the topic\n return false\n }\n }\n\n return false\n}\n\n// Create span for producer operation\nexport function createProducerSpan(\n tracer: Tracer,\n record: ProducerRecord,\n operation = 'send',\n parentContext?: Context,\n): Span | null {\n if (!tracer) {\n return null\n }\n const parent = parentContext ?? context.active()\n\n const spanName = `${record.topic} ${operation}`\n const attributes = getProducerRecordAttributes(record, operation)\n\n const spanOptions = {\n kind: SpanKind.PRODUCER,\n attributes,\n }\n\n return tracer.startSpan(spanName, spanOptions, parent)\n}\n\n// Create span for consumer operation\nexport function createConsumerSpan(\n tracer: Tracer,\n message: Message,\n operation = 'process',\n parentContext?: Context,\n): Span | null {\n if (!tracer) {\n return null\n }\n\n const spanName = `${message.topic} ${operation}`\n const attributes = getMessageAttributes(message, operation)\n\n const spanOptions = {\n kind: SpanKind.CONSUMER,\n attributes,\n }\n\n // Start span with parent context if provided\n if (parentContext) {\n return tracer.startSpan(spanName, spanOptions, parentContext)\n }\n\n return tracer.startSpan(spanName, spanOptions)\n}\n\n// Create batch span for batch operations\nexport function createBatchSpan(\n tracer: Tracer,\n batchSize: number,\n topic?: string,\n operation = 'batch_process',\n parentContext?: Context,\n): Span | null {\n if (!tracer) {\n return null\n }\n\n const spanName = topic ? `${topic} ${operation}` : `kafka ${operation}`\n const attributes: Attributes = {\n [KAFKA_SEMANTIC_CONVENTIONS.MESSAGING_SYSTEM]: KAFKA_DEFAULTS.MESSAGING_SYSTEM,\n [KAFKA_SEMANTIC_CONVENTIONS.MESSAGING_OPERATION_NAME]: operation,\n [KAFKA_SEMANTIC_CONVENTIONS.MESSAGING_BATCH_MESSAGE_COUNT]: batchSize,\n }\n\n if (topic) {\n attributes[KAFKA_SEMANTIC_CONVENTIONS.MESSAGING_DESTINATION_NAME] = topic\n attributes[KAFKA_SEMANTIC_CONVENTIONS.MESSAGING_DESTINATION_KIND] = KAFKA_DEFAULTS.DESTINATION_KIND\n }\n\n const spanOptions = {\n kind: SpanKind.CONSUMER,\n attributes,\n }\n\n if (parentContext) {\n return tracer.startSpan(spanName, spanOptions, parentContext)\n }\n\n return tracer.startSpan(spanName, spanOptions)\n}\n", "import { Readable, type ReadableOptions } from 'node:stream'\n\nimport type { CommitMode, KafkaConsumer, Message, OffsetModel, TopicPartitionConfig } from '../../js-binding.js'\n\nexport interface KafkaStreamReadableOptions extends ReadableOptions<Readable> {\n kafkaConsumer: KafkaConsumer\n}\n\n/**\n * Abstract base class for Kafka stream readers\n * @extends Readable\n */\nexport abstract class BaseKafkaStreamReadable extends Readable {\n private _kafkaConsumer: KafkaConsumer\n\n /**\n * Creates a BaseKafkaStreamReadable instance\n */\n constructor(\n streamOptions: KafkaStreamReadableOptions,\n ) {\n const { kafkaConsumer, ...opts } = streamOptions\n\n super(opts)\n\n if (!kafkaConsumer) {\n throw new Error('A valid KafkaConsumer instance is required.')\n }\n\n this._kafkaConsumer = kafkaConsumer\n }\n\n get kafkaConsumer(): KafkaConsumer {\n return this._kafkaConsumer\n }\n\n /**\n * Checks if the stream is currently paused\n * @returns {boolean} True if the stream is paused\n */\n isPaused(): boolean {\n return this.readableFlowing === false\n }\n\n /**\n * Subscribes to topics\n */\n async subscribe(topics: string | Array<TopicPartitionConfig>) {\n if (!topics || (Array.isArray(topics) && topics.length === 0)) {\n throw new Error('Topics must be a non-empty string or array.')\n }\n await this.kafkaConsumer.subscribe(topics)\n }\n\n seek(topic: string, partition: number, offsetModel: OffsetModel, timeout?: number) {\n this.kafkaConsumer.seek(topic, partition, offsetModel, timeout)\n }\n\n async commit(topic: string, partition: number, offset: number, commitMode: CommitMode) {\n return this.kafkaConsumer.commit(topic, partition, offset, commitMode)\n }\n\n /**\n * Commits the offset for a message.\n * This is a convenience method that automatically increments the offset by 1.\n * The offset committed is `message.offset + 1` since Kafka expects the next offset to be consumed.\n * @param message - The message to commit\n * @param commitMode - The commit mode ('Sync' or 'Async')\n */\n async commitMessage(message: Message, commitMode: CommitMode) {\n return this.kafkaConsumer.commitMessage(message, commitMode)\n }\n\n /**\n * Unsubscribe from topics\n */\n unsubscribe() {\n this.kafkaConsumer.unsubscribe()\n }\n\n /**\n * Disconnects the Kafka consumer\n */\n async disconnect() {\n await this.kafkaConsumer.disconnect()\n }\n\n /**\n * Returns the raw Kafka consumer\n * @returns {KafkaConsumer} The Kafka consumer instance\n */\n rawConsumer() {\n return this.kafkaConsumer\n }\n\n /**\n * Called when the stream is being destroyed\n * Ensures proper cleanup of the Kafka consumer\n * @private\n */\n _destroy(error: Error | null, callback: (error?: Error | null) => void): void {\n // Always unsubscribe first to stop receiving messages\n try {\n this.kafkaConsumer.unsubscribe()\n } catch {\n // Silently ignore unsubscribe errors during cleanup - they're non-critical\n // Common when consumer is already disconnected or in invalid state\n }\n\n // Disconnect the consumer\n this.kafkaConsumer\n .disconnect()\n .then(() => {\n // Success: pass through the original error (if any)\n callback(error)\n })\n // eslint-disable-next-line unicorn/catch-error-name\n .catch((disconnectError) => {\n // Failed to disconnect: combine errors\n const combinedError = error\n ? new Error(`Stream error: ${error.message}; Disconnect error: ${disconnectError.message}`)\n : disconnectError\n callback(combinedError)\n })\n }\n\n /**\n * Abstract method that must be implemented by concrete classes\n * @private\n */\n abstract _read(): void\n}\n", "import type { Message } from '../../js-binding.js'\nimport { BaseKafkaStreamReadable, type KafkaStreamReadableOptions } from './base-kafka-stream-readable.js'\n\n// Constants for batch configuration\nconst DEFAULT_BATCH_TIMEOUT = 1000\n\nexport interface KafkaBatchStreamReadableOptions extends KafkaStreamReadableOptions {\n batchSize: number\n batchTimeout?: number\n}\n\n/**\n * KafkaBatchStreamReadable class for batch message processing\n * @extends BaseKafkaStreamReadable\n */\nexport class KafkaBatchStreamReadable extends BaseKafkaStreamReadable {\n private pendingMessages: Message[] = []\n private readonly batchSize: number\n private readonly batchTimeout: number\n\n /**\n * Creates a KafkaBatchStreamReadable instance\n */\n constructor(\n streamOptions: KafkaBatchStreamReadableOptions,\n ) {\n const { batchSize, batchTimeout = DEFAULT_BATCH_TIMEOUT, ...opts } = streamOptions\n\n // Set highWaterMark to batch size for optimal performance\n opts.highWaterMark = Math.max(batchSize, opts.highWaterMark || 16)\n\n super({ ...streamOptions, ...opts })\n this.batchSize = batchSize\n this.batchTimeout = batchTimeout\n }\n\n /**\n * Gets current batch configuration\n * @returns {object} Current batch settings\n */\n getBatchConfig(): { batchSize: number; batchTimeout: number } {\n return {\n batchSize: this.batchSize,\n batchTimeout: this.batchTimeout,\n }\n }\n\n /**\n * Internal method called by the Readable stream to fetch batch messages\n * @private\n */\n async _read() {\n if (this.destroyed) {\n return\n }\n try {\n // First, push any pending messages\n while (this.pendingMessages.length > 0) {\n const message = this.pendingMessages.shift()\n if (!this.push(message)) {\n return // Backpressure, wait for next _read()\n }\n }\n\n // Fetch new batch if no pending messages\n const messages = await this.kafkaConsumer.recvBatch(this.batchSize, this.batchTimeout)\n\n if (messages.length === 0) {\n // No data this poll; schedule another read instead of ending the stream\n if (!this.destroyed) {\n setImmediate(() => this._read())\n }\n return\n }\n\n // Try to push messages, buffer remainder\n for (let idx = 0; idx < messages.length; idx++) {\n if (!this.push(messages[idx])) {\n // Buffer remaining messages\n this.pendingMessages = messages.slice(idx + 1)\n break\n }\n }\n } catch (error) {\n // Use destroy() instead of emit('error') to properly terminate the stream\n this.destroy(error instanceof Error ? error : new Error(String(error)))\n }\n }\n}\n", "import { BaseKafkaStreamReadable } from './base-kafka-stream-readable.js'\n\n/**\n * KafkaStreamReadable class for single message processing\n * @extends BaseKafkaStreamReadable\n */\nexport class KafkaStreamReadable extends BaseKafkaStreamReadable {\n /**\n * Internal method called by the Readable stream to fetch single messages\n * @private\n */\n async _read() {\n try {\n const message = await this.kafkaConsumer.recv()\n if (message) {\n this.push(message)\n } else {\n this.push(null) // No more data, end of stream\n }\n } catch (error) {\n if (error instanceof Error) {\n this.destroy(error)\n } else {\n this.destroy(new Error(`Unknown error: ${String(error)}`))\n }\n }\n }\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAiBA,IAAAA,qBAQO;;;ACzBP,IAAAC,cAAmC;AAEnC,wBAOO;;;ACTP,IAAAC,cAA8E;;;ACCvE,IAAM,6BAA6B;AAAA;AAAA,EAExC,kBAAkB;AAAA,EAClB,4BAA4B;AAAA,EAC5B,4BAA4B;AAAA,EAC5B,0BAA0B;AAAA,EAC1B,0BAA0B;AAAA,EAC1B,qBAAqB;AAAA,EACrB,sBAAsB;AAAA,EACtB,6BAA6B;AAAA,EAC7B,+BAA+B;AAAA;AAAA,EAG/B,wBAAwB;AAAA,EACxB,2BAA2B;AAAA,EAC3B,6BAA6B;AAAA,EAC7B,gCAAgC;AAAA,EAChC,2BAA2B;AAAA;AAAA,EAG3B,+BAA+B;AACjC;AAGO,IAAM,wBAAwB;AAAA,EACnC,MAAM;AAAA,EACN,SAAS;AAAA,EACT,SAAS;AAAA,EACT,eAAe;AAAA,EACf,eAAe;AACjB;AAYO,IAAM,iBAAiB;AAAA,EAC5B,kBAAkB;AAAA,EAClB,kBAAkB;AAAA,EAClB,kBAAkB;AACpB;AAGO,IAAM,eAAe;AAAA,EAC1B,MAAM;AAAA,EACN,SAAS;AAAA;AACX;;;AC2DO,IAAM,sBAUT;AAAA,EACF,aAAa,QAAQ,IAAI,qBAAqB;AAAA,EAC9C,0BAA0B;AAAA,EAC1B,uBAAuB;AAAA,EACvB,gBAAgB;AAAA,EAChB,uBAAuB;AAAA,EACvB,4BAA4B;AAC9B;;;ACjIA,iBAUO;AAKA,SAAS,UAAU,MAAc,SAAkB;AACxD,SAAO,iBAAM,UAAU,MAAM,OAAO;AACtC;AAGO,SAAS,cAAc,MAAY,OAAqB;AAC7D,MAAI,OAAO;AACT,SAAK,UAAU;AAAA,MACb,MAAM,0BAAe;AAAA,MACrB,SAAS,MAAM;AAAA,IACjB,CAAC;AACD,SAAK,gBAAgB,KAAK;AAAA,EAC5B,OAAO;AACL,SAAK,UAAU,EAAE,MAAM,0BAAe,GAAG,CAAC;AAAA,EAC5C;AACF;AAGO,SAAS,qBAAqB,SAAkB,WAA+B;AACpF,QAAM,aAAyB;AAAA,IAC7B,CAAC,2BAA2B,gBAAgB,GAAG,eAAe;AAAA,IAC9D,CAAC,2BAA2B,0BAA0B,GAAG,QAAQ;AAAA,IACjE,CAAC,2BAA2B,0BAA0B,GAAG,eAAe;AAAA,IACxE,CAAC,2BAA2B,wBAAwB,GAAG;AAAA,IACvD,CAAC,2BAA2B,yBAAyB,GAAG,QAAQ;AAAA,IAChE,CAAC,2BAA2B,sBAAsB,GAAG,QAAQ;AAAA,EAC/D;AAGA,MAAI,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAW;AACrD,eAAW,2BAA2B,2BAA2B,IAAI,OAAO,QAAQ,QAAQ,WACxF,QAAQ,MACR,OAAO,QAAQ,GAAG;AAAA,EACxB;AAEA,MAAI,QAAQ,SAAS;AACnB,QAAI;AACJ,QAAI,OAAO,SAAS,QAAQ,OAAO,GAAG;AACpC,oBAAc,QAAQ,QAAQ;AAAA,IAChC,WAAW,OAAO,QAAQ,YAAY,UAAU;AAC9C,oBAAc,OAAO,WAAW,QAAQ,SAAS,MAAM;AAAA,IACzD,OAAO;AACL,oBAAc,KAAK,UAAU,QAAQ,OAAO,EAAE;AAAA,IAChD;AACA,eAAW,2BAA2B,2BAA2B,IAAI;AAAA,EACvE;AAEA,SAAO;AACT;AAGO,SAAS,4BAA4B,QAAwB,WAA+B;AACjG,QAAM,aAAyB;AAAA,IAC7B,CAAC,2BAA2B,gBAAgB,GAAG,eAAe;AAAA,IAC9D,CAAC,2BAA2B,0BAA0B,GAAG,OAAO;AAAA,IAChE,CAAC,2BAA2B,0BAA0B,GAAG,eAAe;AAAA,IACxE,CAAC,2BAA2B,wBAAwB,GAAG;AAAA,EACzD;AAGA,MAAI,OAAO,YAAY,OAAO,SAAS,SAAS,GAAG;AACjD,eAAW,2BAA2B,6BAA6B,IAAI,OAAO,SAAS;AAGvF,UAAM,CAAC,YAAY,IAAI,OAAO;AAG9B,QAAI,aAAa,QAAQ,QAAQ,aAAa,QAAQ,QAAW;AAC/D,iBAAW,2BAA2B,2BAA2B,IAAI,OAAO,SAAS,aAAa,GAAG,IACjG,aAAa,IAAI,SAAS,IAC1B,OAAO,aAAa,GAAG;AAAA,IAC7B;AAGA,QAAI,aAAa,SAAS;AACxB,UAAI;AACJ,UAAI,OAAO,SAAS,aAAa,OAAO,GAAG;AACzC,sBAAc,aAAa,QAAQ;AAAA,MACrC,WAAW,OAAO,aAAa,YAAY,UAAU;AACnD,sBAAc,OAAO,WAAW,aAAa,SAAS,MAAM;AAAA,MAC9D,OAAO;AACL,sBAAc,KAAK,UAAU,aAAa,OAAO,EAAE;AAAA,MACrD;AACA,iBAAW,2BAA2B,2BAA2B,IAAI;AAAA,IACvE;AAAA,EACF;AAEA,SAAO;AACT;AAGA,SAAS,qBACP,gBAAwC,CAAC,GACM;AAC/C,QAAM,gBAA+D,CAAC;AACtE,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,aAAa,GAAG;AACxD,kBAAc,GAAG,IAAI,MAAM,SAAS,MAAM;AAAA,EAC5C;AACA,SAAO;AACT;AAGA,SAAS,uBAAuB,eAAsF;AACpH,QAAM,gBAAwC,CAAC;AAC/C,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,aAAa,GAAG;AACxD,QAAI,UAAU,QAAW;AACvB,YAAM,cAAc,MAAM,QAAQ,KAAK,IAAI,MAAM,KAAK,GAAG,IAAI;AAC7D,oBAAc,GAAG,IAAI,OAAO,KAAK,aAAa,MAAM;AAAA,IACtD;AAAA,EACF;AACA,SAAO;AACT;AAMO,SAAS,mBACd,UAA8B,CAAC,GAC/B,KACoB;AACpB,QAAM,gBAAgB,OAAO,mBAAQ,OAAO;AAC5C,QAAM,gBAAgB,OAAO,QAAQ,OAAO;AAC5C,QAAM,kBAAkB,cAAc,KAAK,CAAC,CAAC,EAAE,KAAK,MAAM,OAAO,SAAS,KAAK,CAAC;AAGhF,MAAI,iBAAiB;AACnB,UAAM,gBAAgB;AACtB,UAAM,gBAAgB,qBAAqB,aAAa;AAExD,2BAAY,OAAO,eAAe,eAAe;AAAA,MAC/C,KAAK,CAAC,SAAwD,KAAa,UAAkB;AAC3F,gBAAQ,GAAG,IAAI;AAAA,MACjB;AAAA,IACF,CAAC;AAED,UAAM,gBAAgB,uBAAuB,aAAa;AAE1D,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,aAAa,GAAG;AACxD,oBAAc,GAAG,IAAI;AAAA,IACvB;AAEA,WAAO;AAAA,EACT;AAEA,QAAM,gBAAgB;AAEtB,yBAAY,OAAO,eAAe,eAAe;AAAA,IAC/C,KAAK,CAAC,SAAwD,KAAa,UAAkB;AAC3F,cAAQ,GAAG,IAAI;AAAA,IACjB;AAAA,EACF,CAAC;AAGD,SAAO;AACT;AAGO,SAAS,yBAAyB,SAAqD;AAC5F,QAAM,gBAAwC,CAAC;AAE/C,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,OAAO,GAAG;AAClD,QAAI,UAAU,QAAW;AACvB,UAAI,OAAO,SAAS,KAAK,GAAG;AAC1B,sBAAc,GAAG,IAAI;AAAA,MACvB,WAAW,MAAM,QAAQ,KAAK,GAAG;AAC/B,sBAAc,GAAG,IAAI,OAAO,KAAK,MAAM,KAAK,GAAG,GAAG,MAAM;AAAA,MAC1D,OAAO;AACL,sBAAc,GAAG,IAAI,OAAO,KAAK,OAAO,MAAM;AAAA,MAChD;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAGO,SAAS,oBACd,UAAyD,CAAC,GACjD;AACT,SAAO,uBAAY,QAAQ,mBAAQ,OAAO,GAAG,SAAS;AAAA,IACpD,KAAK,CAAC,SAAwD,QAAgB;AAC5E,YAAM,QAAQ,QAAQ,GAAG;AACzB,YAAM,cAAc,MAAM,QAAQ,KAAK,IAAI,MAAM,CAAC,IAAI;AAEtD,UAAI,OAAO,SAAS,WAAW,GAAG;AAChC,eAAO,YAAY,SAAS,MAAM;AAAA,MACpC;AAEA,aAAO;AAAA,IACT;AAAA,IACA,MAAM,CAAC,YAA2D,OAAO,KAAK,OAAO;AAAA,EACvF,CAAC;AACH;AAGO,SAAS,kBACd,OACA,cACS;AACT,MAAI,CAAC,cAAc;AACjB,WAAO;AAAA,EACT;AAEA,MAAI,MAAM,QAAQ,YAAY,GAAG;AAC/B,WAAO,aAAa,SAAS,KAAK;AAAA,EACpC;AAEA,MAAI,OAAO,iBAAiB,YAAY;AACtC,QAAI;AACF,aAAO,aAAa,KAAK;AAAA,IAC3B,QAAQ;AAEN,aAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AACT;AAGO,SAAS,mBACd,QACA,QACA,YAAY,QACZ,eACa;AACb,MAAI,CAAC,QAAQ;AACX,WAAO;AAAA,EACT;AACA,QAAM,SAAS,iBAAiB,mBAAQ,OAAO;AAE/C,QAAM,WAAW,GAAG,OAAO,KAAK,IAAI,SAAS;AAC7C,QAAM,aAAa,4BAA4B,QAAQ,SAAS;AAEhE,QAAM,cAAc;AAAA,IAClB,MAAM,oBAAS;AAAA,IACf;AAAA,EACF;AAEA,SAAO,OAAO,UAAU,UAAU,aAAa,MAAM;AACvD;AAGO,SAAS,mBACd,QACA,SACA,YAAY,WACZ,eACa;AACb,MAAI,CAAC,QAAQ;AACX,WAAO;AAAA,EACT;AAEA,QAAM,WAAW,GAAG,QAAQ,KAAK,IAAI,SAAS;AAC9C,QAAM,aAAa,qBAAqB,SAAS,SAAS;AAE1D,QAAM,cAAc;AAAA,IAClB,MAAM,oBAAS;AAAA,IACf;AAAA,EACF;AAGA,MAAI,eAAe;AACjB,WAAO,OAAO,UAAU,UAAU,aAAa,aAAa;AAAA,EAC9D;AAEA,SAAO,OAAO,UAAU,UAAU,WAAW;AAC/C;AAGO,SAAS,gBACd,QACA,WACA,OACA,YAAY,iBACZ,eACa;AACb,MAAI,CAAC,QAAQ;AACX,WAAO;AAAA,EACT;AAEA,QAAM,WAAW,QAAQ,GAAG,KAAK,IAAI,SAAS,KAAK,SAAS,SAAS;AACrE,QAAM,aAAyB;AAAA,IAC7B,CAAC,2BAA2B,gBAAgB,GAAG,eAAe;AAAA,IAC9D,CAAC,2BAA2B,wBAAwB,GAAG;AAAA,IACvD,CAAC,2BAA2B,6BAA6B,GAAG;AAAA,EAC9D;AAEA,MAAI,OAAO;AACT,eAAW,2BAA2B,0BAA0B,IAAI;AACpE,eAAW,2BAA2B,0BAA0B,IAAI,eAAe;AAAA,EACrF;AAEA,QAAM,cAAc;AAAA,IAClB,MAAM,oBAAS;AAAA,IACf;AAAA,EACF;AAEA,MAAI,eAAe;AACjB,WAAO,OAAO,UAAU,UAAU,aAAa,aAAa;AAAA,EAC9D;AAEA,SAAO,OAAO,UAAU,UAAU,WAAW;AAC/C;;;AHzSO,IAAM,2BAAN,MAA+B;AAAA,EAC5B,eAA8B;AAAA,EAC9B;AAAA,EACA,WAAW;AAAA,EAEnB,YAAY,SAAyC,CAAC,GAAG;AACvD,SAAK,eAAe,EAAE,GAAG,qBAAqB,GAAG,OAAO;AAAA,EAC1D;AAAA,EAEA,IAAW,cAA8C;AACvD,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAW,cAA6B;AACtC,WAAO,KAAK;AAAA,EACd;AAAA,EAEO,aAAa,QAA8C;AAChE,SAAK,eAAe,EAAE,GAAG,KAAK,cAAc,GAAG,OAAO;AAAA,EACxD;AAAA,EAEO,kBAAkB,UAAgC;AACvD,SAAK,eAAe,SAAS,UAAU,aAAa,MAAM,aAAa,OAAO;AAAA,EAChF;AAAA,EAEO,SAAe;AACpB,SAAK,eAAe,UAAU,aAAa,MAAM,aAAa,OAAO;AACrE,SAAK,WAAW;AAEhB,QAAI,KAAK,cAAc,4BAA4B,KAAK,cAAc;AACpE,uBAAK,MAAM,oCAAoC;AAAA,IACjD;AAAA,EACF;AAAA,EAEO,UAAgB;AACrB,SAAK,eAAe;AACpB,SAAK,WAAW;AAChB,qBAAK,MAAM,qCAAqC;AAAA,EAClD;AAAA,EAEO,YAAqB;AAC1B,WAAO,KAAK,YAAY,KAAK,iBAAiB;AAAA,EAChD;AAAA,EAEO,oBAAsC;AAC3C,QAAI,CAAC,KAAK,UAAU,GAAG;AACrB,aAAO,KAAK,uBAAuB;AAAA,IACrC;AAEA,WAAO;AAAA,MACL,SAAS;AAAA,MACT,MAAM,kBAAM,cAAc,KAAK;AAAA;AAAA,MAE/B,QAAQ,KAAK;AAAA,MACb,SAAS,oBAAQ,OAAO;AAAA,MACxB,QAAQ,CAAC,SAAS,iBAAwB;AACxC,YAAI,cAAc;AAChB,gBAAM,cAAc,kBAAM,QAAQ,oBAAQ,OAAO,GAAG,YAAY;AAChE,6BAAmB,SAAS,WAAW;AACvC;AAAA,QACF;AAEA,cAAM,aAAa,kBAAM,cAAc;AACvC,YAAI,YAAY;AACd,gBAAM,cAAc,kBAAM,QAAQ,oBAAQ,OAAO,GAAG,UAAU;AAC9D,6BAAmB,SAAS,WAAW;AAAA,QACzC,OAAO;AACL,6BAAmB,SAAS,oBAAQ,OAAO,CAAC;AAAA,QAC9C;AAAA,MACF;AAAA,MACA,SAAS,CAAC,YAAY,oBAAoB,OAAO;AAAA,MACjD,WAAW,CAAC,MAAM,aAAyB,CAAC,MAAM;AAChD,YAAI,CAAC,KAAK,cAAc;AACtB,gBAAM,IAAI,MAAM,sBAAsB;AAAA,QACxC;AACA,cAAM,OAAO,KAAK,aAAa,UAAU,MAAM,EAAE,WAAW,CAAC;AAC7D,eAAO;AAAA,MACT;AAAA,MACA,SAAS,CAAC,MAAM,UAAU;AACxB,YAAI,CAAC,MAAM;AACT;AAAA,QACF;AACA,sBAAc,MAAM,KAAK;AACzB,aAAK,IAAI;AAAA,MACX;AAAA,IACF;AAAA,EACF;AAAA,EAEO,uBACL,cACA,UAC+D;AAC/D,QAAI,CAAC,KAAK,UAAU,GAAG;AACrB,aAAO;AAAA,IACT;AAGA,UAAM,kBAAkB;AAExB,UAAM,SAAS,KAAK;AAEpB,WAAO,eAAe,iBAAsC,QAA2C;AACrG,UAAI,CAAC,QAAQ;AACX,eAAO,aAAa,KAAK,MAAM,MAAwB;AAAA,MACzD;AAEA,YAAM,gBAAgB,oBAAQ,OAAO;AAErC,YAAM,eAAe,MAAM,QAAQ,MAAM;AACzC,YAAM,UAAU,eAAe,SAAS,CAAC,MAAM;AAE/C,UAAI,QAAQ,WAAW,GAAG;AACxB,eAAO,aAAa,KAAK,MAAM,eAAe,UAAW,MAAyB;AAAA,MACpF;AAEA,YAAM,aAAa,QAAQ;AAAA,QAAM,CAAC,kBAChC,kBAAkB,cAAc,OAAO,gBAAgB,aAAa,YAAY;AAAA,MAClF;AAEA,UAAI,YAAY;AACd,eAAO,aAAa,KAAK,MAAM,eAAe,UAAU,QAAQ,CAAC,CAAC;AAAA,MACpE;AAEA,YAAM,QAAgB,CAAC;AACvB,YAAM,eAAyD,CAAC;AAEhE,YAAM,sBAAsB,QAAQ,IAAI,CAAC,kBAAkB;AACzD,YAAI,CAAC,iBAAiB,kBAAkB,cAAc,OAAO,gBAAgB,aAAa,YAAY,GAAG;AACvG,iBAAO;AAAA,QACT;AAEA,cAAM,OAAO,mBAAmB,QAAQ,eAAe,QAAQ,aAAa;AAE5E,YAAI,CAAC,MAAM;AACT,iBAAO;AAAA,QACT;AAEA,YAAI,UAAU;AACZ,eAAK,cAAc,EAAE,uBAAuB,SAAS,CAAC;AAAA,QACxD;AAEA,cAAM,KAAK,IAAI;AACf,qBAAa,KAAK,EAAE,MAAM,QAAQ,cAAc,CAAC;AAEjD,cAAM,cAAc,kBAAM,QAAQ,eAAe,IAAI;AAErD,cAAM,qBAAqC;AAAA,UACzC,GAAG;AAAA,UACH,WAAW,cAAc,YAAY,CAAC,GAAG,IAAI,aAAW;AACtD,kBAAM,kBAAkB,EAAE,GAAG,QAAQ,QAAQ;AAC7C,kBAAM,kBAAkB,mBAAmB,iBAAiB,WAAW;AACvE,kBAAM,oBAAoB,yBAAyB,eAAe;AAElE,mBAAO;AAAA,cACL,GAAG;AAAA,cACH,SAAS;AAAA,YACX;AAAA,UACF,CAAC;AAAA,QACH;AAEA,YAAI,gBAAgB,aAAa,cAAc;AAC7C,cAAI;AACF,gCAAQ,KAAK,aAAa,MAAM;AAC9B,8BAAgB,aAAa,eAAe,MAAM,aAAa;AAAA,YACjE,CAAC;AAAA,UACH,SAAS,OAAO;AACd,6BAAK,KAAK,yBAAyB,KAAK;AAAA,UAC1C;AAAA,QACF;AAEA,eAAO;AAAA,MACT,CAAC;AAED,YAAM,UAAU,eAAe,sBAAsB,oBAAoB,CAAC;AAE1E,UAAI;AACF,cAAM,SAAS,MAAM,oBAAQ,KAAK,eAAe,YAAY,aAAa,KAAK,MAAM,OAAyB,CAAC;AAE/G,cAAM,gBAAgB,MAAM,QAAQ,MAAM,IAAI,SAAS,CAAC;AACxD,iBAAS,MAAM,GAAG,MAAM,aAAa,QAAQ,OAAO;AAClD,gBAAM,EAAE,KAAK,IAAI,aAAa,GAAG;AACjC,gBAAM,WAAW,cAAc,GAAG;AAClC,cAAI,UAAU;AACZ,gBAAI,SAAS,cAAc,QAAW;AACpC,mBAAK,aAAa,6BAA6B,SAAS,SAAS;AAAA,YACnE;AACA,gBAAI,SAAS,WAAW,QAAW;AACjC,mBAAK,aAAa,0BAA0B,SAAS,MAAM;AAAA,YAC7D;AAAA,UACF;AACA,wBAAc,MAAM,UAAU,QAAQ,IAAI,MAAM,SAAS,MAAM,OAAO,IAAI,MAAS;AACnF,eAAK,IAAI;AAAA,QACX;AAEA,YAAI,gBAAgB,aAAa,gBAAgB,cAAc,QAAQ;AACrE,gBAAM,CAAC,KAAK,IAAI;AAChB,cAAI,OAAO;AACT,gBAAI;AACF,8BAAgB,aAAa,aAAa,MAAM,MAAM,MAAM,QAAQ,cAAc,CAAC,CAAC;AAAA,YACtF,SAAS,OAAO;AACd,+BAAK,KAAK,uCAAuC,KAAK;AAAA,YACxD;AAAA,UACF;AAAA,QACF;AAEA,eAAO;AAAA,MACT,SAAS,OAAO;AACd,mBAAW,QAAQ,OAAO;AACxB,wBAAc,MAAM,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC,CAAC;AAC7E,eAAK,IAAI;AAAA,QACX;AACA,cAAM;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA,EAEO,0BAA0B,iBAA2B,SAAiD;AAC3G,QAAI,CAAC,KAAK,UAAU,GAAG;AACrB,aAAO;AAAA,IACT;AAGA,UAAM,kBAAkB;AAExB,UAAM,SAAS,KAAK;AAEpB,WAAO,eAAe,sBAAyC;AAC7D,YAAM,UAAU,MAAM,gBAAgB,KAAK,IAAI;AAE/C,UAAI,CAAC,SAAS;AACZ,eAAO;AAAA,MACT;AAEA,UAAI,kBAAkB,QAAQ,OAAO,gBAAgB,aAAa,YAAY,GAAG;AAC/E,eAAO;AAAA,MACT;AAEA,YAAM,gBAAgB,oBAAoB,QAAQ,WAAW,CAAC,CAAC,KAAK,oBAAQ,OAAO;AACnF,YAAM,OAAO,mBAAmB,QAAQ,SAAS,WAAW,aAAa;AAEzE,UAAI,MAAM;AACR,cAAM,UAAU,kBAAM,QAAQ,eAAe,IAAI;AAEjD,4BAAQ,KAAK,SAAS,MAAM;AAC1B,cAAI,SAAS;AACX,iBAAK,cAAc,EAAE,iCAAiC,QAAQ,CAAC;AAAA,UACjE;AAEA,cAAI,gBAAgB,aAAa,aAAa;AAC5C,gBAAI;AACF,8BAAgB,aAAa,YAAY,MAAM,OAAO;AAAA,YACxD,SAAS,OAAO;AACd,+BAAK,KAAK,wBAAwB,KAAK;AAAA,YACzC;AAAA,UACF;AAEA,wBAAc,IAAI;AAAA,QACpB,CAAC;AAED,aAAK,IAAI;AAAA,MACX;AAEA,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEO,uBACL,sBACA,SACyD;AACzD,QAAI,CAAC,KAAK,UAAU,KAAK,CAAC,KAAK,aAAa,4BAA4B;AACtE,aAAO;AAAA,IACT;AAGA,UAAM,kBAAkB;AAExB,UAAM,SAAS,KAAK;AAEpB,WAAO,eAAe,yBAA8C,MAAc,WAAmB;AACnG,YAAM,WAAW,MAAM,qBAAqB,KAAK,MAAM,MAAM,SAAS;AAEtE,UAAI,CAAC,MAAM,QAAQ,QAAQ,KAAK,SAAS,WAAW,GAAG;AACrD,eAAO;AAAA,MACT;AAEA,YAAM,uBAAuB,SAAS;AAAA,QAAO,CAAC,YAC5C,CAAC,kBAAkB,QAAQ,OAAO,gBAAgB,aAAa,YAAY;AAAA,MAC7E;AAEA,UAAI,qBAAqB,WAAW,GAAG;AACrC,eAAO;AAAA,MACT;AAEA,YAAM,CAAC,YAAY,IAAI;AACvB,YAAM,gBAAgB,oBAAoB,aAAa,WAAW,CAAC,CAAC,KAAK,oBAAQ,OAAO;AACxF,YAAM,YAAY;AAAA,QAChB;AAAA,QACA,qBAAqB;AAAA,QACrB,aAAa;AAAA,QACb;AAAA,QACA;AAAA,MACF;AAEA,UAAI,WAAW;AACb,YAAI,SAAS;AACX,oBAAU,cAAc,EAAE,iCAAiC,QAAQ,CAAC;AAAA,QACtE;AAEA,YAAI;AACF,qBAAW,WAAW,sBAAsB;AAC1C,kBAAM,mBAAmB,oBAAoB,QAAQ,WAAW,CAAC,CAAC,KAAK;AACvE,kBAAM,cAAc,mBAAmB,QAAQ,SAAS,WAAW,gBAAgB;AAEnF,gBAAI,aAAa;AACf,oBAAM,qBAAqB,kBAAM,QAAQ,oBAAoB,oBAAQ,OAAO,GAAG,WAAW;AAC1F,kCAAQ,KAAK,oBAAoB,MAAM;AACrC,4BAAY,cAAc;AAAA,kBACxB,iCAAiC,qBAAqB;AAAA,gBACxD,CAAC;AAED,oBAAI,gBAAgB,aAAa,aAAa;AAC5C,sBAAI;AACF,oCAAgB,aAAa,YAAY,aAAa,OAAO;AAAA,kBAC/D,SAAS,OAAO;AACd,qCAAK,KAAK,wBAAwB,KAAK;AAAA,kBACzC;AAAA,gBACF;AAEA,8BAAc,WAAW;AAAA,cAC3B,CAAC;AACD,0BAAY,IAAI;AAAA,YAClB;AAAA,UACF;AAEA,wBAAc,SAAS;AAAA,QACzB,SAAS,OAAO;AACd,wBAAc,WAAW,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC,CAAC;AAAA,QACpF,UAAE;AACA,oBAAU,IAAI;AAAA,QAChB;AAAA,MACF;AAEA,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA,EAGQ,yBAA2C;AACjD,WAAO;AAAA,MACL,SAAS;AAAA,MACT,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,SAAS,oBAAQ,OAAO;AAAA,MACxB,QAAQ,MAAM;AAAA,MAEd;AAAA,MACA,SAAS,MAAM,oBAAQ,OAAO;AAAA,MAC9B,WAAW,MAAM;AAAA,MACjB,SAAS,MAAM;AAAA,MAEf;AAAA,IACF;AAAA,EACF;AACF;AAGA,IAAI,wBAAyD;AAEtD,SAAS,wBAAwB,QAAmE;AACzG,MAAI,CAAC,uBAAuB;AAC1B,4BAAwB,IAAI,yBAAyB,MAAM;AAC3D,0BAAsB,OAAO;AAAA,EAC/B,WAAW,QAAQ;AACjB,0BAAsB,aAAa,MAAM;AAAA,EAC3C;AACA,SAAO;AACT;AAEO,SAAS,4BAAkC;AAChD,MAAI,uBAAuB;AACzB,0BAAsB,QAAQ;AAC9B,4BAAwB;AAAA,EAC1B;AACF;;;AItZA,yBAA+C;AAYxC,IAAe,0BAAf,cAA+C,4BAAS;AAAA,EACrD;AAAA;AAAA;AAAA;AAAA,EAKR,YACE,eACA;AACA,UAAM,EAAE,eAAe,GAAG,KAAK,IAAI;AAEnC,UAAM,IAAI;AAEV,QAAI,CAAC,eAAe;AAClB,YAAM,IAAI,MAAM,6CAA6C;AAAA,IAC/D;AAEA,SAAK,iBAAiB;AAAA,EACxB;AAAA,EAEA,IAAI,gBAA+B;AACjC,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,WAAoB;AAClB,WAAO,KAAK,oBAAoB;AAAA,EAClC;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,UAAU,QAA8C;AAC5D,QAAI,CAAC,UAAW,MAAM,QAAQ,MAAM,KAAK,OAAO,WAAW,GAAI;AAC7D,YAAM,IAAI,MAAM,6CAA6C;AAAA,IAC/D;AACA,UAAM,KAAK,cAAc,UAAU,MAAM;AAAA,EAC3C;AAAA,EAEA,KAAK,OAAe,WAAmB,aAA0B,SAAkB;AACjF,SAAK,cAAc,KAAK,OAAO,WAAW,aAAa,OAAO;AAAA,EAChE;AAAA,EAEA,MAAM,OAAO,OAAe,WAAmB,QAAgB,YAAwB;AACrF,WAAO,KAAK,cAAc,OAAO,OAAO,WAAW,QAAQ,UAAU;AAAA,EACvE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,cAAc,SAAkB,YAAwB;AAC5D,WAAO,KAAK,cAAc,cAAc,SAAS,UAAU;AAAA,EAC7D;AAAA;AAAA;AAAA;AAAA,EAKA,cAAc;AACZ,SAAK,cAAc,YAAY;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,aAAa;AACjB,UAAM,KAAK,cAAc,WAAW;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,cAAc;AACZ,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,SAAS,OAAqB,UAAgD;AAE5E,QAAI;AACF,WAAK,cAAc,YAAY;AAAA,IACjC,QAAQ;AAAA,IAGR;AAGA,SAAK,cACF,WAAW,EACX,KAAK,MAAM;AAEV,eAAS,KAAK;AAAA,IAChB,CAAC,EAEA,MAAM,CAAC,oBAAoB;AAE1B,YAAM,gBAAgB,QAClB,IAAI,MAAM,iBAAiB,MAAM,OAAO,uBAAuB,gBAAgB,OAAO,EAAE,IACxF;AACJ,eAAS,aAAa;AAAA,IACxB,CAAC;AAAA,EACL;AAOF;;;AC/HA,IAAM,wBAAwB;AAWvB,IAAM,2BAAN,cAAuC,wBAAwB;AAAA,EAC5D,kBAA6B,CAAC;AAAA,EACrB;AAAA,EACA;AAAA;AAAA;AAAA;AAAA,EAKjB,YACE,eACA;AACA,UAAM,EAAE,WAAW,eAAe,uBAAuB,GAAG,KAAK,IAAI;AAGrE,SAAK,gBAAgB,KAAK,IAAI,WAAW,KAAK,iBAAiB,EAAE;AAEjE,UAAM,EAAE,GAAG,eAAe,GAAG,KAAK,CAAC;AACnC,SAAK,YAAY;AACjB,SAAK,eAAe;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,iBAA8D;AAC5D,WAAO;AAAA,MACL,WAAW,KAAK;AAAA,MAChB,cAAc,KAAK;AAAA,IACrB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,QAAQ;AACZ,QAAI,KAAK,WAAW;AAClB;AAAA,IACF;AACA,QAAI;AAEF,aAAO,KAAK,gBAAgB,SAAS,GAAG;AACtC,cAAM,UAAU,KAAK,gBAAgB,MAAM;AAC3C,YAAI,CAAC,KAAK,KAAK,OAAO,GAAG;AACvB;AAAA,QACF;AAAA,MACF;AAGA,YAAM,WAAW,MAAM,KAAK,cAAc,UAAU,KAAK,WAAW,KAAK,YAAY;AAErF,UAAI,SAAS,WAAW,GAAG;AAEzB,YAAI,CAAC,KAAK,WAAW;AACnB,uBAAa,MAAM,KAAK,MAAM,CAAC;AAAA,QACjC;AACA;AAAA,MACF;AAGA,eAAS,MAAM,GAAG,MAAM,SAAS,QAAQ,OAAO;AAC9C,YAAI,CAAC,KAAK,KAAK,SAAS,GAAG,CAAC,GAAG;AAE7B,eAAK,kBAAkB,SAAS,MAAM,MAAM,CAAC;AAC7C;AAAA,QACF;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AAEd,WAAK,QAAQ,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC,CAAC;AAAA,IACxE;AAAA,EACF;AACF;;;AClFO,IAAM,sBAAN,cAAkC,wBAAwB;AAAA;AAAA;AAAA;AAAA;AAAA,EAK/D,MAAM,QAAQ;AACZ,QAAI;AACF,YAAM,UAAU,MAAM,KAAK,cAAc,KAAK;AAC9C,UAAI,SAAS;AACX,aAAK,KAAK,OAAO;AAAA,MACnB,OAAO;AACL,aAAK,KAAK,IAAI;AAAA,MAChB;AAAA,IACF,SAAS,OAAO;AACd,UAAI,iBAAiB,OAAO;AAC1B,aAAK,QAAQ,KAAK;AAAA,MACpB,OAAO;AACL,aAAK,QAAQ,IAAI,MAAM,kBAAkB,OAAO,KAAK,CAAC,EAAE,CAAC;AAAA,MAC3D;AAAA,IACF;AAAA,EACF;AACF;;;APEO,IAAM,cAAN,MAAM,aAAY;AAAA;AAAA;AAAA;AAAA;AAAA,EASvB,YAA6B,oBAA8C;AAA9C;AAE3B,UAAM,EAAE,MAAM,GAAG,YAAY,IAAI;AACjC,SAAK,oBAAoB,IAAI,oCAAkB,WAAW;AAG1D,SAAK,eAAe,SAAS,SAAS,SAAS;AAC/C,QAAI,KAAK,gBAAgB,OAAO,SAAS,UAAU;AACjD,YAAM,kBAAkB,wBAAwB,IAAI;AACpD,WAAK,eAAe,gBAAgB,kBAAkB;AAAA,IACxD,WAAW,KAAK,cAAc;AAC5B,YAAM,kBAAkB,wBAAwB;AAChD,WAAK,eAAe,gBAAgB,kBAAkB;AAAA,IACxD,OAAO;AACL,WAAK,eAAe,KAAK,2BAA2B;AAAA,IACtD;AAAA,EACF;AAAA,EAxBiB;AAAA,EACA;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAAA,EA4BjB,IAAI,OAAyB;AAC3B,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,eAAe,uBAA+C;AAC5D,UAAM,WAAW,wBACb,KAAK,kBAAkB,eAAe,qBAAqB,IAC3D,KAAK,kBAAkB,eAAe,CAAC,CAAC;AAG5C,QAAI,KAAK,gBAAgB,KAAK,aAAa,SAAS;AAClD,aAAO,KAAK,oBAAoB,QAAQ;AAAA,IAC1C;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,eAAe,uBAA8C;AAC3D,UAAM,WAAW,KAAK,kBAAkB,eAAe,qBAAqB;AAG5E,QAAI,KAAK,gBAAgB,KAAK,aAAa,SAAS;AAClD,aAAO,aAAY,oBAAoB,UAAU,sBAAsB,OAAO;AAAA,IAChF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,qBACE,qBACgD;AAChD,UAAM,EAAE,WAAW,cAAc,eAAe,GAAG,sBAAsB,IAAI;AAC7E,UAAM,gBAAgB,KAAK,kBAAkB,eAAe,qBAAqB;AACjF,UAAM,uBAAuB,KAAK,gBAAgB,KAAK,aAAa,UAChE,aAAY,oBAAoB,eAAe,sBAAsB,OAAO,IAC5E;AACJ,UAAM,OAAO,iBAAiB,EAAE,YAAY,KAAK;AAGjD,QAAI,aAAa,YAAY,GAAG;AAC9B,aAAO,IAAI,yBAAyB,EAAE,eAAe,sBAAsB,WAAW,cAAc,GAAG,KAAK,CAAC;AAAA,IAC/G;AAEA,WAAO,IAAI,oBAAoB,EAAE,eAAe,sBAAsB,GAAG,KAAK,CAAC;AAAA,EACjF;AAAA,EAEQ,oBAAoB,UAAyB;AACnD,UAAM,kBAAkB,wBAAwB;AAChD,UAAM,eAAe,SAAS,KAAK,KAAK,QAAQ;AAEhD,aAAS,OAAO,gBAAgB;AAAA,MAC9B;AAAA,MACA,KAAK,mBAAmB;AAAA,IAC1B;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,OAAe,oBAAoB,UAAyB,SAAkB;AAC5E,UAAM,kBAAkB,wBAAwB;AAChD,UAAM,eAAe,SAAS,KAAK,KAAK,QAAQ;AAChD,UAAM,oBAAoB,SAAS,UAAU,KAAK,QAAQ;AAE1D,aAAS,OAAO,gBAAgB,0BAA0B,cAAc,OAAO;AAC/E,aAAS,YAAY,gBAAgB,uBAAuB,mBAAmB,OAAO;AAEtF,WAAO;AAAA,EACT;AAAA;AAAA,EAGQ,6BAA+C;AAErD,WAAO;AAAA,MACL,SAAS;AAAA,MACT,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,SAAS,oBAAQ,OAAO;AAAA,MACxB,QAAQ,MAAM;AAAA,MAEd;AAAA,MACA,SAAS,MAAM,oBAAQ,OAAO;AAAA,MAC9B,WAAW,MAAM;AAAA,MACjB,SAAS,CAAC,SAAuB;AAC/B,YAAI,QAAQ,OAAO,KAAK,QAAQ,YAAY;AAC1C,eAAK,IAAI;AAAA,QACX;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;",
|
|
6
6
|
"names": ["import_js_binding", "import_api", "import_api"]
|
|
7
7
|
}
|
package/dist/index.js
CHANGED
|
@@ -661,14 +661,6 @@ var BaseKafkaStreamReadable = class extends Readable {
|
|
|
661
661
|
* @private
|
|
662
662
|
*/
|
|
663
663
|
_destroy(error, callback) {
|
|
664
|
-
try {
|
|
665
|
-
this.push(null);
|
|
666
|
-
} catch {
|
|
667
|
-
}
|
|
668
|
-
try {
|
|
669
|
-
this.emit("end");
|
|
670
|
-
} catch {
|
|
671
|
-
}
|
|
672
664
|
try {
|
|
673
665
|
this.kafkaConsumer.unsubscribe();
|
|
674
666
|
} catch {
|
|
@@ -680,14 +672,6 @@ var BaseKafkaStreamReadable = class extends Readable {
|
|
|
680
672
|
callback(combinedError);
|
|
681
673
|
});
|
|
682
674
|
}
|
|
683
|
-
/**
|
|
684
|
-
* Called when the stream is finishing (no more data will be written)
|
|
685
|
-
* Ensures proper cleanup when stream ends normally
|
|
686
|
-
* @private
|
|
687
|
-
*/
|
|
688
|
-
_final(callback) {
|
|
689
|
-
this.kafkaConsumer.disconnect().then(() => callback()).catch((error) => callback(error));
|
|
690
|
-
}
|
|
691
675
|
};
|
|
692
676
|
|
|
693
677
|
// js-src/streams/kafka-batch-stream-readable.ts
|