@raccoon.ninja/otel-react 1.0.0 → 1.2.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -53,20 +53,21 @@ All telemetry is sent to `http://localhost:4318` by default (the standard OTLP H
53
53
 
54
54
  ### OtelProvider Props
55
55
 
56
- | Prop | Type | Default | Description |
57
- | -------------------- | ------------------------ | ----------------------- | ---------------------------------------------------- |
58
- | `serviceName` | `string` | **(required)** | Sets the `service.name` resource attribute |
59
- | `endpoint` | `string` | `http://localhost:4318` | OTLP HTTP collector endpoint |
60
- | `serviceVersion` | `string` | -- | Sets `service.version` resource attribute |
61
- | `environment` | `string` | -- | Sets `deployment.environment` resource attribute |
62
- | `headers` | `Record<string, string>` | -- | Custom headers for OTLP requests (e.g., auth tokens) |
63
- | `exportTimeout` | `number` | `30000` | Export timeout in milliseconds |
64
- | `ignoreUrls` | `(string \| RegExp)[]` | -- | URLs to exclude from fetch/XHR instrumentation |
65
- | `instrumentations` | `InstrumentationConfig` | all enabled | Enable/disable specific auto-instrumentations |
66
- | `resourceAttributes` | `Record<string, string>` | -- | Additional OTel resource attributes |
67
- | `extensions` | `OtelExtension[]` | -- | Opt-in extensions (e.g., `withReactRouter()`) |
68
- | `configureTracing` | `(provider) => void` | -- | Escape hatch to configure the TracerProvider |
69
- | `configureExporter` | `(exporter) => void` | -- | Escape hatch to configure the OTLP exporter |
56
+ | Prop | Type | Default | Description |
57
+ | ------------------------------ | ------------------------ | ----------------------- | --------------------------------------------------------------- |
58
+ | `serviceName` | `string` | **(required)** | Sets the `service.name` resource attribute |
59
+ | `endpoint` | `string` | `http://localhost:4318` | OTLP HTTP collector endpoint |
60
+ | `serviceVersion` | `string` | -- | Sets `service.version` resource attribute |
61
+ | `environment` | `string` | -- | Sets `deployment.environment` resource attribute |
62
+ | `headers` | `Record<string, string>` | -- | Custom headers for OTLP requests (e.g., auth tokens) |
63
+ | `exportTimeout` | `number` | `30000` | Export timeout in milliseconds |
64
+ | `ignoreUrls` | `(string \| RegExp)[]` | -- | URLs to exclude from fetch/XHR instrumentation |
65
+ | `propagateTraceHeaderCorsUrls` | `(string \| RegExp)[]` | `[]` | Cross-origin URLs that should receive W3C Trace Context headers |
66
+ | `instrumentations` | `InstrumentationConfig` | all enabled | Enable/disable specific auto-instrumentations |
67
+ | `resourceAttributes` | `Record<string, string>` | -- | Additional OTel resource attributes |
68
+ | `extensions` | `OtelExtension[]` | -- | Opt-in extensions (e.g., `withReactRouter()`) |
69
+ | `configureTracing` | `(provider) => void` | -- | Escape hatch to configure the TracerProvider |
70
+ | `configureExporter` | `(exporter) => void` | -- | Escape hatch to configure the OTLP exporter |
70
71
 
71
72
  ### Pointing to a Collector
72
73
 
package/dist/index.cjs CHANGED
@@ -66,12 +66,11 @@ function validateOptions(options) {
66
66
  }
67
67
  }
68
68
  var SDK_NAME = "@raccoon.ninja/otel-react";
69
- var SDK_VERSION = "1.0.0";
70
69
  function buildResource(options) {
71
70
  const attributes = {
72
71
  [semanticConventions.ATTR_SERVICE_NAME]: options.serviceName,
73
72
  "telemetry.sdk.name": SDK_NAME,
74
- "telemetry.sdk.version": SDK_VERSION,
73
+ "telemetry.sdk.version": "1.2.0-rc.1",
75
74
  "telemetry.sdk.language": "webjs"
76
75
  };
77
76
  if (options.serviceVersion) {
@@ -121,8 +120,10 @@ function createLoggerProvider(options, resource) {
121
120
  headers: options.headers,
122
121
  timeoutMillis: timeout
123
122
  });
124
- const provider = new sdkLogs.LoggerProvider({ resource });
125
- provider.addLogRecordProcessor(new sdkLogs.BatchLogRecordProcessor(exporter));
123
+ const provider = new sdkLogs.LoggerProvider({
124
+ resource,
125
+ processors: [new sdkLogs.BatchLogRecordProcessor(exporter)]
126
+ });
126
127
  apiLogs.logs.setGlobalLoggerProvider(provider);
127
128
  return provider;
128
129
  }
@@ -149,19 +150,27 @@ function createMeterProvider(options, resource) {
149
150
  }
150
151
  function registerAutoInstrumentations(options) {
151
152
  const config = resolveInstrumentations(options);
152
- const ignoreUrls = options.ignoreUrls ?? [];
153
+ const endpoint = resolveEndpoint(options);
154
+ const escapedEndpoint = endpoint.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
155
+ const ignoreUrls = [
156
+ ...options.ignoreUrls ?? [],
157
+ new RegExp(escapedEndpoint)
158
+ ];
153
159
  const instrumentations = [];
160
+ const propagateTraceHeaderCorsUrls = options.propagateTraceHeaderCorsUrls ?? [];
154
161
  if (config.fetch) {
155
162
  instrumentations.push(
156
163
  new instrumentationFetch.FetchInstrumentation({
157
- ignoreUrls
164
+ ignoreUrls,
165
+ propagateTraceHeaderCorsUrls
158
166
  })
159
167
  );
160
168
  }
161
169
  if (config.xhr) {
162
170
  instrumentations.push(
163
171
  new instrumentationXmlHttpRequest.XMLHttpRequestInstrumentation({
164
- ignoreUrls
172
+ ignoreUrls,
173
+ propagateTraceHeaderCorsUrls
165
174
  })
166
175
  );
167
176
  }
@@ -177,7 +186,7 @@ function registerAutoInstrumentations(options) {
177
186
  }
178
187
  var METER_NAME = "@raccoon.ninja/otel-react/web-vitals";
179
188
  function startWebVitalsCollection() {
180
- const meter = api.metrics.getMeter(METER_NAME, "1.0.0");
189
+ const meter = api.metrics.getMeter(METER_NAME, "1.2.0-rc.1");
181
190
  const lcpHistogram = meter.createHistogram("web_vitals.lcp", {
182
191
  description: "Largest Contentful Paint",
183
192
  unit: "ms"
@@ -299,7 +308,7 @@ function initOtel(options) {
299
308
  ext({ tracerProvider });
300
309
  }
301
310
  }
302
- const logger = loggerProvider.getLogger("@raccoon.ninja/otel-react", "1.0.0");
311
+ const logger = loggerProvider.getLogger("@raccoon.ninja/otel-react", "1.2.0-rc.1");
303
312
  logger.emit({
304
313
  severityNumber: apiLogs.SeverityNumber.INFO,
305
314
  severityText: "INFO",
@@ -327,6 +336,7 @@ function OtelProvider({
327
336
  headers,
328
337
  exportTimeout,
329
338
  ignoreUrls,
339
+ propagateTraceHeaderCorsUrls,
330
340
  configureTracing,
331
341
  configureExporter,
332
342
  extensions
@@ -343,6 +353,7 @@ function OtelProvider({
343
353
  headers,
344
354
  exportTimeout,
345
355
  ignoreUrls,
356
+ propagateTraceHeaderCorsUrls,
346
357
  configureTracing,
347
358
  configureExporter,
348
359
  extensions
@@ -366,7 +377,7 @@ var TracedErrorBoundary = class extends react.Component {
366
377
  return { hasError: true, error };
367
378
  }
368
379
  componentDidCatch(error, errorInfo) {
369
- const tracer = api.trace.getTracer(TRACER_NAME, "1.0.0");
380
+ const tracer = api.trace.getTracer(TRACER_NAME, "1.2.0-rc.1");
370
381
  const span = tracer.startSpan("error-boundary.catch");
371
382
  span.setStatus({ code: api.SpanStatusCode.ERROR, message: error.message });
372
383
  span.setAttribute("error.type", error.name);
@@ -380,7 +391,7 @@ var TracedErrorBoundary = class extends react.Component {
380
391
  span.recordException(error);
381
392
  span.end();
382
393
  try {
383
- const logger = apiLogs.logs.getLogger(LOGGER_NAME, "1.0.0");
394
+ const logger = apiLogs.logs.getLogger(LOGGER_NAME, "1.2.0-rc.1");
384
395
  logger.emit({
385
396
  severityNumber: apiLogs.SeverityNumber.ERROR,
386
397
  severityText: "ERROR",
@@ -417,7 +428,7 @@ function useTracer(name, version) {
417
428
  var TRACER_NAME2 = "@raccoon.ninja/otel-react/router";
418
429
  function withReactRouter() {
419
430
  return (_context) => {
420
- api.trace.getTracer(TRACER_NAME2, "1.0.0");
431
+ api.trace.getTracer(TRACER_NAME2, "1.2.0-rc.1");
421
432
  };
422
433
  }
423
434
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core/options.ts","../src/core/resource.ts","../src/providers/tracer.ts","../src/providers/logger.ts","../src/providers/meter.ts","../src/instrumentations/auto.ts","../src/instrumentations/web-vitals.ts","../src/core/shutdown.ts","../src/core/init.ts","../src/components/OtelProvider.tsx","../src/components/TracedErrorBoundary.tsx","../src/hooks/useTracer.ts","../src/instrumentations/router.ts"],"names":["ATTR_SERVICE_NAME","ATTR_SERVICE_VERSION","SEMRESATTRS_DEPLOYMENT_ENVIRONMENT","resourceFromAttributes","OTLPTraceExporter","WebTracerProvider","BatchSpanProcessor","OTLPLogExporter","LoggerProvider","BatchLogRecordProcessor","logs","OTLPMetricExporter","MeterProvider","PeriodicExportingMetricReader","metrics","FetchInstrumentation","XMLHttpRequestInstrumentation","DocumentLoadInstrumentation","UserInteractionInstrumentation","registerInstrumentations","SeverityNumber","useRef","useEffect","Component","trace","SpanStatusCode","useMemo","TRACER_NAME"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { WebTracerProvider } from '@opentelemetry/sdk-trace-web';\nimport type { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';\n\n/** Configuration for enabling/disabling specific auto-instrumentations. */\nexport interface InstrumentationConfig {\n /** Auto-instrument fetch() calls. Default: true */\n fetch?: boolean;\n /** Auto-instrument XMLHttpRequest. Default: true */\n xhr?: boolean;\n /** Document load timing spans. Default: true */\n documentLoad?: boolean;\n /** Click/input interaction spans. Default: true */\n userInteraction?: boolean;\n /** LCP, CLS, INP, TTFB, FCP metrics. Default: true */\n webVitals?: boolean;\n}\n\n/** Extension function type for opt-in instrumentations (e.g., withReactRouter). */\nexport type OtelExtension = (context: ExtensionContext) => void;\n\n/** Context provided to extension functions during initialization. */\nexport interface ExtensionContext {\n tracerProvider: WebTracerProvider;\n}\n\n/** Configuration options for initOtel(). */\nexport interface OtelOptions {\n /** Required. Sets the service.name resource attribute. */\n serviceName: string;\n\n /** OTLP HTTP endpoint. Default: 'http://localhost:4318' */\n endpoint?: string;\n\n /** Additional OTel resource attributes. */\n resourceAttributes?: Record<string, string>;\n\n /** Service version. Sets service.version resource attribute. */\n serviceVersion?: string;\n\n /** Deployment environment. Sets deployment.environment resource attribute. */\n environment?: string;\n\n /** Enable/disable specific auto-instrumentations. All enabled by default. */\n instrumentations?: InstrumentationConfig;\n\n /** Escape hatch: configure the TracerProvider before it's registered. */\n configureTracing?: (provider: WebTracerProvider) => void;\n\n /** Escape hatch: configure the OTLP exporter. */\n configureExporter?: (exporter: OTLPTraceExporter) => void;\n\n /** Custom headers sent with OTLP export requests (e.g., auth tokens). */\n headers?: Record<string, string>;\n\n /** Export timeout in milliseconds. Default: 30000 */\n exportTimeout?: number;\n\n /**\n * URLs to exclude from fetch/XHR instrumentation.\n * Supports string patterns or RegExp.\n */\n ignoreUrls?: Array<string | RegExp>;\n\n /** Extension functions for opt-in instrumentations. */\n extensions?: OtelExtension[];\n}\n\n/** Handle returned from initOtel() for lifecycle management. */\nexport interface OtelHandle {\n /** Flush all pending telemetry and shut down providers. */\n shutdown: () => Promise<void>;\n}\n\nconst DEFAULT_ENDPOINT = 'http://localhost:4318';\nconst DEFAULT_EXPORT_TIMEOUT = 30000;\n\nexport function resolveEndpoint(options: OtelOptions): string {\n return options.endpoint ?? DEFAULT_ENDPOINT;\n}\n\nexport function resolveExportTimeout(options: OtelOptions): number {\n return options.exportTimeout ?? DEFAULT_EXPORT_TIMEOUT;\n}\n\nexport function resolveInstrumentations(options: OtelOptions): Required<InstrumentationConfig> {\n return {\n fetch: options.instrumentations?.fetch ?? true,\n xhr: options.instrumentations?.xhr ?? true,\n documentLoad: options.instrumentations?.documentLoad ?? true,\n userInteraction: options.instrumentations?.userInteraction ?? true,\n webVitals: options.instrumentations?.webVitals ?? true,\n };\n}\n\nexport function validateOptions(options: OtelOptions): void {\n if (!options.serviceName || typeof options.serviceName !== 'string') {\n throw new Error(\n '[@raccoon.ninja/otel-react] serviceName is required and must be a non-empty string.',\n );\n }\n\n if (options.serviceName.trim() !== options.serviceName) {\n throw new Error(\n '[@raccoon.ninja/otel-react] serviceName must not have leading or trailing whitespace.',\n );\n }\n\n if (options.endpoint !== undefined) {\n if (typeof options.endpoint !== 'string' || options.endpoint.trim() === '') {\n throw new Error(\n '[@raccoon.ninja/otel-react] endpoint must be a non-empty string when provided.',\n );\n }\n }\n\n if (options.exportTimeout !== undefined) {\n if (typeof options.exportTimeout !== 'number' || options.exportTimeout <= 0) {\n throw new Error(\n '[@raccoon.ninja/otel-react] exportTimeout must be a positive number when provided.',\n );\n }\n }\n}\n","import { resourceFromAttributes } from '@opentelemetry/resources';\nimport {\n ATTR_SERVICE_NAME,\n ATTR_SERVICE_VERSION,\n SEMRESATTRS_DEPLOYMENT_ENVIRONMENT,\n} from '@opentelemetry/semantic-conventions';\nimport type { OtelOptions } from './options';\n\nconst SDK_NAME = '@raccoon.ninja/otel-react';\nconst SDK_VERSION = '1.0.0';\n\nexport function buildResource(options: OtelOptions) {\n const attributes: Record<string, string> = {\n [ATTR_SERVICE_NAME]: options.serviceName,\n 'telemetry.sdk.name': SDK_NAME,\n 'telemetry.sdk.version': SDK_VERSION,\n 'telemetry.sdk.language': 'webjs',\n };\n\n if (options.serviceVersion) {\n attributes[ATTR_SERVICE_VERSION] = options.serviceVersion;\n }\n\n if (options.environment) {\n attributes[SEMRESATTRS_DEPLOYMENT_ENVIRONMENT] = options.environment;\n }\n\n if (typeof navigator !== 'undefined') {\n if (navigator.language) {\n attributes['browser.language'] = navigator.language;\n }\n if (navigator.userAgent) {\n attributes['browser.user_agent'] = navigator.userAgent;\n }\n if (navigator.platform) {\n attributes['browser.platform'] = navigator.platform;\n }\n }\n\n if (options.resourceAttributes) {\n Object.assign(attributes, options.resourceAttributes);\n }\n\n return resourceFromAttributes(attributes);\n}\n","import { WebTracerProvider } from '@opentelemetry/sdk-trace-web';\nimport { BatchSpanProcessor } from '@opentelemetry/sdk-trace-base';\nimport { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';\nimport type { Resource } from '@opentelemetry/resources';\nimport type { OtelOptions } from '../core/options';\nimport { resolveEndpoint, resolveExportTimeout } from '../core/options';\n\nexport interface TracerSetupResult {\n provider: WebTracerProvider;\n exporter: OTLPTraceExporter;\n}\n\nexport function createTracerProvider(options: OtelOptions, resource: Resource): TracerSetupResult {\n const endpoint = resolveEndpoint(options);\n const timeout = resolveExportTimeout(options);\n\n const exporter = new OTLPTraceExporter({\n url: `${endpoint}/v1/traces`,\n headers: options.headers,\n timeoutMillis: timeout,\n });\n\n options.configureExporter?.(exporter);\n\n const provider = new WebTracerProvider({\n resource,\n spanProcessors: [new BatchSpanProcessor(exporter)],\n });\n\n options.configureTracing?.(provider);\n\n provider.register();\n\n return { provider, exporter };\n}\n","import { LoggerProvider, BatchLogRecordProcessor } from '@opentelemetry/sdk-logs';\nimport { OTLPLogExporter } from '@opentelemetry/exporter-logs-otlp-http';\nimport { logs } from '@opentelemetry/api-logs';\nimport type { Resource } from '@opentelemetry/resources';\nimport type { OtelOptions } from '../core/options';\nimport { resolveEndpoint, resolveExportTimeout } from '../core/options';\n\nexport function createLoggerProvider(options: OtelOptions, resource: Resource): LoggerProvider {\n const endpoint = resolveEndpoint(options);\n const timeout = resolveExportTimeout(options);\n\n const exporter = new OTLPLogExporter({\n url: `${endpoint}/v1/logs`,\n headers: options.headers,\n timeoutMillis: timeout,\n });\n\n const provider = new LoggerProvider({ resource });\n provider.addLogRecordProcessor(new BatchLogRecordProcessor(exporter));\n\n logs.setGlobalLoggerProvider(provider);\n\n return provider;\n}\n","import { MeterProvider, PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics';\nimport { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-http';\nimport { metrics } from '@opentelemetry/api';\nimport type { Resource } from '@opentelemetry/resources';\nimport type { OtelOptions } from '../core/options';\nimport { resolveEndpoint, resolveExportTimeout } from '../core/options';\n\nconst METRIC_EXPORT_INTERVAL_MS = 30_000;\n\nexport function createMeterProvider(options: OtelOptions, resource: Resource): MeterProvider {\n const endpoint = resolveEndpoint(options);\n const timeout = resolveExportTimeout(options);\n\n const exporter = new OTLPMetricExporter({\n url: `${endpoint}/v1/metrics`,\n headers: options.headers,\n timeoutMillis: timeout,\n });\n\n const provider = new MeterProvider({\n resource,\n readers: [\n new PeriodicExportingMetricReader({\n exporter,\n exportIntervalMillis: METRIC_EXPORT_INTERVAL_MS,\n }),\n ],\n });\n\n metrics.setGlobalMeterProvider(provider);\n\n return provider;\n}\n","import { registerInstrumentations } from '@opentelemetry/instrumentation';\nimport { FetchInstrumentation } from '@opentelemetry/instrumentation-fetch';\nimport { XMLHttpRequestInstrumentation } from '@opentelemetry/instrumentation-xml-http-request';\nimport { DocumentLoadInstrumentation } from '@opentelemetry/instrumentation-document-load';\nimport { UserInteractionInstrumentation } from '@opentelemetry/instrumentation-user-interaction';\nimport type { InstrumentationConfig, OtelOptions } from '../core/options';\nimport { resolveInstrumentations } from '../core/options';\n\nexport function registerAutoInstrumentations(options: OtelOptions): void {\n const config: Required<InstrumentationConfig> = resolveInstrumentations(options);\n const ignoreUrls = options.ignoreUrls ?? [];\n\n const instrumentations = [];\n\n if (config.fetch) {\n instrumentations.push(\n new FetchInstrumentation({\n ignoreUrls,\n }),\n );\n }\n\n if (config.xhr) {\n instrumentations.push(\n new XMLHttpRequestInstrumentation({\n ignoreUrls,\n }),\n );\n }\n\n if (config.documentLoad) {\n instrumentations.push(new DocumentLoadInstrumentation());\n }\n\n if (config.userInteraction) {\n instrumentations.push(new UserInteractionInstrumentation());\n }\n\n if (instrumentations.length > 0) {\n registerInstrumentations({ instrumentations });\n }\n}\n","import { metrics } from '@opentelemetry/api';\nimport type { Metric } from 'web-vitals';\n\nconst METER_NAME = '@raccoon.ninja/otel-react/web-vitals';\n\nexport function startWebVitalsCollection(): void {\n const meter = metrics.getMeter(METER_NAME, '1.0.0');\n\n const lcpHistogram = meter.createHistogram('web_vitals.lcp', {\n description: 'Largest Contentful Paint',\n unit: 'ms',\n });\n\n const clsHistogram = meter.createHistogram('web_vitals.cls', {\n description: 'Cumulative Layout Shift',\n unit: '',\n });\n\n const inpHistogram = meter.createHistogram('web_vitals.inp', {\n description: 'Interaction to Next Paint',\n unit: 'ms',\n });\n\n const ttfbHistogram = meter.createHistogram('web_vitals.ttfb', {\n description: 'Time to First Byte',\n unit: 'ms',\n });\n\n const fcpHistogram = meter.createHistogram('web_vitals.fcp', {\n description: 'First Contentful Paint',\n unit: 'ms',\n });\n\n const recordMetric = (histogram: ReturnType<typeof meter.createHistogram>) => {\n return (metric: Metric) => {\n const attrs: Record<string, string> = {\n 'web_vitals.rating': metric.rating,\n };\n\n if (typeof window !== 'undefined' && window.location) {\n attrs['page.url'] = window.location.pathname;\n }\n\n histogram.record(metric.value, attrs);\n };\n };\n\n // Dynamic import to enable tree-shaking when web-vitals is not used\n import('web-vitals').then(({ onLCP, onCLS, onINP, onTTFB, onFCP }) => {\n onLCP(recordMetric(lcpHistogram));\n onCLS(recordMetric(clsHistogram));\n onINP(recordMetric(inpHistogram));\n onTTFB(recordMetric(ttfbHistogram));\n onFCP(recordMetric(fcpHistogram));\n });\n}\n","import type { WebTracerProvider } from '@opentelemetry/sdk-trace-web';\nimport type { LoggerProvider } from '@opentelemetry/sdk-logs';\nimport type { MeterProvider } from '@opentelemetry/sdk-metrics';\n\nexport interface ShutdownTargets {\n tracerProvider: WebTracerProvider;\n loggerProvider: LoggerProvider;\n meterProvider: MeterProvider;\n}\n\nlet shutdownTargets: ShutdownTargets | null = null;\nlet visibilityHandler: (() => void) | null = null;\nlet beforeUnloadHandler: (() => void) | null = null;\n\nexport function registerShutdownTargets(targets: ShutdownTargets): void {\n shutdownTargets = targets;\n\n visibilityHandler = () => {\n if (document.visibilityState === 'hidden') {\n flushAll();\n }\n };\n\n beforeUnloadHandler = () => {\n flushAll();\n };\n\n if (typeof document !== 'undefined') {\n document.addEventListener('visibilitychange', visibilityHandler);\n }\n if (typeof window !== 'undefined') {\n window.addEventListener('beforeunload', beforeUnloadHandler);\n }\n}\n\nfunction flushAll(): void {\n if (!shutdownTargets) return;\n\n try {\n shutdownTargets.tracerProvider.forceFlush();\n shutdownTargets.loggerProvider.forceFlush();\n shutdownTargets.meterProvider.forceFlush();\n } catch {\n // Flush is best-effort during page unload\n }\n}\n\nexport async function shutdown(): Promise<void> {\n if (!shutdownTargets) return;\n\n if (typeof document !== 'undefined' && visibilityHandler) {\n document.removeEventListener('visibilitychange', visibilityHandler);\n }\n if (typeof window !== 'undefined' && beforeUnloadHandler) {\n window.removeEventListener('beforeunload', beforeUnloadHandler);\n }\n\n try {\n await Promise.all([\n shutdownTargets.tracerProvider.forceFlush(),\n shutdownTargets.loggerProvider.forceFlush(),\n shutdownTargets.meterProvider.forceFlush(),\n ]);\n\n await Promise.all([\n shutdownTargets.tracerProvider.shutdown(),\n shutdownTargets.loggerProvider.shutdown(),\n shutdownTargets.meterProvider.shutdown(),\n ]);\n } finally {\n shutdownTargets = null;\n visibilityHandler = null;\n beforeUnloadHandler = null;\n }\n}\n","import { SeverityNumber } from '@opentelemetry/api-logs';\nimport type { OtelOptions, OtelHandle } from './options';\nimport { validateOptions, resolveInstrumentations } from './options';\nimport { buildResource } from './resource';\nimport { createTracerProvider } from '../providers/tracer';\nimport { createLoggerProvider } from '../providers/logger';\nimport { createMeterProvider } from '../providers/meter';\nimport { registerAutoInstrumentations } from '../instrumentations/auto';\nimport { startWebVitalsCollection } from '../instrumentations/web-vitals';\nimport { registerShutdownTargets, shutdown } from './shutdown';\n\nlet initialized = false;\n\nexport function initOtel(options: OtelOptions): OtelHandle {\n if (initialized) {\n console.warn(\n '[@raccoon.ninja/otel-react] initOtel() has already been called. Skipping re-initialization.',\n );\n return { shutdown };\n }\n\n validateOptions(options);\n\n const resource = buildResource(options);\n const { provider: tracerProvider } = createTracerProvider(options, resource);\n const loggerProvider = createLoggerProvider(options, resource);\n const meterProvider = createMeterProvider(options, resource);\n\n registerAutoInstrumentations(options);\n\n const instrumentationConfig = resolveInstrumentations(options);\n if (instrumentationConfig.webVitals) {\n startWebVitalsCollection();\n }\n\n registerShutdownTargets({ tracerProvider, loggerProvider, meterProvider });\n\n // Run extensions\n if (options.extensions) {\n for (const ext of options.extensions) {\n ext({ tracerProvider });\n }\n }\n\n // Log initialization success\n const logger = loggerProvider.getLogger('@raccoon.ninja/otel-react', '1.0.0');\n logger.emit({\n severityNumber: SeverityNumber.INFO,\n severityText: 'INFO',\n body: `OpenTelemetry initialized for service \"${options.serviceName}\"`,\n attributes: {\n 'otel.service_name': options.serviceName,\n },\n });\n\n initialized = true;\n\n return {\n shutdown: async () => {\n await shutdown();\n initialized = false;\n },\n };\n}\n\n/** Reset initialization state (for testing). */\nexport function _resetInitState(): void {\n initialized = false;\n}\n","import { useEffect, useRef, type ReactNode } from 'react';\nimport { initOtel } from '../core/init';\nimport type { OtelOptions, OtelHandle, OtelExtension } from '../core/options';\n\n/** Props for the OtelProvider component. */\nexport interface OtelProviderProps {\n /** Required. Sets the service.name resource attribute. */\n serviceName: string;\n /** OTLP HTTP endpoint. Default: 'http://localhost:4318' */\n endpoint?: string;\n /** Additional OTel resource attributes. */\n resourceAttributes?: Record<string, string>;\n /** Service version. */\n serviceVersion?: string;\n /** Deployment environment. */\n environment?: string;\n /** Enable/disable specific auto-instrumentations. */\n instrumentations?: OtelOptions['instrumentations'];\n /** Custom headers sent with OTLP export requests. */\n headers?: Record<string, string>;\n /** Export timeout in milliseconds. */\n exportTimeout?: number;\n /** URLs to exclude from fetch/XHR instrumentation. */\n ignoreUrls?: Array<string | RegExp>;\n /** Escape hatch: configure the TracerProvider. */\n configureTracing?: OtelOptions['configureTracing'];\n /** Escape hatch: configure the OTLP exporter. */\n configureExporter?: OtelOptions['configureExporter'];\n /** Extension functions for opt-in instrumentations. */\n extensions?: OtelExtension[];\n /** React children to render. */\n children: ReactNode;\n}\n\n/**\n * React Provider component that initializes OpenTelemetry on mount\n * and flushes/shuts down on unmount.\n *\n * @example\n * ```tsx\n * import { OtelProvider } from '@raccoon.ninja/otel-react';\n *\n * function App() {\n * return (\n * <OtelProvider serviceName=\"my-app\">\n * <RestOfTheApp />\n * </OtelProvider>\n * );\n * }\n * ```\n */\nexport function OtelProvider({\n children,\n serviceName,\n endpoint,\n resourceAttributes,\n serviceVersion,\n environment,\n instrumentations,\n headers,\n exportTimeout,\n ignoreUrls,\n configureTracing,\n configureExporter,\n extensions,\n}: OtelProviderProps) {\n const handleRef = useRef<OtelHandle | null>(null);\n\n useEffect(() => {\n const handle = initOtel({\n serviceName,\n endpoint,\n resourceAttributes,\n serviceVersion,\n environment,\n instrumentations,\n headers,\n exportTimeout,\n ignoreUrls,\n configureTracing,\n configureExporter,\n extensions,\n });\n\n handleRef.current = handle;\n\n return () => {\n handleRef.current?.shutdown();\n handleRef.current = null;\n };\n // We intentionally only run this on mount/unmount.\n // Config changes require remounting the provider.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n return <>{children}</>;\n}\n","import { Component, type ReactNode, type ErrorInfo } from 'react';\nimport { trace, SpanStatusCode } from '@opentelemetry/api';\nimport { SeverityNumber } from '@opentelemetry/api-logs';\nimport { logs } from '@opentelemetry/api-logs';\n\nconst TRACER_NAME = '@raccoon.ninja/otel-react/error-boundary';\nconst LOGGER_NAME = '@raccoon.ninja/otel-react/error-boundary';\n\n/** Props for the TracedErrorBoundary component. */\nexport interface TracedErrorBoundaryProps {\n /** Fallback UI to render when an error is caught. */\n fallback: ReactNode | ((error: Error, reset: () => void) => ReactNode);\n /** Optional callback when an error is caught. */\n onError?: (error: Error, errorInfo: ErrorInfo) => void;\n /** Children to render. */\n children: ReactNode;\n}\n\ninterface TracedErrorBoundaryState {\n hasError: boolean;\n error: Error | null;\n}\n\n/**\n * Error boundary that records caught errors as OpenTelemetry spans and logs.\n *\n * @example\n * ```tsx\n * import { TracedErrorBoundary } from '@raccoon.ninja/otel-react';\n *\n * <TracedErrorBoundary fallback={<ErrorPage />}>\n * <RiskyComponent />\n * </TracedErrorBoundary>\n * ```\n */\nexport class TracedErrorBoundary extends Component<\n TracedErrorBoundaryProps,\n TracedErrorBoundaryState\n> {\n constructor(props: TracedErrorBoundaryProps) {\n super(props);\n this.state = { hasError: false, error: null };\n }\n\n static getDerivedStateFromError(error: Error): TracedErrorBoundaryState {\n return { hasError: true, error };\n }\n\n componentDidCatch(error: Error, errorInfo: ErrorInfo): void {\n const tracer = trace.getTracer(TRACER_NAME, '1.0.0');\n const span = tracer.startSpan('error-boundary.catch');\n\n span.setStatus({ code: SpanStatusCode.ERROR, message: error.message });\n span.setAttribute('error.type', error.name);\n span.setAttribute('error.message', error.message);\n\n if (error.stack) {\n span.setAttribute('error.stack', error.stack);\n }\n if (errorInfo.componentStack) {\n span.setAttribute('error.component_stack', errorInfo.componentStack);\n }\n\n span.recordException(error);\n span.end();\n\n // Also emit as a log record\n try {\n const logger = logs.getLogger(LOGGER_NAME, '1.0.0');\n logger.emit({\n severityNumber: SeverityNumber.ERROR,\n severityText: 'ERROR',\n body: `Unhandled error: ${error.message}`,\n attributes: {\n 'error.type': error.name,\n 'error.message': error.message,\n ...(error.stack ? { 'error.stack': error.stack } : {}),\n ...(errorInfo.componentStack\n ? { 'error.component_stack': errorInfo.componentStack }\n : {}),\n },\n });\n } catch {\n // Logging is best-effort\n }\n\n this.props.onError?.(error, errorInfo);\n }\n\n private reset = () => {\n this.setState({ hasError: false, error: null });\n };\n\n render() {\n if (this.state.hasError && this.state.error) {\n const { fallback } = this.props;\n if (typeof fallback === 'function') {\n return fallback(this.state.error, this.reset);\n }\n return fallback;\n }\n\n return this.props.children;\n }\n}\n","import { useMemo } from 'react';\nimport { trace, type Tracer } from '@opentelemetry/api';\n\nconst DEFAULT_TRACER_NAME = '@raccoon.ninja/otel-react/custom';\n\n/**\n * Hook to get an OpenTelemetry Tracer for creating custom spans.\n *\n * @param name - Optional tracer name. Defaults to '@raccoon.ninja/otel-react/custom'.\n * @param version - Optional tracer version.\n * @returns An OTel Tracer instance.\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * const tracer = useTracer();\n *\n * const handleClick = () => {\n * const span = tracer.startSpan('button-click');\n * // ... do work ...\n * span.end();\n * };\n * }\n * ```\n */\nexport function useTracer(name?: string, version?: string): Tracer {\n return useMemo(() => trace.getTracer(name ?? DEFAULT_TRACER_NAME, version), [name, version]);\n}\n","import { trace } from '@opentelemetry/api';\nimport type { OtelExtension, ExtensionContext } from '../core/options';\n\nconst TRACER_NAME = '@raccoon.ninja/otel-react/router';\n\n/**\n * Extension for React Router v6/v7 route-change tracing.\n *\n * Usage:\n * ```tsx\n * import { OtelProvider, withReactRouter } from '@raccoon.ninja/otel-react';\n *\n * <OtelProvider serviceName=\"my-app\" extensions={[withReactRouter()]}>\n * <App />\n * </OtelProvider>\n * ```\n *\n * Note: The actual hook-based integration should be used inside\n * a component that has access to React Router's context. This extension\n * registers the tracer scope for route-change spans.\n */\nexport function withReactRouter(): OtelExtension {\n return (_context: ExtensionContext) => {\n // Pre-register the tracer scope so route spans are properly attributed\n trace.getTracer(TRACER_NAME, '1.0.0');\n };\n}\n\n/** Tracer name for route-change spans, exported for use in hooks. */\nexport const ROUTER_TRACER_NAME = TRACER_NAME;\n"]}
1
+ {"version":3,"sources":["../src/core/options.ts","../src/core/resource.ts","../src/providers/tracer.ts","../src/providers/logger.ts","../src/providers/meter.ts","../src/instrumentations/auto.ts","../src/instrumentations/web-vitals.ts","../src/core/shutdown.ts","../src/core/init.ts","../src/components/OtelProvider.tsx","../src/components/TracedErrorBoundary.tsx","../src/hooks/useTracer.ts","../src/instrumentations/router.ts"],"names":["ATTR_SERVICE_NAME","ATTR_SERVICE_VERSION","SEMRESATTRS_DEPLOYMENT_ENVIRONMENT","resourceFromAttributes","OTLPTraceExporter","WebTracerProvider","BatchSpanProcessor","OTLPLogExporter","LoggerProvider","BatchLogRecordProcessor","logs","OTLPMetricExporter","MeterProvider","PeriodicExportingMetricReader","metrics","FetchInstrumentation","XMLHttpRequestInstrumentation","DocumentLoadInstrumentation","UserInteractionInstrumentation","registerInstrumentations","SeverityNumber","useRef","useEffect","Component","trace","SpanStatusCode","useMemo","TRACER_NAME"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { WebTracerProvider } from '@opentelemetry/sdk-trace-web';\nimport type { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';\n\n/** Configuration for enabling/disabling specific auto-instrumentations. */\nexport interface InstrumentationConfig {\n /** Auto-instrument fetch() calls. Default: true */\n fetch?: boolean;\n /** Auto-instrument XMLHttpRequest. Default: true */\n xhr?: boolean;\n /** Document load timing spans. Default: true */\n documentLoad?: boolean;\n /** Click/input interaction spans. Default: true */\n userInteraction?: boolean;\n /** LCP, CLS, INP, TTFB, FCP metrics. Default: true */\n webVitals?: boolean;\n}\n\n/** Extension function type for opt-in instrumentations (e.g., withReactRouter). */\nexport type OtelExtension = (context: ExtensionContext) => void;\n\n/** Context provided to extension functions during initialization. */\nexport interface ExtensionContext {\n tracerProvider: WebTracerProvider;\n}\n\n/** Configuration options for initOtel(). */\nexport interface OtelOptions {\n /** Required. Sets the service.name resource attribute. */\n serviceName: string;\n\n /** OTLP HTTP endpoint. Default: 'http://localhost:4318' */\n endpoint?: string;\n\n /** Additional OTel resource attributes. */\n resourceAttributes?: Record<string, string>;\n\n /** Service version. Sets service.version resource attribute. */\n serviceVersion?: string;\n\n /** Deployment environment. Sets deployment.environment resource attribute. */\n environment?: string;\n\n /** Enable/disable specific auto-instrumentations. All enabled by default. */\n instrumentations?: InstrumentationConfig;\n\n /** Escape hatch: configure the TracerProvider before it's registered. */\n configureTracing?: (provider: WebTracerProvider) => void;\n\n /** Escape hatch: configure the OTLP exporter. */\n configureExporter?: (exporter: OTLPTraceExporter) => void;\n\n /** Custom headers sent with OTLP export requests (e.g., auth tokens). */\n headers?: Record<string, string>;\n\n /** Export timeout in milliseconds. Default: 30000 */\n exportTimeout?: number;\n\n /**\n * URLs to exclude from fetch/XHR instrumentation.\n * Supports string patterns or RegExp.\n */\n ignoreUrls?: Array<string | RegExp>;\n\n /**\n * Cross-origin URLs that should receive W3C Trace Context headers\n * (traceparent / tracestate). Required when the frontend calls APIs\n * on a different origin and you want end-to-end distributed traces.\n *\n * @example\n * ```ts\n * propagateTraceHeaderCorsUrls: [/api\\.example\\.com/, 'https://my-backend.local']\n * ```\n */\n propagateTraceHeaderCorsUrls?: Array<string | RegExp>;\n\n /** Extension functions for opt-in instrumentations. */\n extensions?: OtelExtension[];\n}\n\n/** Handle returned from initOtel() for lifecycle management. */\nexport interface OtelHandle {\n /** Flush all pending telemetry and shut down providers. */\n shutdown: () => Promise<void>;\n}\n\nconst DEFAULT_ENDPOINT = 'http://localhost:4318';\nconst DEFAULT_EXPORT_TIMEOUT = 30000;\n\nexport function resolveEndpoint(options: OtelOptions): string {\n return options.endpoint ?? DEFAULT_ENDPOINT;\n}\n\nexport function resolveExportTimeout(options: OtelOptions): number {\n return options.exportTimeout ?? DEFAULT_EXPORT_TIMEOUT;\n}\n\nexport function resolveInstrumentations(options: OtelOptions): Required<InstrumentationConfig> {\n return {\n fetch: options.instrumentations?.fetch ?? true,\n xhr: options.instrumentations?.xhr ?? true,\n documentLoad: options.instrumentations?.documentLoad ?? true,\n userInteraction: options.instrumentations?.userInteraction ?? true,\n webVitals: options.instrumentations?.webVitals ?? true,\n };\n}\n\nexport function validateOptions(options: OtelOptions): void {\n if (!options.serviceName || typeof options.serviceName !== 'string') {\n throw new Error(\n '[@raccoon.ninja/otel-react] serviceName is required and must be a non-empty string.',\n );\n }\n\n if (options.serviceName.trim() !== options.serviceName) {\n throw new Error(\n '[@raccoon.ninja/otel-react] serviceName must not have leading or trailing whitespace.',\n );\n }\n\n if (options.endpoint !== undefined) {\n if (typeof options.endpoint !== 'string' || options.endpoint.trim() === '') {\n throw new Error(\n '[@raccoon.ninja/otel-react] endpoint must be a non-empty string when provided.',\n );\n }\n }\n\n if (options.exportTimeout !== undefined) {\n if (typeof options.exportTimeout !== 'number' || options.exportTimeout <= 0) {\n throw new Error(\n '[@raccoon.ninja/otel-react] exportTimeout must be a positive number when provided.',\n );\n }\n }\n}\n","import { resourceFromAttributes } from '@opentelemetry/resources';\nimport {\n ATTR_SERVICE_NAME,\n ATTR_SERVICE_VERSION,\n SEMRESATTRS_DEPLOYMENT_ENVIRONMENT,\n} from '@opentelemetry/semantic-conventions';\nimport type { OtelOptions } from './options';\n\nconst SDK_NAME = '@raccoon.ninja/otel-react';\n\nexport function buildResource(options: OtelOptions) {\n const attributes: Record<string, string> = {\n [ATTR_SERVICE_NAME]: options.serviceName,\n 'telemetry.sdk.name': SDK_NAME,\n 'telemetry.sdk.version': __SDK_VERSION__,\n 'telemetry.sdk.language': 'webjs',\n };\n\n if (options.serviceVersion) {\n attributes[ATTR_SERVICE_VERSION] = options.serviceVersion;\n }\n\n if (options.environment) {\n attributes[SEMRESATTRS_DEPLOYMENT_ENVIRONMENT] = options.environment;\n }\n\n if (typeof navigator !== 'undefined') {\n if (navigator.language) {\n attributes['browser.language'] = navigator.language;\n }\n if (navigator.userAgent) {\n attributes['browser.user_agent'] = navigator.userAgent;\n }\n if (navigator.platform) {\n attributes['browser.platform'] = navigator.platform;\n }\n }\n\n if (options.resourceAttributes) {\n Object.assign(attributes, options.resourceAttributes);\n }\n\n return resourceFromAttributes(attributes);\n}\n","import { WebTracerProvider } from '@opentelemetry/sdk-trace-web';\nimport { BatchSpanProcessor } from '@opentelemetry/sdk-trace-base';\nimport { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';\nimport type { Resource } from '@opentelemetry/resources';\nimport type { OtelOptions } from '@/core/options';\nimport { resolveEndpoint, resolveExportTimeout } from '@/core/options';\n\nexport interface TracerSetupResult {\n provider: WebTracerProvider;\n exporter: OTLPTraceExporter;\n}\n\nexport function createTracerProvider(options: OtelOptions, resource: Resource): TracerSetupResult {\n const endpoint = resolveEndpoint(options);\n const timeout = resolveExportTimeout(options);\n\n const exporter = new OTLPTraceExporter({\n url: `${endpoint}/v1/traces`,\n headers: options.headers,\n timeoutMillis: timeout,\n });\n\n options.configureExporter?.(exporter);\n\n const provider = new WebTracerProvider({\n resource,\n spanProcessors: [new BatchSpanProcessor(exporter)],\n });\n\n options.configureTracing?.(provider);\n\n provider.register();\n\n return { provider, exporter };\n}\n","import { LoggerProvider, BatchLogRecordProcessor } from '@opentelemetry/sdk-logs';\nimport { OTLPLogExporter } from '@opentelemetry/exporter-logs-otlp-http';\nimport { logs } from '@opentelemetry/api-logs';\nimport type { Resource } from '@opentelemetry/resources';\nimport type { OtelOptions } from '@/core/options';\nimport { resolveEndpoint, resolveExportTimeout } from '@/core/options';\n\nexport function createLoggerProvider(options: OtelOptions, resource: Resource): LoggerProvider {\n const endpoint = resolveEndpoint(options);\n const timeout = resolveExportTimeout(options);\n\n const exporter = new OTLPLogExporter({\n url: `${endpoint}/v1/logs`,\n headers: options.headers,\n timeoutMillis: timeout,\n });\n\n const provider = new LoggerProvider({\n resource,\n processors: [new BatchLogRecordProcessor(exporter)],\n });\n\n logs.setGlobalLoggerProvider(provider);\n\n return provider;\n}\n","import { MeterProvider, PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics';\nimport { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-http';\nimport { metrics } from '@opentelemetry/api';\nimport type { Resource } from '@opentelemetry/resources';\nimport type { OtelOptions } from '../core/options';\nimport { resolveEndpoint, resolveExportTimeout } from '../core/options';\n\nconst METRIC_EXPORT_INTERVAL_MS = 30_000;\n\nexport function createMeterProvider(options: OtelOptions, resource: Resource): MeterProvider {\n const endpoint = resolveEndpoint(options);\n const timeout = resolveExportTimeout(options);\n\n const exporter = new OTLPMetricExporter({\n url: `${endpoint}/v1/metrics`,\n headers: options.headers,\n timeoutMillis: timeout,\n });\n\n const provider = new MeterProvider({\n resource,\n readers: [\n new PeriodicExportingMetricReader({\n exporter,\n exportIntervalMillis: METRIC_EXPORT_INTERVAL_MS,\n }),\n ],\n });\n\n metrics.setGlobalMeterProvider(provider);\n\n return provider;\n}\n","import { registerInstrumentations } from '@opentelemetry/instrumentation';\nimport { FetchInstrumentation } from '@opentelemetry/instrumentation-fetch';\nimport { XMLHttpRequestInstrumentation } from '@opentelemetry/instrumentation-xml-http-request';\nimport { DocumentLoadInstrumentation } from '@opentelemetry/instrumentation-document-load';\nimport { UserInteractionInstrumentation } from '@opentelemetry/instrumentation-user-interaction';\nimport type { InstrumentationConfig, OtelOptions } from '@/core/options';\nimport { resolveInstrumentations, resolveEndpoint } from '@/core/options';\n\nexport function registerAutoInstrumentations(options: OtelOptions): void {\n const config: Required<InstrumentationConfig> = resolveInstrumentations(options);\n\n // Automatically exclude the OTLP collector endpoint from instrumentation\n // to prevent the SDK from tracing its own export requests.\n const endpoint = resolveEndpoint(options);\n const escapedEndpoint = endpoint.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const ignoreUrls: Array<string | RegExp> = [\n ...(options.ignoreUrls ?? []),\n new RegExp(escapedEndpoint),\n ];\n\n const instrumentations = [];\n\n const propagateTraceHeaderCorsUrls = options.propagateTraceHeaderCorsUrls ?? [];\n\n if (config.fetch) {\n instrumentations.push(\n new FetchInstrumentation({\n ignoreUrls,\n propagateTraceHeaderCorsUrls,\n }),\n );\n }\n\n if (config.xhr) {\n instrumentations.push(\n new XMLHttpRequestInstrumentation({\n ignoreUrls,\n propagateTraceHeaderCorsUrls,\n }),\n );\n }\n\n if (config.documentLoad) {\n instrumentations.push(new DocumentLoadInstrumentation());\n }\n\n if (config.userInteraction) {\n instrumentations.push(new UserInteractionInstrumentation());\n }\n\n if (instrumentations.length > 0) {\n registerInstrumentations({ instrumentations });\n }\n}\n","import { metrics } from '@opentelemetry/api';\nimport type { Metric } from 'web-vitals';\n\nconst METER_NAME = '@raccoon.ninja/otel-react/web-vitals';\n\nexport function startWebVitalsCollection(): void {\n const meter = metrics.getMeter(METER_NAME, __SDK_VERSION__);\n\n const lcpHistogram = meter.createHistogram('web_vitals.lcp', {\n description: 'Largest Contentful Paint',\n unit: 'ms',\n });\n\n const clsHistogram = meter.createHistogram('web_vitals.cls', {\n description: 'Cumulative Layout Shift',\n unit: '',\n });\n\n const inpHistogram = meter.createHistogram('web_vitals.inp', {\n description: 'Interaction to Next Paint',\n unit: 'ms',\n });\n\n const ttfbHistogram = meter.createHistogram('web_vitals.ttfb', {\n description: 'Time to First Byte',\n unit: 'ms',\n });\n\n const fcpHistogram = meter.createHistogram('web_vitals.fcp', {\n description: 'First Contentful Paint',\n unit: 'ms',\n });\n\n const recordMetric = (histogram: ReturnType<typeof meter.createHistogram>) => {\n return (metric: Metric) => {\n const attrs: Record<string, string> = {\n 'web_vitals.rating': metric.rating,\n };\n\n if (typeof window !== 'undefined' && window.location) {\n attrs['page.url'] = window.location.pathname;\n }\n\n histogram.record(metric.value, attrs);\n };\n };\n\n // Dynamic import to enable tree-shaking when web-vitals is not used\n import('web-vitals').then(({ onLCP, onCLS, onINP, onTTFB, onFCP }) => {\n onLCP(recordMetric(lcpHistogram));\n onCLS(recordMetric(clsHistogram));\n onINP(recordMetric(inpHistogram));\n onTTFB(recordMetric(ttfbHistogram));\n onFCP(recordMetric(fcpHistogram));\n });\n}\n","import type { WebTracerProvider } from '@opentelemetry/sdk-trace-web';\nimport type { LoggerProvider } from '@opentelemetry/sdk-logs';\nimport type { MeterProvider } from '@opentelemetry/sdk-metrics';\n\nexport interface ShutdownTargets {\n tracerProvider: WebTracerProvider;\n loggerProvider: LoggerProvider;\n meterProvider: MeterProvider;\n}\n\nlet shutdownTargets: ShutdownTargets | null = null;\nlet visibilityHandler: (() => void) | null = null;\nlet beforeUnloadHandler: (() => void) | null = null;\n\nexport function registerShutdownTargets(targets: ShutdownTargets): void {\n shutdownTargets = targets;\n\n visibilityHandler = () => {\n if (document.visibilityState === 'hidden') {\n flushAll();\n }\n };\n\n beforeUnloadHandler = () => {\n flushAll();\n };\n\n if (typeof document !== 'undefined') {\n document.addEventListener('visibilitychange', visibilityHandler);\n }\n if (typeof window !== 'undefined') {\n window.addEventListener('beforeunload', beforeUnloadHandler);\n }\n}\n\nfunction flushAll(): void {\n if (!shutdownTargets) return;\n\n try {\n shutdownTargets.tracerProvider.forceFlush();\n shutdownTargets.loggerProvider.forceFlush();\n shutdownTargets.meterProvider.forceFlush();\n } catch {\n // Flush is best-effort during page unload\n }\n}\n\nexport async function shutdown(): Promise<void> {\n if (!shutdownTargets) return;\n\n if (typeof document !== 'undefined' && visibilityHandler) {\n document.removeEventListener('visibilitychange', visibilityHandler);\n }\n if (typeof window !== 'undefined' && beforeUnloadHandler) {\n window.removeEventListener('beforeunload', beforeUnloadHandler);\n }\n\n try {\n await Promise.all([\n shutdownTargets.tracerProvider.forceFlush(),\n shutdownTargets.loggerProvider.forceFlush(),\n shutdownTargets.meterProvider.forceFlush(),\n ]);\n\n await Promise.all([\n shutdownTargets.tracerProvider.shutdown(),\n shutdownTargets.loggerProvider.shutdown(),\n shutdownTargets.meterProvider.shutdown(),\n ]);\n } finally {\n shutdownTargets = null;\n visibilityHandler = null;\n beforeUnloadHandler = null;\n }\n}\n","import { SeverityNumber } from '@opentelemetry/api-logs';\nimport type { OtelOptions, OtelHandle } from './options';\nimport { validateOptions, resolveInstrumentations } from './options';\nimport { buildResource } from './resource';\nimport { createTracerProvider } from '../providers/tracer';\nimport { createLoggerProvider } from '../providers/logger';\nimport { createMeterProvider } from '../providers/meter';\nimport { registerAutoInstrumentations } from '../instrumentations/auto';\nimport { startWebVitalsCollection } from '../instrumentations/web-vitals';\nimport { registerShutdownTargets, shutdown } from './shutdown';\n\nlet initialized = false;\n\nexport function initOtel(options: OtelOptions): OtelHandle {\n if (initialized) {\n console.warn(\n '[@raccoon.ninja/otel-react] initOtel() has already been called. Skipping re-initialization.',\n );\n return { shutdown };\n }\n\n validateOptions(options);\n\n const resource = buildResource(options);\n const { provider: tracerProvider } = createTracerProvider(options, resource);\n const loggerProvider = createLoggerProvider(options, resource);\n const meterProvider = createMeterProvider(options, resource);\n\n registerAutoInstrumentations(options);\n\n const instrumentationConfig = resolveInstrumentations(options);\n if (instrumentationConfig.webVitals) {\n startWebVitalsCollection();\n }\n\n registerShutdownTargets({ tracerProvider, loggerProvider, meterProvider });\n\n // Run extensions\n if (options.extensions) {\n for (const ext of options.extensions) {\n ext({ tracerProvider });\n }\n }\n\n // Log initialization success\n const logger = loggerProvider.getLogger('@raccoon.ninja/otel-react', __SDK_VERSION__);\n logger.emit({\n severityNumber: SeverityNumber.INFO,\n severityText: 'INFO',\n body: `OpenTelemetry initialized for service \"${options.serviceName}\"`,\n attributes: {\n 'otel.service_name': options.serviceName,\n },\n });\n\n initialized = true;\n\n return {\n shutdown: async () => {\n await shutdown();\n initialized = false;\n },\n };\n}\n\n/** Reset initialization state (for testing). */\nexport function _resetInitState(): void {\n initialized = false;\n}\n","import { useEffect, useRef, type ReactNode } from 'react';\nimport { initOtel } from '../core/init';\nimport type { OtelOptions, OtelHandle, OtelExtension } from '../core/options';\n\n/** Props for the OtelProvider component. */\nexport interface OtelProviderProps {\n /** Required. Sets the service.name resource attribute. */\n serviceName: string;\n /** OTLP HTTP endpoint. Default: 'http://localhost:4318' */\n endpoint?: string;\n /** Additional OTel resource attributes. */\n resourceAttributes?: Record<string, string>;\n /** Service version. */\n serviceVersion?: string;\n /** Deployment environment. */\n environment?: string;\n /** Enable/disable specific auto-instrumentations. */\n instrumentations?: OtelOptions['instrumentations'];\n /** Custom headers sent with OTLP export requests. */\n headers?: Record<string, string>;\n /** Export timeout in milliseconds. */\n exportTimeout?: number;\n /** URLs to exclude from fetch/XHR instrumentation. */\n ignoreUrls?: Array<string | RegExp>;\n /** Cross-origin URLs that should receive W3C Trace Context headers. */\n propagateTraceHeaderCorsUrls?: Array<string | RegExp>;\n /** Escape hatch: configure the TracerProvider. */\n configureTracing?: OtelOptions['configureTracing'];\n /** Escape hatch: configure the OTLP exporter. */\n configureExporter?: OtelOptions['configureExporter'];\n /** Extension functions for opt-in instrumentations. */\n extensions?: OtelExtension[];\n /** React children to render. */\n children: ReactNode;\n}\n\n/**\n * React Provider component that initializes OpenTelemetry on mount\n * and flushes/shuts down on unmount.\n *\n * @example\n * ```tsx\n * import { OtelProvider } from '@raccoon.ninja/otel-react';\n *\n * function App() {\n * return (\n * <OtelProvider serviceName=\"my-app\">\n * <RestOfTheApp />\n * </OtelProvider>\n * );\n * }\n * ```\n */\nexport function OtelProvider({\n children,\n serviceName,\n endpoint,\n resourceAttributes,\n serviceVersion,\n environment,\n instrumentations,\n headers,\n exportTimeout,\n ignoreUrls,\n propagateTraceHeaderCorsUrls,\n configureTracing,\n configureExporter,\n extensions,\n}: OtelProviderProps) {\n const handleRef = useRef<OtelHandle | null>(null);\n\n useEffect(() => {\n const handle = initOtel({\n serviceName,\n endpoint,\n resourceAttributes,\n serviceVersion,\n environment,\n instrumentations,\n headers,\n exportTimeout,\n ignoreUrls,\n propagateTraceHeaderCorsUrls,\n configureTracing,\n configureExporter,\n extensions,\n });\n\n handleRef.current = handle;\n\n return () => {\n handleRef.current?.shutdown();\n handleRef.current = null;\n };\n // We intentionally only run this on mount/unmount.\n // Config changes require remounting the provider.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n return <>{children}</>;\n}\n","import { Component, type ReactNode, type ErrorInfo } from 'react';\nimport { trace, SpanStatusCode } from '@opentelemetry/api';\nimport { SeverityNumber } from '@opentelemetry/api-logs';\nimport { logs } from '@opentelemetry/api-logs';\n\nconst TRACER_NAME = '@raccoon.ninja/otel-react/error-boundary';\nconst LOGGER_NAME = '@raccoon.ninja/otel-react/error-boundary';\n\n/** Props for the TracedErrorBoundary component. */\nexport interface TracedErrorBoundaryProps {\n /** Fallback UI to render when an error is caught. */\n fallback: ReactNode | ((error: Error, reset: () => void) => ReactNode);\n /** Optional callback when an error is caught. */\n onError?: (error: Error, errorInfo: ErrorInfo) => void;\n /** Children to render. */\n children: ReactNode;\n}\n\ninterface TracedErrorBoundaryState {\n hasError: boolean;\n error: Error | null;\n}\n\n/**\n * Error boundary that records caught errors as OpenTelemetry spans and logs.\n *\n * @example\n * ```tsx\n * import { TracedErrorBoundary } from '@raccoon.ninja/otel-react';\n *\n * <TracedErrorBoundary fallback={<ErrorPage />}>\n * <RiskyComponent />\n * </TracedErrorBoundary>\n * ```\n */\nexport class TracedErrorBoundary extends Component<\n TracedErrorBoundaryProps,\n TracedErrorBoundaryState\n> {\n constructor(props: TracedErrorBoundaryProps) {\n super(props);\n this.state = { hasError: false, error: null };\n }\n\n static getDerivedStateFromError(error: Error): TracedErrorBoundaryState {\n return { hasError: true, error };\n }\n\n componentDidCatch(error: Error, errorInfo: ErrorInfo): void {\n const tracer = trace.getTracer(TRACER_NAME, __SDK_VERSION__);\n const span = tracer.startSpan('error-boundary.catch');\n\n span.setStatus({ code: SpanStatusCode.ERROR, message: error.message });\n span.setAttribute('error.type', error.name);\n span.setAttribute('error.message', error.message);\n\n if (error.stack) {\n span.setAttribute('error.stack', error.stack);\n }\n if (errorInfo.componentStack) {\n span.setAttribute('error.component_stack', errorInfo.componentStack);\n }\n\n span.recordException(error);\n span.end();\n\n // Also emit as a log record\n try {\n const logger = logs.getLogger(LOGGER_NAME, __SDK_VERSION__);\n logger.emit({\n severityNumber: SeverityNumber.ERROR,\n severityText: 'ERROR',\n body: `Unhandled error: ${error.message}`,\n attributes: {\n 'error.type': error.name,\n 'error.message': error.message,\n ...(error.stack ? { 'error.stack': error.stack } : {}),\n ...(errorInfo.componentStack\n ? { 'error.component_stack': errorInfo.componentStack }\n : {}),\n },\n });\n } catch {\n // Logging is best-effort\n }\n\n this.props.onError?.(error, errorInfo);\n }\n\n private reset = () => {\n this.setState({ hasError: false, error: null });\n };\n\n render() {\n if (this.state.hasError && this.state.error) {\n const { fallback } = this.props;\n if (typeof fallback === 'function') {\n return fallback(this.state.error, this.reset);\n }\n return fallback;\n }\n\n return this.props.children;\n }\n}\n","import { useMemo } from 'react';\nimport { trace, type Tracer } from '@opentelemetry/api';\n\nconst DEFAULT_TRACER_NAME = '@raccoon.ninja/otel-react/custom';\n\n/**\n * Hook to get an OpenTelemetry Tracer for creating custom spans.\n *\n * @param name - Optional tracer name. Defaults to '@raccoon.ninja/otel-react/custom'.\n * @param version - Optional tracer version.\n * @returns An OTel Tracer instance.\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * const tracer = useTracer();\n *\n * const handleClick = () => {\n * const span = tracer.startSpan('button-click');\n * // ... do work ...\n * span.end();\n * };\n * }\n * ```\n */\nexport function useTracer(name?: string, version?: string): Tracer {\n return useMemo(() => trace.getTracer(name ?? DEFAULT_TRACER_NAME, version), [name, version]);\n}\n","import { trace } from '@opentelemetry/api';\nimport type { OtelExtension, ExtensionContext } from '../core/options';\n\nconst TRACER_NAME = '@raccoon.ninja/otel-react/router';\n\n/**\n * Extension for React Router v6/v7 route-change tracing.\n *\n * Usage:\n * ```tsx\n * import { OtelProvider, withReactRouter } from '@raccoon.ninja/otel-react';\n *\n * <OtelProvider serviceName=\"my-app\" extensions={[withReactRouter()]}>\n * <App />\n * </OtelProvider>\n * ```\n *\n * Note: The actual hook-based integration should be used inside\n * a component that has access to React Router's context. This extension\n * registers the tracer scope for route-change spans.\n */\nexport function withReactRouter(): OtelExtension {\n return (_context: ExtensionContext) => {\n // Pre-register the tracer scope so route spans are properly attributed\n trace.getTracer(TRACER_NAME, __SDK_VERSION__);\n };\n}\n\n/** Tracer name for route-change spans, exported for use in hooks. */\nexport const ROUTER_TRACER_NAME = TRACER_NAME;\n"]}
package/dist/index.d.mts CHANGED
@@ -50,6 +50,17 @@ interface OtelOptions {
50
50
  * Supports string patterns or RegExp.
51
51
  */
52
52
  ignoreUrls?: Array<string | RegExp>;
53
+ /**
54
+ * Cross-origin URLs that should receive W3C Trace Context headers
55
+ * (traceparent / tracestate). Required when the frontend calls APIs
56
+ * on a different origin and you want end-to-end distributed traces.
57
+ *
58
+ * @example
59
+ * ```ts
60
+ * propagateTraceHeaderCorsUrls: [/api\.example\.com/, 'https://my-backend.local']
61
+ * ```
62
+ */
63
+ propagateTraceHeaderCorsUrls?: Array<string | RegExp>;
53
64
  /** Extension functions for opt-in instrumentations. */
54
65
  extensions?: OtelExtension[];
55
66
  }
@@ -81,6 +92,8 @@ interface OtelProviderProps {
81
92
  exportTimeout?: number;
82
93
  /** URLs to exclude from fetch/XHR instrumentation. */
83
94
  ignoreUrls?: Array<string | RegExp>;
95
+ /** Cross-origin URLs that should receive W3C Trace Context headers. */
96
+ propagateTraceHeaderCorsUrls?: Array<string | RegExp>;
84
97
  /** Escape hatch: configure the TracerProvider. */
85
98
  configureTracing?: OtelOptions['configureTracing'];
86
99
  /** Escape hatch: configure the OTLP exporter. */
@@ -107,7 +120,7 @@ interface OtelProviderProps {
107
120
  * }
108
121
  * ```
109
122
  */
110
- declare function OtelProvider({ children, serviceName, endpoint, resourceAttributes, serviceVersion, environment, instrumentations, headers, exportTimeout, ignoreUrls, configureTracing, configureExporter, extensions, }: OtelProviderProps): react_jsx_runtime.JSX.Element;
123
+ declare function OtelProvider({ children, serviceName, endpoint, resourceAttributes, serviceVersion, environment, instrumentations, headers, exportTimeout, ignoreUrls, propagateTraceHeaderCorsUrls, configureTracing, configureExporter, extensions, }: OtelProviderProps): react_jsx_runtime.JSX.Element;
111
124
 
112
125
  /** Props for the TracedErrorBoundary component. */
113
126
  interface TracedErrorBoundaryProps {
package/dist/index.d.ts CHANGED
@@ -50,6 +50,17 @@ interface OtelOptions {
50
50
  * Supports string patterns or RegExp.
51
51
  */
52
52
  ignoreUrls?: Array<string | RegExp>;
53
+ /**
54
+ * Cross-origin URLs that should receive W3C Trace Context headers
55
+ * (traceparent / tracestate). Required when the frontend calls APIs
56
+ * on a different origin and you want end-to-end distributed traces.
57
+ *
58
+ * @example
59
+ * ```ts
60
+ * propagateTraceHeaderCorsUrls: [/api\.example\.com/, 'https://my-backend.local']
61
+ * ```
62
+ */
63
+ propagateTraceHeaderCorsUrls?: Array<string | RegExp>;
53
64
  /** Extension functions for opt-in instrumentations. */
54
65
  extensions?: OtelExtension[];
55
66
  }
@@ -81,6 +92,8 @@ interface OtelProviderProps {
81
92
  exportTimeout?: number;
82
93
  /** URLs to exclude from fetch/XHR instrumentation. */
83
94
  ignoreUrls?: Array<string | RegExp>;
95
+ /** Cross-origin URLs that should receive W3C Trace Context headers. */
96
+ propagateTraceHeaderCorsUrls?: Array<string | RegExp>;
84
97
  /** Escape hatch: configure the TracerProvider. */
85
98
  configureTracing?: OtelOptions['configureTracing'];
86
99
  /** Escape hatch: configure the OTLP exporter. */
@@ -107,7 +120,7 @@ interface OtelProviderProps {
107
120
  * }
108
121
  * ```
109
122
  */
110
- declare function OtelProvider({ children, serviceName, endpoint, resourceAttributes, serviceVersion, environment, instrumentations, headers, exportTimeout, ignoreUrls, configureTracing, configureExporter, extensions, }: OtelProviderProps): react_jsx_runtime.JSX.Element;
123
+ declare function OtelProvider({ children, serviceName, endpoint, resourceAttributes, serviceVersion, environment, instrumentations, headers, exportTimeout, ignoreUrls, propagateTraceHeaderCorsUrls, configureTracing, configureExporter, extensions, }: OtelProviderProps): react_jsx_runtime.JSX.Element;
111
124
 
112
125
  /** Props for the TracedErrorBoundary component. */
113
126
  interface TracedErrorBoundaryProps {
package/dist/index.mjs CHANGED
@@ -64,12 +64,11 @@ function validateOptions(options) {
64
64
  }
65
65
  }
66
66
  var SDK_NAME = "@raccoon.ninja/otel-react";
67
- var SDK_VERSION = "1.0.0";
68
67
  function buildResource(options) {
69
68
  const attributes = {
70
69
  [ATTR_SERVICE_NAME]: options.serviceName,
71
70
  "telemetry.sdk.name": SDK_NAME,
72
- "telemetry.sdk.version": SDK_VERSION,
71
+ "telemetry.sdk.version": "1.2.0-rc.1",
73
72
  "telemetry.sdk.language": "webjs"
74
73
  };
75
74
  if (options.serviceVersion) {
@@ -119,8 +118,10 @@ function createLoggerProvider(options, resource) {
119
118
  headers: options.headers,
120
119
  timeoutMillis: timeout
121
120
  });
122
- const provider = new LoggerProvider({ resource });
123
- provider.addLogRecordProcessor(new BatchLogRecordProcessor(exporter));
121
+ const provider = new LoggerProvider({
122
+ resource,
123
+ processors: [new BatchLogRecordProcessor(exporter)]
124
+ });
124
125
  logs.setGlobalLoggerProvider(provider);
125
126
  return provider;
126
127
  }
@@ -147,19 +148,27 @@ function createMeterProvider(options, resource) {
147
148
  }
148
149
  function registerAutoInstrumentations(options) {
149
150
  const config = resolveInstrumentations(options);
150
- const ignoreUrls = options.ignoreUrls ?? [];
151
+ const endpoint = resolveEndpoint(options);
152
+ const escapedEndpoint = endpoint.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
153
+ const ignoreUrls = [
154
+ ...options.ignoreUrls ?? [],
155
+ new RegExp(escapedEndpoint)
156
+ ];
151
157
  const instrumentations = [];
158
+ const propagateTraceHeaderCorsUrls = options.propagateTraceHeaderCorsUrls ?? [];
152
159
  if (config.fetch) {
153
160
  instrumentations.push(
154
161
  new FetchInstrumentation({
155
- ignoreUrls
162
+ ignoreUrls,
163
+ propagateTraceHeaderCorsUrls
156
164
  })
157
165
  );
158
166
  }
159
167
  if (config.xhr) {
160
168
  instrumentations.push(
161
169
  new XMLHttpRequestInstrumentation({
162
- ignoreUrls
170
+ ignoreUrls,
171
+ propagateTraceHeaderCorsUrls
163
172
  })
164
173
  );
165
174
  }
@@ -175,7 +184,7 @@ function registerAutoInstrumentations(options) {
175
184
  }
176
185
  var METER_NAME = "@raccoon.ninja/otel-react/web-vitals";
177
186
  function startWebVitalsCollection() {
178
- const meter = metrics.getMeter(METER_NAME, "1.0.0");
187
+ const meter = metrics.getMeter(METER_NAME, "1.2.0-rc.1");
179
188
  const lcpHistogram = meter.createHistogram("web_vitals.lcp", {
180
189
  description: "Largest Contentful Paint",
181
190
  unit: "ms"
@@ -297,7 +306,7 @@ function initOtel(options) {
297
306
  ext({ tracerProvider });
298
307
  }
299
308
  }
300
- const logger = loggerProvider.getLogger("@raccoon.ninja/otel-react", "1.0.0");
309
+ const logger = loggerProvider.getLogger("@raccoon.ninja/otel-react", "1.2.0-rc.1");
301
310
  logger.emit({
302
311
  severityNumber: SeverityNumber.INFO,
303
312
  severityText: "INFO",
@@ -325,6 +334,7 @@ function OtelProvider({
325
334
  headers,
326
335
  exportTimeout,
327
336
  ignoreUrls,
337
+ propagateTraceHeaderCorsUrls,
328
338
  configureTracing,
329
339
  configureExporter,
330
340
  extensions
@@ -341,6 +351,7 @@ function OtelProvider({
341
351
  headers,
342
352
  exportTimeout,
343
353
  ignoreUrls,
354
+ propagateTraceHeaderCorsUrls,
344
355
  configureTracing,
345
356
  configureExporter,
346
357
  extensions
@@ -364,7 +375,7 @@ var TracedErrorBoundary = class extends Component {
364
375
  return { hasError: true, error };
365
376
  }
366
377
  componentDidCatch(error, errorInfo) {
367
- const tracer = trace.getTracer(TRACER_NAME, "1.0.0");
378
+ const tracer = trace.getTracer(TRACER_NAME, "1.2.0-rc.1");
368
379
  const span = tracer.startSpan("error-boundary.catch");
369
380
  span.setStatus({ code: SpanStatusCode.ERROR, message: error.message });
370
381
  span.setAttribute("error.type", error.name);
@@ -378,7 +389,7 @@ var TracedErrorBoundary = class extends Component {
378
389
  span.recordException(error);
379
390
  span.end();
380
391
  try {
381
- const logger = logs.getLogger(LOGGER_NAME, "1.0.0");
392
+ const logger = logs.getLogger(LOGGER_NAME, "1.2.0-rc.1");
382
393
  logger.emit({
383
394
  severityNumber: SeverityNumber.ERROR,
384
395
  severityText: "ERROR",
@@ -415,7 +426,7 @@ function useTracer(name, version) {
415
426
  var TRACER_NAME2 = "@raccoon.ninja/otel-react/router";
416
427
  function withReactRouter() {
417
428
  return (_context) => {
418
- trace.getTracer(TRACER_NAME2, "1.0.0");
429
+ trace.getTracer(TRACER_NAME2, "1.2.0-rc.1");
419
430
  };
420
431
  }
421
432