@sentry/react-native 8.4.0 → 8.6.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 (266) hide show
  1. package/RNSentry.podspec +1 -1
  2. package/android/build.gradle +2 -2
  3. package/android/expo-handler/build.gradle +20 -0
  4. package/android/expo-handler/src/main/java/io/sentry/react/expo/SentryExpoPackage.java +22 -0
  5. package/android/expo-handler/src/main/java/io/sentry/react/expo/SentryReactNativeHostHandler.java +48 -0
  6. package/android/expo-stubs/README.md +7 -0
  7. package/android/expo-stubs/build.gradle +23 -0
  8. package/android/expo-stubs/gradle/wrapper/gradle-wrapper.jar +0 -0
  9. package/android/expo-stubs/gradle/wrapper/gradle-wrapper.properties +7 -0
  10. package/android/expo-stubs/gradlew +251 -0
  11. package/android/expo-stubs/gradlew.bat +94 -0
  12. package/android/expo-stubs/settings.gradle +1 -0
  13. package/android/expo-stubs/src/main/java/expo/modules/core/interfaces/Package.java +11 -0
  14. package/android/expo-stubs/src/main/java/expo/modules/core/interfaces/ReactNativeHostHandler.java +7 -0
  15. package/android/libs/expo-stubs.jar +0 -0
  16. package/android/libs/replay-stubs.jar +0 -0
  17. package/android/replay-stubs/build.gradle +1 -1
  18. package/android/src/main/java/io/sentry/react/RNSentryModuleImpl.java +71 -15
  19. package/android/src/main/java/io/sentry/react/RNSentryStart.java +3 -0
  20. package/android/src/main/java/io/sentry/react/RNSentryVersion.java +1 -1
  21. package/android/src/newarch/java/io/sentry/react/RNSentryModule.java +10 -0
  22. package/android/src/oldarch/java/io/sentry/react/RNSentryModule.java +10 -0
  23. package/dist/js/NativeLogListener.js.map +1 -1
  24. package/dist/js/NativeRNSentry.d.ts +2 -0
  25. package/dist/js/NativeRNSentry.d.ts.map +1 -1
  26. package/dist/js/NativeRNSentry.js.map +1 -1
  27. package/dist/js/RNSentryReplayMaskNativeComponent.d.ts.map +1 -1
  28. package/dist/js/RNSentryReplayUnmaskNativeComponent.d.ts.map +1 -1
  29. package/dist/js/breadcrumb.js.map +1 -1
  30. package/dist/js/client.js.map +1 -1
  31. package/dist/js/feedback/FeedbackButton.js.map +1 -1
  32. package/dist/js/feedback/FeedbackWidget.js +6 -6
  33. package/dist/js/feedback/FeedbackWidget.js.map +1 -1
  34. package/dist/js/feedback/FeedbackWidget.styles.d.ts.map +1 -1
  35. package/dist/js/feedback/FeedbackWidgetManager.d.ts +3 -1
  36. package/dist/js/feedback/FeedbackWidgetManager.d.ts.map +1 -1
  37. package/dist/js/feedback/FeedbackWidgetManager.js +15 -1
  38. package/dist/js/feedback/FeedbackWidgetManager.js.map +1 -1
  39. package/dist/js/feedback/FeedbackWidgetProvider.d.ts +3 -2
  40. package/dist/js/feedback/FeedbackWidgetProvider.d.ts.map +1 -1
  41. package/dist/js/feedback/FeedbackWidgetProvider.js +12 -4
  42. package/dist/js/feedback/FeedbackWidgetProvider.js.map +1 -1
  43. package/dist/js/feedback/ScreenshotButton.d.ts +1 -1
  44. package/dist/js/feedback/ScreenshotButton.js.map +1 -1
  45. package/dist/js/feedback/ShakeToReportBug.d.ts +27 -0
  46. package/dist/js/feedback/ShakeToReportBug.d.ts.map +1 -0
  47. package/dist/js/feedback/ShakeToReportBug.js +83 -0
  48. package/dist/js/feedback/ShakeToReportBug.js.map +1 -0
  49. package/dist/js/feedback/defaults.js.map +1 -1
  50. package/dist/js/feedback/integration.d.ts +13 -2
  51. package/dist/js/feedback/integration.d.ts.map +1 -1
  52. package/dist/js/feedback/integration.js +7 -1
  53. package/dist/js/feedback/integration.js.map +1 -1
  54. package/dist/js/feedback/lazy.js.map +1 -1
  55. package/dist/js/feedback/utils.d.ts.map +1 -1
  56. package/dist/js/feedback/utils.js.map +1 -1
  57. package/dist/js/index.d.ts +1 -1
  58. package/dist/js/index.d.ts.map +1 -1
  59. package/dist/js/index.js +1 -1
  60. package/dist/js/index.js.map +1 -1
  61. package/dist/js/integrations/appRegistry.d.ts.map +1 -1
  62. package/dist/js/integrations/appRegistry.js.map +1 -1
  63. package/dist/js/integrations/breadcrumbs.d.ts.map +1 -1
  64. package/dist/js/integrations/debugsymbolicator.js +6 -4
  65. package/dist/js/integrations/debugsymbolicator.js.map +1 -1
  66. package/dist/js/integrations/debugsymbolicatorutils.js.map +1 -1
  67. package/dist/js/integrations/default.d.ts.map +1 -1
  68. package/dist/js/integrations/default.js +3 -2
  69. package/dist/js/integrations/default.js.map +1 -1
  70. package/dist/js/integrations/devicecontext.js +1 -1
  71. package/dist/js/integrations/devicecontext.js.map +1 -1
  72. package/dist/js/integrations/expoconstants.js.map +1 -1
  73. package/dist/js/integrations/expocontext.js.map +1 -1
  74. package/dist/js/integrations/exports.d.ts +1 -0
  75. package/dist/js/integrations/exports.d.ts.map +1 -1
  76. package/dist/js/integrations/exports.js +1 -0
  77. package/dist/js/integrations/exports.js.map +1 -1
  78. package/dist/js/integrations/expoupdateslistener.d.ts +38 -0
  79. package/dist/js/integrations/expoupdateslistener.d.ts.map +1 -0
  80. package/dist/js/integrations/expoupdateslistener.js +130 -0
  81. package/dist/js/integrations/expoupdateslistener.js.map +1 -0
  82. package/dist/js/integrations/logEnricherIntegration.js +1 -1
  83. package/dist/js/integrations/logEnricherIntegration.js.map +1 -1
  84. package/dist/js/integrations/modulesloader.js.map +1 -1
  85. package/dist/js/integrations/nativelinkederrors.d.ts.map +1 -1
  86. package/dist/js/integrations/nativelinkederrors.js +1 -0
  87. package/dist/js/integrations/nativelinkederrors.js.map +1 -1
  88. package/dist/js/integrations/primitiveTagIntegration.js.map +1 -1
  89. package/dist/js/integrations/reactnativeerrorhandlers.d.ts.map +1 -1
  90. package/dist/js/integrations/reactnativeerrorhandlers.js.map +1 -1
  91. package/dist/js/integrations/reactnativeerrorhandlersutils.js.map +1 -1
  92. package/dist/js/integrations/reactnativeinfo.js.map +1 -1
  93. package/dist/js/integrations/release.js +1 -1
  94. package/dist/js/integrations/release.js.map +1 -1
  95. package/dist/js/integrations/rewriteframes.js.map +1 -1
  96. package/dist/js/integrations/screenshot.js +1 -1
  97. package/dist/js/integrations/screenshot.js.map +1 -1
  98. package/dist/js/integrations/sdkinfo.js.map +1 -1
  99. package/dist/js/integrations/spotlight.js.map +1 -1
  100. package/dist/js/integrations/viewhierarchy.js +1 -1
  101. package/dist/js/integrations/viewhierarchy.js.map +1 -1
  102. package/dist/js/misc.js +2 -2
  103. package/dist/js/misc.js.map +1 -1
  104. package/dist/js/options.d.ts +13 -1
  105. package/dist/js/options.d.ts.map +1 -1
  106. package/dist/js/options.js.map +1 -1
  107. package/dist/js/playground/examples.js.map +1 -1
  108. package/dist/js/playground/modal.d.ts +2 -2
  109. package/dist/js/playground/modal.d.ts.map +1 -1
  110. package/dist/js/playground/modal.js +6 -6
  111. package/dist/js/playground/modal.js.map +1 -1
  112. package/dist/js/profiling/cache.js.map +1 -1
  113. package/dist/js/profiling/convertHermesProfile.js.map +1 -1
  114. package/dist/js/profiling/debugid.js.map +1 -1
  115. package/dist/js/profiling/integration.d.ts.map +1 -1
  116. package/dist/js/profiling/integration.js.map +1 -1
  117. package/dist/js/profiling/utils.js.map +1 -1
  118. package/dist/js/replay/CustomMask.d.ts.map +1 -1
  119. package/dist/js/replay/CustomMask.js.map +1 -1
  120. package/dist/js/replay/CustomMask.web.d.ts.map +1 -1
  121. package/dist/js/replay/browserReplay.d.ts.map +1 -1
  122. package/dist/js/replay/browserReplay.js.map +1 -1
  123. package/dist/js/replay/mobilereplay.d.ts.map +1 -1
  124. package/dist/js/replay/mobilereplay.js +21 -2
  125. package/dist/js/replay/mobilereplay.js.map +1 -1
  126. package/dist/js/replay/networkUtils.d.ts +0 -1
  127. package/dist/js/replay/networkUtils.d.ts.map +1 -1
  128. package/dist/js/replay/networkUtils.js.map +1 -1
  129. package/dist/js/replay/xhrUtils.js.map +1 -1
  130. package/dist/js/scopeSync.js.map +1 -1
  131. package/dist/js/sdk.d.ts.map +1 -1
  132. package/dist/js/sdk.js +4 -2
  133. package/dist/js/sdk.js.map +1 -1
  134. package/dist/js/tools/ModulesCollector.js.map +1 -1
  135. package/dist/js/tools/easBuildHooks.js +13 -14
  136. package/dist/js/tools/easBuildHooks.js.map +1 -1
  137. package/dist/js/tools/enableLogger.js +1 -2
  138. package/dist/js/tools/enableLogger.js.map +1 -1
  139. package/dist/js/tools/metroMiddleware.d.ts.map +1 -1
  140. package/dist/js/tools/metroMiddleware.js.map +1 -1
  141. package/dist/js/tools/metroconfig.js +6 -7
  142. package/dist/js/tools/metroconfig.js.map +1 -1
  143. package/dist/js/tools/sentryBabelTransformerUtils.js +7 -7
  144. package/dist/js/tools/sentryBabelTransformerUtils.js.map +1 -1
  145. package/dist/js/tools/sentryMetroSerializer.d.ts.map +1 -1
  146. package/dist/js/tools/sentryMetroSerializer.js +2 -2
  147. package/dist/js/tools/sentryMetroSerializer.js.map +1 -1
  148. package/dist/js/tools/sentryOptionsSerializer.js +1 -2
  149. package/dist/js/tools/sentryOptionsSerializer.js.map +1 -1
  150. package/dist/js/tools/sentryReleaseInjector.d.ts +1 -1
  151. package/dist/js/tools/sentryReleaseInjector.d.ts.map +1 -1
  152. package/dist/js/tools/sentryReleaseInjector.js.map +1 -1
  153. package/dist/js/tools/utils.d.ts.map +1 -1
  154. package/dist/js/tools/utils.js +9 -10
  155. package/dist/js/tools/utils.js.map +1 -1
  156. package/dist/js/tools/vendor/metro/countLines.d.ts.map +1 -1
  157. package/dist/js/tools/vendor/metro/utils.d.ts.map +1 -1
  158. package/dist/js/tools/vendor/metro/utils.js.map +1 -1
  159. package/dist/js/touchevents.d.ts.map +1 -1
  160. package/dist/js/touchevents.js +2 -0
  161. package/dist/js/touchevents.js.map +1 -1
  162. package/dist/js/tracing/expoAsset.js.map +1 -1
  163. package/dist/js/tracing/expoImage.js.map +1 -1
  164. package/dist/js/tracing/expoRouter.js.map +1 -1
  165. package/dist/js/tracing/gesturetracing.js.map +1 -1
  166. package/dist/js/tracing/integrations/appStart.d.ts +9 -1
  167. package/dist/js/tracing/integrations/appStart.d.ts.map +1 -1
  168. package/dist/js/tracing/integrations/appStart.js +61 -12
  169. package/dist/js/tracing/integrations/appStart.js.map +1 -1
  170. package/dist/js/tracing/integrations/nativeFrames.d.ts.map +1 -1
  171. package/dist/js/tracing/integrations/nativeFrames.js +35 -22
  172. package/dist/js/tracing/integrations/nativeFrames.js.map +1 -1
  173. package/dist/js/tracing/integrations/stalltracking.d.ts +1 -1
  174. package/dist/js/tracing/integrations/stalltracking.d.ts.map +1 -1
  175. package/dist/js/tracing/integrations/stalltracking.js +4 -1
  176. package/dist/js/tracing/integrations/stalltracking.js.map +1 -1
  177. package/dist/js/tracing/integrations/timeToDisplayIntegration.d.ts.map +1 -1
  178. package/dist/js/tracing/integrations/timeToDisplayIntegration.js +15 -14
  179. package/dist/js/tracing/integrations/timeToDisplayIntegration.js.map +1 -1
  180. package/dist/js/tracing/integrations/userInteraction.d.ts.map +1 -1
  181. package/dist/js/tracing/integrations/userInteraction.js.map +1 -1
  182. package/dist/js/tracing/onSpanEndUtils.d.ts.map +1 -1
  183. package/dist/js/tracing/onSpanEndUtils.js +20 -13
  184. package/dist/js/tracing/onSpanEndUtils.js.map +1 -1
  185. package/dist/js/tracing/reactnativenavigation.d.ts.map +1 -1
  186. package/dist/js/tracing/reactnativenavigation.js +1 -1
  187. package/dist/js/tracing/reactnativenavigation.js.map +1 -1
  188. package/dist/js/tracing/reactnativeprofiler.js.map +1 -1
  189. package/dist/js/tracing/reactnativetracing.d.ts.map +1 -1
  190. package/dist/js/tracing/reactnativetracing.js.map +1 -1
  191. package/dist/js/tracing/reactnavigation.d.ts +3 -0
  192. package/dist/js/tracing/reactnavigation.d.ts.map +1 -1
  193. package/dist/js/tracing/reactnavigation.js +7 -3
  194. package/dist/js/tracing/reactnavigation.js.map +1 -1
  195. package/dist/js/tracing/span.d.ts +2 -17
  196. package/dist/js/tracing/span.d.ts.map +1 -1
  197. package/dist/js/tracing/span.js.map +1 -1
  198. package/dist/js/tracing/timeToDisplayFallback.d.ts.map +1 -1
  199. package/dist/js/tracing/timetodisplay.js.map +1 -1
  200. package/dist/js/tracing/timetodisplaynative.d.ts.map +1 -1
  201. package/dist/js/tracing/timetodisplaynative.js.map +1 -1
  202. package/dist/js/tracing/utils.js.map +1 -1
  203. package/dist/js/transports/encodePolyfill.d.ts +1 -1
  204. package/dist/js/transports/encodePolyfill.d.ts.map +1 -1
  205. package/dist/js/transports/encodePolyfill.js.map +1 -1
  206. package/dist/js/transports/native.js.map +1 -1
  207. package/dist/js/utils/AsyncExpiringMap.js.map +1 -1
  208. package/dist/js/utils/encode.js.map +1 -1
  209. package/dist/js/utils/environment.js.map +1 -1
  210. package/dist/js/utils/ignorerequirecyclelogs.js +1 -1
  211. package/dist/js/utils/ignorerequirecyclelogs.js.map +1 -1
  212. package/dist/js/utils/normalize.js.map +1 -1
  213. package/dist/js/utils/outcome.js.map +1 -1
  214. package/dist/js/utils/primitiveConverter.js.map +1 -1
  215. package/dist/js/utils/release.js.map +1 -1
  216. package/dist/js/utils/rnlibraries.js.map +1 -1
  217. package/dist/js/utils/safe.d.ts +1 -1
  218. package/dist/js/utils/safe.d.ts.map +1 -1
  219. package/dist/js/utils/safe.js.map +1 -1
  220. package/dist/js/utils/worldwide.d.ts +0 -1
  221. package/dist/js/utils/worldwide.d.ts.map +1 -1
  222. package/dist/js/utils/xhr.d.ts +0 -1
  223. package/dist/js/utils/xhr.d.ts.map +1 -1
  224. package/dist/js/utils/xhr.js.map +1 -1
  225. package/dist/js/vendor/base64-js/fromByteArray.js.map +1 -1
  226. package/dist/js/vendor/buffer/utf8ToBytes.js.map +1 -1
  227. package/dist/js/version.d.ts +1 -1
  228. package/dist/js/version.js +1 -1
  229. package/dist/js/version.js.map +1 -1
  230. package/dist/js/wrapper.d.ts.map +1 -1
  231. package/dist/js/wrapper.js +5 -6
  232. package/dist/js/wrapper.js.map +1 -1
  233. package/expo-module.config.json +7 -0
  234. package/ios/RNSentry.mm +47 -1
  235. package/ios/RNSentryEvents.h +1 -0
  236. package/ios/RNSentryEvents.m +1 -0
  237. package/ios/RNSentryStart.m +4 -1
  238. package/ios/RNSentryVersion.m +1 -1
  239. package/package.json +15 -15
  240. package/plugin/build/withSentry.js +1 -1
  241. package/plugin/build/withSentryAndroidGradlePlugin.d.ts +1 -1
  242. package/plugin/build/withSentryAndroidGradlePlugin.js +1 -1
  243. package/scripts/sentry-xcode.sh +14 -0
  244. package/sentry.gradle +13 -0
  245. package/src/js/NativeRNSentry.ts +2 -0
  246. package/ts3.8/dist/js/NativeRNSentry.d.ts +2 -0
  247. package/ts3.8/dist/js/feedback/FeedbackWidgetManager.d.ts +3 -1
  248. package/ts3.8/dist/js/feedback/FeedbackWidgetProvider.d.ts +3 -2
  249. package/ts3.8/dist/js/feedback/ScreenshotButton.d.ts +1 -1
  250. package/ts3.8/dist/js/feedback/ShakeToReportBug.d.ts +27 -0
  251. package/ts3.8/dist/js/feedback/integration.d.ts +13 -2
  252. package/ts3.8/dist/js/index.d.ts +1 -1
  253. package/ts3.8/dist/js/integrations/exports.d.ts +1 -0
  254. package/ts3.8/dist/js/integrations/expoupdateslistener.d.ts +38 -0
  255. package/ts3.8/dist/js/options.d.ts +13 -1
  256. package/ts3.8/dist/js/playground/modal.d.ts +2 -2
  257. package/ts3.8/dist/js/replay/networkUtils.d.ts +0 -1
  258. package/ts3.8/dist/js/tracing/integrations/appStart.d.ts +9 -1
  259. package/ts3.8/dist/js/tracing/integrations/stalltracking.d.ts +1 -1
  260. package/ts3.8/dist/js/tracing/reactnavigation.d.ts +3 -0
  261. package/ts3.8/dist/js/tracing/span.d.ts +2 -17
  262. package/ts3.8/dist/js/transports/encodePolyfill.d.ts +1 -1
  263. package/ts3.8/dist/js/utils/safe.d.ts +1 -1
  264. package/ts3.8/dist/js/utils/worldwide.d.ts +0 -1
  265. package/ts3.8/dist/js/utils/xhr.d.ts +0 -1
  266. package/ts3.8/dist/js/version.d.ts +1 -1
@@ -28,6 +28,7 @@ export const timeToDisplayIntegration = () => {
28
28
  enableTimeToInitialDisplayForPreloadedRoutes =
29
29
  (_b = (_a = getReactNavigationIntegration(client)) === null || _a === void 0 ? void 0 : _a.options.enableTimeToInitialDisplayForPreloadedRoutes) !== null && _b !== void 0 ? _b : false;
30
30
  },
31
+ // eslint-disable-next-line complexity
31
32
  processEvent: (event) => __awaiter(void 0, void 0, void 0, function* () {
32
33
  var _a, _b, _c, _d, _e;
33
34
  if (event.type !== 'transaction') {
@@ -82,12 +83,12 @@ export const timeToDisplayIntegration = () => {
82
83
  }),
83
84
  };
84
85
  };
85
- function addTimeToInitialDisplay({ event, rootSpanId, transactionStartTimestampSeconds, enableTimeToInitialDisplayForPreloadedRoutes, }) {
86
- var _a;
87
- return __awaiter(this, void 0, void 0, function* () {
86
+ function addTimeToInitialDisplay(_a) {
87
+ return __awaiter(this, arguments, void 0, function* ({ event, rootSpanId, transactionStartTimestampSeconds, enableTimeToInitialDisplayForPreloadedRoutes, }) {
88
+ var _b;
88
89
  const ttidEndTimestampSeconds = yield NATIVE.popTimeToDisplayFor(`ttid-${rootSpanId}`);
89
90
  event.spans = event.spans || [];
90
- let ttidSpan = (_a = event.spans) === null || _a === void 0 ? void 0 : _a.find(span => span.op === UI_LOAD_INITIAL_DISPLAY);
91
+ let ttidSpan = (_b = event.spans) === null || _b === void 0 ? void 0 : _b.find(span => span.op === UI_LOAD_INITIAL_DISPLAY);
91
92
  if (ttidSpan && (ttidSpan.status === undefined || ttidSpan.status === 'ok') && !ttidEndTimestampSeconds) {
92
93
  debug.log(`[${INTEGRATION_NAME}] Ttid span already exists and is ok.`, ttidSpan);
93
94
  return ttidSpan;
@@ -123,12 +124,12 @@ function addTimeToInitialDisplay({ event, rootSpanId, transactionStartTimestampS
123
124
  return ttidSpan;
124
125
  });
125
126
  }
126
- function addAutomaticTimeToInitialDisplay({ event, rootSpanId, transactionStartTimestampSeconds, enableTimeToInitialDisplayForPreloadedRoutes, }) {
127
- var _a, _b, _c, _d, _e, _f;
128
- return __awaiter(this, void 0, void 0, function* () {
127
+ function addAutomaticTimeToInitialDisplay(_a) {
128
+ return __awaiter(this, arguments, void 0, function* ({ event, rootSpanId, transactionStartTimestampSeconds, enableTimeToInitialDisplayForPreloadedRoutes, }) {
129
+ var _b, _c, _d, _e, _f, _g;
129
130
  const ttidNativeTimestampSeconds = yield NATIVE.popTimeToDisplayFor(`ttid-navigation-${rootSpanId}`);
130
131
  const ttidFallbackTimestampSeconds = yield getTimeToInitialDisplayFallback(rootSpanId);
131
- const hasBeenSeen = (_c = (_b = (_a = event.contexts) === null || _a === void 0 ? void 0 : _a.trace) === null || _b === void 0 ? void 0 : _b.data) === null || _c === void 0 ? void 0 : _c[SEMANTIC_ATTRIBUTE_ROUTE_HAS_BEEN_SEEN];
132
+ const hasBeenSeen = (_d = (_c = (_b = event.contexts) === null || _b === void 0 ? void 0 : _b.trace) === null || _c === void 0 ? void 0 : _c.data) === null || _d === void 0 ? void 0 : _d[SEMANTIC_ATTRIBUTE_ROUTE_HAS_BEEN_SEEN];
132
133
  if (hasBeenSeen && !enableTimeToInitialDisplayForPreloadedRoutes) {
133
134
  debug.log(`[${INTEGRATION_NAME}] Route has been seen and time to initial display is disabled for preloaded routes.`);
134
135
  return undefined;
@@ -138,7 +139,7 @@ function addAutomaticTimeToInitialDisplay({ event, rootSpanId, transactionStartT
138
139
  debug.log(`[${INTEGRATION_NAME}] No automatic ttid end timestamp found for span ${rootSpanId}.`);
139
140
  return undefined;
140
141
  }
141
- const viewNames = (_e = (_d = event.contexts) === null || _d === void 0 ? void 0 : _d.app) === null || _e === void 0 ? void 0 : _e.view_names;
142
+ const viewNames = (_f = (_e = event.contexts) === null || _e === void 0 ? void 0 : _e.app) === null || _f === void 0 ? void 0 : _f.view_names;
142
143
  const screenName = Array.isArray(viewNames) ? viewNames[0] : viewNames;
143
144
  const ttidSpan = createSpanJSON({
144
145
  op: UI_LOAD_INITIAL_DISPLAY,
@@ -151,20 +152,20 @@ function addAutomaticTimeToInitialDisplay({ event, rootSpanId, transactionStartT
151
152
  [SPAN_THREAD_NAME]: SPAN_THREAD_NAME_JAVASCRIPT,
152
153
  },
153
154
  });
154
- event.spans = (_f = event.spans) !== null && _f !== void 0 ? _f : [];
155
+ event.spans = (_g = event.spans) !== null && _g !== void 0 ? _g : [];
155
156
  event.spans.push(ttidSpan);
156
157
  return ttidSpan;
157
158
  });
158
159
  }
159
- function addTimeToFullDisplay({ event, rootSpanId, transactionStartTimestampSeconds, ttidSpan, }) {
160
- var _a;
161
- return __awaiter(this, void 0, void 0, function* () {
160
+ function addTimeToFullDisplay(_a) {
161
+ return __awaiter(this, arguments, void 0, function* ({ event, rootSpanId, transactionStartTimestampSeconds, ttidSpan, }) {
162
+ var _b;
162
163
  const ttfdEndTimestampSeconds = yield NATIVE.popTimeToDisplayFor(`ttfd-${rootSpanId}`);
163
164
  if (!ttidSpan || !ttfdEndTimestampSeconds) {
164
165
  return undefined;
165
166
  }
166
167
  event.spans = event.spans || [];
167
- let ttfdSpan = (_a = event.spans) === null || _a === void 0 ? void 0 : _a.find(span => span.op === UI_LOAD_FULL_DISPLAY);
168
+ let ttfdSpan = (_b = event.spans) === null || _b === void 0 ? void 0 : _b.find(span => span.op === UI_LOAD_FULL_DISPLAY);
168
169
  let ttfdAdjustedEndTimestampSeconds = ttfdEndTimestampSeconds;
169
170
  const ttfdIsBeforeTtid = ttidSpan.timestamp && ttfdEndTimestampSeconds < ttidSpan.timestamp;
170
171
  if (ttfdIsBeforeTtid && ttidSpan.timestamp) {
@@ -1 +1 @@
1
- {"version":3,"file":"timeToDisplayIntegration.js","sourceRoot":"","sources":["../../../../src/js/tracing/integrations/timeToDisplayIntegration.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Event, Integration, SpanJSON } from '@sentry/core';\nimport { debug } from '@sentry/core';\nimport { NATIVE } from '../../wrapper';\nimport { UI_LOAD_FULL_DISPLAY, UI_LOAD_INITIAL_DISPLAY } from '../ops';\nimport { SPAN_ORIGIN_AUTO_UI_TIME_TO_DISPLAY, SPAN_ORIGIN_MANUAL_UI_TIME_TO_DISPLAY } from '../origin';\nimport { getReactNavigationIntegration } from '../reactnavigation';\nimport { SEMANTIC_ATTRIBUTE_ROUTE_HAS_BEEN_SEEN } from '../semanticAttributes';\nimport { SPAN_THREAD_NAME, SPAN_THREAD_NAME_JAVASCRIPT } from '../span';\nimport { getTimeToInitialDisplayFallback } from '../timeToDisplayFallback';\nimport { createSpanJSON } from '../utils';\n\nexport const INTEGRATION_NAME = 'TimeToDisplay';\n\nconst TIME_TO_DISPLAY_TIMEOUT_MS = 30_000;\nconst isDeadlineExceeded = (durationMs: number): boolean => durationMs > TIME_TO_DISPLAY_TIMEOUT_MS;\n\nexport const timeToDisplayIntegration = (): Integration => {\n let enableTimeToInitialDisplayForPreloadedRoutes = false;\n\n return {\n name: INTEGRATION_NAME,\n afterAllSetup(client) {\n enableTimeToInitialDisplayForPreloadedRoutes =\n getReactNavigationIntegration(client)?.options.enableTimeToInitialDisplayForPreloadedRoutes ?? false;\n },\n processEvent: async event => {\n if (event.type !== 'transaction') {\n // TimeToDisplay data is only relevant for transactions\n return event;\n }\n\n const rootSpanId = event.contexts?.trace?.span_id;\n if (!rootSpanId) {\n debug.warn(`[${INTEGRATION_NAME}] No root span id found in transaction.`);\n return event;\n }\n\n const transactionStartTimestampSeconds = event.start_timestamp;\n if (!transactionStartTimestampSeconds) {\n // This should never happen\n debug.warn(`[${INTEGRATION_NAME}] No transaction start timestamp found in transaction.`);\n return event;\n }\n\n event.spans = event.spans || [];\n event.measurements = event.measurements || {};\n\n const ttidSpan = await addTimeToInitialDisplay({\n event,\n rootSpanId,\n transactionStartTimestampSeconds,\n enableTimeToInitialDisplayForPreloadedRoutes,\n });\n const ttfdSpan = await addTimeToFullDisplay({ event, rootSpanId, transactionStartTimestampSeconds, ttidSpan });\n\n if (ttidSpan?.start_timestamp && ttidSpan?.timestamp) {\n event.measurements['time_to_initial_display'] = {\n value: (ttidSpan.timestamp - ttidSpan.start_timestamp) * 1000,\n unit: 'millisecond',\n };\n }\n\n if (ttfdSpan?.start_timestamp && ttfdSpan?.timestamp) {\n const durationMs = (ttfdSpan.timestamp - ttfdSpan.start_timestamp) * 1000;\n if (isDeadlineExceeded(durationMs)) {\n if (event.measurements['time_to_initial_display']) {\n event.measurements['time_to_full_display'] = event.measurements['time_to_initial_display'];\n }\n } else {\n event.measurements['time_to_full_display'] = {\n value: durationMs,\n unit: 'millisecond',\n };\n }\n }\n\n const newTransactionEndTimestampSeconds = Math.max(\n ttidSpan?.timestamp ?? -1,\n ttfdSpan?.timestamp ?? -1,\n event.timestamp ?? -1,\n );\n if (newTransactionEndTimestampSeconds !== -1) {\n event.timestamp = newTransactionEndTimestampSeconds;\n }\n\n return event;\n },\n };\n};\n\nasync function addTimeToInitialDisplay({\n event,\n rootSpanId,\n transactionStartTimestampSeconds,\n enableTimeToInitialDisplayForPreloadedRoutes,\n}: {\n event: Event;\n rootSpanId: string;\n transactionStartTimestampSeconds: number;\n enableTimeToInitialDisplayForPreloadedRoutes: boolean;\n}): Promise<SpanJSON | undefined> {\n const ttidEndTimestampSeconds = await NATIVE.popTimeToDisplayFor(`ttid-${rootSpanId}`);\n\n event.spans = event.spans || [];\n\n let ttidSpan: SpanJSON | undefined = event.spans?.find(span => span.op === UI_LOAD_INITIAL_DISPLAY);\n\n if (ttidSpan && (ttidSpan.status === undefined || ttidSpan.status === 'ok') && !ttidEndTimestampSeconds) {\n debug.log(`[${INTEGRATION_NAME}] Ttid span already exists and is ok.`, ttidSpan);\n return ttidSpan;\n }\n\n if (!ttidEndTimestampSeconds) {\n debug.log(`[${INTEGRATION_NAME}] No manual ttid end timestamp found for span ${rootSpanId}.`);\n return addAutomaticTimeToInitialDisplay({\n event,\n rootSpanId,\n transactionStartTimestampSeconds,\n enableTimeToInitialDisplayForPreloadedRoutes,\n });\n }\n\n if (ttidSpan?.status && ttidSpan.status !== 'ok') {\n ttidSpan.status = 'ok';\n ttidSpan.timestamp = ttidEndTimestampSeconds;\n debug.log(`[${INTEGRATION_NAME}] Updated existing ttid span.`, ttidSpan);\n return ttidSpan;\n }\n\n ttidSpan = createSpanJSON({\n op: UI_LOAD_INITIAL_DISPLAY,\n description: 'Time To Initial Display',\n start_timestamp: transactionStartTimestampSeconds,\n timestamp: ttidEndTimestampSeconds,\n origin: SPAN_ORIGIN_MANUAL_UI_TIME_TO_DISPLAY,\n parent_span_id: rootSpanId,\n data: {\n [SPAN_THREAD_NAME]: SPAN_THREAD_NAME_JAVASCRIPT,\n },\n });\n debug.log(`[${INTEGRATION_NAME}] Added ttid span to transaction.`, ttidSpan);\n event.spans.push(ttidSpan);\n return ttidSpan;\n}\n\nasync function addAutomaticTimeToInitialDisplay({\n event,\n rootSpanId,\n transactionStartTimestampSeconds,\n enableTimeToInitialDisplayForPreloadedRoutes,\n}: {\n event: Event;\n rootSpanId: string;\n transactionStartTimestampSeconds: number;\n enableTimeToInitialDisplayForPreloadedRoutes: boolean;\n}): Promise<SpanJSON | undefined> {\n const ttidNativeTimestampSeconds = await NATIVE.popTimeToDisplayFor(`ttid-navigation-${rootSpanId}`);\n const ttidFallbackTimestampSeconds = await getTimeToInitialDisplayFallback(rootSpanId);\n\n const hasBeenSeen = event.contexts?.trace?.data?.[SEMANTIC_ATTRIBUTE_ROUTE_HAS_BEEN_SEEN];\n if (hasBeenSeen && !enableTimeToInitialDisplayForPreloadedRoutes) {\n debug.log(\n `[${INTEGRATION_NAME}] Route has been seen and time to initial display is disabled for preloaded routes.`,\n );\n return undefined;\n }\n\n const ttidTimestampSeconds = ttidNativeTimestampSeconds ?? ttidFallbackTimestampSeconds;\n if (!ttidTimestampSeconds) {\n debug.log(`[${INTEGRATION_NAME}] No automatic ttid end timestamp found for span ${rootSpanId}.`);\n return undefined;\n }\n\n const viewNames = event.contexts?.app?.view_names;\n const screenName = Array.isArray(viewNames) ? viewNames[0] : viewNames;\n\n const ttidSpan = createSpanJSON({\n op: UI_LOAD_INITIAL_DISPLAY,\n description: screenName ? `${screenName} initial display` : 'Time To Initial Display',\n start_timestamp: transactionStartTimestampSeconds,\n timestamp: ttidTimestampSeconds,\n origin: SPAN_ORIGIN_AUTO_UI_TIME_TO_DISPLAY,\n parent_span_id: rootSpanId,\n data: {\n [SPAN_THREAD_NAME]: SPAN_THREAD_NAME_JAVASCRIPT,\n },\n });\n event.spans = event.spans ?? [];\n event.spans.push(ttidSpan);\n return ttidSpan;\n}\n\nasync function addTimeToFullDisplay({\n event,\n rootSpanId,\n transactionStartTimestampSeconds,\n ttidSpan,\n}: {\n event: Event;\n rootSpanId: string;\n transactionStartTimestampSeconds: number;\n ttidSpan: SpanJSON | undefined;\n}): Promise<SpanJSON | undefined> {\n const ttfdEndTimestampSeconds = await NATIVE.popTimeToDisplayFor(`ttfd-${rootSpanId}`);\n\n if (!ttidSpan || !ttfdEndTimestampSeconds) {\n return undefined;\n }\n\n event.spans = event.spans || [];\n\n let ttfdSpan = event.spans?.find(span => span.op === UI_LOAD_FULL_DISPLAY);\n\n let ttfdAdjustedEndTimestampSeconds = ttfdEndTimestampSeconds;\n const ttfdIsBeforeTtid = ttidSpan.timestamp && ttfdEndTimestampSeconds < ttidSpan.timestamp;\n if (ttfdIsBeforeTtid && ttidSpan.timestamp) {\n ttfdAdjustedEndTimestampSeconds = ttidSpan.timestamp;\n }\n\n const durationMs = (ttfdAdjustedEndTimestampSeconds - transactionStartTimestampSeconds) * 1000;\n\n if (ttfdSpan?.status && ttfdSpan.status !== 'ok') {\n ttfdSpan.status = 'ok';\n ttfdSpan.timestamp = ttfdAdjustedEndTimestampSeconds;\n debug.log(`[${INTEGRATION_NAME}] Updated existing ttfd span.`, ttfdSpan);\n return ttfdSpan;\n }\n\n ttfdSpan = createSpanJSON({\n status: isDeadlineExceeded(durationMs) ? 'deadline_exceeded' : 'ok',\n op: UI_LOAD_FULL_DISPLAY,\n description: 'Time To Full Display',\n start_timestamp: transactionStartTimestampSeconds,\n timestamp: ttfdAdjustedEndTimestampSeconds,\n origin: SPAN_ORIGIN_MANUAL_UI_TIME_TO_DISPLAY,\n parent_span_id: rootSpanId,\n data: {\n [SPAN_THREAD_NAME]: SPAN_THREAD_NAME_JAVASCRIPT,\n },\n });\n debug.log(`[${INTEGRATION_NAME}] Added ttfd span to transaction.`, ttfdSpan);\n event.spans.push(ttfdSpan);\n return ttfdSpan;\n}\n"]}
1
+ {"version":3,"file":"timeToDisplayIntegration.js","sourceRoot":"","sources":["../../../../src/js/tracing/integrations/timeToDisplayIntegration.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Event, Integration, SpanJSON } from '@sentry/core';\nimport { debug } from '@sentry/core';\nimport { NATIVE } from '../../wrapper';\nimport { UI_LOAD_FULL_DISPLAY, UI_LOAD_INITIAL_DISPLAY } from '../ops';\nimport { SPAN_ORIGIN_AUTO_UI_TIME_TO_DISPLAY, SPAN_ORIGIN_MANUAL_UI_TIME_TO_DISPLAY } from '../origin';\nimport { getReactNavigationIntegration } from '../reactnavigation';\nimport { SEMANTIC_ATTRIBUTE_ROUTE_HAS_BEEN_SEEN } from '../semanticAttributes';\nimport { SPAN_THREAD_NAME, SPAN_THREAD_NAME_JAVASCRIPT } from '../span';\nimport { getTimeToInitialDisplayFallback } from '../timeToDisplayFallback';\nimport { createSpanJSON } from '../utils';\n\nexport const INTEGRATION_NAME = 'TimeToDisplay';\n\nconst TIME_TO_DISPLAY_TIMEOUT_MS = 30_000;\nconst isDeadlineExceeded = (durationMs: number): boolean => durationMs > TIME_TO_DISPLAY_TIMEOUT_MS;\n\nexport const timeToDisplayIntegration = (): Integration => {\n let enableTimeToInitialDisplayForPreloadedRoutes = false;\n\n return {\n name: INTEGRATION_NAME,\n afterAllSetup(client) {\n enableTimeToInitialDisplayForPreloadedRoutes =\n getReactNavigationIntegration(client)?.options.enableTimeToInitialDisplayForPreloadedRoutes ?? false;\n },\n // eslint-disable-next-line complexity\n processEvent: async event => {\n if (event.type !== 'transaction') {\n // TimeToDisplay data is only relevant for transactions\n return event;\n }\n\n const rootSpanId = event.contexts?.trace?.span_id;\n if (!rootSpanId) {\n debug.warn(`[${INTEGRATION_NAME}] No root span id found in transaction.`);\n return event;\n }\n\n const transactionStartTimestampSeconds = event.start_timestamp;\n if (!transactionStartTimestampSeconds) {\n // This should never happen\n debug.warn(`[${INTEGRATION_NAME}] No transaction start timestamp found in transaction.`);\n return event;\n }\n\n event.spans = event.spans || [];\n event.measurements = event.measurements || {};\n\n const ttidSpan = await addTimeToInitialDisplay({\n event,\n rootSpanId,\n transactionStartTimestampSeconds,\n enableTimeToInitialDisplayForPreloadedRoutes,\n });\n const ttfdSpan = await addTimeToFullDisplay({ event, rootSpanId, transactionStartTimestampSeconds, ttidSpan });\n\n if (ttidSpan?.start_timestamp && ttidSpan?.timestamp) {\n event.measurements['time_to_initial_display'] = {\n value: (ttidSpan.timestamp - ttidSpan.start_timestamp) * 1000,\n unit: 'millisecond',\n };\n }\n\n if (ttfdSpan?.start_timestamp && ttfdSpan?.timestamp) {\n const durationMs = (ttfdSpan.timestamp - ttfdSpan.start_timestamp) * 1000;\n if (isDeadlineExceeded(durationMs)) {\n if (event.measurements['time_to_initial_display']) {\n event.measurements['time_to_full_display'] = event.measurements['time_to_initial_display'];\n }\n } else {\n event.measurements['time_to_full_display'] = {\n value: durationMs,\n unit: 'millisecond',\n };\n }\n }\n\n const newTransactionEndTimestampSeconds = Math.max(\n ttidSpan?.timestamp ?? -1,\n ttfdSpan?.timestamp ?? -1,\n event.timestamp ?? -1,\n );\n if (newTransactionEndTimestampSeconds !== -1) {\n event.timestamp = newTransactionEndTimestampSeconds;\n }\n\n return event;\n },\n };\n};\n\nasync function addTimeToInitialDisplay({\n event,\n rootSpanId,\n transactionStartTimestampSeconds,\n enableTimeToInitialDisplayForPreloadedRoutes,\n}: {\n event: Event;\n rootSpanId: string;\n transactionStartTimestampSeconds: number;\n enableTimeToInitialDisplayForPreloadedRoutes: boolean;\n}): Promise<SpanJSON | undefined> {\n const ttidEndTimestampSeconds = await NATIVE.popTimeToDisplayFor(`ttid-${rootSpanId}`);\n\n event.spans = event.spans || [];\n\n let ttidSpan: SpanJSON | undefined = event.spans?.find(span => span.op === UI_LOAD_INITIAL_DISPLAY);\n\n if (ttidSpan && (ttidSpan.status === undefined || ttidSpan.status === 'ok') && !ttidEndTimestampSeconds) {\n debug.log(`[${INTEGRATION_NAME}] Ttid span already exists and is ok.`, ttidSpan);\n return ttidSpan;\n }\n\n if (!ttidEndTimestampSeconds) {\n debug.log(`[${INTEGRATION_NAME}] No manual ttid end timestamp found for span ${rootSpanId}.`);\n return addAutomaticTimeToInitialDisplay({\n event,\n rootSpanId,\n transactionStartTimestampSeconds,\n enableTimeToInitialDisplayForPreloadedRoutes,\n });\n }\n\n if (ttidSpan?.status && ttidSpan.status !== 'ok') {\n ttidSpan.status = 'ok';\n ttidSpan.timestamp = ttidEndTimestampSeconds;\n debug.log(`[${INTEGRATION_NAME}] Updated existing ttid span.`, ttidSpan);\n return ttidSpan;\n }\n\n ttidSpan = createSpanJSON({\n op: UI_LOAD_INITIAL_DISPLAY,\n description: 'Time To Initial Display',\n start_timestamp: transactionStartTimestampSeconds,\n timestamp: ttidEndTimestampSeconds,\n origin: SPAN_ORIGIN_MANUAL_UI_TIME_TO_DISPLAY,\n parent_span_id: rootSpanId,\n data: {\n [SPAN_THREAD_NAME]: SPAN_THREAD_NAME_JAVASCRIPT,\n },\n });\n debug.log(`[${INTEGRATION_NAME}] Added ttid span to transaction.`, ttidSpan);\n event.spans.push(ttidSpan);\n return ttidSpan;\n}\n\nasync function addAutomaticTimeToInitialDisplay({\n event,\n rootSpanId,\n transactionStartTimestampSeconds,\n enableTimeToInitialDisplayForPreloadedRoutes,\n}: {\n event: Event;\n rootSpanId: string;\n transactionStartTimestampSeconds: number;\n enableTimeToInitialDisplayForPreloadedRoutes: boolean;\n}): Promise<SpanJSON | undefined> {\n const ttidNativeTimestampSeconds = await NATIVE.popTimeToDisplayFor(`ttid-navigation-${rootSpanId}`);\n const ttidFallbackTimestampSeconds = await getTimeToInitialDisplayFallback(rootSpanId);\n\n const hasBeenSeen = event.contexts?.trace?.data?.[SEMANTIC_ATTRIBUTE_ROUTE_HAS_BEEN_SEEN];\n if (hasBeenSeen && !enableTimeToInitialDisplayForPreloadedRoutes) {\n debug.log(\n `[${INTEGRATION_NAME}] Route has been seen and time to initial display is disabled for preloaded routes.`,\n );\n return undefined;\n }\n\n const ttidTimestampSeconds = ttidNativeTimestampSeconds ?? ttidFallbackTimestampSeconds;\n if (!ttidTimestampSeconds) {\n debug.log(`[${INTEGRATION_NAME}] No automatic ttid end timestamp found for span ${rootSpanId}.`);\n return undefined;\n }\n\n const viewNames = event.contexts?.app?.view_names;\n const screenName = Array.isArray(viewNames) ? viewNames[0] : viewNames;\n\n const ttidSpan = createSpanJSON({\n op: UI_LOAD_INITIAL_DISPLAY,\n description: screenName ? `${screenName} initial display` : 'Time To Initial Display',\n start_timestamp: transactionStartTimestampSeconds,\n timestamp: ttidTimestampSeconds,\n origin: SPAN_ORIGIN_AUTO_UI_TIME_TO_DISPLAY,\n parent_span_id: rootSpanId,\n data: {\n [SPAN_THREAD_NAME]: SPAN_THREAD_NAME_JAVASCRIPT,\n },\n });\n event.spans = event.spans ?? [];\n event.spans.push(ttidSpan);\n return ttidSpan;\n}\n\nasync function addTimeToFullDisplay({\n event,\n rootSpanId,\n transactionStartTimestampSeconds,\n ttidSpan,\n}: {\n event: Event;\n rootSpanId: string;\n transactionStartTimestampSeconds: number;\n ttidSpan: SpanJSON | undefined;\n}): Promise<SpanJSON | undefined> {\n const ttfdEndTimestampSeconds = await NATIVE.popTimeToDisplayFor(`ttfd-${rootSpanId}`);\n\n if (!ttidSpan || !ttfdEndTimestampSeconds) {\n return undefined;\n }\n\n event.spans = event.spans || [];\n\n let ttfdSpan = event.spans?.find(span => span.op === UI_LOAD_FULL_DISPLAY);\n\n let ttfdAdjustedEndTimestampSeconds = ttfdEndTimestampSeconds;\n const ttfdIsBeforeTtid = ttidSpan.timestamp && ttfdEndTimestampSeconds < ttidSpan.timestamp;\n if (ttfdIsBeforeTtid && ttidSpan.timestamp) {\n ttfdAdjustedEndTimestampSeconds = ttidSpan.timestamp;\n }\n\n const durationMs = (ttfdAdjustedEndTimestampSeconds - transactionStartTimestampSeconds) * 1000;\n\n if (ttfdSpan?.status && ttfdSpan.status !== 'ok') {\n ttfdSpan.status = 'ok';\n ttfdSpan.timestamp = ttfdAdjustedEndTimestampSeconds;\n debug.log(`[${INTEGRATION_NAME}] Updated existing ttfd span.`, ttfdSpan);\n return ttfdSpan;\n }\n\n ttfdSpan = createSpanJSON({\n status: isDeadlineExceeded(durationMs) ? 'deadline_exceeded' : 'ok',\n op: UI_LOAD_FULL_DISPLAY,\n description: 'Time To Full Display',\n start_timestamp: transactionStartTimestampSeconds,\n timestamp: ttfdAdjustedEndTimestampSeconds,\n origin: SPAN_ORIGIN_MANUAL_UI_TIME_TO_DISPLAY,\n parent_span_id: rootSpanId,\n data: {\n [SPAN_THREAD_NAME]: SPAN_THREAD_NAME_JAVASCRIPT,\n },\n });\n debug.log(`[${INTEGRATION_NAME}] Added ttfd span to transaction.`, ttfdSpan);\n event.spans.push(ttfdSpan);\n return ttfdSpan;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"userInteraction.d.ts","sourceRoot":"","sources":["../../../../src/js/tracing/integrations/userInteraction.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,IAAI,EAAoB,MAAM,cAAc,CAAC;AAiBxE,eAAO,MAAM,0BAA0B,QAAO,WAI7C,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,wBAAwB,sBAAuB;IAC1D,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,EAAE,EAAE,MAAM,CAAC;CACZ,KAAG,IAAI,GAAG,SAmEV,CAAC"}
1
+ {"version":3,"file":"userInteraction.d.ts","sourceRoot":"","sources":["../../../../src/js/tracing/integrations/userInteraction.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,IAAI,EAAoB,MAAM,cAAc,CAAC;AAiBxE,eAAO,MAAM,0BAA0B,QAAO,WAI7C,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,wBAAwB,GAAI,mBAAmB;IAC1D,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,EAAE,EAAE,MAAM,CAAC;CACZ,KAAG,IAAI,GAAG,SAmEV,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"userInteraction.js","sourceRoot":"","sources":["../../../../src/js/tracing/integrations/userInteraction.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Integration, Span, StartSpanOptions } from '@sentry/core';\nimport {\n debug,\n getActiveSpan,\n getClient,\n getCurrentScope,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n spanToJSON,\n} from '@sentry/core';\nimport type { ReactNativeClientOptions } from '../../options';\nimport { onlySampleIfChildSpans } from '../onSpanEndUtils';\nimport { SPAN_ORIGIN_MANUAL_INTERACTION } from '../origin';\nimport { getCurrentReactNativeTracingIntegration } from '../reactnativetracing';\nimport { clearActiveSpanFromScope, isSentryInteractionSpan, startIdleSpan } from '../span';\n\nconst INTEGRATION_NAME = 'UserInteraction';\n\nexport const userInteractionIntegration = (): Integration => {\n return {\n name: INTEGRATION_NAME,\n };\n};\n\n/**\n * Starts a new transaction for a user interaction.\n * @param userInteractionId Consists of `op` representation UI Event and `elementId` unique element identifier on current screen.\n */\nexport const startUserInteractionSpan = (userInteractionId: {\n elementId: string | undefined;\n op: string;\n}): Span | undefined => {\n const client = getClient();\n if (!client) {\n return undefined;\n }\n\n const tracing = getCurrentReactNativeTracingIntegration();\n if (!tracing) {\n debug.log(`[${INTEGRATION_NAME}] Tracing integration is not available. Can not start user interaction span.`);\n return undefined;\n }\n\n const options = client.getOptions() as ReactNativeClientOptions;\n const { elementId, op } = userInteractionId;\n if (!options.enableUserInteractionTracing) {\n debug.log(`[${INTEGRATION_NAME}] User Interaction Tracing is disabled.`);\n return undefined;\n }\n if (!elementId) {\n debug.log(`[${INTEGRATION_NAME}] User Interaction Tracing can not create transaction with undefined elementId.`);\n return undefined;\n }\n if (!tracing.state.currentRoute) {\n debug.log(`[${INTEGRATION_NAME}] User Interaction Tracing can not create transaction without a current route.`);\n return undefined;\n }\n\n const activeTransaction = getActiveSpan();\n const activeTransactionIsNotInteraction = activeTransaction && !isSentryInteractionSpan(activeTransaction);\n if (activeTransaction && activeTransactionIsNotInteraction) {\n debug.warn(\n `[${INTEGRATION_NAME}] Did not create ${op} transaction because active transaction ${\n spanToJSON(activeTransaction).description\n } exists on the scope.`,\n );\n return undefined;\n }\n\n const name = `${tracing.state.currentRoute}.${elementId}`;\n if (\n activeTransaction &&\n spanToJSON(activeTransaction).description === name &&\n spanToJSON(activeTransaction).op === op\n ) {\n debug.warn(\n `[${INTEGRATION_NAME}] Did not create ${op} transaction because it the same transaction ${\n spanToJSON(activeTransaction).description\n } already exists on the scope.`,\n );\n return undefined;\n }\n\n const scope = getCurrentScope();\n const context: StartSpanOptions = {\n name,\n op,\n scope,\n };\n clearActiveSpanFromScope(scope);\n const newSpan = startIdleSpan(context, {\n idleTimeout: tracing.options.idleTimeoutMs,\n finalTimeout: tracing.options.finalTimeoutMs,\n });\n newSpan.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SPAN_ORIGIN_MANUAL_INTERACTION);\n onlySampleIfChildSpans(client, newSpan);\n debug.log(`[${INTEGRATION_NAME}] User Interaction Tracing Created ${op} transaction ${name}.`);\n return newSpan;\n};\n"]}
1
+ {"version":3,"file":"userInteraction.js","sourceRoot":"","sources":["../../../../src/js/tracing/integrations/userInteraction.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Integration, Span, StartSpanOptions } from '@sentry/core';\nimport {\n debug,\n getActiveSpan,\n getClient,\n getCurrentScope,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n spanToJSON,\n} from '@sentry/core';\nimport type { ReactNativeClientOptions } from '../../options';\nimport { onlySampleIfChildSpans } from '../onSpanEndUtils';\nimport { SPAN_ORIGIN_MANUAL_INTERACTION } from '../origin';\nimport { getCurrentReactNativeTracingIntegration } from '../reactnativetracing';\nimport { clearActiveSpanFromScope, isSentryInteractionSpan, startIdleSpan } from '../span';\n\nconst INTEGRATION_NAME = 'UserInteraction';\n\nexport const userInteractionIntegration = (): Integration => {\n return {\n name: INTEGRATION_NAME,\n };\n};\n\n/**\n * Starts a new transaction for a user interaction.\n * @param userInteractionId Consists of `op` representation UI Event and `elementId` unique element identifier on current screen.\n */\nexport const startUserInteractionSpan = (userInteractionId: {\n elementId: string | undefined;\n op: string;\n}): Span | undefined => {\n const client = getClient();\n if (!client) {\n return undefined;\n }\n\n const tracing = getCurrentReactNativeTracingIntegration();\n if (!tracing) {\n debug.log(`[${INTEGRATION_NAME}] Tracing integration is not available. Can not start user interaction span.`);\n return undefined;\n }\n\n const options = client.getOptions() as ReactNativeClientOptions;\n const { elementId, op } = userInteractionId;\n if (!options.enableUserInteractionTracing) {\n debug.log(`[${INTEGRATION_NAME}] User Interaction Tracing is disabled.`);\n return undefined;\n }\n if (!elementId) {\n debug.log(`[${INTEGRATION_NAME}] User Interaction Tracing can not create transaction with undefined elementId.`);\n return undefined;\n }\n if (!tracing.state.currentRoute) {\n debug.log(`[${INTEGRATION_NAME}] User Interaction Tracing can not create transaction without a current route.`);\n return undefined;\n }\n\n const activeTransaction = getActiveSpan();\n const activeTransactionIsNotInteraction = activeTransaction && !isSentryInteractionSpan(activeTransaction);\n if (activeTransaction && activeTransactionIsNotInteraction) {\n debug.warn(\n `[${INTEGRATION_NAME}] Did not create ${op} transaction because active transaction ${\n spanToJSON(activeTransaction).description\n } exists on the scope.`,\n );\n return undefined;\n }\n\n const name = `${tracing.state.currentRoute}.${elementId}`;\n if (\n activeTransaction &&\n spanToJSON(activeTransaction).description === name &&\n spanToJSON(activeTransaction).op === op\n ) {\n debug.warn(\n `[${INTEGRATION_NAME}] Did not create ${op} transaction because it the same transaction ${\n spanToJSON(activeTransaction).description\n } already exists on the scope.`,\n );\n return undefined;\n }\n\n const scope = getCurrentScope();\n const context: StartSpanOptions = {\n name,\n op,\n scope,\n };\n clearActiveSpanFromScope(scope);\n const newSpan = startIdleSpan(context, {\n idleTimeout: tracing.options.idleTimeoutMs,\n finalTimeout: tracing.options.finalTimeoutMs,\n });\n newSpan.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SPAN_ORIGIN_MANUAL_INTERACTION);\n onlySampleIfChildSpans(client, newSpan);\n debug.log(`[${INTEGRATION_NAME}] User Interaction Tracing Created ${op} transaction ${name}.`);\n return newSpan;\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"onSpanEndUtils.d.ts","sourceRoot":"","sources":["../../../src/js/tracing/onSpanEndUtils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAYjD;;GAEG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,GAAG,IAAI,CAO9F;AAED,eAAO,MAAM,yBAAyB,WAAY,MAAM,QAAQ,IAAI,iBAAiB,MAAM,KAAG,IA0B7F,CAAC;AAwDF,eAAO,MAAM,yBAAyB,WAAY,MAAM,GAAG,SAAS,QAAQ,IAAI,GAAG,SAAS,KAAG,IAa9F,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,kCAAkC,WACrC,MAAM,GAAG,SAAS,QACpB,IAAI,GAAG,SAAS,6BACK,MAAM,sBACb,MAAM,OAAO,KAChC,IAoBF,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,sBAAsB,WAAY,MAAM,QAAQ,IAAI,KAAG,IAmBnE,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,kBAAkB,WAAY,MAAM,QAAQ,IAAI,KAAG,IA2C/D,CAAC"}
1
+ {"version":3,"file":"onSpanEndUtils.d.ts","sourceRoot":"","sources":["../../../src/js/tracing/onSpanEndUtils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAYjD;;GAEG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,GAAG,IAAI,CAQ9F;AAED,eAAO,MAAM,yBAAyB,GAAI,QAAQ,MAAM,EAAE,MAAM,IAAI,EAAE,eAAe,MAAM,KAAG,IA2B7F,CAAC;AAyDF,eAAO,MAAM,yBAAyB,GAAI,QAAQ,MAAM,GAAG,SAAS,EAAE,MAAM,IAAI,GAAG,SAAS,KAAG,IAa9F,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,kCAAkC,GAC7C,QAAQ,MAAM,GAAG,SAAS,EAC1B,MAAM,IAAI,GAAG,SAAS,EACtB,2BAA2B,MAAM,EACjC,oBAAoB,MAAM,OAAO,KAChC,IAoBF,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,sBAAsB,GAAI,QAAQ,MAAM,EAAE,MAAM,IAAI,KAAG,IAoBnE,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,kBAAkB,GAAI,QAAQ,MAAM,EAAE,MAAM,IAAI,KAAG,IA8C/D,CAAC"}
@@ -10,10 +10,11 @@ const IOS_INACTIVE_CANCEL_DELAY_MS = 5000;
10
10
  * Hooks on span end event to execute a callback when the span ends.
11
11
  */
12
12
  export function onThisSpanEnd(client, span, callback) {
13
- client.on('spanEnd', (endedSpan) => {
13
+ const unsubscribe = client.on('spanEnd', (endedSpan) => {
14
14
  if (span !== endedSpan) {
15
15
  return;
16
16
  }
17
+ unsubscribe();
17
18
  callback(endedSpan);
18
19
  });
19
20
  }
@@ -22,10 +23,11 @@ export const adjustTransactionDuration = (client, span, maxDurationMs) => {
22
23
  debug.warn('Not sampling empty back spans only works for Sentry Transactions (Root Spans).');
23
24
  return;
24
25
  }
25
- client.on('spanEnd', (endedSpan) => {
26
+ const unsubscribe = client.on('spanEnd', (endedSpan) => {
26
27
  if (endedSpan !== span) {
27
28
  return;
28
29
  }
30
+ unsubscribe();
29
31
  const endTimestamp = spanToJSON(span).timestamp;
30
32
  const startTimestamp = spanToJSON(span).start_timestamp;
31
33
  if (!endTimestamp || !startTimestamp) {
@@ -65,10 +67,11 @@ function discardEmptyNavigationSpan(client, span, shouldDiscardFn, onDiscardFn)
65
67
  debug.warn('Not sampling empty navigation spans only works for Sentry Transactions (Root Spans).');
66
68
  return;
67
69
  }
68
- client.on('spanEnd', (endedSpan) => {
70
+ const unsubscribe = client.on('spanEnd', (endedSpan) => {
69
71
  if (endedSpan !== span) {
70
72
  return;
71
73
  }
74
+ unsubscribe();
72
75
  if (!shouldDiscardFn(span)) {
73
76
  return;
74
77
  }
@@ -122,10 +125,11 @@ export const onlySampleIfChildSpans = (client, span) => {
122
125
  debug.warn('Not sampling childless spans only works for Sentry Transactions (Root Spans).');
123
126
  return;
124
127
  }
125
- client.on('spanEnd', (endedSpan) => {
128
+ const unsubscribe = client.on('spanEnd', (endedSpan) => {
126
129
  if (endedSpan !== span) {
127
130
  return;
128
131
  }
132
+ unsubscribe();
129
133
  const children = getSpanDescendants(span);
130
134
  if (children.length <= 1) {
131
135
  // Span always has at lest one child, itself
@@ -175,17 +179,20 @@ export const cancelInBackground = (client, span) => {
175
179
  }
176
180
  }
177
181
  });
178
- subscription &&
179
- client.on('spanEnd', (endedSpan) => {
182
+ if (subscription) {
183
+ const unsubscribe = client.on('spanEnd', (endedSpan) => {
180
184
  var _a;
181
- if (endedSpan === span) {
182
- debug.log(`Removing AppState listener for ${spanToJSON(span).op} transaction.`);
183
- if (inactiveTimeout !== undefined) {
184
- clearTimeout(inactiveTimeout);
185
- inactiveTimeout = undefined;
186
- }
187
- (_a = subscription === null || subscription === void 0 ? void 0 : subscription.remove) === null || _a === void 0 ? void 0 : _a.call(subscription);
185
+ if (endedSpan !== span) {
186
+ return;
188
187
  }
188
+ unsubscribe();
189
+ debug.log(`Removing AppState listener for ${spanToJSON(span).op} transaction.`);
190
+ if (inactiveTimeout !== undefined) {
191
+ clearTimeout(inactiveTimeout);
192
+ inactiveTimeout = undefined;
193
+ }
194
+ (_a = subscription.remove) === null || _a === void 0 ? void 0 : _a.call(subscription);
189
195
  });
196
+ }
190
197
  };
191
198
  //# sourceMappingURL=onSpanEndUtils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"onSpanEndUtils.js","sourceRoot":"","sources":["../../../src/js/tracing/onSpanEndUtils.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Client, Span } from '@sentry/core';\nimport { debug, getSpanDescendants, SPAN_STATUS_ERROR, spanToJSON } from '@sentry/core';\nimport type { AppStateStatus } from 'react-native';\nimport { AppState, Platform } from 'react-native';\nimport { isRootSpan, isSentrySpan } from '../utils/span';\n\n/**\n * The time to wait after the app enters the `inactive` state on iOS before\n * cancelling the span.\n */\nconst IOS_INACTIVE_CANCEL_DELAY_MS = 5_000;\n\n/**\n * Hooks on span end event to execute a callback when the span ends.\n */\nexport function onThisSpanEnd(client: Client, span: Span, callback: (span: Span) => void): void {\n client.on('spanEnd', (endedSpan: Span) => {\n if (span !== endedSpan) {\n return;\n }\n callback(endedSpan);\n });\n}\n\nexport const adjustTransactionDuration = (client: Client, span: Span, maxDurationMs: number): void => {\n if (!isRootSpan(span)) {\n debug.warn('Not sampling empty back spans only works for Sentry Transactions (Root Spans).');\n return;\n }\n\n client.on('spanEnd', (endedSpan: Span) => {\n if (endedSpan !== span) {\n return;\n }\n\n const endTimestamp = spanToJSON(span).timestamp;\n const startTimestamp = spanToJSON(span).start_timestamp;\n if (!endTimestamp || !startTimestamp) {\n return;\n }\n\n const diff = endTimestamp - startTimestamp; // a diff in *seconds*\n const isOutdatedTransaction = diff > maxDurationMs / 1000 || diff < 0;\n\n if (isOutdatedTransaction) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'deadline_exceeded' });\n // TODO: check where was used, might be possible to delete\n span.setAttribute('maxTransactionDurationExceeded', 'true');\n }\n });\n};\n\n/**\n * Helper function to filter out auto-instrumentation child spans.\n */\nfunction getMeaningfulChildSpans(span: Span): Span[] {\n const children = getSpanDescendants(span);\n return children.filter(\n child =>\n child.spanContext().spanId !== span.spanContext().spanId &&\n spanToJSON(child).op !== 'ui.load.initial_display' &&\n spanToJSON(child).op !== 'navigation.processing',\n );\n}\n\n/**\n * Generic helper to discard empty navigation spans based on a condition.\n */\nfunction discardEmptyNavigationSpan(\n client: Client | undefined,\n span: Span | undefined,\n shouldDiscardFn: (span: Span) => boolean,\n onDiscardFn: (span: Span) => void,\n): void {\n if (!client) {\n debug.warn('Could not hook on spanEnd event because client is not defined.');\n return;\n }\n\n if (!span) {\n debug.warn('Could not hook on spanEnd event because span is not defined.');\n return;\n }\n\n if (!isRootSpan(span) || !isSentrySpan(span)) {\n debug.warn('Not sampling empty navigation spans only works for Sentry Transactions (Root Spans).');\n return;\n }\n\n client.on('spanEnd', (endedSpan: Span) => {\n if (endedSpan !== span) {\n return;\n }\n\n if (!shouldDiscardFn(span)) {\n return;\n }\n\n const meaningfulChildren = getMeaningfulChildSpans(span);\n if (meaningfulChildren.length <= 0) {\n onDiscardFn(span);\n span['_sampled'] = false;\n }\n });\n}\n\nexport const ignoreEmptyBackNavigation = (client: Client | undefined, span: Span | undefined): void => {\n discardEmptyNavigationSpan(\n client,\n span,\n // Only discard if route has been seen before\n span => spanToJSON(span).data?.['route.has_been_seen'] === true,\n // Log message when discarding\n () => {\n debug.log(\n 'Not sampling transaction as route has been seen before. Pass ignoreEmptyBackNavigationTransactions = false to disable this feature.',\n );\n },\n );\n};\n\n/**\n * Discards empty \"Route Change\" transactions that never received route information.\n * This happens when navigation library emits a route change event but getCurrentRoute() returns undefined.\n * Such transactions don't contain any useful information and should not be sent to Sentry.\n *\n * This function must be called with a reference tracker function that can check if the span\n * was cleared from the integration's tracking (indicating it went through the state listener).\n */\nexport const ignoreEmptyRouteChangeTransactions = (\n client: Client | undefined,\n span: Span | undefined,\n defaultNavigationSpanName: string,\n isSpanStillTracked: () => boolean,\n): void => {\n discardEmptyNavigationSpan(\n client,\n span,\n // Only discard if:\n // 1. Still has default name\n // 2. No route information was set\n // 3. Still being tracked (state listener never called)\n span => {\n const spanJSON = spanToJSON(span);\n return (\n spanJSON.description === defaultNavigationSpanName && !spanJSON.data?.['route.name'] && isSpanStillTracked()\n );\n },\n // Log and record dropped event\n _span => {\n debug.log(`Discarding empty \"${defaultNavigationSpanName}\" transaction that never received route information.`);\n client?.recordDroppedEvent('sample_rate', 'transaction');\n },\n );\n};\n\n/**\n * Idle Transaction callback to only sample transactions with child spans.\n * To avoid side effects of other callbacks this should be hooked as the last callback.\n */\nexport const onlySampleIfChildSpans = (client: Client, span: Span): void => {\n if (!isRootSpan(span) || !isSentrySpan(span)) {\n debug.warn('Not sampling childless spans only works for Sentry Transactions (Root Spans).');\n return;\n }\n\n client.on('spanEnd', (endedSpan: Span) => {\n if (endedSpan !== span) {\n return;\n }\n\n const children = getSpanDescendants(span);\n\n if (children.length <= 1) {\n // Span always has at lest one child, itself\n debug.log(`Not sampling as ${spanToJSON(span).op} transaction has no child spans.`);\n span['_sampled'] = false;\n }\n });\n};\n\n/**\n * Hooks on AppState change to cancel the span if the app goes background.\n *\n * On iOS the JS thread can be suspended between the `inactive` and\n * `background` transitions, which means the `background` event may never\n * reach JS in time. To handle this we schedule a deferred cancellation when\n * the app becomes `inactive`. If the app returns to `active` before the\n * timeout fires, the cancellation is cleared. If it transitions to\n * `background` first, we cancel immediately and clear the timeout.\n */\nexport const cancelInBackground = (client: Client, span: Span): void => {\n let inactiveTimeout: ReturnType<typeof setTimeout> | undefined;\n\n const cancelSpan = (): void => {\n if (inactiveTimeout !== undefined) {\n clearTimeout(inactiveTimeout);\n inactiveTimeout = undefined;\n }\n debug.log(`Setting ${spanToJSON(span).op} transaction to cancelled because the app is in the background.`);\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'cancelled' });\n span.end();\n };\n\n const subscription = AppState.addEventListener('change', (newState: AppStateStatus) => {\n if (newState === 'background') {\n cancelSpan();\n } else if (Platform.OS === 'ios' && newState === 'inactive') {\n // Schedule a deferred cancellation — if the JS thread is suspended\n // before the 'background' event fires, this timer will execute when\n // the app is eventually resumed and end the span.\n if (inactiveTimeout === undefined) {\n inactiveTimeout = setTimeout(cancelSpan, IOS_INACTIVE_CANCEL_DELAY_MS);\n }\n } else if (newState === 'active') {\n // App returned to foreground — clear any pending inactive cancellation.\n if (inactiveTimeout !== undefined) {\n clearTimeout(inactiveTimeout);\n inactiveTimeout = undefined;\n }\n }\n });\n\n subscription &&\n client.on('spanEnd', (endedSpan: Span) => {\n if (endedSpan === span) {\n debug.log(`Removing AppState listener for ${spanToJSON(span).op} transaction.`);\n if (inactiveTimeout !== undefined) {\n clearTimeout(inactiveTimeout);\n inactiveTimeout = undefined;\n }\n subscription?.remove?.();\n }\n });\n};\n"]}
1
+ {"version":3,"file":"onSpanEndUtils.js","sourceRoot":"","sources":["../../../src/js/tracing/onSpanEndUtils.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Client, Span } from '@sentry/core';\nimport { debug, getSpanDescendants, SPAN_STATUS_ERROR, spanToJSON } from '@sentry/core';\nimport type { AppStateStatus } from 'react-native';\nimport { AppState, Platform } from 'react-native';\nimport { isRootSpan, isSentrySpan } from '../utils/span';\n\n/**\n * The time to wait after the app enters the `inactive` state on iOS before\n * cancelling the span.\n */\nconst IOS_INACTIVE_CANCEL_DELAY_MS = 5_000;\n\n/**\n * Hooks on span end event to execute a callback when the span ends.\n */\nexport function onThisSpanEnd(client: Client, span: Span, callback: (span: Span) => void): void {\n const unsubscribe = client.on('spanEnd', (endedSpan: Span) => {\n if (span !== endedSpan) {\n return;\n }\n unsubscribe();\n callback(endedSpan);\n });\n}\n\nexport const adjustTransactionDuration = (client: Client, span: Span, maxDurationMs: number): void => {\n if (!isRootSpan(span)) {\n debug.warn('Not sampling empty back spans only works for Sentry Transactions (Root Spans).');\n return;\n }\n\n const unsubscribe = client.on('spanEnd', (endedSpan: Span) => {\n if (endedSpan !== span) {\n return;\n }\n unsubscribe();\n\n const endTimestamp = spanToJSON(span).timestamp;\n const startTimestamp = spanToJSON(span).start_timestamp;\n if (!endTimestamp || !startTimestamp) {\n return;\n }\n\n const diff = endTimestamp - startTimestamp; // a diff in *seconds*\n const isOutdatedTransaction = diff > maxDurationMs / 1000 || diff < 0;\n\n if (isOutdatedTransaction) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'deadline_exceeded' });\n // TODO: check where was used, might be possible to delete\n span.setAttribute('maxTransactionDurationExceeded', 'true');\n }\n });\n};\n\n/**\n * Helper function to filter out auto-instrumentation child spans.\n */\nfunction getMeaningfulChildSpans(span: Span): Span[] {\n const children = getSpanDescendants(span);\n return children.filter(\n child =>\n child.spanContext().spanId !== span.spanContext().spanId &&\n spanToJSON(child).op !== 'ui.load.initial_display' &&\n spanToJSON(child).op !== 'navigation.processing',\n );\n}\n\n/**\n * Generic helper to discard empty navigation spans based on a condition.\n */\nfunction discardEmptyNavigationSpan(\n client: Client | undefined,\n span: Span | undefined,\n shouldDiscardFn: (span: Span) => boolean,\n onDiscardFn: (span: Span) => void,\n): void {\n if (!client) {\n debug.warn('Could not hook on spanEnd event because client is not defined.');\n return;\n }\n\n if (!span) {\n debug.warn('Could not hook on spanEnd event because span is not defined.');\n return;\n }\n\n if (!isRootSpan(span) || !isSentrySpan(span)) {\n debug.warn('Not sampling empty navigation spans only works for Sentry Transactions (Root Spans).');\n return;\n }\n\n const unsubscribe = client.on('spanEnd', (endedSpan: Span) => {\n if (endedSpan !== span) {\n return;\n }\n unsubscribe();\n\n if (!shouldDiscardFn(span)) {\n return;\n }\n\n const meaningfulChildren = getMeaningfulChildSpans(span);\n if (meaningfulChildren.length <= 0) {\n onDiscardFn(span);\n span['_sampled'] = false;\n }\n });\n}\n\nexport const ignoreEmptyBackNavigation = (client: Client | undefined, span: Span | undefined): void => {\n discardEmptyNavigationSpan(\n client,\n span,\n // Only discard if route has been seen before\n span => spanToJSON(span).data?.['route.has_been_seen'] === true,\n // Log message when discarding\n () => {\n debug.log(\n 'Not sampling transaction as route has been seen before. Pass ignoreEmptyBackNavigationTransactions = false to disable this feature.',\n );\n },\n );\n};\n\n/**\n * Discards empty \"Route Change\" transactions that never received route information.\n * This happens when navigation library emits a route change event but getCurrentRoute() returns undefined.\n * Such transactions don't contain any useful information and should not be sent to Sentry.\n *\n * This function must be called with a reference tracker function that can check if the span\n * was cleared from the integration's tracking (indicating it went through the state listener).\n */\nexport const ignoreEmptyRouteChangeTransactions = (\n client: Client | undefined,\n span: Span | undefined,\n defaultNavigationSpanName: string,\n isSpanStillTracked: () => boolean,\n): void => {\n discardEmptyNavigationSpan(\n client,\n span,\n // Only discard if:\n // 1. Still has default name\n // 2. No route information was set\n // 3. Still being tracked (state listener never called)\n span => {\n const spanJSON = spanToJSON(span);\n return (\n spanJSON.description === defaultNavigationSpanName && !spanJSON.data?.['route.name'] && isSpanStillTracked()\n );\n },\n // Log and record dropped event\n _span => {\n debug.log(`Discarding empty \"${defaultNavigationSpanName}\" transaction that never received route information.`);\n client?.recordDroppedEvent('sample_rate', 'transaction');\n },\n );\n};\n\n/**\n * Idle Transaction callback to only sample transactions with child spans.\n * To avoid side effects of other callbacks this should be hooked as the last callback.\n */\nexport const onlySampleIfChildSpans = (client: Client, span: Span): void => {\n if (!isRootSpan(span) || !isSentrySpan(span)) {\n debug.warn('Not sampling childless spans only works for Sentry Transactions (Root Spans).');\n return;\n }\n\n const unsubscribe = client.on('spanEnd', (endedSpan: Span) => {\n if (endedSpan !== span) {\n return;\n }\n unsubscribe();\n\n const children = getSpanDescendants(span);\n\n if (children.length <= 1) {\n // Span always has at lest one child, itself\n debug.log(`Not sampling as ${spanToJSON(span).op} transaction has no child spans.`);\n span['_sampled'] = false;\n }\n });\n};\n\n/**\n * Hooks on AppState change to cancel the span if the app goes background.\n *\n * On iOS the JS thread can be suspended between the `inactive` and\n * `background` transitions, which means the `background` event may never\n * reach JS in time. To handle this we schedule a deferred cancellation when\n * the app becomes `inactive`. If the app returns to `active` before the\n * timeout fires, the cancellation is cleared. If it transitions to\n * `background` first, we cancel immediately and clear the timeout.\n */\nexport const cancelInBackground = (client: Client, span: Span): void => {\n let inactiveTimeout: ReturnType<typeof setTimeout> | undefined;\n\n const cancelSpan = (): void => {\n if (inactiveTimeout !== undefined) {\n clearTimeout(inactiveTimeout);\n inactiveTimeout = undefined;\n }\n debug.log(`Setting ${spanToJSON(span).op} transaction to cancelled because the app is in the background.`);\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'cancelled' });\n span.end();\n };\n\n const subscription = AppState.addEventListener('change', (newState: AppStateStatus) => {\n if (newState === 'background') {\n cancelSpan();\n } else if (Platform.OS === 'ios' && newState === 'inactive') {\n // Schedule a deferred cancellation — if the JS thread is suspended\n // before the 'background' event fires, this timer will execute when\n // the app is eventually resumed and end the span.\n if (inactiveTimeout === undefined) {\n inactiveTimeout = setTimeout(cancelSpan, IOS_INACTIVE_CANCEL_DELAY_MS);\n }\n } else if (newState === 'active') {\n // App returned to foreground — clear any pending inactive cancellation.\n if (inactiveTimeout !== undefined) {\n clearTimeout(inactiveTimeout);\n inactiveTimeout = undefined;\n }\n }\n });\n\n if (subscription) {\n const unsubscribe = client.on('spanEnd', (endedSpan: Span) => {\n if (endedSpan !== span) {\n return;\n }\n unsubscribe();\n debug.log(`Removing AppState listener for ${spanToJSON(span).op} transaction.`);\n if (inactiveTimeout !== undefined) {\n clearTimeout(inactiveTimeout);\n inactiveTimeout = undefined;\n }\n subscription.remove?.();\n });\n }\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"reactnativenavigation.d.ts","sourceRoot":"","sources":["../../../src/js/tracing/reactnativenavigation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAU,WAAW,EAAQ,MAAM,cAAc,CAAC;AAS9D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AAazE,eAAO,MAAM,gBAAgB,0BAA0B,CAAC;AAIxD,UAAU,4BAA4B;IACpC;;;;;OAKG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAE9B;;;;;OAKG;IACH,yBAAyB,CAAC,EAAE,OAAO,CAAC;IAEpC;;;;;OAKG;IACH,qCAAqC,CAAC,EAAE,OAAO,CAAC;IAEhD;;;;;OAKG;IACH,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,UAAU,cAAc;IACtB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,KAAK,aAAa,GAAG,WAAW,GAAG,aAAa,GAAG,kBAAkB,GAAG,cAAc,CAAC;AAEvF,MAAM,WAAW,wBAAyB,SAAQ,cAAc;IAC9D,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,GAAG,MAAM,GAAG,MAAM,EAAE,OAAO,CAAC,CAAC;IACtD,aAAa,EAAE,aAAa,CAAC;CAC9B;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,IAAI,IAAI,CAAC;CAChB;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,mCAAmC,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,wBAAwB,KAAK,IAAI,GAAG,mBAAmB,CAAC;IAC9G,uBAAuB,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,KAAK,IAAI,GAAG,iBAAiB,CAAC;IAC9F,gCAAgC,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,qBAAqB,KAAK,IAAI,GAAG,mBAAmB,CAAC;CACzG;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,cAAc,CAAC;CAC9B;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,gCAAgC,+HAK1C,4BAA4B,KAAG,WA0IjC,CAAC"}
1
+ {"version":3,"file":"reactnativenavigation.d.ts","sourceRoot":"","sources":["../../../src/js/tracing/reactnativenavigation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAU,WAAW,EAAQ,MAAM,cAAc,CAAC;AAS9D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AAazE,eAAO,MAAM,gBAAgB,0BAA0B,CAAC;AAIxD,UAAU,4BAA4B;IACpC;;;;;OAKG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAE9B;;;;;OAKG;IACH,yBAAyB,CAAC,EAAE,OAAO,CAAC;IAEpC;;;;;OAKG;IACH,qCAAqC,CAAC,EAAE,OAAO,CAAC;IAEhD;;;;;OAKG;IACH,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,UAAU,cAAc;IACtB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,KAAK,aAAa,GAAG,WAAW,GAAG,aAAa,GAAG,kBAAkB,GAAG,cAAc,CAAC;AAEvF,MAAM,WAAW,wBAAyB,SAAQ,cAAc;IAC9D,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,GAAG,MAAM,GAAG,MAAM,EAAE,OAAO,CAAC,CAAC;IACtD,aAAa,EAAE,aAAa,CAAC;CAC9B;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,IAAI,IAAI,CAAC;CAChB;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,mCAAmC,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,wBAAwB,KAAK,IAAI,GAAG,mBAAmB,CAAC;IAC9G,uBAAuB,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,KAAK,IAAI,GAAG,iBAAiB,CAAC;IAC9F,gCAAgC,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,qBAAqB,KAAK,IAAI,GAAG,mBAAmB,CAAC;CACzG;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,cAAc,CAAC;CAC9B;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,gCAAgC,GAAI,4HAK9C,4BAA4B,KAAG,WA0IjC,CAAC"}
@@ -52,7 +52,7 @@ export const reactNativeNavigationIntegration = ({ navigation: optionsNavigation
52
52
  return;
53
53
  }
54
54
  // We ignore actions that pertain to the same screen.
55
- const isSameComponent = prevComponentEvent && event.componentId === prevComponentEvent.componentId;
55
+ const isSameComponent = event.componentId === (prevComponentEvent === null || prevComponentEvent === void 0 ? void 0 : prevComponentEvent.componentId);
56
56
  if (isSameComponent) {
57
57
  discardLatestNavigationSpan();
58
58
  return;
@@ -1 +1 @@
1
- {"version":3,"file":"reactnativenavigation.js","sourceRoot":"","sources":["../../../src/js/tracing/reactnativenavigation.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Client, Integration, Span } from '@sentry/core';\nimport {\n addBreadcrumb,\n getClient,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n spanToJSON,\n} from '@sentry/core';\nimport type { EmitterSubscription } from '../utils/rnlibrariesinterface';\nimport { isSentrySpan } from '../utils/span';\nimport { ignoreEmptyBackNavigation, ignoreEmptyRouteChangeTransactions } from './onSpanEndUtils';\nimport { SPAN_ORIGIN_AUTO_NAVIGATION_REACT_NATIVE_NAVIGATION } from './origin';\nimport type { ReactNativeTracingIntegration } from './reactnativetracing';\nimport { getReactNativeTracingIntegration } from './reactnativetracing';\nimport {\n DEFAULT_NAVIGATION_SPAN_NAME,\n defaultIdleOptions,\n getDefaultIdleNavigationSpanOptions,\n startIdleNavigationSpan as startGenericIdleNavigationSpan,\n} from './span';\n\nexport const INTEGRATION_NAME = 'ReactNativeNavigation';\n\nconst NAVIGATION_HISTORY_MAX_SIZE = 200;\n\ninterface ReactNativeNavigationOptions {\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 * Instrumentation will create a transaction on tab change.\n * By default only navigation commands create transactions.\n *\n * @default false\n */\n enableTabsInstrumentation?: 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 /** The React Native Navigation `NavigationDelegate`.\n *\n * ```js\n * import { Navigation } from 'react-native-navigation';\n * ```\n */\n navigation: unknown;\n}\n\ninterface ComponentEvent {\n componentId: string;\n}\n\ntype ComponentType = 'Component' | 'TopBarTitle' | 'TopBarBackground' | 'TopBarButton';\n\nexport interface ComponentWillAppearEvent extends ComponentEvent {\n componentName: string;\n passProps?: Record<string | number | symbol, unknown>;\n componentType: ComponentType;\n}\n\nexport interface EventSubscription {\n remove(): void;\n}\n\nexport interface BottomTabPressedEvent {\n tabIndex: number;\n}\n\nexport interface EventsRegistry {\n registerComponentWillAppearListener(callback: (event: ComponentWillAppearEvent) => void): EmitterSubscription;\n registerCommandListener(callback: (name: string, params: unknown) => void): EventSubscription;\n registerBottomTabPressedListener(callback: (event: BottomTabPressedEvent) => void): EmitterSubscription;\n}\n\nexport interface NavigationDelegate {\n events: () => EventsRegistry;\n}\n\n/**\n * Instrumentation for React Native Navigation. See docs or sample app for usage.\n *\n * How this works:\n * - `_onCommand` is called every time a commands happens and sets an IdleTransaction on the scope without any route context.\n * - `_onComponentWillAppear` is then called AFTER the state change happens due to a dispatch and sets the route context onto the active transaction.\n * - If `_onComponentWillAppear` isn't called within `options.routeChangeTimeoutMs` of the dispatch, then the transaction is not sampled and finished.\n */\nexport const reactNativeNavigationIntegration = ({\n navigation: optionsNavigation,\n routeChangeTimeoutMs = 1_000,\n enableTabsInstrumentation = false,\n ignoreEmptyBackNavigationTransactions = true,\n}: ReactNativeNavigationOptions): Integration => {\n const navigation = optionsNavigation as NavigationDelegate;\n let recentComponentIds: string[] = [];\n\n let tracing: ReactNativeTracingIntegration | undefined;\n let idleSpanOptions: Parameters<typeof startGenericIdleNavigationSpan>[1] = defaultIdleOptions;\n\n let stateChangeTimeout: ReturnType<typeof setTimeout> | undefined;\n let prevComponentEvent: ComponentWillAppearEvent | null = null;\n let latestNavigationSpan: Span | undefined;\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\n const startIdleNavigationSpan = (): void => {\n if (latestNavigationSpan) {\n discardLatestNavigationSpan();\n }\n\n latestNavigationSpan = startGenericIdleNavigationSpan(\n tracing?.options.beforeStartSpan\n ? tracing.options.beforeStartSpan(getDefaultIdleNavigationSpanOptions())\n : getDefaultIdleNavigationSpanOptions(),\n idleSpanOptions,\n );\n latestNavigationSpan?.setAttribute(\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SPAN_ORIGIN_AUTO_NAVIGATION_REACT_NATIVE_NAVIGATION,\n );\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 stateChangeTimeout = setTimeout(discardLatestNavigationSpan.bind(this), routeChangeTimeoutMs);\n };\n\n const updateLatestNavigationSpanWithCurrentComponent = (event: ComponentWillAppearEvent): void => {\n if (!latestNavigationSpan) {\n return;\n }\n\n // We ignore actions that pertain to the same screen.\n const isSameComponent = prevComponentEvent && event.componentId === prevComponentEvent.componentId;\n if (isSameComponent) {\n discardLatestNavigationSpan();\n return;\n }\n\n clearStateChangeTimeout();\n\n const routeHasBeenSeen = recentComponentIds.includes(event.componentId);\n\n if (spanToJSON(latestNavigationSpan).description === DEFAULT_NAVIGATION_SPAN_NAME) {\n latestNavigationSpan.updateName(event.componentName);\n }\n latestNavigationSpan.setAttributes({\n // TODO: Should we include pass props? I don't know exactly what it contains, cant find it in the RNavigation docs\n 'route.name': event.componentName,\n 'route.component_id': event.componentId,\n 'route.component_type': event.componentType,\n 'route.has_been_seen': routeHasBeenSeen,\n 'previous_route.name': prevComponentEvent?.componentName,\n 'previous_route.component_id': prevComponentEvent?.componentId,\n 'previous_route.component_type': prevComponentEvent?.componentType,\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'component',\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'navigation',\n });\n\n tracing?.setCurrentRoute(event.componentName);\n\n addBreadcrumb({\n category: 'navigation',\n type: 'navigation',\n message: `Navigation to ${event.componentName}`,\n data: {\n from: prevComponentEvent?.componentName,\n to: event.componentName,\n },\n });\n\n pushRecentComponentId(event.componentId);\n prevComponentEvent = event;\n latestNavigationSpan = undefined;\n };\n\n navigation.events().registerCommandListener(startIdleNavigationSpan);\n if (enableTabsInstrumentation) {\n navigation.events().registerBottomTabPressedListener(startIdleNavigationSpan);\n }\n navigation.events().registerComponentWillAppearListener(updateLatestNavigationSpanWithCurrentComponent);\n\n const pushRecentComponentId = (id: string): void => {\n recentComponentIds.push(id);\n\n if (recentComponentIds.length > NAVIGATION_HISTORY_MAX_SIZE) {\n recentComponentIds = recentComponentIds.slice(recentComponentIds.length - NAVIGATION_HISTORY_MAX_SIZE);\n }\n };\n\n const discardLatestNavigationSpan = (): 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\n clearStateChangeTimeout();\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 };\n};\n"]}
1
+ {"version":3,"file":"reactnativenavigation.js","sourceRoot":"","sources":["../../../src/js/tracing/reactnativenavigation.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Client, Integration, Span } from '@sentry/core';\nimport {\n addBreadcrumb,\n getClient,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n spanToJSON,\n} from '@sentry/core';\nimport type { EmitterSubscription } from '../utils/rnlibrariesinterface';\nimport { isSentrySpan } from '../utils/span';\nimport { ignoreEmptyBackNavigation, ignoreEmptyRouteChangeTransactions } from './onSpanEndUtils';\nimport { SPAN_ORIGIN_AUTO_NAVIGATION_REACT_NATIVE_NAVIGATION } from './origin';\nimport type { ReactNativeTracingIntegration } from './reactnativetracing';\nimport { getReactNativeTracingIntegration } from './reactnativetracing';\nimport {\n DEFAULT_NAVIGATION_SPAN_NAME,\n defaultIdleOptions,\n getDefaultIdleNavigationSpanOptions,\n startIdleNavigationSpan as startGenericIdleNavigationSpan,\n} from './span';\n\nexport const INTEGRATION_NAME = 'ReactNativeNavigation';\n\nconst NAVIGATION_HISTORY_MAX_SIZE = 200;\n\ninterface ReactNativeNavigationOptions {\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 * Instrumentation will create a transaction on tab change.\n * By default only navigation commands create transactions.\n *\n * @default false\n */\n enableTabsInstrumentation?: 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 /** The React Native Navigation `NavigationDelegate`.\n *\n * ```js\n * import { Navigation } from 'react-native-navigation';\n * ```\n */\n navigation: unknown;\n}\n\ninterface ComponentEvent {\n componentId: string;\n}\n\ntype ComponentType = 'Component' | 'TopBarTitle' | 'TopBarBackground' | 'TopBarButton';\n\nexport interface ComponentWillAppearEvent extends ComponentEvent {\n componentName: string;\n passProps?: Record<string | number | symbol, unknown>;\n componentType: ComponentType;\n}\n\nexport interface EventSubscription {\n remove(): void;\n}\n\nexport interface BottomTabPressedEvent {\n tabIndex: number;\n}\n\nexport interface EventsRegistry {\n registerComponentWillAppearListener(callback: (event: ComponentWillAppearEvent) => void): EmitterSubscription;\n registerCommandListener(callback: (name: string, params: unknown) => void): EventSubscription;\n registerBottomTabPressedListener(callback: (event: BottomTabPressedEvent) => void): EmitterSubscription;\n}\n\nexport interface NavigationDelegate {\n events: () => EventsRegistry;\n}\n\n/**\n * Instrumentation for React Native Navigation. See docs or sample app for usage.\n *\n * How this works:\n * - `_onCommand` is called every time a commands happens and sets an IdleTransaction on the scope without any route context.\n * - `_onComponentWillAppear` is then called AFTER the state change happens due to a dispatch and sets the route context onto the active transaction.\n * - If `_onComponentWillAppear` isn't called within `options.routeChangeTimeoutMs` of the dispatch, then the transaction is not sampled and finished.\n */\nexport const reactNativeNavigationIntegration = ({\n navigation: optionsNavigation,\n routeChangeTimeoutMs = 1_000,\n enableTabsInstrumentation = false,\n ignoreEmptyBackNavigationTransactions = true,\n}: ReactNativeNavigationOptions): Integration => {\n const navigation = optionsNavigation as NavigationDelegate;\n let recentComponentIds: string[] = [];\n\n let tracing: ReactNativeTracingIntegration | undefined;\n let idleSpanOptions: Parameters<typeof startGenericIdleNavigationSpan>[1] = defaultIdleOptions;\n\n let stateChangeTimeout: ReturnType<typeof setTimeout> | undefined;\n let prevComponentEvent: ComponentWillAppearEvent | null = null;\n let latestNavigationSpan: Span | undefined;\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\n const startIdleNavigationSpan = (): void => {\n if (latestNavigationSpan) {\n discardLatestNavigationSpan();\n }\n\n latestNavigationSpan = startGenericIdleNavigationSpan(\n tracing?.options.beforeStartSpan\n ? tracing.options.beforeStartSpan(getDefaultIdleNavigationSpanOptions())\n : getDefaultIdleNavigationSpanOptions(),\n idleSpanOptions,\n );\n latestNavigationSpan?.setAttribute(\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SPAN_ORIGIN_AUTO_NAVIGATION_REACT_NATIVE_NAVIGATION,\n );\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 stateChangeTimeout = setTimeout(discardLatestNavigationSpan.bind(this), routeChangeTimeoutMs);\n };\n\n const updateLatestNavigationSpanWithCurrentComponent = (event: ComponentWillAppearEvent): void => {\n if (!latestNavigationSpan) {\n return;\n }\n\n // We ignore actions that pertain to the same screen.\n const isSameComponent = event.componentId === prevComponentEvent?.componentId;\n if (isSameComponent) {\n discardLatestNavigationSpan();\n return;\n }\n\n clearStateChangeTimeout();\n\n const routeHasBeenSeen = recentComponentIds.includes(event.componentId);\n\n if (spanToJSON(latestNavigationSpan).description === DEFAULT_NAVIGATION_SPAN_NAME) {\n latestNavigationSpan.updateName(event.componentName);\n }\n latestNavigationSpan.setAttributes({\n // TODO: Should we include pass props? I don't know exactly what it contains, cant find it in the RNavigation docs\n 'route.name': event.componentName,\n 'route.component_id': event.componentId,\n 'route.component_type': event.componentType,\n 'route.has_been_seen': routeHasBeenSeen,\n 'previous_route.name': prevComponentEvent?.componentName,\n 'previous_route.component_id': prevComponentEvent?.componentId,\n 'previous_route.component_type': prevComponentEvent?.componentType,\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'component',\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'navigation',\n });\n\n tracing?.setCurrentRoute(event.componentName);\n\n addBreadcrumb({\n category: 'navigation',\n type: 'navigation',\n message: `Navigation to ${event.componentName}`,\n data: {\n from: prevComponentEvent?.componentName,\n to: event.componentName,\n },\n });\n\n pushRecentComponentId(event.componentId);\n prevComponentEvent = event;\n latestNavigationSpan = undefined;\n };\n\n navigation.events().registerCommandListener(startIdleNavigationSpan);\n if (enableTabsInstrumentation) {\n navigation.events().registerBottomTabPressedListener(startIdleNavigationSpan);\n }\n navigation.events().registerComponentWillAppearListener(updateLatestNavigationSpanWithCurrentComponent);\n\n const pushRecentComponentId = (id: string): void => {\n recentComponentIds.push(id);\n\n if (recentComponentIds.length > NAVIGATION_HISTORY_MAX_SIZE) {\n recentComponentIds = recentComponentIds.slice(recentComponentIds.length - NAVIGATION_HISTORY_MAX_SIZE);\n }\n };\n\n const discardLatestNavigationSpan = (): 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\n clearStateChangeTimeout();\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 };\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"reactnativeprofiler.js","sourceRoot":"","sources":["../../../src/js/tracing/reactnativeprofiler.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACzD,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,oCAAoC,EAAE,MAAM,kCAAkC,CAAC;AAE1G,MAAM,8BAA8B,GAAG;IACrC,gBAAgB,EAAE,KAAK;IACvB,oBAAoB,EAAE,GAAG,EAAE;QACzB,8BAA8B,CAAC,gBAAgB,GAAG,KAAK,CAAC;IAC1D,CAAC;CACF,CAAC;AAIF;;GAEG;AACH,MAAM,OAAO,mBAAoB,SAAQ,QAAQ;IAG/C,YAAmB,KAA+B;QAChD,oCAAoC,CAAC,kBAAkB,EAAE,GAAG,IAAI,CAAC,CAAC;QAClE,KAAK,CAAC,KAAK,CAAC,CAAC;QAJC,SAAI,GAAW,qBAAqB,CAAC;IAKrD,CAAC;IAED;;OAEG;IACI,iBAAiB;QACtB,KAAK,CAAC,iBAAiB,EAAE,CAAC;QAC1B,IAAI,CAAC,8BAA8B,CAAC,gBAAgB,EAAE;YACpD,IAAI,CAAC,eAAe,EAAE,CAAC;YACvB,8BAA8B,CAAC,gBAAgB,GAAG,IAAI,CAAC;SACxD;IACH,CAAC;IAED;;OAEG;IACK,eAAe;;QACrB,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;QAE3B,IAAI,CAAC,MAAM,EAAE;YACX,iFAAiF;YACjF,sCAAsC;YACtC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,sFAAsF,CAAC,CAAC;YAChH,OAAO;SACR;QAED,MAAA,MAAM,CAAC,cAAc,uDAAG,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAEtD,MAAM,sBAAsB,GAAG,yBAAyB,CAAC,MAAM,CAAC,CAAC;QACjE,IAAI,sBAAsB,IAAI,OAAO,sBAAsB,CAAC,gBAAgB,KAAK,UAAU,EAAE;YAC3F,sBAAsB,CAAC,gBAAgB,CAAC,8BAA8B,CAAC,oBAAoB,CAAC,CAAC;SAC9F;aAAM;YACL,KAAK,CAAC,IAAI,CAAC,+DAA+D,CAAC,CAAC;SAC7E;QAED,mEAAmE;QACnE,gBAAgB,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;IACxC,CAAC;CACF","sourcesContent":["import { debug, timestampInSeconds } from '@sentry/core';\nimport { getClient, Profiler } from '@sentry/react';\nimport { getAppRegistryIntegration } from '../integrations/appRegistry';\nimport { createIntegration } from '../integrations/factory';\nimport { _captureAppStart, _setRootComponentCreationTimestampMs } from '../tracing/integrations/appStart';\n\nconst ReactNativeProfilerGlobalState = {\n appStartReported: false,\n onRunApplicationHook: () => {\n ReactNativeProfilerGlobalState.appStartReported = false;\n },\n};\n\ntype ProfilerConstructorProps = ConstructorParameters<typeof Profiler>[0];\n\n/**\n * Custom profiler for the React Native app root.\n */\nexport class ReactNativeProfiler extends Profiler {\n public readonly name: string = 'ReactNativeProfiler';\n\n public constructor(props: ProfilerConstructorProps) {\n _setRootComponentCreationTimestampMs(timestampInSeconds() * 1000);\n super(props);\n }\n\n /**\n * Get the app root mount time.\n */\n public componentDidMount(): void {\n super.componentDidMount();\n if (!ReactNativeProfilerGlobalState.appStartReported) {\n this._reportAppStart();\n ReactNativeProfilerGlobalState.appStartReported = true;\n }\n }\n\n /**\n * Notifies the Tracing integration that the app start has finished.\n */\n private _reportAppStart(): void {\n const client = getClient();\n\n if (!client) {\n // We can't use logger here because this will be logged before the `Sentry.init`.\n // eslint-disable-next-line no-console\n __DEV__ && console.warn('App Start Span could not be finished. `Sentry.wrap` was called before `Sentry.init`.');\n return;\n }\n\n client.addIntegration?.(createIntegration(this.name));\n\n const appRegistryIntegration = getAppRegistryIntegration(client);\n if (appRegistryIntegration && typeof appRegistryIntegration.onRunApplication === 'function') {\n appRegistryIntegration.onRunApplication(ReactNativeProfilerGlobalState.onRunApplicationHook);\n } else {\n debug.warn('AppRegistryIntegration.onRunApplication not found or invalid.');\n }\n\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n _captureAppStart({ isManual: false });\n }\n}\n"]}
1
+ {"version":3,"file":"reactnativeprofiler.js","sourceRoot":"","sources":["../../../src/js/tracing/reactnativeprofiler.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACzD,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,oCAAoC,EAAE,MAAM,kCAAkC,CAAC;AAE1G,MAAM,8BAA8B,GAAG;IACrC,gBAAgB,EAAE,KAAK;IACvB,oBAAoB,EAAE,GAAG,EAAE;QACzB,8BAA8B,CAAC,gBAAgB,GAAG,KAAK,CAAC;IAC1D,CAAC;CACF,CAAC;AAIF;;GAEG;AACH,MAAM,OAAO,mBAAoB,SAAQ,QAAQ;IAG/C,YAAmB,KAA+B;QAChD,oCAAoC,CAAC,kBAAkB,EAAE,GAAG,IAAI,CAAC,CAAC;QAClE,KAAK,CAAC,KAAK,CAAC,CAAC;QAJC,SAAI,GAAW,qBAAqB,CAAC;IAKrD,CAAC;IAED;;OAEG;IACI,iBAAiB;QACtB,KAAK,CAAC,iBAAiB,EAAE,CAAC;QAC1B,IAAI,CAAC,8BAA8B,CAAC,gBAAgB,EAAE,CAAC;YACrD,IAAI,CAAC,eAAe,EAAE,CAAC;YACvB,8BAA8B,CAAC,gBAAgB,GAAG,IAAI,CAAC;QACzD,CAAC;IACH,CAAC;IAED;;OAEG;IACK,eAAe;;QACrB,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;QAE3B,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,iFAAiF;YACjF,sCAAsC;YACtC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,sFAAsF,CAAC,CAAC;YAChH,OAAO;QACT,CAAC;QAED,MAAA,MAAM,CAAC,cAAc,uDAAG,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAEtD,MAAM,sBAAsB,GAAG,yBAAyB,CAAC,MAAM,CAAC,CAAC;QACjE,IAAI,sBAAsB,IAAI,OAAO,sBAAsB,CAAC,gBAAgB,KAAK,UAAU,EAAE,CAAC;YAC5F,sBAAsB,CAAC,gBAAgB,CAAC,8BAA8B,CAAC,oBAAoB,CAAC,CAAC;QAC/F,CAAC;aAAM,CAAC;YACN,KAAK,CAAC,IAAI,CAAC,+DAA+D,CAAC,CAAC;QAC9E,CAAC;QAED,mEAAmE;QACnE,gBAAgB,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;IACxC,CAAC;CACF","sourcesContent":["import { debug, timestampInSeconds } from '@sentry/core';\nimport { getClient, Profiler } from '@sentry/react';\nimport { getAppRegistryIntegration } from '../integrations/appRegistry';\nimport { createIntegration } from '../integrations/factory';\nimport { _captureAppStart, _setRootComponentCreationTimestampMs } from '../tracing/integrations/appStart';\n\nconst ReactNativeProfilerGlobalState = {\n appStartReported: false,\n onRunApplicationHook: () => {\n ReactNativeProfilerGlobalState.appStartReported = false;\n },\n};\n\ntype ProfilerConstructorProps = ConstructorParameters<typeof Profiler>[0];\n\n/**\n * Custom profiler for the React Native app root.\n */\nexport class ReactNativeProfiler extends Profiler {\n public readonly name: string = 'ReactNativeProfiler';\n\n public constructor(props: ProfilerConstructorProps) {\n _setRootComponentCreationTimestampMs(timestampInSeconds() * 1000);\n super(props);\n }\n\n /**\n * Get the app root mount time.\n */\n public componentDidMount(): void {\n super.componentDidMount();\n if (!ReactNativeProfilerGlobalState.appStartReported) {\n this._reportAppStart();\n ReactNativeProfilerGlobalState.appStartReported = true;\n }\n }\n\n /**\n * Notifies the Tracing integration that the app start has finished.\n */\n private _reportAppStart(): void {\n const client = getClient();\n\n if (!client) {\n // We can't use logger here because this will be logged before the `Sentry.init`.\n // eslint-disable-next-line no-console\n __DEV__ && console.warn('App Start Span could not be finished. `Sentry.wrap` was called before `Sentry.init`.');\n return;\n }\n\n client.addIntegration?.(createIntegration(this.name));\n\n const appRegistryIntegration = getAppRegistryIntegration(client);\n if (appRegistryIntegration && typeof appRegistryIntegration.onRunApplication === 'function') {\n appRegistryIntegration.onRunApplication(ReactNativeProfilerGlobalState.onRunApplicationHook);\n } else {\n debug.warn('AppRegistryIntegration.onRunApplication not found or invalid.');\n }\n\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n _captureAppStart({ isManual: false });\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"reactnativetracing.d.ts","sourceRoot":"","sources":["../../../src/js/tracing/reactnativetracing.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAS,WAAW,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAMjF,eAAO,MAAM,gBAAgB,uBAAuB,CAAC;AAErD,MAAM,WAAW,yBAAyB;IACxC;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;;;;OAKG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;;;;;;OAOG;IACH,UAAU,EAAE,OAAO,CAAC;IAEpB;;;;OAIG;IACH,QAAQ,EAAE,OAAO,CAAC;IAElB;;;;OAIG;IACH,iBAAiB,EAAE,OAAO,CAAC;IAE3B;;;OAGG;IACH,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,gBAAgB,CAAC;IAElE;;;;;OAKG;IACH,0BAA0B,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CAC/D;AASD,eAAO,MAAM,gCAAgC,EAAE,yBAQ9C,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;CAClC,CAAC;AAEF,eAAO,MAAM,6BAA6B,aAC/B,QAAQ,yBAAyB,CAAC;aAElC,yBAAyB;WAC3B,uBAAuB;6BACL,MAAM,KAAK,IAAI;CA8DzC,CAAC;AAEF,MAAM,MAAM,6BAA6B,GAAG,UAAU,CAAC,OAAO,6BAA6B,CAAC,CAAC;AAE7F;;GAEG;AACH,wBAAgB,uCAAuC,IAAI,6BAA6B,GAAG,SAAS,CAOnG;AAED;;GAEG;AACH,wBAAgB,gCAAgC,CAAC,MAAM,EAAE,MAAM,GAAG,6BAA6B,GAAG,SAAS,CAE1G"}
1
+ {"version":3,"file":"reactnativetracing.d.ts","sourceRoot":"","sources":["../../../src/js/tracing/reactnativetracing.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAS,WAAW,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAMjF,eAAO,MAAM,gBAAgB,uBAAuB,CAAC;AAErD,MAAM,WAAW,yBAAyB;IACxC;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;;;;OAKG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;;;;;;OAOG;IACH,UAAU,EAAE,OAAO,CAAC;IAEpB;;;;OAIG;IACH,QAAQ,EAAE,OAAO,CAAC;IAElB;;;;OAIG;IACH,iBAAiB,EAAE,OAAO,CAAC;IAE3B;;;OAGG;IACH,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,gBAAgB,CAAC;IAElE;;;;;OAKG;IACH,0BAA0B,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CAC/D;AASD,eAAO,MAAM,gCAAgC,EAAE,yBAQ9C,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;CAClC,CAAC;AAEF,eAAO,MAAM,6BAA6B,GACxC,UAAS,OAAO,CAAC,yBAAyB,CAAM,KAC/C,WAAW,GAAG;IACf,OAAO,EAAE,yBAAyB,CAAC;IACnC,KAAK,EAAE,uBAAuB,CAAC;IAC/B,eAAe,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CA8D1C,CAAC;AAEF,MAAM,MAAM,6BAA6B,GAAG,UAAU,CAAC,OAAO,6BAA6B,CAAC,CAAC;AAE7F;;GAEG;AACH,wBAAgB,uCAAuC,IAAI,6BAA6B,GAAG,SAAS,CAOnG;AAED;;GAEG;AACH,wBAAgB,gCAAgC,CAAC,MAAM,EAAE,MAAM,GAAG,6BAA6B,GAAG,SAAS,CAE1G"}
@@ -1 +1 @@
1
- {"version":3,"file":"reactnativetracing.js","sourceRoot":"","sources":["../../../src/js/tracing/reactnativetracing.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable max-lines */\nimport { instrumentOutgoingRequests } from '@sentry/browser';\nimport type { Client, Event, Integration, StartSpanOptions } from '@sentry/core';\nimport { getClient } from '@sentry/core';\nimport { isWeb } from '../utils/environment';\nimport { getDevServer } from './../integrations/debugsymbolicatorutils';\nimport { addDefaultOpForSpanFrom, addThreadInfoToSpan, defaultIdleOptions } from './span';\n\nexport const INTEGRATION_NAME = 'ReactNativeTracing';\n\nexport interface ReactNativeTracingOptions {\n /**\n * The time that has to pass without any span being created.\n * If this time is exceeded, the idle span will finish.\n *\n * @default 1_000 (ms)\n */\n idleTimeoutMs?: number;\n\n /**\n * The max. time an idle span may run.\n * If this time is exceeded, the idle span will finish no matter what.\n *\n * @default 60_0000 (ms)\n */\n finalTimeoutMs?: number;\n\n /**\n * Flag to disable patching all together for fetch requests.\n *\n * Fetch in React Native is a `whatwg-fetch` polyfill which uses XHR under the hood.\n * This causes duplicates when both `traceFetch` and `traceXHR` are enabled at the same time.\n *\n * @default false\n */\n traceFetch: boolean;\n\n /**\n * Flag to disable patching all together for xhr requests.\n *\n * @default true\n */\n traceXHR: boolean;\n\n /**\n * If true, Sentry will capture http timings and add them to the corresponding http spans.\n *\n * @default true\n */\n enableHTTPTimings: boolean;\n\n /**\n * A callback which is called before a span for a navigation is started.\n * It receives the options passed to `startSpan`, and expects to return an updated options object.\n */\n beforeStartSpan?: (options: StartSpanOptions) => StartSpanOptions;\n\n /**\n * This function will be called before creating a span for a request with the given url.\n * Return false if you don't want a span for the given url.\n *\n * @default (url: string) => true\n */\n shouldCreateSpanForRequest?(this: void, url: string): boolean;\n}\n\nfunction getDefaultTracePropagationTargets(): RegExp[] | undefined {\n if (isWeb()) {\n return undefined;\n }\n return [/.*/];\n}\n\nexport const defaultReactNativeTracingOptions: ReactNativeTracingOptions = {\n // Fetch in React Native is a `whatwg-fetch` polyfill which uses XHR under the hood.\n // This causes duplicates when both `traceFetch` and `traceXHR` are enabled at the same time.\n // https://github.com/facebook/react-native/blob/28945c68da056ab2ac01de7e542a845b2bca6096/packages/react-native/Libraries/Network/fetch.js\n // (RN Web uses browsers native fetch implementation)\n traceFetch: isWeb() ? true : false,\n traceXHR: true,\n enableHTTPTimings: true,\n};\n\nexport type ReactNativeTracingState = {\n currentRoute: string | undefined;\n};\n\nexport const reactNativeTracingIntegration = (\n options: Partial<ReactNativeTracingOptions> = {},\n): Integration & {\n options: ReactNativeTracingOptions;\n state: ReactNativeTracingState;\n setCurrentRoute: (route: string) => void;\n} => {\n const state: ReactNativeTracingState = {\n currentRoute: undefined,\n };\n\n const finalOptions = {\n ...defaultReactNativeTracingOptions,\n ...options,\n beforeStartSpan: options.beforeStartSpan ?? ((options: StartSpanOptions) => options),\n finalTimeoutMs: options.finalTimeoutMs ?? defaultIdleOptions.finalTimeout,\n idleTimeoutMs: options.idleTimeoutMs ?? defaultIdleOptions.idleTimeout,\n };\n\n const userShouldCreateSpanForRequest = finalOptions.shouldCreateSpanForRequest;\n\n // Drop Dev Server Spans\n const devServerUrl = getDevServer()?.url;\n const finalShouldCreateSpanForRequest =\n devServerUrl === undefined\n ? userShouldCreateSpanForRequest\n : (url: string): boolean => {\n if (url.startsWith(devServerUrl)) {\n return false;\n }\n if (userShouldCreateSpanForRequest) {\n return userShouldCreateSpanForRequest(url);\n }\n return true;\n };\n\n finalOptions.shouldCreateSpanForRequest = finalShouldCreateSpanForRequest;\n\n const setup = (client: Client): void => {\n addDefaultOpForSpanFrom(client);\n addThreadInfoToSpan(client);\n\n instrumentOutgoingRequests(client, {\n traceFetch: finalOptions.traceFetch,\n traceXHR: finalOptions.traceXHR,\n shouldCreateSpanForRequest: finalOptions.shouldCreateSpanForRequest,\n tracePropagationTargets: client.getOptions().tracePropagationTargets || getDefaultTracePropagationTargets(),\n });\n };\n\n const processEvent = (event: Event): Event => {\n if (event.contexts && state.currentRoute) {\n event.contexts.app = { view_names: [state.currentRoute], ...event.contexts.app };\n }\n return event;\n };\n\n return {\n name: INTEGRATION_NAME,\n setup,\n processEvent,\n options: finalOptions,\n state,\n setCurrentRoute: (route: string) => {\n state.currentRoute = route;\n },\n };\n};\n\nexport type ReactNativeTracingIntegration = ReturnType<typeof reactNativeTracingIntegration>;\n\n/**\n * Returns the current React Native Tracing integration.\n */\nexport function getCurrentReactNativeTracingIntegration(): ReactNativeTracingIntegration | undefined {\n const client = getClient();\n if (!client) {\n return undefined;\n }\n\n return getReactNativeTracingIntegration(client);\n}\n\n/**\n * Returns React Native Tracing integration of given client.\n */\nexport function getReactNativeTracingIntegration(client: Client): ReactNativeTracingIntegration | undefined {\n return client.getIntegrationByName(INTEGRATION_NAME);\n}\n"]}
1
+ {"version":3,"file":"reactnativetracing.js","sourceRoot":"","sources":["../../../src/js/tracing/reactnativetracing.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable max-lines */\nimport { instrumentOutgoingRequests } from '@sentry/browser';\nimport type { Client, Event, Integration, StartSpanOptions } from '@sentry/core';\nimport { getClient } from '@sentry/core';\nimport { isWeb } from '../utils/environment';\nimport { getDevServer } from './../integrations/debugsymbolicatorutils';\nimport { addDefaultOpForSpanFrom, addThreadInfoToSpan, defaultIdleOptions } from './span';\n\nexport const INTEGRATION_NAME = 'ReactNativeTracing';\n\nexport interface ReactNativeTracingOptions {\n /**\n * The time that has to pass without any span being created.\n * If this time is exceeded, the idle span will finish.\n *\n * @default 1_000 (ms)\n */\n idleTimeoutMs?: number;\n\n /**\n * The max. time an idle span may run.\n * If this time is exceeded, the idle span will finish no matter what.\n *\n * @default 60_0000 (ms)\n */\n finalTimeoutMs?: number;\n\n /**\n * Flag to disable patching all together for fetch requests.\n *\n * Fetch in React Native is a `whatwg-fetch` polyfill which uses XHR under the hood.\n * This causes duplicates when both `traceFetch` and `traceXHR` are enabled at the same time.\n *\n * @default false\n */\n traceFetch: boolean;\n\n /**\n * Flag to disable patching all together for xhr requests.\n *\n * @default true\n */\n traceXHR: boolean;\n\n /**\n * If true, Sentry will capture http timings and add them to the corresponding http spans.\n *\n * @default true\n */\n enableHTTPTimings: boolean;\n\n /**\n * A callback which is called before a span for a navigation is started.\n * It receives the options passed to `startSpan`, and expects to return an updated options object.\n */\n beforeStartSpan?: (options: StartSpanOptions) => StartSpanOptions;\n\n /**\n * This function will be called before creating a span for a request with the given url.\n * Return false if you don't want a span for the given url.\n *\n * @default (url: string) => true\n */\n shouldCreateSpanForRequest?(this: void, url: string): boolean;\n}\n\nfunction getDefaultTracePropagationTargets(): RegExp[] | undefined {\n if (isWeb()) {\n return undefined;\n }\n return [/.*/];\n}\n\nexport const defaultReactNativeTracingOptions: ReactNativeTracingOptions = {\n // Fetch in React Native is a `whatwg-fetch` polyfill which uses XHR under the hood.\n // This causes duplicates when both `traceFetch` and `traceXHR` are enabled at the same time.\n // https://github.com/facebook/react-native/blob/28945c68da056ab2ac01de7e542a845b2bca6096/packages/react-native/Libraries/Network/fetch.js\n // (RN Web uses browsers native fetch implementation)\n traceFetch: isWeb() ? true : false,\n traceXHR: true,\n enableHTTPTimings: true,\n};\n\nexport type ReactNativeTracingState = {\n currentRoute: string | undefined;\n};\n\nexport const reactNativeTracingIntegration = (\n options: Partial<ReactNativeTracingOptions> = {},\n): Integration & {\n options: ReactNativeTracingOptions;\n state: ReactNativeTracingState;\n setCurrentRoute: (route: string) => void;\n} => {\n const state: ReactNativeTracingState = {\n currentRoute: undefined,\n };\n\n const finalOptions = {\n ...defaultReactNativeTracingOptions,\n ...options,\n beforeStartSpan: options.beforeStartSpan ?? ((options: StartSpanOptions) => options),\n finalTimeoutMs: options.finalTimeoutMs ?? defaultIdleOptions.finalTimeout,\n idleTimeoutMs: options.idleTimeoutMs ?? defaultIdleOptions.idleTimeout,\n };\n\n const userShouldCreateSpanForRequest = finalOptions.shouldCreateSpanForRequest;\n\n // Drop Dev Server Spans\n const devServerUrl = getDevServer()?.url;\n const finalShouldCreateSpanForRequest =\n devServerUrl === undefined\n ? userShouldCreateSpanForRequest\n : (url: string): boolean => {\n if (url.startsWith(devServerUrl)) {\n return false;\n }\n if (userShouldCreateSpanForRequest) {\n return userShouldCreateSpanForRequest(url);\n }\n return true;\n };\n\n finalOptions.shouldCreateSpanForRequest = finalShouldCreateSpanForRequest;\n\n const setup = (client: Client): void => {\n addDefaultOpForSpanFrom(client);\n addThreadInfoToSpan(client);\n\n instrumentOutgoingRequests(client, {\n traceFetch: finalOptions.traceFetch,\n traceXHR: finalOptions.traceXHR,\n shouldCreateSpanForRequest: finalOptions.shouldCreateSpanForRequest,\n tracePropagationTargets: client.getOptions().tracePropagationTargets || getDefaultTracePropagationTargets(),\n });\n };\n\n const processEvent = (event: Event): Event => {\n if (event.contexts && state.currentRoute) {\n event.contexts.app = { view_names: [state.currentRoute], ...event.contexts.app };\n }\n return event;\n };\n\n return {\n name: INTEGRATION_NAME,\n setup,\n processEvent,\n options: finalOptions,\n state,\n setCurrentRoute: (route: string) => {\n state.currentRoute = route;\n },\n };\n};\n\nexport type ReactNativeTracingIntegration = ReturnType<typeof reactNativeTracingIntegration>;\n\n/**\n * Returns the current React Native Tracing integration.\n */\nexport function getCurrentReactNativeTracingIntegration(): ReactNativeTracingIntegration | undefined {\n const client = getClient();\n if (!client) {\n return undefined;\n }\n\n return getReactNativeTracingIntegration(client);\n}\n\n/**\n * Returns React Native Tracing integration of given client.\n */\nexport function getReactNativeTracingIntegration(client: Client): ReactNativeTracingIntegration | undefined {\n return client.getIntegrationByName(INTEGRATION_NAME);\n}\n"]}
@@ -27,6 +27,9 @@ interface ReactNavigationIntegrationOptions {
27
27
  * Time to initial display measures the time it takes from
28
28
  * navigation dispatch to the render of the first frame of the new screen.
29
29
  *
30
+ * Note: Enabling this adds native bridge calls on every navigation
31
+ * which may cause noticeable overhead on low-end devices.
32
+ *
30
33
  * @default false
31
34
  */
32
35
  enableTimeToInitialDisplay: boolean;
@@ -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;CA4W3C,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;;;;;;;;OAQG;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,GAAI,+NAQxC,OAAO,CAAC,iCAAiC,CAAM,KAAG,WAAW,GAAG;IACjE;;;OAGG;IACH,2BAA2B,EAAE,CAAC,sBAAsB,EAAE,OAAO,KAAK,IAAI,CAAC;IACvE,OAAO,EAAE,iCAAiC,CAAC;CAgX5C,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"}
@@ -183,6 +183,7 @@ export const reactNavigationIntegration = ({ routeChangeTimeoutMs = 1000, enable
183
183
  * @param unknownEvent - The event object that contains navigation action data
184
184
  * @param isAppRestart - Whether this span is being started due to an app restart rather than a normal navigation action
185
185
  */
186
+ // eslint-disable-next-line complexity
186
187
  const startIdleNavigationSpan = (unknownEvent, isAppRestart = false) => {
187
188
  const event = unknownEvent;
188
189
  if (useDispatchedActionData && (event === null || event === void 0 ? void 0 : event.data.noop)) {
@@ -222,7 +223,7 @@ export const reactNavigationIntegration = ({ routeChangeTimeoutMs = 1000, enable
222
223
  navigationActionType &&
223
224
  [
224
225
  // Process common actions
225
- 'PRELOAD',
226
+ 'PRELOAD', // Still filter PRELOAD when enablePrefetchTracking is false
226
227
  'SET_PARAMS',
227
228
  // Drawer actions
228
229
  'OPEN_DRAWER',
@@ -262,6 +263,7 @@ export const reactNavigationIntegration = ({ routeChangeTimeoutMs = 1000, enable
262
263
  /**
263
264
  * To be called AFTER the state has been changed to populate the transaction with the current route.
264
265
  */
266
+ // eslint-disable-next-line complexity
265
267
  const updateLatestNavigationSpanWithCurrentRoute = () => {
266
268
  var _a, _b, _c;
267
269
  const stateChangedTimestamp = timestampInSeconds();
@@ -279,8 +281,10 @@ export const reactNavigationIntegration = ({ routeChangeTimeoutMs = 1000, enable
279
281
  debug.log(`[${INTEGRATION_NAME}] Navigation state changed, but navigation transaction was not started on dispatch.`);
280
282
  return undefined;
281
283
  }
282
- addTimeToInitialDisplayFallback(latestNavigationSpan.spanContext().spanId, NATIVE.getNewScreenTimeToDisplay());
283
- if (previousRoute && previousRoute.key === route.key) {
284
+ if (enableTimeToInitialDisplay) {
285
+ addTimeToInitialDisplayFallback(latestNavigationSpan.spanContext().spanId, NATIVE.getNewScreenTimeToDisplay());
286
+ }
287
+ if ((previousRoute === null || previousRoute === void 0 ? void 0 : previousRoute.key) === route.key) {
284
288
  debug.log(`[${INTEGRATION_NAME}] Navigation state changed, but route is the same as previous.`);
285
289
  pushRecentRouteKey(route.key);
286
290
  latestRoute = route;