@raccoon.ninja/otel-react 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -14
- package/dist/index.cjs +17 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +14 -1
- package/dist/index.d.ts +14 -1
- package/dist/index.mjs +17 -10
- package/dist/index.mjs.map +1 -1
- package/dist/native/index.cjs +8 -6
- package/dist/native/index.cjs.map +1 -1
- package/dist/native/index.d.mts +11 -0
- package/dist/native/index.d.ts +11 -0
- package/dist/native/index.mjs +8 -6
- package/dist/native/index.mjs.map +1 -1
- package/dist/nextjs/index.cjs +5 -3
- package/dist/nextjs/index.cjs.map +1 -1
- package/dist/nextjs/index.d.mts +11 -0
- package/dist/nextjs/index.d.ts +11 -0
- package/dist/nextjs/index.mjs +5 -3
- package/dist/nextjs/index.mjs.map +1 -1
- package/package.json +33 -33
package/dist/nextjs/index.d.mts
CHANGED
|
@@ -47,6 +47,17 @@ interface OtelOptions {
|
|
|
47
47
|
* Supports string patterns or RegExp.
|
|
48
48
|
*/
|
|
49
49
|
ignoreUrls?: Array<string | RegExp>;
|
|
50
|
+
/**
|
|
51
|
+
* Cross-origin URLs that should receive W3C Trace Context headers
|
|
52
|
+
* (traceparent / tracestate). Required when the frontend calls APIs
|
|
53
|
+
* on a different origin and you want end-to-end distributed traces.
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* ```ts
|
|
57
|
+
* propagateTraceHeaderCorsUrls: [/api\.example\.com/, 'https://my-backend.local']
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
60
|
+
propagateTraceHeaderCorsUrls?: Array<string | RegExp>;
|
|
50
61
|
/** Extension functions for opt-in instrumentations. */
|
|
51
62
|
extensions?: OtelExtension[];
|
|
52
63
|
}
|
package/dist/nextjs/index.d.ts
CHANGED
|
@@ -47,6 +47,17 @@ interface OtelOptions {
|
|
|
47
47
|
* Supports string patterns or RegExp.
|
|
48
48
|
*/
|
|
49
49
|
ignoreUrls?: Array<string | RegExp>;
|
|
50
|
+
/**
|
|
51
|
+
* Cross-origin URLs that should receive W3C Trace Context headers
|
|
52
|
+
* (traceparent / tracestate). Required when the frontend calls APIs
|
|
53
|
+
* on a different origin and you want end-to-end distributed traces.
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* ```ts
|
|
57
|
+
* propagateTraceHeaderCorsUrls: [/api\.example\.com/, 'https://my-backend.local']
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
60
|
+
propagateTraceHeaderCorsUrls?: Array<string | RegExp>;
|
|
50
61
|
/** Extension functions for opt-in instrumentations. */
|
|
51
62
|
extensions?: OtelExtension[];
|
|
52
63
|
}
|
package/dist/nextjs/index.mjs
CHANGED
|
@@ -58,7 +58,7 @@ async function initOtelServer(options) {
|
|
|
58
58
|
const attributes = {
|
|
59
59
|
[ATTR_SERVICE_NAME]: options.serviceName,
|
|
60
60
|
"telemetry.sdk.name": "@raccoon.ninja/otel-react",
|
|
61
|
-
"telemetry.sdk.version": "1.
|
|
61
|
+
"telemetry.sdk.version": "1.1.0"
|
|
62
62
|
};
|
|
63
63
|
if (options.serviceVersion) {
|
|
64
64
|
attributes[ATTR_SERVICE_VERSION] = options.serviceVersion;
|
|
@@ -85,8 +85,10 @@ async function initOtelServer(options) {
|
|
|
85
85
|
headers: options.headers,
|
|
86
86
|
timeoutMillis: timeout
|
|
87
87
|
});
|
|
88
|
-
const loggerProvider = new LoggerProvider({
|
|
89
|
-
|
|
88
|
+
const loggerProvider = new LoggerProvider({
|
|
89
|
+
resource,
|
|
90
|
+
processors: [new BatchLogRecordProcessor(logExporter)]
|
|
91
|
+
});
|
|
90
92
|
logs.setGlobalLoggerProvider(loggerProvider);
|
|
91
93
|
return {
|
|
92
94
|
shutdown: async () => {
|
|
@@ -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('@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
|
+
{"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 /**\n * Cross-origin URLs that should receive W3C Trace Context headers\n * (traceparent / tracestate). Required when the frontend calls APIs\n * on a different origin and you want end-to-end distributed traces.\n *\n * @example\n * ```ts\n * propagateTraceHeaderCorsUrls: [/api\\.example\\.com/, 'https://my-backend.local']\n * ```\n */\n propagateTraceHeaderCorsUrls?: Array<string | RegExp>;\n\n /** Extension functions for opt-in instrumentations. */\n extensions?: OtelExtension[];\n}\n\n/** Handle returned from initOtel() for lifecycle management. */\nexport interface OtelHandle {\n /** Flush all pending telemetry and shut down providers. */\n shutdown: () => Promise<void>;\n}\n\nconst DEFAULT_ENDPOINT = 'http://localhost:4318';\nconst DEFAULT_EXPORT_TIMEOUT = 30000;\n\nexport function resolveEndpoint(options: OtelOptions): string {\n return options.endpoint ?? DEFAULT_ENDPOINT;\n}\n\nexport function resolveExportTimeout(options: OtelOptions): number {\n return options.exportTimeout ?? DEFAULT_EXPORT_TIMEOUT;\n}\n\nexport function resolveInstrumentations(options: OtelOptions): Required<InstrumentationConfig> {\n return {\n fetch: options.instrumentations?.fetch ?? true,\n xhr: options.instrumentations?.xhr ?? true,\n documentLoad: options.instrumentations?.documentLoad ?? true,\n userInteraction: options.instrumentations?.userInteraction ?? true,\n webVitals: options.instrumentations?.webVitals ?? true,\n };\n}\n\nexport function validateOptions(options: OtelOptions): void {\n if (!options.serviceName || typeof options.serviceName !== 'string') {\n throw new Error(\n '[@raccoon.ninja/otel-react] serviceName is required and must be a non-empty string.',\n );\n }\n\n if (options.serviceName.trim() !== options.serviceName) {\n throw new Error(\n '[@raccoon.ninja/otel-react] serviceName must not have leading or trailing whitespace.',\n );\n }\n\n if (options.endpoint !== undefined) {\n if (typeof options.endpoint !== 'string' || options.endpoint.trim() === '') {\n throw new Error(\n '[@raccoon.ninja/otel-react] endpoint must be a non-empty string when provided.',\n );\n }\n }\n\n if (options.exportTimeout !== undefined) {\n if (typeof options.exportTimeout !== 'number' || options.exportTimeout <= 0) {\n throw new Error(\n '[@raccoon.ninja/otel-react] exportTimeout must be a positive number when provided.',\n );\n }\n }\n}\n","import 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.1.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({\n resource,\n processors: [new BatchLogRecordProcessor(logExporter)],\n });\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,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@raccoon.ninja/otel-react",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Drop-in OpenTelemetry instrumentation for React, React Native, and Next.js",
|
|
5
5
|
"author": "raccoon.ninja",
|
|
6
6
|
"license": "MIT",
|
|
@@ -92,39 +92,39 @@
|
|
|
92
92
|
},
|
|
93
93
|
"dependencies": {
|
|
94
94
|
"@opentelemetry/api": "^1.9.0",
|
|
95
|
-
"@opentelemetry/api-logs": "^0.
|
|
96
|
-
"@opentelemetry/sdk-trace-web": "^2.
|
|
97
|
-
"@opentelemetry/sdk-trace-base": "^2.
|
|
98
|
-
"@opentelemetry/sdk-metrics": "^2.
|
|
99
|
-
"@opentelemetry/sdk-logs": "^0.
|
|
100
|
-
"@opentelemetry/exporter-trace-otlp-http": "^0.
|
|
101
|
-
"@opentelemetry/exporter-logs-otlp-http": "^0.
|
|
102
|
-
"@opentelemetry/exporter-metrics-otlp-http": "^0.
|
|
103
|
-
"@opentelemetry/resources": "^2.
|
|
104
|
-
"@opentelemetry/semantic-conventions": "^1.
|
|
105
|
-
"@opentelemetry/instrumentation": "^0.
|
|
106
|
-
"@opentelemetry/instrumentation-fetch": "^0.
|
|
107
|
-
"@opentelemetry/instrumentation-xml-http-request": "^0.
|
|
108
|
-
"@opentelemetry/instrumentation-document-load": "^0.
|
|
109
|
-
"@opentelemetry/instrumentation-user-interaction": "^0.
|
|
110
|
-
"web-vitals": "^
|
|
95
|
+
"@opentelemetry/api-logs": "^0.213.0",
|
|
96
|
+
"@opentelemetry/sdk-trace-web": "^2.6.0",
|
|
97
|
+
"@opentelemetry/sdk-trace-base": "^2.6.0",
|
|
98
|
+
"@opentelemetry/sdk-metrics": "^2.6.0",
|
|
99
|
+
"@opentelemetry/sdk-logs": "^0.213.0",
|
|
100
|
+
"@opentelemetry/exporter-trace-otlp-http": "^0.213.0",
|
|
101
|
+
"@opentelemetry/exporter-logs-otlp-http": "^0.213.0",
|
|
102
|
+
"@opentelemetry/exporter-metrics-otlp-http": "^0.213.0",
|
|
103
|
+
"@opentelemetry/resources": "^2.6.0",
|
|
104
|
+
"@opentelemetry/semantic-conventions": "^1.40.0",
|
|
105
|
+
"@opentelemetry/instrumentation": "^0.213.0",
|
|
106
|
+
"@opentelemetry/instrumentation-fetch": "^0.213.0",
|
|
107
|
+
"@opentelemetry/instrumentation-xml-http-request": "^0.213.0",
|
|
108
|
+
"@opentelemetry/instrumentation-document-load": "^0.58.0",
|
|
109
|
+
"@opentelemetry/instrumentation-user-interaction": "^0.57.0",
|
|
110
|
+
"web-vitals": "^5.1.0"
|
|
111
111
|
},
|
|
112
112
|
"devDependencies": {
|
|
113
|
-
"@testing-library/react": "^16.
|
|
114
|
-
"@testing-library/jest-dom": "^6.
|
|
115
|
-
"@types/react": "^19.
|
|
116
|
-
"@types/react-dom": "^19.
|
|
117
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
118
|
-
"@typescript-eslint/parser": "^8.
|
|
119
|
-
"@vitest/coverage-v8": "^
|
|
120
|
-
"eslint": "^9.
|
|
121
|
-
"eslint-plugin-react-hooks": "^
|
|
122
|
-
"jsdom": "^
|
|
123
|
-
"prettier": "^3.
|
|
124
|
-
"react": "^19.
|
|
125
|
-
"react-dom": "^19.
|
|
126
|
-
"tsup": "^8.
|
|
127
|
-
"typescript": "^5.
|
|
128
|
-
"vitest": "^
|
|
113
|
+
"@testing-library/react": "^16.3.2",
|
|
114
|
+
"@testing-library/jest-dom": "^6.9.1",
|
|
115
|
+
"@types/react": "^19.2.14",
|
|
116
|
+
"@types/react-dom": "^19.2.3",
|
|
117
|
+
"@typescript-eslint/eslint-plugin": "^8.56.1",
|
|
118
|
+
"@typescript-eslint/parser": "^8.56.1",
|
|
119
|
+
"@vitest/coverage-v8": "^4.0.18",
|
|
120
|
+
"eslint": "^9.39.4",
|
|
121
|
+
"eslint-plugin-react-hooks": "^7.0.1",
|
|
122
|
+
"jsdom": "^28.1.0",
|
|
123
|
+
"prettier": "^3.8.1",
|
|
124
|
+
"react": "^19.2.4",
|
|
125
|
+
"react-dom": "^19.2.4",
|
|
126
|
+
"tsup": "^8.5.1",
|
|
127
|
+
"typescript": "^5.9.3",
|
|
128
|
+
"vitest": "^4.0.18"
|
|
129
129
|
}
|
|
130
130
|
}
|