{"version":3,"file":"tracingChannel.js","sources":["../../src/tracingChannel.ts"],"sourcesContent":["/**\n * Vendored and adapted from https://github.com/logaretm/otel-tracing-channel\n *\n * Creates a TracingChannel with proper OpenTelemetry context propagation\n * using Node.js diagnostic_channel's `bindStore` mechanism.\n */\nimport type { TracingChannel, TracingChannelSubscribers } from 'node:diagnostics_channel';\nimport { tracingChannel as nativeTracingChannel } from 'node:diagnostics_channel';\nimport type { Span } from '@opentelemetry/api';\nimport { context, trace } from '@opentelemetry/api';\nimport { logger } from '@sentry/core';\nimport type { SentryAsyncLocalStorageContextManager } from './asyncLocalStorageContextManager';\nimport type { AsyncLocalStorageLookup } from './contextManager';\nimport { DEBUG_BUILD } from './debug-build';\n\n/**\n * Transform function that creates a span from the channel data.\n */\nexport type OtelTracingChannelTransform = (data: TData) => Span;\n\nexport type TracingChannelContextWithSpan = TContext & { _sentrySpan?: Span };\n\n/**\n * A TracingChannel whose `subscribe` / `unsubscribe` accept partial subscriber\n * objects — you only need to provide handlers for the events you care about.\n */\nexport interface OtelTracingChannel<\n TData extends object = object,\n TDataWithSpan extends object = TracingChannelContextWithSpan,\n> extends Omit, 'subscribe' | 'unsubscribe'> {\n subscribe(subscribers: Partial>): void;\n unsubscribe(subscribers: Partial>): void;\n}\n\ninterface ContextApi {\n _getContextManager(): SentryAsyncLocalStorageContextManager;\n}\n\n/**\n * Creates a new tracing channel with proper OTel context propagation.\n *\n * When the channel's `tracePromise` / `traceSync` / `traceCallback` is called,\n * the `transformStart` function runs inside `bindStore` so that:\n * 1. A new span is created from the channel data.\n * 2. The span is set on the OTel context stored in AsyncLocalStorage.\n * 3. Downstream code (including Sentry's span processor) sees the correct parent.\n *\n * @param channelNameOrInstance - Either a channel name string or an existing TracingChannel instance.\n * @param transformStart - Function that creates an OpenTelemetry span from the channel data.\n * @returns The tracing channel with OTel context bound.\n */\nexport function tracingChannel(\n channelNameOrInstance: string,\n transformStart: OtelTracingChannelTransform,\n): OtelTracingChannel> {\n const channel = nativeTracingChannel, TracingChannelContextWithSpan>(\n channelNameOrInstance,\n ) as unknown as OtelTracingChannel>;\n\n let lookup: AsyncLocalStorageLookup | undefined;\n try {\n const contextManager = (context as unknown as ContextApi)._getContextManager();\n lookup = contextManager.getAsyncLocalStorageLookup();\n } catch {\n // getAsyncLocalStorageLookup may not exist if using a non-Sentry context manager\n }\n\n if (!lookup) {\n DEBUG_BUILD &&\n logger.warn(\n '[TracingChannel] Could not access OpenTelemetry AsyncLocalStorage, context propagation will not work.',\n );\n return channel;\n }\n\n const otelStorage = lookup.asyncLocalStorage;\n\n // Bind the start channel so that each trace invocation runs the transform\n // and stores the resulting context (with span) in AsyncLocalStorage.\n // @ts-expect-error bindStore types don't account for AsyncLocalStorage of a different generic type\n channel.start.bindStore(otelStorage, (data: TracingChannelContextWithSpan) => {\n const span = transformStart(data);\n\n // Store the span on data so downstream event handlers (asyncEnd, error, etc.) can access it.\n data._sentrySpan = span;\n\n // Return the context with the span set — this is what gets stored in AsyncLocalStorage.\n return trace.setSpan(context.active(), span);\n });\n\n return channel;\n}\n"],"names":["nativeTracingChannel","context","DEBUG_BUILD","logger","trace"],"mappings":";;;;;;;AAmDO,SAAS,cAAA,CACd,uBACA,cAAA,EACiE;AACjE,EAAA,MAAM,OAAA,GAAUA,uCAAA;AAAA,IACd;AAAA,GACF;AAEA,EAAA,IAAI,MAAA;AACJ,EAAA,IAAI;AACF,IAAA,MAAM,cAAA,GAAkBC,YAAkC,kBAAA,EAAmB;AAC7E,IAAA,MAAA,GAAS,eAAe,0BAAA,EAA2B;AAAA,EACrD,CAAA,CAAA,MAAQ;AAAA,EAER;AAEA,EAAA,IAAI,CAAC,MAAA,EAAQ;AACX,IAAAC,sBAAA,IACEC,WAAA,CAAO,IAAA;AAAA,MACL;AAAA,KACF;AACF,IAAA,OAAO,OAAA;AAAA,EACT;AAEA,EAAA,MAAM,cAAc,MAAA,CAAO,iBAAA;AAK3B,EAAA,OAAA,CAAQ,KAAA,CAAM,SAAA,CAAU,WAAA,EAAa,CAAC,IAAA,KAA+C;AACnF,IAAA,MAAM,IAAA,GAAO,eAAe,IAAI,CAAA;AAGhC,IAAA,IAAA,CAAK,WAAA,GAAc,IAAA;AAGnB,IAAA,OAAOC,SAAA,CAAM,OAAA,CAAQH,WAAA,CAAQ,MAAA,IAAU,IAAI,CAAA;AAAA,EAC7C,CAAC,CAAA;AAED,EAAA,OAAO,OAAA;AACT;;;;"}