@sentry/react-native 5.28.0 → 6.0.0-alpha.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 (294) hide show
  1. package/CHANGELOG.md +113 -0
  2. package/android/build.gradle +1 -1
  3. package/dist/js/client.d.ts +5 -9
  4. package/dist/js/client.d.ts.map +1 -1
  5. package/dist/js/client.js +11 -42
  6. package/dist/js/client.js.map +1 -1
  7. package/dist/js/index.d.ts +5 -10
  8. package/dist/js/index.d.ts.map +1 -1
  9. package/dist/js/index.js +4 -21
  10. package/dist/js/index.js.map +1 -1
  11. package/dist/js/integrations/debugsymbolicator.d.ts +2 -8
  12. package/dist/js/integrations/debugsymbolicator.d.ts.map +1 -1
  13. package/dist/js/integrations/debugsymbolicator.js +1 -9
  14. package/dist/js/integrations/debugsymbolicator.js.map +1 -1
  15. package/dist/js/integrations/default.d.ts.map +1 -1
  16. package/dist/js/integrations/default.js +18 -7
  17. package/dist/js/integrations/default.js.map +1 -1
  18. package/dist/js/integrations/devicecontext.d.ts +2 -8
  19. package/dist/js/integrations/devicecontext.d.ts.map +1 -1
  20. package/dist/js/integrations/devicecontext.js +0 -9
  21. package/dist/js/integrations/devicecontext.js.map +1 -1
  22. package/dist/js/integrations/eventorigin.d.ts +2 -8
  23. package/dist/js/integrations/eventorigin.d.ts.map +1 -1
  24. package/dist/js/integrations/eventorigin.js +0 -8
  25. package/dist/js/integrations/eventorigin.js.map +1 -1
  26. package/dist/js/integrations/expocontext.d.ts +2 -8
  27. package/dist/js/integrations/expocontext.d.ts.map +1 -1
  28. package/dist/js/integrations/expocontext.js +0 -8
  29. package/dist/js/integrations/expocontext.js.map +1 -1
  30. package/dist/js/integrations/exports.d.ts +4 -0
  31. package/dist/js/integrations/exports.d.ts.map +1 -1
  32. package/dist/js/integrations/exports.js +4 -0
  33. package/dist/js/integrations/exports.js.map +1 -1
  34. package/dist/js/integrations/modulesloader.d.ts +2 -8
  35. package/dist/js/integrations/modulesloader.d.ts.map +1 -1
  36. package/dist/js/integrations/modulesloader.js +0 -8
  37. package/dist/js/integrations/modulesloader.js.map +1 -1
  38. package/dist/js/integrations/nativelinkederrors.d.ts +2 -8
  39. package/dist/js/integrations/nativelinkederrors.d.ts.map +1 -1
  40. package/dist/js/integrations/nativelinkederrors.js +0 -8
  41. package/dist/js/integrations/nativelinkederrors.js.map +1 -1
  42. package/dist/js/integrations/reactnativeerrorhandlers.d.ts +2 -8
  43. package/dist/js/integrations/reactnativeerrorhandlers.d.ts.map +1 -1
  44. package/dist/js/integrations/reactnativeerrorhandlers.js +1 -8
  45. package/dist/js/integrations/reactnativeerrorhandlers.js.map +1 -1
  46. package/dist/js/integrations/reactnativeinfo.d.ts +2 -8
  47. package/dist/js/integrations/reactnativeinfo.d.ts.map +1 -1
  48. package/dist/js/integrations/reactnativeinfo.js +0 -8
  49. package/dist/js/integrations/reactnativeinfo.js.map +1 -1
  50. package/dist/js/integrations/release.d.ts +2 -8
  51. package/dist/js/integrations/release.d.ts.map +1 -1
  52. package/dist/js/integrations/release.js +0 -8
  53. package/dist/js/integrations/release.js.map +1 -1
  54. package/dist/js/integrations/rewriteframes.js +1 -1
  55. package/dist/js/integrations/rewriteframes.js.map +1 -1
  56. package/dist/js/integrations/screenshot.d.ts +2 -8
  57. package/dist/js/integrations/screenshot.d.ts.map +1 -1
  58. package/dist/js/integrations/screenshot.js +2 -11
  59. package/dist/js/integrations/screenshot.js.map +1 -1
  60. package/dist/js/integrations/sdkinfo.d.ts +2 -8
  61. package/dist/js/integrations/sdkinfo.d.ts.map +1 -1
  62. package/dist/js/integrations/sdkinfo.js +0 -8
  63. package/dist/js/integrations/sdkinfo.js.map +1 -1
  64. package/dist/js/integrations/spotlight.d.ts +2 -10
  65. package/dist/js/integrations/spotlight.d.ts.map +1 -1
  66. package/dist/js/integrations/spotlight.js +1 -10
  67. package/dist/js/integrations/spotlight.js.map +1 -1
  68. package/dist/js/integrations/viewhierarchy.d.ts +2 -8
  69. package/dist/js/integrations/viewhierarchy.d.ts.map +1 -1
  70. package/dist/js/integrations/viewhierarchy.js +0 -8
  71. package/dist/js/integrations/viewhierarchy.js.map +1 -1
  72. package/dist/js/options.d.ts +43 -0
  73. package/dist/js/options.d.ts.map +1 -1
  74. package/dist/js/options.js.map +1 -1
  75. package/dist/js/profiling/cache.d.ts +1 -1
  76. package/dist/js/profiling/hermes.d.ts +1 -1
  77. package/dist/js/profiling/hermes.d.ts.map +1 -1
  78. package/dist/js/profiling/integration.d.ts +1 -7
  79. package/dist/js/profiling/integration.d.ts.map +1 -1
  80. package/dist/js/profiling/integration.js +39 -25
  81. package/dist/js/profiling/integration.js.map +1 -1
  82. package/dist/js/profiling/utils.js +2 -1
  83. package/dist/js/profiling/utils.js.map +1 -1
  84. package/dist/js/replay/mobilereplay.d.ts +2 -2
  85. package/dist/js/replay/mobilereplay.d.ts.map +1 -1
  86. package/dist/js/replay/mobilereplay.js.map +1 -1
  87. package/dist/js/scopeSync.d.ts +6 -0
  88. package/dist/js/scopeSync.d.ts.map +1 -0
  89. package/dist/js/scopeSync.js +60 -0
  90. package/dist/js/scopeSync.js.map +1 -0
  91. package/dist/js/sdk.d.ts +1 -20
  92. package/dist/js/sdk.d.ts.map +1 -1
  93. package/dist/js/sdk.js +20 -53
  94. package/dist/js/sdk.js.map +1 -1
  95. package/dist/js/tools/sentryMetroSerializer.js.map +1 -1
  96. package/dist/js/touchevents.d.ts +0 -1
  97. package/dist/js/touchevents.d.ts.map +1 -1
  98. package/dist/js/touchevents.js +5 -9
  99. package/dist/js/touchevents.js.map +1 -1
  100. package/dist/js/tracing/gesturetracing.d.ts +1 -6
  101. package/dist/js/tracing/gesturetracing.d.ts.map +1 -1
  102. package/dist/js/tracing/gesturetracing.js +8 -12
  103. package/dist/js/tracing/gesturetracing.js.map +1 -1
  104. package/dist/js/tracing/index.d.ts +6 -7
  105. package/dist/js/tracing/index.d.ts.map +1 -1
  106. package/dist/js/tracing/index.js +4 -7
  107. package/dist/js/tracing/index.js.map +1 -1
  108. package/dist/js/tracing/integrations/appStart.d.ts +39 -0
  109. package/dist/js/tracing/integrations/appStart.d.ts.map +1 -0
  110. package/dist/js/tracing/integrations/appStart.js +301 -0
  111. package/dist/js/tracing/integrations/appStart.js.map +1 -0
  112. package/dist/js/tracing/integrations/nativeFrames.d.ts +20 -0
  113. package/dist/js/tracing/integrations/nativeFrames.d.ts.map +1 -0
  114. package/dist/js/tracing/integrations/nativeFrames.js +256 -0
  115. package/dist/js/tracing/integrations/nativeFrames.js.map +1 -0
  116. package/dist/js/tracing/integrations/stalltracking.d.ts +31 -0
  117. package/dist/js/tracing/integrations/stalltracking.d.ts.map +1 -0
  118. package/dist/js/tracing/integrations/stalltracking.js +236 -0
  119. package/dist/js/tracing/integrations/stalltracking.js.map +1 -0
  120. package/dist/js/tracing/integrations/userInteraction.d.ts +11 -0
  121. package/dist/js/tracing/integrations/userInteraction.d.ts.map +1 -0
  122. package/dist/js/tracing/integrations/userInteraction.js +70 -0
  123. package/dist/js/tracing/integrations/userInteraction.js.map +1 -0
  124. package/dist/js/tracing/onSpanEndUtils.d.ts +17 -0
  125. package/dist/js/tracing/onSpanEndUtils.d.ts.map +1 -0
  126. package/dist/js/tracing/onSpanEndUtils.js +112 -0
  127. package/dist/js/tracing/onSpanEndUtils.js.map +1 -0
  128. package/dist/js/tracing/origin.d.ts +2 -0
  129. package/dist/js/tracing/origin.d.ts.map +1 -0
  130. package/dist/js/tracing/origin.js +2 -0
  131. package/dist/js/tracing/origin.js.map +1 -0
  132. package/dist/js/tracing/reactnativenavigation.d.ts +21 -39
  133. package/dist/js/tracing/reactnativenavigation.d.ts.map +1 -1
  134. package/dist/js/tracing/reactnativenavigation.js +98 -87
  135. package/dist/js/tracing/reactnativenavigation.js.map +1 -1
  136. package/dist/js/tracing/reactnativeprofiler.d.ts.map +1 -1
  137. package/dist/js/tracing/reactnativeprofiler.js +6 -13
  138. package/dist/js/tracing/reactnativeprofiler.js.map +1 -1
  139. package/dist/js/tracing/reactnativetracing.d.ts +44 -160
  140. package/dist/js/tracing/reactnativetracing.d.ts.map +1 -1
  141. package/dist/js/tracing/reactnativetracing.js +51 -481
  142. package/dist/js/tracing/reactnativetracing.js.map +1 -1
  143. package/dist/js/tracing/reactnavigation.d.ts +18 -63
  144. package/dist/js/tracing/reactnavigation.d.ts.map +1 -1
  145. package/dist/js/tracing/reactnavigation.js +197 -218
  146. package/dist/js/tracing/reactnavigation.js.map +1 -1
  147. package/dist/js/tracing/semanticAttributes.d.ts +12 -0
  148. package/dist/js/tracing/semanticAttributes.d.ts.map +1 -0
  149. package/dist/js/tracing/semanticAttributes.js +12 -0
  150. package/dist/js/tracing/semanticAttributes.js.map +1 -0
  151. package/dist/js/tracing/span.d.ts +52 -0
  152. package/dist/js/tracing/span.d.ts.map +1 -0
  153. package/dist/js/tracing/span.js +82 -0
  154. package/dist/js/tracing/span.js.map +1 -0
  155. package/dist/js/tracing/timetodisplay.d.ts.map +1 -1
  156. package/dist/js/tracing/timetodisplay.js +16 -29
  157. package/dist/js/tracing/timetodisplay.js.map +1 -1
  158. package/dist/js/tracing/timetodisplaynative.d.ts.map +1 -1
  159. package/dist/js/tracing/timetodisplaynative.js +5 -3
  160. package/dist/js/tracing/timetodisplaynative.js.map +1 -1
  161. package/dist/js/tracing/types.d.ts +2 -9
  162. package/dist/js/tracing/types.d.ts.map +1 -1
  163. package/dist/js/tracing/types.js.map +1 -1
  164. package/dist/js/tracing/utils.d.ts +23 -12
  165. package/dist/js/tracing/utils.d.ts.map +1 -1
  166. package/dist/js/tracing/utils.js +48 -52
  167. package/dist/js/tracing/utils.js.map +1 -1
  168. package/dist/js/transports/encodePolyfill.d.ts +3 -0
  169. package/dist/js/transports/encodePolyfill.d.ts.map +1 -0
  170. package/dist/js/transports/encodePolyfill.js +13 -0
  171. package/dist/js/transports/encodePolyfill.js.map +1 -0
  172. package/dist/js/transports/native.d.ts +2 -2
  173. package/dist/js/transports/native.d.ts.map +1 -1
  174. package/dist/js/transports/native.js +2 -1
  175. package/dist/js/transports/native.js.map +1 -1
  176. package/dist/js/utils/fill.d.ts +7 -0
  177. package/dist/js/utils/fill.d.ts.map +1 -0
  178. package/dist/js/utils/fill.js +9 -0
  179. package/dist/js/utils/fill.js.map +1 -0
  180. package/dist/js/utils/normalize.d.ts.map +1 -1
  181. package/dist/js/utils/normalize.js +8 -5
  182. package/dist/js/utils/normalize.js.map +1 -1
  183. package/dist/js/utils/rnlibraries.d.ts.map +1 -1
  184. package/dist/js/utils/rnlibraries.js +6 -0
  185. package/dist/js/utils/rnlibraries.js.map +1 -1
  186. package/dist/js/utils/rnlibrariesinterface.d.ts +3 -0
  187. package/dist/js/utils/rnlibrariesinterface.d.ts.map +1 -1
  188. package/dist/js/utils/rnlibrariesinterface.js.map +1 -1
  189. package/dist/js/utils/span.d.ts +19 -0
  190. package/dist/js/utils/span.d.ts.map +1 -0
  191. package/dist/js/utils/span.js +29 -0
  192. package/dist/js/utils/span.js.map +1 -0
  193. package/dist/js/vendor/react-native/index.d.ts +5 -1
  194. package/dist/js/vendor/react-native/index.d.ts.map +1 -1
  195. package/dist/js/vendor/react-native/index.js.map +1 -1
  196. package/dist/js/version.d.ts +1 -1
  197. package/dist/js/version.d.ts.map +1 -1
  198. package/dist/js/version.js +1 -1
  199. package/dist/js/version.js.map +1 -1
  200. package/dist/js/wrapper.d.ts.map +1 -1
  201. package/dist/js/wrapper.js +1 -0
  202. package/dist/js/wrapper.js.map +1 -1
  203. package/package.json +12 -13
  204. package/ts3.8/dist/js/client.d.ts +5 -9
  205. package/ts3.8/dist/js/index.d.ts +5 -10
  206. package/ts3.8/dist/js/integrations/debugsymbolicator.d.ts +2 -8
  207. package/ts3.8/dist/js/integrations/devicecontext.d.ts +2 -8
  208. package/ts3.8/dist/js/integrations/eventorigin.d.ts +2 -8
  209. package/ts3.8/dist/js/integrations/expocontext.d.ts +2 -8
  210. package/ts3.8/dist/js/integrations/exports.d.ts +4 -0
  211. package/ts3.8/dist/js/integrations/modulesloader.d.ts +2 -8
  212. package/ts3.8/dist/js/integrations/nativelinkederrors.d.ts +2 -8
  213. package/ts3.8/dist/js/integrations/reactnativeerrorhandlers.d.ts +2 -8
  214. package/ts3.8/dist/js/integrations/reactnativeinfo.d.ts +2 -8
  215. package/ts3.8/dist/js/integrations/release.d.ts +2 -8
  216. package/ts3.8/dist/js/integrations/screenshot.d.ts +2 -8
  217. package/ts3.8/dist/js/integrations/sdkinfo.d.ts +2 -8
  218. package/ts3.8/dist/js/integrations/spotlight.d.ts +2 -10
  219. package/ts3.8/dist/js/integrations/viewhierarchy.d.ts +2 -8
  220. package/ts3.8/dist/js/options.d.ts +43 -0
  221. package/ts3.8/dist/js/profiling/cache.d.ts +1 -1
  222. package/ts3.8/dist/js/profiling/hermes.d.ts +1 -1
  223. package/ts3.8/dist/js/profiling/integration.d.ts +1 -7
  224. package/ts3.8/dist/js/replay/mobilereplay.d.ts +2 -2
  225. package/ts3.8/dist/js/scopeSync.d.ts +6 -0
  226. package/ts3.8/dist/js/sdk.d.ts +1 -20
  227. package/ts3.8/dist/js/touchevents.d.ts +0 -1
  228. package/ts3.8/dist/js/tracing/gesturetracing.d.ts +1 -6
  229. package/ts3.8/dist/js/tracing/index.d.ts +6 -7
  230. package/ts3.8/dist/js/tracing/integrations/appStart.d.ts +39 -0
  231. package/ts3.8/dist/js/tracing/integrations/nativeFrames.d.ts +20 -0
  232. package/ts3.8/dist/js/tracing/integrations/stalltracking.d.ts +31 -0
  233. package/ts3.8/dist/js/tracing/integrations/userInteraction.d.ts +11 -0
  234. package/ts3.8/dist/js/tracing/onSpanEndUtils.d.ts +17 -0
  235. package/ts3.8/dist/js/tracing/origin.d.ts +2 -0
  236. package/ts3.8/dist/js/tracing/reactnativenavigation.d.ts +21 -39
  237. package/ts3.8/dist/js/tracing/reactnativetracing.d.ts +44 -160
  238. package/ts3.8/dist/js/tracing/reactnavigation.d.ts +18 -63
  239. package/ts3.8/dist/js/tracing/semanticAttributes.d.ts +12 -0
  240. package/ts3.8/dist/js/tracing/span.d.ts +52 -0
  241. package/ts3.8/dist/js/tracing/types.d.ts +2 -9
  242. package/ts3.8/dist/js/tracing/utils.d.ts +23 -12
  243. package/ts3.8/dist/js/transports/encodePolyfill.d.ts +3 -0
  244. package/ts3.8/dist/js/transports/native.d.ts +2 -2
  245. package/ts3.8/dist/js/utils/fill.d.ts +7 -0
  246. package/ts3.8/dist/js/utils/rnlibrariesinterface.d.ts +3 -0
  247. package/ts3.8/dist/js/utils/span.d.ts +19 -0
  248. package/ts3.8/dist/js/vendor/react-native/index.d.ts +5 -1
  249. package/ts3.8/dist/js/version.d.ts +1 -1
  250. package/dist/js/integrations/index.d.ts +0 -16
  251. package/dist/js/integrations/index.d.ts.map +0 -1
  252. package/dist/js/integrations/index.js +0 -17
  253. package/dist/js/integrations/index.js.map +0 -1
  254. package/dist/js/scope.d.ts +0 -54
  255. package/dist/js/scope.d.ts.map +0 -1
  256. package/dist/js/scope.js +0 -89
  257. package/dist/js/scope.js.map +0 -1
  258. package/dist/js/tracing/addTracingExtensions.d.ts +0 -8
  259. package/dist/js/tracing/addTracingExtensions.d.ts.map +0 -1
  260. package/dist/js/tracing/addTracingExtensions.js +0 -66
  261. package/dist/js/tracing/addTracingExtensions.js.map +0 -1
  262. package/dist/js/tracing/nativeframes.d.ts +0 -60
  263. package/dist/js/tracing/nativeframes.d.ts.map +0 -1
  264. package/dist/js/tracing/nativeframes.js +0 -210
  265. package/dist/js/tracing/nativeframes.js.map +0 -1
  266. package/dist/js/tracing/reactnavigationv4.d.ts +0 -92
  267. package/dist/js/tracing/reactnavigationv4.d.ts.map +0 -1
  268. package/dist/js/tracing/reactnavigationv4.js +0 -229
  269. package/dist/js/tracing/reactnavigationv4.js.map +0 -1
  270. package/dist/js/tracing/routingInstrumentation.d.ts +0 -52
  271. package/dist/js/tracing/routingInstrumentation.d.ts.map +0 -1
  272. package/dist/js/tracing/routingInstrumentation.js +0 -36
  273. package/dist/js/tracing/routingInstrumentation.js.map +0 -1
  274. package/dist/js/tracing/stalltracking.d.ts +0 -99
  275. package/dist/js/tracing/stalltracking.d.ts.map +0 -1
  276. package/dist/js/tracing/stalltracking.js +0 -286
  277. package/dist/js/tracing/stalltracking.js.map +0 -1
  278. package/dist/js/tracing/transaction.d.ts +0 -11
  279. package/dist/js/tracing/transaction.d.ts.map +0 -1
  280. package/dist/js/tracing/transaction.js +0 -37
  281. package/dist/js/tracing/transaction.js.map +0 -1
  282. package/dist/js/transports/TextEncoder.d.ts +0 -3
  283. package/dist/js/transports/TextEncoder.d.ts.map +0 -1
  284. package/dist/js/transports/TextEncoder.js +0 -12
  285. package/dist/js/transports/TextEncoder.js.map +0 -1
  286. package/ts3.8/dist/js/integrations/index.d.ts +0 -16
  287. package/ts3.8/dist/js/scope.d.ts +0 -54
  288. package/ts3.8/dist/js/tracing/addTracingExtensions.d.ts +0 -8
  289. package/ts3.8/dist/js/tracing/nativeframes.d.ts +0 -60
  290. package/ts3.8/dist/js/tracing/reactnavigationv4.d.ts +0 -92
  291. package/ts3.8/dist/js/tracing/routingInstrumentation.d.ts +0 -52
  292. package/ts3.8/dist/js/tracing/stalltracking.d.ts +0 -99
  293. package/ts3.8/dist/js/tracing/transaction.d.ts +0 -11
  294. package/ts3.8/dist/js/transports/TextEncoder.d.ts +0 -3
@@ -1,210 +0,0 @@
1
- import { __awaiter } from "tslib";
2
- import { logger, timestampInSeconds } from '@sentry/utils';
3
- import { NATIVE } from '../wrapper';
4
- import { instrumentChildSpanFinish } from './utils';
5
- /**
6
- * Timeout from the final native frames fetch to processing the associated transaction.
7
- * If the transaction is not processed by this time, the native frames will be dropped
8
- * and not added to the event.
9
- */
10
- const FINAL_FRAMES_TIMEOUT_MS = 2000;
11
- /** The listeners for each native frames response, keyed by traceId. This must be global to avoid closure issues and reading outdated values. */
12
- const _framesListeners = new Map();
13
- /** The native frames at the transaction finish time, keyed by traceId. This must be global to avoid closure issues and reading outdated values. */
14
- const _finishFrames = new Map();
15
- /**
16
- * A margin of error of 50ms is allowed for the async native bridge call.
17
- * Anything larger would reduce the accuracy of our frames measurements.
18
- */
19
- const MARGIN_OF_ERROR_SECONDS = 0.05;
20
- /**
21
- * Instrumentation to add native slow/frozen frames measurements onto transactions.
22
- */
23
- export class NativeFramesInstrumentation {
24
- constructor(addGlobalEventProcessor, doesExist) {
25
- logger.log('[ReactNativeTracing] Native frames instrumentation initialized.');
26
- addGlobalEventProcessor(event => this._processEvent(event, doesExist));
27
- }
28
- /**
29
- * To be called when a transaction is started.
30
- * Logs the native frames at this start point and instruments child span finishes.
31
- */
32
- onTransactionStart(transaction) {
33
- logger.debug(`[NativeFrames] Fetching frames for root span start (${transaction.spanContext().spanId}).`);
34
- void NATIVE.fetchNativeFrames()
35
- .then(framesMetrics => {
36
- if (framesMetrics) {
37
- transaction.setData('__startFrames', framesMetrics);
38
- }
39
- else {
40
- logger.warn(`[NativeFrames] Fetched frames for root span start (${transaction.spanContext().spanId}), but no frames were returned.`);
41
- }
42
- })
43
- .then(undefined, error => {
44
- logger.error(`[NativeFrames] Error while fetching frames for root span start (${transaction.spanContext().spanId})`, error);
45
- });
46
- instrumentChildSpanFinish(transaction, (_, endTimestamp) => {
47
- if (!endTimestamp) {
48
- this._onSpanFinish();
49
- }
50
- });
51
- }
52
- /**
53
- * To be called when a transaction is finished
54
- */
55
- onTransactionFinish(transaction) {
56
- this._fetchEndFramesForTransaction(transaction).then(undefined, (reason) => {
57
- logger.error(`[NativeFrames] Error while fetching frames for root span start (${transaction.spanContext().spanId})`, reason);
58
- });
59
- }
60
- /**
61
- * Called on a span finish to fetch native frames to support transactions with trimEnd.
62
- * Only to be called when a span does not have an end timestamp.
63
- */
64
- _onSpanFinish() {
65
- const timestamp = timestampInSeconds();
66
- void NATIVE.fetchNativeFrames()
67
- .then(nativeFrames => {
68
- if (nativeFrames) {
69
- this._lastSpanFinishFrames = {
70
- timestamp,
71
- nativeFrames,
72
- };
73
- }
74
- })
75
- .then(undefined, error => {
76
- logger.error(`[NativeFrames] Error while fetching frames for child span end.`, error);
77
- });
78
- }
79
- /**
80
- * Returns the computed frames measurements and awaits for them if they are not ready yet.
81
- */
82
- _getFramesMeasurements(traceId, finalEndTimestamp, startFrames) {
83
- return __awaiter(this, void 0, void 0, function* () {
84
- if (_finishFrames.has(traceId)) {
85
- logger.debug(`[NativeFrames] Native end frames already fetched for trace id (${traceId}).`);
86
- return this._prepareMeasurements(traceId, finalEndTimestamp, startFrames);
87
- }
88
- return new Promise(resolve => {
89
- const timeout = setTimeout(() => {
90
- logger.debug(`[NativeFrames] Native end frames listener removed by timeout for trace id (${traceId}).`);
91
- _framesListeners.delete(traceId);
92
- resolve(null);
93
- }, 2000);
94
- _framesListeners.set(traceId, () => {
95
- logger.debug(`[NativeFrames] Native end frames listener called for trace id (${traceId}).`);
96
- resolve(this._prepareMeasurements(traceId, finalEndTimestamp, startFrames));
97
- clearTimeout(timeout);
98
- _framesListeners.delete(traceId);
99
- });
100
- });
101
- });
102
- }
103
- /**
104
- * Returns the computed frames measurements given ready data
105
- */
106
- _prepareMeasurements(traceId, finalEndTimestamp, // The actual transaction finish time.
107
- startFrames) {
108
- let finalFinishFrames;
109
- const finish = _finishFrames.get(traceId);
110
- if (finish &&
111
- finish.nativeFrames &&
112
- // Must be in the margin of error of the actual transaction finish time (finalEndTimestamp)
113
- Math.abs(finish.timestamp - finalEndTimestamp) < MARGIN_OF_ERROR_SECONDS) {
114
- logger.debug(`[NativeFrames] Using frames from root span end (traceId, ${traceId}).`);
115
- finalFinishFrames = finish.nativeFrames;
116
- }
117
- else if (this._lastSpanFinishFrames &&
118
- Math.abs(this._lastSpanFinishFrames.timestamp - finalEndTimestamp) < MARGIN_OF_ERROR_SECONDS) {
119
- // Fallback to the last span finish if it is within the margin of error of the actual finish timestamp.
120
- // This should be the case for trimEnd.
121
- logger.debug(`[NativeFrames] Using native frames from last span end (traceId, ${traceId}).`);
122
- finalFinishFrames = this._lastSpanFinishFrames.nativeFrames;
123
- }
124
- else {
125
- logger.warn(`[NativeFrames] Frames were collected within larger than margin of error delay for traceId (${traceId}). Dropping the inaccurate values.`);
126
- return null;
127
- }
128
- const measurements = {
129
- frames_total: {
130
- value: finalFinishFrames.totalFrames - startFrames.totalFrames,
131
- unit: 'none',
132
- },
133
- frames_frozen: {
134
- value: finalFinishFrames.frozenFrames - startFrames.frozenFrames,
135
- unit: 'none',
136
- },
137
- frames_slow: {
138
- value: finalFinishFrames.slowFrames - startFrames.slowFrames,
139
- unit: 'none',
140
- },
141
- };
142
- if (measurements.frames_frozen.value <= 0 &&
143
- measurements.frames_slow.value <= 0 &&
144
- measurements.frames_total.value <= 0) {
145
- logger.warn(`[NativeFrames] Detected zero slow or frozen frames. Not adding measurements to traceId (${traceId}).`);
146
- return null;
147
- }
148
- return measurements;
149
- }
150
- /**
151
- * Fetch finish frames for a transaction at the current time. Calls any awaiting listeners.
152
- */
153
- _fetchEndFramesForTransaction(transaction) {
154
- var _a;
155
- return __awaiter(this, void 0, void 0, function* () {
156
- const startFrames = transaction.data.__startFrames;
157
- // This timestamp marks when the finish frames were retrieved. It should be pretty close to the transaction finish.
158
- const timestamp = timestampInSeconds();
159
- let finishFrames = null;
160
- if (startFrames) {
161
- finishFrames = yield NATIVE.fetchNativeFrames();
162
- }
163
- _finishFrames.set(transaction.traceId, {
164
- nativeFrames: finishFrames,
165
- timestamp,
166
- });
167
- (_a = _framesListeners.get(transaction.traceId)) === null || _a === void 0 ? void 0 : _a();
168
- setTimeout(() => this._cancelEndFrames(transaction), FINAL_FRAMES_TIMEOUT_MS);
169
- });
170
- }
171
- /**
172
- * On a finish frames failure, we cancel the await.
173
- */
174
- _cancelEndFrames(transaction) {
175
- if (_finishFrames.has(transaction.traceId)) {
176
- _finishFrames.delete(transaction.traceId);
177
- logger.log(`[NativeFrames] Native frames timed out for ${transaction.op} transaction ${transaction.name}. Not adding native frames measurements.`);
178
- }
179
- }
180
- /**
181
- * Adds frames measurements to an event. Called from a valid event processor.
182
- * Awaits for finish frames if needed.
183
- */
184
- _processEvent(event, doesExist) {
185
- var _a, _b, _c;
186
- return __awaiter(this, void 0, void 0, function* () {
187
- if (!doesExist()) {
188
- return event;
189
- }
190
- if (event.type === 'transaction' && event.transaction && event.contexts && event.contexts.trace) {
191
- const traceContext = event.contexts.trace;
192
- const traceId = traceContext.trace_id;
193
- if (!((_a = traceContext.data) === null || _a === void 0 ? void 0 : _a.__startFrames)) {
194
- logger.warn(`[NativeFrames] Start frames of transaction ${event.transaction} (eventId, ${event.event_id}) are missing, but it already ended.`);
195
- }
196
- if (traceId && ((_b = traceContext.data) === null || _b === void 0 ? void 0 : _b.__startFrames) && event.timestamp) {
197
- const measurements = yield this._getFramesMeasurements(traceId, event.timestamp, traceContext.data.__startFrames);
198
- if (measurements) {
199
- logger.log(`[Measurements] Adding measurements to ${traceContext.op} transaction ${event.transaction}: ${JSON.stringify(measurements, undefined, 2)}`);
200
- event.measurements = Object.assign(Object.assign({}, ((_c = event.measurements) !== null && _c !== void 0 ? _c : {})), measurements);
201
- _finishFrames.delete(traceId);
202
- }
203
- delete traceContext.data.__startFrames;
204
- }
205
- }
206
- return event;
207
- });
208
- }
209
- }
210
- //# sourceMappingURL=nativeframes.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"nativeframes.js","sourceRoot":"","sources":["../../../src/js/tracing/nativeframes.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Span, Transaction } from '@sentry/core';\nimport type { Event, EventProcessor, Measurements, MeasurementUnit } from '@sentry/types';\nimport { logger, timestampInSeconds } from '@sentry/utils';\n\nimport type { NativeFramesResponse } from '../NativeRNSentry';\nimport { NATIVE } from '../wrapper';\nimport { instrumentChildSpanFinish } from './utils';\n\n/**\n * Timeout from the final native frames fetch to processing the associated transaction.\n * If the transaction is not processed by this time, the native frames will be dropped\n * and not added to the event.\n */\nconst FINAL_FRAMES_TIMEOUT_MS = 2000;\n\nexport interface FramesMeasurements extends Measurements {\n frames_total: { value: number; unit: MeasurementUnit };\n frames_slow: { value: number; unit: MeasurementUnit };\n frames_frozen: { value: number; unit: MeasurementUnit };\n}\n\n/** The listeners for each native frames response, keyed by traceId. This must be global to avoid closure issues and reading outdated values. */\nconst _framesListeners: Map<string, () => void> = new Map();\n\n/** The native frames at the transaction finish time, keyed by traceId. This must be global to avoid closure issues and reading outdated values. */\nconst _finishFrames: Map<string, { timestamp: number; nativeFrames: NativeFramesResponse | null }> = new Map();\n\n/**\n * A margin of error of 50ms is allowed for the async native bridge call.\n * Anything larger would reduce the accuracy of our frames measurements.\n */\nconst MARGIN_OF_ERROR_SECONDS = 0.05;\n\n/**\n * Instrumentation to add native slow/frozen frames measurements onto transactions.\n */\nexport class NativeFramesInstrumentation {\n /** The native frames at the finish time of the most recent span. */\n private _lastSpanFinishFrames?: {\n timestamp: number;\n nativeFrames: NativeFramesResponse;\n };\n\n public constructor(addGlobalEventProcessor: (e: EventProcessor) => void, doesExist: () => boolean) {\n logger.log('[ReactNativeTracing] Native frames instrumentation initialized.');\n\n addGlobalEventProcessor(event => this._processEvent(event, doesExist));\n }\n\n /**\n * To be called when a transaction is started.\n * Logs the native frames at this start point and instruments child span finishes.\n */\n public onTransactionStart(transaction: Transaction): void {\n logger.debug(`[NativeFrames] Fetching frames for root span start (${transaction.spanContext().spanId}).`);\n void NATIVE.fetchNativeFrames()\n .then(framesMetrics => {\n if (framesMetrics) {\n transaction.setData('__startFrames', framesMetrics);\n } else {\n logger.warn(\n `[NativeFrames] Fetched frames for root span start (${\n transaction.spanContext().spanId\n }), but no frames were returned.`,\n );\n }\n })\n .then(undefined, error => {\n logger.error(\n `[NativeFrames] Error while fetching frames for root span start (${transaction.spanContext().spanId})`,\n error,\n );\n });\n\n instrumentChildSpanFinish(transaction, (_: Span, endTimestamp?: number) => {\n if (!endTimestamp) {\n this._onSpanFinish();\n }\n });\n }\n\n /**\n * To be called when a transaction is finished\n */\n public onTransactionFinish(transaction: Transaction): void {\n this._fetchEndFramesForTransaction(transaction).then(undefined, (reason: unknown) => {\n logger.error(\n `[NativeFrames] Error while fetching frames for root span start (${transaction.spanContext().spanId})`,\n reason,\n );\n });\n }\n\n /**\n * Called on a span finish to fetch native frames to support transactions with trimEnd.\n * Only to be called when a span does not have an end timestamp.\n */\n private _onSpanFinish(): void {\n const timestamp = timestampInSeconds();\n\n void NATIVE.fetchNativeFrames()\n .then(nativeFrames => {\n if (nativeFrames) {\n this._lastSpanFinishFrames = {\n timestamp,\n nativeFrames,\n };\n }\n })\n .then(undefined, error => {\n logger.error(`[NativeFrames] Error while fetching frames for child span end.`, error);\n });\n }\n\n /**\n * Returns the computed frames measurements and awaits for them if they are not ready yet.\n */\n private async _getFramesMeasurements(\n traceId: string,\n finalEndTimestamp: number,\n startFrames: NativeFramesResponse,\n ): Promise<FramesMeasurements | null> {\n if (_finishFrames.has(traceId)) {\n logger.debug(`[NativeFrames] Native end frames already fetched for trace id (${traceId}).`);\n return this._prepareMeasurements(traceId, finalEndTimestamp, startFrames);\n }\n\n return new Promise(resolve => {\n const timeout = setTimeout(() => {\n logger.debug(`[NativeFrames] Native end frames listener removed by timeout for trace id (${traceId}).`);\n _framesListeners.delete(traceId);\n\n resolve(null);\n }, 2000);\n\n _framesListeners.set(traceId, () => {\n logger.debug(`[NativeFrames] Native end frames listener called for trace id (${traceId}).`);\n resolve(this._prepareMeasurements(traceId, finalEndTimestamp, startFrames));\n\n clearTimeout(timeout);\n _framesListeners.delete(traceId);\n });\n });\n }\n\n /**\n * Returns the computed frames measurements given ready data\n */\n private _prepareMeasurements(\n traceId: string,\n finalEndTimestamp: number, // The actual transaction finish time.\n startFrames: NativeFramesResponse,\n ): FramesMeasurements | null {\n let finalFinishFrames: NativeFramesResponse | undefined;\n\n const finish = _finishFrames.get(traceId);\n if (\n finish &&\n finish.nativeFrames &&\n // Must be in the margin of error of the actual transaction finish time (finalEndTimestamp)\n Math.abs(finish.timestamp - finalEndTimestamp) < MARGIN_OF_ERROR_SECONDS\n ) {\n logger.debug(`[NativeFrames] Using frames from root span end (traceId, ${traceId}).`);\n finalFinishFrames = finish.nativeFrames;\n } else if (\n this._lastSpanFinishFrames &&\n Math.abs(this._lastSpanFinishFrames.timestamp - finalEndTimestamp) < MARGIN_OF_ERROR_SECONDS\n ) {\n // Fallback to the last span finish if it is within the margin of error of the actual finish timestamp.\n // This should be the case for trimEnd.\n logger.debug(`[NativeFrames] Using native frames from last span end (traceId, ${traceId}).`);\n finalFinishFrames = this._lastSpanFinishFrames.nativeFrames;\n } else {\n logger.warn(\n `[NativeFrames] Frames were collected within larger than margin of error delay for traceId (${traceId}). Dropping the inaccurate values.`,\n );\n return null;\n }\n\n const measurements = {\n frames_total: {\n value: finalFinishFrames.totalFrames - startFrames.totalFrames,\n unit: 'none',\n },\n frames_frozen: {\n value: finalFinishFrames.frozenFrames - startFrames.frozenFrames,\n unit: 'none',\n },\n frames_slow: {\n value: finalFinishFrames.slowFrames - startFrames.slowFrames,\n unit: 'none',\n },\n };\n\n if (\n measurements.frames_frozen.value <= 0 &&\n measurements.frames_slow.value <= 0 &&\n measurements.frames_total.value <= 0\n ) {\n logger.warn(\n `[NativeFrames] Detected zero slow or frozen frames. Not adding measurements to traceId (${traceId}).`,\n );\n return null;\n }\n\n return measurements;\n }\n\n /**\n * Fetch finish frames for a transaction at the current time. Calls any awaiting listeners.\n */\n private async _fetchEndFramesForTransaction(transaction: Transaction): Promise<void> {\n const startFrames = transaction.data.__startFrames as NativeFramesResponse | undefined;\n\n // This timestamp marks when the finish frames were retrieved. It should be pretty close to the transaction finish.\n const timestamp = timestampInSeconds();\n let finishFrames: NativeFramesResponse | null = null;\n if (startFrames) {\n finishFrames = await NATIVE.fetchNativeFrames();\n }\n\n _finishFrames.set(transaction.traceId, {\n nativeFrames: finishFrames,\n timestamp,\n });\n\n _framesListeners.get(transaction.traceId)?.();\n\n setTimeout(() => this._cancelEndFrames(transaction), FINAL_FRAMES_TIMEOUT_MS);\n }\n\n /**\n * On a finish frames failure, we cancel the await.\n */\n private _cancelEndFrames(transaction: Transaction): void {\n if (_finishFrames.has(transaction.traceId)) {\n _finishFrames.delete(transaction.traceId);\n\n logger.log(\n `[NativeFrames] Native frames timed out for ${transaction.op} transaction ${transaction.name}. Not adding native frames measurements.`,\n );\n }\n }\n\n /**\n * Adds frames measurements to an event. Called from a valid event processor.\n * Awaits for finish frames if needed.\n */\n private async _processEvent(event: Event, doesExist: () => boolean): Promise<Event> {\n if (!doesExist()) {\n return event;\n }\n\n if (event.type === 'transaction' && event.transaction && event.contexts && event.contexts.trace) {\n const traceContext = event.contexts.trace as {\n data?: { [key: string]: unknown };\n trace_id: string;\n name?: string;\n op?: string;\n };\n\n const traceId = traceContext.trace_id;\n\n if (!traceContext.data?.__startFrames) {\n logger.warn(\n `[NativeFrames] Start frames of transaction ${event.transaction} (eventId, ${event.event_id}) are missing, but it already ended.`,\n );\n }\n\n if (traceId && traceContext.data?.__startFrames && event.timestamp) {\n const measurements = await this._getFramesMeasurements(\n traceId,\n event.timestamp,\n traceContext.data.__startFrames as NativeFramesResponse,\n );\n\n if (measurements) {\n logger.log(\n `[Measurements] Adding measurements to ${traceContext.op} transaction ${\n event.transaction\n }: ${JSON.stringify(measurements, undefined, 2)}`,\n );\n\n event.measurements = {\n ...(event.measurements ?? {}),\n ...measurements,\n };\n\n _finishFrames.delete(traceId);\n }\n\n delete traceContext.data.__startFrames;\n }\n }\n\n return event;\n }\n}\n"]}
@@ -1,92 +0,0 @@
1
- import type { TransactionContext } from '@sentry/types';
2
- import type { OnConfirmRoute, TransactionCreator } from './routingInstrumentation';
3
- import { InternalRoutingInstrumentation } from './routingInstrumentation';
4
- import type { BeforeNavigate } from './types';
5
- export interface NavigationRouteV4 {
6
- routeName: string;
7
- key: string;
8
- params?: Record<string, any>;
9
- }
10
- export interface NavigationStateV4 {
11
- index: number;
12
- key: string;
13
- isTransitioning: boolean;
14
- routeName?: string;
15
- routes: (NavigationRouteV4 | NavigationStateV4)[];
16
- }
17
- export interface AppContainerInstance {
18
- _navigation: {
19
- state: NavigationStateV4;
20
- router: {
21
- getStateForAction: (action: any, state: NavigationStateV4) => NavigationStateV4;
22
- };
23
- };
24
- }
25
- interface ReactNavigationV4Options {
26
- /**
27
- * How long the instrumentation will wait for the route to mount after a change has been initiated,
28
- * before the transaction is discarded.
29
- * Time is in ms.
30
- *
31
- * Default: 1000
32
- */
33
- routeChangeTimeoutMs: number;
34
- }
35
- /**
36
- * Instrumentation for React-Navigation V4.
37
- * Register the app container with `registerAppContainer` to use, or see docs for more details.
38
- */
39
- declare class ReactNavigationV4Instrumentation extends InternalRoutingInstrumentation {
40
- static instrumentationName: string;
41
- readonly name: string;
42
- private _appContainer;
43
- private readonly _maxRecentRouteLen;
44
- private _prevRoute?;
45
- private _recentRouteKeys;
46
- private _latestTransaction?;
47
- private _initialStateHandled;
48
- private _stateChangeTimeout?;
49
- private _options;
50
- constructor(options?: Partial<ReactNavigationV4Options>);
51
- /**
52
- * Extends by calling _handleInitialState at the end.
53
- */
54
- registerRoutingInstrumentation(listener: TransactionCreator, beforeNavigate: BeforeNavigate, onConfirmRoute: OnConfirmRoute): void;
55
- /**
56
- * Pass the ref to the app container to register it to the instrumentation
57
- * @param appContainerRef Ref to an `AppContainer`
58
- */
59
- registerAppContainer(appContainerRef: any): void;
60
- /**
61
- * Updates the latest transaction with the current state and calls beforeNavigate.
62
- */
63
- private _updateLatestTransaction;
64
- /**
65
- * Patches the react navigation router so we can listen to the route changes and attach the `IdleTransaction` before the
66
- * new screen is mounted.
67
- */
68
- private _patchRouter;
69
- /**
70
- * To be called on navigation state changes and creates the transaction.
71
- */
72
- private _onStateChange;
73
- /** Creates final transaction context before confirmation */
74
- private _prepareFinalContext;
75
- /**
76
- * Gets the transaction context for a `NavigationRouteV4`
77
- */
78
- private _getTransactionContext;
79
- /**
80
- * Gets the current route given a navigation state
81
- */
82
- private _getCurrentRouteFromState;
83
- /** Pushes a recent route key, and removes earlier routes when there is greater than the max length */
84
- private _pushRecentRouteKey;
85
- /** Helper to log a transaction that was not sampled due to beforeNavigate */
86
- private _onBeforeNavigateNotSampled;
87
- /** Cancels the latest transaction so it does not get sent to Sentry. */
88
- private _discardLatestTransaction;
89
- }
90
- declare const INITIAL_TRANSACTION_CONTEXT_V4: TransactionContext;
91
- export { ReactNavigationV4Instrumentation, INITIAL_TRANSACTION_CONTEXT_V4 };
92
- //# sourceMappingURL=reactnavigationv4.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"reactnavigationv4.d.ts","sourceRoot":"","sources":["../../../src/js/tracing/reactnavigationv4.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAe,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAIrE,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AACnF,OAAO,EAAE,8BAA8B,EAAE,MAAM,0BAA0B,CAAC;AAC1E,OAAO,KAAK,EAAE,cAAc,EAA6D,MAAM,SAAS,CAAC;AAGzG,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IAEZ,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC9B;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,eAAe,EAAE,OAAO,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,CAAC,iBAAiB,GAAG,iBAAiB,CAAC,EAAE,CAAC;CACnD;AAED,MAAM,WAAW,oBAAoB;IACnC,WAAW,EAAE;QACX,KAAK,EAAE,iBAAiB,CAAC;QACzB,MAAM,EAAE;YACN,iBAAiB,EAAE,CAEjB,MAAM,EAAE,GAAG,EACX,KAAK,EAAE,iBAAiB,KACrB,iBAAiB,CAAC;SACxB,CAAC;KACH,CAAC;CACH;AAED,UAAU,wBAAwB;IAChC;;;;;;OAMG;IACH,oBAAoB,EAAE,MAAM,CAAC;CAC9B;AAMD;;;GAGG;AACH,cAAM,gCAAiC,SAAQ,8BAA8B;IAC3E,OAAc,mBAAmB,EAAE,MAAM,CAAyB;IAElE,SAAgB,IAAI,EAAE,MAAM,CAAwD;IAEpF,OAAO,CAAC,aAAa,CAAqC;IAE1D,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAe;IAElD,OAAO,CAAC,UAAU,CAAC,CAAoB;IACvC,OAAO,CAAC,gBAAgB,CAAgB;IAExC,OAAO,CAAC,kBAAkB,CAAC,CAAc;IACzC,OAAO,CAAC,oBAAoB,CAAkB;IAC9C,OAAO,CAAC,mBAAmB,CAAC,CAAqB;IAEjD,OAAO,CAAC,QAAQ,CAA2B;gBAExB,OAAO,GAAE,OAAO,CAAC,wBAAwB,CAAM;IASlE;;OAEG;IACI,8BAA8B,CACnC,QAAQ,EAAE,kBAAkB,EAC5B,cAAc,EAAE,cAAc,EAC9B,cAAc,EAAE,cAAc,GAC7B,IAAI;IAmBP;;;OAGG;IAEI,oBAAoB,CAAC,eAAe,EAAE,GAAG,GAAG,IAAI;IAmCvD;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAchC;;;OAGG;IACH,OAAO,CAAC,YAAY;IAcpB;;OAEG;IACH,OAAO,CAAC,cAAc;IA4CtB,4DAA4D;IAC5D,OAAO,CAAC,oBAAoB;IAsB5B;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAiC9B;;OAEG;IACH,OAAO,CAAC,yBAAyB;IAejC,sGAAsG;IACtG,OAAO,CAAC,mBAAmB,CAMzB;IAEF,6EAA6E;IAC7E,OAAO,CAAC,2BAA2B,CAIjC;IAEF,wEAAwE;IACxE,OAAO,CAAC,yBAAyB;CAOlC;AAED,QAAA,MAAM,8BAA8B,EAAE,kBAUrC,CAAC;AAEF,OAAO,EAAE,gCAAgC,EAAE,8BAA8B,EAAE,CAAC"}
@@ -1,229 +0,0 @@
1
- import { logger } from '@sentry/utils';
2
- import { RN_GLOBAL_OBJ } from '../utils/worldwide';
3
- import { InternalRoutingInstrumentation } from './routingInstrumentation';
4
- import { customTransactionSource, defaultTransactionSource } from './utils';
5
- const defaultOptions = {
6
- routeChangeTimeoutMs: 1000,
7
- };
8
- /**
9
- * Instrumentation for React-Navigation V4.
10
- * Register the app container with `registerAppContainer` to use, or see docs for more details.
11
- */
12
- class ReactNavigationV4Instrumentation extends InternalRoutingInstrumentation {
13
- constructor(options = {}) {
14
- super();
15
- this.name = ReactNavigationV4Instrumentation.instrumentationName;
16
- this._appContainer = null;
17
- this._maxRecentRouteLen = 200;
18
- this._recentRouteKeys = [];
19
- this._initialStateHandled = false;
20
- /** Pushes a recent route key, and removes earlier routes when there is greater than the max length */
21
- this._pushRecentRouteKey = (key) => {
22
- this._recentRouteKeys.push(key);
23
- if (this._recentRouteKeys.length > this._maxRecentRouteLen) {
24
- this._recentRouteKeys = this._recentRouteKeys.slice(this._recentRouteKeys.length - this._maxRecentRouteLen);
25
- }
26
- };
27
- /** Helper to log a transaction that was not sampled due to beforeNavigate */
28
- this._onBeforeNavigateNotSampled = (transactionName) => {
29
- logger.log(`[ReactNavigationV4Instrumentation] Will not send transaction "${transactionName}" due to beforeNavigate.`);
30
- };
31
- this._options = Object.assign(Object.assign({}, defaultOptions), options);
32
- }
33
- /**
34
- * Extends by calling _handleInitialState at the end.
35
- */
36
- registerRoutingInstrumentation(listener, beforeNavigate, onConfirmRoute) {
37
- super.registerRoutingInstrumentation(listener, beforeNavigate, onConfirmRoute);
38
- // Need to handle the initial state as the router patch will only attach transactions on subsequent route changes.
39
- if (!this._initialStateHandled) {
40
- this._latestTransaction = this.onRouteWillChange(INITIAL_TRANSACTION_CONTEXT_V4);
41
- if (this._appContainer) {
42
- this._updateLatestTransaction();
43
- this._initialStateHandled = true;
44
- }
45
- else {
46
- this._stateChangeTimeout = setTimeout(this._discardLatestTransaction.bind(this), this._options.routeChangeTimeoutMs);
47
- }
48
- }
49
- }
50
- /**
51
- * Pass the ref to the app container to register it to the instrumentation
52
- * @param appContainerRef Ref to an `AppContainer`
53
- */
54
- // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
55
- registerAppContainer(appContainerRef) {
56
- /* We prevent duplicate routing instrumentation to be initialized on fast refreshes
57
-
58
- Explanation: If the user triggers a fast refresh on the file that the instrumentation is
59
- initialized in, it will initialize a new instance and will cause undefined behavior.
60
- */
61
- if (!RN_GLOBAL_OBJ.__sentry_rn_v4_registered) {
62
- if ('current' in appContainerRef) {
63
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
64
- this._appContainer = appContainerRef.current;
65
- }
66
- else {
67
- this._appContainer = appContainerRef;
68
- }
69
- if (this._appContainer) {
70
- this._patchRouter();
71
- if (!this._initialStateHandled) {
72
- if (this._latestTransaction) {
73
- this._updateLatestTransaction();
74
- }
75
- else {
76
- logger.log('[ReactNavigationV4Instrumentation] App container registered, but integration has not been setup yet.');
77
- }
78
- this._initialStateHandled = true;
79
- }
80
- RN_GLOBAL_OBJ.__sentry_rn_v4_registered = true;
81
- }
82
- else {
83
- logger.warn('[ReactNavigationV4Instrumentation] Received invalid app container ref!');
84
- }
85
- }
86
- }
87
- /**
88
- * Updates the latest transaction with the current state and calls beforeNavigate.
89
- */
90
- _updateLatestTransaction() {
91
- // We can assume the ref is present as this is called from registerAppContainer
92
- if (this._appContainer && this._latestTransaction) {
93
- const state = this._appContainer._navigation.state;
94
- if (typeof this._stateChangeTimeout !== 'undefined') {
95
- clearTimeout(this._stateChangeTimeout);
96
- this._stateChangeTimeout = undefined;
97
- }
98
- this._onStateChange(state, true);
99
- }
100
- }
101
- /**
102
- * Patches the react navigation router so we can listen to the route changes and attach the `IdleTransaction` before the
103
- * new screen is mounted.
104
- */
105
- _patchRouter() {
106
- if (this._appContainer) {
107
- const originalGetStateForAction = this._appContainer._navigation.router.getStateForAction;
108
- this._appContainer._navigation.router.getStateForAction = (action, state) => {
109
- const newState = originalGetStateForAction(action, state);
110
- this._onStateChange(newState);
111
- return newState;
112
- };
113
- }
114
- }
115
- /**
116
- * To be called on navigation state changes and creates the transaction.
117
- */
118
- _onStateChange(state, updateLatestTransaction = false) {
119
- var _a;
120
- // it's not guaranteed that a state is always produced.
121
- // see: https://github.com/react-navigation/react-navigation/blob/45d419be93c34e900e8734ce98321ae875ac4997/packages/core/src/routers/SwitchRouter.js?rgh-link-date=2021-09-25T12%3A43%3A36Z#L301
122
- if (!state || state === undefined) {
123
- logger.warn('[ReactNavigationV4Instrumentation] onStateChange called without a valid state.');
124
- return;
125
- }
126
- const currentRoute = this._getCurrentRouteFromState(state);
127
- // If the route is a different key, this is so we ignore actions that pertain to the same screen.
128
- if (!this._prevRoute || currentRoute.key !== this._prevRoute.key) {
129
- const originalContext = this._getTransactionContext(currentRoute, this._prevRoute);
130
- let mergedContext = originalContext;
131
- if (updateLatestTransaction && this._latestTransaction) {
132
- mergedContext = Object.assign(Object.assign({}, this._latestTransaction.toContext()), originalContext);
133
- }
134
- const finalContext = this._prepareFinalContext(mergedContext);
135
- if (updateLatestTransaction && this._latestTransaction) {
136
- // Update the latest transaction instead of calling onRouteWillChange
137
- this._latestTransaction.updateWithContext(finalContext);
138
- const isCustomName = mergedContext.name !== finalContext.name;
139
- this._latestTransaction.setName(finalContext.name, isCustomName ? customTransactionSource : defaultTransactionSource);
140
- }
141
- else {
142
- this._latestTransaction = this.onRouteWillChange(finalContext);
143
- }
144
- (_a = this._onConfirmRoute) === null || _a === void 0 ? void 0 : _a.call(this, finalContext);
145
- this._pushRecentRouteKey(currentRoute.key);
146
- this._prevRoute = currentRoute;
147
- }
148
- }
149
- /** Creates final transaction context before confirmation */
150
- _prepareFinalContext(mergedContext) {
151
- var _a;
152
- let finalContext = (_a = this._beforeNavigate) === null || _a === void 0 ? void 0 : _a.call(this, Object.assign({}, mergedContext));
153
- // This block is to catch users not returning a transaction context
154
- if (!finalContext) {
155
- logger.error(`[ReactNavigationV4Instrumentation] beforeNavigate returned ${finalContext}, return context.sampled = false to not send transaction.`);
156
- finalContext = Object.assign(Object.assign({}, mergedContext), { sampled: false });
157
- }
158
- if (finalContext.sampled === false) {
159
- this._onBeforeNavigateNotSampled(finalContext.name);
160
- }
161
- return finalContext;
162
- }
163
- /**
164
- * Gets the transaction context for a `NavigationRouteV4`
165
- */
166
- _getTransactionContext(route, previousRoute) {
167
- const data = {
168
- route: {
169
- name: route.routeName,
170
- key: route.key,
171
- // TODO: filter PII params instead of dropping them all
172
- params: {},
173
- hasBeenSeen: this._recentRouteKeys.includes(route.key),
174
- },
175
- previousRoute: previousRoute
176
- ? {
177
- name: previousRoute.routeName,
178
- key: previousRoute.key,
179
- // TODO: filter PII params instead of dropping them all
180
- params: {},
181
- }
182
- : null,
183
- };
184
- return {
185
- name: route.routeName,
186
- op: 'navigation',
187
- tags: {
188
- 'routing.instrumentation': ReactNavigationV4Instrumentation.instrumentationName,
189
- 'routing.route.name': route.routeName,
190
- },
191
- data,
192
- };
193
- }
194
- /**
195
- * Gets the current route given a navigation state
196
- */
197
- _getCurrentRouteFromState(state) {
198
- const parentRoute = state.routes[state.index];
199
- if ('index' in parentRoute &&
200
- 'routes' in parentRoute &&
201
- typeof parentRoute.index === 'number' &&
202
- Array.isArray(parentRoute.routes)) {
203
- return this._getCurrentRouteFromState(parentRoute);
204
- }
205
- return parentRoute;
206
- }
207
- /** Cancels the latest transaction so it does not get sent to Sentry. */
208
- _discardLatestTransaction() {
209
- if (this._latestTransaction) {
210
- this._latestTransaction.sampled = false;
211
- this._latestTransaction.finish();
212
- this._latestTransaction = undefined;
213
- }
214
- }
215
- }
216
- ReactNavigationV4Instrumentation.instrumentationName = 'react-navigation-v4';
217
- const INITIAL_TRANSACTION_CONTEXT_V4 = {
218
- name: 'App Launch',
219
- op: 'navigation',
220
- tags: {
221
- 'routing.instrumentation': ReactNavigationV4Instrumentation.instrumentationName,
222
- },
223
- data: {},
224
- metadata: {
225
- source: 'view',
226
- },
227
- };
228
- export { ReactNavigationV4Instrumentation, INITIAL_TRANSACTION_CONTEXT_V4 };
229
- //# sourceMappingURL=reactnavigationv4.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"reactnavigationv4.js","sourceRoot":"","sources":["../../../src/js/tracing/reactnavigationv4.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAEvC,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD,OAAO,EAAE,8BAA8B,EAAE,MAAM,0BAA0B,CAAC;AAE1E,OAAO,EAAE,uBAAuB,EAAE,wBAAwB,EAAE,MAAM,SAAS,CAAC;AAyC5E,MAAM,cAAc,GAA6B;IAC/C,oBAAoB,EAAE,IAAI;CAC3B,CAAC;AAEF;;;GAGG;AACH,MAAM,gCAAiC,SAAQ,8BAA8B;IAkB3E,YAAmB,UAA6C,EAAE;QAChE,KAAK,EAAE,CAAC;QAhBM,SAAI,GAAW,gCAAgC,CAAC,mBAAmB,CAAC;QAE5E,kBAAa,GAAgC,IAAI,CAAC;QAEzC,uBAAkB,GAAW,GAAG,CAAC;QAG1C,qBAAgB,GAAa,EAAE,CAAC;QAGhC,yBAAoB,GAAY,KAAK,CAAC;QA+O9C,sGAAsG;QAC9F,wBAAmB,GAAG,CAAC,GAAW,EAAQ,EAAE;YAClD,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAEhC,IAAI,IAAI,CAAC,gBAAgB,CAAC,MAAM,GAAG,IAAI,CAAC,kBAAkB,EAAE;gBAC1D,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,MAAM,GAAG,IAAI,CAAC,kBAAkB,CAAC,CAAC;aAC7G;QACH,CAAC,CAAC;QAEF,6EAA6E;QACrE,gCAA2B,GAAG,CAAC,eAAuB,EAAQ,EAAE;YACtE,MAAM,CAAC,GAAG,CACR,iEAAiE,eAAe,0BAA0B,CAC3G,CAAC;QACJ,CAAC,CAAC;QArPA,IAAI,CAAC,QAAQ,mCACR,cAAc,GACd,OAAO,CACX,CAAC;IACJ,CAAC;IAED;;OAEG;IACI,8BAA8B,CACnC,QAA4B,EAC5B,cAA8B,EAC9B,cAA8B;QAE9B,KAAK,CAAC,8BAA8B,CAAC,QAAQ,EAAE,cAAc,EAAE,cAAc,CAAC,CAAC;QAE/E,kHAAkH;QAClH,IAAI,CAAC,IAAI,CAAC,oBAAoB,EAAE;YAC9B,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC,iBAAiB,CAAC,8BAA8B,CAAC,CAAC;YACjF,IAAI,IAAI,CAAC,aAAa,EAAE;gBACtB,IAAI,CAAC,wBAAwB,EAAE,CAAC;gBAEhC,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC;aAClC;iBAAM;gBACL,IAAI,CAAC,mBAAmB,GAAG,UAAU,CACnC,IAAI,CAAC,yBAAyB,CAAC,IAAI,CAAC,IAAI,CAAC,EACzC,IAAI,CAAC,QAAQ,CAAC,oBAAoB,CACnC,CAAC;aACH;SACF;IACH,CAAC;IAED;;;OAGG;IACH,iHAAiH;IAC1G,oBAAoB,CAAC,eAAoB;QAC9C;;;;WAIG;QACH,IAAI,CAAC,aAAa,CAAC,yBAAyB,EAAE;YAC5C,IAAI,SAAS,IAAI,eAAe,EAAE;gBAChC,sEAAsE;gBACtE,IAAI,CAAC,aAAa,GAAG,eAAe,CAAC,OAAO,CAAC;aAC9C;iBAAM;gBACL,IAAI,CAAC,aAAa,GAAG,eAAe,CAAC;aACtC;YAED,IAAI,IAAI,CAAC,aAAa,EAAE;gBACtB,IAAI,CAAC,YAAY,EAAE,CAAC;gBAEpB,IAAI,CAAC,IAAI,CAAC,oBAAoB,EAAE;oBAC9B,IAAI,IAAI,CAAC,kBAAkB,EAAE;wBAC3B,IAAI,CAAC,wBAAwB,EAAE,CAAC;qBACjC;yBAAM;wBACL,MAAM,CAAC,GAAG,CACR,sGAAsG,CACvG,CAAC;qBACH;oBACD,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC;iBAClC;gBAED,aAAa,CAAC,yBAAyB,GAAG,IAAI,CAAC;aAChD;iBAAM;gBACL,MAAM,CAAC,IAAI,CAAC,wEAAwE,CAAC,CAAC;aACvF;SACF;IACH,CAAC;IAED;;OAEG;IACK,wBAAwB;QAC9B,+EAA+E;QAC/E,IAAI,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,kBAAkB,EAAE;YACjD,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,KAAK,CAAC;YAEnD,IAAI,OAAO,IAAI,CAAC,mBAAmB,KAAK,WAAW,EAAE;gBACnD,YAAY,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;gBACvC,IAAI,CAAC,mBAAmB,GAAG,SAAS,CAAC;aACtC;YAED,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;SAClC;IACH,CAAC;IAED;;;OAGG;IACK,YAAY;QAClB,IAAI,IAAI,CAAC,aAAa,EAAE;YACtB,MAAM,yBAAyB,GAAG,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,MAAM,CAAC,iBAAiB,CAAC;YAE1F,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,MAAM,CAAC,iBAAiB,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE;gBAC1E,MAAM,QAAQ,GAAG,yBAAyB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;gBAE1D,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;gBAE9B,OAAO,QAAQ,CAAC;YAClB,CAAC,CAAC;SACH;IACH,CAAC;IAED;;OAEG;IACK,cAAc,CAAC,KAAoC,EAAE,0BAAmC,KAAK;;QACnG,uDAAuD;QACvD,gMAAgM;QAChM,IAAI,CAAC,KAAK,IAAI,KAAK,KAAK,SAAS,EAAE;YACjC,MAAM,CAAC,IAAI,CAAC,gFAAgF,CAAC,CAAC;YAE9F,OAAO;SACR;QAED,MAAM,YAAY,GAAG,IAAI,CAAC,yBAAyB,CAAC,KAAK,CAAC,CAAC;QAE3D,iGAAiG;QACjG,IAAI,CAAC,IAAI,CAAC,UAAU,IAAI,YAAY,CAAC,GAAG,KAAK,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE;YAChE,MAAM,eAAe,GAAG,IAAI,CAAC,sBAAsB,CAAC,YAAY,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;YAEnF,IAAI,aAAa,GAAG,eAAe,CAAC;YACpC,IAAI,uBAAuB,IAAI,IAAI,CAAC,kBAAkB,EAAE;gBACtD,aAAa,mCACR,IAAI,CAAC,kBAAkB,CAAC,SAAS,EAAE,GACnC,eAAe,CACnB,CAAC;aACH;YAED,MAAM,YAAY,GAAG,IAAI,CAAC,oBAAoB,CAAC,aAAa,CAAC,CAAC;YAE9D,IAAI,uBAAuB,IAAI,IAAI,CAAC,kBAAkB,EAAE;gBACtD,qEAAqE;gBACrE,IAAI,CAAC,kBAAkB,CAAC,iBAAiB,CAAC,YAAY,CAAC,CAAC;gBACxD,MAAM,YAAY,GAAG,aAAa,CAAC,IAAI,KAAK,YAAY,CAAC,IAAI,CAAC;gBAC9D,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAC7B,YAAY,CAAC,IAAI,EACjB,YAAY,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,wBAAwB,CAClE,CAAC;aACH;iBAAM;gBACL,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC,iBAAiB,CAAC,YAAY,CAAC,CAAC;aAChE;YAED,MAAA,IAAI,CAAC,eAAe,qDAAG,YAAY,CAAC,CAAC;YAErC,IAAI,CAAC,mBAAmB,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;YAC3C,IAAI,CAAC,UAAU,GAAG,YAAY,CAAC;SAChC;IACH,CAAC;IAED,4DAA4D;IACpD,oBAAoB,CAAC,aAAiC;;QAC5D,IAAI,YAAY,GAAG,MAAA,IAAI,CAAC,eAAe,uEAAQ,aAAa,EAAG,CAAC;QAEhE,mEAAmE;QACnE,IAAI,CAAC,YAAY,EAAE;YACjB,MAAM,CAAC,KAAK,CACV,8DAA8D,YAAY,2DAA2D,CACtI,CAAC;YAEF,YAAY,mCACP,aAAa,KAChB,OAAO,EAAE,KAAK,GACf,CAAC;SACH;QAED,IAAI,YAAY,CAAC,OAAO,KAAK,KAAK,EAAE;YAClC,IAAI,CAAC,2BAA2B,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;SACrD;QAED,OAAO,YAAY,CAAC;IACtB,CAAC;IAED;;OAEG;IACK,sBAAsB,CAC5B,KAAwB,EACxB,aAAiC;QAEjC,MAAM,IAAI,GAA2B;YACnC,KAAK,EAAE;gBACL,IAAI,EAAE,KAAK,CAAC,SAAS;gBACrB,GAAG,EAAE,KAAK,CAAC,GAAG;gBACd,uDAAuD;gBACvD,MAAM,EAAE,EAAE;gBACV,WAAW,EAAE,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC;aACvD;YACD,aAAa,EAAE,aAAa;gBAC1B,CAAC,CAAC;oBACE,IAAI,EAAE,aAAa,CAAC,SAAS;oBAC7B,GAAG,EAAE,aAAa,CAAC,GAAG;oBACtB,uDAAuD;oBACvD,MAAM,EAAE,EAAE;iBACX;gBACH,CAAC,CAAC,IAAI;SACT,CAAC;QAEF,OAAO;YACL,IAAI,EAAE,KAAK,CAAC,SAAS;YACrB,EAAE,EAAE,YAAY;YAChB,IAAI,EAAE;gBACJ,yBAAyB,EAAE,gCAAgC,CAAC,mBAAmB;gBAC/E,oBAAoB,EAAE,KAAK,CAAC,SAAS;aACtC;YACD,IAAI;SACL,CAAC;IACJ,CAAC;IAED;;OAEG;IACK,yBAAyB,CAAC,KAAwB;QACxD,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAE9C,IACE,OAAO,IAAI,WAAW;YACtB,QAAQ,IAAI,WAAW;YACvB,OAAO,WAAW,CAAC,KAAK,KAAK,QAAQ;YACrC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,EACjC;YACA,OAAO,IAAI,CAAC,yBAAyB,CAAC,WAAW,CAAC,CAAC;SACpD;QAED,OAAO,WAAgC,CAAC;IAC1C,CAAC;IAkBD,wEAAwE;IAChE,yBAAyB;QAC/B,IAAI,IAAI,CAAC,kBAAkB,EAAE;YAC3B,IAAI,CAAC,kBAAkB,CAAC,OAAO,GAAG,KAAK,CAAC;YACxC,IAAI,CAAC,kBAAkB,CAAC,MAAM,EAAE,CAAC;YACjC,IAAI,CAAC,kBAAkB,GAAG,SAAS,CAAC;SACrC;IACH,CAAC;;AAlRa,oDAAmB,GAAW,qBAAqB,CAAC;AAqRpE,MAAM,8BAA8B,GAAuB;IACzD,IAAI,EAAE,YAAY;IAClB,EAAE,EAAE,YAAY;IAChB,IAAI,EAAE;QACJ,yBAAyB,EAAE,gCAAgC,CAAC,mBAAmB;KAChF;IACD,IAAI,EAAE,EAAE;IACR,QAAQ,EAAE;QACR,MAAM,EAAE,MAAM;KACf;CACF,CAAC;AAEF,OAAO,EAAE,gCAAgC,EAAE,8BAA8B,EAAE,CAAC","sourcesContent":["/* eslint-disable max-lines */\nimport type { Transaction, TransactionContext } from '@sentry/types';\nimport { logger } from '@sentry/utils';\n\nimport { RN_GLOBAL_OBJ } from '../utils/worldwide';\nimport type { OnConfirmRoute, TransactionCreator } from './routingInstrumentation';\nimport { InternalRoutingInstrumentation } from './routingInstrumentation';\nimport type { BeforeNavigate, ReactNavigationTransactionContext, RouteChangeContextData } from './types';\nimport { customTransactionSource, defaultTransactionSource } from './utils';\n\nexport interface NavigationRouteV4 {\n routeName: string;\n key: string;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n params?: Record<string, any>;\n}\n\nexport interface NavigationStateV4 {\n index: number;\n key: string;\n isTransitioning: boolean;\n routeName?: string;\n routes: (NavigationRouteV4 | NavigationStateV4)[];\n}\n\nexport interface AppContainerInstance {\n _navigation: {\n state: NavigationStateV4;\n router: {\n getStateForAction: (\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n action: any,\n state: NavigationStateV4,\n ) => NavigationStateV4;\n };\n };\n}\n\ninterface ReactNavigationV4Options {\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 * Time is in ms.\n *\n * Default: 1000\n */\n routeChangeTimeoutMs: number;\n}\n\nconst defaultOptions: ReactNavigationV4Options = {\n routeChangeTimeoutMs: 1000,\n};\n\n/**\n * Instrumentation for React-Navigation V4.\n * Register the app container with `registerAppContainer` to use, or see docs for more details.\n */\nclass ReactNavigationV4Instrumentation extends InternalRoutingInstrumentation {\n public static instrumentationName: string = 'react-navigation-v4';\n\n public readonly name: string = ReactNavigationV4Instrumentation.instrumentationName;\n\n private _appContainer: AppContainerInstance | null = null;\n\n private readonly _maxRecentRouteLen: number = 200;\n\n private _prevRoute?: NavigationRouteV4;\n private _recentRouteKeys: string[] = [];\n\n private _latestTransaction?: Transaction;\n private _initialStateHandled: boolean = false;\n private _stateChangeTimeout?: number | undefined;\n\n private _options: ReactNavigationV4Options;\n\n public constructor(options: Partial<ReactNavigationV4Options> = {}) {\n super();\n\n this._options = {\n ...defaultOptions,\n ...options,\n };\n }\n\n /**\n * Extends by calling _handleInitialState at the end.\n */\n public registerRoutingInstrumentation(\n listener: TransactionCreator,\n beforeNavigate: BeforeNavigate,\n onConfirmRoute: OnConfirmRoute,\n ): void {\n super.registerRoutingInstrumentation(listener, beforeNavigate, onConfirmRoute);\n\n // Need to handle the initial state as the router patch will only attach transactions on subsequent route changes.\n if (!this._initialStateHandled) {\n this._latestTransaction = this.onRouteWillChange(INITIAL_TRANSACTION_CONTEXT_V4);\n if (this._appContainer) {\n this._updateLatestTransaction();\n\n this._initialStateHandled = true;\n } else {\n this._stateChangeTimeout = setTimeout(\n this._discardLatestTransaction.bind(this),\n this._options.routeChangeTimeoutMs,\n );\n }\n }\n }\n\n /**\n * Pass the ref to the app container to register it to the instrumentation\n * @param appContainerRef Ref to an `AppContainer`\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types\n public registerAppContainer(appContainerRef: any): void {\n /* We prevent duplicate routing instrumentation to be initialized on fast refreshes\n\n Explanation: If the user triggers a fast refresh on the file that the instrumentation is\n initialized in, it will initialize a new instance and will cause undefined behavior.\n */\n if (!RN_GLOBAL_OBJ.__sentry_rn_v4_registered) {\n if ('current' in appContainerRef) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n this._appContainer = appContainerRef.current;\n } else {\n this._appContainer = appContainerRef;\n }\n\n if (this._appContainer) {\n this._patchRouter();\n\n if (!this._initialStateHandled) {\n if (this._latestTransaction) {\n this._updateLatestTransaction();\n } else {\n logger.log(\n '[ReactNavigationV4Instrumentation] App container registered, but integration has not been setup yet.',\n );\n }\n this._initialStateHandled = true;\n }\n\n RN_GLOBAL_OBJ.__sentry_rn_v4_registered = true;\n } else {\n logger.warn('[ReactNavigationV4Instrumentation] Received invalid app container ref!');\n }\n }\n }\n\n /**\n * Updates the latest transaction with the current state and calls beforeNavigate.\n */\n private _updateLatestTransaction(): void {\n // We can assume the ref is present as this is called from registerAppContainer\n if (this._appContainer && this._latestTransaction) {\n const state = this._appContainer._navigation.state;\n\n if (typeof this._stateChangeTimeout !== 'undefined') {\n clearTimeout(this._stateChangeTimeout);\n this._stateChangeTimeout = undefined;\n }\n\n this._onStateChange(state, true);\n }\n }\n\n /**\n * Patches the react navigation router so we can listen to the route changes and attach the `IdleTransaction` before the\n * new screen is mounted.\n */\n private _patchRouter(): void {\n if (this._appContainer) {\n const originalGetStateForAction = this._appContainer._navigation.router.getStateForAction;\n\n this._appContainer._navigation.router.getStateForAction = (action, state) => {\n const newState = originalGetStateForAction(action, state);\n\n this._onStateChange(newState);\n\n return newState;\n };\n }\n }\n\n /**\n * To be called on navigation state changes and creates the transaction.\n */\n private _onStateChange(state: NavigationStateV4 | undefined, updateLatestTransaction: boolean = false): void {\n // it's not guaranteed that a state is always produced.\n // see: https://github.com/react-navigation/react-navigation/blob/45d419be93c34e900e8734ce98321ae875ac4997/packages/core/src/routers/SwitchRouter.js?rgh-link-date=2021-09-25T12%3A43%3A36Z#L301\n if (!state || state === undefined) {\n logger.warn('[ReactNavigationV4Instrumentation] onStateChange called without a valid state.');\n\n return;\n }\n\n const currentRoute = this._getCurrentRouteFromState(state);\n\n // If the route is a different key, this is so we ignore actions that pertain to the same screen.\n if (!this._prevRoute || currentRoute.key !== this._prevRoute.key) {\n const originalContext = this._getTransactionContext(currentRoute, this._prevRoute);\n\n let mergedContext = originalContext;\n if (updateLatestTransaction && this._latestTransaction) {\n mergedContext = {\n ...this._latestTransaction.toContext(),\n ...originalContext,\n };\n }\n\n const finalContext = this._prepareFinalContext(mergedContext);\n\n if (updateLatestTransaction && this._latestTransaction) {\n // Update the latest transaction instead of calling onRouteWillChange\n this._latestTransaction.updateWithContext(finalContext);\n const isCustomName = mergedContext.name !== finalContext.name;\n this._latestTransaction.setName(\n finalContext.name,\n isCustomName ? customTransactionSource : defaultTransactionSource,\n );\n } else {\n this._latestTransaction = this.onRouteWillChange(finalContext);\n }\n\n this._onConfirmRoute?.(finalContext);\n\n this._pushRecentRouteKey(currentRoute.key);\n this._prevRoute = currentRoute;\n }\n }\n\n /** Creates final transaction context before confirmation */\n private _prepareFinalContext(mergedContext: TransactionContext): TransactionContext {\n let finalContext = this._beforeNavigate?.({ ...mergedContext });\n\n // This block is to catch users not returning a transaction context\n if (!finalContext) {\n logger.error(\n `[ReactNavigationV4Instrumentation] beforeNavigate returned ${finalContext}, return context.sampled = false to not send transaction.`,\n );\n\n finalContext = {\n ...mergedContext,\n sampled: false,\n };\n }\n\n if (finalContext.sampled === false) {\n this._onBeforeNavigateNotSampled(finalContext.name);\n }\n\n return finalContext;\n }\n\n /**\n * Gets the transaction context for a `NavigationRouteV4`\n */\n private _getTransactionContext(\n route: NavigationRouteV4,\n previousRoute?: NavigationRouteV4,\n ): ReactNavigationTransactionContext {\n const data: RouteChangeContextData = {\n route: {\n name: route.routeName, // Include name here too for use in `beforeNavigate`\n key: route.key,\n // TODO: filter PII params instead of dropping them all\n params: {},\n hasBeenSeen: this._recentRouteKeys.includes(route.key),\n },\n previousRoute: previousRoute\n ? {\n name: previousRoute.routeName,\n key: previousRoute.key,\n // TODO: filter PII params instead of dropping them all\n params: {},\n }\n : null,\n };\n\n return {\n name: route.routeName,\n op: 'navigation',\n tags: {\n 'routing.instrumentation': ReactNavigationV4Instrumentation.instrumentationName,\n 'routing.route.name': route.routeName,\n },\n data,\n };\n }\n\n /**\n * Gets the current route given a navigation state\n */\n private _getCurrentRouteFromState(state: NavigationStateV4): NavigationRouteV4 {\n const parentRoute = state.routes[state.index];\n\n if (\n 'index' in parentRoute &&\n 'routes' in parentRoute &&\n typeof parentRoute.index === 'number' &&\n Array.isArray(parentRoute.routes)\n ) {\n return this._getCurrentRouteFromState(parentRoute);\n }\n\n return parentRoute as NavigationRouteV4;\n }\n\n /** Pushes a recent route key, and removes earlier routes when there is greater than the max length */\n private _pushRecentRouteKey = (key: string): void => {\n this._recentRouteKeys.push(key);\n\n if (this._recentRouteKeys.length > this._maxRecentRouteLen) {\n this._recentRouteKeys = this._recentRouteKeys.slice(this._recentRouteKeys.length - this._maxRecentRouteLen);\n }\n };\n\n /** Helper to log a transaction that was not sampled due to beforeNavigate */\n private _onBeforeNavigateNotSampled = (transactionName: string): void => {\n logger.log(\n `[ReactNavigationV4Instrumentation] Will not send transaction \"${transactionName}\" due to beforeNavigate.`,\n );\n };\n\n /** Cancels the latest transaction so it does not get sent to Sentry. */\n private _discardLatestTransaction(): void {\n if (this._latestTransaction) {\n this._latestTransaction.sampled = false;\n this._latestTransaction.finish();\n this._latestTransaction = undefined;\n }\n }\n}\n\nconst INITIAL_TRANSACTION_CONTEXT_V4: TransactionContext = {\n name: 'App Launch',\n op: 'navigation',\n tags: {\n 'routing.instrumentation': ReactNavigationV4Instrumentation.instrumentationName,\n },\n data: {},\n metadata: {\n source: 'view',\n },\n};\n\nexport { ReactNavigationV4Instrumentation, INITIAL_TRANSACTION_CONTEXT_V4 };\n"]}