@raccoon.ninja/otel-react 0.0.1 → 0.0.2

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.

Potentially problematic release.


This version of @raccoon.ninja/otel-react might be problematic. Click here for more details.

package/README.md CHANGED
@@ -53,20 +53,20 @@ 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
+ | `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 |
70
70
 
71
71
  ### Pointing to a Collector
72
72
 
@@ -86,11 +86,11 @@ All telemetry is sent to `http://localhost:4318` by default (the standard OTLP H
86
86
  <OtelProvider
87
87
  serviceName="my-app"
88
88
  instrumentations={{
89
- fetch: true, // default: true
90
- xhr: false, // disable XHR instrumentation
91
- documentLoad: true, // default: true
89
+ fetch: true, // default: true
90
+ xhr: false, // disable XHR instrumentation
91
+ documentLoad: true, // default: true
92
92
  userInteraction: false, // disable click tracking
93
- webVitals: true, // default: true
93
+ webVitals: true, // default: true
94
94
  }}
95
95
  >
96
96
  <App />
@@ -104,11 +104,7 @@ Useful for health checks, analytics endpoints, or any URL that shouldn't generat
104
104
  ```tsx
105
105
  <OtelProvider
106
106
  serviceName="my-app"
107
- ignoreUrls={[
108
- /\/health$/,
109
- /\/analytics/,
110
- 'https://cdn.example.com',
111
- ]}
107
+ ignoreUrls={[/\/health$/, /\/analytics/, 'https://cdn.example.com']}
112
108
  >
113
109
  <App />
114
110
  </OtelProvider>
@@ -170,6 +166,7 @@ The fallback can also be a render function that receives the error and a reset c
170
166
  ```
171
167
 
172
168
  Each caught error generates:
169
+
173
170
  - A span with `error.type`, `error.message`, `error.stack`, and `error.component_stack` attributes
174
171
  - A log record at `ERROR` severity with the same details
175
172
 
@@ -220,10 +217,7 @@ import { OtelProvider, withReactRouter } from '@raccoon.ninja/otel-react';
220
217
 
221
218
  function App() {
222
219
  return (
223
- <OtelProvider
224
- serviceName="my-app"
225
- extensions={[withReactRouter()]}
226
- >
220
+ <OtelProvider serviceName="my-app" extensions={[withReactRouter()]}>
227
221
  <RouterProvider router={router} />
228
222
  </OtelProvider>
229
223
  );
@@ -234,38 +228,38 @@ function App() {
234
228
 
235
229
  ### Traces (Automatic)
236
230
 
237
- | Signal | Source | What It Captures |
238
- |--------|--------|-----------------|
239
- | `fetch()` calls | `@opentelemetry/instrumentation-fetch` | URL, method, status, duration |
240
- | `XMLHttpRequest` | `@opentelemetry/instrumentation-xml-http-request` | URL, method, status, duration |
241
- | Document load | `@opentelemetry/instrumentation-document-load` | DNS, TCP, TLS, DOM processing |
242
- | User interactions | `@opentelemetry/instrumentation-user-interaction` | Click events on DOM elements |
243
- | Error boundary | `TracedErrorBoundary` | Uncaught errors with component stack |
231
+ | Signal | Source | What It Captures |
232
+ | ----------------- | ------------------------------------------------- | ------------------------------------ |
233
+ | `fetch()` calls | `@opentelemetry/instrumentation-fetch` | URL, method, status, duration |
234
+ | `XMLHttpRequest` | `@opentelemetry/instrumentation-xml-http-request` | URL, method, status, duration |
235
+ | Document load | `@opentelemetry/instrumentation-document-load` | DNS, TCP, TLS, DOM processing |
236
+ | User interactions | `@opentelemetry/instrumentation-user-interaction` | Click events on DOM elements |
237
+ | Error boundary | `TracedErrorBoundary` | Uncaught errors with component stack |
244
238
 
245
239
  ### Metrics (Automatic)
246
240
 
247
- | Metric | Type | Description |
248
- |--------|------|-------------|
249
- | `web_vitals.lcp` | Histogram | Largest Contentful Paint (ms) |
250
- | `web_vitals.cls` | Histogram | Cumulative Layout Shift |
251
- | `web_vitals.inp` | Histogram | Interaction to Next Paint (ms) |
252
- | `web_vitals.ttfb` | Histogram | Time to First Byte (ms) |
253
- | `web_vitals.fcp` | Histogram | First Contentful Paint (ms) |
241
+ | Metric | Type | Description |
242
+ | ----------------- | --------- | ------------------------------ |
243
+ | `web_vitals.lcp` | Histogram | Largest Contentful Paint (ms) |
244
+ | `web_vitals.cls` | Histogram | Cumulative Layout Shift |
245
+ | `web_vitals.inp` | Histogram | Interaction to Next Paint (ms) |
246
+ | `web_vitals.ttfb` | Histogram | Time to First Byte (ms) |
247
+ | `web_vitals.fcp` | Histogram | First Contentful Paint (ms) |
254
248
 
255
249
  Each metric includes `web_vitals.rating` (`good`, `needs-improvement`, `poor`) and `page.url` attributes.
256
250
 
257
251
  ### Resource Attributes (Automatic)
258
252
 
259
- | Attribute | Source |
260
- |-----------|--------|
261
- | `service.name` | Config (required) |
262
- | `service.version` | Config (optional) |
263
- | `deployment.environment` | Config (optional) |
264
- | `telemetry.sdk.name` | `@raccoon.ninja/otel-react` |
265
- | `telemetry.sdk.version` | Package version |
266
- | `browser.language` | `navigator.language` |
267
- | `browser.user_agent` | `navigator.userAgent` |
268
- | `browser.platform` | `navigator.platform` |
253
+ | Attribute | Source |
254
+ | ------------------------ | --------------------------- |
255
+ | `service.name` | Config (required) |
256
+ | `service.version` | Config (optional) |
257
+ | `deployment.environment` | Config (optional) |
258
+ | `telemetry.sdk.name` | `@raccoon.ninja/otel-react` |
259
+ | `telemetry.sdk.version` | Package version |
260
+ | `browser.language` | `navigator.language` |
261
+ | `browser.user_agent` | `navigator.userAgent` |
262
+ | `browser.platform` | `navigator.platform` |
269
263
 
270
264
  Custom attributes can be added via the `resourceAttributes` prop.
271
265
 
@@ -283,6 +277,7 @@ const otel = await initOtel({
283
277
  ```
284
278
 
285
279
  Key differences from the browser entry:
280
+
286
281
  - Uses `BasicTracerProvider` instead of `WebTracerProvider` (no DOM APIs)
287
282
  - Only `fetch` instrumentation is enabled (no document load, user interaction, or Web Vitals)
288
283
  - XHR is disabled by default to avoid duplicate spans (React Native's `fetch` polyfills over XHR)
@@ -337,11 +332,7 @@ export async function register() {
337
332
  import { OtelProvider } from '@raccoon.ninja/otel-react';
338
333
 
339
334
  export function Providers({ children }: { children: React.ReactNode }) {
340
- return (
341
- <OtelProvider serviceName="my-nextjs-app">
342
- {children}
343
- </OtelProvider>
344
- );
335
+ return <OtelProvider serviceName="my-nextjs-app">{children}</OtelProvider>;
345
336
  }
346
337
 
347
338
  // app/layout.tsx
@@ -371,11 +362,11 @@ receivers:
371
362
  endpoint: 0.0.0.0:4318
372
363
  cors:
373
364
  allowed_origins:
374
- - "https://your-app.com"
375
- - "http://localhost:3000"
365
+ - 'https://your-app.com'
366
+ - 'http://localhost:3000'
376
367
  allowed_headers:
377
- - "Content-Type"
378
- - "X-Requested-With"
368
+ - 'Content-Type'
369
+ - 'X-Requested-With'
379
370
  max_age: 7200
380
371
  ```
381
372
 
@@ -394,32 +385,32 @@ This ensures telemetry is not lost during page navigation or tab close.
394
385
 
395
386
  ### Exports from `@raccoon.ninja/otel-react`
396
387
 
397
- | Export | Type | Description |
398
- |--------|------|-------------|
399
- | `OtelProvider` | Component | React provider that initializes OTel on mount |
400
- | `TracedErrorBoundary` | Component | Error boundary that records errors as spans/logs |
401
- | `initOtel` | Function | Imperative initialization, returns `OtelHandle` |
402
- | `useTracer` | Hook | Get an OTel `Tracer` for custom spans |
403
- | `withReactRouter` | Function | Extension for React Router route tracing |
404
- | `OtelOptions` | Type | Configuration interface |
405
- | `OtelHandle` | Type | Handle with `shutdown()` method |
406
- | `OtelExtension` | Type | Extension function signature |
407
- | `InstrumentationConfig` | Type | Instrumentation toggle config |
408
- | `OtelProviderProps` | Type | Props for `<OtelProvider>` |
409
- | `TracedErrorBoundaryProps` | Type | Props for `<TracedErrorBoundary>` |
388
+ | Export | Type | Description |
389
+ | -------------------------- | --------- | ------------------------------------------------ |
390
+ | `OtelProvider` | Component | React provider that initializes OTel on mount |
391
+ | `TracedErrorBoundary` | Component | Error boundary that records errors as spans/logs |
392
+ | `initOtel` | Function | Imperative initialization, returns `OtelHandle` |
393
+ | `useTracer` | Hook | Get an OTel `Tracer` for custom spans |
394
+ | `withReactRouter` | Function | Extension for React Router route tracing |
395
+ | `OtelOptions` | Type | Configuration interface |
396
+ | `OtelHandle` | Type | Handle with `shutdown()` method |
397
+ | `OtelExtension` | Type | Extension function signature |
398
+ | `InstrumentationConfig` | Type | Instrumentation toggle config |
399
+ | `OtelProviderProps` | Type | Props for `<OtelProvider>` |
400
+ | `TracedErrorBoundaryProps` | Type | Props for `<TracedErrorBoundary>` |
410
401
 
411
402
  ### Exports from `@raccoon.ninja/otel-react/native`
412
403
 
413
- | Export | Type | Description |
414
- |--------|------|-------------|
415
- | `initOtel` | Function | RN-specific initialization (async) |
416
- | `withReactNavigation` | Function | Extension for React Navigation |
417
- | `createNavigationTracker` | Function | Creates `onStateChange` handler |
404
+ | Export | Type | Description |
405
+ | ------------------------- | -------- | ---------------------------------- |
406
+ | `initOtel` | Function | RN-specific initialization (async) |
407
+ | `withReactNavigation` | Function | Extension for React Navigation |
408
+ | `createNavigationTracker` | Function | Creates `onStateChange` handler |
418
409
 
419
410
  ### Exports from `@raccoon.ninja/otel-react/nextjs`
420
411
 
421
- | Export | Type | Description |
422
- |--------|------|-------------|
412
+ | Export | Type | Description |
413
+ | ---------------- | -------- | --------------------------------------------------- |
423
414
  | `initOtelServer` | Function | Server-side initialization for `instrumentation.ts` |
424
415
 
425
416
  ## Requirements
package/dist/index.cjs CHANGED
@@ -66,7 +66,7 @@ function validateOptions(options) {
66
66
  }
67
67
  }
68
68
  var SDK_NAME = "@raccoon.ninja/otel-react";
69
- var SDK_VERSION = "0.0.1";
69
+ var SDK_VERSION = "0.0.2";
70
70
  function buildResource(options) {
71
71
  const attributes = {
72
72
  [semanticConventions.ATTR_SERVICE_NAME]: options.serviceName,
@@ -412,10 +412,7 @@ var TracedErrorBoundary = class extends react.Component {
412
412
  };
413
413
  var DEFAULT_TRACER_NAME = "@raccoon.ninja/otel-react/custom";
414
414
  function useTracer(name, version) {
415
- return react.useMemo(
416
- () => api.trace.getTracer(name ?? DEFAULT_TRACER_NAME, version),
417
- [name, version]
418
- );
415
+ return react.useMemo(() => api.trace.getTracer(name ?? DEFAULT_TRACER_NAME, version), [name, version]);
419
416
  }
420
417
  var TRACER_NAME2 = "@raccoon.ninja/otel-react/router";
421
418
  function withReactRouter() {
@@ -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 = '0.0.1';\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(\n () => trace.getTracer(name ?? DEFAULT_TRACER_NAME, version),\n [name, version],\n );\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 /** 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 = '0.0.2';\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"]}
package/dist/index.mjs CHANGED
@@ -64,7 +64,7 @@ function validateOptions(options) {
64
64
  }
65
65
  }
66
66
  var SDK_NAME = "@raccoon.ninja/otel-react";
67
- var SDK_VERSION = "0.0.1";
67
+ var SDK_VERSION = "0.0.2";
68
68
  function buildResource(options) {
69
69
  const attributes = {
70
70
  [ATTR_SERVICE_NAME]: options.serviceName,
@@ -410,10 +410,7 @@ var TracedErrorBoundary = class extends Component {
410
410
  };
411
411
  var DEFAULT_TRACER_NAME = "@raccoon.ninja/otel-react/custom";
412
412
  function useTracer(name, version) {
413
- return useMemo(
414
- () => trace.getTracer(name ?? DEFAULT_TRACER_NAME, version),
415
- [name, version]
416
- );
413
+ return useMemo(() => trace.getTracer(name ?? DEFAULT_TRACER_NAME, version), [name, version]);
417
414
  }
418
415
  var TRACER_NAME2 = "@raccoon.ninja/otel-react/router";
419
416
  function withReactRouter() {
@@ -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":["metrics","logs","SeverityNumber","trace","TRACER_NAME"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAyEA,IAAM,gBAAA,GAAmB,uBAAA;AACzB,IAAM,sBAAA,GAAyB,GAAA;AAExB,SAAS,gBAAgB,OAAA,EAA8B;AAC5D,EAAA,OAAO,QAAQ,QAAA,IAAY,gBAAA;AAC7B;AAEO,SAAS,qBAAqB,OAAA,EAA8B;AACjE,EAAA,OAAO,QAAQ,aAAA,IAAiB,sBAAA;AAClC;AAEO,SAAS,wBAAwB,OAAA,EAAuD;AAC7F,EAAA,OAAO;AAAA,IACL,KAAA,EAAO,OAAA,CAAQ,gBAAA,EAAkB,KAAA,IAAS,IAAA;AAAA,IAC1C,GAAA,EAAK,OAAA,CAAQ,gBAAA,EAAkB,GAAA,IAAO,IAAA;AAAA,IACtC,YAAA,EAAc,OAAA,CAAQ,gBAAA,EAAkB,YAAA,IAAgB,IAAA;AAAA,IACxD,eAAA,EAAiB,OAAA,CAAQ,gBAAA,EAAkB,eAAA,IAAmB,IAAA;AAAA,IAC9D,SAAA,EAAW,OAAA,CAAQ,gBAAA,EAAkB,SAAA,IAAa;AAAA,GACpD;AACF;AAEO,SAAS,gBAAgB,OAAA,EAA4B;AAC1D,EAAA,IAAI,CAAC,OAAA,CAAQ,WAAA,IAAe,OAAO,OAAA,CAAQ,gBAAgB,QAAA,EAAU;AACnE,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AAEA,EAAA,IAAI,OAAA,CAAQ,WAAA,CAAY,IAAA,EAAK,KAAM,QAAQ,WAAA,EAAa;AACtD,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AAEA,EAAA,IAAI,OAAA,CAAQ,aAAa,MAAA,EAAW;AAClC,IAAA,IAAI,OAAO,QAAQ,QAAA,KAAa,QAAA,IAAY,QAAQ,QAAA,CAAS,IAAA,OAAW,EAAA,EAAI;AAC1E,MAAA,MAAM,IAAI,KAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AAAA,EACF;AAEA,EAAA,IAAI,OAAA,CAAQ,kBAAkB,MAAA,EAAW;AACvC,IAAA,IAAI,OAAO,OAAA,CAAQ,aAAA,KAAkB,QAAA,IAAY,OAAA,CAAQ,iBAAiB,CAAA,EAAG;AAC3E,MAAA,MAAM,IAAI,KAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AAAA,EACF;AACF;AClHA,IAAM,QAAA,GAAW,2BAAA;AACjB,IAAM,WAAA,GAAc,OAAA;AAEb,SAAS,cAAc,OAAA,EAAsB;AAClD,EAAA,MAAM,UAAA,GAAqC;AAAA,IACzC,CAAC,iBAAiB,GAAG,OAAA,CAAQ,WAAA;AAAA,IAC7B,oBAAA,EAAsB,QAAA;AAAA,IACtB,uBAAA,EAAyB,WAAA;AAAA,IACzB,wBAAA,EAA0B;AAAA,GAC5B;AAEA,EAAA,IAAI,QAAQ,cAAA,EAAgB;AAC1B,IAAA,UAAA,CAAW,oBAAoB,IAAI,OAAA,CAAQ,cAAA;AAAA,EAC7C;AAEA,EAAA,IAAI,QAAQ,WAAA,EAAa;AACvB,IAAA,UAAA,CAAW,kCAAkC,IAAI,OAAA,CAAQ,WAAA;AAAA,EAC3D;AAEA,EAAA,IAAI,OAAO,cAAc,WAAA,EAAa;AACpC,IAAA,IAAI,UAAU,QAAA,EAAU;AACtB,MAAA,UAAA,CAAW,kBAAkB,IAAI,SAAA,CAAU,QAAA;AAAA,IAC7C;AACA,IAAA,IAAI,UAAU,SAAA,EAAW;AACvB,MAAA,UAAA,CAAW,oBAAoB,IAAI,SAAA,CAAU,SAAA;AAAA,IAC/C;AACA,IAAA,IAAI,UAAU,QAAA,EAAU;AACtB,MAAA,UAAA,CAAW,kBAAkB,IAAI,SAAA,CAAU,QAAA;AAAA,IAC7C;AAAA,EACF;AAEA,EAAA,IAAI,QAAQ,kBAAA,EAAoB;AAC9B,IAAA,MAAA,CAAO,MAAA,CAAO,UAAA,EAAY,OAAA,CAAQ,kBAAkB,CAAA;AAAA,EACtD;AAEA,EAAA,OAAO,uBAAuB,UAAU,CAAA;AAC1C;AChCO,SAAS,oBAAA,CAAqB,SAAsB,QAAA,EAAuC;AAChG,EAAA,MAAM,QAAA,GAAW,gBAAgB,OAAO,CAAA;AACxC,EAAA,MAAM,OAAA,GAAU,qBAAqB,OAAO,CAAA;AAE5C,EAAA,MAAM,QAAA,GAAW,IAAI,iBAAA,CAAkB;AAAA,IACrC,GAAA,EAAK,GAAG,QAAQ,CAAA,UAAA,CAAA;AAAA,IAChB,SAAS,OAAA,CAAQ,OAAA;AAAA,IACjB,aAAA,EAAe;AAAA,GAChB,CAAA;AAED,EAAA,OAAA,CAAQ,oBAAoB,QAAQ,CAAA;AAEpC,EAAA,MAAM,QAAA,GAAW,IAAI,iBAAA,CAAkB;AAAA,IACrC,QAAA;AAAA,IACA,cAAA,EAAgB,CAAC,IAAI,kBAAA,CAAmB,QAAQ,CAAC;AAAA,GAClD,CAAA;AAED,EAAA,OAAA,CAAQ,mBAAmB,QAAQ,CAAA;AAEnC,EAAA,QAAA,CAAS,QAAA,EAAS;AAElB,EAAA,OAAO,EAAE,UAAU,QAAA,EAAS;AAC9B;AC3BO,SAAS,oBAAA,CAAqB,SAAsB,QAAA,EAAoC;AAC7F,EAAA,MAAM,QAAA,GAAW,gBAAgB,OAAO,CAAA;AACxC,EAAA,MAAM,OAAA,GAAU,qBAAqB,OAAO,CAAA;AAE5C,EAAA,MAAM,QAAA,GAAW,IAAI,eAAA,CAAgB;AAAA,IACnC,GAAA,EAAK,GAAG,QAAQ,CAAA,QAAA,CAAA;AAAA,IAChB,SAAS,OAAA,CAAQ,OAAA;AAAA,IACjB,aAAA,EAAe;AAAA,GAChB,CAAA;AAED,EAAA,MAAM,QAAA,GAAW,IAAI,cAAA,CAAe,EAAE,UAAU,CAAA;AAChD,EAAA,QAAA,CAAS,qBAAA,CAAsB,IAAI,uBAAA,CAAwB,QAAQ,CAAC,CAAA;AAEpE,EAAA,IAAA,CAAK,wBAAwB,QAAQ,CAAA;AAErC,EAAA,OAAO,QAAA;AACT;AChBA,IAAM,yBAAA,GAA4B,GAAA;AAE3B,SAAS,mBAAA,CAAoB,SAAsB,QAAA,EAAmC;AAC3F,EAAA,MAAM,QAAA,GAAW,gBAAgB,OAAO,CAAA;AACxC,EAAA,MAAM,OAAA,GAAU,qBAAqB,OAAO,CAAA;AAE5C,EAAA,MAAM,QAAA,GAAW,IAAI,kBAAA,CAAmB;AAAA,IACtC,GAAA,EAAK,GAAG,QAAQ,CAAA,WAAA,CAAA;AAAA,IAChB,SAAS,OAAA,CAAQ,OAAA;AAAA,IACjB,aAAA,EAAe;AAAA,GAChB,CAAA;AAED,EAAA,MAAM,QAAA,GAAW,IAAI,aAAA,CAAc;AAAA,IACjC,QAAA;AAAA,IACA,OAAA,EAAS;AAAA,MACP,IAAI,6BAAA,CAA8B;AAAA,QAChC,QAAA;AAAA,QACA,oBAAA,EAAsB;AAAA,OACvB;AAAA;AACH,GACD,CAAA;AAED,EAAA,OAAA,CAAQ,uBAAuB,QAAQ,CAAA;AAEvC,EAAA,OAAO,QAAA;AACT;ACxBO,SAAS,6BAA6B,OAAA,EAA4B;AACvE,EAAA,MAAM,MAAA,GAA0C,wBAAwB,OAAO,CAAA;AAC/E,EAAA,MAAM,UAAA,GAAa,OAAA,CAAQ,UAAA,IAAc,EAAC;AAE1C,EAAA,MAAM,mBAAmB,EAAC;AAE1B,EAAA,IAAI,OAAO,KAAA,EAAO;AAChB,IAAA,gBAAA,CAAiB,IAAA;AAAA,MACf,IAAI,oBAAA,CAAqB;AAAA,QACvB;AAAA,OACD;AAAA,KACH;AAAA,EACF;AAEA,EAAA,IAAI,OAAO,GAAA,EAAK;AACd,IAAA,gBAAA,CAAiB,IAAA;AAAA,MACf,IAAI,6BAAA,CAA8B;AAAA,QAChC;AAAA,OACD;AAAA,KACH;AAAA,EACF;AAEA,EAAA,IAAI,OAAO,YAAA,EAAc;AACvB,IAAA,gBAAA,CAAiB,IAAA,CAAK,IAAI,2BAAA,EAA6B,CAAA;AAAA,EACzD;AAEA,EAAA,IAAI,OAAO,eAAA,EAAiB;AAC1B,IAAA,gBAAA,CAAiB,IAAA,CAAK,IAAI,8BAAA,EAAgC,CAAA;AAAA,EAC5D;AAEA,EAAA,IAAI,gBAAA,CAAiB,SAAS,CAAA,EAAG;AAC/B,IAAA,wBAAA,CAAyB,EAAE,kBAAkB,CAAA;AAAA,EAC/C;AACF;ACtCA,IAAM,UAAA,GAAa,sCAAA;AAEZ,SAAS,wBAAA,GAAiC;AAC/C,EAAA,MAAM,KAAA,GAAQA,OAAAA,CAAQ,QAAA,CAAS,UAAA,EAAY,OAAO,CAAA;AAElD,EAAA,MAAM,YAAA,GAAe,KAAA,CAAM,eAAA,CAAgB,gBAAA,EAAkB;AAAA,IAC3D,WAAA,EAAa,0BAAA;AAAA,IACb,IAAA,EAAM;AAAA,GACP,CAAA;AAED,EAAA,MAAM,YAAA,GAAe,KAAA,CAAM,eAAA,CAAgB,gBAAA,EAAkB;AAAA,IAC3D,WAAA,EAAa,yBAAA;AAAA,IACb,IAAA,EAAM;AAAA,GACP,CAAA;AAED,EAAA,MAAM,YAAA,GAAe,KAAA,CAAM,eAAA,CAAgB,gBAAA,EAAkB;AAAA,IAC3D,WAAA,EAAa,2BAAA;AAAA,IACb,IAAA,EAAM;AAAA,GACP,CAAA;AAED,EAAA,MAAM,aAAA,GAAgB,KAAA,CAAM,eAAA,CAAgB,iBAAA,EAAmB;AAAA,IAC7D,WAAA,EAAa,oBAAA;AAAA,IACb,IAAA,EAAM;AAAA,GACP,CAAA;AAED,EAAA,MAAM,YAAA,GAAe,KAAA,CAAM,eAAA,CAAgB,gBAAA,EAAkB;AAAA,IAC3D,WAAA,EAAa,wBAAA;AAAA,IACb,IAAA,EAAM;AAAA,GACP,CAAA;AAED,EAAA,MAAM,YAAA,GAAe,CAAC,SAAA,KAAwD;AAC5E,IAAA,OAAO,CAAC,MAAA,KAAmB;AACzB,MAAA,MAAM,KAAA,GAAgC;AAAA,QACpC,qBAAqB,MAAA,CAAO;AAAA,OAC9B;AAEA,MAAA,IAAI,OAAO,MAAA,KAAW,WAAA,IAAe,MAAA,CAAO,QAAA,EAAU;AACpD,QAAA,KAAA,CAAM,UAAU,CAAA,GAAI,MAAA,CAAO,QAAA,CAAS,QAAA;AAAA,MACtC;AAEA,MAAA,SAAA,CAAU,MAAA,CAAO,MAAA,CAAO,KAAA,EAAO,KAAK,CAAA;AAAA,IACtC,CAAA;AAAA,EACF,CAAA;AAGA,EAAA,OAAO,YAAY,CAAA,CAAE,IAAA,CAAK,CAAC,EAAE,OAAO,KAAA,EAAO,KAAA,EAAO,MAAA,EAAQ,KAAA,EAAM,KAAM;AACpE,IAAA,KAAA,CAAM,YAAA,CAAa,YAAY,CAAC,CAAA;AAChC,IAAA,KAAA,CAAM,YAAA,CAAa,YAAY,CAAC,CAAA;AAChC,IAAA,KAAA,CAAM,YAAA,CAAa,YAAY,CAAC,CAAA;AAChC,IAAA,MAAA,CAAO,YAAA,CAAa,aAAa,CAAC,CAAA;AAClC,IAAA,KAAA,CAAM,YAAA,CAAa,YAAY,CAAC,CAAA;AAAA,EAClC,CAAC,CAAA;AACH;;;AC7CA,IAAI,eAAA,GAA0C,IAAA;AAC9C,IAAI,iBAAA,GAAyC,IAAA;AAC7C,IAAI,mBAAA,GAA2C,IAAA;AAExC,SAAS,wBAAwB,OAAA,EAAgC;AACtE,EAAA,eAAA,GAAkB,OAAA;AAElB,EAAA,iBAAA,GAAoB,MAAM;AACxB,IAAA,IAAI,QAAA,CAAS,oBAAoB,QAAA,EAAU;AACzC,MAAA,QAAA,EAAS;AAAA,IACX;AAAA,EACF,CAAA;AAEA,EAAA,mBAAA,GAAsB,MAAM;AAC1B,IAAA,QAAA,EAAS;AAAA,EACX,CAAA;AAEA,EAAA,IAAI,OAAO,aAAa,WAAA,EAAa;AACnC,IAAA,QAAA,CAAS,gBAAA,CAAiB,oBAAoB,iBAAiB,CAAA;AAAA,EACjE;AACA,EAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AACjC,IAAA,MAAA,CAAO,gBAAA,CAAiB,gBAAgB,mBAAmB,CAAA;AAAA,EAC7D;AACF;AAEA,SAAS,QAAA,GAAiB;AACxB,EAAA,IAAI,CAAC,eAAA,EAAiB;AAEtB,EAAA,IAAI;AACF,IAAA,eAAA,CAAgB,eAAe,UAAA,EAAW;AAC1C,IAAA,eAAA,CAAgB,eAAe,UAAA,EAAW;AAC1C,IAAA,eAAA,CAAgB,cAAc,UAAA,EAAW;AAAA,EAC3C,CAAA,CAAA,MAAQ;AAAA,EAER;AACF;AAEA,eAAsB,QAAA,GAA0B;AAC9C,EAAA,IAAI,CAAC,eAAA,EAAiB;AAEtB,EAAA,IAAI,OAAO,QAAA,KAAa,WAAA,IAAe,iBAAA,EAAmB;AACxD,IAAA,QAAA,CAAS,mBAAA,CAAoB,oBAAoB,iBAAiB,CAAA;AAAA,EACpE;AACA,EAAA,IAAI,OAAO,MAAA,KAAW,WAAA,IAAe,mBAAA,EAAqB;AACxD,IAAA,MAAA,CAAO,mBAAA,CAAoB,gBAAgB,mBAAmB,CAAA;AAAA,EAChE;AAEA,EAAA,IAAI;AACF,IAAA,MAAM,QAAQ,GAAA,CAAI;AAAA,MAChB,eAAA,CAAgB,eAAe,UAAA,EAAW;AAAA,MAC1C,eAAA,CAAgB,eAAe,UAAA,EAAW;AAAA,MAC1C,eAAA,CAAgB,cAAc,UAAA;AAAW,KAC1C,CAAA;AAED,IAAA,MAAM,QAAQ,GAAA,CAAI;AAAA,MAChB,eAAA,CAAgB,eAAe,QAAA,EAAS;AAAA,MACxC,eAAA,CAAgB,eAAe,QAAA,EAAS;AAAA,MACxC,eAAA,CAAgB,cAAc,QAAA;AAAS,KACxC,CAAA;AAAA,EACH,CAAA,SAAE;AACA,IAAA,eAAA,GAAkB,IAAA;AAClB,IAAA,iBAAA,GAAoB,IAAA;AACpB,IAAA,mBAAA,GAAsB,IAAA;AAAA,EACxB;AACF;;;AC/DA,IAAI,WAAA,GAAc,KAAA;AAEX,SAAS,SAAS,OAAA,EAAkC;AACzD,EAAA,IAAI,WAAA,EAAa;AACf,IAAA,OAAA,CAAQ,IAAA;AAAA,MACN;AAAA,KACF;AACA,IAAA,OAAO,EAAE,QAAA,EAAS;AAAA,EACpB;AAEA,EAAA,eAAA,CAAgB,OAAO,CAAA;AAEvB,EAAA,MAAM,QAAA,GAAW,cAAc,OAAO,CAAA;AACtC,EAAA,MAAM,EAAE,QAAA,EAAU,cAAA,EAAe,GAAI,oBAAA,CAAqB,SAAS,QAAQ,CAAA;AAC3E,EAAA,MAAM,cAAA,GAAiB,oBAAA,CAAqB,OAAA,EAAS,QAAQ,CAAA;AAC7D,EAAA,MAAM,aAAA,GAAgB,mBAAA,CAAoB,OAAA,EAAS,QAAQ,CAAA;AAE3D,EAAA,4BAAA,CAA6B,OAAO,CAAA;AAEpC,EAAA,MAAM,qBAAA,GAAwB,wBAAwB,OAAO,CAAA;AAC7D,EAAA,IAAI,sBAAsB,SAAA,EAAW;AACnC,IAAA,wBAAA,EAAyB;AAAA,EAC3B;AAEA,EAAA,uBAAA,CAAwB,EAAE,cAAA,EAAgB,cAAA,EAAgB,aAAA,EAAe,CAAA;AAGzE,EAAA,IAAI,QAAQ,UAAA,EAAY;AACtB,IAAA,KAAA,MAAW,GAAA,IAAO,QAAQ,UAAA,EAAY;AACpC,MAAA,GAAA,CAAI,EAAE,gBAAgB,CAAA;AAAA,IACxB;AAAA,EACF;AAGA,EAAA,MAAM,MAAA,GAAS,cAAA,CAAe,SAAA,CAAU,2BAAA,EAA6B,OAAO,CAAA;AAC5E,EAAA,MAAA,CAAO,IAAA,CAAK;AAAA,IACV,gBAAgB,cAAA,CAAe,IAAA;AAAA,IAC/B,YAAA,EAAc,MAAA;AAAA,IACd,IAAA,EAAM,CAAA,uCAAA,EAA0C,OAAA,CAAQ,WAAW,CAAA,CAAA,CAAA;AAAA,IACnE,UAAA,EAAY;AAAA,MACV,qBAAqB,OAAA,CAAQ;AAAA;AAC/B,GACD,CAAA;AAED,EAAA,WAAA,GAAc,IAAA;AAEd,EAAA,OAAO;AAAA,IACL,UAAU,YAAY;AACpB,MAAA,MAAM,QAAA,EAAS;AACf,MAAA,WAAA,GAAc,KAAA;AAAA,IAChB;AAAA,GACF;AACF;ACZO,SAAS,YAAA,CAAa;AAAA,EAC3B,QAAA;AAAA,EACA,WAAA;AAAA,EACA,QAAA;AAAA,EACA,kBAAA;AAAA,EACA,cAAA;AAAA,EACA,WAAA;AAAA,EACA,gBAAA;AAAA,EACA,OAAA;AAAA,EACA,aAAA;AAAA,EACA,UAAA;AAAA,EACA,gBAAA;AAAA,EACA,iBAAA;AAAA,EACA;AACF,CAAA,EAAsB;AACpB,EAAA,MAAM,SAAA,GAAY,OAA0B,IAAI,CAAA;AAEhD,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,MAAM,SAAS,QAAA,CAAS;AAAA,MACtB,WAAA;AAAA,MACA,QAAA;AAAA,MACA,kBAAA;AAAA,MACA,cAAA;AAAA,MACA,WAAA;AAAA,MACA,gBAAA;AAAA,MACA,OAAA;AAAA,MACA,aAAA;AAAA,MACA,UAAA;AAAA,MACA,gBAAA;AAAA,MACA,iBAAA;AAAA,MACA;AAAA,KACD,CAAA;AAED,IAAA,SAAA,CAAU,OAAA,GAAU,MAAA;AAEpB,IAAA,OAAO,MAAM;AACX,MAAA,SAAA,CAAU,SAAS,QAAA,EAAS;AAC5B,MAAA,SAAA,CAAU,OAAA,GAAU,IAAA;AAAA,IACtB,CAAA;AAAA,EAIF,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,uCAAU,QAAA,EAAS,CAAA;AACrB;AC3FA,IAAM,WAAA,GAAc,0CAAA;AACpB,IAAM,WAAA,GAAc,0CAAA;AA6Bb,IAAM,mBAAA,GAAN,cAAkC,SAAA,CAGvC;AAAA,EACA,YAAY,KAAA,EAAiC;AAC3C,IAAA,KAAA,CAAM,KAAK,CAAA;AACX,IAAA,IAAA,CAAK,KAAA,GAAQ,EAAE,QAAA,EAAU,KAAA,EAAO,OAAO,IAAA,EAAK;AAAA,EAC9C;AAAA,EAEA,OAAO,yBAAyB,KAAA,EAAwC;AACtE,IAAA,OAAO,EAAE,QAAA,EAAU,IAAA,EAAM,KAAA,EAAM;AAAA,EACjC;AAAA,EAEA,iBAAA,CAAkB,OAAc,SAAA,EAA4B;AAC1D,IAAA,MAAM,MAAA,GAAS,KAAA,CAAM,SAAA,CAAU,WAAA,EAAa,OAAO,CAAA;AACnD,IAAA,MAAM,IAAA,GAAO,MAAA,CAAO,SAAA,CAAU,sBAAsB,CAAA;AAEpD,IAAA,IAAA,CAAK,SAAA,CAAU,EAAE,IAAA,EAAM,cAAA,CAAe,OAAO,OAAA,EAAS,KAAA,CAAM,SAAS,CAAA;AACrE,IAAA,IAAA,CAAK,YAAA,CAAa,YAAA,EAAc,KAAA,CAAM,IAAI,CAAA;AAC1C,IAAA,IAAA,CAAK,YAAA,CAAa,eAAA,EAAiB,KAAA,CAAM,OAAO,CAAA;AAEhD,IAAA,IAAI,MAAM,KAAA,EAAO;AACf,MAAA,IAAA,CAAK,YAAA,CAAa,aAAA,EAAe,KAAA,CAAM,KAAK,CAAA;AAAA,IAC9C;AACA,IAAA,IAAI,UAAU,cAAA,EAAgB;AAC5B,MAAA,IAAA,CAAK,YAAA,CAAa,uBAAA,EAAyB,SAAA,CAAU,cAAc,CAAA;AAAA,IACrE;AAEA,IAAA,IAAA,CAAK,gBAAgB,KAAK,CAAA;AAC1B,IAAA,IAAA,CAAK,GAAA,EAAI;AAGT,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAASC,IAAAA,CAAK,SAAA,CAAU,WAAA,EAAa,OAAO,CAAA;AAClD,MAAA,MAAA,CAAO,IAAA,CAAK;AAAA,QACV,gBAAgBC,cAAAA,CAAe,KAAA;AAAA,QAC/B,YAAA,EAAc,OAAA;AAAA,QACd,IAAA,EAAM,CAAA,iBAAA,EAAoB,KAAA,CAAM,OAAO,CAAA,CAAA;AAAA,QACvC,UAAA,EAAY;AAAA,UACV,cAAc,KAAA,CAAM,IAAA;AAAA,UACpB,iBAAiB,KAAA,CAAM,OAAA;AAAA,UACvB,GAAI,MAAM,KAAA,GAAQ,EAAE,eAAe,KAAA,CAAM,KAAA,KAAU,EAAC;AAAA,UACpD,GAAI,UAAU,cAAA,GACV,EAAE,yBAAyB,SAAA,CAAU,cAAA,KACrC;AAAC;AACP,OACD,CAAA;AAAA,IACH,CAAA,CAAA,MAAQ;AAAA,IAER;AAEA,IAAA,IAAA,CAAK,KAAA,CAAM,OAAA,GAAU,KAAA,EAAO,SAAS,CAAA;AAAA,EACvC;AAAA,EAEQ,QAAQ,MAAM;AACpB,IAAA,IAAA,CAAK,SAAS,EAAE,QAAA,EAAU,KAAA,EAAO,KAAA,EAAO,MAAM,CAAA;AAAA,EAChD,CAAA;AAAA,EAEA,MAAA,GAAS;AACP,IAAA,IAAI,IAAA,CAAK,KAAA,CAAM,QAAA,IAAY,IAAA,CAAK,MAAM,KAAA,EAAO;AAC3C,MAAA,MAAM,EAAE,QAAA,EAAS,GAAI,IAAA,CAAK,KAAA;AAC1B,MAAA,IAAI,OAAO,aAAa,UAAA,EAAY;AAClC,QAAA,OAAO,QAAA,CAAS,IAAA,CAAK,KAAA,CAAM,KAAA,EAAO,KAAK,KAAK,CAAA;AAAA,MAC9C;AACA,MAAA,OAAO,QAAA;AAAA,IACT;AAEA,IAAA,OAAO,KAAK,KAAA,CAAM,QAAA;AAAA,EACpB;AACF;ACrGA,IAAM,mBAAA,GAAsB,kCAAA;AAsBrB,SAAS,SAAA,CAAU,MAAe,OAAA,EAA0B;AACjE,EAAA,OAAO,OAAA;AAAA,IACL,MAAMC,KAAAA,CAAM,SAAA,CAAU,IAAA,IAAQ,qBAAqB,OAAO,CAAA;AAAA,IAC1D,CAAC,MAAM,OAAO;AAAA,GAChB;AACF;AC3BA,IAAMC,YAAAA,GAAc,kCAAA;AAkBb,SAAS,eAAA,GAAiC;AAC/C,EAAA,OAAO,CAAC,QAAA,KAA+B;AAErC,IAAAD,KAAAA,CAAM,SAAA,CAAUC,YAAAA,EAAa,OAAO,CAAA;AAAA,EACtC,CAAA;AACF","file":"index.mjs","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 = '0.0.1';\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(\n () => trace.getTracer(name ?? DEFAULT_TRACER_NAME, version),\n [name, version],\n );\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":["metrics","logs","SeverityNumber","trace","TRACER_NAME"],"mappings":"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","file":"index.mjs","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 = '0.0.2';\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"]}
@@ -54,7 +54,7 @@ function validateOptions(options) {
54
54
  }
55
55
  }
56
56
  var SDK_NAME = "@raccoon.ninja/otel-react";
57
- var SDK_VERSION = "0.0.1";
57
+ var SDK_VERSION = "0.0.2";
58
58
  function buildResource(options) {
59
59
  const attributes = {
60
60
  [semanticConventions.ATTR_SERVICE_NAME]: options.serviceName,
@@ -123,9 +123,7 @@ function createMeterProvider(options, resource) {
123
123
  var initialized = false;
124
124
  async function initOtelNative(options) {
125
125
  if (initialized) {
126
- console.warn(
127
- "[@raccoon.ninja/otel-react] initOtelNative() has already been called. Skipping."
128
- );
126
+ console.warn("[@raccoon.ninja/otel-react] initOtelNative() has already been called. Skipping.");
129
127
  return {
130
128
  shutdown: async () => {
131
129
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/core/options.ts","../../src/core/resource.ts","../../src/providers/logger.ts","../../src/providers/meter.ts","../../src/native/init.ts","../../src/native/navigation.ts"],"names":["ATTR_SERVICE_NAME","ATTR_SERVICE_VERSION","SEMRESATTRS_DEPLOYMENT_ENVIRONMENT","resourceFromAttributes","OTLPLogExporter","LoggerProvider","BatchLogRecordProcessor","logs","OTLPMetricExporter","MeterProvider","PeriodicExportingMetricReader","metrics","OTLPTraceExporter","BasicTracerProvider","BatchSpanProcessor","trace","SeverityNumber","SpanStatusCode"],"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 = '0.0.1';\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 { 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 { trace } from '@opentelemetry/api';\nimport { BasicTracerProvider, BatchSpanProcessor } from '@opentelemetry/sdk-trace-base';\nimport { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';\nimport { SeverityNumber } from '@opentelemetry/api-logs';\nimport type { OtelOptions, OtelHandle } from '../core/options';\nimport {\n validateOptions,\n resolveEndpoint,\n resolveExportTimeout,\n} from '../core/options';\nimport { buildResource } from '../core/resource';\nimport { createLoggerProvider } from '../providers/logger';\nimport { createMeterProvider } from '../providers/meter';\n\nlet initialized = false;\n\n/**\n * Initialize OpenTelemetry for React Native.\n *\n * Key differences from browser init:\n * - Uses BasicTracerProvider (sdk-trace-base) instead of WebTracerProvider\n * - Only fetch instrumentation enabled (no document-load, no user-interaction, no Web Vitals)\n * - XHR disabled by default to avoid duplicate spans (RN's fetch polyfills over XHR)\n * - Uses AppState for flush instead of visibilitychange\n */\nexport async function initOtelNative(options: OtelOptions): Promise<OtelHandle> {\n if (initialized) {\n console.warn(\n '[@raccoon.ninja/otel-react] initOtelNative() has already been called. Skipping.',\n );\n return {\n shutdown: async () => {\n /* noop */\n },\n };\n }\n\n validateOptions(options);\n\n const resource = buildResource(options);\n const endpoint = resolveEndpoint(options);\n const timeout = resolveExportTimeout(options);\n\n const traceExporter = new OTLPTraceExporter({\n url: `${endpoint}/v1/traces`,\n headers: options.headers,\n timeoutMillis: timeout,\n });\n\n const tracerProvider = new BasicTracerProvider({\n resource,\n spanProcessors: [new BatchSpanProcessor(traceExporter)],\n });\n\n // BasicTracerProvider doesn't have register(), use the API directly\n trace.setGlobalTracerProvider(tracerProvider);\n\n const loggerProvider = createLoggerProvider(options, resource);\n const meterProvider = createMeterProvider(options, resource);\n\n // Listen for AppState changes for flush (React Native)\n let appStateSubscription: { remove: () => void } | null = null;\n try {\n // Dynamic import of AppState so this module doesn't crash in non-RN environments\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const { AppState } = require('react-native') as {\n AppState: {\n addEventListener: (\n type: string,\n handler: (state: string) => void,\n ) => { remove: () => void };\n };\n };\n appStateSubscription = AppState.addEventListener('change', (nextState: string) => {\n if (nextState === 'background' || nextState === 'inactive') {\n tracerProvider.forceFlush();\n loggerProvider.forceFlush();\n meterProvider.forceFlush();\n }\n });\n } catch {\n // AppState not available — skip\n }\n\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 (RN) initialized for service \"${options.serviceName}\"`,\n });\n\n initialized = true;\n\n return {\n shutdown: async () => {\n appStateSubscription?.remove();\n await Promise.all([\n tracerProvider.forceFlush(),\n loggerProvider.forceFlush(),\n meterProvider.forceFlush(),\n ]);\n await Promise.all([\n tracerProvider.shutdown(),\n loggerProvider.shutdown(),\n meterProvider.shutdown(),\n ]);\n initialized = false;\n },\n };\n}\n","import { trace, SpanStatusCode } from '@opentelemetry/api';\nimport type { OtelExtension } from '../core/options';\n\nconst TRACER_NAME = '@raccoon.ninja/otel-react/react-navigation';\n\n/**\n * Extension for React Navigation route-change tracing.\n *\n * This extension pre-registers the tracer scope. Actual navigation\n * tracking requires hooking into React Navigation's onStateChange\n * in the consuming app.\n *\n * @example\n * ```tsx\n * import { withReactNavigation, createNavigationTracker } from '@raccoon.ninja/otel-react/native';\n *\n * const otel = await initOtelNative({\n * serviceName: 'my-rn-app',\n * extensions: [withReactNavigation()],\n * });\n * ```\n */\nexport function withReactNavigation(): OtelExtension {\n return () => {\n trace.getTracer(TRACER_NAME, '1.0.0');\n };\n}\n\n/**\n * Creates a navigation state change handler that records route changes as spans.\n *\n * @returns A function suitable for React Navigation's onStateChange prop.\n */\nexport function createNavigationTracker() {\n const tracer = trace.getTracer(TRACER_NAME, '1.0.0');\n let previousRouteName: string | undefined;\n\n return (state: { routes: Array<{ name: string }>; index: number } | undefined) => {\n if (!state) return;\n\n const currentRoute = state.routes[state.index];\n if (!currentRoute) return;\n\n const currentRouteName = currentRoute.name;\n\n if (previousRouteName && previousRouteName !== currentRouteName) {\n const span = tracer.startSpan('navigation.route_change');\n span.setAttribute('navigation.from', previousRouteName);\n span.setAttribute('navigation.to', currentRouteName);\n span.setStatus({ code: SpanStatusCode.OK });\n span.end();\n }\n\n previousRouteName = currentRouteName;\n };\n}\n"]}
1
+ {"version":3,"sources":["../../src/core/options.ts","../../src/core/resource.ts","../../src/providers/logger.ts","../../src/providers/meter.ts","../../src/native/init.ts","../../src/native/navigation.ts"],"names":["ATTR_SERVICE_NAME","ATTR_SERVICE_VERSION","SEMRESATTRS_DEPLOYMENT_ENVIRONMENT","resourceFromAttributes","OTLPLogExporter","LoggerProvider","BatchLogRecordProcessor","logs","OTLPMetricExporter","MeterProvider","PeriodicExportingMetricReader","metrics","OTLPTraceExporter","BasicTracerProvider","BatchSpanProcessor","trace","SeverityNumber","SpanStatusCode"],"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 = '0.0.2';\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 { 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 { trace } from '@opentelemetry/api';\nimport { BasicTracerProvider, BatchSpanProcessor } from '@opentelemetry/sdk-trace-base';\nimport { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';\nimport { SeverityNumber } from '@opentelemetry/api-logs';\nimport type { OtelOptions, OtelHandle } from '../core/options';\nimport { validateOptions, resolveEndpoint, resolveExportTimeout } from '../core/options';\nimport { buildResource } from '../core/resource';\nimport { createLoggerProvider } from '../providers/logger';\nimport { createMeterProvider } from '../providers/meter';\n\nlet initialized = false;\n\n/**\n * Initialize OpenTelemetry for React Native.\n *\n * Key differences from browser init:\n * - Uses BasicTracerProvider (sdk-trace-base) instead of WebTracerProvider\n * - Only fetch instrumentation enabled (no document-load, no user-interaction, no Web Vitals)\n * - XHR disabled by default to avoid duplicate spans (RN's fetch polyfills over XHR)\n * - Uses AppState for flush instead of visibilitychange\n */\nexport async function initOtelNative(options: OtelOptions): Promise<OtelHandle> {\n if (initialized) {\n console.warn('[@raccoon.ninja/otel-react] initOtelNative() has already been called. Skipping.');\n return {\n shutdown: async () => {\n /* noop */\n },\n };\n }\n\n validateOptions(options);\n\n const resource = buildResource(options);\n const endpoint = resolveEndpoint(options);\n const timeout = resolveExportTimeout(options);\n\n const traceExporter = new OTLPTraceExporter({\n url: `${endpoint}/v1/traces`,\n headers: options.headers,\n timeoutMillis: timeout,\n });\n\n const tracerProvider = new BasicTracerProvider({\n resource,\n spanProcessors: [new BatchSpanProcessor(traceExporter)],\n });\n\n // BasicTracerProvider doesn't have register(), use the API directly\n trace.setGlobalTracerProvider(tracerProvider);\n\n const loggerProvider = createLoggerProvider(options, resource);\n const meterProvider = createMeterProvider(options, resource);\n\n // Listen for AppState changes for flush (React Native)\n let appStateSubscription: { remove: () => void } | null = null;\n try {\n // Dynamic import of AppState so this module doesn't crash in non-RN environments\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const { AppState } = require('react-native') as {\n AppState: {\n addEventListener: (\n type: string,\n handler: (state: string) => void,\n ) => { remove: () => void };\n };\n };\n appStateSubscription = AppState.addEventListener('change', (nextState: string) => {\n if (nextState === 'background' || nextState === 'inactive') {\n tracerProvider.forceFlush();\n loggerProvider.forceFlush();\n meterProvider.forceFlush();\n }\n });\n } catch {\n // AppState not available — skip\n }\n\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 (RN) initialized for service \"${options.serviceName}\"`,\n });\n\n initialized = true;\n\n return {\n shutdown: async () => {\n appStateSubscription?.remove();\n await Promise.all([\n tracerProvider.forceFlush(),\n loggerProvider.forceFlush(),\n meterProvider.forceFlush(),\n ]);\n await Promise.all([\n tracerProvider.shutdown(),\n loggerProvider.shutdown(),\n meterProvider.shutdown(),\n ]);\n initialized = false;\n },\n };\n}\n","import { trace, SpanStatusCode } from '@opentelemetry/api';\nimport type { OtelExtension } from '../core/options';\n\nconst TRACER_NAME = '@raccoon.ninja/otel-react/react-navigation';\n\n/**\n * Extension for React Navigation route-change tracing.\n *\n * This extension pre-registers the tracer scope. Actual navigation\n * tracking requires hooking into React Navigation's onStateChange\n * in the consuming app.\n *\n * @example\n * ```tsx\n * import { withReactNavigation, createNavigationTracker } from '@raccoon.ninja/otel-react/native';\n *\n * const otel = await initOtelNative({\n * serviceName: 'my-rn-app',\n * extensions: [withReactNavigation()],\n * });\n * ```\n */\nexport function withReactNavigation(): OtelExtension {\n return () => {\n trace.getTracer(TRACER_NAME, '1.0.0');\n };\n}\n\n/**\n * Creates a navigation state change handler that records route changes as spans.\n *\n * @returns A function suitable for React Navigation's onStateChange prop.\n */\nexport function createNavigationTracker() {\n const tracer = trace.getTracer(TRACER_NAME, '1.0.0');\n let previousRouteName: string | undefined;\n\n return (state: { routes: Array<{ name: string }>; index: number } | undefined) => {\n if (!state) return;\n\n const currentRoute = state.routes[state.index];\n if (!currentRoute) return;\n\n const currentRouteName = currentRoute.name;\n\n if (previousRouteName && previousRouteName !== currentRouteName) {\n const span = tracer.startSpan('navigation.route_change');\n span.setAttribute('navigation.from', previousRouteName);\n span.setAttribute('navigation.to', currentRouteName);\n span.setStatus({ code: SpanStatusCode.OK });\n span.end();\n }\n\n previousRouteName = currentRouteName;\n };\n}\n"]}
@@ -52,7 +52,7 @@ function validateOptions(options) {
52
52
  }
53
53
  }
54
54
  var SDK_NAME = "@raccoon.ninja/otel-react";
55
- var SDK_VERSION = "0.0.1";
55
+ var SDK_VERSION = "0.0.2";
56
56
  function buildResource(options) {
57
57
  const attributes = {
58
58
  [ATTR_SERVICE_NAME]: options.serviceName,
@@ -121,9 +121,7 @@ function createMeterProvider(options, resource) {
121
121
  var initialized = false;
122
122
  async function initOtelNative(options) {
123
123
  if (initialized) {
124
- console.warn(
125
- "[@raccoon.ninja/otel-react] initOtelNative() has already been called. Skipping."
126
- );
124
+ console.warn("[@raccoon.ninja/otel-react] initOtelNative() has already been called. Skipping.");
127
125
  return {
128
126
  shutdown: async () => {
129
127
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/core/options.ts","../../src/core/resource.ts","../../src/providers/logger.ts","../../src/providers/meter.ts","../../src/native/init.ts","../../src/native/navigation.ts"],"names":["trace"],"mappings":"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","file":"index.mjs","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 = '0.0.1';\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 { 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 { trace } from '@opentelemetry/api';\nimport { BasicTracerProvider, BatchSpanProcessor } from '@opentelemetry/sdk-trace-base';\nimport { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';\nimport { SeverityNumber } from '@opentelemetry/api-logs';\nimport type { OtelOptions, OtelHandle } from '../core/options';\nimport {\n validateOptions,\n resolveEndpoint,\n resolveExportTimeout,\n} from '../core/options';\nimport { buildResource } from '../core/resource';\nimport { createLoggerProvider } from '../providers/logger';\nimport { createMeterProvider } from '../providers/meter';\n\nlet initialized = false;\n\n/**\n * Initialize OpenTelemetry for React Native.\n *\n * Key differences from browser init:\n * - Uses BasicTracerProvider (sdk-trace-base) instead of WebTracerProvider\n * - Only fetch instrumentation enabled (no document-load, no user-interaction, no Web Vitals)\n * - XHR disabled by default to avoid duplicate spans (RN's fetch polyfills over XHR)\n * - Uses AppState for flush instead of visibilitychange\n */\nexport async function initOtelNative(options: OtelOptions): Promise<OtelHandle> {\n if (initialized) {\n console.warn(\n '[@raccoon.ninja/otel-react] initOtelNative() has already been called. Skipping.',\n );\n return {\n shutdown: async () => {\n /* noop */\n },\n };\n }\n\n validateOptions(options);\n\n const resource = buildResource(options);\n const endpoint = resolveEndpoint(options);\n const timeout = resolveExportTimeout(options);\n\n const traceExporter = new OTLPTraceExporter({\n url: `${endpoint}/v1/traces`,\n headers: options.headers,\n timeoutMillis: timeout,\n });\n\n const tracerProvider = new BasicTracerProvider({\n resource,\n spanProcessors: [new BatchSpanProcessor(traceExporter)],\n });\n\n // BasicTracerProvider doesn't have register(), use the API directly\n trace.setGlobalTracerProvider(tracerProvider);\n\n const loggerProvider = createLoggerProvider(options, resource);\n const meterProvider = createMeterProvider(options, resource);\n\n // Listen for AppState changes for flush (React Native)\n let appStateSubscription: { remove: () => void } | null = null;\n try {\n // Dynamic import of AppState so this module doesn't crash in non-RN environments\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const { AppState } = require('react-native') as {\n AppState: {\n addEventListener: (\n type: string,\n handler: (state: string) => void,\n ) => { remove: () => void };\n };\n };\n appStateSubscription = AppState.addEventListener('change', (nextState: string) => {\n if (nextState === 'background' || nextState === 'inactive') {\n tracerProvider.forceFlush();\n loggerProvider.forceFlush();\n meterProvider.forceFlush();\n }\n });\n } catch {\n // AppState not available — skip\n }\n\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 (RN) initialized for service \"${options.serviceName}\"`,\n });\n\n initialized = true;\n\n return {\n shutdown: async () => {\n appStateSubscription?.remove();\n await Promise.all([\n tracerProvider.forceFlush(),\n loggerProvider.forceFlush(),\n meterProvider.forceFlush(),\n ]);\n await Promise.all([\n tracerProvider.shutdown(),\n loggerProvider.shutdown(),\n meterProvider.shutdown(),\n ]);\n initialized = false;\n },\n };\n}\n","import { trace, SpanStatusCode } from '@opentelemetry/api';\nimport type { OtelExtension } from '../core/options';\n\nconst TRACER_NAME = '@raccoon.ninja/otel-react/react-navigation';\n\n/**\n * Extension for React Navigation route-change tracing.\n *\n * This extension pre-registers the tracer scope. Actual navigation\n * tracking requires hooking into React Navigation's onStateChange\n * in the consuming app.\n *\n * @example\n * ```tsx\n * import { withReactNavigation, createNavigationTracker } from '@raccoon.ninja/otel-react/native';\n *\n * const otel = await initOtelNative({\n * serviceName: 'my-rn-app',\n * extensions: [withReactNavigation()],\n * });\n * ```\n */\nexport function withReactNavigation(): OtelExtension {\n return () => {\n trace.getTracer(TRACER_NAME, '1.0.0');\n };\n}\n\n/**\n * Creates a navigation state change handler that records route changes as spans.\n *\n * @returns A function suitable for React Navigation's onStateChange prop.\n */\nexport function createNavigationTracker() {\n const tracer = trace.getTracer(TRACER_NAME, '1.0.0');\n let previousRouteName: string | undefined;\n\n return (state: { routes: Array<{ name: string }>; index: number } | undefined) => {\n if (!state) return;\n\n const currentRoute = state.routes[state.index];\n if (!currentRoute) return;\n\n const currentRouteName = currentRoute.name;\n\n if (previousRouteName && previousRouteName !== currentRouteName) {\n const span = tracer.startSpan('navigation.route_change');\n span.setAttribute('navigation.from', previousRouteName);\n span.setAttribute('navigation.to', currentRouteName);\n span.setStatus({ code: SpanStatusCode.OK });\n span.end();\n }\n\n previousRouteName = currentRouteName;\n };\n}\n"]}
1
+ {"version":3,"sources":["../../src/core/options.ts","../../src/core/resource.ts","../../src/providers/logger.ts","../../src/providers/meter.ts","../../src/native/init.ts","../../src/native/navigation.ts"],"names":["trace"],"mappings":"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","file":"index.mjs","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 = '0.0.2';\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 { 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 { trace } from '@opentelemetry/api';\nimport { BasicTracerProvider, BatchSpanProcessor } from '@opentelemetry/sdk-trace-base';\nimport { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';\nimport { SeverityNumber } from '@opentelemetry/api-logs';\nimport type { OtelOptions, OtelHandle } from '../core/options';\nimport { validateOptions, resolveEndpoint, resolveExportTimeout } from '../core/options';\nimport { buildResource } from '../core/resource';\nimport { createLoggerProvider } from '../providers/logger';\nimport { createMeterProvider } from '../providers/meter';\n\nlet initialized = false;\n\n/**\n * Initialize OpenTelemetry for React Native.\n *\n * Key differences from browser init:\n * - Uses BasicTracerProvider (sdk-trace-base) instead of WebTracerProvider\n * - Only fetch instrumentation enabled (no document-load, no user-interaction, no Web Vitals)\n * - XHR disabled by default to avoid duplicate spans (RN's fetch polyfills over XHR)\n * - Uses AppState for flush instead of visibilitychange\n */\nexport async function initOtelNative(options: OtelOptions): Promise<OtelHandle> {\n if (initialized) {\n console.warn('[@raccoon.ninja/otel-react] initOtelNative() has already been called. Skipping.');\n return {\n shutdown: async () => {\n /* noop */\n },\n };\n }\n\n validateOptions(options);\n\n const resource = buildResource(options);\n const endpoint = resolveEndpoint(options);\n const timeout = resolveExportTimeout(options);\n\n const traceExporter = new OTLPTraceExporter({\n url: `${endpoint}/v1/traces`,\n headers: options.headers,\n timeoutMillis: timeout,\n });\n\n const tracerProvider = new BasicTracerProvider({\n resource,\n spanProcessors: [new BatchSpanProcessor(traceExporter)],\n });\n\n // BasicTracerProvider doesn't have register(), use the API directly\n trace.setGlobalTracerProvider(tracerProvider);\n\n const loggerProvider = createLoggerProvider(options, resource);\n const meterProvider = createMeterProvider(options, resource);\n\n // Listen for AppState changes for flush (React Native)\n let appStateSubscription: { remove: () => void } | null = null;\n try {\n // Dynamic import of AppState so this module doesn't crash in non-RN environments\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const { AppState } = require('react-native') as {\n AppState: {\n addEventListener: (\n type: string,\n handler: (state: string) => void,\n ) => { remove: () => void };\n };\n };\n appStateSubscription = AppState.addEventListener('change', (nextState: string) => {\n if (nextState === 'background' || nextState === 'inactive') {\n tracerProvider.forceFlush();\n loggerProvider.forceFlush();\n meterProvider.forceFlush();\n }\n });\n } catch {\n // AppState not available — skip\n }\n\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 (RN) initialized for service \"${options.serviceName}\"`,\n });\n\n initialized = true;\n\n return {\n shutdown: async () => {\n appStateSubscription?.remove();\n await Promise.all([\n tracerProvider.forceFlush(),\n loggerProvider.forceFlush(),\n meterProvider.forceFlush(),\n ]);\n await Promise.all([\n tracerProvider.shutdown(),\n loggerProvider.shutdown(),\n meterProvider.shutdown(),\n ]);\n initialized = false;\n },\n };\n}\n","import { trace, SpanStatusCode } from '@opentelemetry/api';\nimport type { OtelExtension } from '../core/options';\n\nconst TRACER_NAME = '@raccoon.ninja/otel-react/react-navigation';\n\n/**\n * Extension for React Navigation route-change tracing.\n *\n * This extension pre-registers the tracer scope. Actual navigation\n * tracking requires hooking into React Navigation's onStateChange\n * in the consuming app.\n *\n * @example\n * ```tsx\n * import { withReactNavigation, createNavigationTracker } from '@raccoon.ninja/otel-react/native';\n *\n * const otel = await initOtelNative({\n * serviceName: 'my-rn-app',\n * extensions: [withReactNavigation()],\n * });\n * ```\n */\nexport function withReactNavigation(): OtelExtension {\n return () => {\n trace.getTracer(TRACER_NAME, '1.0.0');\n };\n}\n\n/**\n * Creates a navigation state change handler that records route changes as spans.\n *\n * @returns A function suitable for React Navigation's onStateChange prop.\n */\nexport function createNavigationTracker() {\n const tracer = trace.getTracer(TRACER_NAME, '1.0.0');\n let previousRouteName: string | undefined;\n\n return (state: { routes: Array<{ name: string }>; index: number } | undefined) => {\n if (!state) return;\n\n const currentRoute = state.routes[state.index];\n if (!currentRoute) return;\n\n const currentRouteName = currentRoute.name;\n\n if (previousRouteName && previousRouteName !== currentRouteName) {\n const span = tracer.startSpan('navigation.route_change');\n span.setAttribute('navigation.from', previousRouteName);\n span.setAttribute('navigation.to', currentRouteName);\n span.setStatus({ code: SpanStatusCode.OK });\n span.end();\n }\n\n previousRouteName = currentRouteName;\n };\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/core/options.ts","../../src/nextjs/server.ts"],"names":[],"mappings":";;;AAyEA,IAAM,gBAAA,GAAmB,uBAAA;AACzB,IAAM,sBAAA,GAAyB,GAAA;AAExB,SAAS,gBAAgB,OAAA,EAA8B;AAC5D,EAAA,OAAO,QAAQ,QAAA,IAAY,gBAAA;AAC7B;AAEO,SAAS,qBAAqB,OAAA,EAA8B;AACjE,EAAA,OAAO,QAAQ,aAAA,IAAiB,sBAAA;AAClC;AAYO,SAAS,gBAAgB,OAAA,EAA4B;AAC1D,EAAA,IAAI,CAAC,OAAA,CAAQ,WAAA,IAAe,OAAO,OAAA,CAAQ,gBAAgB,QAAA,EAAU;AACnE,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AAEA,EAAA,IAAI,OAAA,CAAQ,WAAA,CAAY,IAAA,EAAK,KAAM,QAAQ,WAAA,EAAa;AACtD,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AAEA,EAAA,IAAI,OAAA,CAAQ,aAAa,MAAA,EAAW;AAClC,IAAA,IAAI,OAAO,QAAQ,QAAA,KAAa,QAAA,IAAY,QAAQ,QAAA,CAAS,IAAA,OAAW,EAAA,EAAI;AAC1E,MAAA,MAAM,IAAI,KAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AAAA,EACF;AAEA,EAAA,IAAI,OAAA,CAAQ,kBAAkB,MAAA,EAAW;AACvC,IAAA,IAAI,OAAO,OAAA,CAAQ,aAAA,KAAkB,QAAA,IAAY,OAAA,CAAQ,iBAAiB,CAAA,EAAG;AAC3E,MAAA,MAAM,IAAI,KAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AAAA,EACF;AACF;;;ACvGA,eAAsB,eAAe,OAAA,EAA2C;AAC9E,EAAA,eAAA,CAAgB,OAAO,CAAA;AAEvB,EAAA,MAAM,OAAA,GAAU,QAAQ,GAAA,CAAI,YAAA;AAC5B,EAAA,IAAI,YAAY,MAAA,EAAQ;AACtB,IAAA,OAAA,CAAQ,IAAA;AAAA,MACN;AAAA,KACF;AACA,IAAA,OAAO,EAAE,UAAU,YAAY;AAAA,IAAC,CAAA,EAAE;AAAA,EACpC;AAEA,EAAA,MAAM,QAAA,GAAW,gBAAgB,OAAO,CAAA;AACxC,EAAA,MAAM,OAAA,GAAU,qBAAqB,OAAO,CAAA;AAK5C,EAAA,MAAM,EAAE,mBAAA,EAAqB,kBAAA,EAAmB,GAAI,MAAM,OACxD,+BACF,CAAA;AACA,EAAA,MAAM,EAAE,iBAAA,EAAkB,GAAI,MAAM,OAAO,yCAAyC,CAAA;AACpF,EAAA,MAAM,EAAE,eAAA,EAAgB,GAAI,MAAM,OAAO,wCAAwC,CAAA;AACjF,EAAA,MAAM,EAAE,cAAA,EAAgB,uBAAA,EAAwB,GAAI,MAAM,OAAO,yBAAyB,CAAA;AAC1F,EAAA,MAAM,EAAE,sBAAA,EAAuB,GAAI,MAAM,OAAO,0BAA0B,CAAA;AAC1E,EAAA,MAAM,EAAE,iBAAA,EAAmB,oBAAA,EAAsB,oCAAmC,GAClF,MAAM,OAAO,qCAAqC,CAAA;AACpD,EAAA,MAAM,EAAE,KAAA,EAAM,GAAI,MAAM,OAAO,oBAAoB,CAAA;AACnD,EAAA,MAAM,EAAE,IAAA,EAAK,GAAI,MAAM,OAAO,yBAAyB,CAAA;AAEvD,EAAA,MAAM,UAAA,GAAqC;AAAA,IACzC,CAAC,iBAAiB,GAAG,OAAA,CAAQ,WAAA;AAAA,IAC7B,oBAAA,EAAsB,2BAAA;AAAA,IACtB,uBAAA,EAAyB;AAAA,GAC3B;AAEA,EAAA,IAAI,QAAQ,cAAA,EAAgB;AAC1B,IAAA,UAAA,CAAW,oBAAoB,IAAI,OAAA,CAAQ,cAAA;AAAA,EAC7C;AACA,EAAA,IAAI,QAAQ,WAAA,EAAa;AACvB,IAAA,UAAA,CAAW,kCAAkC,IAAI,OAAA,CAAQ,WAAA;AAAA,EAC3D;AACA,EAAA,IAAI,QAAQ,kBAAA,EAAoB;AAC9B,IAAA,MAAA,CAAO,MAAA,CAAO,UAAA,EAAY,OAAA,CAAQ,kBAAkB,CAAA;AAAA,EACtD;AAEA,EAAA,MAAM,QAAA,GAAW,uBAAuB,UAAU,CAAA;AAElD,EAAA,MAAM,aAAA,GAAgB,IAAI,iBAAA,CAAkB;AAAA,IAC1C,GAAA,EAAK,GAAG,QAAQ,CAAA,UAAA,CAAA;AAAA,IAChB,SAAS,OAAA,CAAQ,OAAA;AAAA,IACjB,aAAA,EAAe;AAAA,GAChB,CAAA;AAED,EAAA,MAAM,cAAA,GAAiB,IAAI,mBAAA,CAAoB;AAAA,IAC7C,QAAA;AAAA,IACA,cAAA,EAAgB,CAAC,IAAI,kBAAA,CAAmB,aAAa,CAAC;AAAA,GACvD,CAAA;AAED,EAAA,KAAA,CAAM,wBAAwB,cAAc,CAAA;AAE5C,EAAA,MAAM,WAAA,GAAc,IAAI,eAAA,CAAgB;AAAA,IACtC,GAAA,EAAK,GAAG,QAAQ,CAAA,QAAA,CAAA;AAAA,IAChB,SAAS,OAAA,CAAQ,OAAA;AAAA,IACjB,aAAA,EAAe;AAAA,GAChB,CAAA;AAED,EAAA,MAAM,cAAA,GAAiB,IAAI,cAAA,CAAe,EAAE,UAAU,CAAA;AACtD,EAAA,cAAA,CAAe,qBAAA,CAAsB,IAAI,uBAAA,CAAwB,WAAW,CAAC,CAAA;AAC7E,EAAA,IAAA,CAAK,wBAAwB,cAAc,CAAA;AAE3C,EAAA,OAAO;AAAA,IACL,UAAU,YAAY;AACpB,MAAA,MAAM,OAAA,CAAQ,IAAI,CAAC,cAAA,CAAe,YAAW,EAAG,cAAA,CAAe,UAAA,EAAY,CAAC,CAAA;AAC5E,MAAA,MAAM,OAAA,CAAQ,IAAI,CAAC,cAAA,CAAe,UAAS,EAAG,cAAA,CAAe,QAAA,EAAU,CAAC,CAAA;AAAA,IAC1E;AAAA,GACF;AACF","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 type { OtelOptions, OtelHandle } from '../core/options';\nimport { validateOptions, resolveEndpoint, resolveExportTimeout } from '../core/options';\n\n/**\n * Initialize OpenTelemetry for Next.js server-side (instrumentation.ts).\n *\n * This function wraps the Node.js OTel SDK setup for use in Next.js's\n * `instrumentation.ts` file.\n *\n * @example\n * ```typescript\n * // instrumentation.ts\n * import { initOtelServer } from '@raccoon.ninja/otel-react/nextjs';\n *\n * export function register() {\n * initOtelServer({ serviceName: 'my-nextjs-app' });\n * }\n * ```\n */\nexport async function initOtelServer(options: OtelOptions): Promise<OtelHandle> {\n validateOptions(options);\n\n const runtime = process.env.NEXT_RUNTIME;\n if (runtime === 'edge') {\n console.warn(\n '[@raccoon.ninja/otel-react] Edge runtime detected. Server OTel is limited to Node.js runtime.',\n );\n return { shutdown: async () => {} };\n }\n\n const endpoint = resolveEndpoint(options);\n const timeout = resolveExportTimeout(options);\n\n // Dynamic imports to prevent bundling Node.js SDK in client builds.\n // These packages must be installed separately by the user as they are\n // Node.js-only and not included in this package's dependencies.\n const { BasicTracerProvider, BatchSpanProcessor } = await import(\n '@opentelemetry/sdk-trace-base'\n );\n const { OTLPTraceExporter } = await import('@opentelemetry/exporter-trace-otlp-http');\n const { OTLPLogExporter } = await import('@opentelemetry/exporter-logs-otlp-http');\n const { LoggerProvider, BatchLogRecordProcessor } = await import('@opentelemetry/sdk-logs');\n const { resourceFromAttributes } = await import('@opentelemetry/resources');\n const { ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION, SEMRESATTRS_DEPLOYMENT_ENVIRONMENT } =\n await import('@opentelemetry/semantic-conventions');\n const { trace } = await import('@opentelemetry/api');\n const { logs } = await import('@opentelemetry/api-logs');\n\n const attributes: Record<string, string> = {\n [ATTR_SERVICE_NAME]: options.serviceName,\n 'telemetry.sdk.name': '@raccoon.ninja/otel-react',\n 'telemetry.sdk.version': '1.0.0',\n };\n\n if (options.serviceVersion) {\n attributes[ATTR_SERVICE_VERSION] = options.serviceVersion;\n }\n if (options.environment) {\n attributes[SEMRESATTRS_DEPLOYMENT_ENVIRONMENT] = options.environment;\n }\n if (options.resourceAttributes) {\n Object.assign(attributes, options.resourceAttributes);\n }\n\n const resource = resourceFromAttributes(attributes);\n\n const traceExporter = new OTLPTraceExporter({\n url: `${endpoint}/v1/traces`,\n headers: options.headers,\n timeoutMillis: timeout,\n });\n\n const tracerProvider = new BasicTracerProvider({\n resource,\n spanProcessors: [new BatchSpanProcessor(traceExporter)],\n });\n\n trace.setGlobalTracerProvider(tracerProvider);\n\n const logExporter = new OTLPLogExporter({\n url: `${endpoint}/v1/logs`,\n headers: options.headers,\n timeoutMillis: timeout,\n });\n\n const loggerProvider = new LoggerProvider({ resource });\n loggerProvider.addLogRecordProcessor(new BatchLogRecordProcessor(logExporter));\n logs.setGlobalLoggerProvider(loggerProvider);\n\n return {\n shutdown: async () => {\n await Promise.all([tracerProvider.forceFlush(), loggerProvider.forceFlush()]);\n await Promise.all([tracerProvider.shutdown(), loggerProvider.shutdown()]);\n },\n };\n}\n"]}
1
+ {"version":3,"sources":["../../src/core/options.ts","../../src/nextjs/server.ts"],"names":[],"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 type { OtelOptions, OtelHandle } from '../core/options';\nimport { validateOptions, resolveEndpoint, resolveExportTimeout } from '../core/options';\n\n/**\n * Initialize OpenTelemetry for Next.js server-side (instrumentation.ts).\n *\n * This function wraps the Node.js OTel SDK setup for use in Next.js's\n * `instrumentation.ts` file.\n *\n * @example\n * ```typescript\n * // instrumentation.ts\n * import { initOtelServer } from '@raccoon.ninja/otel-react/nextjs';\n *\n * export function register() {\n * initOtelServer({ serviceName: 'my-nextjs-app' });\n * }\n * ```\n */\nexport async function initOtelServer(options: OtelOptions): Promise<OtelHandle> {\n validateOptions(options);\n\n const runtime = process.env.NEXT_RUNTIME;\n if (runtime === 'edge') {\n console.warn(\n '[@raccoon.ninja/otel-react] Edge runtime detected. Server OTel is limited to Node.js runtime.',\n );\n return { shutdown: async () => {} };\n }\n\n const endpoint = resolveEndpoint(options);\n const timeout = resolveExportTimeout(options);\n\n // Dynamic imports to prevent bundling Node.js SDK in client builds.\n // These packages must be installed separately by the user as they are\n // Node.js-only and not included in this package's dependencies.\n const { BasicTracerProvider, BatchSpanProcessor } = await import('@opentelemetry/sdk-trace-base');\n const { OTLPTraceExporter } = await import('@opentelemetry/exporter-trace-otlp-http');\n const { OTLPLogExporter } = await import('@opentelemetry/exporter-logs-otlp-http');\n const { LoggerProvider, BatchLogRecordProcessor } = await import('@opentelemetry/sdk-logs');\n const { resourceFromAttributes } = await import('@opentelemetry/resources');\n const { ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION, SEMRESATTRS_DEPLOYMENT_ENVIRONMENT } =\n await import('@opentelemetry/semantic-conventions');\n const { trace } = await import('@opentelemetry/api');\n const { logs } = await import('@opentelemetry/api-logs');\n\n const attributes: Record<string, string> = {\n [ATTR_SERVICE_NAME]: options.serviceName,\n 'telemetry.sdk.name': '@raccoon.ninja/otel-react',\n 'telemetry.sdk.version': '1.0.0',\n };\n\n if (options.serviceVersion) {\n attributes[ATTR_SERVICE_VERSION] = options.serviceVersion;\n }\n if (options.environment) {\n attributes[SEMRESATTRS_DEPLOYMENT_ENVIRONMENT] = options.environment;\n }\n if (options.resourceAttributes) {\n Object.assign(attributes, options.resourceAttributes);\n }\n\n const resource = resourceFromAttributes(attributes);\n\n const traceExporter = new OTLPTraceExporter({\n url: `${endpoint}/v1/traces`,\n headers: options.headers,\n timeoutMillis: timeout,\n });\n\n const tracerProvider = new BasicTracerProvider({\n resource,\n spanProcessors: [new BatchSpanProcessor(traceExporter)],\n });\n\n trace.setGlobalTracerProvider(tracerProvider);\n\n const logExporter = new OTLPLogExporter({\n url: `${endpoint}/v1/logs`,\n headers: options.headers,\n timeoutMillis: timeout,\n });\n\n const loggerProvider = new LoggerProvider({ resource });\n loggerProvider.addLogRecordProcessor(new BatchLogRecordProcessor(logExporter));\n logs.setGlobalLoggerProvider(loggerProvider);\n\n return {\n shutdown: async () => {\n await Promise.all([tracerProvider.forceFlush(), loggerProvider.forceFlush()]);\n await Promise.all([tracerProvider.shutdown(), loggerProvider.shutdown()]);\n },\n };\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/core/options.ts","../../src/nextjs/server.ts"],"names":[],"mappings":"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","file":"index.mjs","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 type { OtelOptions, OtelHandle } from '../core/options';\nimport { validateOptions, resolveEndpoint, resolveExportTimeout } from '../core/options';\n\n/**\n * Initialize OpenTelemetry for Next.js server-side (instrumentation.ts).\n *\n * This function wraps the Node.js OTel SDK setup for use in Next.js's\n * `instrumentation.ts` file.\n *\n * @example\n * ```typescript\n * // instrumentation.ts\n * import { initOtelServer } from '@raccoon.ninja/otel-react/nextjs';\n *\n * export function register() {\n * initOtelServer({ serviceName: 'my-nextjs-app' });\n * }\n * ```\n */\nexport async function initOtelServer(options: OtelOptions): Promise<OtelHandle> {\n validateOptions(options);\n\n const runtime = process.env.NEXT_RUNTIME;\n if (runtime === 'edge') {\n console.warn(\n '[@raccoon.ninja/otel-react] Edge runtime detected. Server OTel is limited to Node.js runtime.',\n );\n return { shutdown: async () => {} };\n }\n\n const endpoint = resolveEndpoint(options);\n const timeout = resolveExportTimeout(options);\n\n // Dynamic imports to prevent bundling Node.js SDK in client builds.\n // These packages must be installed separately by the user as they are\n // Node.js-only and not included in this package's dependencies.\n const { BasicTracerProvider, BatchSpanProcessor } = await import(\n '@opentelemetry/sdk-trace-base'\n );\n const { OTLPTraceExporter } = await import('@opentelemetry/exporter-trace-otlp-http');\n const { OTLPLogExporter } = await import('@opentelemetry/exporter-logs-otlp-http');\n const { LoggerProvider, BatchLogRecordProcessor } = await import('@opentelemetry/sdk-logs');\n const { resourceFromAttributes } = await import('@opentelemetry/resources');\n const { ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION, SEMRESATTRS_DEPLOYMENT_ENVIRONMENT } =\n await import('@opentelemetry/semantic-conventions');\n const { trace } = await import('@opentelemetry/api');\n const { logs } = await import('@opentelemetry/api-logs');\n\n const attributes: Record<string, string> = {\n [ATTR_SERVICE_NAME]: options.serviceName,\n 'telemetry.sdk.name': '@raccoon.ninja/otel-react',\n 'telemetry.sdk.version': '1.0.0',\n };\n\n if (options.serviceVersion) {\n attributes[ATTR_SERVICE_VERSION] = options.serviceVersion;\n }\n if (options.environment) {\n attributes[SEMRESATTRS_DEPLOYMENT_ENVIRONMENT] = options.environment;\n }\n if (options.resourceAttributes) {\n Object.assign(attributes, options.resourceAttributes);\n }\n\n const resource = resourceFromAttributes(attributes);\n\n const traceExporter = new OTLPTraceExporter({\n url: `${endpoint}/v1/traces`,\n headers: options.headers,\n timeoutMillis: timeout,\n });\n\n const tracerProvider = new BasicTracerProvider({\n resource,\n spanProcessors: [new BatchSpanProcessor(traceExporter)],\n });\n\n trace.setGlobalTracerProvider(tracerProvider);\n\n const logExporter = new OTLPLogExporter({\n url: `${endpoint}/v1/logs`,\n headers: options.headers,\n timeoutMillis: timeout,\n });\n\n const loggerProvider = new LoggerProvider({ resource });\n loggerProvider.addLogRecordProcessor(new BatchLogRecordProcessor(logExporter));\n logs.setGlobalLoggerProvider(loggerProvider);\n\n return {\n shutdown: async () => {\n await Promise.all([tracerProvider.forceFlush(), loggerProvider.forceFlush()]);\n await Promise.all([tracerProvider.shutdown(), loggerProvider.shutdown()]);\n },\n };\n}\n"]}
1
+ {"version":3,"sources":["../../src/core/options.ts","../../src/nextjs/server.ts"],"names":[],"mappings":";AAyEA,IAAM,gBAAA,GAAmB,uBAAA;AACzB,IAAM,sBAAA,GAAyB,GAAA;AAExB,SAAS,gBAAgB,OAAA,EAA8B;AAC5D,EAAA,OAAO,QAAQ,QAAA,IAAY,gBAAA;AAC7B;AAEO,SAAS,qBAAqB,OAAA,EAA8B;AACjE,EAAA,OAAO,QAAQ,aAAA,IAAiB,sBAAA;AAClC;AAYO,SAAS,gBAAgB,OAAA,EAA4B;AAC1D,EAAA,IAAI,CAAC,OAAA,CAAQ,WAAA,IAAe,OAAO,OAAA,CAAQ,gBAAgB,QAAA,EAAU;AACnE,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AAEA,EAAA,IAAI,OAAA,CAAQ,WAAA,CAAY,IAAA,EAAK,KAAM,QAAQ,WAAA,EAAa;AACtD,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AAEA,EAAA,IAAI,OAAA,CAAQ,aAAa,MAAA,EAAW;AAClC,IAAA,IAAI,OAAO,QAAQ,QAAA,KAAa,QAAA,IAAY,QAAQ,QAAA,CAAS,IAAA,OAAW,EAAA,EAAI;AAC1E,MAAA,MAAM,IAAI,KAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AAAA,EACF;AAEA,EAAA,IAAI,OAAA,CAAQ,kBAAkB,MAAA,EAAW;AACvC,IAAA,IAAI,OAAO,OAAA,CAAQ,aAAA,KAAkB,QAAA,IAAY,OAAA,CAAQ,iBAAiB,CAAA,EAAG;AAC3E,MAAA,MAAM,IAAI,KAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AAAA,EACF;AACF;;;ACvGA,eAAsB,eAAe,OAAA,EAA2C;AAC9E,EAAA,eAAA,CAAgB,OAAO,CAAA;AAEvB,EAAA,MAAM,OAAA,GAAU,QAAQ,GAAA,CAAI,YAAA;AAC5B,EAAA,IAAI,YAAY,MAAA,EAAQ;AACtB,IAAA,OAAA,CAAQ,IAAA;AAAA,MACN;AAAA,KACF;AACA,IAAA,OAAO,EAAE,UAAU,YAAY;AAAA,IAAC,CAAA,EAAE;AAAA,EACpC;AAEA,EAAA,MAAM,QAAA,GAAW,gBAAgB,OAAO,CAAA;AACxC,EAAA,MAAM,OAAA,GAAU,qBAAqB,OAAO,CAAA;AAK5C,EAAA,MAAM,EAAE,mBAAA,EAAqB,kBAAA,EAAmB,GAAI,MAAM,OAAO,+BAA+B,CAAA;AAChG,EAAA,MAAM,EAAE,iBAAA,EAAkB,GAAI,MAAM,OAAO,yCAAyC,CAAA;AACpF,EAAA,MAAM,EAAE,eAAA,EAAgB,GAAI,MAAM,OAAO,wCAAwC,CAAA;AACjF,EAAA,MAAM,EAAE,cAAA,EAAgB,uBAAA,EAAwB,GAAI,MAAM,OAAO,yBAAyB,CAAA;AAC1F,EAAA,MAAM,EAAE,sBAAA,EAAuB,GAAI,MAAM,OAAO,0BAA0B,CAAA;AAC1E,EAAA,MAAM,EAAE,iBAAA,EAAmB,oBAAA,EAAsB,oCAAmC,GAClF,MAAM,OAAO,qCAAqC,CAAA;AACpD,EAAA,MAAM,EAAE,KAAA,EAAM,GAAI,MAAM,OAAO,oBAAoB,CAAA;AACnD,EAAA,MAAM,EAAE,IAAA,EAAK,GAAI,MAAM,OAAO,yBAAyB,CAAA;AAEvD,EAAA,MAAM,UAAA,GAAqC;AAAA,IACzC,CAAC,iBAAiB,GAAG,OAAA,CAAQ,WAAA;AAAA,IAC7B,oBAAA,EAAsB,2BAAA;AAAA,IACtB,uBAAA,EAAyB;AAAA,GAC3B;AAEA,EAAA,IAAI,QAAQ,cAAA,EAAgB;AAC1B,IAAA,UAAA,CAAW,oBAAoB,IAAI,OAAA,CAAQ,cAAA;AAAA,EAC7C;AACA,EAAA,IAAI,QAAQ,WAAA,EAAa;AACvB,IAAA,UAAA,CAAW,kCAAkC,IAAI,OAAA,CAAQ,WAAA;AAAA,EAC3D;AACA,EAAA,IAAI,QAAQ,kBAAA,EAAoB;AAC9B,IAAA,MAAA,CAAO,MAAA,CAAO,UAAA,EAAY,OAAA,CAAQ,kBAAkB,CAAA;AAAA,EACtD;AAEA,EAAA,MAAM,QAAA,GAAW,uBAAuB,UAAU,CAAA;AAElD,EAAA,MAAM,aAAA,GAAgB,IAAI,iBAAA,CAAkB;AAAA,IAC1C,GAAA,EAAK,GAAG,QAAQ,CAAA,UAAA,CAAA;AAAA,IAChB,SAAS,OAAA,CAAQ,OAAA;AAAA,IACjB,aAAA,EAAe;AAAA,GAChB,CAAA;AAED,EAAA,MAAM,cAAA,GAAiB,IAAI,mBAAA,CAAoB;AAAA,IAC7C,QAAA;AAAA,IACA,cAAA,EAAgB,CAAC,IAAI,kBAAA,CAAmB,aAAa,CAAC;AAAA,GACvD,CAAA;AAED,EAAA,KAAA,CAAM,wBAAwB,cAAc,CAAA;AAE5C,EAAA,MAAM,WAAA,GAAc,IAAI,eAAA,CAAgB;AAAA,IACtC,GAAA,EAAK,GAAG,QAAQ,CAAA,QAAA,CAAA;AAAA,IAChB,SAAS,OAAA,CAAQ,OAAA;AAAA,IACjB,aAAA,EAAe;AAAA,GAChB,CAAA;AAED,EAAA,MAAM,cAAA,GAAiB,IAAI,cAAA,CAAe,EAAE,UAAU,CAAA;AACtD,EAAA,cAAA,CAAe,qBAAA,CAAsB,IAAI,uBAAA,CAAwB,WAAW,CAAC,CAAA;AAC7E,EAAA,IAAA,CAAK,wBAAwB,cAAc,CAAA;AAE3C,EAAA,OAAO;AAAA,IACL,UAAU,YAAY;AACpB,MAAA,MAAM,OAAA,CAAQ,IAAI,CAAC,cAAA,CAAe,YAAW,EAAG,cAAA,CAAe,UAAA,EAAY,CAAC,CAAA;AAC5E,MAAA,MAAM,OAAA,CAAQ,IAAI,CAAC,cAAA,CAAe,UAAS,EAAG,cAAA,CAAe,QAAA,EAAU,CAAC,CAAA;AAAA,IAC1E;AAAA,GACF;AACF","file":"index.mjs","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 type { OtelOptions, OtelHandle } from '../core/options';\nimport { validateOptions, resolveEndpoint, resolveExportTimeout } from '../core/options';\n\n/**\n * Initialize OpenTelemetry for Next.js server-side (instrumentation.ts).\n *\n * This function wraps the Node.js OTel SDK setup for use in Next.js's\n * `instrumentation.ts` file.\n *\n * @example\n * ```typescript\n * // instrumentation.ts\n * import { initOtelServer } from '@raccoon.ninja/otel-react/nextjs';\n *\n * export function register() {\n * initOtelServer({ serviceName: 'my-nextjs-app' });\n * }\n * ```\n */\nexport async function initOtelServer(options: OtelOptions): Promise<OtelHandle> {\n validateOptions(options);\n\n const runtime = process.env.NEXT_RUNTIME;\n if (runtime === 'edge') {\n console.warn(\n '[@raccoon.ninja/otel-react] Edge runtime detected. Server OTel is limited to Node.js runtime.',\n );\n return { shutdown: async () => {} };\n }\n\n const endpoint = resolveEndpoint(options);\n const timeout = resolveExportTimeout(options);\n\n // Dynamic imports to prevent bundling Node.js SDK in client builds.\n // These packages must be installed separately by the user as they are\n // Node.js-only and not included in this package's dependencies.\n const { BasicTracerProvider, BatchSpanProcessor } = await import('@opentelemetry/sdk-trace-base');\n const { OTLPTraceExporter } = await import('@opentelemetry/exporter-trace-otlp-http');\n const { OTLPLogExporter } = await import('@opentelemetry/exporter-logs-otlp-http');\n const { LoggerProvider, BatchLogRecordProcessor } = await import('@opentelemetry/sdk-logs');\n const { resourceFromAttributes } = await import('@opentelemetry/resources');\n const { ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION, SEMRESATTRS_DEPLOYMENT_ENVIRONMENT } =\n await import('@opentelemetry/semantic-conventions');\n const { trace } = await import('@opentelemetry/api');\n const { logs } = await import('@opentelemetry/api-logs');\n\n const attributes: Record<string, string> = {\n [ATTR_SERVICE_NAME]: options.serviceName,\n 'telemetry.sdk.name': '@raccoon.ninja/otel-react',\n 'telemetry.sdk.version': '1.0.0',\n };\n\n if (options.serviceVersion) {\n attributes[ATTR_SERVICE_VERSION] = options.serviceVersion;\n }\n if (options.environment) {\n attributes[SEMRESATTRS_DEPLOYMENT_ENVIRONMENT] = options.environment;\n }\n if (options.resourceAttributes) {\n Object.assign(attributes, options.resourceAttributes);\n }\n\n const resource = resourceFromAttributes(attributes);\n\n const traceExporter = new OTLPTraceExporter({\n url: `${endpoint}/v1/traces`,\n headers: options.headers,\n timeoutMillis: timeout,\n });\n\n const tracerProvider = new BasicTracerProvider({\n resource,\n spanProcessors: [new BatchSpanProcessor(traceExporter)],\n });\n\n trace.setGlobalTracerProvider(tracerProvider);\n\n const logExporter = new OTLPLogExporter({\n url: `${endpoint}/v1/logs`,\n headers: options.headers,\n timeoutMillis: timeout,\n });\n\n const loggerProvider = new LoggerProvider({ resource });\n loggerProvider.addLogRecordProcessor(new BatchLogRecordProcessor(logExporter));\n logs.setGlobalLoggerProvider(loggerProvider);\n\n return {\n shutdown: async () => {\n await Promise.all([tracerProvider.forceFlush(), loggerProvider.forceFlush()]);\n await Promise.all([tracerProvider.shutdown(), loggerProvider.shutdown()]);\n },\n };\n}\n"]}
package/package.json CHANGED
@@ -1,9 +1,13 @@
1
1
  {
2
2
  "name": "@raccoon.ninja/otel-react",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
4
4
  "description": "Drop-in OpenTelemetry instrumentation for React, React Native, and Next.js",
5
5
  "author": "raccoon.ninja",
6
6
  "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/brenordv/npm-raccoon-otel.git"
10
+ },
7
11
  "exports": {
8
12
  ".": {
9
13
  "import": {
@@ -58,6 +62,7 @@
58
62
  "test": "vitest run",
59
63
  "test:watch": "vitest",
60
64
  "test:coverage": "vitest run --coverage",
65
+ "check": "npm run lint && npm run format:check && npm run typecheck && npm run test && npm run build",
61
66
  "prepublishOnly": "npm run build"
62
67
  },
63
68
  "peerDependencies": {