@sentry/react-native 8.3.0 → 8.5.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.
Files changed (137) hide show
  1. package/RNSentry.podspec +1 -1
  2. package/android/build.gradle +2 -2
  3. package/android/libs/replay-stubs.jar +0 -0
  4. package/android/replay-stubs/build.gradle +1 -1
  5. package/android/src/main/java/io/sentry/react/RNSentryModuleImpl.java +56 -4
  6. package/android/src/main/java/io/sentry/react/RNSentryStart.java +13 -0
  7. package/android/src/main/java/io/sentry/react/RNSentryVersion.java +1 -1
  8. package/android/src/newarch/java/io/sentry/react/RNSentryModule.java +10 -0
  9. package/android/src/oldarch/java/io/sentry/react/RNSentryModule.java +10 -0
  10. package/dist/js/NativeRNSentry.d.ts +2 -0
  11. package/dist/js/NativeRNSentry.d.ts.map +1 -1
  12. package/dist/js/NativeRNSentry.js.map +1 -1
  13. package/dist/js/feedback/FeedbackWidgetManager.d.ts +3 -1
  14. package/dist/js/feedback/FeedbackWidgetManager.d.ts.map +1 -1
  15. package/dist/js/feedback/FeedbackWidgetManager.js +15 -1
  16. package/dist/js/feedback/FeedbackWidgetManager.js.map +1 -1
  17. package/dist/js/feedback/FeedbackWidgetProvider.d.ts +3 -2
  18. package/dist/js/feedback/FeedbackWidgetProvider.d.ts.map +1 -1
  19. package/dist/js/feedback/FeedbackWidgetProvider.js +12 -4
  20. package/dist/js/feedback/FeedbackWidgetProvider.js.map +1 -1
  21. package/dist/js/feedback/ShakeToReportBug.d.ts +27 -0
  22. package/dist/js/feedback/ShakeToReportBug.d.ts.map +1 -0
  23. package/dist/js/feedback/ShakeToReportBug.js +83 -0
  24. package/dist/js/feedback/ShakeToReportBug.js.map +1 -0
  25. package/dist/js/feedback/integration.d.ts +11 -0
  26. package/dist/js/feedback/integration.d.ts.map +1 -1
  27. package/dist/js/feedback/integration.js +7 -1
  28. package/dist/js/feedback/integration.js.map +1 -1
  29. package/dist/js/index.d.ts +3 -3
  30. package/dist/js/index.d.ts.map +1 -1
  31. package/dist/js/index.js +2 -2
  32. package/dist/js/index.js.map +1 -1
  33. package/dist/js/integrations/debugsymbolicator.js +3 -1
  34. package/dist/js/integrations/debugsymbolicator.js.map +1 -1
  35. package/dist/js/integrations/default.d.ts.map +1 -1
  36. package/dist/js/integrations/default.js +2 -1
  37. package/dist/js/integrations/default.js.map +1 -1
  38. package/dist/js/integrations/expocontext.d.ts.map +1 -1
  39. package/dist/js/integrations/expocontext.js +35 -1
  40. package/dist/js/integrations/expocontext.js.map +1 -1
  41. package/dist/js/integrations/exports.d.ts +1 -0
  42. package/dist/js/integrations/exports.d.ts.map +1 -1
  43. package/dist/js/integrations/exports.js +1 -0
  44. package/dist/js/integrations/exports.js.map +1 -1
  45. package/dist/js/integrations/expoupdateslistener.d.ts +38 -0
  46. package/dist/js/integrations/expoupdateslistener.d.ts.map +1 -0
  47. package/dist/js/integrations/expoupdateslistener.js +130 -0
  48. package/dist/js/integrations/expoupdateslistener.js.map +1 -0
  49. package/dist/js/misc.js +2 -2
  50. package/dist/js/misc.js.map +1 -1
  51. package/dist/js/options.d.ts +12 -0
  52. package/dist/js/options.d.ts.map +1 -1
  53. package/dist/js/options.js.map +1 -1
  54. package/dist/js/sdk.d.ts.map +1 -1
  55. package/dist/js/sdk.js +3 -2
  56. package/dist/js/sdk.js.map +1 -1
  57. package/dist/js/tools/metroconfig.d.ts +4 -0
  58. package/dist/js/tools/metroconfig.d.ts.map +1 -1
  59. package/dist/js/tools/metroconfig.js +46 -1
  60. package/dist/js/tools/metroconfig.js.map +1 -1
  61. package/dist/js/tools/utils.d.ts.map +1 -1
  62. package/dist/js/tools/utils.js +2 -3
  63. package/dist/js/tools/utils.js.map +1 -1
  64. package/dist/js/tracing/expoAsset.d.ts +42 -0
  65. package/dist/js/tracing/expoAsset.d.ts.map +1 -0
  66. package/dist/js/tracing/expoAsset.js +60 -0
  67. package/dist/js/tracing/expoAsset.js.map +1 -0
  68. package/dist/js/tracing/expoImage.d.ts +61 -0
  69. package/dist/js/tracing/expoImage.d.ts.map +1 -0
  70. package/dist/js/tracing/expoImage.js +101 -0
  71. package/dist/js/tracing/expoImage.js.map +1 -0
  72. package/dist/js/tracing/index.d.ts +4 -0
  73. package/dist/js/tracing/index.d.ts.map +1 -1
  74. package/dist/js/tracing/index.js +2 -0
  75. package/dist/js/tracing/index.js.map +1 -1
  76. package/dist/js/tracing/integrations/appStart.d.ts +8 -0
  77. package/dist/js/tracing/integrations/appStart.d.ts.map +1 -1
  78. package/dist/js/tracing/integrations/appStart.js +56 -7
  79. package/dist/js/tracing/integrations/appStart.js.map +1 -1
  80. package/dist/js/tracing/integrations/nativeFrames.d.ts.map +1 -1
  81. package/dist/js/tracing/integrations/nativeFrames.js +32 -22
  82. package/dist/js/tracing/integrations/nativeFrames.js.map +1 -1
  83. package/dist/js/tracing/integrations/timeToDisplayIntegration.d.ts.map +1 -1
  84. package/dist/js/tracing/integrations/timeToDisplayIntegration.js +1 -0
  85. package/dist/js/tracing/integrations/timeToDisplayIntegration.js.map +1 -1
  86. package/dist/js/tracing/origin.d.ts +2 -0
  87. package/dist/js/tracing/origin.d.ts.map +1 -1
  88. package/dist/js/tracing/origin.js +2 -0
  89. package/dist/js/tracing/origin.js.map +1 -1
  90. package/dist/js/tracing/reactnativenavigation.js +1 -1
  91. package/dist/js/tracing/reactnativenavigation.js.map +1 -1
  92. package/dist/js/tracing/reactnavigation.d.ts.map +1 -1
  93. package/dist/js/tracing/reactnavigation.js +12 -5
  94. package/dist/js/tracing/reactnavigation.js.map +1 -1
  95. package/dist/js/tracing/utils.d.ts +27 -1
  96. package/dist/js/tracing/utils.d.ts.map +1 -1
  97. package/dist/js/tracing/utils.js +66 -1
  98. package/dist/js/tracing/utils.js.map +1 -1
  99. package/dist/js/utils/ignorerequirecyclelogs.js +1 -1
  100. package/dist/js/utils/ignorerequirecyclelogs.js.map +1 -1
  101. package/dist/js/utils/safe.d.ts +1 -1
  102. package/dist/js/utils/safe.d.ts.map +1 -1
  103. package/dist/js/utils/safe.js.map +1 -1
  104. package/dist/js/version.d.ts +1 -1
  105. package/dist/js/version.js +1 -1
  106. package/dist/js/version.js.map +1 -1
  107. package/ios/RNSentry.mm +47 -1
  108. package/ios/RNSentryEvents.h +1 -0
  109. package/ios/RNSentryEvents.m +1 -0
  110. package/ios/RNSentryVersion.m +1 -1
  111. package/package.json +14 -14
  112. package/plugin/build/utils.d.ts +1 -0
  113. package/plugin/build/utils.js +19 -1
  114. package/plugin/build/withSentry.d.ts +1 -0
  115. package/plugin/build/withSentry.js +29 -1
  116. package/plugin/build/withSentryAndroidGradlePlugin.d.ts +1 -1
  117. package/plugin/build/withSentryAndroidGradlePlugin.js +1 -1
  118. package/scripts/sentry-xcode.sh +14 -0
  119. package/sentry.gradle +13 -0
  120. package/src/js/NativeRNSentry.ts +2 -0
  121. package/ts3.8/dist/js/NativeRNSentry.d.ts +2 -0
  122. package/ts3.8/dist/js/feedback/FeedbackWidgetManager.d.ts +3 -1
  123. package/ts3.8/dist/js/feedback/FeedbackWidgetProvider.d.ts +3 -2
  124. package/ts3.8/dist/js/feedback/ShakeToReportBug.d.ts +27 -0
  125. package/ts3.8/dist/js/feedback/integration.d.ts +11 -0
  126. package/ts3.8/dist/js/index.d.ts +3 -3
  127. package/ts3.8/dist/js/integrations/exports.d.ts +1 -0
  128. package/ts3.8/dist/js/integrations/expoupdateslistener.d.ts +38 -0
  129. package/ts3.8/dist/js/options.d.ts +12 -0
  130. package/ts3.8/dist/js/tracing/expoAsset.d.ts +42 -0
  131. package/ts3.8/dist/js/tracing/expoImage.d.ts +61 -0
  132. package/ts3.8/dist/js/tracing/index.d.ts +4 -0
  133. package/ts3.8/dist/js/tracing/integrations/appStart.d.ts +8 -0
  134. package/ts3.8/dist/js/tracing/origin.d.ts +2 -0
  135. package/ts3.8/dist/js/tracing/utils.d.ts +27 -1
  136. package/ts3.8/dist/js/utils/safe.d.ts +1 -1
  137. package/ts3.8/dist/js/version.d.ts +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"reactnavigation.d.ts","sourceRoot":"","sources":["../../../src/js/tracing/reactnavigation.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,WAAW,EAAQ,MAAM,cAAc,CAAC;AA+B9D,eAAO,MAAM,gBAAgB,oBAAoB,CAAC;AAIlD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,yBAAyB,CACvC,SAAS,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CA2BpC;AA0BD,UAAU,iCAAiC;IACzC;;;;;OAKG;IACH,oBAAoB,EAAE,MAAM,CAAC;IAE7B;;;;;OAKG;IACH,0BAA0B,EAAE,OAAO,CAAC;IAEpC;;;;;OAKG;IACH,qCAAqC,EAAE,OAAO,CAAC;IAE/C;;;;;OAKG;IACH,4CAA4C,EAAE,OAAO,CAAC;IAEtD;;;;OAIG;IACH,uBAAuB,EAAE,OAAO,CAAC;IAEjC;;;;OAIG;IACH,+BAA+B,EAAE,OAAO,CAAC;IAEzC;;;;;;OAMG;IACH,sBAAsB,EAAE,OAAO,CAAC;CACjC;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,0BAA0B,kOAQpC,QAAQ,iCAAiC,CAAC;IAC3C;;;OAGG;0DACmD,OAAO,KAAK,IAAI;aAC7D,iCAAiC;CAqW3C,CAAC;AAEF,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IAEZ,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC7B,KAAK,CAAC,EAAE,eAAe,CAAC;CACzB;AAED,UAAU,eAAe;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,eAAe,EAAE,CAAC;CAC3B;AAQD;;GAEG;AACH,wBAAgB,6BAA6B,CAC3C,MAAM,EAAE,MAAM,GACb,UAAU,CAAC,OAAO,0BAA0B,CAAC,GAAG,SAAS,CAE3D"}
1
+ {"version":3,"file":"reactnavigation.d.ts","sourceRoot":"","sources":["../../../src/js/tracing/reactnavigation.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,WAAW,EAAQ,MAAM,cAAc,CAAC;AA+B9D,eAAO,MAAM,gBAAgB,oBAAoB,CAAC;AAIlD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,yBAAyB,CACvC,SAAS,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CA2BpC;AA0BD,UAAU,iCAAiC;IACzC;;;;;OAKG;IACH,oBAAoB,EAAE,MAAM,CAAC;IAE7B;;;;;OAKG;IACH,0BAA0B,EAAE,OAAO,CAAC;IAEpC;;;;;OAKG;IACH,qCAAqC,EAAE,OAAO,CAAC;IAE/C;;;;;OAKG;IACH,4CAA4C,EAAE,OAAO,CAAC;IAEtD;;;;OAIG;IACH,uBAAuB,EAAE,OAAO,CAAC;IAEjC;;;;OAIG;IACH,+BAA+B,EAAE,OAAO,CAAC;IAEzC;;;;;;OAMG;IACH,sBAAsB,EAAE,OAAO,CAAC;CACjC;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,0BAA0B,kOAQpC,QAAQ,iCAAiC,CAAC;IAC3C;;;OAGG;0DACmD,OAAO,KAAK,IAAI;aAC7D,iCAAiC;CA8W3C,CAAC;AAEF,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IAEZ,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC7B,KAAK,CAAC,EAAE,eAAe,CAAC;CACzB;AAED,UAAU,eAAe;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,eAAe,EAAE,CAAC;CAC3B;AAQD;;GAEG;AACH,wBAAgB,6BAA6B,CAC3C,MAAM,EAAE,MAAM,GACb,UAAU,CAAC,OAAO,0BAA0B,CAAC,GAAG,SAAS,CAE3D"}
@@ -86,6 +86,7 @@ export const reactNavigationIntegration = ({ routeChangeTimeoutMs = 1000, enable
86
86
  let latestNavigationSpan;
87
87
  let navigationProcessingSpan;
88
88
  let initialStateHandled = false;
89
+ let isSetupComplete = false;
89
90
  let stateChangeTimeout;
90
91
  let recentRouteKeys = [];
91
92
  if (enableTimeToInitialDisplay) {
@@ -120,12 +121,13 @@ export const reactNavigationIntegration = ({ routeChangeTimeoutMs = 1000, enable
120
121
  startIdleNavigationSpan(undefined, true);
121
122
  }
122
123
  });
123
- startIdleNavigationSpan();
124
+ isSetupComplete = true;
124
125
  if (!navigationContainer) {
125
126
  // This is expected as navigation container is registered after the root component is mounted.
126
127
  return undefined;
127
128
  }
128
- // Navigation container already registered, just populate with route state
129
+ // Navigation container already registered, create and populate initial span
130
+ startIdleNavigationSpan();
129
131
  updateLatestNavigationSpanWithCurrentRoute();
130
132
  initialStateHandled = true;
131
133
  };
@@ -161,8 +163,11 @@ export const reactNavigationIntegration = ({ routeChangeTimeoutMs = 1000, enable
161
163
  return undefined;
162
164
  }
163
165
  if (!latestNavigationSpan) {
164
- debug.log(`${INTEGRATION_NAME} Navigation container registered, but integration has not been setup yet.`);
165
- return undefined;
166
+ if (!isSetupComplete) {
167
+ debug.log(`${INTEGRATION_NAME} Navigation container registered before integration setup. Initial span will be created when setup completes.`);
168
+ return undefined;
169
+ }
170
+ startIdleNavigationSpan();
166
171
  }
167
172
  // Navigation Container is registered after the first navigation
168
173
  // Initial navigation span was started, after integration setup,
@@ -178,6 +183,7 @@ export const reactNavigationIntegration = ({ routeChangeTimeoutMs = 1000, enable
178
183
  * @param unknownEvent - The event object that contains navigation action data
179
184
  * @param isAppRestart - Whether this span is being started due to an app restart rather than a normal navigation action
180
185
  */
186
+ // eslint-disable-next-line complexity
181
187
  const startIdleNavigationSpan = (unknownEvent, isAppRestart = false) => {
182
188
  const event = unknownEvent;
183
189
  if (useDispatchedActionData && (event === null || event === void 0 ? void 0 : event.data.noop)) {
@@ -257,6 +263,7 @@ export const reactNavigationIntegration = ({ routeChangeTimeoutMs = 1000, enable
257
263
  /**
258
264
  * To be called AFTER the state has been changed to populate the transaction with the current route.
259
265
  */
266
+ // eslint-disable-next-line complexity
260
267
  const updateLatestNavigationSpanWithCurrentRoute = () => {
261
268
  var _a, _b, _c;
262
269
  const stateChangedTimestamp = timestampInSeconds();
@@ -275,7 +282,7 @@ export const reactNavigationIntegration = ({ routeChangeTimeoutMs = 1000, enable
275
282
  return undefined;
276
283
  }
277
284
  addTimeToInitialDisplayFallback(latestNavigationSpan.spanContext().spanId, NATIVE.getNewScreenTimeToDisplay());
278
- if (previousRoute && previousRoute.key === route.key) {
285
+ if ((previousRoute === null || previousRoute === void 0 ? void 0 : previousRoute.key) === route.key) {
279
286
  debug.log(`[${INTEGRATION_NAME}] Navigation state changed, but route is the same as previous.`);
280
287
  pushRecentRouteKey(route.key);
281
288
  latestRoute = route;
@@ -1 +1 @@
1
- {"version":3,"file":"reactnavigation.js","sourceRoot":"","sources":["../../../src/js/tracing/reactnavigation.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable max-lines */\nimport type { Client, Integration, Span } from '@sentry/core';\nimport {\n addBreadcrumb,\n debug,\n getClient,\n isPlainObject,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SPAN_STATUS_OK,\n spanToJSON,\n startInactiveSpan,\n timestampInSeconds,\n} from '@sentry/core';\nimport { getAppRegistryIntegration } from '../integrations/appRegistry';\nimport { isSentrySpan } from '../utils/span';\nimport { RN_GLOBAL_OBJ } from '../utils/worldwide';\nimport type { UnsafeAction } from '../vendor/react-navigation/types';\nimport { NATIVE } from '../wrapper';\nimport { ignoreEmptyBackNavigation, ignoreEmptyRouteChangeTransactions } from './onSpanEndUtils';\nimport { SPAN_ORIGIN_AUTO_NAVIGATION_REACT_NAVIGATION } from './origin';\nimport type { ReactNativeTracingIntegration } from './reactnativetracing';\nimport { getReactNativeTracingIntegration } from './reactnativetracing';\nimport { SEMANTIC_ATTRIBUTE_NAVIGATION_ACTION_TYPE, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } from './semanticAttributes';\nimport {\n DEFAULT_NAVIGATION_SPAN_NAME,\n defaultIdleOptions,\n getDefaultIdleNavigationSpanOptions,\n startIdleNavigationSpan as startGenericIdleNavigationSpan,\n} from './span';\nimport { addTimeToInitialDisplayFallback } from './timeToDisplayFallback';\n\nexport const INTEGRATION_NAME = 'ReactNavigation';\n\nconst NAVIGATION_HISTORY_MAX_SIZE = 200;\n\n/**\n * Extracts dynamic route parameters from a route name and its params.\n * Matches Expo Router style dynamic segments like `[id]` and `[...slug]`.\n *\n * Only params whose keys appear as dynamic segments in the route name are returned,\n * filtering out non-structural params (query params, etc.) that may contain PII.\n *\n * Note: dynamic segment values (e.g. the `123` in `profile/[id]`) may be user-identifiable.\n * This function only extracts params — callers are responsible for checking `sendDefaultPii`\n * before including the result in span attributes.\n *\n * Previous route params are intentionally not captured — only the current route's\n * structural params are needed for trace attribution.\n */\nexport function extractDynamicRouteParams(\n routeName: string,\n params?: Record<string, unknown>,\n): Record<string, string> | undefined {\n if (!params) {\n return undefined;\n }\n\n const dynamicKeys = new Set<string>();\n const pattern = /\\[(?:\\.\\.\\.)?(\\w+)\\]/g;\n let match: RegExpExecArray | null;\n while ((match = pattern.exec(routeName)) !== null) {\n if (match[1]) {\n dynamicKeys.add(match[1]);\n }\n }\n\n if (dynamicKeys.size === 0) {\n return undefined;\n }\n\n const result: Record<string, string> = {};\n for (const key of dynamicKeys) {\n if (key in params) {\n const value = params[key];\n result[`route.params.${key}`] = Array.isArray(value) ? value.join('/') : String(value ?? '');\n }\n }\n\n return Object.keys(result).length > 0 ? result : undefined;\n}\n\n/**\n * Builds a full path from the navigation state by traversing nested navigators.\n * For example, with nested navigators: \"Home/Settings/Profile\"\n */\nfunction getPathFromState(state?: NavigationState): string | undefined {\n if (!state) {\n return undefined;\n }\n\n const routeNames: string[] = [];\n let currentState: NavigationState | undefined = state;\n\n while (currentState) {\n const index: number = currentState.index ?? 0;\n const route: NavigationRoute | undefined = currentState.routes[index];\n if (route?.name) {\n routeNames.push(route.name);\n }\n currentState = route?.state;\n }\n\n return routeNames.length > 0 ? routeNames.join('/') : undefined;\n}\n\ninterface ReactNavigationIntegrationOptions {\n /**\n * How long the instrumentation will wait for the route to mount after a change has been initiated,\n * before the transaction is discarded.\n *\n * @default 1_000 (ms)\n */\n routeChangeTimeoutMs: number;\n\n /**\n * Time to initial display measures the time it takes from\n * navigation dispatch to the render of the first frame of the new screen.\n *\n * @default false\n */\n enableTimeToInitialDisplay: boolean;\n\n /**\n * Does not sample transactions that are from routes that have been seen any more and don't have any spans.\n * This removes a lot of the clutter as most back navigation transactions are now ignored.\n *\n * @default true\n */\n ignoreEmptyBackNavigationTransactions: boolean;\n\n /**\n * Enabled measuring Time to Initial Display for routes that are already loaded in memory.\n * (a.k.a., Routes that the navigation integration has already seen.)\n *\n * @default false\n */\n enableTimeToInitialDisplayForPreloadedRoutes: boolean;\n\n /**\n * Whether to use the dispatched action data to populate the transaction metadata.\n *\n * @default false\n */\n useDispatchedActionData: boolean;\n\n /**\n * Whether to use the full paths for navigation routes.\n *\n * @default false\n */\n useFullPathsForNavigationRoutes: boolean;\n\n /**\n * Track performance of route prefetching operations.\n * Creates separate spans for PRELOAD actions to measure prefetch performance.\n * This is useful for Expo Router apps that use the prefetch functionality.\n *\n * @default false\n */\n enablePrefetchTracking: boolean;\n}\n\n/**\n * Instrumentation for React-Navigation V5 and above. See docs or sample app for usage.\n *\n * How this works:\n * - `_onDispatch` is called every time a dispatch happens and sets an IdleTransaction on the scope without any route context.\n * - `_onStateChange` is then called AFTER the state change happens due to a dispatch and sets the route context onto the active transaction.\n * - If `_onStateChange` isn't called within `STATE_CHANGE_TIMEOUT_DURATION` of the dispatch, then the transaction is not sampled and finished.\n */\nexport const reactNavigationIntegration = ({\n routeChangeTimeoutMs = 1_000,\n enableTimeToInitialDisplay = false,\n ignoreEmptyBackNavigationTransactions = true,\n enableTimeToInitialDisplayForPreloadedRoutes = false,\n useDispatchedActionData = false,\n useFullPathsForNavigationRoutes = false,\n enablePrefetchTracking = false,\n}: Partial<ReactNavigationIntegrationOptions> = {}): Integration & {\n /**\n * Pass the ref to the navigation container to register it to the instrumentation\n * @param navigationContainerRef Ref to a `NavigationContainer`\n */\n registerNavigationContainer: (navigationContainerRef: unknown) => void;\n options: ReactNavigationIntegrationOptions;\n} => {\n let navigationContainer: NavigationContainer | undefined;\n\n let tracing: ReactNativeTracingIntegration | undefined;\n let idleSpanOptions: Parameters<typeof startGenericIdleNavigationSpan>[1] = defaultIdleOptions;\n let latestRoute: NavigationRoute | undefined;\n\n let latestNavigationSpan: Span | undefined;\n let navigationProcessingSpan: Span | undefined;\n\n let initialStateHandled: boolean = false;\n let stateChangeTimeout: ReturnType<typeof setTimeout> | undefined;\n let recentRouteKeys: string[] = [];\n\n if (enableTimeToInitialDisplay) {\n NATIVE.initNativeReactNavigationNewFrameTracking().catch((reason: unknown) => {\n debug.error(`${INTEGRATION_NAME} Failed to initialize native new frame tracking: ${reason}`);\n });\n }\n\n /**\n * Set the initial state and start initial navigation span for the current screen.\n */\n const afterAllSetup = (client: Client): void => {\n tracing = getReactNativeTracingIntegration(client);\n if (tracing) {\n idleSpanOptions = {\n finalTimeout: tracing.options.finalTimeoutMs,\n idleTimeout: tracing.options.idleTimeoutMs,\n };\n }\n\n if (initialStateHandled) {\n // We create an initial state here to ensure a transaction gets created before the first route mounts.\n // This assumes that the Sentry.init() call is made before the first route mounts.\n // If this is not the case, the first transaction will be nameless 'Route Changed'\n return undefined;\n }\n\n getAppRegistryIntegration(client)?.onRunApplication(() => {\n if (initialStateHandled) {\n // To avoid conflict with the initial transaction we check if it was already handled.\n // This ensures runApplication calls after the initial start are correctly traced.\n // This is used for example when Activity is (re)started on Android.\n debug.log('[ReactNavigationIntegration] Starting new idle navigation span based on runApplication call.');\n startIdleNavigationSpan(undefined, true);\n }\n });\n\n startIdleNavigationSpan();\n\n if (!navigationContainer) {\n // This is expected as navigation container is registered after the root component is mounted.\n return undefined;\n }\n\n // Navigation container already registered, just populate with route state\n updateLatestNavigationSpanWithCurrentRoute();\n initialStateHandled = true;\n };\n\n const registerNavigationContainer = (maybeNewNavigationContainer: unknown): void => {\n if (RN_GLOBAL_OBJ.__sentry_rn_v5_registered) {\n debug.log(`${INTEGRATION_NAME} Instrumentation already exists, but registering again...`);\n // In the past we have not allowed re-registering the navigation container to avoid unexpected behavior.\n // But this doesn't work for Android and re-recreating application main activity.\n // Where new navigation container is created and the old one is discarded. We need to re-register to\n // trace the new navigation container navigation.\n }\n\n let newNavigationContainer: NavigationContainer | undefined;\n if (isPlainObject(maybeNewNavigationContainer) && 'current' in maybeNewNavigationContainer) {\n newNavigationContainer = maybeNewNavigationContainer.current as NavigationContainer;\n } else {\n newNavigationContainer = maybeNewNavigationContainer as NavigationContainer;\n }\n\n if (navigationContainer === newNavigationContainer) {\n debug.log(`${INTEGRATION_NAME} Navigation container ref is the same as the one already registered.`);\n return;\n }\n navigationContainer = newNavigationContainer;\n\n if (!navigationContainer) {\n debug.warn(`${INTEGRATION_NAME} Received invalid navigation container ref!`);\n return undefined;\n }\n\n // This action is emitted on every dispatch\n navigationContainer.addListener('__unsafe_action__', startIdleNavigationSpan);\n navigationContainer.addListener('state', updateLatestNavigationSpanWithCurrentRoute);\n RN_GLOBAL_OBJ.__sentry_rn_v5_registered = true;\n\n if (initialStateHandled) {\n return undefined;\n }\n\n if (!latestNavigationSpan) {\n debug.log(`${INTEGRATION_NAME} Navigation container registered, but integration has not been setup yet.`);\n return undefined;\n }\n\n // Navigation Container is registered after the first navigation\n // Initial navigation span was started, after integration setup,\n // so now we populate it with the current route.\n updateLatestNavigationSpanWithCurrentRoute();\n initialStateHandled = true;\n };\n\n /**\n * To be called on every React-Navigation action dispatch.\n * It does not name the transaction or populate it with route information. Instead, it waits for the state to fully change\n * and gets the route information from there, @see updateLatestNavigationSpanWithCurrentRoute\n *\n * @param unknownEvent - The event object that contains navigation action data\n * @param isAppRestart - Whether this span is being started due to an app restart rather than a normal navigation action\n */\n const startIdleNavigationSpan = (unknownEvent?: unknown, isAppRestart = false): void => {\n const event = unknownEvent as UnsafeAction | undefined;\n if (useDispatchedActionData && event?.data.noop) {\n debug.log(`${INTEGRATION_NAME} Navigation action is a noop, not starting navigation span.`);\n return;\n }\n\n const navigationActionType = useDispatchedActionData ? event?.data.action.type : undefined;\n\n // Handle PRELOAD actions separately if prefetch tracking is enabled\n if (enablePrefetchTracking && navigationActionType === 'PRELOAD') {\n const preloadData = event?.data.action;\n const payload = preloadData?.payload;\n const targetRoute =\n payload && typeof payload === 'object' && 'name' in payload && typeof payload.name === 'string'\n ? payload.name\n : 'Unknown Route';\n\n debug.log(`${INTEGRATION_NAME} Starting prefetch span for route: ${targetRoute}`);\n\n const prefetchSpan = startInactiveSpan({\n op: 'navigation.prefetch',\n name: `Prefetch ${targetRoute}`,\n attributes: {\n 'route.name': targetRoute,\n },\n });\n\n // Store prefetch span to end it when state changes or timeout\n navigationProcessingSpan = prefetchSpan;\n\n // Set timeout to ensure we don't leave hanging spans\n stateChangeTimeout = setTimeout(() => {\n if (navigationProcessingSpan === prefetchSpan) {\n debug.log(`${INTEGRATION_NAME} Prefetch span timed out for route: ${targetRoute}`);\n prefetchSpan?.setStatus({ code: SPAN_STATUS_OK });\n prefetchSpan?.end();\n navigationProcessingSpan = undefined;\n }\n }, routeChangeTimeoutMs);\n\n return;\n }\n\n if (\n useDispatchedActionData &&\n navigationActionType &&\n [\n // Process common actions\n 'PRELOAD', // Still filter PRELOAD when enablePrefetchTracking is false\n 'SET_PARAMS',\n // Drawer actions\n 'OPEN_DRAWER',\n 'CLOSE_DRAWER',\n 'TOGGLE_DRAWER',\n ].includes(navigationActionType)\n ) {\n debug.log(`${INTEGRATION_NAME} Navigation action is ${navigationActionType}, not starting navigation span.`);\n return;\n }\n\n if (latestNavigationSpan) {\n debug.log(`${INTEGRATION_NAME} A transaction was detected that turned out to be a noop, discarding.`);\n _discardLatestTransaction();\n clearStateChangeTimeout();\n }\n\n latestNavigationSpan = startGenericIdleNavigationSpan(\n tracing?.options.beforeStartSpan\n ? tracing.options.beforeStartSpan(getDefaultIdleNavigationSpanOptions())\n : getDefaultIdleNavigationSpanOptions(),\n { ...idleSpanOptions, isAppRestart },\n );\n latestNavigationSpan?.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SPAN_ORIGIN_AUTO_NAVIGATION_REACT_NAVIGATION);\n latestNavigationSpan?.setAttribute(SEMANTIC_ATTRIBUTE_NAVIGATION_ACTION_TYPE, navigationActionType);\n if (ignoreEmptyBackNavigationTransactions) {\n ignoreEmptyBackNavigation(getClient(), latestNavigationSpan);\n }\n // Always discard transactions that never receive route information\n const spanToCheck = latestNavigationSpan;\n ignoreEmptyRouteChangeTransactions(\n getClient(),\n spanToCheck,\n DEFAULT_NAVIGATION_SPAN_NAME,\n () => latestNavigationSpan === spanToCheck,\n );\n\n if (enableTimeToInitialDisplay && latestNavigationSpan) {\n NATIVE.setActiveSpanId(latestNavigationSpan.spanContext().spanId);\n navigationProcessingSpan = startInactiveSpan({\n op: 'navigation.processing',\n name: 'Navigation dispatch to navigation cancelled or screen mounted',\n startTime: spanToJSON(latestNavigationSpan).start_timestamp,\n });\n navigationProcessingSpan.setAttribute(\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SPAN_ORIGIN_AUTO_NAVIGATION_REACT_NAVIGATION,\n );\n }\n\n stateChangeTimeout = setTimeout(_discardLatestTransaction, routeChangeTimeoutMs);\n };\n\n /**\n * To be called AFTER the state has been changed to populate the transaction with the current route.\n */\n const updateLatestNavigationSpanWithCurrentRoute = (): void => {\n const stateChangedTimestamp = timestampInSeconds();\n const previousRoute = latestRoute;\n\n if (!navigationContainer) {\n debug.warn(`${INTEGRATION_NAME} Missing navigation container ref. Route transactions will not be sent.`);\n return undefined;\n }\n\n const route = navigationContainer.getCurrentRoute();\n if (!route) {\n debug.log(`[${INTEGRATION_NAME}] Navigation state changed, but no route is rendered.`);\n return undefined;\n }\n\n if (!latestNavigationSpan) {\n debug.log(\n `[${INTEGRATION_NAME}] Navigation state changed, but navigation transaction was not started on dispatch.`,\n );\n return undefined;\n }\n\n addTimeToInitialDisplayFallback(latestNavigationSpan.spanContext().spanId, NATIVE.getNewScreenTimeToDisplay());\n\n if (previousRoute && previousRoute.key === route.key) {\n debug.log(`[${INTEGRATION_NAME}] Navigation state changed, but route is the same as previous.`);\n pushRecentRouteKey(route.key);\n latestRoute = route;\n\n // Clear the latest transaction as it has been handled.\n latestNavigationSpan = undefined;\n return undefined;\n }\n\n const routeHasBeenSeen = recentRouteKeys.includes(route.key);\n\n // Get the full navigation path for nested navigators\n let routeName = route.name;\n if (useFullPathsForNavigationRoutes) {\n const navigationState = navigationContainer.getState();\n routeName = getPathFromState(navigationState) || route.name;\n }\n\n navigationProcessingSpan?.updateName(`Navigation dispatch to screen ${routeName} mounted`);\n navigationProcessingSpan?.setStatus({ code: SPAN_STATUS_OK });\n navigationProcessingSpan?.end(stateChangedTimestamp);\n navigationProcessingSpan = undefined;\n\n if (spanToJSON(latestNavigationSpan).description === DEFAULT_NAVIGATION_SPAN_NAME) {\n latestNavigationSpan.updateName(routeName);\n }\n const sendDefaultPii = getClient()?.getOptions()?.sendDefaultPii ?? false;\n latestNavigationSpan.setAttributes({\n 'route.name': routeName,\n 'route.key': route.key,\n ...(sendDefaultPii ? extractDynamicRouteParams(routeName, route.params) : undefined),\n 'route.has_been_seen': routeHasBeenSeen,\n 'previous_route.name': previousRoute?.name,\n 'previous_route.key': previousRoute?.key,\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'component',\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'navigation',\n });\n\n // Clear the timeout so the transaction does not get cancelled.\n clearStateChangeTimeout();\n\n addBreadcrumb({\n category: 'navigation',\n type: 'navigation',\n message: `Navigation to ${routeName}`,\n data: {\n from: previousRoute?.name,\n to: routeName,\n },\n });\n\n tracing?.setCurrentRoute(routeName);\n\n pushRecentRouteKey(route.key);\n if (useFullPathsForNavigationRoutes) {\n latestRoute = { ...route, name: routeName };\n } else {\n latestRoute = route;\n }\n // Clear the latest transaction as it has been handled.\n latestNavigationSpan = undefined;\n };\n\n /** Pushes a recent route key, and removes earlier routes when there is greater than the max length */\n const pushRecentRouteKey = (key: string): void => {\n recentRouteKeys.push(key);\n\n if (recentRouteKeys.length > NAVIGATION_HISTORY_MAX_SIZE) {\n recentRouteKeys = recentRouteKeys.slice(recentRouteKeys.length - NAVIGATION_HISTORY_MAX_SIZE);\n }\n };\n\n /** Cancels the latest transaction so it does not get sent to Sentry. */\n const _discardLatestTransaction = (): void => {\n if (latestNavigationSpan) {\n if (isSentrySpan(latestNavigationSpan)) {\n latestNavigationSpan['_sampled'] = false;\n }\n // TODO: What if it's not SentrySpan?\n latestNavigationSpan.end();\n latestNavigationSpan = undefined;\n }\n if (navigationProcessingSpan) {\n navigationProcessingSpan = undefined;\n }\n };\n\n const clearStateChangeTimeout = (): void => {\n if (typeof stateChangeTimeout !== 'undefined') {\n clearTimeout(stateChangeTimeout);\n stateChangeTimeout = undefined;\n }\n };\n\n return {\n name: INTEGRATION_NAME,\n afterAllSetup,\n registerNavigationContainer,\n options: {\n routeChangeTimeoutMs,\n enableTimeToInitialDisplay,\n ignoreEmptyBackNavigationTransactions,\n enableTimeToInitialDisplayForPreloadedRoutes,\n useDispatchedActionData,\n useFullPathsForNavigationRoutes,\n enablePrefetchTracking,\n },\n };\n};\n\nexport interface NavigationRoute {\n name: string;\n key: string;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n params?: Record<string, any>;\n state?: NavigationState;\n}\n\ninterface NavigationState {\n index?: number;\n routes: NavigationRoute[];\n}\n\ninterface NavigationContainer {\n addListener: (type: string, listener: (event?: unknown) => void) => void;\n getCurrentRoute: () => NavigationRoute;\n getState: () => NavigationState | undefined;\n}\n\n/**\n * Returns React Navigation integration of the given client.\n */\nexport function getReactNavigationIntegration(\n client: Client,\n): ReturnType<typeof reactNavigationIntegration> | undefined {\n return client.getIntegrationByName<ReturnType<typeof reactNavigationIntegration>>(INTEGRATION_NAME);\n}\n"]}
1
+ {"version":3,"file":"reactnavigation.js","sourceRoot":"","sources":["../../../src/js/tracing/reactnavigation.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable max-lines */\nimport type { Client, Integration, Span } from '@sentry/core';\nimport {\n addBreadcrumb,\n debug,\n getClient,\n isPlainObject,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SPAN_STATUS_OK,\n spanToJSON,\n startInactiveSpan,\n timestampInSeconds,\n} from '@sentry/core';\nimport { getAppRegistryIntegration } from '../integrations/appRegistry';\nimport { isSentrySpan } from '../utils/span';\nimport { RN_GLOBAL_OBJ } from '../utils/worldwide';\nimport type { UnsafeAction } from '../vendor/react-navigation/types';\nimport { NATIVE } from '../wrapper';\nimport { ignoreEmptyBackNavigation, ignoreEmptyRouteChangeTransactions } from './onSpanEndUtils';\nimport { SPAN_ORIGIN_AUTO_NAVIGATION_REACT_NAVIGATION } from './origin';\nimport type { ReactNativeTracingIntegration } from './reactnativetracing';\nimport { getReactNativeTracingIntegration } from './reactnativetracing';\nimport { SEMANTIC_ATTRIBUTE_NAVIGATION_ACTION_TYPE, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } from './semanticAttributes';\nimport {\n DEFAULT_NAVIGATION_SPAN_NAME,\n defaultIdleOptions,\n getDefaultIdleNavigationSpanOptions,\n startIdleNavigationSpan as startGenericIdleNavigationSpan,\n} from './span';\nimport { addTimeToInitialDisplayFallback } from './timeToDisplayFallback';\n\nexport const INTEGRATION_NAME = 'ReactNavigation';\n\nconst NAVIGATION_HISTORY_MAX_SIZE = 200;\n\n/**\n * Extracts dynamic route parameters from a route name and its params.\n * Matches Expo Router style dynamic segments like `[id]` and `[...slug]`.\n *\n * Only params whose keys appear as dynamic segments in the route name are returned,\n * filtering out non-structural params (query params, etc.) that may contain PII.\n *\n * Note: dynamic segment values (e.g. the `123` in `profile/[id]`) may be user-identifiable.\n * This function only extracts params — callers are responsible for checking `sendDefaultPii`\n * before including the result in span attributes.\n *\n * Previous route params are intentionally not captured — only the current route's\n * structural params are needed for trace attribution.\n */\nexport function extractDynamicRouteParams(\n routeName: string,\n params?: Record<string, unknown>,\n): Record<string, string> | undefined {\n if (!params) {\n return undefined;\n }\n\n const dynamicKeys = new Set<string>();\n const pattern = /\\[(?:\\.\\.\\.)?(\\w+)\\]/g;\n let match: RegExpExecArray | null;\n while ((match = pattern.exec(routeName)) !== null) {\n if (match[1]) {\n dynamicKeys.add(match[1]);\n }\n }\n\n if (dynamicKeys.size === 0) {\n return undefined;\n }\n\n const result: Record<string, string> = {};\n for (const key of dynamicKeys) {\n if (key in params) {\n const value = params[key];\n result[`route.params.${key}`] = Array.isArray(value) ? value.join('/') : String(value ?? '');\n }\n }\n\n return Object.keys(result).length > 0 ? result : undefined;\n}\n\n/**\n * Builds a full path from the navigation state by traversing nested navigators.\n * For example, with nested navigators: \"Home/Settings/Profile\"\n */\nfunction getPathFromState(state?: NavigationState): string | undefined {\n if (!state) {\n return undefined;\n }\n\n const routeNames: string[] = [];\n let currentState: NavigationState | undefined = state;\n\n while (currentState) {\n const index: number = currentState.index ?? 0;\n const route: NavigationRoute | undefined = currentState.routes[index];\n if (route?.name) {\n routeNames.push(route.name);\n }\n currentState = route?.state;\n }\n\n return routeNames.length > 0 ? routeNames.join('/') : undefined;\n}\n\ninterface ReactNavigationIntegrationOptions {\n /**\n * How long the instrumentation will wait for the route to mount after a change has been initiated,\n * before the transaction is discarded.\n *\n * @default 1_000 (ms)\n */\n routeChangeTimeoutMs: number;\n\n /**\n * Time to initial display measures the time it takes from\n * navigation dispatch to the render of the first frame of the new screen.\n *\n * @default false\n */\n enableTimeToInitialDisplay: boolean;\n\n /**\n * Does not sample transactions that are from routes that have been seen any more and don't have any spans.\n * This removes a lot of the clutter as most back navigation transactions are now ignored.\n *\n * @default true\n */\n ignoreEmptyBackNavigationTransactions: boolean;\n\n /**\n * Enabled measuring Time to Initial Display for routes that are already loaded in memory.\n * (a.k.a., Routes that the navigation integration has already seen.)\n *\n * @default false\n */\n enableTimeToInitialDisplayForPreloadedRoutes: boolean;\n\n /**\n * Whether to use the dispatched action data to populate the transaction metadata.\n *\n * @default false\n */\n useDispatchedActionData: boolean;\n\n /**\n * Whether to use the full paths for navigation routes.\n *\n * @default false\n */\n useFullPathsForNavigationRoutes: boolean;\n\n /**\n * Track performance of route prefetching operations.\n * Creates separate spans for PRELOAD actions to measure prefetch performance.\n * This is useful for Expo Router apps that use the prefetch functionality.\n *\n * @default false\n */\n enablePrefetchTracking: boolean;\n}\n\n/**\n * Instrumentation for React-Navigation V5 and above. See docs or sample app for usage.\n *\n * How this works:\n * - `_onDispatch` is called every time a dispatch happens and sets an IdleTransaction on the scope without any route context.\n * - `_onStateChange` is then called AFTER the state change happens due to a dispatch and sets the route context onto the active transaction.\n * - If `_onStateChange` isn't called within `STATE_CHANGE_TIMEOUT_DURATION` of the dispatch, then the transaction is not sampled and finished.\n */\nexport const reactNavigationIntegration = ({\n routeChangeTimeoutMs = 1_000,\n enableTimeToInitialDisplay = false,\n ignoreEmptyBackNavigationTransactions = true,\n enableTimeToInitialDisplayForPreloadedRoutes = false,\n useDispatchedActionData = false,\n useFullPathsForNavigationRoutes = false,\n enablePrefetchTracking = false,\n}: Partial<ReactNavigationIntegrationOptions> = {}): Integration & {\n /**\n * Pass the ref to the navigation container to register it to the instrumentation\n * @param navigationContainerRef Ref to a `NavigationContainer`\n */\n registerNavigationContainer: (navigationContainerRef: unknown) => void;\n options: ReactNavigationIntegrationOptions;\n} => {\n let navigationContainer: NavigationContainer | undefined;\n\n let tracing: ReactNativeTracingIntegration | undefined;\n let idleSpanOptions: Parameters<typeof startGenericIdleNavigationSpan>[1] = defaultIdleOptions;\n let latestRoute: NavigationRoute | undefined;\n\n let latestNavigationSpan: Span | undefined;\n let navigationProcessingSpan: Span | undefined;\n\n let initialStateHandled: boolean = false;\n let isSetupComplete: boolean = false;\n let stateChangeTimeout: ReturnType<typeof setTimeout> | undefined;\n let recentRouteKeys: string[] = [];\n\n if (enableTimeToInitialDisplay) {\n NATIVE.initNativeReactNavigationNewFrameTracking().catch((reason: unknown) => {\n debug.error(`${INTEGRATION_NAME} Failed to initialize native new frame tracking: ${reason}`);\n });\n }\n\n /**\n * Set the initial state and start initial navigation span for the current screen.\n */\n const afterAllSetup = (client: Client): void => {\n tracing = getReactNativeTracingIntegration(client);\n if (tracing) {\n idleSpanOptions = {\n finalTimeout: tracing.options.finalTimeoutMs,\n idleTimeout: tracing.options.idleTimeoutMs,\n };\n }\n\n if (initialStateHandled) {\n // We create an initial state here to ensure a transaction gets created before the first route mounts.\n // This assumes that the Sentry.init() call is made before the first route mounts.\n // If this is not the case, the first transaction will be nameless 'Route Changed'\n return undefined;\n }\n\n getAppRegistryIntegration(client)?.onRunApplication(() => {\n if (initialStateHandled) {\n // To avoid conflict with the initial transaction we check if it was already handled.\n // This ensures runApplication calls after the initial start are correctly traced.\n // This is used for example when Activity is (re)started on Android.\n debug.log('[ReactNavigationIntegration] Starting new idle navigation span based on runApplication call.');\n startIdleNavigationSpan(undefined, true);\n }\n });\n\n isSetupComplete = true;\n\n if (!navigationContainer) {\n // This is expected as navigation container is registered after the root component is mounted.\n return undefined;\n }\n\n // Navigation container already registered, create and populate initial span\n startIdleNavigationSpan();\n updateLatestNavigationSpanWithCurrentRoute();\n initialStateHandled = true;\n };\n\n const registerNavigationContainer = (maybeNewNavigationContainer: unknown): void => {\n if (RN_GLOBAL_OBJ.__sentry_rn_v5_registered) {\n debug.log(`${INTEGRATION_NAME} Instrumentation already exists, but registering again...`);\n // In the past we have not allowed re-registering the navigation container to avoid unexpected behavior.\n // But this doesn't work for Android and re-recreating application main activity.\n // Where new navigation container is created and the old one is discarded. We need to re-register to\n // trace the new navigation container navigation.\n }\n\n let newNavigationContainer: NavigationContainer | undefined;\n if (isPlainObject(maybeNewNavigationContainer) && 'current' in maybeNewNavigationContainer) {\n newNavigationContainer = maybeNewNavigationContainer.current as NavigationContainer;\n } else {\n newNavigationContainer = maybeNewNavigationContainer as NavigationContainer;\n }\n\n if (navigationContainer === newNavigationContainer) {\n debug.log(`${INTEGRATION_NAME} Navigation container ref is the same as the one already registered.`);\n return;\n }\n navigationContainer = newNavigationContainer;\n\n if (!navigationContainer) {\n debug.warn(`${INTEGRATION_NAME} Received invalid navigation container ref!`);\n return undefined;\n }\n\n // This action is emitted on every dispatch\n navigationContainer.addListener('__unsafe_action__', startIdleNavigationSpan);\n navigationContainer.addListener('state', updateLatestNavigationSpanWithCurrentRoute);\n RN_GLOBAL_OBJ.__sentry_rn_v5_registered = true;\n\n if (initialStateHandled) {\n return undefined;\n }\n\n if (!latestNavigationSpan) {\n if (!isSetupComplete) {\n debug.log(\n `${INTEGRATION_NAME} Navigation container registered before integration setup. Initial span will be created when setup completes.`,\n );\n return undefined;\n }\n startIdleNavigationSpan();\n }\n\n // Navigation Container is registered after the first navigation\n // Initial navigation span was started, after integration setup,\n // so now we populate it with the current route.\n updateLatestNavigationSpanWithCurrentRoute();\n initialStateHandled = true;\n };\n\n /**\n * To be called on every React-Navigation action dispatch.\n * It does not name the transaction or populate it with route information. Instead, it waits for the state to fully change\n * and gets the route information from there, @see updateLatestNavigationSpanWithCurrentRoute\n *\n * @param unknownEvent - The event object that contains navigation action data\n * @param isAppRestart - Whether this span is being started due to an app restart rather than a normal navigation action\n */\n // eslint-disable-next-line complexity\n const startIdleNavigationSpan = (unknownEvent?: unknown, isAppRestart = false): void => {\n const event = unknownEvent as UnsafeAction | undefined;\n if (useDispatchedActionData && event?.data.noop) {\n debug.log(`${INTEGRATION_NAME} Navigation action is a noop, not starting navigation span.`);\n return;\n }\n\n const navigationActionType = useDispatchedActionData ? event?.data.action.type : undefined;\n\n // Handle PRELOAD actions separately if prefetch tracking is enabled\n if (enablePrefetchTracking && navigationActionType === 'PRELOAD') {\n const preloadData = event?.data.action;\n const payload = preloadData?.payload;\n const targetRoute =\n payload && typeof payload === 'object' && 'name' in payload && typeof payload.name === 'string'\n ? payload.name\n : 'Unknown Route';\n\n debug.log(`${INTEGRATION_NAME} Starting prefetch span for route: ${targetRoute}`);\n\n const prefetchSpan = startInactiveSpan({\n op: 'navigation.prefetch',\n name: `Prefetch ${targetRoute}`,\n attributes: {\n 'route.name': targetRoute,\n },\n });\n\n // Store prefetch span to end it when state changes or timeout\n navigationProcessingSpan = prefetchSpan;\n\n // Set timeout to ensure we don't leave hanging spans\n stateChangeTimeout = setTimeout(() => {\n if (navigationProcessingSpan === prefetchSpan) {\n debug.log(`${INTEGRATION_NAME} Prefetch span timed out for route: ${targetRoute}`);\n prefetchSpan?.setStatus({ code: SPAN_STATUS_OK });\n prefetchSpan?.end();\n navigationProcessingSpan = undefined;\n }\n }, routeChangeTimeoutMs);\n\n return;\n }\n\n if (\n useDispatchedActionData &&\n navigationActionType &&\n [\n // Process common actions\n 'PRELOAD', // Still filter PRELOAD when enablePrefetchTracking is false\n 'SET_PARAMS',\n // Drawer actions\n 'OPEN_DRAWER',\n 'CLOSE_DRAWER',\n 'TOGGLE_DRAWER',\n ].includes(navigationActionType)\n ) {\n debug.log(`${INTEGRATION_NAME} Navigation action is ${navigationActionType}, not starting navigation span.`);\n return;\n }\n\n if (latestNavigationSpan) {\n debug.log(`${INTEGRATION_NAME} A transaction was detected that turned out to be a noop, discarding.`);\n _discardLatestTransaction();\n clearStateChangeTimeout();\n }\n\n latestNavigationSpan = startGenericIdleNavigationSpan(\n tracing?.options.beforeStartSpan\n ? tracing.options.beforeStartSpan(getDefaultIdleNavigationSpanOptions())\n : getDefaultIdleNavigationSpanOptions(),\n { ...idleSpanOptions, isAppRestart },\n );\n latestNavigationSpan?.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SPAN_ORIGIN_AUTO_NAVIGATION_REACT_NAVIGATION);\n latestNavigationSpan?.setAttribute(SEMANTIC_ATTRIBUTE_NAVIGATION_ACTION_TYPE, navigationActionType);\n if (ignoreEmptyBackNavigationTransactions) {\n ignoreEmptyBackNavigation(getClient(), latestNavigationSpan);\n }\n // Always discard transactions that never receive route information\n const spanToCheck = latestNavigationSpan;\n ignoreEmptyRouteChangeTransactions(\n getClient(),\n spanToCheck,\n DEFAULT_NAVIGATION_SPAN_NAME,\n () => latestNavigationSpan === spanToCheck,\n );\n\n if (enableTimeToInitialDisplay && latestNavigationSpan) {\n NATIVE.setActiveSpanId(latestNavigationSpan.spanContext().spanId);\n navigationProcessingSpan = startInactiveSpan({\n op: 'navigation.processing',\n name: 'Navigation dispatch to navigation cancelled or screen mounted',\n startTime: spanToJSON(latestNavigationSpan).start_timestamp,\n });\n navigationProcessingSpan.setAttribute(\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SPAN_ORIGIN_AUTO_NAVIGATION_REACT_NAVIGATION,\n );\n }\n\n stateChangeTimeout = setTimeout(_discardLatestTransaction, routeChangeTimeoutMs);\n };\n\n /**\n * To be called AFTER the state has been changed to populate the transaction with the current route.\n */\n // eslint-disable-next-line complexity\n const updateLatestNavigationSpanWithCurrentRoute = (): void => {\n const stateChangedTimestamp = timestampInSeconds();\n const previousRoute = latestRoute;\n\n if (!navigationContainer) {\n debug.warn(`${INTEGRATION_NAME} Missing navigation container ref. Route transactions will not be sent.`);\n return undefined;\n }\n\n const route = navigationContainer.getCurrentRoute();\n if (!route) {\n debug.log(`[${INTEGRATION_NAME}] Navigation state changed, but no route is rendered.`);\n return undefined;\n }\n\n if (!latestNavigationSpan) {\n debug.log(\n `[${INTEGRATION_NAME}] Navigation state changed, but navigation transaction was not started on dispatch.`,\n );\n return undefined;\n }\n\n addTimeToInitialDisplayFallback(latestNavigationSpan.spanContext().spanId, NATIVE.getNewScreenTimeToDisplay());\n\n if (previousRoute?.key === route.key) {\n debug.log(`[${INTEGRATION_NAME}] Navigation state changed, but route is the same as previous.`);\n pushRecentRouteKey(route.key);\n latestRoute = route;\n\n // Clear the latest transaction as it has been handled.\n latestNavigationSpan = undefined;\n return undefined;\n }\n\n const routeHasBeenSeen = recentRouteKeys.includes(route.key);\n\n // Get the full navigation path for nested navigators\n let routeName = route.name;\n if (useFullPathsForNavigationRoutes) {\n const navigationState = navigationContainer.getState();\n routeName = getPathFromState(navigationState) || route.name;\n }\n\n navigationProcessingSpan?.updateName(`Navigation dispatch to screen ${routeName} mounted`);\n navigationProcessingSpan?.setStatus({ code: SPAN_STATUS_OK });\n navigationProcessingSpan?.end(stateChangedTimestamp);\n navigationProcessingSpan = undefined;\n\n if (spanToJSON(latestNavigationSpan).description === DEFAULT_NAVIGATION_SPAN_NAME) {\n latestNavigationSpan.updateName(routeName);\n }\n const sendDefaultPii = getClient()?.getOptions()?.sendDefaultPii ?? false;\n latestNavigationSpan.setAttributes({\n 'route.name': routeName,\n 'route.key': route.key,\n ...(sendDefaultPii ? extractDynamicRouteParams(routeName, route.params) : undefined),\n 'route.has_been_seen': routeHasBeenSeen,\n 'previous_route.name': previousRoute?.name,\n 'previous_route.key': previousRoute?.key,\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'component',\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'navigation',\n });\n\n // Clear the timeout so the transaction does not get cancelled.\n clearStateChangeTimeout();\n\n addBreadcrumb({\n category: 'navigation',\n type: 'navigation',\n message: `Navigation to ${routeName}`,\n data: {\n from: previousRoute?.name,\n to: routeName,\n },\n });\n\n tracing?.setCurrentRoute(routeName);\n\n pushRecentRouteKey(route.key);\n if (useFullPathsForNavigationRoutes) {\n latestRoute = { ...route, name: routeName };\n } else {\n latestRoute = route;\n }\n // Clear the latest transaction as it has been handled.\n latestNavigationSpan = undefined;\n };\n\n /** Pushes a recent route key, and removes earlier routes when there is greater than the max length */\n const pushRecentRouteKey = (key: string): void => {\n recentRouteKeys.push(key);\n\n if (recentRouteKeys.length > NAVIGATION_HISTORY_MAX_SIZE) {\n recentRouteKeys = recentRouteKeys.slice(recentRouteKeys.length - NAVIGATION_HISTORY_MAX_SIZE);\n }\n };\n\n /** Cancels the latest transaction so it does not get sent to Sentry. */\n const _discardLatestTransaction = (): void => {\n if (latestNavigationSpan) {\n if (isSentrySpan(latestNavigationSpan)) {\n latestNavigationSpan['_sampled'] = false;\n }\n // TODO: What if it's not SentrySpan?\n latestNavigationSpan.end();\n latestNavigationSpan = undefined;\n }\n if (navigationProcessingSpan) {\n navigationProcessingSpan = undefined;\n }\n };\n\n const clearStateChangeTimeout = (): void => {\n if (typeof stateChangeTimeout !== 'undefined') {\n clearTimeout(stateChangeTimeout);\n stateChangeTimeout = undefined;\n }\n };\n\n return {\n name: INTEGRATION_NAME,\n afterAllSetup,\n registerNavigationContainer,\n options: {\n routeChangeTimeoutMs,\n enableTimeToInitialDisplay,\n ignoreEmptyBackNavigationTransactions,\n enableTimeToInitialDisplayForPreloadedRoutes,\n useDispatchedActionData,\n useFullPathsForNavigationRoutes,\n enablePrefetchTracking,\n },\n };\n};\n\nexport interface NavigationRoute {\n name: string;\n key: string;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n params?: Record<string, any>;\n state?: NavigationState;\n}\n\ninterface NavigationState {\n index?: number;\n routes: NavigationRoute[];\n}\n\ninterface NavigationContainer {\n addListener: (type: string, listener: (event?: unknown) => void) => void;\n getCurrentRoute: () => NavigationRoute;\n getState: () => NavigationState | undefined;\n}\n\n/**\n * Returns React Navigation integration of the given client.\n */\nexport function getReactNavigationIntegration(\n client: Client,\n): ReturnType<typeof reactNavigationIntegration> | undefined {\n return client.getIntegrationByName<ReturnType<typeof reactNavigationIntegration>>(INTEGRATION_NAME);\n}\n"]}
@@ -1,4 +1,4 @@
1
- import type { MeasurementUnit, Span, SpanJSON, TransactionSource } from '@sentry/core';
1
+ import type { MeasurementUnit, Span, SpanJSON, StartSpanOptions, TransactionSource } from '@sentry/core';
2
2
  export declare const defaultTransactionSource: TransactionSource;
3
3
  export declare const customTransactionSource: TransactionSource;
4
4
  /**
@@ -42,6 +42,32 @@ export declare function getBundleStartTimestampMs(): number | undefined;
42
42
  * Creates valid span JSON object from the given data.
43
43
  */
44
44
  export declare function createSpanJSON(from: Partial<SpanJSON> & Pick<Required<SpanJSON>, 'description' | 'start_timestamp' | 'timestamp' | 'origin'>): SpanJSON;
45
+ /**
46
+ * Wraps a function call that returns a `Promise` with an inactive span that
47
+ * is automatically ended on success or failure (both sync throws and async
48
+ * rejections).
49
+ *
50
+ * This is the standard pattern for instrumenting async SDK operations such as
51
+ * `Image.loadAsync` and `Asset.loadAsync`.
52
+ *
53
+ * The span status is always set by this utility (`ok` on resolve, `error` on
54
+ * reject or sync throw). If you need custom status logic (e.g. inspecting the
55
+ * resolved value), handle span lifecycle manually instead.
56
+ *
57
+ * @param spanOptions Options forwarded to `startInactiveSpan`.
58
+ * @param fn The function to call.
59
+ * @returns Whatever `fn` returns (the original `Promise`).
60
+ */
61
+ export declare function traceAsyncOperation<T>(spanOptions: StartSpanOptions, fn: () => Promise<T>): Promise<T>;
62
+ /**
63
+ * Strips query string and fragment from a URL, preserving the scheme, host, and path.
64
+ */
65
+ export declare function sanitizeUrl(url: string): string;
66
+ /**
67
+ * Extracts a short, human-readable description from a URL by stripping
68
+ * the query string, fragment, and path — returning only the filename.
69
+ */
70
+ export declare function describeUrl(url: string): string;
45
71
  /**
46
72
  *
47
73
  */
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/js/tracing/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAgBvF,eAAO,MAAM,wBAAwB,EAAE,iBAA+B,CAAC;AACvE,eAAO,MAAM,uBAAuB,EAAE,iBAA4B,CAAC;AAEnE;;;GAGG;AACH,eAAO,MAAM,uBAAuB,OAAO,CAAC;AAI5C;;GAEG;AACH,wBAAgB,yBAAyB,IAAI,MAAM,CAElD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAKlE;AAED;;;GAGG;AACH,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,GAAG,IAAI,CAO3E;AAED;;;GAGG;AACH,wBAAgB,kCAAkC,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,GAAG,IAAI,CAO3F;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,GAAG,IAAI,CAKtG;AAED;;GAEG;AACH,wBAAgB,8BAA8B,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,GAAG,SAAS,CAM7E;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,IAAI,MAAM,GAAG,SAAS,CAe9D;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,aAAa,GAAG,iBAAiB,GAAG,WAAW,GAAG,QAAQ,CAAC,GAC7G,QAAQ,CAYV;AAID;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,QAAQ,EAChB,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,aAAa,GAAG,iBAAiB,GAAG,WAAW,CAAC,GAClG,QAAQ,CAQV"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/js/tracing/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,QAAQ,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAmBzG,eAAO,MAAM,wBAAwB,EAAE,iBAA+B,CAAC;AACvE,eAAO,MAAM,uBAAuB,EAAE,iBAA4B,CAAC;AAEnE;;;GAGG;AACH,eAAO,MAAM,uBAAuB,OAAO,CAAC;AAI5C;;GAEG;AACH,wBAAgB,yBAAyB,IAAI,MAAM,CAElD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAKlE;AAED;;;GAGG;AACH,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,GAAG,IAAI,CAO3E;AAED;;;GAGG;AACH,wBAAgB,kCAAkC,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,GAAG,IAAI,CAO3F;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,GAAG,IAAI,CAKtG;AAED;;GAEG;AACH,wBAAgB,8BAA8B,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,GAAG,SAAS,CAM7E;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,IAAI,MAAM,GAAG,SAAS,CAe9D;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,aAAa,GAAG,iBAAiB,GAAG,WAAW,GAAG,QAAQ,CAAC,GAC7G,QAAQ,CAYV;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,WAAW,EAAE,gBAAgB,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAoBtG;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAO/C;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAU/C;AAID;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,QAAQ,EAChB,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,aAAa,GAAG,iBAAiB,GAAG,WAAW,CAAC,GAClG,QAAQ,CAQV"}
@@ -1,4 +1,4 @@
1
- import { debug, dropUndefinedKeys, getSpanDescendants, SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_UNIT, SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_VALUE, SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, setMeasurement, spanToJSON, timestampInSeconds, uuid4, } from '@sentry/core';
1
+ import { debug, dropUndefinedKeys, getSpanDescendants, SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_UNIT, SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_VALUE, SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, setMeasurement, SPAN_STATUS_ERROR, SPAN_STATUS_OK, spanToJSON, startInactiveSpan, timestampInSeconds, uuid4, } from '@sentry/core';
2
2
  import { RN_GLOBAL_OBJ } from '../utils/worldwide';
3
3
  export const defaultTransactionSource = 'component';
4
4
  export const customTransactionSource = 'custom';
@@ -88,6 +88,71 @@ export function getBundleStartTimestampMs() {
88
88
  export function createSpanJSON(from) {
89
89
  return dropUndefinedKeys(Object.assign(Object.assign({ status: 'ok' }, from), { span_id: from.span_id ? from.span_id : uuid4().substring(16), trace_id: from.trace_id ? from.trace_id : uuid4(), data: dropUndefinedKeys(Object.assign({ [SEMANTIC_ATTRIBUTE_SENTRY_OP]: from.op, [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: from.origin }, (from.data ? from.data : {}))) }));
90
90
  }
91
+ /**
92
+ * Wraps a function call that returns a `Promise` with an inactive span that
93
+ * is automatically ended on success or failure (both sync throws and async
94
+ * rejections).
95
+ *
96
+ * This is the standard pattern for instrumenting async SDK operations such as
97
+ * `Image.loadAsync` and `Asset.loadAsync`.
98
+ *
99
+ * The span status is always set by this utility (`ok` on resolve, `error` on
100
+ * reject or sync throw). If you need custom status logic (e.g. inspecting the
101
+ * resolved value), handle span lifecycle manually instead.
102
+ *
103
+ * @param spanOptions Options forwarded to `startInactiveSpan`.
104
+ * @param fn The function to call.
105
+ * @returns Whatever `fn` returns (the original `Promise`).
106
+ */
107
+ export function traceAsyncOperation(spanOptions, fn) {
108
+ const span = startInactiveSpan(spanOptions);
109
+ try {
110
+ return fn()
111
+ .then(result => {
112
+ span === null || span === void 0 ? void 0 : span.setStatus({ code: SPAN_STATUS_OK });
113
+ span === null || span === void 0 ? void 0 : span.end();
114
+ return result;
115
+ })
116
+ .catch((error) => {
117
+ span === null || span === void 0 ? void 0 : span.setStatus({ code: SPAN_STATUS_ERROR, message: String(error) });
118
+ span === null || span === void 0 ? void 0 : span.end();
119
+ throw error;
120
+ });
121
+ }
122
+ catch (error) {
123
+ span === null || span === void 0 ? void 0 : span.setStatus({ code: SPAN_STATUS_ERROR, message: String(error) });
124
+ span === null || span === void 0 ? void 0 : span.end();
125
+ throw error;
126
+ }
127
+ }
128
+ /**
129
+ * Strips query string and fragment from a URL, preserving the scheme, host, and path.
130
+ */
131
+ export function sanitizeUrl(url) {
132
+ try {
133
+ const withoutQuery = url.split('?')[0] || url;
134
+ return withoutQuery.split('#')[0] || withoutQuery;
135
+ }
136
+ catch (_a) {
137
+ return url;
138
+ }
139
+ }
140
+ /**
141
+ * Extracts a short, human-readable description from a URL by stripping
142
+ * the query string, fragment, and path — returning only the filename.
143
+ */
144
+ export function describeUrl(url) {
145
+ try {
146
+ // Remove query string and fragment
147
+ const withoutQuery = url.split('?')[0] || url;
148
+ const withoutFragment = withoutQuery.split('#')[0] || withoutQuery;
149
+ const filename = withoutFragment.split('/').pop();
150
+ return filename || withoutFragment;
151
+ }
152
+ catch (_a) {
153
+ return url;
154
+ }
155
+ }
91
156
  const SENTRY_DEFAULT_ORIGIN = 'manual';
92
157
  /**
93
158
  *
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/js/tracing/utils.ts"],"names":[],"mappings":"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","sourcesContent":["import type { MeasurementUnit, Span, SpanJSON, TransactionSource } from '@sentry/core';\nimport {\n debug,\n dropUndefinedKeys,\n getSpanDescendants,\n SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_UNIT,\n SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_VALUE,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n setMeasurement,\n spanToJSON,\n timestampInSeconds,\n uuid4,\n} from '@sentry/core';\nimport { RN_GLOBAL_OBJ } from '../utils/worldwide';\n\nexport const defaultTransactionSource: TransactionSource = 'component';\nexport const customTransactionSource: TransactionSource = 'custom';\n\n/**\n * A margin of error of 50ms is allowed for the async native bridge call.\n * Anything larger would reduce the accuracy of our frames measurements.\n */\nexport const MARGIN_OF_ERROR_SECONDS = 0.05;\n\nconst timeOriginMilliseconds = Date.now();\n\n/**\n * Returns the timestamp where the JS global scope was initialized.\n */\nexport function getTimeOriginMilliseconds(): number {\n return timeOriginMilliseconds;\n}\n\n/**\n * Determines if the timestamp is now or within the specified margin of error from now.\n */\nexport function isNearToNow(timestamp: number | undefined): boolean {\n if (!timestamp) {\n return false;\n }\n return Math.abs(timestampInSeconds() - timestamp) <= MARGIN_OF_ERROR_SECONDS;\n}\n\n/**\n * Sets the duration of the span as a measurement.\n * Uses `setMeasurement` function from @sentry/core.\n */\nexport function setSpanDurationAsMeasurement(name: string, span: Span): void {\n const { timestamp: spanEnd, start_timestamp: spanStart } = spanToJSON(span);\n if (!spanEnd || !spanStart) {\n return;\n }\n\n setMeasurement(name, (spanEnd - spanStart) * 1000, 'millisecond');\n}\n\n/**\n * Sets the duration of the span as a measurement.\n * Uses `setMeasurement` function from @sentry/core.\n */\nexport function setSpanDurationAsMeasurementOnSpan(name: string, span: Span, on: Span): void {\n const { timestamp: spanEnd, start_timestamp: spanStart } = spanToJSON(span);\n if (!spanEnd || !spanStart) {\n return;\n }\n\n setSpanMeasurement(on, name, (spanEnd - spanStart) * 1000, 'millisecond');\n}\n\n/**\n * Sets measurement on the give span.\n */\nexport function setSpanMeasurement(span: Span, key: string, value: number, unit: MeasurementUnit): void {\n span.addEvent(key, {\n [SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_VALUE]: value,\n [SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_UNIT]: unit as string,\n });\n}\n\n/**\n * Returns the latest end timestamp of the child spans of the given span.\n */\nexport function getLatestChildSpanEndTimestamp(span: Span): number | undefined {\n const childEndTimestamps = getSpanDescendants(span)\n .map(span => spanToJSON(span).timestamp)\n .filter(timestamp => !!timestamp) as number[];\n\n return childEndTimestamps.length ? Math.max(...childEndTimestamps) : undefined;\n}\n\n/**\n * Returns unix timestamp in ms of the bundle start time.\n *\n * If not available, returns undefined.\n */\nexport function getBundleStartTimestampMs(): number | undefined {\n const bundleStartTime = RN_GLOBAL_OBJ.__BUNDLE_START_TIME__;\n if (!bundleStartTime) {\n debug.warn('Missing the bundle start time on the global object.');\n return undefined;\n }\n\n if (!RN_GLOBAL_OBJ.nativePerformanceNow) {\n // bundleStartTime is Date.now() in milliseconds\n return bundleStartTime;\n }\n\n // nativePerformanceNow() is monotonic clock like performance.now()\n const approxStartingTimeOrigin = Date.now() - RN_GLOBAL_OBJ.nativePerformanceNow();\n return approxStartingTimeOrigin + bundleStartTime;\n}\n\n/**\n * Creates valid span JSON object from the given data.\n */\nexport function createSpanJSON(\n from: Partial<SpanJSON> & Pick<Required<SpanJSON>, 'description' | 'start_timestamp' | 'timestamp' | 'origin'>,\n): SpanJSON {\n return dropUndefinedKeys({\n status: 'ok',\n ...from,\n span_id: from.span_id ? from.span_id : uuid4().substring(16),\n trace_id: from.trace_id ? from.trace_id : uuid4(),\n data: dropUndefinedKeys({\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: from.op,\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: from.origin,\n ...(from.data ? from.data : {}),\n }),\n });\n}\n\nconst SENTRY_DEFAULT_ORIGIN = 'manual';\n\n/**\n *\n */\nexport function createChildSpanJSON(\n parent: SpanJSON,\n from: Partial<SpanJSON> & Pick<Required<SpanJSON>, 'description' | 'start_timestamp' | 'timestamp'>,\n): SpanJSON {\n return createSpanJSON({\n op: parent.op,\n trace_id: parent.trace_id,\n parent_span_id: parent.span_id,\n origin: parent.origin || SENTRY_DEFAULT_ORIGIN,\n ...from,\n });\n}\n"]}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/js/tracing/utils.ts"],"names":[],"mappings":"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","sourcesContent":["import type { MeasurementUnit, Span, SpanJSON, StartSpanOptions, TransactionSource } from '@sentry/core';\nimport {\n debug,\n dropUndefinedKeys,\n getSpanDescendants,\n SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_UNIT,\n SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_VALUE,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n setMeasurement,\n SPAN_STATUS_ERROR,\n SPAN_STATUS_OK,\n spanToJSON,\n startInactiveSpan,\n timestampInSeconds,\n uuid4,\n} from '@sentry/core';\nimport { RN_GLOBAL_OBJ } from '../utils/worldwide';\n\nexport const defaultTransactionSource: TransactionSource = 'component';\nexport const customTransactionSource: TransactionSource = 'custom';\n\n/**\n * A margin of error of 50ms is allowed for the async native bridge call.\n * Anything larger would reduce the accuracy of our frames measurements.\n */\nexport const MARGIN_OF_ERROR_SECONDS = 0.05;\n\nconst timeOriginMilliseconds = Date.now();\n\n/**\n * Returns the timestamp where the JS global scope was initialized.\n */\nexport function getTimeOriginMilliseconds(): number {\n return timeOriginMilliseconds;\n}\n\n/**\n * Determines if the timestamp is now or within the specified margin of error from now.\n */\nexport function isNearToNow(timestamp: number | undefined): boolean {\n if (!timestamp) {\n return false;\n }\n return Math.abs(timestampInSeconds() - timestamp) <= MARGIN_OF_ERROR_SECONDS;\n}\n\n/**\n * Sets the duration of the span as a measurement.\n * Uses `setMeasurement` function from @sentry/core.\n */\nexport function setSpanDurationAsMeasurement(name: string, span: Span): void {\n const { timestamp: spanEnd, start_timestamp: spanStart } = spanToJSON(span);\n if (!spanEnd || !spanStart) {\n return;\n }\n\n setMeasurement(name, (spanEnd - spanStart) * 1000, 'millisecond');\n}\n\n/**\n * Sets the duration of the span as a measurement.\n * Uses `setMeasurement` function from @sentry/core.\n */\nexport function setSpanDurationAsMeasurementOnSpan(name: string, span: Span, on: Span): void {\n const { timestamp: spanEnd, start_timestamp: spanStart } = spanToJSON(span);\n if (!spanEnd || !spanStart) {\n return;\n }\n\n setSpanMeasurement(on, name, (spanEnd - spanStart) * 1000, 'millisecond');\n}\n\n/**\n * Sets measurement on the give span.\n */\nexport function setSpanMeasurement(span: Span, key: string, value: number, unit: MeasurementUnit): void {\n span.addEvent(key, {\n [SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_VALUE]: value,\n [SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_UNIT]: unit as string,\n });\n}\n\n/**\n * Returns the latest end timestamp of the child spans of the given span.\n */\nexport function getLatestChildSpanEndTimestamp(span: Span): number | undefined {\n const childEndTimestamps = getSpanDescendants(span)\n .map(span => spanToJSON(span).timestamp)\n .filter(timestamp => !!timestamp) as number[];\n\n return childEndTimestamps.length ? Math.max(...childEndTimestamps) : undefined;\n}\n\n/**\n * Returns unix timestamp in ms of the bundle start time.\n *\n * If not available, returns undefined.\n */\nexport function getBundleStartTimestampMs(): number | undefined {\n const bundleStartTime = RN_GLOBAL_OBJ.__BUNDLE_START_TIME__;\n if (!bundleStartTime) {\n debug.warn('Missing the bundle start time on the global object.');\n return undefined;\n }\n\n if (!RN_GLOBAL_OBJ.nativePerformanceNow) {\n // bundleStartTime is Date.now() in milliseconds\n return bundleStartTime;\n }\n\n // nativePerformanceNow() is monotonic clock like performance.now()\n const approxStartingTimeOrigin = Date.now() - RN_GLOBAL_OBJ.nativePerformanceNow();\n return approxStartingTimeOrigin + bundleStartTime;\n}\n\n/**\n * Creates valid span JSON object from the given data.\n */\nexport function createSpanJSON(\n from: Partial<SpanJSON> & Pick<Required<SpanJSON>, 'description' | 'start_timestamp' | 'timestamp' | 'origin'>,\n): SpanJSON {\n return dropUndefinedKeys({\n status: 'ok',\n ...from,\n span_id: from.span_id ? from.span_id : uuid4().substring(16),\n trace_id: from.trace_id ? from.trace_id : uuid4(),\n data: dropUndefinedKeys({\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: from.op,\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: from.origin,\n ...(from.data ? from.data : {}),\n }),\n });\n}\n\n/**\n * Wraps a function call that returns a `Promise` with an inactive span that\n * is automatically ended on success or failure (both sync throws and async\n * rejections).\n *\n * This is the standard pattern for instrumenting async SDK operations such as\n * `Image.loadAsync` and `Asset.loadAsync`.\n *\n * The span status is always set by this utility (`ok` on resolve, `error` on\n * reject or sync throw). If you need custom status logic (e.g. inspecting the\n * resolved value), handle span lifecycle manually instead.\n *\n * @param spanOptions Options forwarded to `startInactiveSpan`.\n * @param fn The function to call.\n * @returns Whatever `fn` returns (the original `Promise`).\n */\nexport function traceAsyncOperation<T>(spanOptions: StartSpanOptions, fn: () => Promise<T>): Promise<T> {\n const span = startInactiveSpan(spanOptions);\n\n try {\n return fn()\n .then(result => {\n span?.setStatus({ code: SPAN_STATUS_OK });\n span?.end();\n return result;\n })\n .catch((error: unknown) => {\n span?.setStatus({ code: SPAN_STATUS_ERROR, message: String(error) });\n span?.end();\n throw error;\n });\n } catch (error) {\n span?.setStatus({ code: SPAN_STATUS_ERROR, message: String(error) });\n span?.end();\n throw error;\n }\n}\n\n/**\n * Strips query string and fragment from a URL, preserving the scheme, host, and path.\n */\nexport function sanitizeUrl(url: string): string {\n try {\n const withoutQuery = url.split('?')[0] || url;\n return withoutQuery.split('#')[0] || withoutQuery;\n } catch {\n return url;\n }\n}\n\n/**\n * Extracts a short, human-readable description from a URL by stripping\n * the query string, fragment, and path — returning only the filename.\n */\nexport function describeUrl(url: string): string {\n try {\n // Remove query string and fragment\n const withoutQuery = url.split('?')[0] || url;\n const withoutFragment = withoutQuery.split('#')[0] || withoutQuery;\n const filename = withoutFragment.split('/').pop();\n return filename || withoutFragment;\n } catch {\n return url;\n }\n}\n\nconst SENTRY_DEFAULT_ORIGIN = 'manual';\n\n/**\n *\n */\nexport function createChildSpanJSON(\n parent: SpanJSON,\n from: Partial<SpanJSON> & Pick<Required<SpanJSON>, 'description' | 'start_timestamp' | 'timestamp'>,\n): SpanJSON {\n return createSpanJSON({\n op: parent.op,\n trace_id: parent.trace_id,\n parent_span_id: parent.span_id,\n origin: parent.origin || SENTRY_DEFAULT_ORIGIN,\n ...from,\n });\n}\n"]}
@@ -3,7 +3,7 @@ import { LogBox } from 'react-native';
3
3
  * This is a workaround for using fetch on RN, this is a known issue in react-native and only generates a warning.
4
4
  */
5
5
  export function ignoreRequireCycleLogs(version) {
6
- if (version && version.major === 0 && version.minor < 70) {
6
+ if ((version === null || version === void 0 ? void 0 : version.major) === 0 && version.minor < 70) {
7
7
  // Do not ignore require cycle logs on React Native versions >= 0.70
8
8
  // https://github.com/getsentry/sentry-react-native/issues/3484#issuecomment-1877034820
9
9
  LogBox.ignoreLogs(['Require cycle:']);
@@ -1 +1 @@
1
- {"version":3,"file":"ignorerequirecyclelogs.js","sourceRoot":"","sources":["../../../src/js/utils/ignorerequirecyclelogs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAOtC;;GAEG;AACH,MAAM,UAAU,sBAAsB,CAAC,OAA4B;IACjE,IAAI,OAAO,IAAI,OAAO,CAAC,KAAK,KAAK,CAAC,IAAI,OAAO,CAAC,KAAK,GAAG,EAAE,EAAE;QACxD,oEAAoE;QACpE,uFAAuF;QACvF,MAAM,CAAC,UAAU,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC;KACvC;AACH,CAAC","sourcesContent":["import { LogBox } from 'react-native';\n\ninterface ReactNativeVersion {\n major: number;\n minor: number;\n}\n\n/**\n * This is a workaround for using fetch on RN, this is a known issue in react-native and only generates a warning.\n */\nexport function ignoreRequireCycleLogs(version?: ReactNativeVersion): void {\n if (version && version.major === 0 && version.minor < 70) {\n // Do not ignore require cycle logs on React Native versions >= 0.70\n // https://github.com/getsentry/sentry-react-native/issues/3484#issuecomment-1877034820\n LogBox.ignoreLogs(['Require cycle:']);\n }\n}\n"]}
1
+ {"version":3,"file":"ignorerequirecyclelogs.js","sourceRoot":"","sources":["../../../src/js/utils/ignorerequirecyclelogs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAOtC;;GAEG;AACH,MAAM,UAAU,sBAAsB,CAAC,OAA4B;IACjE,IAAI,CAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,KAAK,MAAK,CAAC,IAAI,OAAO,CAAC,KAAK,GAAG,EAAE,EAAE;QAC9C,oEAAoE;QACpE,uFAAuF;QACvF,MAAM,CAAC,UAAU,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC;KACvC;AACH,CAAC","sourcesContent":["import { LogBox } from 'react-native';\n\ninterface ReactNativeVersion {\n major: number;\n minor: number;\n}\n\n/**\n * This is a workaround for using fetch on RN, this is a known issue in react-native and only generates a warning.\n */\nexport function ignoreRequireCycleLogs(version?: ReactNativeVersion): void {\n if (version?.major === 0 && version.minor < 70) {\n // Do not ignore require cycle logs on React Native versions >= 0.70\n // https://github.com/getsentry/sentry-react-native/issues/3484#issuecomment-1877034820\n LogBox.ignoreLogs(['Require cycle:']);\n }\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  import type { ReactNativeOptions } from '../options';
2
- type DangerTypesWithoutCallSignature = Object | null | undefined;
2
+ type DangerTypesWithoutCallSignature = object | null | undefined;
3
3
  /**
4
4
  * Returns callback factory wrapped with try/catch
5
5
  * or the original passed value is it's not a function.
@@ -1 +1 @@
1
- {"version":3,"file":"safe.d.ts","sourceRoot":"","sources":["../../../src/js/utils/safe.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAErD,KAAK,+BAA+B,GAElC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;AAE5B;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,+BAA+B,EACnG,MAAM,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,EAC/B,OAAO,GAAE;IACP,aAAa,CAAC,EAAE,MAAM,CAAC;CACnB,GACL,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAgBzB;AAID;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,aAAa,EAAE,kBAAkB,CAAC,eAAe,CAAC,GACjD,kBAAkB,CAAC,eAAe,CAAC,CAarC"}
1
+ {"version":3,"file":"safe.d.ts","sourceRoot":"","sources":["../../../src/js/utils/safe.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAErD,KAAK,+BAA+B,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;AAEjE;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,+BAA+B,EACnG,MAAM,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,EAC/B,OAAO,GAAE;IACP,aAAa,CAAC,EAAE,MAAM,CAAC;CACnB,GACL,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAgBzB;AAID;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,aAAa,EAAE,kBAAkB,CAAC,eAAe,CAAC,GACjD,kBAAkB,CAAC,eAAe,CAAC,CAarC"}
@@ -1 +1 @@
1
- {"version":3,"file":"safe.js","sourceRoot":"","sources":["../../../src/js/utils/safe.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAOrC;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CACzB,MAA+B,EAC/B,UAEI,EAAE;IAEN,IAAI,OAAO,MAAM,KAAK,UAAU,EAAE;QAChC,OAAO,CAAC,GAAG,IAAI,EAAE,EAAE;YACjB,IAAI;gBACF,OAAO,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC;aACxB;YAAC,OAAO,KAAK,EAAE;gBACd,KAAK,CAAC,KAAK,CACT,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,OAAO,MAAM,CAAC,IAAI,0BAA0B,EAC5F,KAAK,CACN,CAAC;gBACF,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC;aAChB;QACH,CAAC,CAAC;KACH;SAAM;QACL,OAAO,MAAM,CAAC;KACf;AACH,CAAC;AAID;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAC/B,aAAkD;IAElD,IAAI,aAAa,EAAE;QACjB,OAAO,CAAC,GAAG,IAA+B,EAA6B,EAAE;YACvE,IAAI;gBACF,OAAO,aAAa,CAAC,GAAG,IAAI,CAAC,CAAC;aAC/B;YAAC,OAAO,KAAK,EAAE;gBACd,KAAK,CAAC,KAAK,CAAC,2CAA2C,EAAE,KAAK,CAAC,CAAC;gBAChE,OAAO,CAAC,CAAC;aACV;QACH,CAAC,CAAC;KACH;SAAM;QACL,OAAO,aAAa,CAAC;KACtB;AACH,CAAC","sourcesContent":["import { debug } from '@sentry/core';\nimport type { ReactNativeOptions } from '../options';\n\ntype DangerTypesWithoutCallSignature =\n // eslint-disable-next-line @typescript-eslint/ban-types\n Object | null | undefined;\n\n/**\n * Returns callback factory wrapped with try/catch\n * or the original passed value is it's not a function.\n *\n * If the factory fails original data are returned as it.\n * They might be partially modified by the failed function.\n */\nexport function safeFactory<A extends [R, ...unknown[]], R, T extends DangerTypesWithoutCallSignature>(\n danger: ((...args: A) => R) | T,\n options: {\n loggerMessage?: string;\n } = {},\n): ((...args: A) => R) | T {\n if (typeof danger === 'function') {\n return (...args) => {\n try {\n return danger(...args);\n } catch (error) {\n debug.error(\n options.loggerMessage ? options.loggerMessage : `The ${danger.name} callback threw an error`,\n error,\n );\n return args[0];\n }\n };\n } else {\n return danger;\n }\n}\n\ntype TracesSampler = Required<ReactNativeOptions>['tracesSampler'];\n\n/**\n * Returns sage tracesSampler that returns 0 if the original failed.\n */\nexport function safeTracesSampler(\n tracesSampler: ReactNativeOptions['tracesSampler'],\n): ReactNativeOptions['tracesSampler'] {\n if (tracesSampler) {\n return (...args: Parameters<TracesSampler>): ReturnType<TracesSampler> => {\n try {\n return tracesSampler(...args);\n } catch (error) {\n debug.error('The tracesSampler callback threw an error', error);\n return 0;\n }\n };\n } else {\n return tracesSampler;\n }\n}\n"]}
1
+ {"version":3,"file":"safe.js","sourceRoot":"","sources":["../../../src/js/utils/safe.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAKrC;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CACzB,MAA+B,EAC/B,UAEI,EAAE;IAEN,IAAI,OAAO,MAAM,KAAK,UAAU,EAAE;QAChC,OAAO,CAAC,GAAG,IAAI,EAAE,EAAE;YACjB,IAAI;gBACF,OAAO,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC;aACxB;YAAC,OAAO,KAAK,EAAE;gBACd,KAAK,CAAC,KAAK,CACT,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,OAAO,MAAM,CAAC,IAAI,0BAA0B,EAC5F,KAAK,CACN,CAAC;gBACF,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC;aAChB;QACH,CAAC,CAAC;KACH;SAAM;QACL,OAAO,MAAM,CAAC;KACf;AACH,CAAC;AAID;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAC/B,aAAkD;IAElD,IAAI,aAAa,EAAE;QACjB,OAAO,CAAC,GAAG,IAA+B,EAA6B,EAAE;YACvE,IAAI;gBACF,OAAO,aAAa,CAAC,GAAG,IAAI,CAAC,CAAC;aAC/B;YAAC,OAAO,KAAK,EAAE;gBACd,KAAK,CAAC,KAAK,CAAC,2CAA2C,EAAE,KAAK,CAAC,CAAC;gBAChE,OAAO,CAAC,CAAC;aACV;QACH,CAAC,CAAC;KACH;SAAM;QACL,OAAO,aAAa,CAAC;KACtB;AACH,CAAC","sourcesContent":["import { debug } from '@sentry/core';\nimport type { ReactNativeOptions } from '../options';\n\ntype DangerTypesWithoutCallSignature = object | null | undefined;\n\n/**\n * Returns callback factory wrapped with try/catch\n * or the original passed value is it's not a function.\n *\n * If the factory fails original data are returned as it.\n * They might be partially modified by the failed function.\n */\nexport function safeFactory<A extends [R, ...unknown[]], R, T extends DangerTypesWithoutCallSignature>(\n danger: ((...args: A) => R) | T,\n options: {\n loggerMessage?: string;\n } = {},\n): ((...args: A) => R) | T {\n if (typeof danger === 'function') {\n return (...args) => {\n try {\n return danger(...args);\n } catch (error) {\n debug.error(\n options.loggerMessage ? options.loggerMessage : `The ${danger.name} callback threw an error`,\n error,\n );\n return args[0];\n }\n };\n } else {\n return danger;\n }\n}\n\ntype TracesSampler = Required<ReactNativeOptions>['tracesSampler'];\n\n/**\n * Returns sage tracesSampler that returns 0 if the original failed.\n */\nexport function safeTracesSampler(\n tracesSampler: ReactNativeOptions['tracesSampler'],\n): ReactNativeOptions['tracesSampler'] {\n if (tracesSampler) {\n return (...args: Parameters<TracesSampler>): ReturnType<TracesSampler> => {\n try {\n return tracesSampler(...args);\n } catch (error) {\n debug.error('The tracesSampler callback threw an error', error);\n return 0;\n }\n };\n } else {\n return tracesSampler;\n }\n}\n"]}
@@ -1,4 +1,4 @@
1
1
  export declare const SDK_PACKAGE_NAME = "npm:@sentry/react-native";
2
2
  export declare const SDK_NAME = "sentry.javascript.react-native";
3
- export declare const SDK_VERSION = "8.3.0";
3
+ export declare const SDK_VERSION = "8.5.0";
4
4
  //# sourceMappingURL=version.d.ts.map
@@ -3,5 +3,5 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SDK_VERSION = exports.SDK_NAME = exports.SDK_PACKAGE_NAME = void 0;
4
4
  exports.SDK_PACKAGE_NAME = 'npm:@sentry/react-native';
5
5
  exports.SDK_NAME = 'sentry.javascript.react-native';
6
- exports.SDK_VERSION = '8.3.0';
6
+ exports.SDK_VERSION = '8.5.0';
7
7
  //# sourceMappingURL=version.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/js/version.ts"],"names":[],"mappings":";;;AAAa,QAAA,gBAAgB,GAAG,0BAA0B,CAAC;AAC9C,QAAA,QAAQ,GAAG,gCAAgC,CAAC;AAC5C,QAAA,WAAW,GAAG,OAAO,CAAC","sourcesContent":["export const SDK_PACKAGE_NAME = 'npm:@sentry/react-native';\nexport const SDK_NAME = 'sentry.javascript.react-native';\nexport const SDK_VERSION = '8.3.0';\n"]}
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/js/version.ts"],"names":[],"mappings":";;;AAAa,QAAA,gBAAgB,GAAG,0BAA0B,CAAC;AAC9C,QAAA,QAAQ,GAAG,gCAAgC,CAAC;AAC5C,QAAA,WAAW,GAAG,OAAO,CAAC","sourcesContent":["export const SDK_PACKAGE_NAME = 'npm:@sentry/react-native';\nexport const SDK_NAME = 'sentry.javascript.react-native';\nexport const SDK_VERSION = '8.5.0';\n"]}
package/ios/RNSentry.mm CHANGED
@@ -60,6 +60,7 @@ static bool hasFetchedAppStart;
60
60
 
61
61
  @implementation RNSentry {
62
62
  bool hasListeners;
63
+ bool _shakeDetectionEnabled;
63
64
  RNSentryTimeToDisplay *_timeToDisplay;
64
65
  NSArray<NSString *> *_ignoreErrorPatternsStr;
65
66
  NSArray<NSRegularExpression *> *_ignoreErrorPatternsRegex;
@@ -295,9 +296,54 @@ RCT_EXPORT_METHOD(initNativeReactNavigationNewFrameTracking : (
295
296
  [[RNSentryNativeLogsForwarder shared] stopForwarding];
296
297
  }
297
298
 
299
+ - (void)handleShakeDetected
300
+ {
301
+ if (_shakeDetectionEnabled) {
302
+ [self sendEventWithName:RNSentryOnShakeEvent body:@{}];
303
+ }
304
+ }
305
+
306
+ // SentryShakeDetector is a Swift class; its notification name and methods are accessed
307
+ // via the raw string / NSClassFromString to avoid requiring @import Sentry in this .mm file.
308
+ static NSNotificationName const RNSentryShakeNotification = @"SentryShakeDetected";
309
+
310
+ RCT_EXPORT_METHOD(enableShakeDetection)
311
+ {
312
+ [[NSNotificationCenter defaultCenter] removeObserver:self
313
+ name:RNSentryShakeNotification
314
+ object:nil];
315
+ [[NSNotificationCenter defaultCenter] addObserver:self
316
+ selector:@selector(handleShakeDetected)
317
+ name:RNSentryShakeNotification
318
+ object:nil];
319
+ Class shakeDetector = NSClassFromString(@"SentryShakeDetector");
320
+ if (shakeDetector) {
321
+ #pragma clang diagnostic push
322
+ #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
323
+ [shakeDetector performSelector:@selector(enable)];
324
+ #pragma clang diagnostic pop
325
+ }
326
+ _shakeDetectionEnabled = YES;
327
+ }
328
+
329
+ RCT_EXPORT_METHOD(disableShakeDetection)
330
+ {
331
+ _shakeDetectionEnabled = NO;
332
+ Class shakeDetector = NSClassFromString(@"SentryShakeDetector");
333
+ if (shakeDetector) {
334
+ #pragma clang diagnostic push
335
+ #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
336
+ [shakeDetector performSelector:@selector(disable)];
337
+ #pragma clang diagnostic pop
338
+ }
339
+ [[NSNotificationCenter defaultCenter] removeObserver:self
340
+ name:RNSentryShakeNotification
341
+ object:nil];
342
+ }
343
+
298
344
  - (NSArray<NSString *> *)supportedEvents
299
345
  {
300
- return @[ RNSentryNewFrameEvent, RNSentryNativeLogEvent ];
346
+ return @[ RNSentryNewFrameEvent, RNSentryNativeLogEvent, RNSentryOnShakeEvent ];
301
347
  }
302
348
 
303
349
  RCT_EXPORT_METHOD(
@@ -1,4 +1,5 @@
1
1
  #import <Foundation/Foundation.h>
2
2
 
3
3
  extern NSString *const RNSentryNewFrameEvent;
4
+ extern NSString *const RNSentryOnShakeEvent;
4
5
  extern NSString *const RNSentryNativeLogEvent;
@@ -1,4 +1,5 @@
1
1
  #import "RNSentryEvents.h"
2
2
 
3
3
  NSString *const RNSentryNewFrameEvent = @"rn_sentry_new_frame";
4
+ NSString *const RNSentryOnShakeEvent = @"rn_sentry_on_shake";
4
5
  NSString *const RNSentryNativeLogEvent = @"SentryNativeLog";
@@ -3,4 +3,4 @@
3
3
  NSString *const NATIVE_SDK_NAME = @"sentry.cocoa.react-native";
4
4
  NSString *const REACT_NATIVE_SDK_NAME = @"sentry.javascript.react-native";
5
5
  NSString *const REACT_NATIVE_SDK_PACKAGE_NAME = @"npm:@sentry/react-native";
6
- NSString *const REACT_NATIVE_SDK_PACKAGE_VERSION = @"8.3.0";
6
+ NSString *const REACT_NATIVE_SDK_PACKAGE_VERSION = @"8.5.0";