autotel
Version:
Write Once, Observe Anywhere
798 lines (795 loc) • 27.4 kB
JavaScript
;
var chunkUTZR7P7E_cjs = require('./chunk-UTZR7P7E.cjs');
var chunkVH77IPJN_cjs = require('./chunk-VH77IPJN.cjs');
var api = require('@opentelemetry/api');
function traceProducer(config) {
const spanName = `${config.system}.publish ${config.destination}`;
return (fnFactory) => {
return chunkUTZR7P7E_cjs.trace(
{ name: spanName, spanKind: api.SpanKind.PRODUCER },
(baseCtx) => {
const ctx = extendContextForProducer(baseCtx, config);
setProducerAttributes(ctx, config);
return (...args) => {
setDynamicProducerAttributes(ctx, config, args);
if (config.customAttributes) {
const customAttrs = config.customAttributes(ctx, args);
for (const [key, value] of Object.entries(customAttrs)) {
if (value !== void 0 && value !== null) {
ctx.setAttribute(key, value);
}
}
}
if (config.beforeSend) {
config.beforeSend(ctx, args);
}
const userFn = fnFactory(ctx);
return userFn(...args).catch((error) => {
if (config.onError) {
config.onError(error, ctx);
}
throw error;
});
};
}
);
};
}
function traceConsumer(config) {
const operation = config.batchMode ? "receive" : "process";
const spanName = `${config.system}.${operation} ${config.destination}`;
return (fnFactory) => {
return chunkUTZR7P7E_cjs.trace(
{ name: spanName, spanKind: api.SpanKind.CONSUMER },
(baseCtx) => {
const linkStorage = { links: [] };
const orderingState = {
sequenceNumber: null,
partitionKey: null,
messageId: null,
isDuplicate: false,
outOfOrderInfo: null
};
const groupTracking = config.consumerGroupTracking;
const groupState = {
memberId: typeof groupTracking?.memberId === "function" ? groupTracking.memberId() ?? null : groupTracking?.memberId ?? null,
groupInstanceId: typeof groupTracking?.groupInstanceId === "function" ? groupTracking.groupInstanceId() ?? null : groupTracking?.groupInstanceId ?? null,
assignedPartitions: [],
generation: null,
isActive: true,
lastHeartbeat: null,
state: null
};
const ctx = extendContextForConsumer(
baseCtx,
config,
linkStorage,
orderingState,
groupState
);
setConsumerAttributes(ctx, config);
return async (...args) => {
await extractAndAddLinks(ctx, config, args, linkStorage);
if (config.ordering) {
extractAndProcessOrdering(ctx, config, args, orderingState);
}
if (config.lagMetrics) {
await extractLagMetrics(ctx, config.lagMetrics, args);
}
if (config.customAttributes) {
const batch = args[0];
const msg = config.batchMode && Array.isArray(batch) && batch.length > 0 ? batch[0] : batch;
if (msg !== void 0) {
const customAttrs = config.customAttributes(ctx, msg);
for (const [key, value] of Object.entries(customAttrs)) {
if (value !== void 0 && value !== null) {
ctx.setAttribute(key, value);
}
}
}
}
const userFn = fnFactory(ctx);
return userFn(...args).catch((error) => {
if (config.onError) {
config.onError(error, ctx);
}
throw error;
});
};
}
);
};
}
function extendContextForProducer(baseCtx, config) {
const producerCtx = {
...baseCtx,
getTraceHeaders() {
const headers = {};
api.propagation.inject(api.context.active(), headers);
const result = {
traceparent: headers["traceparent"] || ""
};
if (headers["tracestate"]) {
result.tracestate = headers["tracestate"];
}
return result;
},
getAllPropagationHeaders() {
const headers = {};
api.propagation.inject(api.context.active(), headers);
if (config.propagateBaggage) {
const baggage = api.propagation.getBaggage(api.context.active());
if (baggage) {
const entries = [];
for (const [key, value] of baggage.getAllEntries()) {
entries.push(
`${encodeURIComponent(key)}=${encodeURIComponent(value.value)}`
);
}
if (entries.length > 0) {
headers["baggage"] = entries.join(",");
}
}
}
return headers;
},
getFullHeaders() {
const headers = producerCtx.getAllPropagationHeaders();
if (config.customHeaders) {
const customHeaders = config.customHeaders(producerCtx);
Object.assign(headers, customHeaders);
}
return headers;
}
};
return producerCtx;
}
var sequenceTrackers = /* @__PURE__ */ new Map();
var deduplicationWindow = /* @__PURE__ */ new Map();
var DEFAULT_DEDUP_WINDOW_SIZE = 1e3;
function trimDeduplicationWindow(maxSize) {
if (deduplicationWindow.size > maxSize) {
const excess = deduplicationWindow.size - maxSize;
const iterator = deduplicationWindow.keys();
for (let i = 0; i < excess; i++) {
const key = iterator.next().value;
if (key) deduplicationWindow.delete(key);
}
}
}
function extendContextForConsumer(baseCtx, config, linkStorage, orderingState, groupState) {
const consumerCtx = {
...baseCtx,
recordDLQ(reason, dlqNameOrOptions, optionsParam) {
let dlqName;
let options;
if (typeof dlqNameOrOptions === "string") {
dlqName = dlqNameOrOptions;
options = optionsParam;
} else if (typeof dlqNameOrOptions === "object") {
options = dlqNameOrOptions;
}
const linkToProducer = options?.linkToProducer ?? true;
baseCtx.setAttribute("messaging.dlq.reason", reason);
if (dlqName) {
baseCtx.setAttribute("messaging.dlq.name", dlqName);
}
if (options?.reasonCategory) {
baseCtx.setAttribute(
"messaging.dlq.reason_category",
options.reasonCategory
);
}
if (options?.attemptCount !== void 0) {
baseCtx.setAttribute(
"messaging.dlq.attempt_count",
options.attemptCount
);
}
if (options?.originalError) {
baseCtx.setAttribute(
"messaging.dlq.error.type",
options.originalError.name
);
baseCtx.setAttribute(
"messaging.dlq.error.message",
options.originalError.message
);
}
if (options?.metadata) {
for (const [key, value] of Object.entries(options.metadata)) {
baseCtx.setAttribute(`messaging.dlq.metadata.${key}`, value);
}
}
const producerLink = linkStorage.links[0];
if (linkToProducer && producerLink) {
baseCtx.setAttribute(
"messaging.dlq.producer_trace_id",
producerLink.context.traceId
);
baseCtx.setAttribute(
"messaging.dlq.producer_span_id",
producerLink.context.spanId
);
}
const eventAttrs = {
"messaging.dlq.reason": reason,
...dlqName && { "messaging.dlq.name": dlqName },
...options?.reasonCategory && {
"messaging.dlq.reason_category": options.reasonCategory
},
...options?.attemptCount !== void 0 && {
"messaging.dlq.attempt_count": options.attemptCount
},
...options?.originalError && {
"messaging.dlq.error.type": options.originalError.name,
"messaging.dlq.error.message": options.originalError.message
}
};
if (linkToProducer && producerLink) {
eventAttrs["messaging.dlq.producer_trace_id"] = producerLink.context.traceId;
eventAttrs["messaging.dlq.producer_span_id"] = producerLink.context.spanId;
}
baseCtx.addEvent("dlq_routed", eventAttrs);
if (config.onDLQ) {
config.onDLQ(consumerCtx, reason);
}
},
recordReplay(options) {
baseCtx.setAttribute("messaging.replay", true);
if (options?.replayAttempt !== void 0) {
baseCtx.setAttribute("messaging.replay.attempt", options.replayAttempt);
}
if (options?.dlqDwellTimeMs !== void 0) {
baseCtx.setAttribute(
"messaging.replay.dwell_time_ms",
options.dlqDwellTimeMs
);
}
if (options?.originalDLQSpanContext) {
baseCtx.addLinks([
{
context: options.originalDLQSpanContext,
attributes: { "messaging.link.source": "dlq_replay" }
}
]);
}
const eventAttrs = {
"messaging.replay": true,
...options?.replayAttempt !== void 0 && {
"messaging.replay.attempt": options.replayAttempt
},
...options?.dlqDwellTimeMs !== void 0 && {
"messaging.replay.dwell_time_ms": options.dlqDwellTimeMs
}
};
baseCtx.addEvent("dlq_replay", eventAttrs);
},
recordRetry(attemptNumber, maxAttempts) {
baseCtx.setAttribute("messaging.retry.count", attemptNumber);
if (maxAttempts !== void 0) {
baseCtx.setAttribute("messaging.retry.max_attempts", maxAttempts);
}
baseCtx.addEvent("retry_attempt", {
"messaging.retry.count": attemptNumber,
...maxAttempts !== void 0 && {
"messaging.retry.max_attempts": maxAttempts
}
});
},
getProducerLinks() {
return [...linkStorage.links];
},
// ---- Ordering Methods ----
isDuplicate() {
return orderingState.isDuplicate;
},
getOutOfOrderInfo() {
return orderingState.outOfOrderInfo;
},
getSequenceNumber() {
return orderingState.sequenceNumber;
},
getPartitionKey() {
return orderingState.partitionKey;
},
// ---- Consumer Group Methods ----
recordRebalance(event) {
if (event.type === "assigned") {
groupState.assignedPartitions = event.partitions;
groupState.isActive = true;
groupState.state = "stable";
} else if (event.type === "revoked" || event.type === "lost") {
const revokedSet = new Set(
event.partitions.map((p) => `${p.topic}:${p.partition}`)
);
groupState.assignedPartitions = groupState.assignedPartitions.filter(
(p) => !revokedSet.has(`${p.topic}:${p.partition}`)
);
if (event.type === "lost") {
groupState.isActive = false;
groupState.state = "dead";
} else {
groupState.state = groupState.assignedPartitions.length === 0 ? "empty" : "preparing_rebalance";
}
}
if (event.generation !== void 0) {
groupState.generation = event.generation;
}
if (event.memberId) {
groupState.memberId = event.memberId;
}
baseCtx.setAttribute(
"messaging.consumer_group.rebalance.type",
event.type
);
baseCtx.setAttribute(
"messaging.consumer_group.rebalance.partition_count",
event.partitions.length
);
if (event.generation !== void 0) {
baseCtx.setAttribute(
"messaging.consumer_group.generation",
event.generation
);
}
if (event.memberId) {
baseCtx.setAttribute(
"messaging.consumer_group.member_id",
event.memberId
);
}
if (event.reason) {
baseCtx.setAttribute(
"messaging.consumer_group.rebalance.reason",
event.reason
);
}
if (groupState.state) {
baseCtx.setAttribute(
"messaging.consumer_group.state",
groupState.state
);
}
const eventAttrs = {
"messaging.consumer_group.rebalance.type": event.type,
"messaging.consumer_group.rebalance.partition_count": event.partitions.length,
"messaging.consumer_group.rebalance.timestamp": event.timestamp,
...event.generation !== void 0 && {
"messaging.consumer_group.generation": event.generation
},
...event.memberId && {
"messaging.consumer_group.member_id": event.memberId
},
...event.reason && {
"messaging.consumer_group.rebalance.reason": event.reason
},
...groupState.state && {
"messaging.consumer_group.state": groupState.state
}
};
if (event.partitions.length <= 10) {
eventAttrs["messaging.consumer_group.rebalance.partitions"] = event.partitions.map((p) => `${p.topic}:${p.partition}`).join(",");
}
baseCtx.addEvent(`consumer_group_${event.type}`, eventAttrs);
if (config.consumerGroupTracking?.onRebalance) {
config.consumerGroupTracking.onRebalance(consumerCtx, event);
}
if (event.type === "assigned" && config.consumerGroupTracking?.onPartitionsAssigned) {
config.consumerGroupTracking.onPartitionsAssigned(
consumerCtx,
event.partitions
);
}
if (event.type === "revoked" && config.consumerGroupTracking?.onPartitionsRevoked) {
config.consumerGroupTracking.onPartitionsRevoked(
consumerCtx,
event.partitions
);
}
},
recordHeartbeat(healthy, latencyMs) {
groupState.lastHeartbeat = Date.now();
baseCtx.setAttribute(
"messaging.consumer_group.heartbeat.healthy",
healthy
);
if (latencyMs !== void 0) {
baseCtx.setAttribute(
"messaging.consumer_group.heartbeat.latency_ms",
latencyMs
);
}
baseCtx.addEvent("consumer_group_heartbeat", {
"messaging.consumer_group.heartbeat.healthy": healthy,
"messaging.consumer_group.heartbeat.timestamp": groupState.lastHeartbeat,
...latencyMs !== void 0 && {
"messaging.consumer_group.heartbeat.latency_ms": latencyMs
}
});
},
recordPartitionLag(lag) {
const prefix = `messaging.consumer_group.lag.${lag.topic}.${lag.partition}`;
baseCtx.setAttribute(`${prefix}.current_offset`, lag.currentOffset);
baseCtx.setAttribute(`${prefix}.end_offset`, lag.endOffset);
baseCtx.setAttribute(`${prefix}.lag`, lag.lag);
baseCtx.addEvent("partition_lag_recorded", {
"messaging.consumer_group.lag.topic": lag.topic,
"messaging.consumer_group.lag.partition": lag.partition,
"messaging.consumer_group.lag.current_offset": lag.currentOffset,
"messaging.consumer_group.lag.end_offset": lag.endOffset,
"messaging.consumer_group.lag.lag": lag.lag,
"messaging.consumer_group.lag.timestamp": lag.timestamp
});
},
getConsumerGroupState() {
if (!config.consumerGroup) {
return null;
}
return {
groupId: config.consumerGroup,
memberId: groupState.memberId ?? void 0,
groupInstanceId: groupState.groupInstanceId ?? void 0,
assignedPartitions: [...groupState.assignedPartitions],
generation: groupState.generation ?? void 0,
isActive: groupState.isActive,
lastHeartbeat: groupState.lastHeartbeat ?? void 0,
state: groupState.state ?? void 0
};
},
getMemberId() {
return groupState.memberId;
},
getAssignedPartitions() {
return [...groupState.assignedPartitions];
}
};
return consumerCtx;
}
function setProducerAttributes(ctx, config) {
ctx.setAttribute("messaging.system", config.system);
ctx.setAttribute("messaging.operation", "publish");
ctx.setAttribute("messaging.destination.name", config.destination);
if (config.system === "kafka") {
ctx.setAttribute("messaging.kafka.destination.topic", config.destination);
}
if (config.attributes) {
setCustomAttributes(ctx, config.attributes);
}
}
function setDynamicProducerAttributes(ctx, config, args) {
if (config.messageIdFrom) {
const messageId = extractValue(config.messageIdFrom, args);
if (messageId !== void 0) {
ctx.setAttribute("messaging.message.id", String(messageId));
}
}
if (config.partitionFrom) {
const partition = extractValue(config.partitionFrom, args);
if (partition !== void 0) {
ctx.setAttribute(
"messaging.kafka.destination.partition",
Number(partition)
);
}
}
if (config.keyFrom) {
const key = extractValue(config.keyFrom, args);
if (key !== void 0) {
ctx.setAttribute("messaging.kafka.message.key", String(key));
}
}
}
function setConsumerAttributes(ctx, config) {
ctx.setAttribute("messaging.system", config.system);
ctx.setAttribute(
"messaging.operation",
config.batchMode ? "receive" : "process"
);
ctx.setAttribute("messaging.destination.name", config.destination);
if (config.consumerGroup) {
ctx.setAttribute("messaging.consumer.group", config.consumerGroup);
if (config.system === "kafka") {
ctx.setAttribute("messaging.kafka.consumer.group", config.consumerGroup);
}
}
if (config.system === "kafka") {
ctx.setAttribute("messaging.kafka.destination.topic", config.destination);
}
if (config.attributes) {
setCustomAttributes(ctx, config.attributes);
}
}
async function extractAndAddLinks(ctx, config, args, linkStorage) {
if (!config.headersFrom && !config.customContextExtractor) {
return;
}
const links = [];
if (config.batchMode && Array.isArray(args[0])) {
const messages = args[0];
if (config.headersFrom) {
const batchLinks = chunkVH77IPJN_cjs.extractLinksFromBatch(
messages.map((msg) => {
const headers = extractHeaders(config.headersFrom, msg);
return { headers };
}),
"headers"
);
links.push(...batchLinks);
}
if (config.customContextExtractor && config.headersFrom) {
for (const msg of messages) {
const headers = extractHeaders(config.headersFrom, msg);
if (headers) {
const w3cLink = chunkVH77IPJN_cjs.createLinkFromHeaders(headers);
if (!w3cLink) {
const customContext = config.customContextExtractor(headers);
if (customContext) {
links.push({
context: customContext,
attributes: { "messaging.link.source": "custom_extractor" }
});
}
}
}
}
}
ctx.setAttribute("messaging.batch.message_count", messages.length);
} else {
const msg = args[0];
const headers = config.headersFrom ? extractHeaders(config.headersFrom, msg) : void 0;
if (headers) {
const w3cLink = chunkVH77IPJN_cjs.createLinkFromHeaders(headers);
if (w3cLink) {
links.push(w3cLink);
} else if (config.customContextExtractor) {
const customContext = config.customContextExtractor(headers);
if (customContext) {
links.push({
context: customContext,
attributes: { "messaging.link.source": "custom_extractor" }
});
}
}
}
}
if (links.length > 0) {
ctx.addLinks(links);
linkStorage.links.push(...links);
}
}
async function extractLagMetrics(ctx, lagConfig, args) {
const msg = Array.isArray(args[0]) ? args[0][0] : args[0];
let currentOffset;
if (lagConfig.getCurrentOffset && msg) {
currentOffset = lagConfig.getCurrentOffset(msg);
if (currentOffset !== void 0) {
ctx.setAttribute("messaging.kafka.message.offset", currentOffset);
}
}
if (lagConfig.getPartition && msg) {
const partition = lagConfig.getPartition(msg);
if (partition !== void 0) {
ctx.setAttribute("messaging.kafka.partition", partition);
}
}
if (lagConfig.getEndOffset) {
try {
const endOffset = await Promise.resolve(lagConfig.getEndOffset());
if (endOffset !== void 0 && currentOffset !== void 0) {
const lag = endOffset - currentOffset;
ctx.setAttribute("messaging.kafka.consumer_lag", lag);
ctx.addEvent("consumer_lag_measured", {
"messaging.kafka.consumer_lag": lag,
"messaging.kafka.message.offset": currentOffset,
"messaging.kafka.high_watermark": endOffset
});
}
} catch {
}
}
if (lagConfig.getCommittedOffset) {
try {
const committedOffset = await Promise.resolve(
lagConfig.getCommittedOffset()
);
if (committedOffset !== void 0) {
ctx.setAttribute("messaging.kafka.committed_offset", committedOffset);
}
} catch {
}
}
if (Array.isArray(args[0]) && args[0].length > 0) {
const messages = args[0];
if (lagConfig.getCurrentOffset) {
const firstOffset = lagConfig.getCurrentOffset(messages[0]);
const lastMessage = messages.at(-1);
const lastOffset = lastMessage === void 0 ? void 0 : lagConfig.getCurrentOffset(lastMessage);
if (firstOffset !== void 0) {
ctx.setAttribute("messaging.batch.first_offset", firstOffset);
}
if (lastOffset !== void 0) {
ctx.setAttribute("messaging.batch.last_offset", lastOffset);
}
}
}
}
function extractHeaders(headersFrom, msg) {
if (typeof headersFrom === "function") {
return headersFrom(msg);
}
if (typeof msg === "object" && msg !== null) {
const value = msg[headersFrom];
if (typeof value === "object" && value !== null) {
return value;
}
}
return void 0;
}
function extractValue(extractor, args) {
if (typeof extractor === "function") {
return extractor(args);
}
const firstArg = args[0];
if (typeof firstArg === "object" && firstArg !== null) {
return firstArg[extractor];
}
return void 0;
}
function setCustomAttributes(ctx, attributes) {
for (const [key, value] of Object.entries(attributes)) {
if (value !== void 0 && value !== null) {
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
ctx.setAttribute(key, value);
} else if (Array.isArray(value)) {
const cleanArray = value.filter(
(v) => v !== null && v !== void 0 && (typeof v === "string" || typeof v === "number" || typeof v === "boolean")
);
if (cleanArray.length > 0) {
ctx.setAttribute(key, cleanArray);
}
} else {
ctx.setAttribute(key, JSON.stringify(value));
}
}
}
}
function extractAndProcessOrdering(ctx, config, args, orderingState) {
const ordering = config.ordering;
if (!ordering) return;
const messages = config.batchMode && Array.isArray(args[0]) ? args[0] : [args[0]];
if (messages.length === 0) return;
let outOfOrderCount = 0;
let duplicateCount = 0;
let lastSequence = null;
let lastPartitionKey = null;
let lastMessageId = null;
for (const [i, msg] of messages.entries()) {
if (!msg) continue;
let msgSequence = null;
let msgPartitionKey = null;
let msgId = null;
if (ordering.sequenceFrom) {
const seq = ordering.sequenceFrom(msg);
if (seq !== void 0) {
msgSequence = seq;
lastSequence = seq;
}
}
if (ordering.partitionKeyFrom) {
const key = ordering.partitionKeyFrom(msg);
if (key !== void 0) {
msgPartitionKey = key;
lastPartitionKey = key;
}
}
if (ordering.messageIdFrom) {
const id = ordering.messageIdFrom(msg);
if (id !== void 0) {
msgId = id;
lastMessageId = id;
}
}
if (ordering.detectOutOfOrder && msgSequence !== null) {
const msgOrderingState = {
partitionKey: msgPartitionKey};
const trackerKey = buildTrackerKey(config, msgOrderingState);
const prevSequence = sequenceTrackers.get(trackerKey);
if (prevSequence !== void 0) {
const expectedSequence = prevSequence + 1;
if (msgSequence !== expectedSequence) {
outOfOrderCount++;
const gap = msgSequence - expectedSequence;
const outOfOrderInfo = {
currentSequence: msgSequence,
expectedSequence,
partitionKey: msgPartitionKey ?? void 0,
gap
};
if (!orderingState.outOfOrderInfo) {
orderingState.outOfOrderInfo = outOfOrderInfo;
}
ctx.addEvent("message_out_of_order", {
"messaging.ordering.batch_index": i,
"messaging.ordering.current_sequence": msgSequence,
"messaging.ordering.expected_sequence": expectedSequence,
"messaging.ordering.gap": gap,
...msgPartitionKey && {
"messaging.ordering.partition_key": msgPartitionKey
}
});
if (ordering.onOutOfOrder) {
ordering.onOutOfOrder(ctx, outOfOrderInfo);
}
}
}
sequenceTrackers.set(trackerKey, msgSequence);
}
if (ordering.detectDuplicates && msgId !== null) {
const msgOrderingState = {
messageId: msgId};
const dedupKey = buildDedupKey(config, msgOrderingState);
if (deduplicationWindow.has(dedupKey)) {
duplicateCount++;
ctx.addEvent("message_duplicate", {
"messaging.ordering.batch_index": i,
"messaging.message.id": msgId
});
if (ordering.onDuplicate) {
ordering.onDuplicate(ctx, msgId);
}
} else {
deduplicationWindow.set(dedupKey, Date.now());
const windowSize = ordering.deduplicationWindowSize ?? DEFAULT_DEDUP_WINDOW_SIZE;
trimDeduplicationWindow(windowSize);
}
}
}
orderingState.sequenceNumber = lastSequence;
orderingState.partitionKey = lastPartitionKey;
orderingState.messageId = lastMessageId;
orderingState.isDuplicate = duplicateCount > 0;
if (lastSequence !== null) {
ctx.setAttribute("messaging.message.sequence_number", lastSequence);
}
if (lastPartitionKey !== null) {
ctx.setAttribute("messaging.message.partition_key", lastPartitionKey);
}
if (lastMessageId !== null) {
ctx.setAttribute("messaging.message.id", lastMessageId);
}
if (outOfOrderCount > 0) {
ctx.setAttribute("messaging.ordering.out_of_order", true);
ctx.setAttribute("messaging.ordering.out_of_order_count", outOfOrderCount);
}
if (duplicateCount > 0) {
ctx.setAttribute("messaging.ordering.duplicate", true);
ctx.setAttribute("messaging.ordering.duplicate_count", duplicateCount);
}
}
function buildTrackerKey(config, orderingState) {
const parts = [config.system, config.destination];
if (orderingState.partitionKey) {
parts.push(orderingState.partitionKey);
}
if (config.consumerGroup) {
parts.push(config.consumerGroup);
}
return parts.join(":");
}
function buildDedupKey(config, orderingState) {
const parts = [config.system, config.destination];
if (orderingState.messageId) {
parts.push(orderingState.messageId);
}
return parts.join(":");
}
function clearOrderingState() {
sequenceTrackers.clear();
deduplicationWindow.clear();
}
exports.clearOrderingState = clearOrderingState;
exports.traceConsumer = traceConsumer;
exports.traceProducer = traceProducer;
//# sourceMappingURL=chunk-OBWXM4NN.cjs.map
//# sourceMappingURL=chunk-OBWXM4NN.cjs.map