{"version":3,"sources":["../src/messaging.ts"],"names":["trace","SpanKind","propagation","context","emitCorrelatedEvent","extractLinksFromBatch","createLinkFromHeaders"],"mappings":"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","file":"chunk-IRJHH6PH.cjs","sourcesContent":["/**\n * Messaging helpers for event-driven architectures\n *\n * Provides specialized tracing for message producers and consumers\n * with automatic context propagation, link extraction, and OTel\n * semantic convention compliance.\n *\n * @example Producer\n * ```typescript\n * import { traceProducer } from 'autotel/messaging';\n *\n * export const publishEvent = traceProducer({\n *   system: 'kafka',\n *   destination: 'user-events',\n * })(ctx => async (event: UserEvent) => {\n *   const headers = ctx.getTraceHeaders();\n *   await producer.send({\n *     topic: 'user-events',\n *     messages: [{ value: JSON.stringify(event), headers }]\n *   });\n * });\n * ```\n *\n * @example Consumer\n * ```typescript\n * import { traceConsumer } from 'autotel/messaging';\n *\n * export const processEvents = traceConsumer({\n *   system: 'kafka',\n *   destination: 'user-events',\n *   consumerGroup: 'event-processor',\n *   batchMode: true,\n * })(ctx => async (messages: KafkaMessage[]) => {\n *   // Links to producer spans are automatically extracted\n *   for (const msg of messages) {\n *     await processMessage(msg);\n *   }\n * });\n * ```\n *\n * @module\n */\n\nimport { SpanKind, context, propagation } from '@opentelemetry/api';\nimport type {\n  Attributes,\n  AttributeValue,\n  Link,\n  SpanContext,\n} from '@opentelemetry/api';\nimport { trace } from './functional';\nimport type { TraceContext } from './trace-context';\nimport { emitCorrelatedEvent } from './correlated-events';\nimport { createLinkFromHeaders, extractLinksFromBatch } from './sampling';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Supported messaging systems\n */\nexport type MessagingSystem =\n  | 'kafka'\n  | 'rabbitmq'\n  | 'sqs'\n  | 'sns'\n  | 'pubsub'\n  | 'activemq'\n  | 'azure_servicebus'\n  | 'eventhubs'\n  | (string & {});\n\n/**\n * Messaging operation types\n */\nexport type MessagingOperation = 'publish' | 'receive' | 'process' | 'settle';\n\n/**\n * Configuration for producer tracing\n */\nexport interface ProducerConfig {\n  /** Messaging system (kafka, rabbitmq, sqs, etc.) */\n  system: MessagingSystem;\n\n  /** Destination name (topic/queue) */\n  destination: string;\n\n  /** Extract message ID from arguments */\n  messageIdFrom?: string | ((args: unknown[]) => string | undefined);\n\n  /** Extract partition from arguments (Kafka-specific) */\n  partitionFrom?: string | ((args: unknown[]) => number | undefined);\n\n  /** Extract message key from arguments (Kafka-specific) */\n  keyFrom?: string | ((args: unknown[]) => string | undefined);\n\n  /** Additional attributes to set on span */\n  attributes?: Attributes;\n\n  /** Propagate baggage in message headers */\n  propagateBaggage?: boolean;\n\n  /** Callback before sending (for custom attributes) */\n  beforeSend?: (ctx: ProducerContext, args: unknown[]) => void;\n\n  /** Callback on error */\n  onError?: (error: Error, ctx: ProducerContext) => void;\n\n  // ---- Extensible Hooks (\"Bring Your Own\" System Support) ----\n\n  /**\n   * Hook to add system-specific attributes\n   *\n   * Use this to add attributes for messaging systems not explicitly supported\n   * (e.g., NATS, Temporal, Cloudflare Queues, Redis Streams).\n   *\n   * @example NATS attributes\n   * ```typescript\n   * customAttributes: (ctx, args) => ({\n   *   'nats.subject': args[0].subject,\n   *   'nats.reply_to': args[0].replyTo,\n   *   'nats.stream': 'orders',\n   * })\n   * ```\n   *\n   * @example Temporal attributes\n   * ```typescript\n   * customAttributes: (ctx, args) => ({\n   *   'temporal.workflow_id': args[0].workflowId,\n   *   'temporal.run_id': args[0].runId,\n   *   'temporal.task_queue': 'orders-queue',\n   * })\n   * ```\n   */\n  customAttributes?: (\n    ctx: ProducerContext,\n    args: unknown[],\n  ) => Record<string, AttributeValue>;\n\n  /**\n   * Hook for custom header injection (beyond W3C traceparent)\n   *\n   * Use this to inject headers for systems that use non-standard\n   * context propagation formats.\n   *\n   * @example Datadog headers\n   * ```typescript\n   * customHeaders: (ctx) => ({\n   *   'x-datadog-trace-id': ctx.getTraceId(),\n   *   'x-datadog-parent-id': ctx.getSpanId(),\n   * })\n   * ```\n   *\n   * @example Custom correlation headers\n   * ```typescript\n   * customHeaders: (ctx) => ({\n   *   'x-correlation-id': correlationId,\n   *   'x-request-id': requestId,\n   * })\n   * ```\n   */\n  customHeaders?: (ctx: ProducerContext) => Record<string, string>;\n}\n\n/**\n * Configuration for consumer tracing\n */\nexport interface ConsumerConfig {\n  /** Messaging system (kafka, rabbitmq, sqs, etc.) */\n  system: MessagingSystem;\n\n  /** Destination name (topic/queue) */\n  destination: string;\n\n  /** Consumer group name */\n  consumerGroup?: string;\n\n  /** Extract headers from message for link creation */\n  headersFrom?: string | ((msg: unknown) => Record<string, string> | undefined);\n\n  /** Enable batch mode - extract links from all messages */\n  batchMode?: boolean;\n\n  /** Extract baggage from message headers */\n  extractBaggage?: boolean;\n\n  /** Additional attributes to set on span */\n  attributes?: Attributes;\n\n  /** Consumer lag metrics extraction */\n  lagMetrics?: LagMetricsConfig;\n\n  /** Callback when message goes to DLQ */\n  onDLQ?: (ctx: ConsumerContext, reason: string) => void;\n\n  /** Callback on error */\n  onError?: (error: Error, ctx: ConsumerContext) => void;\n\n  // ---- Message Ordering Support ----\n\n  /**\n   * Message ordering configuration\n   *\n   * Enable sequence tracking, out-of-order detection, and deduplication.\n   *\n   * @example Kafka ordering\n   * ```typescript\n   * ordering: {\n   *   sequenceFrom: (msg) => msg.offset,\n   *   partitionKeyFrom: (msg) => msg.key,\n   *   detectOutOfOrder: true,\n   *   onOutOfOrder: (ctx, info) => {\n   *     console.warn(`Out of order: expected ${info.expectedSequence}, got ${info.currentSequence}`);\n   *   },\n   * }\n   * ```\n   */\n  ordering?: OrderingConfig;\n\n  // ---- Consumer Group Tracking ----\n\n  /**\n   * Consumer group tracking configuration\n   *\n   * Enables observability of consumer group state, including membership,\n   * partition assignments, and rebalancing events.\n   *\n   * @example Kafka consumer group tracking\n   * ```typescript\n   * consumerGroupTracking: {\n   *   memberId: () => consumer.memberId,\n   *   groupInstanceId: process.env.KAFKA_GROUP_INSTANCE_ID,\n   *   onRebalance: (ctx, event) => {\n   *     if (event.type === 'revoked') {\n   *       logger.warn('Partitions revoked', event.partitions);\n   *     }\n   *   },\n   *   trackPartitionLag: true,\n   * }\n   * ```\n   */\n  consumerGroupTracking?: ConsumerGroupTrackingConfig;\n\n  // ---- Extensible Hooks (\"Bring Your Own\" System Support) ----\n\n  /**\n   * Hook to add system-specific attributes\n   *\n   * Use this to add attributes for messaging systems not explicitly supported\n   * (e.g., NATS, Temporal, Cloudflare Queues, Redis Streams).\n   *\n   * @example NATS consumer attributes\n   * ```typescript\n   * customAttributes: (ctx, msg) => ({\n   *   'nats.subject': msg.subject,\n   *   'nats.stream': msg.info?.stream,\n   *   'nats.consumer': msg.info?.consumer,\n   *   'nats.delivered_count': msg.info?.redeliveryCount,\n   * })\n   * ```\n   *\n   * @example Cloudflare Queue attributes\n   * ```typescript\n   * customAttributes: (ctx, msg) => ({\n   *   'cloudflare.queue_id': msg.id,\n   *   'cloudflare.timestamp_ms': msg.timestamp.getTime(),\n   *   'cloudflare.attempts': msg.attempts,\n   * })\n   * ```\n   */\n  customAttributes?: (\n    ctx: ConsumerContext,\n    msg: unknown,\n  ) => Record<string, AttributeValue>;\n\n  /**\n   * Hook for custom context extraction (beyond W3C traceparent)\n   *\n   * Use this to extract parent span context from systems that use\n   * non-standard header formats.\n   *\n   * @example Datadog context extraction\n   * ```typescript\n   * customContextExtractor: (headers) => {\n   *   const traceId = headers['x-datadog-trace-id'];\n   *   const spanId = headers['x-datadog-parent-id'];\n   *   if (!traceId || !spanId) return null;\n   *   return {\n   *     traceId: traceIdToOtel(traceId),\n   *     spanId: spanIdToOtel(spanId),\n   *     traceFlags: TraceFlags.SAMPLED,\n   *   };\n   * }\n   * ```\n   *\n   * @example B3 format extraction\n   * ```typescript\n   * customContextExtractor: (headers) => {\n   *   const traceId = headers['x-b3-traceid'];\n   *   const spanId = headers['x-b3-spanid'];\n   *   const sampled = headers['x-b3-sampled'] === '1';\n   *   if (!traceId || !spanId) return null;\n   *   return {\n   *     traceId,\n   *     spanId,\n   *     traceFlags: sampled ? TraceFlags.SAMPLED : TraceFlags.NONE,\n   *   };\n   * }\n   * ```\n   */\n  customContextExtractor?: (\n    headers: Record<string, string>,\n  ) => SpanContext | null;\n}\n\n/**\n * Configuration for consumer lag metrics\n */\nexport interface LagMetricsConfig {\n  /** Get current message offset */\n  getCurrentOffset?: (msg: unknown) => number | undefined;\n\n  /** Get end offset (high watermark) - can be async */\n  getEndOffset?: () => number | Promise<number>;\n\n  /** Get committed offset - can be async */\n  getCommittedOffset?: () => number | Promise<number>;\n\n  /** Get partition from message */\n  getPartition?: (msg: unknown) => number | undefined;\n}\n\n/**\n * Configuration for message ordering tracking\n */\nexport interface OrderingConfig {\n  /**\n   * Extract sequence number from message\n   *\n   * Sequence numbers enable out-of-order detection and gap analysis.\n   *\n   * @example Kafka offset\n   * ```typescript\n   * sequenceFrom: (msg) => msg.offset\n   * ```\n   */\n  sequenceFrom?: (msg: unknown) => number | undefined;\n\n  /**\n   * Extract partition key from message\n   *\n   * Partition keys determine message ordering in Kafka.\n   *\n   * @example Message key\n   * ```typescript\n   * partitionKeyFrom: (msg) => msg.key\n   * ```\n   */\n  partitionKeyFrom?: (msg: unknown) => string | undefined;\n\n  /**\n   * Extract message ID for deduplication\n   *\n   * Used to detect duplicate messages.\n   *\n   * @example Idempotency key\n   * ```typescript\n   * messageIdFrom: (msg) => msg.headers['idempotency-key']\n   * ```\n   */\n  messageIdFrom?: (msg: unknown) => string | undefined;\n\n  /**\n   * Enable out-of-order detection\n   *\n   * Tracks sequence numbers per partition and detects when messages\n   * arrive out of order.\n   *\n   * @default false\n   */\n  detectOutOfOrder?: boolean;\n\n  /**\n   * Enable deduplication detection\n   *\n   * Tracks message IDs and detects duplicates within the window.\n   *\n   * @default false\n   */\n  detectDuplicates?: boolean;\n\n  /**\n   * Deduplication window size (number of message IDs to track)\n   *\n   * @default 1000\n   */\n  deduplicationWindowSize?: number;\n\n  /**\n   * Callback when out-of-order message detected\n   */\n  onOutOfOrder?: (ctx: ConsumerContext, info: OutOfOrderInfo) => void;\n\n  /**\n   * Callback when duplicate message detected\n   */\n  onDuplicate?: (ctx: ConsumerContext, messageId: string) => void;\n}\n\n/**\n * Information about out-of-order message\n */\nexport interface OutOfOrderInfo {\n  /** Current sequence number */\n  currentSequence: number;\n\n  /** Expected sequence number */\n  expectedSequence: number;\n\n  /** Partition key (if available) */\n  partitionKey?: string;\n\n  /** Gap size (positive = gap, negative = out of order) */\n  gap: number;\n}\n\n// ============================================================================\n// Consumer Group Tracking Types\n// ============================================================================\n\n/**\n * Configuration for consumer group tracking\n *\n * Enables observability of consumer group state, including membership,\n * partition assignments, and rebalancing events.\n *\n * @example Kafka consumer group tracking\n * ```typescript\n * consumerGroupTracking: {\n *   memberId: consumer.memberId,\n *   groupInstanceId: process.env.CONSUMER_ID,\n *   onRebalance: (ctx, event) => {\n *     if (event.type === 'assigned') {\n *       console.log(`Assigned partitions: ${event.partitions}`);\n *     }\n *   },\n * }\n * ```\n */\nexport interface ConsumerGroupTrackingConfig {\n  /**\n   * Consumer member ID\n   *\n   * Unique identifier assigned by the broker to this consumer.\n   */\n  memberId?: string | (() => string | undefined);\n\n  /**\n   * Static group instance ID (for static membership)\n   *\n   * If set, enables static group membership which prevents\n   * rebalances when consumers restart.\n   */\n  groupInstanceId?: string | (() => string | undefined);\n\n  /**\n   * Callback when rebalance occurs\n   */\n  onRebalance?: (ctx: ConsumerContext, event: RebalanceEvent) => void;\n\n  /**\n   * Callback when partitions are assigned\n   */\n  onPartitionsAssigned?: (\n    ctx: ConsumerContext,\n    partitions: PartitionAssignment[],\n  ) => void;\n\n  /**\n   * Callback when partitions are revoked\n   */\n  onPartitionsRevoked?: (\n    ctx: ConsumerContext,\n    partitions: PartitionAssignment[],\n  ) => void;\n\n  /**\n   * Track consumer lag per partition\n   *\n   * @default true\n   */\n  trackPartitionLag?: boolean;\n\n  /**\n   * Track consumer heartbeat health\n   *\n   * @default false\n   */\n  trackHeartbeat?: boolean;\n\n  /**\n   * Heartbeat interval in milliseconds (for health tracking)\n   */\n  heartbeatIntervalMs?: number;\n}\n\n/**\n * Rebalance event types\n */\nexport type RebalanceType = 'assigned' | 'revoked' | 'lost';\n\n/**\n * Rebalance event information\n */\nexport interface RebalanceEvent {\n  /** Type of rebalance event */\n  type: RebalanceType;\n\n  /** Partitions affected by the rebalance */\n  partitions: PartitionAssignment[];\n\n  /** Timestamp of the rebalance event */\n  timestamp: number;\n\n  /** Generation ID (increments on each rebalance) */\n  generation?: number;\n\n  /** Consumer member ID */\n  memberId?: string;\n\n  /** Reason for the rebalance (if available) */\n  reason?: string;\n}\n\n/**\n * Partition assignment information\n */\nexport interface PartitionAssignment {\n  /** Topic name */\n  topic: string;\n\n  /** Partition number */\n  partition: number;\n\n  /** Initial offset (if available) */\n  offset?: number;\n\n  /** Metadata (if available) */\n  metadata?: string;\n}\n\n/**\n * Consumer group state snapshot\n */\nexport interface ConsumerGroupState {\n  /** Consumer group name */\n  groupId: string;\n\n  /** Consumer member ID */\n  memberId?: string;\n\n  /** Static instance ID (if using static membership) */\n  groupInstanceId?: string;\n\n  /** Currently assigned partitions */\n  assignedPartitions: PartitionAssignment[];\n\n  /** Group generation ID */\n  generation?: number;\n\n  /** Whether the consumer is currently active */\n  isActive: boolean;\n\n  /** Last heartbeat timestamp */\n  lastHeartbeat?: number;\n\n  /** Consumer state (stable, preparing_rebalance, completing_rebalance, dead) */\n  state?:\n    | 'stable'\n    | 'preparing_rebalance'\n    | 'completing_rebalance'\n    | 'dead'\n    | 'empty';\n}\n\n/**\n * Partition lag information\n */\nexport interface PartitionLag {\n  /** Topic name */\n  topic: string;\n\n  /** Partition number */\n  partition: number;\n\n  /** Current consumer offset */\n  currentOffset: number;\n\n  /** End offset (high watermark) */\n  endOffset: number;\n\n  /** Calculated lag */\n  lag: number;\n\n  /** Timestamp of measurement */\n  timestamp: number;\n}\n\n/**\n * DLQ failure category types\n */\nexport type DLQReasonCategory =\n  | 'validation'\n  | 'processing'\n  | 'timeout'\n  | 'poison'\n  | 'unknown';\n\n/**\n * Options for enhanced DLQ recording\n */\nexport interface DLQOptions {\n  /**\n   * Automatically link to the producer span context\n   *\n   * When true, creates a span link from the DLQ event back to\n   * the original producer span for correlation.\n   *\n   * @default true\n   */\n  linkToProducer?: boolean;\n\n  /**\n   * Category of the failure that caused DLQ routing\n   *\n   * - validation: Message failed schema/format validation\n   * - processing: Business logic error during processing\n   * - timeout: Processing exceeded allowed time\n   * - poison: Message causes repeated failures (poison pill)\n   * - unknown: Uncategorized failure\n   */\n  reasonCategory?: DLQReasonCategory;\n\n  /**\n   * Number of processing attempts before DLQ routing\n   */\n  attemptCount?: number;\n\n  /**\n   * The original error that caused DLQ routing\n   *\n   * Error details are recorded as span attributes for debugging.\n   */\n  originalError?: Error;\n\n  /**\n   * Additional metadata to record with the DLQ event\n   */\n  metadata?: Record<string, string | number | boolean>;\n}\n\n/**\n * Options for recording DLQ replay\n */\nexport interface DLQReplayOptions {\n  /**\n   * Original span context from DLQ message\n   *\n   * If provided, creates a span link to correlate with the original failure.\n   */\n  originalDLQSpanContext?: SpanContext;\n\n  /**\n   * Time spent in DLQ before replay (milliseconds)\n   */\n  dlqDwellTimeMs?: number;\n\n  /**\n   * Retry attempt number for this replay\n   */\n  replayAttempt?: number;\n}\n\n/**\n * Extended trace context for producers with header injection\n */\nexport interface ProducerContext extends TraceContext {\n  /**\n   * Get W3C trace context headers to inject into message\n   *\n   * @returns Headers object with traceparent and optionally tracestate\n   *\n   * @example\n   * ```typescript\n   * const headers = ctx.getTraceHeaders();\n   * await producer.send({\n   *   topic: 'events',\n   *   messages: [{ value: data, headers }]\n   * });\n   * ```\n   */\n  getTraceHeaders(): { traceparent: string; tracestate?: string };\n\n  /**\n   * Get all propagation headers including baggage if enabled\n   *\n   * @returns Headers object with all W3C trace context headers\n   */\n  getAllPropagationHeaders(): Record<string, string>;\n\n  /**\n   * Get all headers including custom headers from customHeaders hook\n   *\n   * This combines W3C trace context headers, baggage (if enabled),\n   * and any custom headers defined via the customHeaders hook.\n   *\n   * @returns Combined headers object\n   *\n   * @example\n   * ```typescript\n   * const headers = ctx.getFullHeaders();\n   * // Contains: traceparent, tracestate, baggage (if enabled), and custom headers\n   * await producer.send({ topic, messages: [{ value, headers }] });\n   * ```\n   */\n  getFullHeaders(): Record<string, string>;\n}\n\n/**\n * Extended trace context for consumers\n */\nexport interface ConsumerContext extends TraceContext {\n  /**\n   * Record that a message is being sent to DLQ\n   *\n   * Enhanced with auto-linking to producer span, failure categorization,\n   * and detailed error recording for comprehensive DLQ observability.\n   *\n   * @param reason - Human-readable reason for DLQ routing\n   * @param dlqNameOrOptions - DLQ name (string) or enhanced options object\n   * @param options - Enhanced DLQ options (when second param is dlqName)\n   *\n   * @example Basic usage (backwards compatible)\n   * ```typescript\n   * ctx.recordDLQ('Schema validation failed', 'orders-dlq');\n   * ```\n   *\n   * @example Enhanced usage with options\n   * ```typescript\n   * ctx.recordDLQ('Invalid order total', 'orders-dlq', {\n   *   reasonCategory: 'validation',\n   *   attemptCount: 3,\n   *   originalError: error,\n   *   linkToProducer: true, // Auto-links to producer span\n   * });\n   * ```\n   *\n   * @example Using options object as second param\n   * ```typescript\n   * ctx.recordDLQ('Processing timeout', {\n   *   reasonCategory: 'timeout',\n   *   attemptCount: 5,\n   *   metadata: { processingTimeMs: 30000 },\n   * });\n   * ```\n   */\n  recordDLQ(reason: string, dlqName?: string, options?: DLQOptions): void;\n  recordDLQ(reason: string, options?: DLQOptions): void;\n\n  /**\n   * Record replay of a message from DLQ\n   *\n   * Use this when processing a message that was replayed from the DLQ\n   * to create links for correlation and track replay metrics.\n   *\n   * @param options - Replay tracking options\n   *\n   * @example\n   * ```typescript\n   * export const processReplay = traceConsumer({\n   *   system: 'kafka',\n   *   destination: 'orders-dlq-replay',\n   * })(ctx => async (message) => {\n   *   ctx.recordReplay({\n   *     originalDLQSpanContext: extractSpanContext(message.headers),\n   *     dlqDwellTimeMs: Date.now() - message.timestamp,\n   *     replayAttempt: message.replayCount,\n   *   });\n   *   await processOrder(message);\n   * });\n   * ```\n   */\n  recordReplay(options?: DLQReplayOptions): void;\n\n  /**\n   * Record retry attempt\n   *\n   * @param attemptNumber - Current retry attempt (1-based)\n   * @param maxAttempts - Maximum retry attempts\n   */\n  recordRetry(attemptNumber: number, maxAttempts?: number): void;\n\n  /**\n   * Get the producer span context links extracted from message headers\n   *\n   * Useful for accessing the producer span context when implementing\n   * custom DLQ or retry logic.\n   *\n   * @returns Array of span links extracted from the message, or empty array\n   */\n  getProducerLinks(): Link[];\n\n  // ---- Message Ordering Methods ----\n\n  /**\n   * Check if the current message is a duplicate\n   *\n   * @returns True if the message has been seen before\n   */\n  isDuplicate(): boolean;\n\n  /**\n   * Check if the current message arrived out of order\n   *\n   * @returns Out of order info, or null if in order\n   */\n  getOutOfOrderInfo(): OutOfOrderInfo | null;\n\n  /**\n   * Get current sequence number\n   *\n   * @returns The sequence number, or null if not configured\n   */\n  getSequenceNumber(): number | null;\n\n  /**\n   * Get partition key\n   *\n   * @returns The partition key, or null if not configured\n   */\n  getPartitionKey(): string | null;\n\n  // ---- Consumer Group Methods ----\n\n  /**\n   * Record a rebalance event\n   *\n   * Call this when the consumer group undergoes a rebalance to capture\n   * the event as a span event with partition assignment details.\n   *\n   * @param event - The rebalance event details\n   *\n   * @example\n   * ```typescript\n   * consumer.on('rebalance', (event) => {\n   *   ctx.recordRebalance({\n   *     type: event.type,\n   *     partitions: event.assignment,\n   *     generation: event.generationId,\n   *     timestamp: Date.now(),\n   *   });\n   * });\n   * ```\n   */\n  recordRebalance(event: RebalanceEvent): void;\n\n  /**\n   * Record a heartbeat event\n   *\n   * Call this on each heartbeat to track consumer health.\n   *\n   * @param healthy - Whether the heartbeat was successful\n   * @param latencyMs - Optional latency of the heartbeat in milliseconds\n   */\n  recordHeartbeat(healthy: boolean, latencyMs?: number): void;\n\n  /**\n   * Record partition lag for a specific partition\n   *\n   * @param lag - The partition lag information\n   */\n  recordPartitionLag(lag: PartitionLag): void;\n\n  /**\n   * Get the current consumer group state\n   *\n   * @returns The current consumer group state, or null if not configured\n   */\n  getConsumerGroupState(): ConsumerGroupState | null;\n\n  /**\n   * Get the consumer member ID\n   *\n   * @returns The member ID, or null if not available\n   */\n  getMemberId(): string | null;\n\n  /**\n   * Get the current partition assignments\n   *\n   * @returns Array of assigned partitions, or empty array if none\n   */\n  getAssignedPartitions(): PartitionAssignment[];\n}\n\n// ============================================================================\n// Producer Helper\n// ============================================================================\n\n/**\n * Create a traced message producer function\n *\n * Sets SpanKind.PRODUCER, OTel messaging semantic attributes,\n * and provides context injection helpers.\n *\n * @param config - Producer configuration\n * @returns Factory function that wraps your producer logic\n *\n * @example Kafka producer\n * ```typescript\n * export const publishUserEvent = traceProducer({\n *   system: 'kafka',\n *   destination: 'user-events',\n *   messageIdFrom: (args) => args[0]?.eventId,\n * })(ctx => async (event: UserEvent) => {\n *   const headers = ctx.getTraceHeaders();\n *   await producer.send({\n *     topic: 'user-events',\n *     messages: [{\n *       key: event.userId,\n *       value: JSON.stringify(event),\n *       headers,\n *     }]\n *   });\n * });\n * ```\n *\n * @example SQS producer\n * ```typescript\n * export const sendToSQS = traceProducer({\n *   system: 'sqs',\n *   destination: 'orders-queue',\n * })(ctx => async (order: Order) => {\n *   const headers = ctx.getAllPropagationHeaders();\n *   await sqs.sendMessage({\n *     QueueUrl: QUEUE_URL,\n *     MessageBody: JSON.stringify(order),\n *     MessageAttributes: headersToSQSAttributes(headers),\n *   });\n * });\n * ```\n */\nexport function traceProducer<TArgs extends unknown[], TReturn>(\n  config: ProducerConfig,\n) {\n  const spanName = `${config.system}.publish ${config.destination}`;\n\n  return (\n    fnFactory: (ctx: ProducerContext) => (...args: TArgs) => Promise<TReturn>,\n  ): ((...args: TArgs) => Promise<TReturn>) => {\n    return trace<TArgs, TReturn>(\n      { name: spanName, spanKind: SpanKind.PRODUCER },\n      (baseCtx) => {\n        // Extend context with producer-specific methods\n        const ctx = extendContextForProducer(baseCtx, config);\n\n        // Set semantic convention attributes\n        setProducerAttributes(ctx, config);\n\n        // Call beforeSend callback if provided\n        return (...args: TArgs) => {\n          // Extract dynamic attributes from args\n          setDynamicProducerAttributes(ctx, config, args);\n\n          // Apply custom attributes hook if provided\n          if (config.customAttributes) {\n            const customAttrs = config.customAttributes(ctx, args);\n            for (const [key, value] of Object.entries(customAttrs)) {\n              if (value !== undefined && value !== null) {\n                ctx.setAttribute(key, value as string | number | boolean);\n              }\n            }\n          }\n\n          if (config.beforeSend) {\n            config.beforeSend(ctx, args);\n          }\n\n          // Execute user's function\n          const userFn = fnFactory(ctx);\n          return userFn(...args).catch((error) => {\n            if (config.onError) {\n              config.onError(error as Error, ctx);\n            }\n            throw error;\n          });\n        };\n      },\n    );\n  };\n}\n\n// ============================================================================\n// Consumer Helper\n// ============================================================================\n\n/**\n * Create a traced message consumer function\n *\n * Sets SpanKind.CONSUMER, OTel messaging semantic attributes,\n * automatically extracts links from producer trace headers,\n * and provides DLQ/retry recording helpers.\n *\n * @param config - Consumer configuration\n * @returns Factory function that wraps your consumer logic\n *\n * @example Kafka consumer (single message)\n * ```typescript\n * export const processUserEvent = traceConsumer({\n *   system: 'kafka',\n *   destination: 'user-events',\n *   consumerGroup: 'event-processor',\n *   headersFrom: (msg) => msg.headers,\n * })(ctx => async (message: KafkaMessage) => {\n *   // Link to producer span is automatically created\n *   const event = JSON.parse(message.value.toString());\n *   await processEvent(event);\n * });\n * ```\n *\n * @example Kafka consumer (batch mode)\n * ```typescript\n * export const processUserEventBatch = traceConsumer({\n *   system: 'kafka',\n *   destination: 'user-events',\n *   consumerGroup: 'event-processor',\n *   batchMode: true,\n *   headersFrom: (msg) => msg.headers,\n *   lagMetrics: {\n *     getCurrentOffset: (msg) => msg.offset,\n *     getEndOffset: () => consumer.getHighWatermark(),\n *     getPartition: (msg) => msg.partition,\n *   },\n * })(ctx => async (messages: KafkaMessage[]) => {\n *   // Links to all producer spans are automatically created\n *   for (const msg of messages) {\n *     await processEvent(JSON.parse(msg.value.toString()));\n *   }\n * });\n * ```\n *\n * @example SQS consumer with DLQ handling\n * ```typescript\n * export const processSQSMessage = traceConsumer({\n *   system: 'sqs',\n *   destination: 'orders-queue',\n *   headersFrom: (msg) => sqsAttributesToHeaders(msg.MessageAttributes),\n *   onDLQ: (ctx, reason) => {\n *     ctx.recordDLQ(reason, 'orders-dlq');\n *   },\n * })(ctx => async (message: SQSMessage) => {\n *   try {\n *     await processOrder(JSON.parse(message.Body));\n *   } catch (error) {\n *     if (message.ApproximateReceiveCount > 3) {\n *       ctx.recordDLQ(error.message);\n *       throw error;\n *     }\n *     ctx.recordRetry(message.ApproximateReceiveCount, 3);\n *     throw error;\n *   }\n * });\n * ```\n */\nexport function traceConsumer<TArgs extends unknown[], TReturn>(\n  config: ConsumerConfig,\n) {\n  const operation = config.batchMode ? 'receive' : 'process';\n  const spanName = `${config.system}.${operation} ${config.destination}`;\n\n  return (\n    fnFactory: (ctx: ConsumerContext) => (...args: TArgs) => Promise<TReturn>,\n  ): ((...args: TArgs) => Promise<TReturn>) => {\n    return trace<TArgs, TReturn>(\n      { name: spanName, spanKind: SpanKind.CONSUMER },\n      (baseCtx) => {\n        // Create mutable storage for producer links (populated during extractAndAddLinks)\n        const linkStorage: ProducerLinkStorage = { links: [] };\n\n        // Create mutable ordering state (populated during extractOrdering)\n        const orderingState: OrderingState = {\n          sequenceNumber: null,\n          partitionKey: null,\n          messageId: null,\n          isDuplicate: false,\n          outOfOrderInfo: null,\n        };\n\n        // Create consumer group state\n        const groupTracking = config.consumerGroupTracking;\n        const groupState: ConsumerGroupStateInternal = {\n          memberId:\n            typeof groupTracking?.memberId === 'function'\n              ? (groupTracking.memberId() ?? null)\n              : (groupTracking?.memberId ?? null),\n          groupInstanceId:\n            typeof groupTracking?.groupInstanceId === 'function'\n              ? (groupTracking.groupInstanceId() ?? null)\n              : (groupTracking?.groupInstanceId ?? null),\n          assignedPartitions: [],\n          generation: null,\n          isActive: true,\n          lastHeartbeat: null,\n          state: null,\n        };\n\n        // Extend context with consumer-specific methods\n        const ctx = extendContextForConsumer(\n          baseCtx,\n          config,\n          linkStorage,\n          orderingState,\n          groupState,\n        );\n\n        // Set semantic convention attributes\n        setConsumerAttributes(ctx, config);\n\n        return async (...args: TArgs) => {\n          // Extract links from message headers (includes customContextExtractor if provided)\n          // This also populates linkStorage.links for getProducerLinks() and DLQ auto-linking\n          await extractAndAddLinks(ctx, config, args, linkStorage);\n\n          // Extract and process ordering information\n          if (config.ordering) {\n            extractAndProcessOrdering(ctx, config, args, orderingState);\n          }\n\n          // Extract lag metrics if configured\n          if (config.lagMetrics) {\n            await extractLagMetrics(ctx, config.lagMetrics, args);\n          }\n\n          // Apply custom attributes hook if provided\n          if (config.customAttributes) {\n            // For batch mode, extract first message; for single mode, use args[0] directly\n            const batch = args[0];\n            const msg =\n              config.batchMode && Array.isArray(batch) && batch.length > 0\n                ? batch[0]\n                : batch;\n            // Only call hook if we have a message\n            if (msg !== undefined) {\n              const customAttrs = config.customAttributes(ctx, msg);\n              for (const [key, value] of Object.entries(customAttrs)) {\n                if (value !== undefined && value !== null) {\n                  ctx.setAttribute(key, value as string | number | boolean);\n                }\n              }\n            }\n          }\n\n          // Execute user's function\n          const userFn = fnFactory(ctx);\n          return userFn(...args).catch((error) => {\n            if (config.onError) {\n              config.onError(error as Error, ctx);\n            }\n            throw error;\n          });\n        };\n      },\n    );\n  };\n}\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Extend base context with producer-specific methods\n */\nfunction extendContextForProducer(\n  baseCtx: TraceContext,\n  config: ProducerConfig,\n): ProducerContext {\n  // Create a reference for `this` binding in getFullHeaders\n  const producerCtx: ProducerContext = {\n    ...baseCtx,\n\n    getTraceHeaders(): { traceparent: string; tracestate?: string } {\n      const headers: Record<string, string> = {};\n      propagation.inject(context.active(), headers);\n\n      const result: { traceparent: string; tracestate?: string } = {\n        traceparent: headers['traceparent'] || '',\n      };\n\n      if (headers['tracestate']) {\n        result.tracestate = headers['tracestate'];\n      }\n\n      return result;\n    },\n\n    getAllPropagationHeaders(): Record<string, string> {\n      const headers: Record<string, string> = {};\n      propagation.inject(context.active(), headers);\n\n      // Include baggage if configured\n      if (config.propagateBaggage) {\n        const baggage = propagation.getBaggage(context.active());\n        if (baggage) {\n          const entries: string[] = [];\n          for (const [key, value] of baggage.getAllEntries()) {\n            entries.push(\n              `${encodeURIComponent(key)}=${encodeURIComponent(value.value)}`,\n            );\n          }\n          if (entries.length > 0) {\n            headers['baggage'] = entries.join(',');\n          }\n        }\n      }\n\n      return headers;\n    },\n\n    getFullHeaders(): Record<string, string> {\n      // Start with all propagation headers (W3C + baggage)\n      const headers = producerCtx.getAllPropagationHeaders();\n\n      // Add custom headers from hook if configured\n      if (config.customHeaders) {\n        const customHeaders = config.customHeaders(producerCtx);\n        Object.assign(headers, customHeaders);\n      }\n\n      return headers;\n    },\n  };\n\n  return producerCtx;\n}\n\n/**\n * Mutable storage for producer links (populated during extractAndAddLinks)\n */\ninterface ProducerLinkStorage {\n  links: Link[];\n}\n\n/**\n * Ordering state for a single message\n */\ninterface OrderingState {\n  sequenceNumber: number | null;\n  partitionKey: string | null;\n  messageId: string | null;\n  isDuplicate: boolean;\n  outOfOrderInfo: OutOfOrderInfo | null;\n}\n\n/**\n * Global sequence tracker for out-of-order detection (per partition)\n */\nconst sequenceTrackers = new Map<string, number>();\n\n/**\n * Global deduplication window (LRU-style using Map insertion order)\n */\nconst deduplicationWindow = new Map<string, number>();\nconst DEFAULT_DEDUP_WINDOW_SIZE = 1000;\n\n/**\n * Clean up old entries from deduplication window\n */\nfunction trimDeduplicationWindow(maxSize: number): void {\n  if (deduplicationWindow.size > maxSize) {\n    const excess = deduplicationWindow.size - maxSize;\n    const iterator = deduplicationWindow.keys();\n    for (let i = 0; i < excess; i++) {\n      const key = iterator.next().value;\n      if (key) deduplicationWindow.delete(key);\n    }\n  }\n}\n\n/**\n * Consumer group state tracking for a single consumer\n */\ninterface ConsumerGroupStateInternal {\n  memberId: string | null;\n  groupInstanceId: string | null;\n  assignedPartitions: PartitionAssignment[];\n  generation: number | null;\n  isActive: boolean;\n  lastHeartbeat: number | null;\n  state: ConsumerGroupState['state'] | null;\n}\n\n/**\n * Extend base context with consumer-specific methods\n */\nfunction extendContextForConsumer(\n  baseCtx: TraceContext,\n  config: ConsumerConfig,\n  linkStorage: ProducerLinkStorage,\n  orderingState: OrderingState,\n  groupState: ConsumerGroupStateInternal,\n): ConsumerContext {\n  const consumerCtx: ConsumerContext = {\n    ...baseCtx,\n\n    recordDLQ(\n      reason: string,\n      dlqNameOrOptions?: string | DLQOptions,\n      optionsParam?: DLQOptions,\n    ): void {\n      // Parse overloaded arguments\n      let dlqName: string | undefined;\n      let options: DLQOptions | undefined;\n\n      if (typeof dlqNameOrOptions === 'string') {\n        dlqName = dlqNameOrOptions;\n        options = optionsParam;\n      } else if (typeof dlqNameOrOptions === 'object') {\n        options = dlqNameOrOptions;\n      }\n\n      // Default linkToProducer to true\n      const linkToProducer = options?.linkToProducer ?? true;\n\n      // Set basic DLQ attributes\n      baseCtx.setAttribute('messaging.dlq.reason', reason);\n      if (dlqName) {\n        baseCtx.setAttribute('messaging.dlq.name', dlqName);\n      }\n\n      // Set enhanced DLQ attributes\n      if (options?.reasonCategory) {\n        baseCtx.setAttribute(\n          'messaging.dlq.reason_category',\n          options.reasonCategory,\n        );\n      }\n      if (options?.attemptCount !== undefined) {\n        baseCtx.setAttribute(\n          'messaging.dlq.attempt_count',\n          options.attemptCount,\n        );\n      }\n      if (options?.originalError) {\n        baseCtx.setAttribute(\n          'messaging.dlq.error.type',\n          options.originalError.name,\n        );\n        baseCtx.setAttribute(\n          'messaging.dlq.error.message',\n          options.originalError.message,\n        );\n      }\n\n      // Set custom metadata\n      if (options?.metadata) {\n        for (const [key, value] of Object.entries(options.metadata)) {\n          baseCtx.setAttribute(`messaging.dlq.metadata.${key}`, value);\n        }\n      }\n\n      // Auto-link to producer span if available and enabled\n      const producerLink = linkStorage.links[0];\n      if (linkToProducer && producerLink) {\n        baseCtx.setAttribute(\n          'messaging.dlq.producer_trace_id',\n          producerLink.context.traceId,\n        );\n        baseCtx.setAttribute(\n          'messaging.dlq.producer_span_id',\n          producerLink.context.spanId,\n        );\n      }\n\n      // Record event with all attributes\n      const eventAttrs: Record<string, string | number | boolean> = {\n        'messaging.dlq.reason': reason,\n        ...(dlqName && { 'messaging.dlq.name': dlqName }),\n        ...(options?.reasonCategory && {\n          'messaging.dlq.reason_category': options.reasonCategory,\n        }),\n        ...(options?.attemptCount !== undefined && {\n          'messaging.dlq.attempt_count': options.attemptCount,\n        }),\n        ...(options?.originalError && {\n          'messaging.dlq.error.type': options.originalError.name,\n          'messaging.dlq.error.message': options.originalError.message,\n        }),\n      };\n\n      // Add producer link info to event if available\n      if (linkToProducer && producerLink) {\n        eventAttrs['messaging.dlq.producer_trace_id'] =\n          producerLink.context.traceId;\n        eventAttrs['messaging.dlq.producer_span_id'] =\n          producerLink.context.spanId;\n      }\n\n      emitCorrelatedEvent(baseCtx, 'dlq_routed', eventAttrs);\n\n      // Call user's onDLQ callback if provided\n      if (config.onDLQ) {\n        config.onDLQ(consumerCtx, reason);\n      }\n    },\n\n    recordReplay(options?: DLQReplayOptions): void {\n      baseCtx.setAttribute('messaging.replay', true);\n\n      if (options?.replayAttempt !== undefined) {\n        baseCtx.setAttribute('messaging.replay.attempt', options.replayAttempt);\n      }\n      if (options?.dlqDwellTimeMs !== undefined) {\n        baseCtx.setAttribute(\n          'messaging.replay.dwell_time_ms',\n          options.dlqDwellTimeMs,\n        );\n      }\n\n      // Create span link to original DLQ span if provided\n      if (options?.originalDLQSpanContext) {\n        baseCtx.addLinks([\n          {\n            context: options.originalDLQSpanContext,\n            attributes: { 'messaging.link.source': 'dlq_replay' },\n          },\n        ]);\n      }\n\n      const eventAttrs: Record<string, string | number | boolean> = {\n        'messaging.replay': true,\n        ...(options?.replayAttempt !== undefined && {\n          'messaging.replay.attempt': options.replayAttempt,\n        }),\n        ...(options?.dlqDwellTimeMs !== undefined && {\n          'messaging.replay.dwell_time_ms': options.dlqDwellTimeMs,\n        }),\n      };\n\n      emitCorrelatedEvent(baseCtx, 'dlq_replay', eventAttrs);\n    },\n\n    recordRetry(attemptNumber: number, maxAttempts?: number): void {\n      baseCtx.setAttribute('messaging.retry.count', attemptNumber);\n      if (maxAttempts !== undefined) {\n        baseCtx.setAttribute('messaging.retry.max_attempts', maxAttempts);\n      }\n      emitCorrelatedEvent(baseCtx, 'retry_attempt', {\n        'messaging.retry.count': attemptNumber,\n        ...(maxAttempts !== undefined && {\n          'messaging.retry.max_attempts': maxAttempts,\n        }),\n      });\n    },\n\n    getProducerLinks(): Link[] {\n      return [...linkStorage.links];\n    },\n\n    // ---- Ordering Methods ----\n\n    isDuplicate(): boolean {\n      return orderingState.isDuplicate;\n    },\n\n    getOutOfOrderInfo(): OutOfOrderInfo | null {\n      return orderingState.outOfOrderInfo;\n    },\n\n    getSequenceNumber(): number | null {\n      return orderingState.sequenceNumber;\n    },\n\n    getPartitionKey(): string | null {\n      return orderingState.partitionKey;\n    },\n\n    // ---- Consumer Group Methods ----\n\n    recordRebalance(event: RebalanceEvent): void {\n      // Update internal state including consumer group state\n      if (event.type === 'assigned') {\n        groupState.assignedPartitions = event.partitions;\n        groupState.isActive = true;\n        // After assignment completes, group is stable\n        groupState.state = 'stable';\n      } else if (event.type === 'revoked' || event.type === 'lost') {\n        // Remove revoked partitions from assignments\n        const revokedSet = new Set(\n          event.partitions.map((p) => `${p.topic}:${p.partition}`),\n        );\n        groupState.assignedPartitions = groupState.assignedPartitions.filter(\n          (p) => !revokedSet.has(`${p.topic}:${p.partition}`),\n        );\n        if (event.type === 'lost') {\n          groupState.isActive = false;\n          // Consumer lost connection, mark as dead\n          groupState.state = 'dead';\n        } else {\n          // Revoked means rebalance is starting\n          // If no partitions remain, consumer is empty; otherwise preparing for rebalance\n          groupState.state =\n            groupState.assignedPartitions.length === 0\n              ? 'empty'\n              : 'preparing_rebalance';\n        }\n      }\n\n      if (event.generation !== undefined) {\n        groupState.generation = event.generation;\n      }\n      if (event.memberId) {\n        groupState.memberId = event.memberId;\n      }\n\n      // Set span attributes\n      baseCtx.setAttribute(\n        'messaging.consumer_group.rebalance.type',\n        event.type,\n      );\n      baseCtx.setAttribute(\n        'messaging.consumer_group.rebalance.partition_count',\n        event.partitions.length,\n      );\n      if (event.generation !== undefined) {\n        baseCtx.setAttribute(\n          'messaging.consumer_group.generation',\n          event.generation,\n        );\n      }\n      if (event.memberId) {\n        baseCtx.setAttribute(\n          'messaging.consumer_group.member_id',\n          event.memberId,\n        );\n      }\n      if (event.reason) {\n        baseCtx.setAttribute(\n          'messaging.consumer_group.rebalance.reason',\n          event.reason,\n        );\n      }\n\n      // Set the new state on the span\n      if (groupState.state) {\n        baseCtx.setAttribute(\n          'messaging.consumer_group.state',\n          groupState.state,\n        );\n      }\n\n      // Record event\n      const eventAttrs: Record<string, string | number | boolean> = {\n        'messaging.consumer_group.rebalance.type': event.type,\n        'messaging.consumer_group.rebalance.partition_count':\n          event.partitions.length,\n        'messaging.consumer_group.rebalance.timestamp': event.timestamp,\n        ...(event.generation !== undefined && {\n          'messaging.consumer_group.generation': event.generation,\n        }),\n        ...(event.memberId && {\n          'messaging.consumer_group.member_id': event.memberId,\n        }),\n        ...(event.reason && {\n          'messaging.consumer_group.rebalance.reason': event.reason,\n        }),\n        ...(groupState.state && {\n          'messaging.consumer_group.state': groupState.state,\n        }),\n      };\n\n      // Add partition details if not too many\n      if (event.partitions.length <= 10) {\n        eventAttrs['messaging.consumer_group.rebalance.partitions'] =\n          event.partitions.map((p) => `${p.topic}:${p.partition}`).join(',');\n      }\n\n      emitCorrelatedEvent(baseCtx, `consumer_group_${event.type}`, eventAttrs);\n\n      // Call user's onRebalance callback if provided\n      if (config.consumerGroupTracking?.onRebalance) {\n        config.consumerGroupTracking.onRebalance(consumerCtx, event);\n      }\n\n      // Call specific callbacks\n      if (\n        event.type === 'assigned' &&\n        config.consumerGroupTracking?.onPartitionsAssigned\n      ) {\n        config.consumerGroupTracking.onPartitionsAssigned(\n          consumerCtx,\n          event.partitions,\n        );\n      }\n      if (\n        event.type === 'revoked' &&\n        config.consumerGroupTracking?.onPartitionsRevoked\n      ) {\n        config.consumerGroupTracking.onPartitionsRevoked(\n          consumerCtx,\n          event.partitions,\n        );\n      }\n    },\n\n    recordHeartbeat(healthy: boolean, latencyMs?: number): void {\n      groupState.lastHeartbeat = Date.now();\n\n      baseCtx.setAttribute(\n        'messaging.consumer_group.heartbeat.healthy',\n        healthy,\n      );\n      if (latencyMs !== undefined) {\n        baseCtx.setAttribute(\n          'messaging.consumer_group.heartbeat.latency_ms',\n          latencyMs,\n        );\n      }\n\n      emitCorrelatedEvent(baseCtx, 'consumer_group_heartbeat', {\n        'messaging.consumer_group.heartbeat.healthy': healthy,\n        'messaging.consumer_group.heartbeat.timestamp':\n          groupState.lastHeartbeat,\n        ...(latencyMs !== undefined && {\n          'messaging.consumer_group.heartbeat.latency_ms': latencyMs,\n        }),\n      });\n    },\n\n    recordPartitionLag(lag: PartitionLag): void {\n      const prefix = `messaging.consumer_group.lag.${lag.topic}.${lag.partition}`;\n\n      baseCtx.setAttribute(`${prefix}.current_offset`, lag.currentOffset);\n      baseCtx.setAttribute(`${prefix}.end_offset`, lag.endOffset);\n      baseCtx.setAttribute(`${prefix}.lag`, lag.lag);\n\n      emitCorrelatedEvent(baseCtx, 'partition_lag_recorded', {\n        'messaging.consumer_group.lag.topic': lag.topic,\n        'messaging.consumer_group.lag.partition': lag.partition,\n        'messaging.consumer_group.lag.current_offset': lag.currentOffset,\n        'messaging.consumer_group.lag.end_offset': lag.endOffset,\n        'messaging.consumer_group.lag.lag': lag.lag,\n        'messaging.consumer_group.lag.timestamp': lag.timestamp,\n      });\n    },\n\n    getConsumerGroupState(): ConsumerGroupState | null {\n      if (!config.consumerGroup) {\n        return null;\n      }\n\n      return {\n        groupId: config.consumerGroup,\n        memberId: groupState.memberId ?? undefined,\n        groupInstanceId: groupState.groupInstanceId ?? undefined,\n        assignedPartitions: [...groupState.assignedPartitions],\n        generation: groupState.generation ?? undefined,\n        isActive: groupState.isActive,\n        lastHeartbeat: groupState.lastHeartbeat ?? undefined,\n        state: groupState.state ?? undefined,\n      };\n    },\n\n    getMemberId(): string | null {\n      return groupState.memberId;\n    },\n\n    getAssignedPartitions(): PartitionAssignment[] {\n      return [...groupState.assignedPartitions];\n    },\n  };\n\n  return consumerCtx;\n}\n\n/**\n * Set OTel semantic convention attributes for producer\n */\nfunction setProducerAttributes(\n  ctx: TraceContext,\n  config: ProducerConfig,\n): void {\n  ctx.setAttribute('messaging.system', config.system);\n  ctx.setAttribute('messaging.operation', 'publish');\n  ctx.setAttribute('messaging.destination.name', config.destination);\n\n  // Set system-specific destination attribute\n  if (config.system === 'kafka') {\n    ctx.setAttribute('messaging.kafka.destination.topic', config.destination);\n  }\n\n  // Set custom attributes\n  if (config.attributes) {\n    setCustomAttributes(ctx, config.attributes);\n  }\n}\n\n/**\n * Set dynamic producer attributes from arguments\n */\nfunction setDynamicProducerAttributes(\n  ctx: TraceContext,\n  config: ProducerConfig,\n  args: unknown[],\n): void {\n  // Message ID\n  if (config.messageIdFrom) {\n    const messageId = extractValue(config.messageIdFrom, args);\n    if (messageId !== undefined) {\n      ctx.setAttribute('messaging.message.id', String(messageId));\n    }\n  }\n\n  // Partition (Kafka-specific)\n  if (config.partitionFrom) {\n    const partition = extractValue(config.partitionFrom, args);\n    if (partition !== undefined) {\n      ctx.setAttribute(\n        'messaging.kafka.destination.partition',\n        Number(partition),\n      );\n    }\n  }\n\n  // Key (Kafka-specific)\n  if (config.keyFrom) {\n    const key = extractValue(config.keyFrom, args);\n    if (key !== undefined) {\n      ctx.setAttribute('messaging.kafka.message.key', String(key));\n    }\n  }\n}\n\n/**\n * Set OTel semantic convention attributes for consumer\n */\nfunction setConsumerAttributes(\n  ctx: TraceContext,\n  config: ConsumerConfig,\n): void {\n  ctx.setAttribute('messaging.system', config.system);\n  ctx.setAttribute(\n    'messaging.operation',\n    config.batchMode ? 'receive' : 'process',\n  );\n  ctx.setAttribute('messaging.destination.name', config.destination);\n\n  // Consumer group\n  if (config.consumerGroup) {\n    ctx.setAttribute('messaging.consumer.group', config.consumerGroup);\n\n    // System-specific consumer group attribute\n    if (config.system === 'kafka') {\n      ctx.setAttribute('messaging.kafka.consumer.group', config.consumerGroup);\n    }\n  }\n\n  // Set system-specific destination attribute\n  if (config.system === 'kafka') {\n    ctx.setAttribute('messaging.kafka.destination.topic', config.destination);\n  }\n\n  // Set custom attributes\n  if (config.attributes) {\n    setCustomAttributes(ctx, config.attributes);\n  }\n}\n\n/**\n * Extract links from message headers and add to span\n *\n * Uses W3C trace context by default, falls back to customContextExtractor if provided.\n * Also populates linkStorage for getProducerLinks() and DLQ auto-linking.\n */\nasync function extractAndAddLinks(\n  ctx: ConsumerContext,\n  config: ConsumerConfig,\n  args: unknown[],\n  linkStorage: ProducerLinkStorage,\n): Promise<void> {\n  if (!config.headersFrom && !config.customContextExtractor) {\n    return;\n  }\n\n  const links: Link[] = [];\n\n  if (config.batchMode && Array.isArray(args[0])) {\n    // Batch mode - extract links from all messages\n    const messages = args[0] as unknown[];\n\n    if (config.headersFrom) {\n      const batchLinks = extractLinksFromBatch(\n        messages.map((msg) => {\n          const headers = extractHeaders(config.headersFrom!, msg);\n          return { headers };\n        }),\n        'headers',\n      );\n      links.push(...batchLinks);\n    }\n\n    // Try custom context extractor for messages without W3C links\n    if (config.customContextExtractor && config.headersFrom) {\n      for (const msg of messages) {\n        const headers = extractHeaders(config.headersFrom, msg);\n        if (headers) {\n          // Only use custom extractor if W3C headers weren't present\n          const w3cLink = createLinkFromHeaders(headers);\n          if (!w3cLink) {\n            const customContext = config.customContextExtractor(headers);\n            if (customContext) {\n              links.push({\n                context: customContext,\n                attributes: { 'messaging.link.source': 'custom_extractor' },\n              });\n            }\n          }\n        }\n      }\n    }\n\n    // Set batch count\n    ctx.setAttribute('messaging.batch.message_count', messages.length);\n  } else {\n    // Single message mode\n    const msg = args[0];\n    const headers = config.headersFrom\n      ? extractHeaders(config.headersFrom, msg)\n      : undefined;\n\n    if (headers) {\n      // Try W3C format first\n      const w3cLink = createLinkFromHeaders(headers);\n      if (w3cLink) {\n        links.push(w3cLink);\n      } else if (config.customContextExtractor) {\n        // Fall back to custom extractor\n        const customContext = config.customContextExtractor(headers);\n        if (customContext) {\n          links.push({\n            context: customContext,\n            attributes: { 'messaging.link.source': 'custom_extractor' },\n          });\n        }\n      }\n    }\n  }\n\n  // Add all extracted links and store for getProducerLinks() / DLQ auto-linking\n  if (links.length > 0) {\n    ctx.addLinks(links);\n    linkStorage.links.push(...links);\n  }\n}\n\n/**\n * Extract lag metrics and set as span attributes\n */\nasync function extractLagMetrics(\n  ctx: ConsumerContext,\n  lagConfig: LagMetricsConfig,\n  args: unknown[],\n): Promise<void> {\n  const msg = Array.isArray(args[0]) ? args[0][0] : args[0];\n\n  // Current offset\n  let currentOffset: number | undefined;\n  if (lagConfig.getCurrentOffset && msg) {\n    currentOffset = lagConfig.getCurrentOffset(msg);\n    if (currentOffset !== undefined) {\n      ctx.setAttribute('messaging.kafka.message.offset', currentOffset);\n    }\n  }\n\n  // Partition\n  if (lagConfig.getPartition && msg) {\n    const partition = lagConfig.getPartition(msg);\n    if (partition !== undefined) {\n      ctx.setAttribute('messaging.kafka.partition', partition);\n    }\n  }\n\n  // End offset (high watermark) and lag calculation\n  if (lagConfig.getEndOffset) {\n    try {\n      const endOffset = await Promise.resolve(lagConfig.getEndOffset());\n      if (endOffset !== undefined && currentOffset !== undefined) {\n        const lag = endOffset - currentOffset;\n        ctx.setAttribute('messaging.kafka.consumer_lag', lag);\n\n        // Add lag event\n        emitCorrelatedEvent(ctx, 'consumer_lag_measured', {\n          'messaging.kafka.consumer_lag': lag,\n          'messaging.kafka.message.offset': currentOffset,\n          'messaging.kafka.high_watermark': endOffset,\n        });\n      }\n    } catch {\n      // Ignore lag calculation errors\n    }\n  }\n\n  // Committed offset\n  if (lagConfig.getCommittedOffset) {\n    try {\n      const committedOffset = await Promise.resolve(\n        lagConfig.getCommittedOffset(),\n      );\n      if (committedOffset !== undefined) {\n        ctx.setAttribute('messaging.kafka.committed_offset', committedOffset);\n      }\n    } catch {\n      // Ignore committed offset errors\n    }\n  }\n\n  // Batch-specific metrics\n  if (Array.isArray(args[0]) && args[0].length > 0) {\n    const messages = args[0] as unknown[];\n    if (lagConfig.getCurrentOffset) {\n      const firstOffset = lagConfig.getCurrentOffset(messages[0]);\n      const lastMessage = messages.at(-1);\n      const lastOffset =\n        lastMessage === undefined\n          ? undefined\n          : lagConfig.getCurrentOffset(lastMessage);\n\n      if (firstOffset !== undefined) {\n        ctx.setAttribute('messaging.batch.first_offset', firstOffset);\n      }\n      if (lastOffset !== undefined) {\n        ctx.setAttribute('messaging.batch.last_offset', lastOffset);\n      }\n    }\n  }\n}\n\n/**\n * Extract headers from message using config\n */\nfunction extractHeaders(\n  headersFrom: string | ((msg: unknown) => Record<string, string> | undefined),\n  msg: unknown,\n): Record<string, string> | undefined {\n  if (typeof headersFrom === 'function') {\n    return headersFrom(msg);\n  }\n\n  // String path - extract from message property\n  if (typeof msg === 'object' && msg !== null) {\n    const value = (msg as Record<string, unknown>)[headersFrom];\n    if (typeof value === 'object' && value !== null) {\n      return value as Record<string, string>;\n    }\n  }\n\n  return undefined;\n}\n\n/**\n * Extract value from arguments using config\n */\nfunction extractValue(\n  extractor: string | ((args: unknown[]) => unknown),\n  args: unknown[],\n): unknown {\n  if (typeof extractor === 'function') {\n    return extractor(args);\n  }\n\n  // String path - extract from first argument\n  const firstArg = args[0];\n  if (typeof firstArg === 'object' && firstArg !== null) {\n    return (firstArg as Record<string, unknown>)[extractor];\n  }\n\n  return undefined;\n}\n\n/**\n * Set custom attributes on context, handling non-primitive values\n */\nfunction setCustomAttributes(ctx: TraceContext, attributes: Attributes): void {\n  for (const [key, value] of Object.entries(attributes)) {\n    if (value !== undefined && value !== null) {\n      // setAttribute accepts primitives and arrays of primitives\n      if (\n        typeof value === 'string' ||\n        typeof value === 'number' ||\n        typeof value === 'boolean'\n      ) {\n        ctx.setAttribute(key, value);\n      } else if (Array.isArray(value)) {\n        // Filter out null/undefined from arrays and ensure proper typing\n        const cleanArray = value.filter(\n          (v): v is string | number | boolean =>\n            v !== null &&\n            v !== undefined &&\n            (typeof v === 'string' ||\n              typeof v === 'number' ||\n              typeof v === 'boolean'),\n        );\n        if (cleanArray.length > 0) {\n          ctx.setAttribute(key, cleanArray as string[] | number[] | boolean[]);\n        }\n      } else {\n        ctx.setAttribute(key, JSON.stringify(value));\n      }\n    }\n  }\n}\n\n/**\n * Extract and process ordering information from message\n *\n * Handles:\n * - Sequence number extraction and tracking\n * - Out-of-order detection\n * - Duplicate detection\n * - Span attribute setting\n * - Callback invocation\n */\nfunction extractAndProcessOrdering(\n  ctx: ConsumerContext,\n  config: ConsumerConfig,\n  args: unknown[],\n  orderingState: OrderingState,\n): void {\n  const ordering = config.ordering;\n  if (!ordering) return;\n\n  // Get messages to process - all messages in batch mode, single message otherwise\n  const messages: unknown[] =\n    config.batchMode && Array.isArray(args[0]) ? args[0] : [args[0]];\n\n  if (messages.length === 0) return;\n\n  // Track aggregate stats for batch reporting\n  let outOfOrderCount = 0;\n  let duplicateCount = 0;\n  let lastSequence: number | null = null;\n  let lastPartitionKey: string | null = null;\n  let lastMessageId: string | null = null;\n\n  for (const [i, msg] of messages.entries()) {\n    if (!msg) continue;\n\n    // Per-message state for this iteration\n    let msgSequence: number | null = null;\n    let msgPartitionKey: string | null = null;\n    let msgId: string | null = null;\n\n    // Extract sequence number\n    if (ordering.sequenceFrom) {\n      const seq = ordering.sequenceFrom(msg);\n      if (seq !== undefined) {\n        msgSequence = seq;\n        lastSequence = seq;\n      }\n    }\n\n    // Extract partition key\n    if (ordering.partitionKeyFrom) {\n      const key = ordering.partitionKeyFrom(msg);\n      if (key !== undefined) {\n        msgPartitionKey = key;\n        lastPartitionKey = key;\n      }\n    }\n\n    // Extract message ID for deduplication\n    if (ordering.messageIdFrom) {\n      const id = ordering.messageIdFrom(msg);\n      if (id !== undefined) {\n        msgId = id;\n        lastMessageId = id;\n      }\n    }\n\n    // Out-of-order detection for this message\n    if (ordering.detectOutOfOrder && msgSequence !== null) {\n      // Build tracker key using per-message partition key\n      const msgOrderingState: OrderingState = {\n        sequenceNumber: msgSequence,\n        partitionKey: msgPartitionKey,\n        messageId: msgId,\n        isDuplicate: false,\n        outOfOrderInfo: null,\n      };\n      const trackerKey = buildTrackerKey(config, msgOrderingState);\n      const prevSequence = sequenceTrackers.get(trackerKey);\n\n      if (prevSequence !== undefined) {\n        const expectedSequence = prevSequence + 1;\n\n        if (msgSequence !== expectedSequence) {\n          outOfOrderCount++;\n          const gap = msgSequence - expectedSequence;\n          const outOfOrderInfo: OutOfOrderInfo = {\n            currentSequence: msgSequence,\n            expectedSequence,\n            partitionKey: msgPartitionKey ?? undefined,\n            gap,\n          };\n\n          // Store the first out-of-order info for backward compatibility\n          if (!orderingState.outOfOrderInfo) {\n            orderingState.outOfOrderInfo = outOfOrderInfo;\n          }\n\n          // Add event for each out-of-order message\n          emitCorrelatedEvent(ctx, 'message_out_of_order', {\n            'messaging.ordering.batch_index': i,\n            'messaging.ordering.current_sequence': msgSequence,\n            'messaging.ordering.expected_sequence': expectedSequence,\n            'messaging.ordering.gap': gap,\n            ...(msgPartitionKey && {\n              'messaging.ordering.partition_key': msgPartitionKey,\n            }),\n          });\n\n          // Call user callback if provided\n          if (ordering.onOutOfOrder) {\n            ordering.onOutOfOrder(ctx, outOfOrderInfo);\n          }\n        }\n      }\n\n      // Update tracker with this message's sequence\n      sequenceTrackers.set(trackerKey, msgSequence);\n    }\n\n    // Duplicate detection for this message\n    if (ordering.detectDuplicates && msgId !== null) {\n      const msgOrderingState: OrderingState = {\n        sequenceNumber: msgSequence,\n        partitionKey: msgPartitionKey,\n        messageId: msgId,\n        isDuplicate: false,\n        outOfOrderInfo: null,\n      };\n      const dedupKey = buildDedupKey(config, msgOrderingState);\n\n      if (deduplicationWindow.has(dedupKey)) {\n        duplicateCount++;\n\n        // Add event for each duplicate\n        emitCorrelatedEvent(ctx, 'message_duplicate', {\n          'messaging.ordering.batch_index': i,\n          'messaging.message.id': msgId,\n        });\n\n        // Call user callback if provided\n        if (ordering.onDuplicate) {\n          ordering.onDuplicate(ctx, msgId);\n        }\n      } else {\n        // Add to deduplication window\n        deduplicationWindow.set(dedupKey, Date.now());\n\n        // Trim window if needed\n        const windowSize =\n          ordering.deduplicationWindowSize ?? DEFAULT_DEDUP_WINDOW_SIZE;\n        trimDeduplicationWindow(windowSize);\n      }\n    }\n  }\n\n  // Update orderingState with final values from the batch\n  orderingState.sequenceNumber = lastSequence;\n  orderingState.partitionKey = lastPartitionKey;\n  orderingState.messageId = lastMessageId;\n  orderingState.isDuplicate = duplicateCount > 0;\n\n  // Set aggregate span attributes\n  if (lastSequence !== null) {\n    ctx.setAttribute('messaging.message.sequence_number', lastSequence);\n  }\n  if (lastPartitionKey !== null) {\n    ctx.setAttribute('messaging.message.partition_key', lastPartitionKey);\n  }\n  if (lastMessageId !== null) {\n    ctx.setAttribute('messaging.message.id', lastMessageId);\n  }\n\n  // Report batch-level ordering statistics\n  if (outOfOrderCount > 0) {\n    ctx.setAttribute('messaging.ordering.out_of_order', true);\n    ctx.setAttribute('messaging.ordering.out_of_order_count', outOfOrderCount);\n  }\n  if (duplicateCount > 0) {\n    ctx.setAttribute('messaging.ordering.duplicate', true);\n    ctx.setAttribute('messaging.ordering.duplicate_count', duplicateCount);\n  }\n}\n\n/**\n * Build a unique key for sequence tracking based on system, destination, and partition\n */\nfunction buildTrackerKey(\n  config: ConsumerConfig,\n  orderingState: OrderingState,\n): string {\n  const parts = [config.system, config.destination];\n  if (orderingState.partitionKey) {\n    parts.push(orderingState.partitionKey);\n  }\n  if (config.consumerGroup) {\n    parts.push(config.consumerGroup);\n  }\n  return parts.join(':');\n}\n\n/**\n * Build a unique key for deduplication based on system, destination, and message ID\n */\nfunction buildDedupKey(\n  config: ConsumerConfig,\n  orderingState: OrderingState,\n): string {\n  const parts = [config.system, config.destination];\n  if (orderingState.messageId) {\n    parts.push(orderingState.messageId);\n  }\n  return parts.join(':');\n}\n\n/**\n * Clear sequence tracking state (useful for testing)\n */\nexport function clearOrderingState(): void {\n  sequenceTrackers.clear();\n  deduplicationWindow.clear();\n}\n"]}