@sentry/react-native 5.31.1 → 6.0.0-alpha.1

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 +102 -0
  2. package/dist/js/client.d.ts +5 -9
  3. package/dist/js/client.d.ts.map +1 -1
  4. package/dist/js/client.js +11 -42
  5. package/dist/js/client.js.map +1 -1
  6. package/dist/js/index.d.ts +5 -10
  7. package/dist/js/index.d.ts.map +1 -1
  8. package/dist/js/index.js +4 -21
  9. package/dist/js/index.js.map +1 -1
  10. package/dist/js/integrations/debugsymbolicator.d.ts +2 -8
  11. package/dist/js/integrations/debugsymbolicator.d.ts.map +1 -1
  12. package/dist/js/integrations/debugsymbolicator.js +1 -9
  13. package/dist/js/integrations/debugsymbolicator.js.map +1 -1
  14. package/dist/js/integrations/default.d.ts.map +1 -1
  15. package/dist/js/integrations/default.js +16 -4
  16. package/dist/js/integrations/default.js.map +1 -1
  17. package/dist/js/integrations/devicecontext.d.ts +2 -8
  18. package/dist/js/integrations/devicecontext.d.ts.map +1 -1
  19. package/dist/js/integrations/devicecontext.js +0 -9
  20. package/dist/js/integrations/devicecontext.js.map +1 -1
  21. package/dist/js/integrations/eventorigin.d.ts +2 -8
  22. package/dist/js/integrations/eventorigin.d.ts.map +1 -1
  23. package/dist/js/integrations/eventorigin.js +0 -8
  24. package/dist/js/integrations/eventorigin.js.map +1 -1
  25. package/dist/js/integrations/expocontext.d.ts +2 -8
  26. package/dist/js/integrations/expocontext.d.ts.map +1 -1
  27. package/dist/js/integrations/expocontext.js +0 -8
  28. package/dist/js/integrations/expocontext.js.map +1 -1
  29. package/dist/js/integrations/exports.d.ts +5 -0
  30. package/dist/js/integrations/exports.d.ts.map +1 -1
  31. package/dist/js/integrations/exports.js +5 -0
  32. package/dist/js/integrations/exports.js.map +1 -1
  33. package/dist/js/integrations/modulesloader.d.ts +2 -8
  34. package/dist/js/integrations/modulesloader.d.ts.map +1 -1
  35. package/dist/js/integrations/modulesloader.js +0 -8
  36. package/dist/js/integrations/modulesloader.js.map +1 -1
  37. package/dist/js/integrations/nativelinkederrors.d.ts +2 -8
  38. package/dist/js/integrations/nativelinkederrors.d.ts.map +1 -1
  39. package/dist/js/integrations/nativelinkederrors.js +0 -8
  40. package/dist/js/integrations/nativelinkederrors.js.map +1 -1
  41. package/dist/js/integrations/reactnativeerrorhandlers.d.ts +2 -8
  42. package/dist/js/integrations/reactnativeerrorhandlers.d.ts.map +1 -1
  43. package/dist/js/integrations/reactnativeerrorhandlers.js +1 -8
  44. package/dist/js/integrations/reactnativeerrorhandlers.js.map +1 -1
  45. package/dist/js/integrations/reactnativeinfo.d.ts +2 -8
  46. package/dist/js/integrations/reactnativeinfo.d.ts.map +1 -1
  47. package/dist/js/integrations/reactnativeinfo.js +0 -8
  48. package/dist/js/integrations/reactnativeinfo.js.map +1 -1
  49. package/dist/js/integrations/release.d.ts +2 -8
  50. package/dist/js/integrations/release.d.ts.map +1 -1
  51. package/dist/js/integrations/release.js +0 -8
  52. package/dist/js/integrations/release.js.map +1 -1
  53. package/dist/js/integrations/rewriteframes.js +1 -1
  54. package/dist/js/integrations/rewriteframes.js.map +1 -1
  55. package/dist/js/integrations/screenshot.d.ts +2 -8
  56. package/dist/js/integrations/screenshot.d.ts.map +1 -1
  57. package/dist/js/integrations/screenshot.js +2 -11
  58. package/dist/js/integrations/screenshot.js.map +1 -1
  59. package/dist/js/integrations/sdkinfo.d.ts +2 -8
  60. package/dist/js/integrations/sdkinfo.d.ts.map +1 -1
  61. package/dist/js/integrations/sdkinfo.js +0 -8
  62. package/dist/js/integrations/sdkinfo.js.map +1 -1
  63. package/dist/js/integrations/spotlight.d.ts +2 -10
  64. package/dist/js/integrations/spotlight.d.ts.map +1 -1
  65. package/dist/js/integrations/spotlight.js +1 -10
  66. package/dist/js/integrations/spotlight.js.map +1 -1
  67. package/dist/js/integrations/viewhierarchy.d.ts +2 -8
  68. package/dist/js/integrations/viewhierarchy.d.ts.map +1 -1
  69. package/dist/js/integrations/viewhierarchy.js +0 -8
  70. package/dist/js/integrations/viewhierarchy.js.map +1 -1
  71. package/dist/js/options.d.ts +34 -2
  72. package/dist/js/options.d.ts.map +1 -1
  73. package/dist/js/options.js.map +1 -1
  74. package/dist/js/profiling/cache.d.ts +1 -1
  75. package/dist/js/profiling/hermes.d.ts +1 -1
  76. package/dist/js/profiling/hermes.d.ts.map +1 -1
  77. package/dist/js/profiling/integration.d.ts +1 -7
  78. package/dist/js/profiling/integration.d.ts.map +1 -1
  79. package/dist/js/profiling/integration.js +39 -25
  80. package/dist/js/profiling/integration.js.map +1 -1
  81. package/dist/js/profiling/utils.js +2 -1
  82. package/dist/js/profiling/utils.js.map +1 -1
  83. package/dist/js/replay/mobilereplay.d.ts +2 -2
  84. package/dist/js/replay/mobilereplay.d.ts.map +1 -1
  85. package/dist/js/replay/mobilereplay.js.map +1 -1
  86. package/dist/js/replay/networkUtils.d.ts +0 -1
  87. package/dist/js/replay/networkUtils.d.ts.map +1 -1
  88. package/dist/js/scopeSync.d.ts +6 -0
  89. package/dist/js/scopeSync.d.ts.map +1 -0
  90. package/dist/js/scopeSync.js +60 -0
  91. package/dist/js/scopeSync.js.map +1 -0
  92. package/dist/js/sdk.d.ts +1 -20
  93. package/dist/js/sdk.d.ts.map +1 -1
  94. package/dist/js/sdk.js +20 -53
  95. package/dist/js/sdk.js.map +1 -1
  96. package/dist/js/tools/metroconfig.d.ts +1 -1
  97. package/dist/js/tools/metroconfig.d.ts.map +1 -1
  98. package/dist/js/tools/metroconfig.js.map +1 -1
  99. package/dist/js/tools/sentryMetroSerializer.js.map +1 -1
  100. package/dist/js/touchevents.d.ts +0 -1
  101. package/dist/js/touchevents.d.ts.map +1 -1
  102. package/dist/js/touchevents.js +5 -9
  103. package/dist/js/touchevents.js.map +1 -1
  104. package/dist/js/tracing/gesturetracing.d.ts +1 -6
  105. package/dist/js/tracing/gesturetracing.d.ts.map +1 -1
  106. package/dist/js/tracing/gesturetracing.js +8 -12
  107. package/dist/js/tracing/gesturetracing.js.map +1 -1
  108. package/dist/js/tracing/index.d.ts +6 -7
  109. package/dist/js/tracing/index.d.ts.map +1 -1
  110. package/dist/js/tracing/index.js +4 -7
  111. package/dist/js/tracing/index.js.map +1 -1
  112. package/dist/js/tracing/integrations/appStart.d.ts +39 -0
  113. package/dist/js/tracing/integrations/appStart.d.ts.map +1 -0
  114. package/dist/js/tracing/integrations/appStart.js +301 -0
  115. package/dist/js/tracing/integrations/appStart.js.map +1 -0
  116. package/dist/js/tracing/integrations/nativeFrames.d.ts +21 -0
  117. package/dist/js/tracing/integrations/nativeFrames.d.ts.map +1 -0
  118. package/dist/js/tracing/integrations/nativeFrames.js +195 -0
  119. package/dist/js/tracing/integrations/nativeFrames.js.map +1 -0
  120. package/dist/js/tracing/integrations/stalltracking.d.ts +31 -0
  121. package/dist/js/tracing/integrations/stalltracking.d.ts.map +1 -0
  122. package/dist/js/tracing/integrations/stalltracking.js +236 -0
  123. package/dist/js/tracing/integrations/stalltracking.js.map +1 -0
  124. package/dist/js/tracing/integrations/userInteraction.d.ts +11 -0
  125. package/dist/js/tracing/integrations/userInteraction.d.ts.map +1 -0
  126. package/dist/js/tracing/integrations/userInteraction.js +70 -0
  127. package/dist/js/tracing/integrations/userInteraction.js.map +1 -0
  128. package/dist/js/tracing/onSpanEndUtils.d.ts +17 -0
  129. package/dist/js/tracing/onSpanEndUtils.d.ts.map +1 -0
  130. package/dist/js/tracing/onSpanEndUtils.js +112 -0
  131. package/dist/js/tracing/onSpanEndUtils.js.map +1 -0
  132. package/dist/js/tracing/origin.d.ts +2 -0
  133. package/dist/js/tracing/origin.d.ts.map +1 -0
  134. package/dist/js/tracing/origin.js +2 -0
  135. package/dist/js/tracing/origin.js.map +1 -0
  136. package/dist/js/tracing/reactnativenavigation.d.ts +21 -39
  137. package/dist/js/tracing/reactnativenavigation.d.ts.map +1 -1
  138. package/dist/js/tracing/reactnativenavigation.js +98 -87
  139. package/dist/js/tracing/reactnativenavigation.js.map +1 -1
  140. package/dist/js/tracing/reactnativeprofiler.d.ts.map +1 -1
  141. package/dist/js/tracing/reactnativeprofiler.js +6 -13
  142. package/dist/js/tracing/reactnativeprofiler.js.map +1 -1
  143. package/dist/js/tracing/reactnativetracing.d.ts +44 -160
  144. package/dist/js/tracing/reactnativetracing.d.ts.map +1 -1
  145. package/dist/js/tracing/reactnativetracing.js +51 -481
  146. package/dist/js/tracing/reactnativetracing.js.map +1 -1
  147. package/dist/js/tracing/reactnavigation.d.ts +18 -63
  148. package/dist/js/tracing/reactnavigation.d.ts.map +1 -1
  149. package/dist/js/tracing/reactnavigation.js +200 -205
  150. package/dist/js/tracing/reactnavigation.js.map +1 -1
  151. package/dist/js/tracing/semanticAttributes.d.ts +12 -0
  152. package/dist/js/tracing/semanticAttributes.d.ts.map +1 -0
  153. package/dist/js/tracing/semanticAttributes.js +12 -0
  154. package/dist/js/tracing/semanticAttributes.js.map +1 -0
  155. package/dist/js/tracing/span.d.ts +52 -0
  156. package/dist/js/tracing/span.d.ts.map +1 -0
  157. package/dist/js/tracing/span.js +82 -0
  158. package/dist/js/tracing/span.js.map +1 -0
  159. package/dist/js/tracing/timetodisplay.d.ts.map +1 -1
  160. package/dist/js/tracing/timetodisplay.js +14 -29
  161. package/dist/js/tracing/timetodisplay.js.map +1 -1
  162. package/dist/js/tracing/timetodisplaynative.types.d.ts +0 -1
  163. package/dist/js/tracing/timetodisplaynative.types.d.ts.map +1 -1
  164. package/dist/js/tracing/types.d.ts +2 -9
  165. package/dist/js/tracing/types.d.ts.map +1 -1
  166. package/dist/js/tracing/types.js.map +1 -1
  167. package/dist/js/tracing/utils.d.ts +19 -14
  168. package/dist/js/tracing/utils.d.ts.map +1 -1
  169. package/dist/js/tracing/utils.js +38 -52
  170. package/dist/js/tracing/utils.js.map +1 -1
  171. package/dist/js/transports/encodePolyfill.d.ts +3 -0
  172. package/dist/js/transports/encodePolyfill.d.ts.map +1 -0
  173. package/dist/js/transports/encodePolyfill.js +13 -0
  174. package/dist/js/transports/encodePolyfill.js.map +1 -0
  175. package/dist/js/transports/native.d.ts +2 -2
  176. package/dist/js/transports/native.d.ts.map +1 -1
  177. package/dist/js/transports/native.js +2 -1
  178. package/dist/js/transports/native.js.map +1 -1
  179. package/dist/js/utils/AsyncExpiringMap.d.ts +56 -0
  180. package/dist/js/utils/AsyncExpiringMap.d.ts.map +1 -0
  181. package/dist/js/utils/AsyncExpiringMap.js +130 -0
  182. package/dist/js/utils/AsyncExpiringMap.js.map +1 -0
  183. package/dist/js/utils/fill.d.ts +7 -0
  184. package/dist/js/utils/fill.d.ts.map +1 -0
  185. package/dist/js/utils/fill.js +9 -0
  186. package/dist/js/utils/fill.js.map +1 -0
  187. package/dist/js/utils/span.d.ts +19 -0
  188. package/dist/js/utils/span.d.ts.map +1 -0
  189. package/dist/js/utils/span.js +29 -0
  190. package/dist/js/utils/span.js.map +1 -0
  191. package/dist/js/vendor/react-native/index.d.ts +1 -2
  192. package/dist/js/vendor/react-native/index.d.ts.map +1 -1
  193. package/dist/js/vendor/react-native/index.js.map +1 -1
  194. package/dist/js/version.d.ts +1 -1
  195. package/dist/js/version.d.ts.map +1 -1
  196. package/dist/js/version.js +1 -1
  197. package/dist/js/version.js.map +1 -1
  198. package/dist/js/wrapper.d.ts.map +1 -1
  199. package/dist/js/wrapper.js +1 -0
  200. package/dist/js/wrapper.js.map +1 -1
  201. package/package.json +11 -12
  202. package/ts3.8/dist/js/client.d.ts +5 -9
  203. package/ts3.8/dist/js/index.d.ts +5 -10
  204. package/ts3.8/dist/js/integrations/debugsymbolicator.d.ts +2 -8
  205. package/ts3.8/dist/js/integrations/devicecontext.d.ts +2 -8
  206. package/ts3.8/dist/js/integrations/eventorigin.d.ts +2 -8
  207. package/ts3.8/dist/js/integrations/expocontext.d.ts +2 -8
  208. package/ts3.8/dist/js/integrations/exports.d.ts +5 -0
  209. package/ts3.8/dist/js/integrations/modulesloader.d.ts +2 -8
  210. package/ts3.8/dist/js/integrations/nativelinkederrors.d.ts +2 -8
  211. package/ts3.8/dist/js/integrations/reactnativeerrorhandlers.d.ts +2 -8
  212. package/ts3.8/dist/js/integrations/reactnativeinfo.d.ts +2 -8
  213. package/ts3.8/dist/js/integrations/release.d.ts +2 -8
  214. package/ts3.8/dist/js/integrations/screenshot.d.ts +2 -8
  215. package/ts3.8/dist/js/integrations/sdkinfo.d.ts +2 -8
  216. package/ts3.8/dist/js/integrations/spotlight.d.ts +2 -10
  217. package/ts3.8/dist/js/integrations/viewhierarchy.d.ts +2 -8
  218. package/ts3.8/dist/js/options.d.ts +34 -2
  219. package/ts3.8/dist/js/profiling/cache.d.ts +1 -1
  220. package/ts3.8/dist/js/profiling/hermes.d.ts +1 -1
  221. package/ts3.8/dist/js/profiling/integration.d.ts +1 -7
  222. package/ts3.8/dist/js/replay/mobilereplay.d.ts +2 -2
  223. package/ts3.8/dist/js/replay/networkUtils.d.ts +0 -1
  224. package/ts3.8/dist/js/scopeSync.d.ts +6 -0
  225. package/ts3.8/dist/js/sdk.d.ts +1 -20
  226. package/ts3.8/dist/js/touchevents.d.ts +0 -1
  227. package/ts3.8/dist/js/tracing/gesturetracing.d.ts +1 -6
  228. package/ts3.8/dist/js/tracing/index.d.ts +6 -7
  229. package/ts3.8/dist/js/tracing/integrations/appStart.d.ts +39 -0
  230. package/ts3.8/dist/js/tracing/integrations/nativeFrames.d.ts +21 -0
  231. package/ts3.8/dist/js/tracing/integrations/stalltracking.d.ts +31 -0
  232. package/ts3.8/dist/js/tracing/integrations/userInteraction.d.ts +11 -0
  233. package/ts3.8/dist/js/tracing/onSpanEndUtils.d.ts +17 -0
  234. package/ts3.8/dist/js/tracing/origin.d.ts +2 -0
  235. package/ts3.8/dist/js/tracing/reactnativenavigation.d.ts +21 -39
  236. package/ts3.8/dist/js/tracing/reactnativetracing.d.ts +44 -160
  237. package/ts3.8/dist/js/tracing/reactnavigation.d.ts +18 -63
  238. package/ts3.8/dist/js/tracing/semanticAttributes.d.ts +12 -0
  239. package/ts3.8/dist/js/tracing/span.d.ts +52 -0
  240. package/ts3.8/dist/js/tracing/timetodisplaynative.types.d.ts +0 -1
  241. package/ts3.8/dist/js/tracing/types.d.ts +2 -9
  242. package/ts3.8/dist/js/tracing/utils.d.ts +19 -14
  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/AsyncExpiringMap.d.ts +56 -0
  246. package/ts3.8/dist/js/utils/fill.d.ts +7 -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 +1 -2
  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
@@ -0,0 +1,17 @@
1
+ import type { Client, Span } from '@sentry/types';
2
+ /**
3
+ * Hooks on span end event to execute a callback when the span ends.
4
+ */
5
+ export declare function onThisSpanEnd(client: Client, span: Span, callback: (span: Span) => void): void;
6
+ export declare const adjustTransactionDuration: (client: Client, span: Span, maxDurationMs: number) => void;
7
+ export declare const ignoreEmptyBackNavigation: (client: Client | undefined, span: Span) => void;
8
+ /**
9
+ * Idle Transaction callback to only sample transactions with child spans.
10
+ * To avoid side effects of other callbacks this should be hooked as the last callback.
11
+ */
12
+ export declare const onlySampleIfChildSpans: (client: Client, span: Span) => void;
13
+ /**
14
+ * Hooks on AppState change to cancel the span if the app goes background.
15
+ */
16
+ export declare const cancelInBackground: (client: Client, span: Span) => void;
17
+ //# sourceMappingURL=onSpanEndUtils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"onSpanEndUtils.d.ts","sourceRoot":"","sources":["../../../src/js/tracing/onSpanEndUtils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAOlD;;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,IAyB7F,CAAC;AAEF,eAAO,MAAM,yBAAyB,WAAY,MAAM,GAAG,SAAS,QAAQ,IAAI,KAAG,IA0ClF,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,sBAAsB,WAAY,MAAM,QAAQ,IAAI,KAAG,IAmBnE,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,kBAAkB,WAAY,MAAM,QAAQ,IAAI,KAAG,IAgB/D,CAAC"}
@@ -0,0 +1,112 @@
1
+ import { getSpanDescendants, SPAN_STATUS_ERROR, spanToJSON } from '@sentry/core';
2
+ import { logger } from '@sentry/utils';
3
+ import { AppState } from 'react-native';
4
+ import { isRootSpan, isSentrySpan } from '../utils/span';
5
+ /**
6
+ * Hooks on span end event to execute a callback when the span ends.
7
+ */
8
+ export function onThisSpanEnd(client, span, callback) {
9
+ client.on('spanEnd', (endedSpan) => {
10
+ if (span !== endedSpan) {
11
+ return;
12
+ }
13
+ callback(endedSpan);
14
+ });
15
+ }
16
+ export const adjustTransactionDuration = (client, span, maxDurationMs) => {
17
+ if (!isRootSpan(span)) {
18
+ logger.warn('Not sampling empty back spans only works for Sentry Transactions (Root Spans).');
19
+ return;
20
+ }
21
+ client.on('spanEnd', (endedSpan) => {
22
+ if (endedSpan !== span) {
23
+ return;
24
+ }
25
+ const endTimestamp = spanToJSON(span).timestamp;
26
+ const startTimestamp = spanToJSON(span).start_timestamp;
27
+ if (!endTimestamp || !startTimestamp) {
28
+ return;
29
+ }
30
+ const diff = endTimestamp - startTimestamp;
31
+ const isOutdatedTransaction = endTimestamp && (diff > maxDurationMs || diff < 0);
32
+ if (isOutdatedTransaction) {
33
+ span.setStatus({ code: SPAN_STATUS_ERROR, message: 'deadline_exceeded' });
34
+ // TODO: check where was used, might be possible to delete
35
+ span.setAttribute('maxTransactionDurationExceeded', 'true');
36
+ }
37
+ });
38
+ };
39
+ export const ignoreEmptyBackNavigation = (client, span) => {
40
+ if (!client) {
41
+ logger.warn('Could not hook on spanEnd event because client is not defined.');
42
+ return;
43
+ }
44
+ if (!span) {
45
+ logger.warn('Could not hook on spanEnd event because span is not defined.');
46
+ return;
47
+ }
48
+ if (!isRootSpan(span) || !isSentrySpan(span)) {
49
+ logger.warn('Not sampling empty back spans only works for Sentry Transactions (Root Spans).');
50
+ return;
51
+ }
52
+ client.on('spanEnd', (endedSpan) => {
53
+ var _a;
54
+ if (endedSpan !== span) {
55
+ return;
56
+ }
57
+ if (!((_a = spanToJSON(span).data) === null || _a === void 0 ? void 0 : _a['route.has_been_seen'])) {
58
+ return;
59
+ }
60
+ const children = getSpanDescendants(span);
61
+ const filtered = children.filter(child => child.spanContext().spanId !== span.spanContext().spanId &&
62
+ spanToJSON(child).op !== 'ui.load.initial_display' &&
63
+ spanToJSON(child).op !== 'navigation.processing');
64
+ if (filtered.length <= 0) {
65
+ // filter children must include at least one span not created by the navigation automatic instrumentation
66
+ logger.log('Not sampling transaction as route has been seen before. Pass ignoreEmptyBackNavigationTransactions = false to disable this feature.');
67
+ // Route has been seen before and has no child spans.
68
+ span['_sampled'] = false;
69
+ }
70
+ });
71
+ };
72
+ /**
73
+ * Idle Transaction callback to only sample transactions with child spans.
74
+ * To avoid side effects of other callbacks this should be hooked as the last callback.
75
+ */
76
+ export const onlySampleIfChildSpans = (client, span) => {
77
+ if (!isRootSpan(span) || !isSentrySpan(span)) {
78
+ logger.warn('Not sampling childless spans only works for Sentry Transactions (Root Spans).');
79
+ return;
80
+ }
81
+ client.on('spanEnd', (endedSpan) => {
82
+ if (endedSpan !== span) {
83
+ return;
84
+ }
85
+ const children = getSpanDescendants(span);
86
+ if (children.length <= 1) {
87
+ // Span always has at lest one child, itself
88
+ logger.log(`Not sampling as ${spanToJSON(span).op} transaction has no child spans.`);
89
+ span['_sampled'] = false;
90
+ }
91
+ });
92
+ };
93
+ /**
94
+ * Hooks on AppState change to cancel the span if the app goes background.
95
+ */
96
+ export const cancelInBackground = (client, span) => {
97
+ const subscription = AppState.addEventListener('change', (newState) => {
98
+ if (newState === 'background') {
99
+ logger.debug(`Setting ${spanToJSON(span).op} transaction to cancelled because the app is in the background.`);
100
+ span.setStatus({ code: SPAN_STATUS_ERROR, message: 'cancelled' });
101
+ span.end();
102
+ }
103
+ });
104
+ subscription &&
105
+ client.on('spanEnd', (endedSpan) => {
106
+ if (endedSpan === span) {
107
+ logger.debug(`Removing AppState listener for ${spanToJSON(span).op} transaction.`);
108
+ subscription && subscription.remove && subscription.remove();
109
+ }
110
+ });
111
+ };
112
+ //# sourceMappingURL=onSpanEndUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"onSpanEndUtils.js","sourceRoot":"","sources":["../../../src/js/tracing/onSpanEndUtils.ts"],"names":[],"mappings":"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","sourcesContent":["import { getSpanDescendants, SPAN_STATUS_ERROR, spanToJSON } from '@sentry/core';\nimport type { Client, Span } from '@sentry/types';\nimport { logger } from '@sentry/utils';\nimport type { AppStateStatus } from 'react-native';\nimport { AppState } from 'react-native';\n\nimport { isRootSpan, isSentrySpan } from '../utils/span';\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 logger.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;\n const isOutdatedTransaction = endTimestamp && (diff > maxDurationMs || diff < 0);\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\nexport const ignoreEmptyBackNavigation = (client: Client | undefined, span: Span): void => {\n if (!client) {\n logger.warn('Could not hook on spanEnd event because client is not defined.');\n return;\n }\n\n if (!span) {\n logger.warn('Could not hook on spanEnd event because span is not defined.');\n return;\n }\n\n if (!isRootSpan(span) || !isSentrySpan(span)) {\n logger.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 if (!spanToJSON(span).data?.['route.has_been_seen']) {\n return;\n }\n\n const children = getSpanDescendants(span);\n const filtered = 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 if (filtered.length <= 0) {\n // filter children must include at least one span not created by the navigation automatic instrumentation\n logger.log(\n 'Not sampling transaction as route has been seen before. Pass ignoreEmptyBackNavigationTransactions = false to disable this feature.',\n );\n // Route has been seen before and has no child spans.\n span['_sampled'] = false;\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 logger.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 logger.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 */\nexport const cancelInBackground = (client: Client, span: Span): void => {\n const subscription = AppState.addEventListener('change', (newState: AppStateStatus) => {\n if (newState === 'background') {\n logger.debug(`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\n subscription &&\n client.on('spanEnd', (endedSpan: Span) => {\n if (endedSpan === span) {\n logger.debug(`Removing AppState listener for ${spanToJSON(span).op} transaction.`);\n subscription && subscription.remove && subscription.remove();\n }\n });\n};\n"]}
@@ -0,0 +1,2 @@
1
+ export declare const SPAN_ORIGIN_AUTO_INTERACTION = "auto.interaction";
2
+ //# sourceMappingURL=origin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"origin.d.ts","sourceRoot":"","sources":["../../../src/js/tracing/origin.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,4BAA4B,qBAAqB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export const SPAN_ORIGIN_AUTO_INTERACTION = 'auto.interaction';
2
+ //# sourceMappingURL=origin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"origin.js","sourceRoot":"","sources":["../../../src/js/tracing/origin.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,4BAA4B,GAAG,kBAAkB,CAAC","sourcesContent":["export const SPAN_ORIGIN_AUTO_INTERACTION = 'auto.interaction';\n"]}
@@ -1,23 +1,35 @@
1
+ import type { Integration } from '@sentry/types';
1
2
  import type { EmitterSubscription } from '../utils/rnlibrariesinterface';
2
- import type { OnConfirmRoute, TransactionCreator } from './routingInstrumentation';
3
- import { InternalRoutingInstrumentation } from './routingInstrumentation';
4
- import type { BeforeNavigate } from './types';
3
+ export declare const INTEGRATION_NAME = "ReactNativeNavigation";
5
4
  interface ReactNativeNavigationOptions {
6
5
  /**
7
6
  * How long the instrumentation will wait for the route to mount after a change has been initiated,
8
7
  * before the transaction is discarded.
9
- * Time is in ms.
10
8
  *
11
- * Default: 1000
9
+ * @default 1_000 (ms)
12
10
  */
13
- routeChangeTimeoutMs: number;
11
+ routeChangeTimeoutMs?: number;
14
12
  /**
15
13
  * Instrumentation will create a transaction on tab change.
16
14
  * By default only navigation commands create transactions.
17
15
  *
18
- * Default: true
16
+ * @default false
19
17
  */
20
- enableTabsInstrumentation: boolean;
18
+ enableTabsInstrumentation?: boolean;
19
+ /**
20
+ * Does not sample transactions that are from routes that have been seen any more and don't have any spans.
21
+ * This removes a lot of the clutter as most back navigation transactions are now ignored.
22
+ *
23
+ * @default true
24
+ */
25
+ ignoreEmptyBackNavigationTransactions?: boolean;
26
+ /** The React Native Navigation `NavigationDelegate`.
27
+ *
28
+ * ```js
29
+ * import { Navigation } from 'react-native-navigation';
30
+ * ```
31
+ */
32
+ navigation: unknown;
21
33
  }
22
34
  interface ComponentEvent {
23
35
  componentId: string;
@@ -50,36 +62,6 @@ export interface NavigationDelegate {
50
62
  * - `_onComponentWillAppear` is then called AFTER the state change happens due to a dispatch and sets the route context onto the active transaction.
51
63
  * - If `_onComponentWillAppear` isn't called within `options.routeChangeTimeoutMs` of the dispatch, then the transaction is not sampled and finished.
52
64
  */
53
- export declare class ReactNativeNavigationInstrumentation extends InternalRoutingInstrumentation {
54
- static instrumentationName: string;
55
- readonly name: string;
56
- private _navigation;
57
- private _options;
58
- private _prevComponentEvent;
59
- private _latestTransaction?;
60
- private _recentComponentIds;
61
- private _stateChangeTimeout?;
62
- constructor(
63
- /** The react native navigation `NavigationDelegate`. This is usually the import named `Navigation`. */
64
- navigation: unknown, options?: Partial<ReactNativeNavigationOptions>);
65
- /**
66
- * Registers the event listeners for React Native Navigation
67
- */
68
- registerRoutingInstrumentation(listener: TransactionCreator, beforeNavigate: BeforeNavigate, onConfirmRoute: OnConfirmRoute): void;
69
- /**
70
- * To be called when a navigation is initiated. (Command, BottomTabSelected, etc.)
71
- */
72
- private _onNavigation;
73
- /**
74
- * To be called AFTER the state has been changed to populate the transaction with the current route.
75
- */
76
- private _onComponentWillAppear;
77
- /** Creates final transaction context before confirmation */
78
- private _prepareFinalContext;
79
- /** Cancels the latest transaction so it does not get sent to Sentry. */
80
- private _discardLatestTransaction;
81
- /** Cancels the latest transaction so it does not get sent to Sentry. */
82
- private _clearStateChangeTimeout;
83
- }
65
+ export declare const reactNativeNavigationIntegration: ({ navigation: optionsNavigation, routeChangeTimeoutMs, enableTabsInstrumentation, ignoreEmptyBackNavigationTransactions, }: ReactNativeNavigationOptions) => Integration;
84
66
  export {};
85
67
  //# sourceMappingURL=reactnativenavigation.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"reactnativenavigation.d.ts","sourceRoot":"","sources":["../../../src/js/tracing/reactnativenavigation.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AACzE,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AACnF,OAAO,EAAE,8BAA8B,EAAE,MAAM,0BAA0B,CAAC;AAC1E,OAAO,KAAK,EAAE,cAAc,EAA0B,MAAM,SAAS,CAAC;AAGtE,UAAU,4BAA4B;IACpC;;;;;;OAMG;IACH,oBAAoB,EAAE,MAAM,CAAC;IAC7B;;;;;OAKG;IACH,yBAAyB,EAAE,OAAO,CAAC;CACpC;AAOD,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,qBAAa,oCAAqC,SAAQ,8BAA8B;IACtF,OAAc,mBAAmB,EAAE,MAAM,CAA6B;IAEtE,SAAgB,IAAI,EAAE,MAAM,CAA4D;IAExF,OAAO,CAAC,WAAW,CAAqB;IACxC,OAAO,CAAC,QAAQ,CAA+B;IAE/C,OAAO,CAAC,mBAAmB,CAAyC;IAEpE,OAAO,CAAC,kBAAkB,CAAC,CAAkB;IAC7C,OAAO,CAAC,mBAAmB,CAAgB;IAC3C,OAAO,CAAC,mBAAmB,CAAC,CAAqB;;IAG/C,uGAAuG;IACvG,UAAU,EAAE,OAAO,EACnB,OAAO,GAAE,OAAO,CAAC,4BAA4B,CAAM;IAYrD;;OAEG;IACI,8BAA8B,CACnC,QAAQ,EAAE,kBAAkB,EAC5B,cAAc,EAAE,cAAc,EAC9B,cAAc,EAAE,cAAc,GAC7B,IAAI;IAYP;;OAEG;IACH,OAAO,CAAC,aAAa;IAerB;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAyD9B,4DAA4D;IAC5D,OAAO,CAAC,oBAAoB;IAwB5B,wEAAwE;IACxE,OAAO,CAAC,yBAAyB;IAUjC,wEAAwE;IACxE,OAAO,CAAC,wBAAwB;CAMjC"}
1
+ {"version":3,"file":"reactnativenavigation.d.ts","sourceRoot":"","sources":["../../../src/js/tracing/reactnativenavigation.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAU,WAAW,EAAQ,MAAM,eAAe,CAAC;AAE/D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AAYzE,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,WA8HjC,CAAC"}
@@ -1,10 +1,10 @@
1
- import { logger } from '@sentry/utils';
2
- import { InternalRoutingInstrumentation } from './routingInstrumentation';
3
- import { customTransactionSource, defaultTransactionSource, getBlankTransactionContext } from './utils';
4
- const defaultOptions = {
5
- routeChangeTimeoutMs: 1000,
6
- enableTabsInstrumentation: true,
7
- };
1
+ import { addBreadcrumb, getClient, SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, spanToJSON, } from '@sentry/core';
2
+ import { isSentrySpan } from '../utils/span';
3
+ import { ignoreEmptyBackNavigation } from './onSpanEndUtils';
4
+ import { getReactNativeTracingIntegration } from './reactnativetracing';
5
+ import { DEFAULT_NAVIGATION_SPAN_NAME, defaultIdleOptions, getDefaultIdleNavigationSpanOptions, startIdleNavigationSpan as startGenericIdleNavigationSpan, } from './span';
6
+ export const INTEGRATION_NAME = 'ReactNativeNavigation';
7
+ const NAVIGATION_HISTORY_MAX_SIZE = 200;
8
8
  /**
9
9
  * Instrumentation for React Native Navigation. See docs or sample app for usage.
10
10
  *
@@ -13,96 +13,107 @@ const defaultOptions = {
13
13
  * - `_onComponentWillAppear` is then called AFTER the state change happens due to a dispatch and sets the route context onto the active transaction.
14
14
  * - If `_onComponentWillAppear` isn't called within `options.routeChangeTimeoutMs` of the dispatch, then the transaction is not sampled and finished.
15
15
  */
16
- export class ReactNativeNavigationInstrumentation extends InternalRoutingInstrumentation {
17
- constructor(
18
- /** The react native navigation `NavigationDelegate`. This is usually the import named `Navigation`. */
19
- navigation, options = {}) {
20
- super();
21
- this.name = ReactNativeNavigationInstrumentation.instrumentationName;
22
- this._prevComponentEvent = null;
23
- this._recentComponentIds = [];
24
- this._navigation = navigation;
25
- this._options = Object.assign(Object.assign({}, defaultOptions), options);
26
- }
27
- /**
28
- * Registers the event listeners for React Native Navigation
29
- */
30
- registerRoutingInstrumentation(listener, beforeNavigate, onConfirmRoute) {
31
- super.registerRoutingInstrumentation(listener, beforeNavigate, onConfirmRoute);
32
- this._navigation.events().registerCommandListener(this._onNavigation.bind(this));
33
- if (this._options.enableTabsInstrumentation) {
34
- this._navigation.events().registerBottomTabPressedListener(this._onNavigation.bind(this));
16
+ export const reactNativeNavigationIntegration = ({ navigation: optionsNavigation, routeChangeTimeoutMs = 1000, enableTabsInstrumentation = false, ignoreEmptyBackNavigationTransactions = true, }) => {
17
+ const navigation = optionsNavigation;
18
+ let recentComponentIds = [];
19
+ let tracing;
20
+ let idleSpanOptions = defaultIdleOptions;
21
+ let stateChangeTimeout;
22
+ let prevComponentEvent = null;
23
+ let latestNavigationSpan;
24
+ const afterAllSetup = (client) => {
25
+ tracing = getReactNativeTracingIntegration(client);
26
+ if (tracing) {
27
+ idleSpanOptions = {
28
+ finalTimeout: tracing.options.finalTimeoutMs,
29
+ idleTimeout: tracing.options.idleTimeoutMs,
30
+ };
35
31
  }
36
- this._navigation.events().registerComponentWillAppearListener(this._onComponentWillAppear.bind(this));
37
- }
38
- /**
39
- * To be called when a navigation is initiated. (Command, BottomTabSelected, etc.)
40
- */
41
- _onNavigation() {
42
- if (this._latestTransaction) {
43
- this._discardLatestTransaction();
32
+ };
33
+ const startIdleNavigationSpan = () => {
34
+ if (latestNavigationSpan) {
35
+ discardLatestNavigationSpan();
44
36
  }
45
- this._latestTransaction = this.onRouteWillChange(getBlankTransactionContext(ReactNativeNavigationInstrumentation.name));
46
- this._stateChangeTimeout = setTimeout(this._discardLatestTransaction.bind(this), this._options.routeChangeTimeoutMs);
47
- }
48
- /**
49
- * To be called AFTER the state has been changed to populate the transaction with the current route.
50
- */
51
- _onComponentWillAppear(event) {
52
- var _a, _b;
53
- if (!this._latestTransaction) {
37
+ latestNavigationSpan = startGenericIdleNavigationSpan(tracing && tracing.options.beforeStartSpan
38
+ ? tracing.options.beforeStartSpan(getDefaultIdleNavigationSpanOptions())
39
+ : getDefaultIdleNavigationSpanOptions(), idleSpanOptions);
40
+ if (ignoreEmptyBackNavigationTransactions) {
41
+ ignoreEmptyBackNavigation(getClient(), latestNavigationSpan);
42
+ }
43
+ stateChangeTimeout = setTimeout(discardLatestNavigationSpan.bind(this), routeChangeTimeoutMs);
44
+ };
45
+ const updateLatestNavigationSpanWithCurrentComponent = (event) => {
46
+ if (!latestNavigationSpan) {
54
47
  return;
55
48
  }
56
49
  // We ignore actions that pertain to the same screen.
57
- const isSameComponent = this._prevComponentEvent && event.componentId === this._prevComponentEvent.componentId;
50
+ const isSameComponent = prevComponentEvent && event.componentId === prevComponentEvent.componentId;
58
51
  if (isSameComponent) {
59
- this._discardLatestTransaction();
52
+ discardLatestNavigationSpan();
60
53
  return;
61
54
  }
62
- this._clearStateChangeTimeout();
63
- const originalContext = this._latestTransaction.toContext();
64
- const routeHasBeenSeen = this._recentComponentIds.includes(event.componentId);
65
- const data = Object.assign(Object.assign({}, originalContext.data), { route: Object.assign(Object.assign({}, event), { name: event.componentName, hasBeenSeen: routeHasBeenSeen }), previousRoute: this._prevComponentEvent
66
- ? Object.assign(Object.assign({}, this._prevComponentEvent), { name: (_a = this._prevComponentEvent) === null || _a === void 0 ? void 0 : _a.componentName }) : null });
67
- const updatedContext = Object.assign(Object.assign({}, originalContext), { name: event.componentName, tags: Object.assign(Object.assign({}, originalContext.tags), { 'routing.route.name': event.componentName }), data });
68
- const finalContext = this._prepareFinalContext(updatedContext);
69
- this._latestTransaction.updateWithContext(finalContext);
70
- const isCustomName = updatedContext.name !== finalContext.name;
71
- this._latestTransaction.setName(finalContext.name, isCustomName ? customTransactionSource : defaultTransactionSource);
72
- (_b = this._onConfirmRoute) === null || _b === void 0 ? void 0 : _b.call(this, finalContext);
73
- this._prevComponentEvent = event;
74
- this._latestTransaction = undefined;
75
- }
76
- /** Creates final transaction context before confirmation */
77
- _prepareFinalContext(updatedContext) {
78
- var _a;
79
- let finalContext = (_a = this._beforeNavigate) === null || _a === void 0 ? void 0 : _a.call(this, Object.assign({}, updatedContext));
80
- // This block is to catch users not returning a transaction context
81
- if (!finalContext) {
82
- logger.error(`[${ReactNativeNavigationInstrumentation.name}] beforeNavigate returned ${finalContext}, return context.sampled = false to not send transaction.`);
83
- finalContext = Object.assign(Object.assign({}, updatedContext), { sampled: false });
55
+ clearStateChangeTimeout();
56
+ const routeHasBeenSeen = recentComponentIds.includes(event.componentId);
57
+ if (spanToJSON(latestNavigationSpan).description === DEFAULT_NAVIGATION_SPAN_NAME) {
58
+ latestNavigationSpan.updateName(event.componentName);
84
59
  }
85
- if (finalContext.sampled === false) {
86
- logger.log(`[${ReactNativeNavigationInstrumentation.name}] Will not send transaction "${finalContext.name}" due to beforeNavigate.`);
87
- }
88
- return finalContext;
60
+ latestNavigationSpan.setAttributes({
61
+ // TODO: Should we include pass props? I don't know exactly what it contains, cant find it in the RNavigation docs
62
+ 'route.name': event.componentName,
63
+ 'route.component_id': event.componentId,
64
+ 'route.component_type': event.componentType,
65
+ 'route.has_been_seen': routeHasBeenSeen,
66
+ 'previous_route.name': prevComponentEvent === null || prevComponentEvent === void 0 ? void 0 : prevComponentEvent.componentName,
67
+ 'previous_route.component_id': prevComponentEvent === null || prevComponentEvent === void 0 ? void 0 : prevComponentEvent.componentId,
68
+ 'previous_route.component_type': prevComponentEvent === null || prevComponentEvent === void 0 ? void 0 : prevComponentEvent.componentType,
69
+ [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'component',
70
+ [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'navigation',
71
+ });
72
+ tracing === null || tracing === void 0 ? void 0 : tracing.setCurrentRoute(event.componentName);
73
+ addBreadcrumb({
74
+ category: 'navigation',
75
+ type: 'navigation',
76
+ message: `Navigation to ${event.componentName}`,
77
+ data: {
78
+ from: prevComponentEvent === null || prevComponentEvent === void 0 ? void 0 : prevComponentEvent.componentName,
79
+ to: event.componentName,
80
+ },
81
+ });
82
+ pushRecentComponentId(event.componentId);
83
+ prevComponentEvent = event;
84
+ latestNavigationSpan = undefined;
85
+ };
86
+ navigation.events().registerCommandListener(startIdleNavigationSpan);
87
+ if (enableTabsInstrumentation) {
88
+ navigation.events().registerBottomTabPressedListener(startIdleNavigationSpan);
89
89
  }
90
- /** Cancels the latest transaction so it does not get sent to Sentry. */
91
- _discardLatestTransaction() {
92
- if (this._latestTransaction) {
93
- this._latestTransaction.sampled = false;
94
- this._latestTransaction.finish();
95
- this._latestTransaction = undefined;
90
+ navigation.events().registerComponentWillAppearListener(updateLatestNavigationSpanWithCurrentComponent);
91
+ const pushRecentComponentId = (id) => {
92
+ recentComponentIds.push(id);
93
+ if (recentComponentIds.length > NAVIGATION_HISTORY_MAX_SIZE) {
94
+ recentComponentIds = recentComponentIds.slice(recentComponentIds.length - NAVIGATION_HISTORY_MAX_SIZE);
96
95
  }
97
- this._clearStateChangeTimeout();
98
- }
99
- /** Cancels the latest transaction so it does not get sent to Sentry. */
100
- _clearStateChangeTimeout() {
101
- if (typeof this._stateChangeTimeout !== 'undefined') {
102
- clearTimeout(this._stateChangeTimeout);
103
- this._stateChangeTimeout = undefined;
96
+ };
97
+ const discardLatestNavigationSpan = () => {
98
+ if (latestNavigationSpan) {
99
+ if (isSentrySpan(latestNavigationSpan)) {
100
+ latestNavigationSpan['_sampled'] = false;
101
+ }
102
+ // TODO: What if it's not SentrySpan?
103
+ latestNavigationSpan.end();
104
+ latestNavigationSpan = undefined;
104
105
  }
105
- }
106
- }
107
- ReactNativeNavigationInstrumentation.instrumentationName = 'react-native-navigation';
106
+ clearStateChangeTimeout();
107
+ };
108
+ const clearStateChangeTimeout = () => {
109
+ if (typeof stateChangeTimeout !== 'undefined') {
110
+ clearTimeout(stateChangeTimeout);
111
+ stateChangeTimeout = undefined;
112
+ }
113
+ };
114
+ return {
115
+ name: INTEGRATION_NAME,
116
+ afterAllSetup,
117
+ };
118
+ };
108
119
  //# sourceMappingURL=reactnativenavigation.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"reactnativenavigation.js","sourceRoot":"","sources":["../../../src/js/tracing/reactnativenavigation.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAIvC,OAAO,EAAE,8BAA8B,EAAE,MAAM,0BAA0B,CAAC;AAE1E,OAAO,EAAE,uBAAuB,EAAE,wBAAwB,EAAE,0BAA0B,EAAE,MAAM,SAAS,CAAC;AAoBxG,MAAM,cAAc,GAAiC;IACnD,oBAAoB,EAAE,IAAI;IAC1B,yBAAyB,EAAE,IAAI;CAChC,CAAC;AAgCF;;;;;;;GAOG;AACH,MAAM,OAAO,oCAAqC,SAAQ,8BAA8B;IActF;IACE,uGAAuG;IACvG,UAAmB,EACnB,UAAiD,EAAE;QAEnD,KAAK,EAAE,CAAC;QAhBM,SAAI,GAAW,oCAAoC,CAAC,mBAAmB,CAAC;QAKhF,wBAAmB,GAAoC,IAAI,CAAC;QAG5D,wBAAmB,GAAa,EAAE,CAAC;QAUzC,IAAI,CAAC,WAAW,GAAG,UAAgC,CAAC;QAEpD,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,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,uBAAuB,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAEjF,IAAI,IAAI,CAAC,QAAQ,CAAC,yBAAyB,EAAE;YAC3C,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,gCAAgC,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;SAC3F;QAED,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,mCAAmC,CAAC,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IACxG,CAAC;IAED;;OAEG;IACK,aAAa;QACnB,IAAI,IAAI,CAAC,kBAAkB,EAAE;YAC3B,IAAI,CAAC,yBAAyB,EAAE,CAAC;SAClC;QAED,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC,iBAAiB,CAC9C,0BAA0B,CAAC,oCAAoC,CAAC,IAAI,CAAC,CACtE,CAAC;QAEF,IAAI,CAAC,mBAAmB,GAAG,UAAU,CACnC,IAAI,CAAC,yBAAyB,CAAC,IAAI,CAAC,IAAI,CAAC,EACzC,IAAI,CAAC,QAAQ,CAAC,oBAAoB,CACnC,CAAC;IACJ,CAAC;IAED;;OAEG;IACK,sBAAsB,CAAC,KAA+B;;QAC5D,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE;YAC5B,OAAO;SACR;QAED,qDAAqD;QACrD,MAAM,eAAe,GAAG,IAAI,CAAC,mBAAmB,IAAI,KAAK,CAAC,WAAW,KAAK,IAAI,CAAC,mBAAmB,CAAC,WAAW,CAAC;QAC/G,IAAI,eAAe,EAAE;YACnB,IAAI,CAAC,yBAAyB,EAAE,CAAC;YACjC,OAAO;SACR;QAED,IAAI,CAAC,wBAAwB,EAAE,CAAC;QAEhC,MAAM,eAAe,GAAG,IAAI,CAAC,kBAAkB,CAAC,SAAS,EAAE,CAAC;QAC5D,MAAM,gBAAgB,GAAG,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QAE9E,MAAM,IAAI,mCACL,eAAe,CAAC,IAAI,KACvB,KAAK,kCACA,KAAK,KACR,IAAI,EAAE,KAAK,CAAC,aAAa,EACzB,WAAW,EAAE,gBAAgB,KAE/B,aAAa,EAAE,IAAI,CAAC,mBAAmB;gBACrC,CAAC,iCACM,IAAI,CAAC,mBAAmB,KAC3B,IAAI,EAAE,MAAA,IAAI,CAAC,mBAAmB,0CAAE,aAAa,IAEjD,CAAC,CAAC,IAAI,GACT,CAAC;QAEF,MAAM,cAAc,mCACf,eAAe,KAClB,IAAI,EAAE,KAAK,CAAC,aAAa,EACzB,IAAI,kCACC,eAAe,CAAC,IAAI,KACvB,oBAAoB,EAAE,KAAK,CAAC,aAAa,KAE3C,IAAI,GACL,CAAC;QAEF,MAAM,YAAY,GAAG,IAAI,CAAC,oBAAoB,CAAC,cAAc,CAAC,CAAC;QAC/D,IAAI,CAAC,kBAAkB,CAAC,iBAAiB,CAAC,YAAY,CAAC,CAAC;QAExD,MAAM,YAAY,GAAG,cAAc,CAAC,IAAI,KAAK,YAAY,CAAC,IAAI,CAAC;QAC/D,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAC7B,YAAY,CAAC,IAAI,EACjB,YAAY,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,wBAAwB,CAClE,CAAC;QAEF,MAAA,IAAI,CAAC,eAAe,qDAAG,YAAY,CAAC,CAAC;QACrC,IAAI,CAAC,mBAAmB,GAAG,KAAK,CAAC;QAEjC,IAAI,CAAC,kBAAkB,GAAG,SAAS,CAAC;IACtC,CAAC;IAED,4DAA4D;IACpD,oBAAoB,CAAC,cAAkC;;QAC7D,IAAI,YAAY,GAAG,MAAA,IAAI,CAAC,eAAe,uEAAQ,cAAc,EAAG,CAAC;QAEjE,mEAAmE;QACnE,IAAI,CAAC,YAAY,EAAE;YACjB,MAAM,CAAC,KAAK,CACV,IAAI,oCAAoC,CAAC,IAAI,6BAA6B,YAAY,2DAA2D,CAClJ,CAAC;YAEF,YAAY,mCACP,cAAc,KACjB,OAAO,EAAE,KAAK,GACf,CAAC;SACH;QAED,IAAI,YAAY,CAAC,OAAO,KAAK,KAAK,EAAE;YAClC,MAAM,CAAC,GAAG,CACR,IAAI,oCAAoC,CAAC,IAAI,gCAAgC,YAAY,CAAC,IAAI,0BAA0B,CACzH,CAAC;SACH;QAED,OAAO,YAAY,CAAC;IACtB,CAAC;IAED,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;QAED,IAAI,CAAC,wBAAwB,EAAE,CAAC;IAClC,CAAC;IAED,wEAAwE;IAChE,wBAAwB;QAC9B,IAAI,OAAO,IAAI,CAAC,mBAAmB,KAAK,WAAW,EAAE;YACnD,YAAY,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;YACvC,IAAI,CAAC,mBAAmB,GAAG,SAAS,CAAC;SACtC;IACH,CAAC;;AAvKa,wDAAmB,GAAW,yBAAyB,CAAC","sourcesContent":["import type { Transaction as TransactionType, TransactionContext } from '@sentry/types';\nimport { logger } from '@sentry/utils';\n\nimport type { EmitterSubscription } from '../utils/rnlibrariesinterface';\nimport type { OnConfirmRoute, TransactionCreator } from './routingInstrumentation';\nimport { InternalRoutingInstrumentation } from './routingInstrumentation';\nimport type { BeforeNavigate, RouteChangeContextData } from './types';\nimport { customTransactionSource, defaultTransactionSource, getBlankTransactionContext } from './utils';\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 * Time is in ms.\n *\n * Default: 1000\n */\n routeChangeTimeoutMs: number;\n /**\n * Instrumentation will create a transaction on tab change.\n * By default only navigation commands create transactions.\n *\n * Default: true\n */\n enableTabsInstrumentation: boolean;\n}\n\nconst defaultOptions: ReactNativeNavigationOptions = {\n routeChangeTimeoutMs: 1000,\n enableTabsInstrumentation: true,\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 class ReactNativeNavigationInstrumentation extends InternalRoutingInstrumentation {\n public static instrumentationName: string = 'react-native-navigation';\n\n public readonly name: string = ReactNativeNavigationInstrumentation.instrumentationName;\n\n private _navigation: NavigationDelegate;\n private _options: ReactNativeNavigationOptions;\n\n private _prevComponentEvent: ComponentWillAppearEvent | null = null;\n\n private _latestTransaction?: TransactionType;\n private _recentComponentIds: string[] = [];\n private _stateChangeTimeout?: number | undefined;\n\n public constructor(\n /** The react native navigation `NavigationDelegate`. This is usually the import named `Navigation`. */\n navigation: unknown,\n options: Partial<ReactNativeNavigationOptions> = {},\n ) {\n super();\n\n this._navigation = navigation as NavigationDelegate;\n\n this._options = {\n ...defaultOptions,\n ...options,\n };\n }\n\n /**\n * Registers the event listeners for React Native Navigation\n */\n public registerRoutingInstrumentation(\n listener: TransactionCreator,\n beforeNavigate: BeforeNavigate,\n onConfirmRoute: OnConfirmRoute,\n ): void {\n super.registerRoutingInstrumentation(listener, beforeNavigate, onConfirmRoute);\n\n this._navigation.events().registerCommandListener(this._onNavigation.bind(this));\n\n if (this._options.enableTabsInstrumentation) {\n this._navigation.events().registerBottomTabPressedListener(this._onNavigation.bind(this));\n }\n\n this._navigation.events().registerComponentWillAppearListener(this._onComponentWillAppear.bind(this));\n }\n\n /**\n * To be called when a navigation is initiated. (Command, BottomTabSelected, etc.)\n */\n private _onNavigation(): void {\n if (this._latestTransaction) {\n this._discardLatestTransaction();\n }\n\n this._latestTransaction = this.onRouteWillChange(\n getBlankTransactionContext(ReactNativeNavigationInstrumentation.name),\n );\n\n this._stateChangeTimeout = setTimeout(\n this._discardLatestTransaction.bind(this),\n this._options.routeChangeTimeoutMs,\n );\n }\n\n /**\n * To be called AFTER the state has been changed to populate the transaction with the current route.\n */\n private _onComponentWillAppear(event: ComponentWillAppearEvent): void {\n if (!this._latestTransaction) {\n return;\n }\n\n // We ignore actions that pertain to the same screen.\n const isSameComponent = this._prevComponentEvent && event.componentId === this._prevComponentEvent.componentId;\n if (isSameComponent) {\n this._discardLatestTransaction();\n return;\n }\n\n this._clearStateChangeTimeout();\n\n const originalContext = this._latestTransaction.toContext();\n const routeHasBeenSeen = this._recentComponentIds.includes(event.componentId);\n\n const data: RouteChangeContextData = {\n ...originalContext.data,\n route: {\n ...event,\n name: event.componentName,\n hasBeenSeen: routeHasBeenSeen,\n },\n previousRoute: this._prevComponentEvent\n ? {\n ...this._prevComponentEvent,\n name: this._prevComponentEvent?.componentName,\n }\n : null,\n };\n\n const updatedContext = {\n ...originalContext,\n name: event.componentName,\n tags: {\n ...originalContext.tags,\n 'routing.route.name': event.componentName,\n },\n data,\n };\n\n const finalContext = this._prepareFinalContext(updatedContext);\n this._latestTransaction.updateWithContext(finalContext);\n\n const isCustomName = updatedContext.name !== finalContext.name;\n this._latestTransaction.setName(\n finalContext.name,\n isCustomName ? customTransactionSource : defaultTransactionSource,\n );\n\n this._onConfirmRoute?.(finalContext);\n this._prevComponentEvent = event;\n\n this._latestTransaction = undefined;\n }\n\n /** Creates final transaction context before confirmation */\n private _prepareFinalContext(updatedContext: TransactionContext): TransactionContext {\n let finalContext = this._beforeNavigate?.({ ...updatedContext });\n\n // This block is to catch users not returning a transaction context\n if (!finalContext) {\n logger.error(\n `[${ReactNativeNavigationInstrumentation.name}] beforeNavigate returned ${finalContext}, return context.sampled = false to not send transaction.`,\n );\n\n finalContext = {\n ...updatedContext,\n sampled: false,\n };\n }\n\n if (finalContext.sampled === false) {\n logger.log(\n `[${ReactNativeNavigationInstrumentation.name}] Will not send transaction \"${finalContext.name}\" due to beforeNavigate.`,\n );\n }\n\n return finalContext;\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 this._clearStateChangeTimeout();\n }\n\n /** Cancels the latest transaction so it does not get sent to Sentry. */\n private _clearStateChangeTimeout(): void {\n if (typeof this._stateChangeTimeout !== 'undefined') {\n clearTimeout(this._stateChangeTimeout);\n this._stateChangeTimeout = undefined;\n }\n }\n}\n"]}
1
+ {"version":3,"file":"reactnativenavigation.js","sourceRoot":"","sources":["../../../src/js/tracing/reactnativenavigation.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n addBreadcrumb,\n getClient,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n spanToJSON,\n} from '@sentry/core';\nimport type { Client, Integration, Span } from '@sentry/types';\n\nimport type { EmitterSubscription } from '../utils/rnlibrariesinterface';\nimport { isSentrySpan } from '../utils/span';\nimport { ignoreEmptyBackNavigation } from './onSpanEndUtils';\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 && tracing.options.beforeStartSpan\n ? tracing.options.beforeStartSpan(getDefaultIdleNavigationSpanOptions())\n : getDefaultIdleNavigationSpanOptions(),\n idleSpanOptions,\n );\n if (ignoreEmptyBackNavigationTransactions) {\n ignoreEmptyBackNavigation(getClient(), latestNavigationSpan);\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 +1 @@
1
- {"version":3,"file":"reactnativeprofiler.d.ts","sourceRoot":"","sources":["../../../src/js/tracing/reactnativeprofiler.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA4B,QAAQ,EAAE,MAAM,eAAe,CAAC;AAUnE;;GAEG;AACH,qBAAa,mBAAoB,SAAQ,QAAQ;IAC/C,SAAgB,IAAI,EAAE,MAAM,CAAyB;gBAElC,KAAK,EAAE,qBAAqB,CAAC,OAAO,QAAQ,CAAC,CAAC,CAAC,CAAC;IAOnE;;OAEG;IACI,iBAAiB,IAAI,IAAI;IAQhC;;OAEG;IACH,OAAO,CAAC,eAAe;CAoBxB"}
1
+ {"version":3,"file":"reactnativeprofiler.d.ts","sourceRoot":"","sources":["../../../src/js/tracing/reactnativeprofiler.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAa,QAAQ,EAAE,MAAM,eAAe,CAAC;AAUpD;;GAEG;AACH,qBAAa,mBAAoB,SAAQ,QAAQ;IAC/C,SAAgB,IAAI,EAAE,MAAM,CAAyB;gBAElC,KAAK,EAAE,qBAAqB,CAAC,OAAO,QAAQ,CAAC,CAAC,CAAC,CAAC;IAKnE;;OAEG;IACI,iBAAiB,IAAI,IAAI;IAQhC;;OAEG;IACH,OAAO,CAAC,eAAe;CAcxB"}
@@ -1,7 +1,7 @@
1
- import { getClient, getCurrentHub, Profiler } from '@sentry/react';
1
+ import { getClient, Profiler } from '@sentry/react';
2
2
  import { timestampInSeconds } from '@sentry/utils';
3
3
  import { createIntegration } from '../integrations/factory';
4
- import { ReactNativeTracing } from './reactnativetracing';
4
+ import { captureAppStart, setRootComponentCreationTimestampMs } from '../tracing/integrations/appStart';
5
5
  const ReactNativeProfilerGlobalState = {
6
6
  appStartReported: false,
7
7
  };
@@ -10,9 +10,7 @@ const ReactNativeProfilerGlobalState = {
10
10
  */
11
11
  export class ReactNativeProfiler extends Profiler {
12
12
  constructor(props) {
13
- const client = getClient();
14
- const integration = client && client.getIntegrationByName && client.getIntegrationByName('ReactNativeTracing');
15
- integration && integration.setRootComponentFirstConstructorCallTimestampMs(timestampInSeconds() * 1000);
13
+ setRootComponentCreationTimestampMs(timestampInSeconds() * 1000);
16
14
  super(props);
17
15
  this.name = 'ReactNativeProfiler';
18
16
  }
@@ -30,8 +28,7 @@ export class ReactNativeProfiler extends Profiler {
30
28
  * Notifies the Tracing integration that the app start has finished.
31
29
  */
32
30
  _reportAppStart() {
33
- const hub = getCurrentHub();
34
- const client = hub.getClient();
31
+ const client = getClient();
35
32
  if (!client) {
36
33
  // We can't use logger here because this will be logged before the `Sentry.init`.
37
34
  // eslint-disable-next-line no-console
@@ -39,12 +36,8 @@ export class ReactNativeProfiler extends Profiler {
39
36
  return;
40
37
  }
41
38
  client.addIntegration && client.addIntegration(createIntegration(this.name));
42
- const tracingIntegration = hub.getIntegration(ReactNativeTracing);
43
- tracingIntegration
44
- && this._mountSpan
45
- && typeof this._mountSpan.endTimestamp !== 'undefined'
46
- // The first root component mount is the app start finish.
47
- && tracingIntegration.onAppStartFinish(this._mountSpan.endTimestamp);
39
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
40
+ captureAppStart();
48
41
  }
49
42
  }
50
43
  //# sourceMappingURL=reactnativeprofiler.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"reactnativeprofiler.js","sourceRoot":"","sources":["../../../src/js/tracing/reactnativeprofiler.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACnE,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAEnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE1D,MAAM,8BAA8B,GAAG;IACrC,gBAAgB,EAAE,KAAK;CACxB,CAAC;AAEF;;GAEG;AACH,MAAM,OAAO,mBAAoB,SAAQ,QAAQ;IAG/C,YAAmB,KAAgD;QACjE,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;QAC3B,MAAM,WAAW,GAAG,MAAM,IAAI,MAAM,CAAC,oBAAoB,IAAI,MAAM,CAAC,oBAAoB,CAAqB,oBAAoB,CAAC,CAAC;QACnI,WAAW,IAAI,WAAW,CAAC,+CAA+C,CAAC,kBAAkB,EAAE,GAAG,IAAI,CAAC,CAAC;QACxG,KAAK,CAAC,KAAK,CAAC,CAAC;QANC,SAAI,GAAW,qBAAqB,CAAC;IAOrD,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,GAAG,GAAG,aAAa,EAAE,CAAC;QAC5B,MAAM,MAAM,GAAG,GAAG,CAAC,SAAS,EAAE,CAAC;QAE/B,IAAI,CAAC,MAAM,EAAE;YACX,iFAAiF;YACjF,sCAAsC;YACtC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,sFAAsF,CAAC,CAAC;YAChH,OAAO;SACR;QAED,MAAM,CAAC,cAAc,IAAI,MAAM,CAAC,cAAc,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAE7E,MAAM,kBAAkB,GAAG,GAAG,CAAC,cAAc,CAAC,kBAAkB,CAAC,CAAC;QAClE,kBAAkB;eACb,IAAI,CAAC,UAAU;eACf,OAAO,IAAI,CAAC,UAAU,CAAC,YAAY,KAAK,WAAW;YACtD,0DAA0D;eACvD,kBAAkB,CAAC,gBAAgB,CAAC,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;IACzE,CAAC;CACF","sourcesContent":["import { getClient, getCurrentHub, Profiler } from '@sentry/react';\nimport { timestampInSeconds } from '@sentry/utils';\n\nimport { createIntegration } from '../integrations/factory';\nimport { ReactNativeTracing } from './reactnativetracing';\n\nconst ReactNativeProfilerGlobalState = {\n appStartReported: false,\n};\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: ConstructorParameters<typeof Profiler>[0]) {\n const client = getClient();\n const integration = client && client.getIntegrationByName && client.getIntegrationByName<ReactNativeTracing>('ReactNativeTracing');\n integration && integration.setRootComponentFirstConstructorCallTimestampMs(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 hub = getCurrentHub();\n const client = hub.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 && client.addIntegration(createIntegration(this.name));\n\n const tracingIntegration = hub.getIntegration(ReactNativeTracing);\n tracingIntegration\n && this._mountSpan\n && typeof this._mountSpan.endTimestamp !== 'undefined'\n // The first root component mount is the app start finish.\n && tracingIntegration.onAppStartFinish(this._mountSpan.endTimestamp);\n }\n}\n"]}
1
+ {"version":3,"file":"reactnativeprofiler.js","sourceRoot":"","sources":["../../../src/js/tracing/reactnativeprofiler.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAEnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,mCAAmC,EAAE,MAAM,kCAAkC,CAAC;AAExG,MAAM,8BAA8B,GAAG;IACrC,gBAAgB,EAAE,KAAK;CACxB,CAAC;AAEF;;GAEG;AACH,MAAM,OAAO,mBAAoB,SAAQ,QAAQ;IAG/C,YAAmB,KAAgD;QACjE,mCAAmC,CAAC,kBAAkB,EAAE,GAAG,IAAI,CAAC,CAAC;QACjE,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,MAAM,CAAC,cAAc,IAAI,MAAM,CAAC,cAAc,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAC7E,mEAAmE;QACnE,eAAe,EAAE,CAAC;IACpB,CAAC;CACF","sourcesContent":["import { getClient, Profiler } from '@sentry/react';\nimport { timestampInSeconds } from '@sentry/utils';\n\nimport { createIntegration } from '../integrations/factory';\nimport { captureAppStart, setRootComponentCreationTimestampMs } from '../tracing/integrations/appStart';\n\nconst ReactNativeProfilerGlobalState = {\n appStartReported: false,\n};\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: ConstructorParameters<typeof Profiler>[0]) {\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 && client.addIntegration(createIntegration(this.name));\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n captureAppStart();\n }\n}\n"]}