@sentry/react-router 10.27.0 → 10.28.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.
@@ -38,7 +38,7 @@ function instrumentHydratedRouter() {
38
38
  pageloadSpan.updateName(parameterizePageloadRoute);
39
39
  pageloadSpan.setAttributes({
40
40
  [core.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route',
41
- [core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.pageload.react-router',
41
+ [core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.pageload.react_router',
42
42
  });
43
43
  }
44
44
 
@@ -74,7 +74,7 @@ function instrumentHydratedRouter() {
74
74
  navigationSpan.updateName(parameterizedNavRoute);
75
75
  navigationSpan.setAttributes({
76
76
  [core.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route',
77
- [core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.navigation.react-router',
77
+ [core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.navigation.react_router',
78
78
  });
79
79
  }
80
80
  });
@@ -115,7 +115,7 @@ function maybeCreateNavigationTransaction(name, source) {
115
115
  attributes: {
116
116
  [core.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: source,
117
117
  [core.SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'navigation',
118
- [core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.navigation.react-router',
118
+ [core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.navigation.react_router',
119
119
  },
120
120
  });
121
121
  }
@@ -1 +1 @@
1
- {"version":3,"file":"hydratedRouter.js","sources":["../../../src/client/hydratedRouter.ts"],"sourcesContent":["import { startBrowserTracingNavigationSpan } from '@sentry/browser';\nimport type { Span } from '@sentry/core';\nimport {\n consoleSandbox,\n getActiveSpan,\n getClient,\n getRootSpan,\n GLOBAL_OBJ,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n spanToJSON,\n} from '@sentry/core';\nimport type { DataRouter, RouterState } from 'react-router';\nimport { DEBUG_BUILD } from '../common/debug-build';\n\nconst GLOBAL_OBJ_WITH_DATA_ROUTER = GLOBAL_OBJ as typeof GLOBAL_OBJ & {\n __reactRouterDataRouter?: DataRouter;\n};\n\nconst MAX_RETRIES = 40; // 2 seconds at 50ms interval\n\n/**\n * Instruments the React Router Data Router for pageloads and navigation.\n *\n * This function waits for the router to be available after hydration, then:\n * 1. Updates the pageload transaction with parameterized route info\n * 2. Patches router.navigate() to create navigation transactions\n * 3. Subscribes to router state changes to update navigation transactions with parameterized routes\n */\nexport function instrumentHydratedRouter(): void {\n function trySubscribe(): boolean {\n const router = GLOBAL_OBJ_WITH_DATA_ROUTER.__reactRouterDataRouter;\n\n if (router) {\n // The first time we hit the router, we try to update the pageload transaction\n // todo: update pageload tx here\n const pageloadSpan = getActiveRootSpan();\n\n if (pageloadSpan) {\n const pageloadName = spanToJSON(pageloadSpan).description;\n const parameterizePageloadRoute = getParameterizedRoute(router.state);\n if (\n pageloadName &&\n // this event is for the currently active pageload\n normalizePathname(router.state.location.pathname) === normalizePathname(pageloadName)\n ) {\n pageloadSpan.updateName(parameterizePageloadRoute);\n pageloadSpan.setAttributes({\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.pageload.react-router',\n });\n }\n\n // Patching navigate for creating accurate navigation transactions\n if (typeof router.navigate === 'function') {\n const originalNav = router.navigate.bind(router);\n router.navigate = function sentryPatchedNavigate(...args) {\n maybeCreateNavigationTransaction(\n String(args[0]) || '<unknown route>', // will be updated anyway\n 'url', // this also will be updated once we have the parameterized route\n );\n return originalNav(...args);\n };\n }\n }\n\n // Subscribe to router state changes to update navigation transactions with parameterized routes\n router.subscribe(newState => {\n const navigationSpan = getActiveRootSpan();\n\n if (!navigationSpan) {\n return;\n }\n\n const navigationSpanName = spanToJSON(navigationSpan).description;\n const parameterizedNavRoute = getParameterizedRoute(newState);\n\n if (\n navigationSpanName &&\n newState.navigation.state === 'idle' && // navigation has completed\n normalizePathname(newState.location.pathname) === normalizePathname(navigationSpanName) // this event is for the currently active navigation\n ) {\n navigationSpan.updateName(parameterizedNavRoute);\n navigationSpan.setAttributes({\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.navigation.react-router',\n });\n }\n });\n return true;\n }\n return false;\n }\n\n // Wait until the router is available (since the SDK loads before hydration)\n if (!trySubscribe()) {\n let retryCount = 0;\n // Retry until the router is available or max retries reached\n const interval = setInterval(() => {\n if (trySubscribe() || retryCount >= MAX_RETRIES) {\n if (retryCount >= MAX_RETRIES) {\n DEBUG_BUILD &&\n consoleSandbox(() => {\n // eslint-disable-next-line no-console\n console.warn('Unable to instrument React Router: router not found after hydration.');\n });\n }\n clearInterval(interval);\n }\n retryCount++;\n }, 50);\n }\n}\n\nfunction maybeCreateNavigationTransaction(name: string, source: 'url' | 'route'): Span | undefined {\n const client = getClient();\n\n if (!client) {\n return undefined;\n }\n\n return startBrowserTracingNavigationSpan(client, {\n name,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: source,\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'navigation',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.navigation.react-router',\n },\n });\n}\n\nfunction getActiveRootSpan(): Span | undefined {\n const activeSpan = getActiveSpan();\n if (!activeSpan) {\n return undefined;\n }\n\n const rootSpan = getRootSpan(activeSpan);\n\n const op = spanToJSON(rootSpan).op;\n\n // Only use this root span if it is a pageload or navigation span\n return op === 'navigation' || op === 'pageload' ? rootSpan : undefined;\n}\n\nfunction getParameterizedRoute(routerState: RouterState): string {\n const lastMatch = routerState.matches[routerState.matches.length - 1];\n return normalizePathname(lastMatch?.route.path ?? routerState.location.pathname);\n}\n\nfunction normalizePathname(pathname: string): string {\n // Ensure it starts with a single slash\n let normalized = pathname.startsWith('/') ? pathname : `/${pathname}`;\n // Remove trailing slash unless it's the root\n if (normalized.length > 1 && normalized.endsWith('/')) {\n normalized = normalized.slice(0, -1);\n }\n return normalized;\n}\n"],"names":["GLOBAL_OBJ","spanToJSON","SEMANTIC_ATTRIBUTE_SENTRY_SOURCE","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","DEBUG_BUILD","consoleSandbox","getClient","startBrowserTracingNavigationSpan","SEMANTIC_ATTRIBUTE_SENTRY_OP","getActiveSpan","getRootSpan"],"mappings":"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"}
1
+ {"version":3,"file":"hydratedRouter.js","sources":["../../../src/client/hydratedRouter.ts"],"sourcesContent":["import { startBrowserTracingNavigationSpan } from '@sentry/browser';\nimport type { Span } from '@sentry/core';\nimport {\n consoleSandbox,\n getActiveSpan,\n getClient,\n getRootSpan,\n GLOBAL_OBJ,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n spanToJSON,\n} from '@sentry/core';\nimport type { DataRouter, RouterState } from 'react-router';\nimport { DEBUG_BUILD } from '../common/debug-build';\n\nconst GLOBAL_OBJ_WITH_DATA_ROUTER = GLOBAL_OBJ as typeof GLOBAL_OBJ & {\n __reactRouterDataRouter?: DataRouter;\n};\n\nconst MAX_RETRIES = 40; // 2 seconds at 50ms interval\n\n/**\n * Instruments the React Router Data Router for pageloads and navigation.\n *\n * This function waits for the router to be available after hydration, then:\n * 1. Updates the pageload transaction with parameterized route info\n * 2. Patches router.navigate() to create navigation transactions\n * 3. Subscribes to router state changes to update navigation transactions with parameterized routes\n */\nexport function instrumentHydratedRouter(): void {\n function trySubscribe(): boolean {\n const router = GLOBAL_OBJ_WITH_DATA_ROUTER.__reactRouterDataRouter;\n\n if (router) {\n // The first time we hit the router, we try to update the pageload transaction\n // todo: update pageload tx here\n const pageloadSpan = getActiveRootSpan();\n\n if (pageloadSpan) {\n const pageloadName = spanToJSON(pageloadSpan).description;\n const parameterizePageloadRoute = getParameterizedRoute(router.state);\n if (\n pageloadName &&\n // this event is for the currently active pageload\n normalizePathname(router.state.location.pathname) === normalizePathname(pageloadName)\n ) {\n pageloadSpan.updateName(parameterizePageloadRoute);\n pageloadSpan.setAttributes({\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.pageload.react_router',\n });\n }\n\n // Patching navigate for creating accurate navigation transactions\n if (typeof router.navigate === 'function') {\n const originalNav = router.navigate.bind(router);\n router.navigate = function sentryPatchedNavigate(...args) {\n maybeCreateNavigationTransaction(\n String(args[0]) || '<unknown route>', // will be updated anyway\n 'url', // this also will be updated once we have the parameterized route\n );\n return originalNav(...args);\n };\n }\n }\n\n // Subscribe to router state changes to update navigation transactions with parameterized routes\n router.subscribe(newState => {\n const navigationSpan = getActiveRootSpan();\n\n if (!navigationSpan) {\n return;\n }\n\n const navigationSpanName = spanToJSON(navigationSpan).description;\n const parameterizedNavRoute = getParameterizedRoute(newState);\n\n if (\n navigationSpanName &&\n newState.navigation.state === 'idle' && // navigation has completed\n normalizePathname(newState.location.pathname) === normalizePathname(navigationSpanName) // this event is for the currently active navigation\n ) {\n navigationSpan.updateName(parameterizedNavRoute);\n navigationSpan.setAttributes({\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.navigation.react_router',\n });\n }\n });\n return true;\n }\n return false;\n }\n\n // Wait until the router is available (since the SDK loads before hydration)\n if (!trySubscribe()) {\n let retryCount = 0;\n // Retry until the router is available or max retries reached\n const interval = setInterval(() => {\n if (trySubscribe() || retryCount >= MAX_RETRIES) {\n if (retryCount >= MAX_RETRIES) {\n DEBUG_BUILD &&\n consoleSandbox(() => {\n // eslint-disable-next-line no-console\n console.warn('Unable to instrument React Router: router not found after hydration.');\n });\n }\n clearInterval(interval);\n }\n retryCount++;\n }, 50);\n }\n}\n\nfunction maybeCreateNavigationTransaction(name: string, source: 'url' | 'route'): Span | undefined {\n const client = getClient();\n\n if (!client) {\n return undefined;\n }\n\n return startBrowserTracingNavigationSpan(client, {\n name,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: source,\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'navigation',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.navigation.react_router',\n },\n });\n}\n\nfunction getActiveRootSpan(): Span | undefined {\n const activeSpan = getActiveSpan();\n if (!activeSpan) {\n return undefined;\n }\n\n const rootSpan = getRootSpan(activeSpan);\n\n const op = spanToJSON(rootSpan).op;\n\n // Only use this root span if it is a pageload or navigation span\n return op === 'navigation' || op === 'pageload' ? rootSpan : undefined;\n}\n\nfunction getParameterizedRoute(routerState: RouterState): string {\n const lastMatch = routerState.matches[routerState.matches.length - 1];\n return normalizePathname(lastMatch?.route.path ?? routerState.location.pathname);\n}\n\nfunction normalizePathname(pathname: string): string {\n // Ensure it starts with a single slash\n let normalized = pathname.startsWith('/') ? pathname : `/${pathname}`;\n // Remove trailing slash unless it's the root\n if (normalized.length > 1 && normalized.endsWith('/')) {\n normalized = normalized.slice(0, -1);\n }\n return normalized;\n}\n"],"names":["GLOBAL_OBJ","spanToJSON","SEMANTIC_ATTRIBUTE_SENTRY_SOURCE","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","DEBUG_BUILD","consoleSandbox","getClient","startBrowserTracingNavigationSpan","SEMANTIC_ATTRIBUTE_SENTRY_OP","getActiveSpan","getRootSpan"],"mappings":"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"}
@@ -80,14 +80,14 @@ class ReactRouterInstrumentation extends instrumentation.InstrumentationBase {
80
80
  core.updateSpanName(rootSpan, `${request.method} ${target}`);
81
81
  rootSpan.setAttributes({
82
82
  [core.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',
83
- [core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react-router.server',
83
+ [core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react_router.server',
84
84
  });
85
85
 
86
86
  return core.startSpan(
87
87
  {
88
88
  name: util.getSpanName(url.pathname, request.method),
89
89
  attributes: {
90
- [core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react-router.server',
90
+ [core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react_router.server',
91
91
  [core.SEMANTIC_ATTRIBUTE_SENTRY_OP]: util.getOpName(url.pathname, request.method),
92
92
  },
93
93
  },
@@ -1 +1 @@
1
- {"version":3,"file":"reactRouter.js","sources":["../../../../src/server/instrumentation/reactRouter.ts"],"sourcesContent":["import type { InstrumentationConfig } from '@opentelemetry/instrumentation';\nimport { InstrumentationBase, InstrumentationNodeModuleDefinition } from '@opentelemetry/instrumentation';\nimport { SEMATTRS_HTTP_TARGET } from '@opentelemetry/semantic-conventions';\nimport {\n debug,\n getActiveSpan,\n getRootSpan,\n SDK_VERSION,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n spanToJSON,\n startSpan,\n updateSpanName,\n} from '@sentry/core';\nimport type * as reactRouter from 'react-router';\nimport { DEBUG_BUILD } from '../../common/debug-build';\nimport { getOpName, getSpanName, isDataRequest } from './util';\n\ntype ReactRouterModuleExports = typeof reactRouter;\n\nconst supportedVersions = ['>=7.0.0'];\nconst COMPONENT = 'react-router';\n\n/**\n * Instrumentation for React Router's server request handler.\n * This patches the requestHandler function to add Sentry performance monitoring for data loaders.\n */\nexport class ReactRouterInstrumentation extends InstrumentationBase<InstrumentationConfig> {\n public constructor(config: InstrumentationConfig = {}) {\n super('ReactRouterInstrumentation', SDK_VERSION, config);\n }\n\n /**\n * Initializes the instrumentation by defining the React Router server modules to be patched.\n */\n // eslint-disable-next-line @typescript-eslint/naming-convention\n protected init(): InstrumentationNodeModuleDefinition {\n const reactRouterServerModule = new InstrumentationNodeModuleDefinition(\n COMPONENT,\n supportedVersions,\n (moduleExports: ReactRouterModuleExports) => {\n return this._createPatchedModuleProxy(moduleExports);\n },\n (_moduleExports: unknown) => {\n // nothing to unwrap here\n return _moduleExports;\n },\n );\n\n return reactRouterServerModule;\n }\n\n /**\n * Creates a proxy around the React Router module exports that patches the createRequestHandler function.\n * This allows us to wrap the request handler to add performance monitoring for data loaders and actions.\n */\n private _createPatchedModuleProxy(moduleExports: ReactRouterModuleExports): ReactRouterModuleExports {\n return new Proxy(moduleExports, {\n get(target, prop, receiver) {\n if (prop === 'createRequestHandler') {\n const original = target[prop];\n return function sentryWrappedCreateRequestHandler(this: unknown, ...args: unknown[]) {\n const originalRequestHandler = original.apply(this, args);\n\n return async function sentryWrappedRequestHandler(request: Request, initialContext?: unknown) {\n let url: URL;\n try {\n url = new URL(request.url);\n } catch {\n return originalRequestHandler(request, initialContext);\n }\n\n // We currently just want to trace loaders and actions\n if (!isDataRequest(url.pathname)) {\n return originalRequestHandler(request, initialContext);\n }\n\n const activeSpan = getActiveSpan();\n const rootSpan = activeSpan && getRootSpan(activeSpan);\n\n if (!rootSpan) {\n DEBUG_BUILD && debug.log('No active root span found, skipping tracing for data request');\n return originalRequestHandler(request, initialContext);\n }\n\n // We cannot rely on the regular span name inferral here, as the express instrumentation sets `*` as the route\n // So we force this to be a more sensible name here\n // TODO: try to set derived parameterized route from build here (args[0])\n const spanData = spanToJSON(rootSpan);\n // eslint-disable-next-line deprecation/deprecation\n const target = spanData.data[SEMATTRS_HTTP_TARGET] || url.pathname;\n updateSpanName(rootSpan, `${request.method} ${target}`);\n rootSpan.setAttributes({\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react-router.server',\n });\n\n return startSpan(\n {\n name: getSpanName(url.pathname, request.method),\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react-router.server',\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: getOpName(url.pathname, request.method),\n },\n },\n () => {\n return originalRequestHandler(request, initialContext);\n },\n );\n };\n };\n }\n return Reflect.get(target, prop, receiver);\n },\n });\n }\n}\n"],"names":["InstrumentationBase","SDK_VERSION","InstrumentationNodeModuleDefinition","isDataRequest","getActiveSpan","getRootSpan","DEBUG_BUILD","debug","spanToJSON","SEMATTRS_HTTP_TARGET","updateSpanName","SEMANTIC_ATTRIBUTE_SENTRY_SOURCE","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","startSpan","getSpanName","SEMANTIC_ATTRIBUTE_SENTRY_OP","getOpName"],"mappings":"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"}
1
+ {"version":3,"file":"reactRouter.js","sources":["../../../../src/server/instrumentation/reactRouter.ts"],"sourcesContent":["import type { InstrumentationConfig } from '@opentelemetry/instrumentation';\nimport { InstrumentationBase, InstrumentationNodeModuleDefinition } from '@opentelemetry/instrumentation';\nimport { SEMATTRS_HTTP_TARGET } from '@opentelemetry/semantic-conventions';\nimport {\n debug,\n getActiveSpan,\n getRootSpan,\n SDK_VERSION,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n spanToJSON,\n startSpan,\n updateSpanName,\n} from '@sentry/core';\nimport type * as reactRouter from 'react-router';\nimport { DEBUG_BUILD } from '../../common/debug-build';\nimport { getOpName, getSpanName, isDataRequest } from './util';\n\ntype ReactRouterModuleExports = typeof reactRouter;\n\nconst supportedVersions = ['>=7.0.0'];\nconst COMPONENT = 'react-router';\n\n/**\n * Instrumentation for React Router's server request handler.\n * This patches the requestHandler function to add Sentry performance monitoring for data loaders.\n */\nexport class ReactRouterInstrumentation extends InstrumentationBase<InstrumentationConfig> {\n public constructor(config: InstrumentationConfig = {}) {\n super('ReactRouterInstrumentation', SDK_VERSION, config);\n }\n\n /**\n * Initializes the instrumentation by defining the React Router server modules to be patched.\n */\n // eslint-disable-next-line @typescript-eslint/naming-convention\n protected init(): InstrumentationNodeModuleDefinition {\n const reactRouterServerModule = new InstrumentationNodeModuleDefinition(\n COMPONENT,\n supportedVersions,\n (moduleExports: ReactRouterModuleExports) => {\n return this._createPatchedModuleProxy(moduleExports);\n },\n (_moduleExports: unknown) => {\n // nothing to unwrap here\n return _moduleExports;\n },\n );\n\n return reactRouterServerModule;\n }\n\n /**\n * Creates a proxy around the React Router module exports that patches the createRequestHandler function.\n * This allows us to wrap the request handler to add performance monitoring for data loaders and actions.\n */\n private _createPatchedModuleProxy(moduleExports: ReactRouterModuleExports): ReactRouterModuleExports {\n return new Proxy(moduleExports, {\n get(target, prop, receiver) {\n if (prop === 'createRequestHandler') {\n const original = target[prop];\n return function sentryWrappedCreateRequestHandler(this: unknown, ...args: unknown[]) {\n const originalRequestHandler = original.apply(this, args);\n\n return async function sentryWrappedRequestHandler(request: Request, initialContext?: unknown) {\n let url: URL;\n try {\n url = new URL(request.url);\n } catch {\n return originalRequestHandler(request, initialContext);\n }\n\n // We currently just want to trace loaders and actions\n if (!isDataRequest(url.pathname)) {\n return originalRequestHandler(request, initialContext);\n }\n\n const activeSpan = getActiveSpan();\n const rootSpan = activeSpan && getRootSpan(activeSpan);\n\n if (!rootSpan) {\n DEBUG_BUILD && debug.log('No active root span found, skipping tracing for data request');\n return originalRequestHandler(request, initialContext);\n }\n\n // We cannot rely on the regular span name inferral here, as the express instrumentation sets `*` as the route\n // So we force this to be a more sensible name here\n // TODO: try to set derived parameterized route from build here (args[0])\n const spanData = spanToJSON(rootSpan);\n // eslint-disable-next-line deprecation/deprecation\n const target = spanData.data[SEMATTRS_HTTP_TARGET] || url.pathname;\n updateSpanName(rootSpan, `${request.method} ${target}`);\n rootSpan.setAttributes({\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react_router.server',\n });\n\n return startSpan(\n {\n name: getSpanName(url.pathname, request.method),\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react_router.server',\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: getOpName(url.pathname, request.method),\n },\n },\n () => {\n return originalRequestHandler(request, initialContext);\n },\n );\n };\n };\n }\n return Reflect.get(target, prop, receiver);\n },\n });\n }\n}\n"],"names":["InstrumentationBase","SDK_VERSION","InstrumentationNodeModuleDefinition","isDataRequest","getActiveSpan","getRootSpan","DEBUG_BUILD","debug","spanToJSON","SEMATTRS_HTTP_TARGET","updateSpanName","SEMANTIC_ATTRIBUTE_SENTRY_SOURCE","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","startSpan","getSpanName","SEMANTIC_ATTRIBUTE_SENTRY_OP","getOpName"],"mappings":"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"}
@@ -41,7 +41,7 @@ function wrapSentryHandleRequest(
41
41
  rootSpan.setAttributes({
42
42
  [semanticConventions.ATTR_HTTP_ROUTE]: routeName,
43
43
  [core.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route',
44
- [core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react-router.request-handler',
44
+ [core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react_router.request_handler',
45
45
  });
46
46
  }
47
47
 
@@ -1 +1 @@
1
- {"version":3,"file":"wrapSentryHandleRequest.js","sources":["../../../src/server/wrapSentryHandleRequest.ts"],"sourcesContent":["import { context } from '@opentelemetry/api';\nimport { getRPCMetadata, RPCType } from '@opentelemetry/core';\nimport { ATTR_HTTP_ROUTE } from '@opentelemetry/semantic-conventions';\nimport {\n flushIfServerless,\n getActiveSpan,\n getRootSpan,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n} from '@sentry/core';\nimport type { AppLoadContext, EntryContext, RouterContextProvider } from 'react-router';\n\ntype OriginalHandleRequestWithoutMiddleware = (\n request: Request,\n responseStatusCode: number,\n responseHeaders: Headers,\n routerContext: EntryContext,\n loadContext: AppLoadContext,\n) => Promise<unknown>;\n\ntype OriginalHandleRequestWithMiddleware = (\n request: Request,\n responseStatusCode: number,\n responseHeaders: Headers,\n routerContext: EntryContext,\n loadContext: RouterContextProvider,\n) => Promise<unknown>;\n\n/**\n * Wraps the original handleRequest function to add Sentry instrumentation.\n *\n * @param originalHandle - The original handleRequest function to wrap\n * @returns A wrapped version of the handle request function with Sentry instrumentation\n */\nexport function wrapSentryHandleRequest(\n originalHandle: OriginalHandleRequestWithoutMiddleware,\n): OriginalHandleRequestWithoutMiddleware;\n/**\n * Wraps the original handleRequest function to add Sentry instrumentation.\n *\n * @param originalHandle - The original handleRequest function to wrap\n * @returns A wrapped version of the handle request function with Sentry instrumentation\n */\nexport function wrapSentryHandleRequest(\n originalHandle: OriginalHandleRequestWithMiddleware,\n): OriginalHandleRequestWithMiddleware;\n/**\n * Wraps the original handleRequest function to add Sentry instrumentation.\n *\n * @param originalHandle - The original handleRequest function to wrap\n * @returns A wrapped version of the handle request function with Sentry instrumentation\n */\nexport function wrapSentryHandleRequest(\n originalHandle: OriginalHandleRequestWithoutMiddleware | OriginalHandleRequestWithMiddleware,\n): OriginalHandleRequestWithoutMiddleware | OriginalHandleRequestWithMiddleware {\n return async function sentryInstrumentedHandleRequest(\n request: Request,\n responseStatusCode: number,\n responseHeaders: Headers,\n routerContext: EntryContext,\n loadContext: AppLoadContext | RouterContextProvider,\n ) {\n const parameterizedPath =\n routerContext?.staticHandlerContext?.matches?.[routerContext.staticHandlerContext.matches.length - 1]?.route.path;\n\n const activeSpan = getActiveSpan();\n const rootSpan = activeSpan ? getRootSpan(activeSpan) : undefined;\n\n if (parameterizedPath && rootSpan) {\n const routeName = `/${parameterizedPath}`;\n\n // The express instrumentation writes on the rpcMetadata and that ends up stomping on the `http.route` attribute.\n const rpcMetadata = getRPCMetadata(context.active());\n\n if (rpcMetadata?.type === RPCType.HTTP) {\n rpcMetadata.route = routeName;\n }\n\n // The span exporter picks up the `http.route` (ATTR_HTTP_ROUTE) attribute to set the transaction name\n rootSpan.setAttributes({\n [ATTR_HTTP_ROUTE]: routeName,\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react-router.request-handler',\n });\n }\n\n try {\n // Type guard to call the correct overload based on loadContext type\n if (isRouterContextProvider(loadContext)) {\n // loadContext is RouterContextProvider\n return await (originalHandle as OriginalHandleRequestWithMiddleware)(\n request,\n responseStatusCode,\n responseHeaders,\n routerContext,\n loadContext,\n );\n } else {\n // loadContext is AppLoadContext\n return await (originalHandle as OriginalHandleRequestWithoutMiddleware)(\n request,\n responseStatusCode,\n responseHeaders,\n routerContext,\n loadContext,\n );\n }\n } finally {\n await flushIfServerless();\n }\n\n /**\n * Helper type guard to determine if the context is a RouterContextProvider.\n *\n * @param ctx - The context to check\n * @returns True if the context is a RouterContextProvider\n */\n function isRouterContextProvider(ctx: AppLoadContext | RouterContextProvider): ctx is RouterContextProvider {\n return typeof (ctx as RouterContextProvider)?.get === 'function';\n }\n };\n}\n\n// todo(v11): remove this\n/** @deprecated Use `wrapSentryHandleRequest` instead. */\nexport const sentryHandleRequest = wrapSentryHandleRequest;\n"],"names":["getActiveSpan","getRootSpan","getRPCMetadata","context","RPCType","ATTR_HTTP_ROUTE","SEMANTIC_ATTRIBUTE_SENTRY_SOURCE","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","flushIfServerless"],"mappings":";;;;;;;AA8CA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,uBAAuB;AACvC,EAAE,cAAc;AAChB,EAAgF;AAChF,EAAE,OAAO,eAAe,+BAA+B;AACvD,IAAI,OAAO;AACX,IAAI,kBAAkB;AACtB,IAAI,eAAe;AACnB,IAAI,aAAa;AACjB,IAAI,WAAW;AACf,IAAI;AACJ,IAAI,MAAM,iBAAA;AACV,MAAM,aAAa,EAAE,oBAAoB,EAAE,OAAO,GAAG,aAAa,CAAC,oBAAoB,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,EAAE,KAAK,CAAC,IAAI;;AAEvH,IAAI,MAAM,UAAA,GAAaA,kBAAa,EAAE;AACtC,IAAI,MAAM,QAAA,GAAW,UAAA,GAAaC,gBAAW,CAAC,UAAU,CAAA,GAAI,SAAS;;AAErE,IAAI,IAAI,iBAAA,IAAqB,QAAQ,EAAE;AACvC,MAAM,MAAM,YAAY,CAAC,CAAC,EAAE,iBAAiB,CAAC,CAAA;;AAEA;AACA,MAAA,MAAA,WAAA,GAAAC,qBAAA,CAAAC,WAAA,CAAA,MAAA,EAAA,CAAA;;AAEA,MAAA,IAAA,WAAA,EAAA,IAAA,KAAAC,cAAA,CAAA,IAAA,EAAA;AACA,QAAA,WAAA,CAAA,KAAA,GAAA,SAAA;AACA,MAAA;;AAEA;AACA,MAAA,QAAA,CAAA,aAAA,CAAA;AACA,QAAA,CAAAC,mCAAA,GAAA,SAAA;AACA,QAAA,CAAAC,qCAAA,GAAA,OAAA;AACA,QAAA,CAAAC,qCAAA,GAAA,wCAAA;AACA,OAAA,CAAA;AACA,IAAA;;AAEA,IAAA,IAAA;AACA;AACA,MAAA,IAAA,uBAAA,CAAA,WAAA,CAAA,EAAA;AACA;AACA,QAAA,OAAA,MAAA,CAAA,cAAA;AACA,UAAA,OAAA;AACA,UAAA,kBAAA;AACA,UAAA,eAAA;AACA,UAAA,aAAA;AACA,UAAA,WAAA;AACA,SAAA;AACA,MAAA,CAAA,MAAA;AACA;AACA,QAAA,OAAA,MAAA,CAAA,cAAA;AACA,UAAA,OAAA;AACA,UAAA,kBAAA;AACA,UAAA,eAAA;AACA,UAAA,aAAA;AACA,UAAA,WAAA;AACA,SAAA;AACA,MAAA;AACA,IAAA,CAAA,SAAA;AACA,MAAA,MAAAC,sBAAA,EAAA;AACA,IAAA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,IAAA,SAAA,uBAAA,CAAA,GAAA,EAAA;AACA,MAAA,OAAA,OAAA,CAAA,GAAA,IAAA,GAAA,KAAA,UAAA;AACA,IAAA;AACA,EAAA,CAAA;AACA;;AAEA;AACA;AACA,MAAA,mBAAA,GAAA;;;;;"}
1
+ {"version":3,"file":"wrapSentryHandleRequest.js","sources":["../../../src/server/wrapSentryHandleRequest.ts"],"sourcesContent":["import { context } from '@opentelemetry/api';\nimport { getRPCMetadata, RPCType } from '@opentelemetry/core';\nimport { ATTR_HTTP_ROUTE } from '@opentelemetry/semantic-conventions';\nimport {\n flushIfServerless,\n getActiveSpan,\n getRootSpan,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n} from '@sentry/core';\nimport type { AppLoadContext, EntryContext, RouterContextProvider } from 'react-router';\n\ntype OriginalHandleRequestWithoutMiddleware = (\n request: Request,\n responseStatusCode: number,\n responseHeaders: Headers,\n routerContext: EntryContext,\n loadContext: AppLoadContext,\n) => Promise<unknown>;\n\ntype OriginalHandleRequestWithMiddleware = (\n request: Request,\n responseStatusCode: number,\n responseHeaders: Headers,\n routerContext: EntryContext,\n loadContext: RouterContextProvider,\n) => Promise<unknown>;\n\n/**\n * Wraps the original handleRequest function to add Sentry instrumentation.\n *\n * @param originalHandle - The original handleRequest function to wrap\n * @returns A wrapped version of the handle request function with Sentry instrumentation\n */\nexport function wrapSentryHandleRequest(\n originalHandle: OriginalHandleRequestWithoutMiddleware,\n): OriginalHandleRequestWithoutMiddleware;\n/**\n * Wraps the original handleRequest function to add Sentry instrumentation.\n *\n * @param originalHandle - The original handleRequest function to wrap\n * @returns A wrapped version of the handle request function with Sentry instrumentation\n */\nexport function wrapSentryHandleRequest(\n originalHandle: OriginalHandleRequestWithMiddleware,\n): OriginalHandleRequestWithMiddleware;\n/**\n * Wraps the original handleRequest function to add Sentry instrumentation.\n *\n * @param originalHandle - The original handleRequest function to wrap\n * @returns A wrapped version of the handle request function with Sentry instrumentation\n */\nexport function wrapSentryHandleRequest(\n originalHandle: OriginalHandleRequestWithoutMiddleware | OriginalHandleRequestWithMiddleware,\n): OriginalHandleRequestWithoutMiddleware | OriginalHandleRequestWithMiddleware {\n return async function sentryInstrumentedHandleRequest(\n request: Request,\n responseStatusCode: number,\n responseHeaders: Headers,\n routerContext: EntryContext,\n loadContext: AppLoadContext | RouterContextProvider,\n ) {\n const parameterizedPath =\n routerContext?.staticHandlerContext?.matches?.[routerContext.staticHandlerContext.matches.length - 1]?.route.path;\n\n const activeSpan = getActiveSpan();\n const rootSpan = activeSpan ? getRootSpan(activeSpan) : undefined;\n\n if (parameterizedPath && rootSpan) {\n const routeName = `/${parameterizedPath}`;\n\n // The express instrumentation writes on the rpcMetadata and that ends up stomping on the `http.route` attribute.\n const rpcMetadata = getRPCMetadata(context.active());\n\n if (rpcMetadata?.type === RPCType.HTTP) {\n rpcMetadata.route = routeName;\n }\n\n // The span exporter picks up the `http.route` (ATTR_HTTP_ROUTE) attribute to set the transaction name\n rootSpan.setAttributes({\n [ATTR_HTTP_ROUTE]: routeName,\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react_router.request_handler',\n });\n }\n\n try {\n // Type guard to call the correct overload based on loadContext type\n if (isRouterContextProvider(loadContext)) {\n // loadContext is RouterContextProvider\n return await (originalHandle as OriginalHandleRequestWithMiddleware)(\n request,\n responseStatusCode,\n responseHeaders,\n routerContext,\n loadContext,\n );\n } else {\n // loadContext is AppLoadContext\n return await (originalHandle as OriginalHandleRequestWithoutMiddleware)(\n request,\n responseStatusCode,\n responseHeaders,\n routerContext,\n loadContext,\n );\n }\n } finally {\n await flushIfServerless();\n }\n\n /**\n * Helper type guard to determine if the context is a RouterContextProvider.\n *\n * @param ctx - The context to check\n * @returns True if the context is a RouterContextProvider\n */\n function isRouterContextProvider(ctx: AppLoadContext | RouterContextProvider): ctx is RouterContextProvider {\n return typeof (ctx as RouterContextProvider)?.get === 'function';\n }\n };\n}\n\n// todo(v11): remove this\n/** @deprecated Use `wrapSentryHandleRequest` instead. */\nexport const sentryHandleRequest = wrapSentryHandleRequest;\n"],"names":["getActiveSpan","getRootSpan","getRPCMetadata","context","RPCType","ATTR_HTTP_ROUTE","SEMANTIC_ATTRIBUTE_SENTRY_SOURCE","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","flushIfServerless"],"mappings":";;;;;;;AA8CA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,uBAAuB;AACvC,EAAE,cAAc;AAChB,EAAgF;AAChF,EAAE,OAAO,eAAe,+BAA+B;AACvD,IAAI,OAAO;AACX,IAAI,kBAAkB;AACtB,IAAI,eAAe;AACnB,IAAI,aAAa;AACjB,IAAI,WAAW;AACf,IAAI;AACJ,IAAI,MAAM,iBAAA;AACV,MAAM,aAAa,EAAE,oBAAoB,EAAE,OAAO,GAAG,aAAa,CAAC,oBAAoB,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,EAAE,KAAK,CAAC,IAAI;;AAEvH,IAAI,MAAM,UAAA,GAAaA,kBAAa,EAAE;AACtC,IAAI,MAAM,QAAA,GAAW,UAAA,GAAaC,gBAAW,CAAC,UAAU,CAAA,GAAI,SAAS;;AAErE,IAAI,IAAI,iBAAA,IAAqB,QAAQ,EAAE;AACvC,MAAM,MAAM,YAAY,CAAC,CAAC,EAAE,iBAAiB,CAAC,CAAA;;AAEA;AACA,MAAA,MAAA,WAAA,GAAAC,qBAAA,CAAAC,WAAA,CAAA,MAAA,EAAA,CAAA;;AAEA,MAAA,IAAA,WAAA,EAAA,IAAA,KAAAC,cAAA,CAAA,IAAA,EAAA;AACA,QAAA,WAAA,CAAA,KAAA,GAAA,SAAA;AACA,MAAA;;AAEA;AACA,MAAA,QAAA,CAAA,aAAA,CAAA;AACA,QAAA,CAAAC,mCAAA,GAAA,SAAA;AACA,QAAA,CAAAC,qCAAA,GAAA,OAAA;AACA,QAAA,CAAAC,qCAAA,GAAA,wCAAA;AACA,OAAA,CAAA;AACA,IAAA;;AAEA,IAAA,IAAA;AACA;AACA,MAAA,IAAA,uBAAA,CAAA,WAAA,CAAA,EAAA;AACA;AACA,QAAA,OAAA,MAAA,CAAA,cAAA;AACA,UAAA,OAAA;AACA,UAAA,kBAAA;AACA,UAAA,eAAA;AACA,UAAA,aAAA;AACA,UAAA,WAAA;AACA,SAAA;AACA,MAAA,CAAA,MAAA;AACA;AACA,QAAA,OAAA,MAAA,CAAA,cAAA;AACA,UAAA,OAAA;AACA,UAAA,kBAAA;AACA,UAAA,eAAA;AACA,UAAA,aAAA;AACA,UAAA,WAAA;AACA,SAAA;AACA,MAAA;AACA,IAAA,CAAA,SAAA;AACA,MAAA,MAAAC,sBAAA,EAAA;AACA,IAAA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,IAAA,SAAA,uBAAA,CAAA,GAAA,EAAA;AACA,MAAA,OAAA,OAAA,CAAA,GAAA,IAAA,GAAA,KAAA,UAAA;AACA,IAAA;AACA,EAAA,CAAA;AACA;;AAEA;AACA;AACA,MAAA,mBAAA,GAAA;;;;;"}
@@ -39,7 +39,7 @@ function wrapServerAction(options = {}, actionFn) {
39
39
  core.updateSpanName(root, `${args.request.method} ${target}`);
40
40
  root.setAttributes({
41
41
  [core.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',
42
- [core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react-router.action',
42
+ [core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react_router.action',
43
43
  });
44
44
  }
45
45
  }
@@ -51,7 +51,7 @@ function wrapServerAction(options = {}, actionFn) {
51
51
  name,
52
52
  ...options,
53
53
  attributes: {
54
- [core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react-router.action',
54
+ [core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react_router.action',
55
55
  [core.SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'function.react-router.action',
56
56
  ...options.attributes,
57
57
  },
@@ -1 +1 @@
1
- {"version":3,"file":"wrapServerAction.js","sources":["../../../src/server/wrapServerAction.ts"],"sourcesContent":["import { SEMATTRS_HTTP_TARGET } from '@opentelemetry/semantic-conventions';\nimport type { SpanAttributes } from '@sentry/core';\nimport {\n flushIfServerless,\n getActiveSpan,\n getRootSpan,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n spanToJSON,\n startSpan,\n updateSpanName,\n} from '@sentry/core';\nimport type { ActionFunctionArgs } from 'react-router';\n\ntype SpanOptions = {\n name?: string;\n attributes?: SpanAttributes;\n};\n\n/**\n * Wraps a React Router server action function with Sentry performance monitoring.\n * @param options - Optional span configuration options including name, operation, description and attributes\n * @param actionFn - The server action function to wrap\n *\n * @example\n * ```ts\n * // Wrap an action function with custom span options\n * export const action = wrapServerAction(\n * {\n * name: 'Submit Form Data',\n * description: 'Processes form submission data',\n * },\n * async ({ request }) => {\n * // ... your action logic\n * }\n * );\n * ```\n */\nexport function wrapServerAction<T>(options: SpanOptions = {}, actionFn: (args: ActionFunctionArgs) => Promise<T>) {\n return async function (args: ActionFunctionArgs) {\n const name = options.name || 'Executing Server Action';\n const active = getActiveSpan();\n if (active) {\n const root = getRootSpan(active);\n const spanData = spanToJSON(root);\n if (spanData.origin === 'auto.http.otel.http') {\n // eslint-disable-next-line deprecation/deprecation\n const target = spanData.data[SEMATTRS_HTTP_TARGET];\n\n if (target) {\n // We cannot rely on the regular span name inferral here, as the express instrumentation sets `*` as the route\n // So we force this to be a more sensible name here\n updateSpanName(root, `${args.request.method} ${target}`);\n root.setAttributes({\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react-router.action',\n });\n }\n }\n }\n\n try {\n return await startSpan(\n {\n name,\n ...options,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react-router.action',\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'function.react-router.action',\n ...options.attributes,\n },\n },\n () => actionFn(args),\n );\n } finally {\n await flushIfServerless();\n }\n };\n}\n"],"names":["getActiveSpan","getRootSpan","spanToJSON","SEMATTRS_HTTP_TARGET","updateSpanName","SEMANTIC_ATTRIBUTE_SENTRY_SOURCE","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","startSpan","SEMANTIC_ATTRIBUTE_SENTRY_OP","flushIfServerless"],"mappings":";;;;;AAoBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,gBAAgB,CAAI,OAAO,GAAgB,EAAE,EAAE,QAAQ,EAA4C;AACnH,EAAE,OAAO,gBAAgB,IAAI,EAAsB;AACnD,IAAI,MAAM,IAAA,GAAO,OAAO,CAAC,IAAA,IAAQ,yBAAyB;AAC1D,IAAI,MAAM,MAAA,GAASA,kBAAa,EAAE;AAClC,IAAI,IAAI,MAAM,EAAE;AAChB,MAAM,MAAM,IAAA,GAAOC,gBAAW,CAAC,MAAM,CAAC;AACtC,MAAM,MAAM,QAAA,GAAWC,eAAU,CAAC,IAAI,CAAC;AACvC,MAAM,IAAI,QAAQ,CAAC,MAAA,KAAW,qBAAqB,EAAE;AACrD;AACA,QAAQ,MAAM,SAAS,QAAQ,CAAC,IAAI,CAACC,wCAAoB,CAAC;;AAE1D,QAAQ,IAAI,MAAM,EAAE;AACpB;AACA;AACA,UAAUC,mBAAc,CAAC,IAAI,EAAE,CAAC,EAAA,IAAA,CAAA,OAAA,CAAA,MAAA,CAAA,CAAA,EAAA,MAAA,CAAA,CAAA,CAAA;AACA,UAAA,IAAA,CAAA,aAAA,CAAA;AACA,YAAA,CAAAC,qCAAA,GAAA,KAAA;AACA,YAAA,CAAAC,qCAAA,GAAA,+BAAA;AACA,WAAA,CAAA;AACA,QAAA;AACA,MAAA;AACA,IAAA;;AAEA,IAAA,IAAA;AACA,MAAA,OAAA,MAAAC,cAAA;AACA,QAAA;AACA,UAAA,IAAA;AACA,UAAA,GAAA,OAAA;AACA,UAAA,UAAA,EAAA;AACA,YAAA,CAAAD,qCAAA,GAAA,+BAAA;AACA,YAAA,CAAAE,iCAAA,GAAA,8BAAA;AACA,YAAA,GAAA,OAAA,CAAA,UAAA;AACA,WAAA;AACA,SAAA;AACA,QAAA,MAAA,QAAA,CAAA,IAAA,CAAA;AACA,OAAA;AACA,IAAA,CAAA,SAAA;AACA,MAAA,MAAAC,sBAAA,EAAA;AACA,IAAA;AACA,EAAA,CAAA;AACA;;;;"}
1
+ {"version":3,"file":"wrapServerAction.js","sources":["../../../src/server/wrapServerAction.ts"],"sourcesContent":["import { SEMATTRS_HTTP_TARGET } from '@opentelemetry/semantic-conventions';\nimport type { SpanAttributes } from '@sentry/core';\nimport {\n flushIfServerless,\n getActiveSpan,\n getRootSpan,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n spanToJSON,\n startSpan,\n updateSpanName,\n} from '@sentry/core';\nimport type { ActionFunctionArgs } from 'react-router';\n\ntype SpanOptions = {\n name?: string;\n attributes?: SpanAttributes;\n};\n\n/**\n * Wraps a React Router server action function with Sentry performance monitoring.\n * @param options - Optional span configuration options including name, operation, description and attributes\n * @param actionFn - The server action function to wrap\n *\n * @example\n * ```ts\n * // Wrap an action function with custom span options\n * export const action = wrapServerAction(\n * {\n * name: 'Submit Form Data',\n * description: 'Processes form submission data',\n * },\n * async ({ request }) => {\n * // ... your action logic\n * }\n * );\n * ```\n */\nexport function wrapServerAction<T>(options: SpanOptions = {}, actionFn: (args: ActionFunctionArgs) => Promise<T>) {\n return async function (args: ActionFunctionArgs) {\n const name = options.name || 'Executing Server Action';\n const active = getActiveSpan();\n if (active) {\n const root = getRootSpan(active);\n const spanData = spanToJSON(root);\n if (spanData.origin === 'auto.http.otel.http') {\n // eslint-disable-next-line deprecation/deprecation\n const target = spanData.data[SEMATTRS_HTTP_TARGET];\n\n if (target) {\n // We cannot rely on the regular span name inferral here, as the express instrumentation sets `*` as the route\n // So we force this to be a more sensible name here\n updateSpanName(root, `${args.request.method} ${target}`);\n root.setAttributes({\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react_router.action',\n });\n }\n }\n }\n\n try {\n return await startSpan(\n {\n name,\n ...options,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react_router.action',\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'function.react-router.action',\n ...options.attributes,\n },\n },\n () => actionFn(args),\n );\n } finally {\n await flushIfServerless();\n }\n };\n}\n"],"names":["getActiveSpan","getRootSpan","spanToJSON","SEMATTRS_HTTP_TARGET","updateSpanName","SEMANTIC_ATTRIBUTE_SENTRY_SOURCE","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","startSpan","SEMANTIC_ATTRIBUTE_SENTRY_OP","flushIfServerless"],"mappings":";;;;;AAoBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,gBAAgB,CAAI,OAAO,GAAgB,EAAE,EAAE,QAAQ,EAA4C;AACnH,EAAE,OAAO,gBAAgB,IAAI,EAAsB;AACnD,IAAI,MAAM,IAAA,GAAO,OAAO,CAAC,IAAA,IAAQ,yBAAyB;AAC1D,IAAI,MAAM,MAAA,GAASA,kBAAa,EAAE;AAClC,IAAI,IAAI,MAAM,EAAE;AAChB,MAAM,MAAM,IAAA,GAAOC,gBAAW,CAAC,MAAM,CAAC;AACtC,MAAM,MAAM,QAAA,GAAWC,eAAU,CAAC,IAAI,CAAC;AACvC,MAAM,IAAI,QAAQ,CAAC,MAAA,KAAW,qBAAqB,EAAE;AACrD;AACA,QAAQ,MAAM,SAAS,QAAQ,CAAC,IAAI,CAACC,wCAAoB,CAAC;;AAE1D,QAAQ,IAAI,MAAM,EAAE;AACpB;AACA;AACA,UAAUC,mBAAc,CAAC,IAAI,EAAE,CAAC,EAAA,IAAA,CAAA,OAAA,CAAA,MAAA,CAAA,CAAA,EAAA,MAAA,CAAA,CAAA,CAAA;AACA,UAAA,IAAA,CAAA,aAAA,CAAA;AACA,YAAA,CAAAC,qCAAA,GAAA,KAAA;AACA,YAAA,CAAAC,qCAAA,GAAA,+BAAA;AACA,WAAA,CAAA;AACA,QAAA;AACA,MAAA;AACA,IAAA;;AAEA,IAAA,IAAA;AACA,MAAA,OAAA,MAAAC,cAAA;AACA,QAAA;AACA,UAAA,IAAA;AACA,UAAA,GAAA,OAAA;AACA,UAAA,UAAA,EAAA;AACA,YAAA,CAAAD,qCAAA,GAAA,+BAAA;AACA,YAAA,CAAAE,iCAAA,GAAA,8BAAA;AACA,YAAA,GAAA,OAAA,CAAA,UAAA;AACA,WAAA;AACA,SAAA;AACA,QAAA,MAAA,QAAA,CAAA,IAAA,CAAA;AACA,OAAA;AACA,IAAA,CAAA,SAAA;AACA,MAAA,MAAAC,sBAAA,EAAA;AACA,IAAA;AACA,EAAA,CAAA;AACA;;;;"}
@@ -40,7 +40,7 @@ function wrapServerLoader(options = {}, loaderFn) {
40
40
  core.updateSpanName(root, `${args.request.method} ${target}`);
41
41
  root.setAttributes({
42
42
  [core.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',
43
- [core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react-router.loader',
43
+ [core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react_router.loader',
44
44
  });
45
45
  }
46
46
  }
@@ -51,7 +51,7 @@ function wrapServerLoader(options = {}, loaderFn) {
51
51
  name,
52
52
  ...options,
53
53
  attributes: {
54
- [core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react-router.loader',
54
+ [core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react_router.loader',
55
55
  [core.SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'function.react-router.loader',
56
56
  ...options.attributes,
57
57
  },
@@ -1 +1 @@
1
- {"version":3,"file":"wrapServerLoader.js","sources":["../../../src/server/wrapServerLoader.ts"],"sourcesContent":["import { SEMATTRS_HTTP_TARGET } from '@opentelemetry/semantic-conventions';\nimport type { SpanAttributes } from '@sentry/core';\nimport {\n flushIfServerless,\n getActiveSpan,\n getRootSpan,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n spanToJSON,\n startSpan,\n updateSpanName,\n} from '@sentry/core';\nimport type { LoaderFunctionArgs } from 'react-router';\n\ntype SpanOptions = {\n name?: string;\n attributes?: SpanAttributes;\n};\n\n/**\n * Wraps a React Router server loader function with Sentry performance monitoring.\n * @param options - Optional span configuration options including name, operation, description and attributes\n * @param loaderFn - The server loader function to wrap\n *\n * @example\n * ```ts\n * // Wrap a loader function with custom span options\n * export const loader = wrapServerLoader(\n * {\n * name: 'Load Some Data',\n * description: 'Loads some data from the db',\n * },\n * async ({ params }) => {\n * // ... your loader logic\n * }\n * );\n * ```\n */\nexport function wrapServerLoader<T>(options: SpanOptions = {}, loaderFn: (args: LoaderFunctionArgs) => Promise<T>) {\n return async function (args: LoaderFunctionArgs) {\n const name = options.name || 'Executing Server Loader';\n const active = getActiveSpan();\n\n if (active) {\n const root = getRootSpan(active);\n const spanData = spanToJSON(root);\n if (spanData.origin === 'auto.http.otel.http') {\n // eslint-disable-next-line deprecation/deprecation\n const target = spanData.data[SEMATTRS_HTTP_TARGET];\n\n if (target) {\n // We cannot rely on the regular span name inferral here, as the express instrumentation sets `*` as the route\n // So we force this to be a more sensible name here\n updateSpanName(root, `${args.request.method} ${target}`);\n root.setAttributes({\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react-router.loader',\n });\n }\n }\n }\n try {\n return await startSpan(\n {\n name,\n ...options,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react-router.loader',\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'function.react-router.loader',\n ...options.attributes,\n },\n },\n () => loaderFn(args),\n );\n } finally {\n await flushIfServerless();\n }\n };\n}\n"],"names":["getActiveSpan","getRootSpan","spanToJSON","SEMATTRS_HTTP_TARGET","updateSpanName","SEMANTIC_ATTRIBUTE_SENTRY_SOURCE","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","startSpan","SEMANTIC_ATTRIBUTE_SENTRY_OP","flushIfServerless"],"mappings":";;;;;AAoBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,gBAAgB,CAAI,OAAO,GAAgB,EAAE,EAAE,QAAQ,EAA4C;AACnH,EAAE,OAAO,gBAAgB,IAAI,EAAsB;AACnD,IAAI,MAAM,IAAA,GAAO,OAAO,CAAC,IAAA,IAAQ,yBAAyB;AAC1D,IAAI,MAAM,MAAA,GAASA,kBAAa,EAAE;;AAElC,IAAI,IAAI,MAAM,EAAE;AAChB,MAAM,MAAM,IAAA,GAAOC,gBAAW,CAAC,MAAM,CAAC;AACtC,MAAM,MAAM,QAAA,GAAWC,eAAU,CAAC,IAAI,CAAC;AACvC,MAAM,IAAI,QAAQ,CAAC,MAAA,KAAW,qBAAqB,EAAE;AACrD;AACA,QAAQ,MAAM,SAAS,QAAQ,CAAC,IAAI,CAACC,wCAAoB,CAAC;;AAE1D,QAAQ,IAAI,MAAM,EAAE;AACpB;AACA;AACA,UAAUC,mBAAc,CAAC,IAAI,EAAE,CAAC,EAAA,IAAA,CAAA,OAAA,CAAA,MAAA,CAAA,CAAA,EAAA,MAAA,CAAA,CAAA,CAAA;AACA,UAAA,IAAA,CAAA,aAAA,CAAA;AACA,YAAA,CAAAC,qCAAA,GAAA,KAAA;AACA,YAAA,CAAAC,qCAAA,GAAA,+BAAA;AACA,WAAA,CAAA;AACA,QAAA;AACA,MAAA;AACA,IAAA;AACA,IAAA,IAAA;AACA,MAAA,OAAA,MAAAC,cAAA;AACA,QAAA;AACA,UAAA,IAAA;AACA,UAAA,GAAA,OAAA;AACA,UAAA,UAAA,EAAA;AACA,YAAA,CAAAD,qCAAA,GAAA,+BAAA;AACA,YAAA,CAAAE,iCAAA,GAAA,8BAAA;AACA,YAAA,GAAA,OAAA,CAAA,UAAA;AACA,WAAA;AACA,SAAA;AACA,QAAA,MAAA,QAAA,CAAA,IAAA,CAAA;AACA,OAAA;AACA,IAAA,CAAA,SAAA;AACA,MAAA,MAAAC,sBAAA,EAAA;AACA,IAAA;AACA,EAAA,CAAA;AACA;;;;"}
1
+ {"version":3,"file":"wrapServerLoader.js","sources":["../../../src/server/wrapServerLoader.ts"],"sourcesContent":["import { SEMATTRS_HTTP_TARGET } from '@opentelemetry/semantic-conventions';\nimport type { SpanAttributes } from '@sentry/core';\nimport {\n flushIfServerless,\n getActiveSpan,\n getRootSpan,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n spanToJSON,\n startSpan,\n updateSpanName,\n} from '@sentry/core';\nimport type { LoaderFunctionArgs } from 'react-router';\n\ntype SpanOptions = {\n name?: string;\n attributes?: SpanAttributes;\n};\n\n/**\n * Wraps a React Router server loader function with Sentry performance monitoring.\n * @param options - Optional span configuration options including name, operation, description and attributes\n * @param loaderFn - The server loader function to wrap\n *\n * @example\n * ```ts\n * // Wrap a loader function with custom span options\n * export const loader = wrapServerLoader(\n * {\n * name: 'Load Some Data',\n * description: 'Loads some data from the db',\n * },\n * async ({ params }) => {\n * // ... your loader logic\n * }\n * );\n * ```\n */\nexport function wrapServerLoader<T>(options: SpanOptions = {}, loaderFn: (args: LoaderFunctionArgs) => Promise<T>) {\n return async function (args: LoaderFunctionArgs) {\n const name = options.name || 'Executing Server Loader';\n const active = getActiveSpan();\n\n if (active) {\n const root = getRootSpan(active);\n const spanData = spanToJSON(root);\n if (spanData.origin === 'auto.http.otel.http') {\n // eslint-disable-next-line deprecation/deprecation\n const target = spanData.data[SEMATTRS_HTTP_TARGET];\n\n if (target) {\n // We cannot rely on the regular span name inferral here, as the express instrumentation sets `*` as the route\n // So we force this to be a more sensible name here\n updateSpanName(root, `${args.request.method} ${target}`);\n root.setAttributes({\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react_router.loader',\n });\n }\n }\n }\n try {\n return await startSpan(\n {\n name,\n ...options,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react_router.loader',\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'function.react-router.loader',\n ...options.attributes,\n },\n },\n () => loaderFn(args),\n );\n } finally {\n await flushIfServerless();\n }\n };\n}\n"],"names":["getActiveSpan","getRootSpan","spanToJSON","SEMATTRS_HTTP_TARGET","updateSpanName","SEMANTIC_ATTRIBUTE_SENTRY_SOURCE","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","startSpan","SEMANTIC_ATTRIBUTE_SENTRY_OP","flushIfServerless"],"mappings":";;;;;AAoBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,gBAAgB,CAAI,OAAO,GAAgB,EAAE,EAAE,QAAQ,EAA4C;AACnH,EAAE,OAAO,gBAAgB,IAAI,EAAsB;AACnD,IAAI,MAAM,IAAA,GAAO,OAAO,CAAC,IAAA,IAAQ,yBAAyB;AAC1D,IAAI,MAAM,MAAA,GAASA,kBAAa,EAAE;;AAElC,IAAI,IAAI,MAAM,EAAE;AAChB,MAAM,MAAM,IAAA,GAAOC,gBAAW,CAAC,MAAM,CAAC;AACtC,MAAM,MAAM,QAAA,GAAWC,eAAU,CAAC,IAAI,CAAC;AACvC,MAAM,IAAI,QAAQ,CAAC,MAAA,KAAW,qBAAqB,EAAE;AACrD;AACA,QAAQ,MAAM,SAAS,QAAQ,CAAC,IAAI,CAACC,wCAAoB,CAAC;;AAE1D,QAAQ,IAAI,MAAM,EAAE;AACpB;AACA;AACA,UAAUC,mBAAc,CAAC,IAAI,EAAE,CAAC,EAAA,IAAA,CAAA,OAAA,CAAA,MAAA,CAAA,CAAA,EAAA,MAAA,CAAA,CAAA,CAAA;AACA,UAAA,IAAA,CAAA,aAAA,CAAA;AACA,YAAA,CAAAC,qCAAA,GAAA,KAAA;AACA,YAAA,CAAAC,qCAAA,GAAA,+BAAA;AACA,WAAA,CAAA;AACA,QAAA;AACA,MAAA;AACA,IAAA;AACA,IAAA,IAAA;AACA,MAAA,OAAA,MAAAC,cAAA;AACA,QAAA;AACA,UAAA,IAAA;AACA,UAAA,GAAA,OAAA;AACA,UAAA,UAAA,EAAA;AACA,YAAA,CAAAD,qCAAA,GAAA,+BAAA;AACA,YAAA,CAAAE,iCAAA,GAAA,8BAAA;AACA,YAAA,GAAA,OAAA,CAAA,UAAA;AACA,WAAA;AACA,SAAA;AACA,QAAA,MAAA,QAAA,CAAA,IAAA,CAAA;AACA,OAAA;AACA,IAAA,CAAA,SAAA;AACA,MAAA,MAAAC,sBAAA,EAAA;AACA,IAAA;AACA,EAAA,CAAA;AACA;;;;"}
@@ -36,7 +36,7 @@ function instrumentHydratedRouter() {
36
36
  pageloadSpan.updateName(parameterizePageloadRoute);
37
37
  pageloadSpan.setAttributes({
38
38
  [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route',
39
- [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.pageload.react-router',
39
+ [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.pageload.react_router',
40
40
  });
41
41
  }
42
42
 
@@ -72,7 +72,7 @@ function instrumentHydratedRouter() {
72
72
  navigationSpan.updateName(parameterizedNavRoute);
73
73
  navigationSpan.setAttributes({
74
74
  [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route',
75
- [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.navigation.react-router',
75
+ [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.navigation.react_router',
76
76
  });
77
77
  }
78
78
  });
@@ -113,7 +113,7 @@ function maybeCreateNavigationTransaction(name, source) {
113
113
  attributes: {
114
114
  [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: source,
115
115
  [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'navigation',
116
- [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.navigation.react-router',
116
+ [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.navigation.react_router',
117
117
  },
118
118
  });
119
119
  }
@@ -1 +1 @@
1
- {"version":3,"file":"hydratedRouter.js","sources":["../../../src/client/hydratedRouter.ts"],"sourcesContent":["import { startBrowserTracingNavigationSpan } from '@sentry/browser';\nimport type { Span } from '@sentry/core';\nimport {\n consoleSandbox,\n getActiveSpan,\n getClient,\n getRootSpan,\n GLOBAL_OBJ,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n spanToJSON,\n} from '@sentry/core';\nimport type { DataRouter, RouterState } from 'react-router';\nimport { DEBUG_BUILD } from '../common/debug-build';\n\nconst GLOBAL_OBJ_WITH_DATA_ROUTER = GLOBAL_OBJ as typeof GLOBAL_OBJ & {\n __reactRouterDataRouter?: DataRouter;\n};\n\nconst MAX_RETRIES = 40; // 2 seconds at 50ms interval\n\n/**\n * Instruments the React Router Data Router for pageloads and navigation.\n *\n * This function waits for the router to be available after hydration, then:\n * 1. Updates the pageload transaction with parameterized route info\n * 2. Patches router.navigate() to create navigation transactions\n * 3. Subscribes to router state changes to update navigation transactions with parameterized routes\n */\nexport function instrumentHydratedRouter(): void {\n function trySubscribe(): boolean {\n const router = GLOBAL_OBJ_WITH_DATA_ROUTER.__reactRouterDataRouter;\n\n if (router) {\n // The first time we hit the router, we try to update the pageload transaction\n // todo: update pageload tx here\n const pageloadSpan = getActiveRootSpan();\n\n if (pageloadSpan) {\n const pageloadName = spanToJSON(pageloadSpan).description;\n const parameterizePageloadRoute = getParameterizedRoute(router.state);\n if (\n pageloadName &&\n // this event is for the currently active pageload\n normalizePathname(router.state.location.pathname) === normalizePathname(pageloadName)\n ) {\n pageloadSpan.updateName(parameterizePageloadRoute);\n pageloadSpan.setAttributes({\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.pageload.react-router',\n });\n }\n\n // Patching navigate for creating accurate navigation transactions\n if (typeof router.navigate === 'function') {\n const originalNav = router.navigate.bind(router);\n router.navigate = function sentryPatchedNavigate(...args) {\n maybeCreateNavigationTransaction(\n String(args[0]) || '<unknown route>', // will be updated anyway\n 'url', // this also will be updated once we have the parameterized route\n );\n return originalNav(...args);\n };\n }\n }\n\n // Subscribe to router state changes to update navigation transactions with parameterized routes\n router.subscribe(newState => {\n const navigationSpan = getActiveRootSpan();\n\n if (!navigationSpan) {\n return;\n }\n\n const navigationSpanName = spanToJSON(navigationSpan).description;\n const parameterizedNavRoute = getParameterizedRoute(newState);\n\n if (\n navigationSpanName &&\n newState.navigation.state === 'idle' && // navigation has completed\n normalizePathname(newState.location.pathname) === normalizePathname(navigationSpanName) // this event is for the currently active navigation\n ) {\n navigationSpan.updateName(parameterizedNavRoute);\n navigationSpan.setAttributes({\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.navigation.react-router',\n });\n }\n });\n return true;\n }\n return false;\n }\n\n // Wait until the router is available (since the SDK loads before hydration)\n if (!trySubscribe()) {\n let retryCount = 0;\n // Retry until the router is available or max retries reached\n const interval = setInterval(() => {\n if (trySubscribe() || retryCount >= MAX_RETRIES) {\n if (retryCount >= MAX_RETRIES) {\n DEBUG_BUILD &&\n consoleSandbox(() => {\n // eslint-disable-next-line no-console\n console.warn('Unable to instrument React Router: router not found after hydration.');\n });\n }\n clearInterval(interval);\n }\n retryCount++;\n }, 50);\n }\n}\n\nfunction maybeCreateNavigationTransaction(name: string, source: 'url' | 'route'): Span | undefined {\n const client = getClient();\n\n if (!client) {\n return undefined;\n }\n\n return startBrowserTracingNavigationSpan(client, {\n name,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: source,\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'navigation',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.navigation.react-router',\n },\n });\n}\n\nfunction getActiveRootSpan(): Span | undefined {\n const activeSpan = getActiveSpan();\n if (!activeSpan) {\n return undefined;\n }\n\n const rootSpan = getRootSpan(activeSpan);\n\n const op = spanToJSON(rootSpan).op;\n\n // Only use this root span if it is a pageload or navigation span\n return op === 'navigation' || op === 'pageload' ? rootSpan : undefined;\n}\n\nfunction getParameterizedRoute(routerState: RouterState): string {\n const lastMatch = routerState.matches[routerState.matches.length - 1];\n return normalizePathname(lastMatch?.route.path ?? routerState.location.pathname);\n}\n\nfunction normalizePathname(pathname: string): string {\n // Ensure it starts with a single slash\n let normalized = pathname.startsWith('/') ? pathname : `/${pathname}`;\n // Remove trailing slash unless it's the root\n if (normalized.length > 1 && normalized.endsWith('/')) {\n normalized = normalized.slice(0, -1);\n }\n return normalized;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"hydratedRouter.js","sources":["../../../src/client/hydratedRouter.ts"],"sourcesContent":["import { startBrowserTracingNavigationSpan } from '@sentry/browser';\nimport type { Span } from '@sentry/core';\nimport {\n consoleSandbox,\n getActiveSpan,\n getClient,\n getRootSpan,\n GLOBAL_OBJ,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n spanToJSON,\n} from '@sentry/core';\nimport type { DataRouter, RouterState } from 'react-router';\nimport { DEBUG_BUILD } from '../common/debug-build';\n\nconst GLOBAL_OBJ_WITH_DATA_ROUTER = GLOBAL_OBJ as typeof GLOBAL_OBJ & {\n __reactRouterDataRouter?: DataRouter;\n};\n\nconst MAX_RETRIES = 40; // 2 seconds at 50ms interval\n\n/**\n * Instruments the React Router Data Router for pageloads and navigation.\n *\n * This function waits for the router to be available after hydration, then:\n * 1. Updates the pageload transaction with parameterized route info\n * 2. Patches router.navigate() to create navigation transactions\n * 3. Subscribes to router state changes to update navigation transactions with parameterized routes\n */\nexport function instrumentHydratedRouter(): void {\n function trySubscribe(): boolean {\n const router = GLOBAL_OBJ_WITH_DATA_ROUTER.__reactRouterDataRouter;\n\n if (router) {\n // The first time we hit the router, we try to update the pageload transaction\n // todo: update pageload tx here\n const pageloadSpan = getActiveRootSpan();\n\n if (pageloadSpan) {\n const pageloadName = spanToJSON(pageloadSpan).description;\n const parameterizePageloadRoute = getParameterizedRoute(router.state);\n if (\n pageloadName &&\n // this event is for the currently active pageload\n normalizePathname(router.state.location.pathname) === normalizePathname(pageloadName)\n ) {\n pageloadSpan.updateName(parameterizePageloadRoute);\n pageloadSpan.setAttributes({\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.pageload.react_router',\n });\n }\n\n // Patching navigate for creating accurate navigation transactions\n if (typeof router.navigate === 'function') {\n const originalNav = router.navigate.bind(router);\n router.navigate = function sentryPatchedNavigate(...args) {\n maybeCreateNavigationTransaction(\n String(args[0]) || '<unknown route>', // will be updated anyway\n 'url', // this also will be updated once we have the parameterized route\n );\n return originalNav(...args);\n };\n }\n }\n\n // Subscribe to router state changes to update navigation transactions with parameterized routes\n router.subscribe(newState => {\n const navigationSpan = getActiveRootSpan();\n\n if (!navigationSpan) {\n return;\n }\n\n const navigationSpanName = spanToJSON(navigationSpan).description;\n const parameterizedNavRoute = getParameterizedRoute(newState);\n\n if (\n navigationSpanName &&\n newState.navigation.state === 'idle' && // navigation has completed\n normalizePathname(newState.location.pathname) === normalizePathname(navigationSpanName) // this event is for the currently active navigation\n ) {\n navigationSpan.updateName(parameterizedNavRoute);\n navigationSpan.setAttributes({\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.navigation.react_router',\n });\n }\n });\n return true;\n }\n return false;\n }\n\n // Wait until the router is available (since the SDK loads before hydration)\n if (!trySubscribe()) {\n let retryCount = 0;\n // Retry until the router is available or max retries reached\n const interval = setInterval(() => {\n if (trySubscribe() || retryCount >= MAX_RETRIES) {\n if (retryCount >= MAX_RETRIES) {\n DEBUG_BUILD &&\n consoleSandbox(() => {\n // eslint-disable-next-line no-console\n console.warn('Unable to instrument React Router: router not found after hydration.');\n });\n }\n clearInterval(interval);\n }\n retryCount++;\n }, 50);\n }\n}\n\nfunction maybeCreateNavigationTransaction(name: string, source: 'url' | 'route'): Span | undefined {\n const client = getClient();\n\n if (!client) {\n return undefined;\n }\n\n return startBrowserTracingNavigationSpan(client, {\n name,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: source,\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'navigation',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.navigation.react_router',\n },\n });\n}\n\nfunction getActiveRootSpan(): Span | undefined {\n const activeSpan = getActiveSpan();\n if (!activeSpan) {\n return undefined;\n }\n\n const rootSpan = getRootSpan(activeSpan);\n\n const op = spanToJSON(rootSpan).op;\n\n // Only use this root span if it is a pageload or navigation span\n return op === 'navigation' || op === 'pageload' ? rootSpan : undefined;\n}\n\nfunction getParameterizedRoute(routerState: RouterState): string {\n const lastMatch = routerState.matches[routerState.matches.length - 1];\n return normalizePathname(lastMatch?.route.path ?? routerState.location.pathname);\n}\n\nfunction normalizePathname(pathname: string): string {\n // Ensure it starts with a single slash\n let normalized = pathname.startsWith('/') ? pathname : `/${pathname}`;\n // Remove trailing slash unless it's the root\n if (normalized.length > 1 && normalized.endsWith('/')) {\n normalized = normalized.slice(0, -1);\n }\n return normalized;\n}\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"type":"module","version":"10.27.0"}
1
+ {"type":"module","version":"10.28.0"}
@@ -78,14 +78,14 @@ class ReactRouterInstrumentation extends InstrumentationBase {
78
78
  updateSpanName(rootSpan, `${request.method} ${target}`);
79
79
  rootSpan.setAttributes({
80
80
  [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',
81
- [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react-router.server',
81
+ [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react_router.server',
82
82
  });
83
83
 
84
84
  return startSpan(
85
85
  {
86
86
  name: getSpanName(url.pathname, request.method),
87
87
  attributes: {
88
- [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react-router.server',
88
+ [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react_router.server',
89
89
  [SEMANTIC_ATTRIBUTE_SENTRY_OP]: getOpName(url.pathname, request.method),
90
90
  },
91
91
  },
@@ -1 +1 @@
1
- {"version":3,"file":"reactRouter.js","sources":["../../../../src/server/instrumentation/reactRouter.ts"],"sourcesContent":["import type { InstrumentationConfig } from '@opentelemetry/instrumentation';\nimport { InstrumentationBase, InstrumentationNodeModuleDefinition } from '@opentelemetry/instrumentation';\nimport { SEMATTRS_HTTP_TARGET } from '@opentelemetry/semantic-conventions';\nimport {\n debug,\n getActiveSpan,\n getRootSpan,\n SDK_VERSION,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n spanToJSON,\n startSpan,\n updateSpanName,\n} from '@sentry/core';\nimport type * as reactRouter from 'react-router';\nimport { DEBUG_BUILD } from '../../common/debug-build';\nimport { getOpName, getSpanName, isDataRequest } from './util';\n\ntype ReactRouterModuleExports = typeof reactRouter;\n\nconst supportedVersions = ['>=7.0.0'];\nconst COMPONENT = 'react-router';\n\n/**\n * Instrumentation for React Router's server request handler.\n * This patches the requestHandler function to add Sentry performance monitoring for data loaders.\n */\nexport class ReactRouterInstrumentation extends InstrumentationBase<InstrumentationConfig> {\n public constructor(config: InstrumentationConfig = {}) {\n super('ReactRouterInstrumentation', SDK_VERSION, config);\n }\n\n /**\n * Initializes the instrumentation by defining the React Router server modules to be patched.\n */\n // eslint-disable-next-line @typescript-eslint/naming-convention\n protected init(): InstrumentationNodeModuleDefinition {\n const reactRouterServerModule = new InstrumentationNodeModuleDefinition(\n COMPONENT,\n supportedVersions,\n (moduleExports: ReactRouterModuleExports) => {\n return this._createPatchedModuleProxy(moduleExports);\n },\n (_moduleExports: unknown) => {\n // nothing to unwrap here\n return _moduleExports;\n },\n );\n\n return reactRouterServerModule;\n }\n\n /**\n * Creates a proxy around the React Router module exports that patches the createRequestHandler function.\n * This allows us to wrap the request handler to add performance monitoring for data loaders and actions.\n */\n private _createPatchedModuleProxy(moduleExports: ReactRouterModuleExports): ReactRouterModuleExports {\n return new Proxy(moduleExports, {\n get(target, prop, receiver) {\n if (prop === 'createRequestHandler') {\n const original = target[prop];\n return function sentryWrappedCreateRequestHandler(this: unknown, ...args: unknown[]) {\n const originalRequestHandler = original.apply(this, args);\n\n return async function sentryWrappedRequestHandler(request: Request, initialContext?: unknown) {\n let url: URL;\n try {\n url = new URL(request.url);\n } catch {\n return originalRequestHandler(request, initialContext);\n }\n\n // We currently just want to trace loaders and actions\n if (!isDataRequest(url.pathname)) {\n return originalRequestHandler(request, initialContext);\n }\n\n const activeSpan = getActiveSpan();\n const rootSpan = activeSpan && getRootSpan(activeSpan);\n\n if (!rootSpan) {\n DEBUG_BUILD && debug.log('No active root span found, skipping tracing for data request');\n return originalRequestHandler(request, initialContext);\n }\n\n // We cannot rely on the regular span name inferral here, as the express instrumentation sets `*` as the route\n // So we force this to be a more sensible name here\n // TODO: try to set derived parameterized route from build here (args[0])\n const spanData = spanToJSON(rootSpan);\n // eslint-disable-next-line deprecation/deprecation\n const target = spanData.data[SEMATTRS_HTTP_TARGET] || url.pathname;\n updateSpanName(rootSpan, `${request.method} ${target}`);\n rootSpan.setAttributes({\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react-router.server',\n });\n\n return startSpan(\n {\n name: getSpanName(url.pathname, request.method),\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react-router.server',\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: getOpName(url.pathname, request.method),\n },\n },\n () => {\n return originalRequestHandler(request, initialContext);\n },\n );\n };\n };\n }\n return Reflect.get(target, prop, receiver);\n },\n });\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"reactRouter.js","sources":["../../../../src/server/instrumentation/reactRouter.ts"],"sourcesContent":["import type { InstrumentationConfig } from '@opentelemetry/instrumentation';\nimport { InstrumentationBase, InstrumentationNodeModuleDefinition } from '@opentelemetry/instrumentation';\nimport { SEMATTRS_HTTP_TARGET } from '@opentelemetry/semantic-conventions';\nimport {\n debug,\n getActiveSpan,\n getRootSpan,\n SDK_VERSION,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n spanToJSON,\n startSpan,\n updateSpanName,\n} from '@sentry/core';\nimport type * as reactRouter from 'react-router';\nimport { DEBUG_BUILD } from '../../common/debug-build';\nimport { getOpName, getSpanName, isDataRequest } from './util';\n\ntype ReactRouterModuleExports = typeof reactRouter;\n\nconst supportedVersions = ['>=7.0.0'];\nconst COMPONENT = 'react-router';\n\n/**\n * Instrumentation for React Router's server request handler.\n * This patches the requestHandler function to add Sentry performance monitoring for data loaders.\n */\nexport class ReactRouterInstrumentation extends InstrumentationBase<InstrumentationConfig> {\n public constructor(config: InstrumentationConfig = {}) {\n super('ReactRouterInstrumentation', SDK_VERSION, config);\n }\n\n /**\n * Initializes the instrumentation by defining the React Router server modules to be patched.\n */\n // eslint-disable-next-line @typescript-eslint/naming-convention\n protected init(): InstrumentationNodeModuleDefinition {\n const reactRouterServerModule = new InstrumentationNodeModuleDefinition(\n COMPONENT,\n supportedVersions,\n (moduleExports: ReactRouterModuleExports) => {\n return this._createPatchedModuleProxy(moduleExports);\n },\n (_moduleExports: unknown) => {\n // nothing to unwrap here\n return _moduleExports;\n },\n );\n\n return reactRouterServerModule;\n }\n\n /**\n * Creates a proxy around the React Router module exports that patches the createRequestHandler function.\n * This allows us to wrap the request handler to add performance monitoring for data loaders and actions.\n */\n private _createPatchedModuleProxy(moduleExports: ReactRouterModuleExports): ReactRouterModuleExports {\n return new Proxy(moduleExports, {\n get(target, prop, receiver) {\n if (prop === 'createRequestHandler') {\n const original = target[prop];\n return function sentryWrappedCreateRequestHandler(this: unknown, ...args: unknown[]) {\n const originalRequestHandler = original.apply(this, args);\n\n return async function sentryWrappedRequestHandler(request: Request, initialContext?: unknown) {\n let url: URL;\n try {\n url = new URL(request.url);\n } catch {\n return originalRequestHandler(request, initialContext);\n }\n\n // We currently just want to trace loaders and actions\n if (!isDataRequest(url.pathname)) {\n return originalRequestHandler(request, initialContext);\n }\n\n const activeSpan = getActiveSpan();\n const rootSpan = activeSpan && getRootSpan(activeSpan);\n\n if (!rootSpan) {\n DEBUG_BUILD && debug.log('No active root span found, skipping tracing for data request');\n return originalRequestHandler(request, initialContext);\n }\n\n // We cannot rely on the regular span name inferral here, as the express instrumentation sets `*` as the route\n // So we force this to be a more sensible name here\n // TODO: try to set derived parameterized route from build here (args[0])\n const spanData = spanToJSON(rootSpan);\n // eslint-disable-next-line deprecation/deprecation\n const target = spanData.data[SEMATTRS_HTTP_TARGET] || url.pathname;\n updateSpanName(rootSpan, `${request.method} ${target}`);\n rootSpan.setAttributes({\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react_router.server',\n });\n\n return startSpan(\n {\n name: getSpanName(url.pathname, request.method),\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react_router.server',\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: getOpName(url.pathname, request.method),\n },\n },\n () => {\n return originalRequestHandler(request, initialContext);\n },\n );\n };\n };\n }\n return Reflect.get(target, prop, receiver);\n },\n });\n }\n}\n"],"names":[],"mappings":"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"}
@@ -39,7 +39,7 @@ function wrapSentryHandleRequest(
39
39
  rootSpan.setAttributes({
40
40
  [ATTR_HTTP_ROUTE]: routeName,
41
41
  [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route',
42
- [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react-router.request-handler',
42
+ [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react_router.request_handler',
43
43
  });
44
44
  }
45
45
 
@@ -1 +1 @@
1
- {"version":3,"file":"wrapSentryHandleRequest.js","sources":["../../../src/server/wrapSentryHandleRequest.ts"],"sourcesContent":["import { context } from '@opentelemetry/api';\nimport { getRPCMetadata, RPCType } from '@opentelemetry/core';\nimport { ATTR_HTTP_ROUTE } from '@opentelemetry/semantic-conventions';\nimport {\n flushIfServerless,\n getActiveSpan,\n getRootSpan,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n} from '@sentry/core';\nimport type { AppLoadContext, EntryContext, RouterContextProvider } from 'react-router';\n\ntype OriginalHandleRequestWithoutMiddleware = (\n request: Request,\n responseStatusCode: number,\n responseHeaders: Headers,\n routerContext: EntryContext,\n loadContext: AppLoadContext,\n) => Promise<unknown>;\n\ntype OriginalHandleRequestWithMiddleware = (\n request: Request,\n responseStatusCode: number,\n responseHeaders: Headers,\n routerContext: EntryContext,\n loadContext: RouterContextProvider,\n) => Promise<unknown>;\n\n/**\n * Wraps the original handleRequest function to add Sentry instrumentation.\n *\n * @param originalHandle - The original handleRequest function to wrap\n * @returns A wrapped version of the handle request function with Sentry instrumentation\n */\nexport function wrapSentryHandleRequest(\n originalHandle: OriginalHandleRequestWithoutMiddleware,\n): OriginalHandleRequestWithoutMiddleware;\n/**\n * Wraps the original handleRequest function to add Sentry instrumentation.\n *\n * @param originalHandle - The original handleRequest function to wrap\n * @returns A wrapped version of the handle request function with Sentry instrumentation\n */\nexport function wrapSentryHandleRequest(\n originalHandle: OriginalHandleRequestWithMiddleware,\n): OriginalHandleRequestWithMiddleware;\n/**\n * Wraps the original handleRequest function to add Sentry instrumentation.\n *\n * @param originalHandle - The original handleRequest function to wrap\n * @returns A wrapped version of the handle request function with Sentry instrumentation\n */\nexport function wrapSentryHandleRequest(\n originalHandle: OriginalHandleRequestWithoutMiddleware | OriginalHandleRequestWithMiddleware,\n): OriginalHandleRequestWithoutMiddleware | OriginalHandleRequestWithMiddleware {\n return async function sentryInstrumentedHandleRequest(\n request: Request,\n responseStatusCode: number,\n responseHeaders: Headers,\n routerContext: EntryContext,\n loadContext: AppLoadContext | RouterContextProvider,\n ) {\n const parameterizedPath =\n routerContext?.staticHandlerContext?.matches?.[routerContext.staticHandlerContext.matches.length - 1]?.route.path;\n\n const activeSpan = getActiveSpan();\n const rootSpan = activeSpan ? getRootSpan(activeSpan) : undefined;\n\n if (parameterizedPath && rootSpan) {\n const routeName = `/${parameterizedPath}`;\n\n // The express instrumentation writes on the rpcMetadata and that ends up stomping on the `http.route` attribute.\n const rpcMetadata = getRPCMetadata(context.active());\n\n if (rpcMetadata?.type === RPCType.HTTP) {\n rpcMetadata.route = routeName;\n }\n\n // The span exporter picks up the `http.route` (ATTR_HTTP_ROUTE) attribute to set the transaction name\n rootSpan.setAttributes({\n [ATTR_HTTP_ROUTE]: routeName,\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react-router.request-handler',\n });\n }\n\n try {\n // Type guard to call the correct overload based on loadContext type\n if (isRouterContextProvider(loadContext)) {\n // loadContext is RouterContextProvider\n return await (originalHandle as OriginalHandleRequestWithMiddleware)(\n request,\n responseStatusCode,\n responseHeaders,\n routerContext,\n loadContext,\n );\n } else {\n // loadContext is AppLoadContext\n return await (originalHandle as OriginalHandleRequestWithoutMiddleware)(\n request,\n responseStatusCode,\n responseHeaders,\n routerContext,\n loadContext,\n );\n }\n } finally {\n await flushIfServerless();\n }\n\n /**\n * Helper type guard to determine if the context is a RouterContextProvider.\n *\n * @param ctx - The context to check\n * @returns True if the context is a RouterContextProvider\n */\n function isRouterContextProvider(ctx: AppLoadContext | RouterContextProvider): ctx is RouterContextProvider {\n return typeof (ctx as RouterContextProvider)?.get === 'function';\n }\n };\n}\n\n// todo(v11): remove this\n/** @deprecated Use `wrapSentryHandleRequest` instead. */\nexport const sentryHandleRequest = wrapSentryHandleRequest;\n"],"names":[],"mappings":";;;;;AA8CA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,uBAAuB;AACvC,EAAE,cAAc;AAChB,EAAgF;AAChF,EAAE,OAAO,eAAe,+BAA+B;AACvD,IAAI,OAAO;AACX,IAAI,kBAAkB;AACtB,IAAI,eAAe;AACnB,IAAI,aAAa;AACjB,IAAI,WAAW;AACf,IAAI;AACJ,IAAI,MAAM,iBAAA;AACV,MAAM,aAAa,EAAE,oBAAoB,EAAE,OAAO,GAAG,aAAa,CAAC,oBAAoB,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,EAAE,KAAK,CAAC,IAAI;;AAEvH,IAAI,MAAM,UAAA,GAAa,aAAa,EAAE;AACtC,IAAI,MAAM,QAAA,GAAW,UAAA,GAAa,WAAW,CAAC,UAAU,CAAA,GAAI,SAAS;;AAErE,IAAI,IAAI,iBAAA,IAAqB,QAAQ,EAAE;AACvC,MAAM,MAAM,YAAY,CAAC,CAAC,EAAE,iBAAiB,CAAC,CAAA;;AAEA;AACA,MAAA,MAAA,WAAA,GAAA,cAAA,CAAA,OAAA,CAAA,MAAA,EAAA,CAAA;;AAEA,MAAA,IAAA,WAAA,EAAA,IAAA,KAAA,OAAA,CAAA,IAAA,EAAA;AACA,QAAA,WAAA,CAAA,KAAA,GAAA,SAAA;AACA,MAAA;;AAEA;AACA,MAAA,QAAA,CAAA,aAAA,CAAA;AACA,QAAA,CAAA,eAAA,GAAA,SAAA;AACA,QAAA,CAAA,gCAAA,GAAA,OAAA;AACA,QAAA,CAAA,gCAAA,GAAA,wCAAA;AACA,OAAA,CAAA;AACA,IAAA;;AAEA,IAAA,IAAA;AACA;AACA,MAAA,IAAA,uBAAA,CAAA,WAAA,CAAA,EAAA;AACA;AACA,QAAA,OAAA,MAAA,CAAA,cAAA;AACA,UAAA,OAAA;AACA,UAAA,kBAAA;AACA,UAAA,eAAA;AACA,UAAA,aAAA;AACA,UAAA,WAAA;AACA,SAAA;AACA,MAAA,CAAA,MAAA;AACA;AACA,QAAA,OAAA,MAAA,CAAA,cAAA;AACA,UAAA,OAAA;AACA,UAAA,kBAAA;AACA,UAAA,eAAA;AACA,UAAA,aAAA;AACA,UAAA,WAAA;AACA,SAAA;AACA,MAAA;AACA,IAAA,CAAA,SAAA;AACA,MAAA,MAAA,iBAAA,EAAA;AACA,IAAA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,IAAA,SAAA,uBAAA,CAAA,GAAA,EAAA;AACA,MAAA,OAAA,OAAA,CAAA,GAAA,IAAA,GAAA,KAAA,UAAA;AACA,IAAA;AACA,EAAA,CAAA;AACA;;AAEA;AACA;AACA,MAAA,mBAAA,GAAA;;;;"}
1
+ {"version":3,"file":"wrapSentryHandleRequest.js","sources":["../../../src/server/wrapSentryHandleRequest.ts"],"sourcesContent":["import { context } from '@opentelemetry/api';\nimport { getRPCMetadata, RPCType } from '@opentelemetry/core';\nimport { ATTR_HTTP_ROUTE } from '@opentelemetry/semantic-conventions';\nimport {\n flushIfServerless,\n getActiveSpan,\n getRootSpan,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n} from '@sentry/core';\nimport type { AppLoadContext, EntryContext, RouterContextProvider } from 'react-router';\n\ntype OriginalHandleRequestWithoutMiddleware = (\n request: Request,\n responseStatusCode: number,\n responseHeaders: Headers,\n routerContext: EntryContext,\n loadContext: AppLoadContext,\n) => Promise<unknown>;\n\ntype OriginalHandleRequestWithMiddleware = (\n request: Request,\n responseStatusCode: number,\n responseHeaders: Headers,\n routerContext: EntryContext,\n loadContext: RouterContextProvider,\n) => Promise<unknown>;\n\n/**\n * Wraps the original handleRequest function to add Sentry instrumentation.\n *\n * @param originalHandle - The original handleRequest function to wrap\n * @returns A wrapped version of the handle request function with Sentry instrumentation\n */\nexport function wrapSentryHandleRequest(\n originalHandle: OriginalHandleRequestWithoutMiddleware,\n): OriginalHandleRequestWithoutMiddleware;\n/**\n * Wraps the original handleRequest function to add Sentry instrumentation.\n *\n * @param originalHandle - The original handleRequest function to wrap\n * @returns A wrapped version of the handle request function with Sentry instrumentation\n */\nexport function wrapSentryHandleRequest(\n originalHandle: OriginalHandleRequestWithMiddleware,\n): OriginalHandleRequestWithMiddleware;\n/**\n * Wraps the original handleRequest function to add Sentry instrumentation.\n *\n * @param originalHandle - The original handleRequest function to wrap\n * @returns A wrapped version of the handle request function with Sentry instrumentation\n */\nexport function wrapSentryHandleRequest(\n originalHandle: OriginalHandleRequestWithoutMiddleware | OriginalHandleRequestWithMiddleware,\n): OriginalHandleRequestWithoutMiddleware | OriginalHandleRequestWithMiddleware {\n return async function sentryInstrumentedHandleRequest(\n request: Request,\n responseStatusCode: number,\n responseHeaders: Headers,\n routerContext: EntryContext,\n loadContext: AppLoadContext | RouterContextProvider,\n ) {\n const parameterizedPath =\n routerContext?.staticHandlerContext?.matches?.[routerContext.staticHandlerContext.matches.length - 1]?.route.path;\n\n const activeSpan = getActiveSpan();\n const rootSpan = activeSpan ? getRootSpan(activeSpan) : undefined;\n\n if (parameterizedPath && rootSpan) {\n const routeName = `/${parameterizedPath}`;\n\n // The express instrumentation writes on the rpcMetadata and that ends up stomping on the `http.route` attribute.\n const rpcMetadata = getRPCMetadata(context.active());\n\n if (rpcMetadata?.type === RPCType.HTTP) {\n rpcMetadata.route = routeName;\n }\n\n // The span exporter picks up the `http.route` (ATTR_HTTP_ROUTE) attribute to set the transaction name\n rootSpan.setAttributes({\n [ATTR_HTTP_ROUTE]: routeName,\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react_router.request_handler',\n });\n }\n\n try {\n // Type guard to call the correct overload based on loadContext type\n if (isRouterContextProvider(loadContext)) {\n // loadContext is RouterContextProvider\n return await (originalHandle as OriginalHandleRequestWithMiddleware)(\n request,\n responseStatusCode,\n responseHeaders,\n routerContext,\n loadContext,\n );\n } else {\n // loadContext is AppLoadContext\n return await (originalHandle as OriginalHandleRequestWithoutMiddleware)(\n request,\n responseStatusCode,\n responseHeaders,\n routerContext,\n loadContext,\n );\n }\n } finally {\n await flushIfServerless();\n }\n\n /**\n * Helper type guard to determine if the context is a RouterContextProvider.\n *\n * @param ctx - The context to check\n * @returns True if the context is a RouterContextProvider\n */\n function isRouterContextProvider(ctx: AppLoadContext | RouterContextProvider): ctx is RouterContextProvider {\n return typeof (ctx as RouterContextProvider)?.get === 'function';\n }\n };\n}\n\n// todo(v11): remove this\n/** @deprecated Use `wrapSentryHandleRequest` instead. */\nexport const sentryHandleRequest = wrapSentryHandleRequest;\n"],"names":[],"mappings":";;;;;AA8CA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,uBAAuB;AACvC,EAAE,cAAc;AAChB,EAAgF;AAChF,EAAE,OAAO,eAAe,+BAA+B;AACvD,IAAI,OAAO;AACX,IAAI,kBAAkB;AACtB,IAAI,eAAe;AACnB,IAAI,aAAa;AACjB,IAAI,WAAW;AACf,IAAI;AACJ,IAAI,MAAM,iBAAA;AACV,MAAM,aAAa,EAAE,oBAAoB,EAAE,OAAO,GAAG,aAAa,CAAC,oBAAoB,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,EAAE,KAAK,CAAC,IAAI;;AAEvH,IAAI,MAAM,UAAA,GAAa,aAAa,EAAE;AACtC,IAAI,MAAM,QAAA,GAAW,UAAA,GAAa,WAAW,CAAC,UAAU,CAAA,GAAI,SAAS;;AAErE,IAAI,IAAI,iBAAA,IAAqB,QAAQ,EAAE;AACvC,MAAM,MAAM,YAAY,CAAC,CAAC,EAAE,iBAAiB,CAAC,CAAA;;AAEA;AACA,MAAA,MAAA,WAAA,GAAA,cAAA,CAAA,OAAA,CAAA,MAAA,EAAA,CAAA;;AAEA,MAAA,IAAA,WAAA,EAAA,IAAA,KAAA,OAAA,CAAA,IAAA,EAAA;AACA,QAAA,WAAA,CAAA,KAAA,GAAA,SAAA;AACA,MAAA;;AAEA;AACA,MAAA,QAAA,CAAA,aAAA,CAAA;AACA,QAAA,CAAA,eAAA,GAAA,SAAA;AACA,QAAA,CAAA,gCAAA,GAAA,OAAA;AACA,QAAA,CAAA,gCAAA,GAAA,wCAAA;AACA,OAAA,CAAA;AACA,IAAA;;AAEA,IAAA,IAAA;AACA;AACA,MAAA,IAAA,uBAAA,CAAA,WAAA,CAAA,EAAA;AACA;AACA,QAAA,OAAA,MAAA,CAAA,cAAA;AACA,UAAA,OAAA;AACA,UAAA,kBAAA;AACA,UAAA,eAAA;AACA,UAAA,aAAA;AACA,UAAA,WAAA;AACA,SAAA;AACA,MAAA,CAAA,MAAA;AACA;AACA,QAAA,OAAA,MAAA,CAAA,cAAA;AACA,UAAA,OAAA;AACA,UAAA,kBAAA;AACA,UAAA,eAAA;AACA,UAAA,aAAA;AACA,UAAA,WAAA;AACA,SAAA;AACA,MAAA;AACA,IAAA,CAAA,SAAA;AACA,MAAA,MAAA,iBAAA,EAAA;AACA,IAAA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,IAAA,SAAA,uBAAA,CAAA,GAAA,EAAA;AACA,MAAA,OAAA,OAAA,CAAA,GAAA,IAAA,GAAA,KAAA,UAAA;AACA,IAAA;AACA,EAAA,CAAA;AACA;;AAEA;AACA;AACA,MAAA,mBAAA,GAAA;;;;"}
@@ -37,7 +37,7 @@ function wrapServerAction(options = {}, actionFn) {
37
37
  updateSpanName(root, `${args.request.method} ${target}`);
38
38
  root.setAttributes({
39
39
  [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',
40
- [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react-router.action',
40
+ [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react_router.action',
41
41
  });
42
42
  }
43
43
  }
@@ -49,7 +49,7 @@ function wrapServerAction(options = {}, actionFn) {
49
49
  name,
50
50
  ...options,
51
51
  attributes: {
52
- [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react-router.action',
52
+ [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react_router.action',
53
53
  [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'function.react-router.action',
54
54
  ...options.attributes,
55
55
  },
@@ -1 +1 @@
1
- {"version":3,"file":"wrapServerAction.js","sources":["../../../src/server/wrapServerAction.ts"],"sourcesContent":["import { SEMATTRS_HTTP_TARGET } from '@opentelemetry/semantic-conventions';\nimport type { SpanAttributes } from '@sentry/core';\nimport {\n flushIfServerless,\n getActiveSpan,\n getRootSpan,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n spanToJSON,\n startSpan,\n updateSpanName,\n} from '@sentry/core';\nimport type { ActionFunctionArgs } from 'react-router';\n\ntype SpanOptions = {\n name?: string;\n attributes?: SpanAttributes;\n};\n\n/**\n * Wraps a React Router server action function with Sentry performance monitoring.\n * @param options - Optional span configuration options including name, operation, description and attributes\n * @param actionFn - The server action function to wrap\n *\n * @example\n * ```ts\n * // Wrap an action function with custom span options\n * export const action = wrapServerAction(\n * {\n * name: 'Submit Form Data',\n * description: 'Processes form submission data',\n * },\n * async ({ request }) => {\n * // ... your action logic\n * }\n * );\n * ```\n */\nexport function wrapServerAction<T>(options: SpanOptions = {}, actionFn: (args: ActionFunctionArgs) => Promise<T>) {\n return async function (args: ActionFunctionArgs) {\n const name = options.name || 'Executing Server Action';\n const active = getActiveSpan();\n if (active) {\n const root = getRootSpan(active);\n const spanData = spanToJSON(root);\n if (spanData.origin === 'auto.http.otel.http') {\n // eslint-disable-next-line deprecation/deprecation\n const target = spanData.data[SEMATTRS_HTTP_TARGET];\n\n if (target) {\n // We cannot rely on the regular span name inferral here, as the express instrumentation sets `*` as the route\n // So we force this to be a more sensible name here\n updateSpanName(root, `${args.request.method} ${target}`);\n root.setAttributes({\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react-router.action',\n });\n }\n }\n }\n\n try {\n return await startSpan(\n {\n name,\n ...options,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react-router.action',\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'function.react-router.action',\n ...options.attributes,\n },\n },\n () => actionFn(args),\n );\n } finally {\n await flushIfServerless();\n }\n };\n}\n"],"names":[],"mappings":";;;AAoBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,gBAAgB,CAAI,OAAO,GAAgB,EAAE,EAAE,QAAQ,EAA4C;AACnH,EAAE,OAAO,gBAAgB,IAAI,EAAsB;AACnD,IAAI,MAAM,IAAA,GAAO,OAAO,CAAC,IAAA,IAAQ,yBAAyB;AAC1D,IAAI,MAAM,MAAA,GAAS,aAAa,EAAE;AAClC,IAAI,IAAI,MAAM,EAAE;AAChB,MAAM,MAAM,IAAA,GAAO,WAAW,CAAC,MAAM,CAAC;AACtC,MAAM,MAAM,QAAA,GAAW,UAAU,CAAC,IAAI,CAAC;AACvC,MAAM,IAAI,QAAQ,CAAC,MAAA,KAAW,qBAAqB,EAAE;AACrD;AACA,QAAQ,MAAM,SAAS,QAAQ,CAAC,IAAI,CAAC,oBAAoB,CAAC;;AAE1D,QAAQ,IAAI,MAAM,EAAE;AACpB;AACA;AACA,UAAU,cAAc,CAAC,IAAI,EAAE,CAAC,EAAA,IAAA,CAAA,OAAA,CAAA,MAAA,CAAA,CAAA,EAAA,MAAA,CAAA,CAAA,CAAA;AACA,UAAA,IAAA,CAAA,aAAA,CAAA;AACA,YAAA,CAAA,gCAAA,GAAA,KAAA;AACA,YAAA,CAAA,gCAAA,GAAA,+BAAA;AACA,WAAA,CAAA;AACA,QAAA;AACA,MAAA;AACA,IAAA;;AAEA,IAAA,IAAA;AACA,MAAA,OAAA,MAAA,SAAA;AACA,QAAA;AACA,UAAA,IAAA;AACA,UAAA,GAAA,OAAA;AACA,UAAA,UAAA,EAAA;AACA,YAAA,CAAA,gCAAA,GAAA,+BAAA;AACA,YAAA,CAAA,4BAAA,GAAA,8BAAA;AACA,YAAA,GAAA,OAAA,CAAA,UAAA;AACA,WAAA;AACA,SAAA;AACA,QAAA,MAAA,QAAA,CAAA,IAAA,CAAA;AACA,OAAA;AACA,IAAA,CAAA,SAAA;AACA,MAAA,MAAA,iBAAA,EAAA;AACA,IAAA;AACA,EAAA,CAAA;AACA;;;;"}
1
+ {"version":3,"file":"wrapServerAction.js","sources":["../../../src/server/wrapServerAction.ts"],"sourcesContent":["import { SEMATTRS_HTTP_TARGET } from '@opentelemetry/semantic-conventions';\nimport type { SpanAttributes } from '@sentry/core';\nimport {\n flushIfServerless,\n getActiveSpan,\n getRootSpan,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n spanToJSON,\n startSpan,\n updateSpanName,\n} from '@sentry/core';\nimport type { ActionFunctionArgs } from 'react-router';\n\ntype SpanOptions = {\n name?: string;\n attributes?: SpanAttributes;\n};\n\n/**\n * Wraps a React Router server action function with Sentry performance monitoring.\n * @param options - Optional span configuration options including name, operation, description and attributes\n * @param actionFn - The server action function to wrap\n *\n * @example\n * ```ts\n * // Wrap an action function with custom span options\n * export const action = wrapServerAction(\n * {\n * name: 'Submit Form Data',\n * description: 'Processes form submission data',\n * },\n * async ({ request }) => {\n * // ... your action logic\n * }\n * );\n * ```\n */\nexport function wrapServerAction<T>(options: SpanOptions = {}, actionFn: (args: ActionFunctionArgs) => Promise<T>) {\n return async function (args: ActionFunctionArgs) {\n const name = options.name || 'Executing Server Action';\n const active = getActiveSpan();\n if (active) {\n const root = getRootSpan(active);\n const spanData = spanToJSON(root);\n if (spanData.origin === 'auto.http.otel.http') {\n // eslint-disable-next-line deprecation/deprecation\n const target = spanData.data[SEMATTRS_HTTP_TARGET];\n\n if (target) {\n // We cannot rely on the regular span name inferral here, as the express instrumentation sets `*` as the route\n // So we force this to be a more sensible name here\n updateSpanName(root, `${args.request.method} ${target}`);\n root.setAttributes({\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react_router.action',\n });\n }\n }\n }\n\n try {\n return await startSpan(\n {\n name,\n ...options,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react_router.action',\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'function.react-router.action',\n ...options.attributes,\n },\n },\n () => actionFn(args),\n );\n } finally {\n await flushIfServerless();\n }\n };\n}\n"],"names":[],"mappings":";;;AAoBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,gBAAgB,CAAI,OAAO,GAAgB,EAAE,EAAE,QAAQ,EAA4C;AACnH,EAAE,OAAO,gBAAgB,IAAI,EAAsB;AACnD,IAAI,MAAM,IAAA,GAAO,OAAO,CAAC,IAAA,IAAQ,yBAAyB;AAC1D,IAAI,MAAM,MAAA,GAAS,aAAa,EAAE;AAClC,IAAI,IAAI,MAAM,EAAE;AAChB,MAAM,MAAM,IAAA,GAAO,WAAW,CAAC,MAAM,CAAC;AACtC,MAAM,MAAM,QAAA,GAAW,UAAU,CAAC,IAAI,CAAC;AACvC,MAAM,IAAI,QAAQ,CAAC,MAAA,KAAW,qBAAqB,EAAE;AACrD;AACA,QAAQ,MAAM,SAAS,QAAQ,CAAC,IAAI,CAAC,oBAAoB,CAAC;;AAE1D,QAAQ,IAAI,MAAM,EAAE;AACpB;AACA;AACA,UAAU,cAAc,CAAC,IAAI,EAAE,CAAC,EAAA,IAAA,CAAA,OAAA,CAAA,MAAA,CAAA,CAAA,EAAA,MAAA,CAAA,CAAA,CAAA;AACA,UAAA,IAAA,CAAA,aAAA,CAAA;AACA,YAAA,CAAA,gCAAA,GAAA,KAAA;AACA,YAAA,CAAA,gCAAA,GAAA,+BAAA;AACA,WAAA,CAAA;AACA,QAAA;AACA,MAAA;AACA,IAAA;;AAEA,IAAA,IAAA;AACA,MAAA,OAAA,MAAA,SAAA;AACA,QAAA;AACA,UAAA,IAAA;AACA,UAAA,GAAA,OAAA;AACA,UAAA,UAAA,EAAA;AACA,YAAA,CAAA,gCAAA,GAAA,+BAAA;AACA,YAAA,CAAA,4BAAA,GAAA,8BAAA;AACA,YAAA,GAAA,OAAA,CAAA,UAAA;AACA,WAAA;AACA,SAAA;AACA,QAAA,MAAA,QAAA,CAAA,IAAA,CAAA;AACA,OAAA;AACA,IAAA,CAAA,SAAA;AACA,MAAA,MAAA,iBAAA,EAAA;AACA,IAAA;AACA,EAAA,CAAA;AACA;;;;"}
@@ -38,7 +38,7 @@ function wrapServerLoader(options = {}, loaderFn) {
38
38
  updateSpanName(root, `${args.request.method} ${target}`);
39
39
  root.setAttributes({
40
40
  [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',
41
- [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react-router.loader',
41
+ [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react_router.loader',
42
42
  });
43
43
  }
44
44
  }
@@ -49,7 +49,7 @@ function wrapServerLoader(options = {}, loaderFn) {
49
49
  name,
50
50
  ...options,
51
51
  attributes: {
52
- [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react-router.loader',
52
+ [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react_router.loader',
53
53
  [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'function.react-router.loader',
54
54
  ...options.attributes,
55
55
  },
@@ -1 +1 @@
1
- {"version":3,"file":"wrapServerLoader.js","sources":["../../../src/server/wrapServerLoader.ts"],"sourcesContent":["import { SEMATTRS_HTTP_TARGET } from '@opentelemetry/semantic-conventions';\nimport type { SpanAttributes } from '@sentry/core';\nimport {\n flushIfServerless,\n getActiveSpan,\n getRootSpan,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n spanToJSON,\n startSpan,\n updateSpanName,\n} from '@sentry/core';\nimport type { LoaderFunctionArgs } from 'react-router';\n\ntype SpanOptions = {\n name?: string;\n attributes?: SpanAttributes;\n};\n\n/**\n * Wraps a React Router server loader function with Sentry performance monitoring.\n * @param options - Optional span configuration options including name, operation, description and attributes\n * @param loaderFn - The server loader function to wrap\n *\n * @example\n * ```ts\n * // Wrap a loader function with custom span options\n * export const loader = wrapServerLoader(\n * {\n * name: 'Load Some Data',\n * description: 'Loads some data from the db',\n * },\n * async ({ params }) => {\n * // ... your loader logic\n * }\n * );\n * ```\n */\nexport function wrapServerLoader<T>(options: SpanOptions = {}, loaderFn: (args: LoaderFunctionArgs) => Promise<T>) {\n return async function (args: LoaderFunctionArgs) {\n const name = options.name || 'Executing Server Loader';\n const active = getActiveSpan();\n\n if (active) {\n const root = getRootSpan(active);\n const spanData = spanToJSON(root);\n if (spanData.origin === 'auto.http.otel.http') {\n // eslint-disable-next-line deprecation/deprecation\n const target = spanData.data[SEMATTRS_HTTP_TARGET];\n\n if (target) {\n // We cannot rely on the regular span name inferral here, as the express instrumentation sets `*` as the route\n // So we force this to be a more sensible name here\n updateSpanName(root, `${args.request.method} ${target}`);\n root.setAttributes({\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react-router.loader',\n });\n }\n }\n }\n try {\n return await startSpan(\n {\n name,\n ...options,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react-router.loader',\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'function.react-router.loader',\n ...options.attributes,\n },\n },\n () => loaderFn(args),\n );\n } finally {\n await flushIfServerless();\n }\n };\n}\n"],"names":[],"mappings":";;;AAoBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,gBAAgB,CAAI,OAAO,GAAgB,EAAE,EAAE,QAAQ,EAA4C;AACnH,EAAE,OAAO,gBAAgB,IAAI,EAAsB;AACnD,IAAI,MAAM,IAAA,GAAO,OAAO,CAAC,IAAA,IAAQ,yBAAyB;AAC1D,IAAI,MAAM,MAAA,GAAS,aAAa,EAAE;;AAElC,IAAI,IAAI,MAAM,EAAE;AAChB,MAAM,MAAM,IAAA,GAAO,WAAW,CAAC,MAAM,CAAC;AACtC,MAAM,MAAM,QAAA,GAAW,UAAU,CAAC,IAAI,CAAC;AACvC,MAAM,IAAI,QAAQ,CAAC,MAAA,KAAW,qBAAqB,EAAE;AACrD;AACA,QAAQ,MAAM,SAAS,QAAQ,CAAC,IAAI,CAAC,oBAAoB,CAAC;;AAE1D,QAAQ,IAAI,MAAM,EAAE;AACpB;AACA;AACA,UAAU,cAAc,CAAC,IAAI,EAAE,CAAC,EAAA,IAAA,CAAA,OAAA,CAAA,MAAA,CAAA,CAAA,EAAA,MAAA,CAAA,CAAA,CAAA;AACA,UAAA,IAAA,CAAA,aAAA,CAAA;AACA,YAAA,CAAA,gCAAA,GAAA,KAAA;AACA,YAAA,CAAA,gCAAA,GAAA,+BAAA;AACA,WAAA,CAAA;AACA,QAAA;AACA,MAAA;AACA,IAAA;AACA,IAAA,IAAA;AACA,MAAA,OAAA,MAAA,SAAA;AACA,QAAA;AACA,UAAA,IAAA;AACA,UAAA,GAAA,OAAA;AACA,UAAA,UAAA,EAAA;AACA,YAAA,CAAA,gCAAA,GAAA,+BAAA;AACA,YAAA,CAAA,4BAAA,GAAA,8BAAA;AACA,YAAA,GAAA,OAAA,CAAA,UAAA;AACA,WAAA;AACA,SAAA;AACA,QAAA,MAAA,QAAA,CAAA,IAAA,CAAA;AACA,OAAA;AACA,IAAA,CAAA,SAAA;AACA,MAAA,MAAA,iBAAA,EAAA;AACA,IAAA;AACA,EAAA,CAAA;AACA;;;;"}
1
+ {"version":3,"file":"wrapServerLoader.js","sources":["../../../src/server/wrapServerLoader.ts"],"sourcesContent":["import { SEMATTRS_HTTP_TARGET } from '@opentelemetry/semantic-conventions';\nimport type { SpanAttributes } from '@sentry/core';\nimport {\n flushIfServerless,\n getActiveSpan,\n getRootSpan,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n spanToJSON,\n startSpan,\n updateSpanName,\n} from '@sentry/core';\nimport type { LoaderFunctionArgs } from 'react-router';\n\ntype SpanOptions = {\n name?: string;\n attributes?: SpanAttributes;\n};\n\n/**\n * Wraps a React Router server loader function with Sentry performance monitoring.\n * @param options - Optional span configuration options including name, operation, description and attributes\n * @param loaderFn - The server loader function to wrap\n *\n * @example\n * ```ts\n * // Wrap a loader function with custom span options\n * export const loader = wrapServerLoader(\n * {\n * name: 'Load Some Data',\n * description: 'Loads some data from the db',\n * },\n * async ({ params }) => {\n * // ... your loader logic\n * }\n * );\n * ```\n */\nexport function wrapServerLoader<T>(options: SpanOptions = {}, loaderFn: (args: LoaderFunctionArgs) => Promise<T>) {\n return async function (args: LoaderFunctionArgs) {\n const name = options.name || 'Executing Server Loader';\n const active = getActiveSpan();\n\n if (active) {\n const root = getRootSpan(active);\n const spanData = spanToJSON(root);\n if (spanData.origin === 'auto.http.otel.http') {\n // eslint-disable-next-line deprecation/deprecation\n const target = spanData.data[SEMATTRS_HTTP_TARGET];\n\n if (target) {\n // We cannot rely on the regular span name inferral here, as the express instrumentation sets `*` as the route\n // So we force this to be a more sensible name here\n updateSpanName(root, `${args.request.method} ${target}`);\n root.setAttributes({\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react_router.loader',\n });\n }\n }\n }\n try {\n return await startSpan(\n {\n name,\n ...options,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react_router.loader',\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'function.react-router.loader',\n ...options.attributes,\n },\n },\n () => loaderFn(args),\n );\n } finally {\n await flushIfServerless();\n }\n };\n}\n"],"names":[],"mappings":";;;AAoBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,gBAAgB,CAAI,OAAO,GAAgB,EAAE,EAAE,QAAQ,EAA4C;AACnH,EAAE,OAAO,gBAAgB,IAAI,EAAsB;AACnD,IAAI,MAAM,IAAA,GAAO,OAAO,CAAC,IAAA,IAAQ,yBAAyB;AAC1D,IAAI,MAAM,MAAA,GAAS,aAAa,EAAE;;AAElC,IAAI,IAAI,MAAM,EAAE;AAChB,MAAM,MAAM,IAAA,GAAO,WAAW,CAAC,MAAM,CAAC;AACtC,MAAM,MAAM,QAAA,GAAW,UAAU,CAAC,IAAI,CAAC;AACvC,MAAM,IAAI,QAAQ,CAAC,MAAA,KAAW,qBAAqB,EAAE;AACrD;AACA,QAAQ,MAAM,SAAS,QAAQ,CAAC,IAAI,CAAC,oBAAoB,CAAC;;AAE1D,QAAQ,IAAI,MAAM,EAAE;AACpB;AACA;AACA,UAAU,cAAc,CAAC,IAAI,EAAE,CAAC,EAAA,IAAA,CAAA,OAAA,CAAA,MAAA,CAAA,CAAA,EAAA,MAAA,CAAA,CAAA,CAAA;AACA,UAAA,IAAA,CAAA,aAAA,CAAA;AACA,YAAA,CAAA,gCAAA,GAAA,KAAA;AACA,YAAA,CAAA,gCAAA,GAAA,+BAAA;AACA,WAAA,CAAA;AACA,QAAA;AACA,MAAA;AACA,IAAA;AACA,IAAA,IAAA;AACA,MAAA,OAAA,MAAA,SAAA;AACA,QAAA;AACA,UAAA,IAAA;AACA,UAAA,GAAA,OAAA;AACA,UAAA,UAAA,EAAA;AACA,YAAA,CAAA,gCAAA,GAAA,+BAAA;AACA,YAAA,CAAA,4BAAA,GAAA,8BAAA;AACA,YAAA,GAAA,OAAA,CAAA,UAAA;AACA,WAAA;AACA,SAAA;AACA,QAAA,MAAA,QAAA,CAAA,IAAA,CAAA;AACA,OAAA;AACA,IAAA,CAAA,SAAA;AACA,MAAA,MAAA,iBAAA,EAAA;AACA,IAAA;AACA,EAAA,CAAA;AACA;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sentry/react-router",
3
- "version": "10.27.0",
3
+ "version": "10.28.0",
4
4
  "description": "Official Sentry SDK for React Router (Framework)",
5
5
  "repository": "git://github.com/getsentry/sentry-javascript.git",
6
6
  "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/react-router",
@@ -49,11 +49,11 @@
49
49
  "@opentelemetry/core": "^2.2.0",
50
50
  "@opentelemetry/instrumentation": "^0.208.0",
51
51
  "@opentelemetry/semantic-conventions": "^1.37.0",
52
- "@sentry/browser": "10.27.0",
52
+ "@sentry/browser": "10.28.0",
53
53
  "@sentry/cli": "^2.58.2",
54
- "@sentry/core": "10.27.0",
55
- "@sentry/node": "10.27.0",
56
- "@sentry/react": "10.27.0",
54
+ "@sentry/core": "10.28.0",
55
+ "@sentry/node": "10.28.0",
56
+ "@sentry/react": "10.28.0",
57
57
  "@sentry/vite-plugin": "^4.1.0",
58
58
  "glob": "11.1.0"
59
59
  },