@sentry/browser-utils 10.58.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 (312) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +23 -0
  3. package/build/cjs/debug-build.js +6 -0
  4. package/build/cjs/debug-build.js.map +1 -0
  5. package/build/cjs/getNativeImplementation.js +51 -0
  6. package/build/cjs/getNativeImplementation.js.map +1 -0
  7. package/build/cjs/htmlTreeAsString.js +110 -0
  8. package/build/cjs/htmlTreeAsString.js.map +1 -0
  9. package/build/cjs/index.js +54 -0
  10. package/build/cjs/index.js.map +1 -0
  11. package/build/cjs/instrument/dom.js +137 -0
  12. package/build/cjs/instrument/dom.js.map +1 -0
  13. package/build/cjs/instrument/history.js +56 -0
  14. package/build/cjs/instrument/history.js.map +1 -0
  15. package/build/cjs/instrument/xhr.js +108 -0
  16. package/build/cjs/instrument/xhr.js.map +1 -0
  17. package/build/cjs/is.js +15 -0
  18. package/build/cjs/is.js.map +1 -0
  19. package/build/cjs/metrics/browserMetrics.js +535 -0
  20. package/build/cjs/metrics/browserMetrics.js.map +1 -0
  21. package/build/cjs/metrics/cls.js +64 -0
  22. package/build/cjs/metrics/cls.js.map +1 -0
  23. package/build/cjs/metrics/elementTiming.js +72 -0
  24. package/build/cjs/metrics/elementTiming.js.map +1 -0
  25. package/build/cjs/metrics/inp.js +170 -0
  26. package/build/cjs/metrics/inp.js.map +1 -0
  27. package/build/cjs/metrics/instrument.js +152 -0
  28. package/build/cjs/metrics/instrument.js.map +1 -0
  29. package/build/cjs/metrics/lcp.js +77 -0
  30. package/build/cjs/metrics/lcp.js.map +1 -0
  31. package/build/cjs/metrics/resourceTiming.js +44 -0
  32. package/build/cjs/metrics/resourceTiming.js.map +1 -0
  33. package/build/cjs/metrics/utils.js +137 -0
  34. package/build/cjs/metrics/utils.js.map +1 -0
  35. package/build/cjs/metrics/web-vitals/getCLS.js +46 -0
  36. package/build/cjs/metrics/web-vitals/getCLS.js.map +1 -0
  37. package/build/cjs/metrics/web-vitals/getINP.js +60 -0
  38. package/build/cjs/metrics/web-vitals/getINP.js.map +1 -0
  39. package/build/cjs/metrics/web-vitals/getLCP.js +62 -0
  40. package/build/cjs/metrics/web-vitals/getLCP.js.map +1 -0
  41. package/build/cjs/metrics/web-vitals/lib/InteractionManager.js +87 -0
  42. package/build/cjs/metrics/web-vitals/lib/InteractionManager.js.map +1 -0
  43. package/build/cjs/metrics/web-vitals/lib/LCPEntryManager.js +11 -0
  44. package/build/cjs/metrics/web-vitals/lib/LCPEntryManager.js.map +1 -0
  45. package/build/cjs/metrics/web-vitals/lib/LayoutShiftManager.js +27 -0
  46. package/build/cjs/metrics/web-vitals/lib/LayoutShiftManager.js.map +1 -0
  47. package/build/cjs/metrics/web-vitals/lib/bindReporter.js +31 -0
  48. package/build/cjs/metrics/web-vitals/lib/bindReporter.js.map +1 -0
  49. package/build/cjs/metrics/web-vitals/lib/generateUniqueID.js +8 -0
  50. package/build/cjs/metrics/web-vitals/lib/generateUniqueID.js.map +1 -0
  51. package/build/cjs/metrics/web-vitals/lib/getActivationStart.js +11 -0
  52. package/build/cjs/metrics/web-vitals/lib/getActivationStart.js.map +1 -0
  53. package/build/cjs/metrics/web-vitals/lib/getNavigationEntry.js +17 -0
  54. package/build/cjs/metrics/web-vitals/lib/getNavigationEntry.js.map +1 -0
  55. package/build/cjs/metrics/web-vitals/lib/getVisibilityWatcher.js +48 -0
  56. package/build/cjs/metrics/web-vitals/lib/getVisibilityWatcher.js.map +1 -0
  57. package/build/cjs/metrics/web-vitals/lib/globalListeners.js +18 -0
  58. package/build/cjs/metrics/web-vitals/lib/globalListeners.js.map +1 -0
  59. package/build/cjs/metrics/web-vitals/lib/initMetric.js +34 -0
  60. package/build/cjs/metrics/web-vitals/lib/initMetric.js.map +1 -0
  61. package/build/cjs/metrics/web-vitals/lib/initUnique.js +16 -0
  62. package/build/cjs/metrics/web-vitals/lib/initUnique.js.map +1 -0
  63. package/build/cjs/metrics/web-vitals/lib/observe.js +20 -0
  64. package/build/cjs/metrics/web-vitals/lib/observe.js.map +1 -0
  65. package/build/cjs/metrics/web-vitals/lib/onHidden.js +17 -0
  66. package/build/cjs/metrics/web-vitals/lib/onHidden.js.map +1 -0
  67. package/build/cjs/metrics/web-vitals/lib/polyfills/interactionCountPolyfill.js +32 -0
  68. package/build/cjs/metrics/web-vitals/lib/polyfills/interactionCountPolyfill.js.map +1 -0
  69. package/build/cjs/metrics/web-vitals/lib/runOnce.js +14 -0
  70. package/build/cjs/metrics/web-vitals/lib/runOnce.js.map +1 -0
  71. package/build/cjs/metrics/web-vitals/lib/whenActivated.js +14 -0
  72. package/build/cjs/metrics/web-vitals/lib/whenActivated.js.map +1 -0
  73. package/build/cjs/metrics/web-vitals/lib/whenIdleOrHidden.js +24 -0
  74. package/build/cjs/metrics/web-vitals/lib/whenIdleOrHidden.js.map +1 -0
  75. package/build/cjs/metrics/web-vitals/onFCP.js +37 -0
  76. package/build/cjs/metrics/web-vitals/onFCP.js.map +1 -0
  77. package/build/cjs/metrics/web-vitals/onTTFB.js +35 -0
  78. package/build/cjs/metrics/web-vitals/onTTFB.js.map +1 -0
  79. package/build/cjs/metrics/webVitalSpans.js +199 -0
  80. package/build/cjs/metrics/webVitalSpans.js.map +1 -0
  81. package/build/cjs/networkUtils.js +70 -0
  82. package/build/cjs/networkUtils.js.map +1 -0
  83. package/build/cjs/types.js +8 -0
  84. package/build/cjs/types.js.map +1 -0
  85. package/build/esm/debug-build.js +4 -0
  86. package/build/esm/debug-build.js.map +1 -0
  87. package/build/esm/getNativeImplementation.js +46 -0
  88. package/build/esm/getNativeImplementation.js.map +1 -0
  89. package/build/esm/htmlTreeAsString.js +108 -0
  90. package/build/esm/htmlTreeAsString.js.map +1 -0
  91. package/build/esm/index.js +15 -0
  92. package/build/esm/index.js.map +1 -0
  93. package/build/esm/instrument/dom.js +134 -0
  94. package/build/esm/instrument/dom.js.map +1 -0
  95. package/build/esm/instrument/history.js +53 -0
  96. package/build/esm/instrument/history.js.map +1 -0
  97. package/build/esm/instrument/xhr.js +104 -0
  98. package/build/esm/instrument/xhr.js.map +1 -0
  99. package/build/esm/is.js +13 -0
  100. package/build/esm/is.js.map +1 -0
  101. package/build/esm/metrics/browserMetrics.js +524 -0
  102. package/build/esm/metrics/browserMetrics.js.map +1 -0
  103. package/build/esm/metrics/cls.js +61 -0
  104. package/build/esm/metrics/cls.js.map +1 -0
  105. package/build/esm/metrics/elementTiming.js +69 -0
  106. package/build/esm/metrics/elementTiming.js.map +1 -0
  107. package/build/esm/metrics/inp.js +162 -0
  108. package/build/esm/metrics/inp.js.map +1 -0
  109. package/build/esm/metrics/instrument.js +145 -0
  110. package/build/esm/metrics/instrument.js.map +1 -0
  111. package/build/esm/metrics/lcp.js +72 -0
  112. package/build/esm/metrics/lcp.js.map +1 -0
  113. package/build/esm/metrics/resourceTiming.js +42 -0
  114. package/build/esm/metrics/resourceTiming.js.map +1 -0
  115. package/build/esm/metrics/utils.js +128 -0
  116. package/build/esm/metrics/utils.js.map +1 -0
  117. package/build/esm/metrics/web-vitals/getCLS.js +43 -0
  118. package/build/esm/metrics/web-vitals/getCLS.js.map +1 -0
  119. package/build/esm/metrics/web-vitals/getINP.js +57 -0
  120. package/build/esm/metrics/web-vitals/getINP.js.map +1 -0
  121. package/build/esm/metrics/web-vitals/getLCP.js +59 -0
  122. package/build/esm/metrics/web-vitals/getLCP.js.map +1 -0
  123. package/build/esm/metrics/web-vitals/lib/InteractionManager.js +85 -0
  124. package/build/esm/metrics/web-vitals/lib/InteractionManager.js.map +1 -0
  125. package/build/esm/metrics/web-vitals/lib/LCPEntryManager.js +9 -0
  126. package/build/esm/metrics/web-vitals/lib/LCPEntryManager.js.map +1 -0
  127. package/build/esm/metrics/web-vitals/lib/LayoutShiftManager.js +25 -0
  128. package/build/esm/metrics/web-vitals/lib/LayoutShiftManager.js.map +1 -0
  129. package/build/esm/metrics/web-vitals/lib/bindReporter.js +29 -0
  130. package/build/esm/metrics/web-vitals/lib/bindReporter.js.map +1 -0
  131. package/build/esm/metrics/web-vitals/lib/generateUniqueID.js +6 -0
  132. package/build/esm/metrics/web-vitals/lib/generateUniqueID.js.map +1 -0
  133. package/build/esm/metrics/web-vitals/lib/getActivationStart.js +9 -0
  134. package/build/esm/metrics/web-vitals/lib/getActivationStart.js.map +1 -0
  135. package/build/esm/metrics/web-vitals/lib/getNavigationEntry.js +15 -0
  136. package/build/esm/metrics/web-vitals/lib/getNavigationEntry.js.map +1 -0
  137. package/build/esm/metrics/web-vitals/lib/getVisibilityWatcher.js +46 -0
  138. package/build/esm/metrics/web-vitals/lib/getVisibilityWatcher.js.map +1 -0
  139. package/build/esm/metrics/web-vitals/lib/globalListeners.js +15 -0
  140. package/build/esm/metrics/web-vitals/lib/globalListeners.js.map +1 -0
  141. package/build/esm/metrics/web-vitals/lib/initMetric.js +32 -0
  142. package/build/esm/metrics/web-vitals/lib/initMetric.js.map +1 -0
  143. package/build/esm/metrics/web-vitals/lib/initUnique.js +14 -0
  144. package/build/esm/metrics/web-vitals/lib/initUnique.js.map +1 -0
  145. package/build/esm/metrics/web-vitals/lib/observe.js +18 -0
  146. package/build/esm/metrics/web-vitals/lib/observe.js.map +1 -0
  147. package/build/esm/metrics/web-vitals/lib/onHidden.js +15 -0
  148. package/build/esm/metrics/web-vitals/lib/onHidden.js.map +1 -0
  149. package/build/esm/metrics/web-vitals/lib/polyfills/interactionCountPolyfill.js +29 -0
  150. package/build/esm/metrics/web-vitals/lib/polyfills/interactionCountPolyfill.js.map +1 -0
  151. package/build/esm/metrics/web-vitals/lib/runOnce.js +12 -0
  152. package/build/esm/metrics/web-vitals/lib/runOnce.js.map +1 -0
  153. package/build/esm/metrics/web-vitals/lib/whenActivated.js +12 -0
  154. package/build/esm/metrics/web-vitals/lib/whenActivated.js.map +1 -0
  155. package/build/esm/metrics/web-vitals/lib/whenIdleOrHidden.js +22 -0
  156. package/build/esm/metrics/web-vitals/lib/whenIdleOrHidden.js.map +1 -0
  157. package/build/esm/metrics/web-vitals/onFCP.js +34 -0
  158. package/build/esm/metrics/web-vitals/onFCP.js.map +1 -0
  159. package/build/esm/metrics/web-vitals/onTTFB.js +32 -0
  160. package/build/esm/metrics/web-vitals/onTTFB.js.map +1 -0
  161. package/build/esm/metrics/webVitalSpans.js +191 -0
  162. package/build/esm/metrics/webVitalSpans.js.map +1 -0
  163. package/build/esm/networkUtils.js +64 -0
  164. package/build/esm/networkUtils.js.map +1 -0
  165. package/build/esm/package.json +1 -0
  166. package/build/esm/types.js +6 -0
  167. package/build/esm/types.js.map +1 -0
  168. package/build/types/debug-build.d.ts +7 -0
  169. package/build/types/debug-build.d.ts.map +1 -0
  170. package/build/types/getNativeImplementation.d.ts +69 -0
  171. package/build/types/getNativeImplementation.d.ts.map +1 -0
  172. package/build/types/htmlTreeAsString.d.ts +11 -0
  173. package/build/types/htmlTreeAsString.d.ts.map +1 -0
  174. package/build/types/index.d.ts +15 -0
  175. package/build/types/index.d.ts.map +1 -0
  176. package/build/types/instrument/dom.d.ts +11 -0
  177. package/build/types/instrument/dom.d.ts.map +1 -0
  178. package/build/types/instrument/history.d.ts +15 -0
  179. package/build/types/instrument/history.d.ts.map +1 -0
  180. package/build/types/instrument/xhr.d.ts +14 -0
  181. package/build/types/instrument/xhr.d.ts.map +1 -0
  182. package/build/types/is.d.ts +7 -0
  183. package/build/types/is.d.ts.map +1 -0
  184. package/build/types/metrics/browserMetrics.d.ts +116 -0
  185. package/build/types/metrics/browserMetrics.d.ts.map +1 -0
  186. package/build/types/metrics/cls.d.ts +17 -0
  187. package/build/types/metrics/cls.d.ts.map +1 -0
  188. package/build/types/metrics/elementTiming.d.ts +19 -0
  189. package/build/types/metrics/elementTiming.d.ts.map +1 -0
  190. package/build/types/metrics/inp.d.ts +35 -0
  191. package/build/types/metrics/inp.d.ts.map +1 -0
  192. package/build/types/metrics/instrument.d.ts +121 -0
  193. package/build/types/metrics/instrument.d.ts.map +1 -0
  194. package/build/types/metrics/lcp.d.ts +22 -0
  195. package/build/types/metrics/lcp.d.ts.map +1 -0
  196. package/build/types/metrics/resourceTiming.d.ts +13 -0
  197. package/build/types/metrics/resourceTiming.d.ts.map +1 -0
  198. package/build/types/metrics/utils.d.ts +73 -0
  199. package/build/types/metrics/utils.d.ts.map +1 -0
  200. package/build/types/metrics/web-vitals/getCLS.d.ts +26 -0
  201. package/build/types/metrics/web-vitals/getCLS.d.ts.map +1 -0
  202. package/build/types/metrics/web-vitals/getINP.d.ts +34 -0
  203. package/build/types/metrics/web-vitals/getINP.d.ts.map +1 -0
  204. package/build/types/metrics/web-vitals/getLCP.d.ts +16 -0
  205. package/build/types/metrics/web-vitals/getLCP.d.ts.map +1 -0
  206. package/build/types/metrics/web-vitals/lib/InteractionManager.d.ts +37 -0
  207. package/build/types/metrics/web-vitals/lib/InteractionManager.d.ts.map +1 -0
  208. package/build/types/metrics/web-vitals/lib/LCPEntryManager.d.ts +5 -0
  209. package/build/types/metrics/web-vitals/lib/LCPEntryManager.d.ts.map +1 -0
  210. package/build/types/metrics/web-vitals/lib/LayoutShiftManager.d.ts +7 -0
  211. package/build/types/metrics/web-vitals/lib/LayoutShiftManager.d.ts.map +1 -0
  212. package/build/types/metrics/web-vitals/lib/bindReporter.d.ts +7 -0
  213. package/build/types/metrics/web-vitals/lib/bindReporter.d.ts.map +1 -0
  214. package/build/types/metrics/web-vitals/lib/generateUniqueID.d.ts +7 -0
  215. package/build/types/metrics/web-vitals/lib/generateUniqueID.d.ts.map +1 -0
  216. package/build/types/metrics/web-vitals/lib/getActivationStart.d.ts +2 -0
  217. package/build/types/metrics/web-vitals/lib/getActivationStart.d.ts.map +1 -0
  218. package/build/types/metrics/web-vitals/lib/getNavigationEntry.d.ts +2 -0
  219. package/build/types/metrics/web-vitals/lib/getNavigationEntry.d.ts.map +1 -0
  220. package/build/types/metrics/web-vitals/lib/getVisibilityWatcher.d.ts +5 -0
  221. package/build/types/metrics/web-vitals/lib/getVisibilityWatcher.d.ts.map +1 -0
  222. package/build/types/metrics/web-vitals/lib/globalListeners.d.ts +11 -0
  223. package/build/types/metrics/web-vitals/lib/globalListeners.d.ts.map +1 -0
  224. package/build/types/metrics/web-vitals/lib/initMetric.d.ts +21 -0
  225. package/build/types/metrics/web-vitals/lib/initMetric.d.ts.map +1 -0
  226. package/build/types/metrics/web-vitals/lib/initUnique.d.ts +7 -0
  227. package/build/types/metrics/web-vitals/lib/initUnique.d.ts.map +1 -0
  228. package/build/types/metrics/web-vitals/lib/observe.d.ts +23 -0
  229. package/build/types/metrics/web-vitals/lib/observe.d.ts.map +1 -0
  230. package/build/types/metrics/web-vitals/lib/onHidden.d.ts +27 -0
  231. package/build/types/metrics/web-vitals/lib/onHidden.d.ts.map +1 -0
  232. package/build/types/metrics/web-vitals/lib/polyfills/interactionCountPolyfill.d.ts +15 -0
  233. package/build/types/metrics/web-vitals/lib/polyfills/interactionCountPolyfill.d.ts.map +1 -0
  234. package/build/types/metrics/web-vitals/lib/runOnce.d.ts +2 -0
  235. package/build/types/metrics/web-vitals/lib/runOnce.d.ts.map +1 -0
  236. package/build/types/metrics/web-vitals/lib/whenActivated.d.ts +2 -0
  237. package/build/types/metrics/web-vitals/lib/whenActivated.d.ts.map +1 -0
  238. package/build/types/metrics/web-vitals/lib/whenIdleOrHidden.d.ts +6 -0
  239. package/build/types/metrics/web-vitals/lib/whenIdleOrHidden.d.ts.map +1 -0
  240. package/build/types/metrics/web-vitals/onFCP.d.ts +11 -0
  241. package/build/types/metrics/web-vitals/onFCP.d.ts.map +1 -0
  242. package/build/types/metrics/web-vitals/onTTFB.d.ts +20 -0
  243. package/build/types/metrics/web-vitals/onTTFB.d.ts.map +1 -0
  244. package/build/types/metrics/web-vitals/types/base.d.ts +103 -0
  245. package/build/types/metrics/web-vitals/types/base.d.ts.map +1 -0
  246. package/build/types/metrics/web-vitals/types/cls.d.ts +58 -0
  247. package/build/types/metrics/web-vitals/types/cls.d.ts.map +1 -0
  248. package/build/types/metrics/web-vitals/types/fcp.d.ts +47 -0
  249. package/build/types/metrics/web-vitals/types/fcp.d.ts.map +1 -0
  250. package/build/types/metrics/web-vitals/types/inp.d.ts +150 -0
  251. package/build/types/metrics/web-vitals/types/inp.d.ts.map +1 -0
  252. package/build/types/metrics/web-vitals/types/lcp.d.ts +74 -0
  253. package/build/types/metrics/web-vitals/types/lcp.d.ts.map +1 -0
  254. package/build/types/metrics/web-vitals/types/ttfb.d.ts +60 -0
  255. package/build/types/metrics/web-vitals/types/ttfb.d.ts.map +1 -0
  256. package/build/types/metrics/web-vitals/types.d.ts +78 -0
  257. package/build/types/metrics/web-vitals/types.d.ts.map +1 -0
  258. package/build/types/metrics/webVitalSpans.d.ts +65 -0
  259. package/build/types/metrics/webVitalSpans.d.ts.map +1 -0
  260. package/build/types/networkUtils.d.ts +25 -0
  261. package/build/types/networkUtils.d.ts.map +1 -0
  262. package/build/types/types.d.ts +15 -0
  263. package/build/types/types.d.ts.map +1 -0
  264. package/build/types-ts3.8/debug-build.d.ts +7 -0
  265. package/build/types-ts3.8/getNativeImplementation.d.ts +69 -0
  266. package/build/types-ts3.8/htmlTreeAsString.d.ts +11 -0
  267. package/build/types-ts3.8/index.d.ts +15 -0
  268. package/build/types-ts3.8/instrument/dom.d.ts +11 -0
  269. package/build/types-ts3.8/instrument/history.d.ts +15 -0
  270. package/build/types-ts3.8/instrument/xhr.d.ts +14 -0
  271. package/build/types-ts3.8/is.d.ts +7 -0
  272. package/build/types-ts3.8/metrics/browserMetrics.d.ts +119 -0
  273. package/build/types-ts3.8/metrics/cls.d.ts +17 -0
  274. package/build/types-ts3.8/metrics/elementTiming.d.ts +19 -0
  275. package/build/types-ts3.8/metrics/inp.d.ts +35 -0
  276. package/build/types-ts3.8/metrics/instrument.d.ts +121 -0
  277. package/build/types-ts3.8/metrics/lcp.d.ts +22 -0
  278. package/build/types-ts3.8/metrics/resourceTiming.d.ts +13 -0
  279. package/build/types-ts3.8/metrics/utils.d.ts +73 -0
  280. package/build/types-ts3.8/metrics/web-vitals/getCLS.d.ts +26 -0
  281. package/build/types-ts3.8/metrics/web-vitals/getINP.d.ts +34 -0
  282. package/build/types-ts3.8/metrics/web-vitals/getLCP.d.ts +16 -0
  283. package/build/types-ts3.8/metrics/web-vitals/lib/InteractionManager.d.ts +37 -0
  284. package/build/types-ts3.8/metrics/web-vitals/lib/LCPEntryManager.d.ts +5 -0
  285. package/build/types-ts3.8/metrics/web-vitals/lib/LayoutShiftManager.d.ts +7 -0
  286. package/build/types-ts3.8/metrics/web-vitals/lib/bindReporter.d.ts +7 -0
  287. package/build/types-ts3.8/metrics/web-vitals/lib/generateUniqueID.d.ts +7 -0
  288. package/build/types-ts3.8/metrics/web-vitals/lib/getActivationStart.d.ts +2 -0
  289. package/build/types-ts3.8/metrics/web-vitals/lib/getNavigationEntry.d.ts +2 -0
  290. package/build/types-ts3.8/metrics/web-vitals/lib/getVisibilityWatcher.d.ts +5 -0
  291. package/build/types-ts3.8/metrics/web-vitals/lib/globalListeners.d.ts +11 -0
  292. package/build/types-ts3.8/metrics/web-vitals/lib/initMetric.d.ts +21 -0
  293. package/build/types-ts3.8/metrics/web-vitals/lib/initUnique.d.ts +7 -0
  294. package/build/types-ts3.8/metrics/web-vitals/lib/observe.d.ts +23 -0
  295. package/build/types-ts3.8/metrics/web-vitals/lib/onHidden.d.ts +27 -0
  296. package/build/types-ts3.8/metrics/web-vitals/lib/polyfills/interactionCountPolyfill.d.ts +15 -0
  297. package/build/types-ts3.8/metrics/web-vitals/lib/runOnce.d.ts +2 -0
  298. package/build/types-ts3.8/metrics/web-vitals/lib/whenActivated.d.ts +2 -0
  299. package/build/types-ts3.8/metrics/web-vitals/lib/whenIdleOrHidden.d.ts +6 -0
  300. package/build/types-ts3.8/metrics/web-vitals/onFCP.d.ts +11 -0
  301. package/build/types-ts3.8/metrics/web-vitals/onTTFB.d.ts +20 -0
  302. package/build/types-ts3.8/metrics/web-vitals/types/base.d.ts +106 -0
  303. package/build/types-ts3.8/metrics/web-vitals/types/cls.d.ts +58 -0
  304. package/build/types-ts3.8/metrics/web-vitals/types/fcp.d.ts +47 -0
  305. package/build/types-ts3.8/metrics/web-vitals/types/inp.d.ts +150 -0
  306. package/build/types-ts3.8/metrics/web-vitals/types/lcp.d.ts +74 -0
  307. package/build/types-ts3.8/metrics/web-vitals/types/ttfb.d.ts +60 -0
  308. package/build/types-ts3.8/metrics/web-vitals/types.d.ts +78 -0
  309. package/build/types-ts3.8/metrics/webVitalSpans.d.ts +65 -0
  310. package/build/types-ts3.8/networkUtils.d.ts +28 -0
  311. package/build/types-ts3.8/types.d.ts +15 -0
  312. package/package.json +69 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browserMetrics.js","sources":["../../../src/metrics/browserMetrics.ts"],"sourcesContent":["/* eslint-disable max-lines */\nimport type { Client, Measurements, Span, SpanAttributes, SpanAttributeValue, StartSpanOptions } from '@sentry/core';\nimport {\n browserPerformanceTimeOrigin,\n debug,\n getActiveSpan,\n getComponentName,\n isPrimitive,\n parseUrl,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n setMeasurement,\n spanToJSON,\n stringMatchesSomePattern,\n} from '@sentry/core';\nimport { htmlTreeAsString } from '../htmlTreeAsString';\nimport { WINDOW } from '../types';\nimport { trackClsAsStandaloneSpan } from './cls';\nimport {\n addClsInstrumentationHandler,\n addLcpInstrumentationHandler,\n addPerformanceInstrumentationHandler,\n addTtfbInstrumentationHandler,\n type PerformanceLongAnimationFrameTiming,\n} from './instrument';\nimport { isValidLcpMetric, trackLcpAsStandaloneSpan } from './lcp';\nimport { resourceTimingToSpanAttributes } from './resourceTiming';\nimport { getBrowserPerformanceAPI, isMeasurementValue, msToSec, startAndEndSpan } from './utils';\nimport { getActivationStart } from './web-vitals/lib/getActivationStart';\nimport { getNavigationEntry } from './web-vitals/lib/getNavigationEntry';\nimport { getVisibilityWatcher } from './web-vitals/lib/getVisibilityWatcher';\nimport { DEBUG_BUILD } from '../debug-build';\ninterface NavigatorNetworkInformation {\n readonly connection?: NetworkInformation;\n}\n\n// http://wicg.github.io/netinfo/#connection-types\ntype ConnectionType = 'bluetooth' | 'cellular' | 'ethernet' | 'mixed' | 'none' | 'other' | 'unknown' | 'wifi' | 'wimax';\n\n// http://wicg.github.io/netinfo/#effectiveconnectiontype-enum\ntype EffectiveConnectionType = '2g' | '3g' | '4g' | 'slow-2g';\n\n// http://wicg.github.io/netinfo/#dom-megabit\ntype Megabit = number;\n// http://wicg.github.io/netinfo/#dom-millisecond\ntype Millisecond = number;\n\n// http://wicg.github.io/netinfo/#networkinformation-interface\ninterface NetworkInformation extends EventTarget {\n // http://wicg.github.io/netinfo/#type-attribute\n readonly type?: ConnectionType;\n // http://wicg.github.io/netinfo/#effectivetype-attribute\n readonly effectiveType?: EffectiveConnectionType;\n // http://wicg.github.io/netinfo/#downlinkmax-attribute\n readonly downlinkMax?: Megabit;\n // http://wicg.github.io/netinfo/#downlink-attribute\n readonly downlink?: Megabit;\n // http://wicg.github.io/netinfo/#rtt-attribute\n readonly rtt?: Millisecond;\n // http://wicg.github.io/netinfo/#savedata-attribute\n readonly saveData?: boolean;\n // http://wicg.github.io/netinfo/#handling-changes-to-the-underlying-connection\n onchange?: EventListener;\n}\n\n// https://w3c.github.io/device-memory/#sec-device-memory-js-api\ninterface NavigatorDeviceMemory {\n readonly deviceMemory?: number;\n}\n\nconst MAX_INT_AS_BYTES = 2147483647;\n\nlet _performanceCursor: number = 0;\n\nlet _measurements: Measurements = {};\nlet _lcpEntry: LargestContentfulPaint | undefined;\nlet _clsEntry: LayoutShift | undefined;\n\ninterface StartTrackingWebVitalsOptions {\n /**\n * When `true`, CLS is tracked as a standalone span. When `false`, CLS is\n * recorded as a measurement on the pageload span. When `undefined`, CLS\n * tracking is skipped entirely (e.g. because span streaming handles it).\n */\n recordClsStandaloneSpans: boolean | undefined;\n /**\n * When `true`, LCP is tracked as a standalone span. When `false`, LCP is\n * recorded as a measurement on the pageload span. When `undefined`, LCP\n * tracking is skipped entirely (e.g. because span streaming handles it).\n */\n recordLcpStandaloneSpans: boolean | undefined;\n client: Client;\n}\n\n/**\n * Start tracking web vitals.\n * The callback returned by this function can be used to stop tracking & ensure all measurements are final & captured.\n *\n * @deprecated this function will be removed and streamlined once we stop supporting standalone v1\n * @returns A function that forces web vitals collection\n */\nexport function startTrackingWebVitals({\n recordClsStandaloneSpans,\n recordLcpStandaloneSpans,\n client,\n}: StartTrackingWebVitalsOptions): () => void {\n const performance = getBrowserPerformanceAPI();\n if (performance && browserPerformanceTimeOrigin()) {\n // @ts-expect-error we want to make sure all of these are available, even if TS is sure they are\n if (performance.mark) {\n WINDOW.performance.mark('sentry-tracing-init');\n }\n\n const lcpCleanupCallback = recordLcpStandaloneSpans\n ? trackLcpAsStandaloneSpan(client)\n : recordLcpStandaloneSpans === false\n ? _trackLCP()\n : undefined;\n\n const clsCleanupCallback = recordClsStandaloneSpans\n ? trackClsAsStandaloneSpan(client)\n : recordClsStandaloneSpans === false\n ? _trackCLS()\n : undefined;\n\n const ttfbCleanupCallback = _trackTtfb();\n const fpFcpCleanupCallback = _trackFpFcp();\n\n return (): void => {\n ttfbCleanupCallback();\n fpFcpCleanupCallback();\n lcpCleanupCallback?.();\n clsCleanupCallback?.();\n };\n }\n\n return () => undefined;\n}\n\n/**\n * Start tracking long tasks.\n */\nexport function startTrackingLongTasks(): void {\n addPerformanceInstrumentationHandler('longtask', ({ entries }) => {\n const parent = getActiveSpan();\n if (!parent) {\n return;\n }\n\n const { op: parentOp, start_timestamp: parentStartTimestamp } = spanToJSON(parent);\n\n for (const entry of entries) {\n const startTime = msToSec((browserPerformanceTimeOrigin() as number) + entry.startTime);\n const duration = msToSec(entry.duration);\n\n if (parentOp === 'navigation' && parentStartTimestamp && startTime < parentStartTimestamp) {\n // Skip adding a span if the long task started before the navigation started.\n // `startAndEndSpan` will otherwise adjust the parent's start time to the span's start\n // time, potentially skewing the duration of the actual navigation as reported via our\n // routing instrumentations\n continue;\n }\n\n startAndEndSpan(parent, startTime, startTime + duration, {\n name: 'Main UI thread blocked',\n op: 'ui.long-task',\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.browser.metrics',\n },\n });\n }\n });\n}\n\n/**\n * Start tracking long animation frames.\n */\nexport function startTrackingLongAnimationFrames(): void {\n // NOTE: the current web-vitals version (3.5.2) does not support long-animation-frame, so\n // we directly observe `long-animation-frame` events instead of through the web-vitals\n // `observe` helper function.\n const observer = new PerformanceObserver(list => {\n const parent = getActiveSpan();\n if (!parent) {\n return;\n }\n for (const entry of list.getEntries() as PerformanceLongAnimationFrameTiming[]) {\n if (!entry.scripts[0]) {\n continue;\n }\n\n const startTime = msToSec((browserPerformanceTimeOrigin() as number) + entry.startTime);\n\n const { start_timestamp: parentStartTimestamp, op: parentOp } = spanToJSON(parent);\n\n if (parentOp === 'navigation' && parentStartTimestamp && startTime < parentStartTimestamp) {\n // Skip adding the span if the long animation frame started before the navigation started.\n // `startAndEndSpan` will otherwise adjust the parent's start time to the span's start\n // time, potentially skewing the duration of the actual navigation as reported via our\n // routing instrumentations\n continue;\n }\n const duration = msToSec(entry.duration);\n\n const attributes: SpanAttributes = {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.browser.metrics',\n };\n\n const initialScript = entry.scripts[0];\n const { invoker, invokerType, sourceURL, sourceFunctionName, sourceCharPosition } = initialScript;\n attributes['browser.script.invoker'] = invoker;\n attributes['browser.script.invoker_type'] = invokerType;\n if (sourceURL) {\n attributes['code.filepath'] = sourceURL;\n }\n if (sourceFunctionName) {\n attributes['code.function'] = sourceFunctionName;\n }\n if (sourceCharPosition !== -1) {\n attributes['browser.script.source_char_position'] = sourceCharPosition;\n }\n\n startAndEndSpan(parent, startTime, startTime + duration, {\n name: 'Main UI thread blocked',\n op: 'ui.long-animation-frame',\n attributes,\n });\n }\n });\n\n observer.observe({ type: 'long-animation-frame', buffered: true });\n}\n\n/**\n * Start tracking interaction events.\n */\nexport function startTrackingInteractions(): void {\n addPerformanceInstrumentationHandler('event', ({ entries }) => {\n const parent = getActiveSpan();\n if (!parent) {\n return;\n }\n for (const entry of entries) {\n if (entry.name === 'click') {\n const startTime = msToSec((browserPerformanceTimeOrigin() as number) + entry.startTime);\n const duration = msToSec(entry.duration);\n\n const spanOptions: StartSpanOptions & Required<Pick<StartSpanOptions, 'attributes'>> = {\n name: htmlTreeAsString(entry.target),\n op: `ui.interaction.${entry.name}`,\n startTime: startTime,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.browser.metrics',\n },\n };\n\n const componentName = getComponentName(entry.target);\n if (componentName) {\n spanOptions.attributes['ui.component_name'] = componentName;\n }\n\n startAndEndSpan(parent, startTime, startTime + duration, spanOptions);\n }\n }\n });\n}\n\nexport { registerInpInteractionListener, startTrackingINP } from './inp';\n\n/**\n * Starts tracking the Cumulative Layout Shift on the current page and collects the value and last entry\n * to the `_measurements` object which ultimately is applied to the pageload span's measurements.\n */\nfunction _trackCLS(): () => void {\n return addClsInstrumentationHandler(({ metric }) => {\n const entry = metric.entries[metric.entries.length - 1] as LayoutShift | undefined;\n if (!entry) {\n return;\n }\n _measurements['cls'] = { value: metric.value, unit: '' };\n _clsEntry = entry;\n }, true);\n}\n\n/** Starts tracking the Largest Contentful Paint on the current page. */\nfunction _trackLCP(): () => void {\n return addLcpInstrumentationHandler(({ metric }) => {\n const entry = metric.entries[metric.entries.length - 1];\n if (!entry || !isValidLcpMetric(metric.value)) {\n return;\n }\n\n _measurements['lcp'] = { value: metric.value, unit: 'millisecond' };\n _lcpEntry = entry as LargestContentfulPaint;\n }, true);\n}\n\nfunction _trackTtfb(): () => void {\n return addTtfbInstrumentationHandler(({ metric }) => {\n const entry = metric.entries[metric.entries.length - 1];\n if (!entry) {\n return;\n }\n\n _measurements['ttfb'] = { value: metric.value, unit: 'millisecond' };\n });\n}\n\n/** Starts tracking First Paint and First Contentful Paint on the current page. */\nfunction _trackFpFcp(): () => void {\n return addPerformanceInstrumentationHandler('paint', ({ entries }) => {\n const firstHidden = getVisibilityWatcher();\n for (const entry of entries) {\n // Only report if the page wasn't hidden prior to the web vital.\n const shouldRecord = entry.startTime < firstHidden.firstHiddenTime;\n if (entry.name === 'first-paint' && shouldRecord) {\n _measurements['fp'] = { value: entry.startTime, unit: 'millisecond' };\n }\n if (entry.name === 'first-contentful-paint' && shouldRecord) {\n _measurements['fcp'] = { value: entry.startTime, unit: 'millisecond' };\n }\n }\n });\n}\n\ninterface AddPerformanceEntriesOptions {\n /**\n * Resource spans with `op`s matching strings in the array will not be emitted.\n *\n * Default: []\n */\n ignoreResourceSpans: Array<'resouce.script' | 'resource.css' | 'resource.img' | 'resource.other' | string>;\n\n /**\n * Performance spans created from browser Performance APIs,\n * `performance.mark(...)` nand `performance.measure(...)`\n * with `name`s matching strings in the array will not be emitted.\n *\n * Default: []\n */\n ignorePerformanceApiSpans: Array<string | RegExp>;\n\n /**\n * Whether span streaming is enabled.\n */\n spanStreamingEnabled?: boolean;\n}\n\ninterface AddWebVitalsToSpanOptions {\n /**\n * Flag to determine if CLS should be recorded as a measurement on the pageload span or\n * sent as a standalone span instead.\n * Sending it as a standalone span will yield more accurate LCP values.\n *\n * Default: `false` for backwards compatibility.\n */\n recordClsOnPageloadSpan: boolean;\n\n /**\n * Flag to determine if LCP should be recorded as a measurement on the pageload span or\n * sent as a standalone span instead.\n * Sending it as a standalone span will yield more accurate LCP values.\n *\n * Default: `false` for backwards compatibility.\n */\n recordLcpOnPageloadSpan: boolean;\n\n /**\n * Whether span streaming is enabled.\n */\n spanStreamingEnabled?: boolean;\n}\n\n/** Add performance related spans to a transaction */\nexport function addPerformanceEntries(span: Span, options: AddPerformanceEntriesOptions): void {\n const performance = getBrowserPerformanceAPI();\n const origin = browserPerformanceTimeOrigin();\n if (!performance?.getEntries || !origin) {\n // Gatekeeper if performance API not available\n return;\n }\n\n const { spanStreamingEnabled, ignorePerformanceApiSpans, ignoreResourceSpans } = options;\n\n const timeOrigin = msToSec(origin);\n\n const performanceEntries = performance.getEntries();\n\n const { op, start_timestamp: transactionStartTime } = spanToJSON(span);\n\n performanceEntries.slice(_performanceCursor).forEach(entry => {\n const startTime = msToSec(entry.startTime);\n const duration = msToSec(\n // Inexplicably, Chrome sometimes emits a negative duration. We need to work around this.\n // There is a SO post attempting to explain this, but it leaves one with open questions: https://stackoverflow.com/questions/23191918/peformance-getentries-and-negative-duration-display\n // The way we clamp the value is probably not accurate, since we have observed this happen for things that may take a while to load, like for example the replay worker.\n // TODO: Investigate why this happens and how to properly mitigate. For now, this is a workaround to prevent transactions being dropped due to negative duration spans.\n Math.max(0, entry.duration),\n );\n\n if (op === 'navigation' && transactionStartTime && timeOrigin + startTime < transactionStartTime) {\n return;\n }\n\n switch (entry.entryType) {\n case 'navigation': {\n _addNavigationSpans(span, entry as PerformanceNavigationTiming, timeOrigin);\n break;\n }\n case 'mark':\n case 'paint':\n case 'measure': {\n _addMeasureSpans(span, entry, startTime, duration, timeOrigin, ignorePerformanceApiSpans);\n break;\n }\n case 'resource': {\n _addResourceSpans(\n span,\n entry as PerformanceResourceTiming,\n entry.name,\n startTime,\n duration,\n timeOrigin,\n ignoreResourceSpans,\n );\n break;\n }\n // Ignore other entry types.\n }\n });\n\n _performanceCursor = Math.max(performanceEntries.length - 1, 0);\n\n _trackNavigator(span, spanStreamingEnabled);\n}\n\n/**\n * Writes the collected web vitals (LCP, CLS, INP, TTFB, FP, FCP) onto the pageload span,\n * either as measurements/attributes (v1) or as web vital attributes (span streaming).\n *\n * This should be called when the pageload span ends, after the web vitals have been finalized.\n * It is a no-op for non-pageload spans, but always resets the collected web vital state so it\n * doesn't leak into a subsequent navigation.\n */\nexport function addWebVitalsToSpan(span: Span, options: AddWebVitalsToSpanOptions): void {\n const origin = browserPerformanceTimeOrigin();\n if (!getBrowserPerformanceAPI()?.getEntries || !origin) {\n // Gatekeeper if performance API not available\n resetWebVitalState();\n return;\n }\n\n const { spanStreamingEnabled, recordClsOnPageloadSpan, recordLcpOnPageloadSpan } = options;\n const timeOrigin = msToSec(origin);\n\n // Measurements are only available for pageload transactions\n if (spanToJSON(span).op === 'pageload') {\n _addTtfbRequestTimeToMeasurements(_measurements);\n\n if (spanStreamingEnabled) {\n const setAttr = (shortWebVitalName: string, value: number, customAttrName?: string) => {\n const attrKey = customAttrName ?? `browser.web_vital.${shortWebVitalName}.value`;\n span.setAttribute(attrKey, value);\n DEBUG_BUILD && debug.log('Setting web vital attribute', { [attrKey]: value }, 'on pageload span');\n };\n // for streamed pageload spans, we add the web vital measurements as attributes.\n // We omit LCP, CLS and INP because they're tracked separately as spans\n ['ttfb', 'fp', 'fcp'].forEach(measurementName => {\n if (_measurements[measurementName]) {\n setAttr(measurementName, _measurements[measurementName].value);\n }\n });\n if (_measurements['ttfb.requestTime']) {\n setAttr('ttfb.requestTime', _measurements['ttfb.requestTime'].value, 'browser.web_vital.ttfb.request_time');\n }\n } else {\n // TODO (V11): Remove this else branch once we remove v1 standalone spans and transactions\n\n // If CLS standalone spans are enabled, don't record CLS as a measurement\n if (!recordClsOnPageloadSpan) {\n delete _measurements.cls;\n }\n\n // If LCP standalone spans are enabled, don't record LCP as a measurement\n if (!recordLcpOnPageloadSpan) {\n delete _measurements.lcp;\n }\n\n Object.entries(_measurements).forEach(([measurementName, measurement]) => {\n setMeasurement(measurementName, measurement.value, measurement.unit, span);\n });\n\n _setWebVitalAttributes(span, options);\n }\n\n // Set timeOrigin which denotes the timestamp which to base the LCP/FCP/FP/TTFB measurements on\n span.setAttribute(spanStreamingEnabled ? 'browser.performance.time_origin' : 'performance.timeOrigin', timeOrigin);\n\n // In prerendering scenarios, where a page might be prefetched and pre-rendered before the user clicks the link,\n // the navigation starts earlier than when the user clicks it. Web Vitals should always be based on the\n // user-perceived time, so they are not reported from the actual start of the navigation, but rather from the\n // time where the user actively started the navigation, for example by clicking a link.\n // This is user action is called \"activation\" and the time between navigation and activation is stored in\n // the `activationStart` attribute of the \"navigation\" PerformanceEntry.\n span.setAttribute(\n spanStreamingEnabled ? 'browser.performance.navigation.activation_start' : 'performance.activationStart',\n getActivationStart(),\n );\n }\n\n resetWebVitalState();\n}\n\nfunction resetWebVitalState(): void {\n _lcpEntry = undefined;\n _clsEntry = undefined;\n _measurements = {};\n}\n\n/**\n * React 19.2+ creates performance.measure entries for component renders.\n * We can identify them by the `detail.devtools.track` property being set to 'Components ⚛'.\n * see: https://react.dev/reference/dev-tools/react-performance-tracks\n * see: https://github.com/facebook/react/blob/06fcc8f380c6a905c7bc18d94453f623cf8cbc81/packages/react-reconciler/src/ReactFiberPerformanceTrack.js#L454-L473\n */\nfunction isReact19MeasureEntry(entry: PerformanceEntry | null): boolean | void {\n if (entry?.entryType !== 'measure') {\n return;\n }\n try {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n return (entry as PerformanceMeasure).detail.devtools.track === 'Components ⚛';\n } catch {\n return;\n }\n}\n\n/**\n * Create measure related spans.\n * Exported only for tests.\n */\nexport function _addMeasureSpans(\n span: Span,\n entry: PerformanceEntry,\n startTime: number,\n duration: number,\n timeOrigin: number,\n ignorePerformanceApiSpans: AddPerformanceEntriesOptions['ignorePerformanceApiSpans'],\n): void {\n if (isReact19MeasureEntry(entry)) {\n return;\n }\n\n if (\n ['mark', 'measure'].includes(entry.entryType) &&\n stringMatchesSomePattern(entry.name, ignorePerformanceApiSpans)\n ) {\n return;\n }\n\n const navEntry = getNavigationEntry(false);\n\n const requestTime = msToSec(navEntry ? navEntry.requestStart : 0);\n // Because performance.measure accepts arbitrary timestamps it can produce\n // spans that happen before the browser even makes a request for the page.\n //\n // An example of this is the automatically generated Next.js-before-hydration\n // spans created by the Next.js framework.\n //\n // To prevent this we will pin the start timestamp to the request start time\n // This does make duration inaccurate, so if this does happen, we will add\n // an attribute to the span\n const measureStartTimestamp = timeOrigin + Math.max(startTime, requestTime);\n const startTimeStamp = timeOrigin + startTime;\n const measureEndTimestamp = startTimeStamp + duration;\n\n const attributes: SpanAttributes = {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.resource.browser.metrics',\n };\n\n if (measureStartTimestamp !== startTimeStamp) {\n attributes['sentry.browser.measure_happened_before_request'] = true;\n attributes['sentry.browser.measure_start_time'] = measureStartTimestamp;\n }\n\n _addDetailToSpanAttributes(attributes, entry as PerformanceMeasure);\n\n // Measurements from third parties can be off, which would create invalid spans, dropping transactions in the process.\n if (measureStartTimestamp <= measureEndTimestamp) {\n startAndEndSpan(span, measureStartTimestamp, measureEndTimestamp, {\n name: entry.name,\n op: entry.entryType,\n attributes,\n });\n }\n}\n\nfunction _addDetailToSpanAttributes(attributes: SpanAttributes, performanceMeasure: PerformanceMeasure): void {\n try {\n // Accessing detail might throw in some browsers (e.g., Firefox) due to security restrictions\n const detail = performanceMeasure.detail;\n\n if (!detail) {\n return;\n }\n\n // Process detail based on its type\n if (typeof detail === 'object') {\n // Handle object details\n for (const [key, value] of Object.entries(detail)) {\n if (value && isPrimitive(value)) {\n attributes[`sentry.browser.measure.detail.${key}`] = value as SpanAttributeValue;\n } else if (value !== undefined) {\n try {\n // This is user defined so we can't guarantee it's serializable\n attributes[`sentry.browser.measure.detail.${key}`] = JSON.stringify(value);\n } catch {\n // Skip values that can't be stringified\n }\n }\n }\n return;\n }\n\n if (isPrimitive(detail)) {\n // Handle primitive details\n attributes['sentry.browser.measure.detail'] = detail as SpanAttributeValue;\n return;\n }\n\n try {\n attributes['sentry.browser.measure.detail'] = JSON.stringify(detail);\n } catch {\n // Skip if stringification fails\n }\n } catch {\n // Silently ignore any errors when accessing detail\n // This handles the Firefox \"Permission denied to access object\" error\n }\n}\n\n/**\n * Instrument navigation entries\n * exported only for tests\n */\nexport function _addNavigationSpans(span: Span, entry: PerformanceNavigationTiming, timeOrigin: number): void {\n (['unloadEvent', 'redirect', 'domContentLoadedEvent', 'loadEvent', 'connect'] as const).forEach(event => {\n _addPerformanceNavigationTiming(span, entry, event, timeOrigin);\n });\n _addPerformanceNavigationTiming(span, entry, 'secureConnection', timeOrigin, 'TLS/SSL');\n _addPerformanceNavigationTiming(span, entry, 'fetch', timeOrigin, 'cache');\n _addPerformanceNavigationTiming(span, entry, 'domainLookup', timeOrigin, 'DNS');\n\n _addRequest(span, entry, timeOrigin);\n}\n\ntype StartEventName =\n | 'secureConnection'\n | 'fetch'\n | 'domainLookup'\n | 'unloadEvent'\n | 'redirect'\n | 'connect'\n | 'domContentLoadedEvent'\n | 'loadEvent';\n\ntype EndEventName =\n | 'domainLookupStart'\n | 'domainLookupEnd'\n | 'unloadEventEnd'\n | 'redirectEnd'\n | 'connectEnd'\n | 'domContentLoadedEventEnd'\n | 'loadEventEnd';\n\n/** Create performance navigation related spans */\nfunction _addPerformanceNavigationTiming(\n span: Span,\n entry: PerformanceNavigationTiming,\n event: StartEventName,\n timeOrigin: number,\n name: string = event,\n): void {\n const eventEnd = _getEndPropertyNameForNavigationTiming(event) satisfies keyof PerformanceNavigationTiming;\n const end = entry[eventEnd];\n const start = entry[`${event}Start`];\n if (!start || !end) {\n return;\n }\n startAndEndSpan(span, timeOrigin + msToSec(start), timeOrigin + msToSec(end), {\n op: `browser.${name}`,\n name: entry.name,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.browser.metrics',\n ...(event === 'redirect' && entry.redirectCount != null ? { 'http.redirect_count': entry.redirectCount } : {}),\n },\n });\n}\n\nfunction _getEndPropertyNameForNavigationTiming(event: StartEventName): EndEventName {\n if (event === 'secureConnection') {\n return 'connectEnd';\n }\n if (event === 'fetch') {\n return 'domainLookupStart';\n }\n return `${event}End`;\n}\n\n/** Create request and response related spans */\nfunction _addRequest(span: Span, entry: PerformanceNavigationTiming, timeOrigin: number): void {\n const requestStartTimestamp = timeOrigin + msToSec(entry.requestStart);\n const responseEndTimestamp = timeOrigin + msToSec(entry.responseEnd);\n const responseStartTimestamp = timeOrigin + msToSec(entry.responseStart);\n if (entry.responseEnd) {\n // It is possible that we are collecting these metrics when the page hasn't finished loading yet, for example when the HTML slowly streams in.\n // In this case, ie. when the document request hasn't finished yet, `entry.responseEnd` will be 0.\n // In order not to produce faulty spans, where the end timestamp is before the start timestamp, we will only collect\n // these spans when the responseEnd value is available. The backend (Relay) would drop the entire span if it contained faulty spans.\n startAndEndSpan(span, requestStartTimestamp, responseEndTimestamp, {\n op: 'browser.request',\n name: entry.name,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.browser.metrics',\n },\n });\n\n startAndEndSpan(span, responseStartTimestamp, responseEndTimestamp, {\n op: 'browser.response',\n name: entry.name,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.browser.metrics',\n },\n });\n }\n}\n\n/**\n * Create resource-related spans.\n * Exported only for tests.\n */\nexport function _addResourceSpans(\n span: Span,\n entry: PerformanceResourceTiming,\n resourceUrl: string,\n startTime: number,\n duration: number,\n timeOrigin: number,\n ignoredResourceSpanOps?: Array<string>,\n): void {\n // we already instrument based on fetch and xhr, so we don't need to\n // duplicate spans here.\n if (entry.initiatorType === 'xmlhttprequest' || entry.initiatorType === 'fetch') {\n return;\n }\n\n const op = entry.initiatorType ? `resource.${entry.initiatorType}` : 'resource.other';\n if (ignoredResourceSpanOps?.includes(op)) {\n return;\n }\n\n const attributes: SpanAttributes = {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.resource.browser.metrics',\n };\n\n const parsedUrl = parseUrl(resourceUrl);\n\n if (parsedUrl.protocol) {\n attributes['url.scheme'] = parsedUrl.protocol.split(':').pop(); // the protocol returned by parseUrl includes a :, but OTEL spec does not, so we remove it.\n }\n\n if (parsedUrl.host) {\n attributes['server.address'] = parsedUrl.host;\n }\n\n attributes['url.same_origin'] = resourceUrl.includes(WINDOW.location.origin);\n\n _setResourceRequestAttributes(entry, attributes, [\n // https://developer.mozilla.org/en-US/docs/Web/API/PerformanceResourceTiming/responseStatus\n ['responseStatus', 'http.response.status_code'],\n\n ['transferSize', 'http.response_transfer_size'],\n ['encodedBodySize', 'http.response_content_length'],\n ['decodedBodySize', 'http.decoded_response_content_length'],\n\n // https://developer.mozilla.org/en-US/docs/Web/API/PerformanceResourceTiming/renderBlockingStatus\n ['renderBlockingStatus', 'resource.render_blocking_status'],\n\n // https://developer.mozilla.org/en-US/docs/Web/API/PerformanceResourceTiming/deliveryType\n ['deliveryType', 'http.response_delivery_type'],\n ]);\n\n const attributesWithResourceTiming: SpanAttributes = { ...attributes, ...resourceTimingToSpanAttributes(entry) };\n\n const startTimestamp = timeOrigin + startTime;\n const endTimestamp = startTimestamp + duration;\n\n startAndEndSpan(span, startTimestamp, endTimestamp, {\n name: resourceUrl.replace(WINDOW.location.origin, ''),\n op,\n attributes: attributesWithResourceTiming,\n });\n}\n\n/**\n * Capture the information of the user agent.\n * TODO v11: Remove non-span-streaming attributes and measurements once we removed transactions\n */\nfunction _trackNavigator(span: Span, spanStreamingEnabled: boolean | undefined): void {\n const navigator = WINDOW.navigator as null | (Navigator & NavigatorNetworkInformation & NavigatorDeviceMemory);\n if (!navigator) {\n return;\n }\n\n // track network connectivity\n const connection = navigator.connection;\n if (connection) {\n if (connection.effectiveType) {\n span.setAttribute(\n spanStreamingEnabled ? 'network.connection.effective_type' : 'effectiveConnectionType',\n connection.effectiveType,\n );\n }\n\n if (connection.type) {\n span.setAttribute(spanStreamingEnabled ? 'network.connection.type' : 'connectionType', connection.type);\n }\n\n if (isMeasurementValue(connection.rtt)) {\n if (spanStreamingEnabled) {\n span.setAttribute('network.connection.rtt', connection.rtt);\n } else if (spanToJSON(span).op === 'pageload') {\n // Measurements are only recorded on the pageload span, matching the historical\n // behavior where `connection.rtt` was only flushed for pageload transactions.\n setMeasurement('connection.rtt', connection.rtt, 'millisecond');\n }\n }\n }\n\n if (isMeasurementValue(navigator.deviceMemory)) {\n if (spanStreamingEnabled) {\n span.setAttribute('device.memory.estimated_capacity', navigator.deviceMemory);\n } else {\n span.setAttribute('deviceMemory', `${navigator.deviceMemory} GB`);\n }\n }\n\n if (isMeasurementValue(navigator.hardwareConcurrency)) {\n if (spanStreamingEnabled) {\n span.setAttribute('device.processor_count', navigator.hardwareConcurrency);\n } else {\n span.setAttribute('hardwareConcurrency', String(navigator.hardwareConcurrency));\n }\n }\n}\n\n/** Add LCP / CLS data to span to allow debugging */\nfunction _setWebVitalAttributes(span: Span, options: AddWebVitalsToSpanOptions): void {\n // Only add LCP attributes if LCP is being recorded on the pageload span\n if (_lcpEntry && options.recordLcpOnPageloadSpan) {\n // Capture Properties of the LCP element that contributes to the LCP.\n\n if (_lcpEntry.element) {\n span.setAttribute('lcp.element', htmlTreeAsString(_lcpEntry.element));\n }\n\n if (_lcpEntry.id) {\n span.setAttribute('lcp.id', _lcpEntry.id);\n }\n\n if (_lcpEntry.url) {\n // Trim URL to the first 200 characters.\n span.setAttribute('lcp.url', _lcpEntry.url.trim().slice(0, 200));\n }\n\n if (_lcpEntry.loadTime != null) {\n // loadTime is the time of LCP that's related to receiving the LCP element response..\n span.setAttribute('lcp.loadTime', _lcpEntry.loadTime);\n }\n\n if (_lcpEntry.renderTime != null) {\n // renderTime is loadTime + rendering time\n // it's 0 if the LCP element is loaded from a 3rd party origin that doesn't send the\n // `Timing-Allow-Origin` header.\n span.setAttribute('lcp.renderTime', _lcpEntry.renderTime);\n }\n\n span.setAttribute('lcp.size', _lcpEntry.size);\n }\n\n // Only add CLS attributes if CLS is being recorded on the pageload span\n if (_clsEntry?.sources && options.recordClsOnPageloadSpan) {\n _clsEntry.sources.forEach((source, index) =>\n span.setAttribute(`cls.source.${index + 1}`, htmlTreeAsString(source.node)),\n );\n }\n}\n\ntype ExperimentalResourceTimingProperty =\n | 'renderBlockingStatus'\n | 'deliveryType'\n // For some reason, TS during build, errors on `responseStatus` not being a property of\n // PerformanceResourceTiming while it actually is. Hence, we're adding it here.\n // Perhaps because response status is not yet available in Webkit/Safari.\n // https://developer.mozilla.org/en-US/docs/Web/API/PerformanceResourceTiming/responseStatus\n | 'responseStatus';\n\n/**\n * Use this to set any attributes we can take directly form the PerformanceResourceTiming entry.\n *\n * This is just a mapping function for entry->attribute to keep bundle-size minimal.\n * Experimental properties are also accepted (see {@link ExperimentalResourceTimingProperty}).\n * Assumes that all entry properties might be undefined for browser-specific differences.\n * Only accepts string and number values for now and also sets 0-values.\n */\nexport function _setResourceRequestAttributes(\n entry: Partial<PerformanceResourceTiming> & Partial<Record<ExperimentalResourceTimingProperty, number | string>>,\n attributes: SpanAttributes,\n properties: [keyof PerformanceResourceTiming | ExperimentalResourceTimingProperty, string][],\n): void {\n properties.forEach(([entryKey, attributeKey]) => {\n const entryVal = entry[entryKey];\n if (\n entryVal != null &&\n ((typeof entryVal === 'number' && entryVal < MAX_INT_AS_BYTES) || typeof entryVal === 'string')\n ) {\n attributes[attributeKey] = entryVal;\n }\n });\n}\n\n/**\n * Add ttfb request time information to measurements.\n *\n * ttfb information is added via vendored web vitals library.\n */\nfunction _addTtfbRequestTimeToMeasurements(_measurements: Measurements): void {\n const navEntry = getNavigationEntry(false);\n if (!navEntry) {\n return;\n }\n\n const { responseStart, requestStart } = navEntry;\n\n if (requestStart <= responseStart) {\n _measurements['ttfb.requestTime'] = {\n value: responseStart - requestStart,\n unit: 'millisecond',\n };\n }\n}\n"],"names":["getBrowserPerformanceAPI","browserPerformanceTimeOrigin","WINDOW","trackLcpAsStandaloneSpan","trackClsAsStandaloneSpan","addPerformanceInstrumentationHandler","getActiveSpan","spanToJSON","msToSec","startAndEndSpan","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","htmlTreeAsString","getComponentName","addClsInstrumentationHandler","addLcpInstrumentationHandler","isValidLcpMetric","addTtfbInstrumentationHandler","getVisibilityWatcher","DEBUG_BUILD","debug","setMeasurement","getActivationStart","stringMatchesSomePattern","getNavigationEntry","isPrimitive","parseUrl","resourceTimingToSpanAttributes","isMeasurementValue","_measurements"],"mappings":"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"}
@@ -0,0 +1,64 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+
3
+ const core = require('@sentry/core');
4
+ const debugBuild = require('../debug-build.js');
5
+ const htmlTreeAsString = require('../htmlTreeAsString.js');
6
+ const instrument = require('./instrument.js');
7
+ const utils = require('./utils.js');
8
+
9
+ function trackClsAsStandaloneSpan(client) {
10
+ let standaloneCLsValue = 0;
11
+ let standaloneClsEntry;
12
+ if (!utils.supportsWebVital("layout-shift")) {
13
+ return;
14
+ }
15
+ const cleanupClsHandler = instrument.addClsInstrumentationHandler(({ metric }) => {
16
+ const entry = metric.entries[metric.entries.length - 1];
17
+ if (!entry) {
18
+ return;
19
+ }
20
+ standaloneCLsValue = metric.value;
21
+ standaloneClsEntry = entry;
22
+ }, true);
23
+ utils.listenForWebVitalReportEvents(client, (reportEvent, pageloadSpanId) => {
24
+ _sendStandaloneClsSpan(standaloneCLsValue, standaloneClsEntry, pageloadSpanId, reportEvent);
25
+ cleanupClsHandler();
26
+ });
27
+ }
28
+ function _sendStandaloneClsSpan(clsValue, entry, pageloadSpanId, reportEvent) {
29
+ debugBuild.DEBUG_BUILD && core.debug.log(`Sending CLS span (${clsValue})`);
30
+ const startTime = entry ? utils.msToSec((core.browserPerformanceTimeOrigin() || 0) + entry.startTime) : core.timestampInSeconds();
31
+ const routeName = core.getCurrentScope().getScopeData().transactionName;
32
+ const name = entry ? htmlTreeAsString.htmlTreeAsString(entry.sources[0]?.node) : "Layout shift";
33
+ const attributes = {
34
+ [core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: "auto.http.browser.cls",
35
+ [core.SEMANTIC_ATTRIBUTE_SENTRY_OP]: "ui.webvital.cls",
36
+ [core.SEMANTIC_ATTRIBUTE_EXCLUSIVE_TIME]: 0,
37
+ // attach the pageload span id to the CLS span so that we can link them in the UI
38
+ "sentry.pageload.span_id": pageloadSpanId,
39
+ // describes what triggered the web vital to be reported
40
+ "sentry.report_event": reportEvent
41
+ };
42
+ if (entry?.sources) {
43
+ entry.sources.forEach((source, index) => {
44
+ attributes[`cls.source.${index + 1}`] = htmlTreeAsString.htmlTreeAsString(source.node);
45
+ });
46
+ }
47
+ const span = utils.startStandaloneWebVitalSpan({
48
+ name,
49
+ transaction: routeName,
50
+ attributes,
51
+ startTime
52
+ });
53
+ if (span) {
54
+ span.addEvent("cls", {
55
+ [core.SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_UNIT]: "",
56
+ [core.SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_VALUE]: clsValue
57
+ });
58
+ span.end(startTime);
59
+ }
60
+ }
61
+
62
+ exports._sendStandaloneClsSpan = _sendStandaloneClsSpan;
63
+ exports.trackClsAsStandaloneSpan = trackClsAsStandaloneSpan;
64
+ //# sourceMappingURL=cls.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cls.js","sources":["../../../src/metrics/cls.ts"],"sourcesContent":["import type { Client, SpanAttributes } from '@sentry/core';\nimport {\n browserPerformanceTimeOrigin,\n debug,\n getCurrentScope,\n SEMANTIC_ATTRIBUTE_EXCLUSIVE_TIME,\n SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_UNIT,\n SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_VALUE,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n timestampInSeconds,\n} from '@sentry/core';\nimport { DEBUG_BUILD } from '../debug-build';\nimport { htmlTreeAsString } from '../htmlTreeAsString';\nimport { addClsInstrumentationHandler } from './instrument';\nimport type { WebVitalReportEvent } from './utils';\nimport { listenForWebVitalReportEvents, msToSec, startStandaloneWebVitalSpan, supportsWebVital } from './utils';\n\n/**\n * Starts tracking the Cumulative Layout Shift on the current page and collects the value once\n *\n * - the page visibility is hidden\n * - a navigation span is started (to stop CLS measurement for SPA soft navigations)\n *\n * Once either of these events triggers, the CLS value is sent as a standalone span and we stop\n * measuring CLS.\n */\nexport function trackClsAsStandaloneSpan(client: Client): void {\n let standaloneCLsValue = 0;\n let standaloneClsEntry: LayoutShift | undefined;\n\n if (!supportsWebVital('layout-shift')) {\n return;\n }\n\n const cleanupClsHandler = addClsInstrumentationHandler(({ metric }) => {\n const entry = metric.entries[metric.entries.length - 1] as LayoutShift | undefined;\n if (!entry) {\n return;\n }\n standaloneCLsValue = metric.value;\n standaloneClsEntry = entry;\n }, true);\n\n listenForWebVitalReportEvents(client, (reportEvent, pageloadSpanId) => {\n _sendStandaloneClsSpan(standaloneCLsValue, standaloneClsEntry, pageloadSpanId, reportEvent);\n cleanupClsHandler();\n });\n}\n\n/**\n * Exported only for testing!\n */\nexport function _sendStandaloneClsSpan(\n clsValue: number,\n entry: LayoutShift | undefined,\n pageloadSpanId: string,\n reportEvent: WebVitalReportEvent,\n) {\n DEBUG_BUILD && debug.log(`Sending CLS span (${clsValue})`);\n\n const startTime = entry ? msToSec((browserPerformanceTimeOrigin() || 0) + entry.startTime) : timestampInSeconds();\n const routeName = getCurrentScope().getScopeData().transactionName;\n\n const name = entry ? htmlTreeAsString(entry.sources[0]?.node) : 'Layout shift';\n\n const attributes: SpanAttributes = {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.browser.cls',\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'ui.webvital.cls',\n [SEMANTIC_ATTRIBUTE_EXCLUSIVE_TIME]: 0,\n // attach the pageload span id to the CLS span so that we can link them in the UI\n 'sentry.pageload.span_id': pageloadSpanId,\n // describes what triggered the web vital to be reported\n 'sentry.report_event': reportEvent,\n };\n\n // Add CLS sources as span attributes to help with debugging layout shifts\n // See: https://developer.mozilla.org/en-US/docs/Web/API/LayoutShift/sources\n if (entry?.sources) {\n entry.sources.forEach((source, index) => {\n attributes[`cls.source.${index + 1}`] = htmlTreeAsString(source.node);\n });\n }\n\n const span = startStandaloneWebVitalSpan({\n name,\n transaction: routeName,\n attributes,\n startTime,\n });\n\n if (span) {\n span.addEvent('cls', {\n [SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_UNIT]: '',\n [SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_VALUE]: clsValue,\n });\n\n // LayoutShift performance entries always have a duration of 0, so we don't need to add `entry.duration` here\n // see: https://developer.mozilla.org/en-US/docs/Web/API/PerformanceEntry/duration\n span.end(startTime);\n }\n}\n"],"names":["supportsWebVital","addClsInstrumentationHandler","listenForWebVitalReportEvents","DEBUG_BUILD","debug","msToSec","browserPerformanceTimeOrigin","timestampInSeconds","getCurrentScope","htmlTreeAsString","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","SEMANTIC_ATTRIBUTE_SENTRY_OP","SEMANTIC_ATTRIBUTE_EXCLUSIVE_TIME","startStandaloneWebVitalSpan","SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_UNIT","SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_VALUE"],"mappings":";;;;;;;;AA2BO,SAAS,yBAAyB,MAAA,EAAsB;AAC7D,EAAA,IAAI,kBAAA,GAAqB,CAAA;AACzB,EAAA,IAAI,kBAAA;AAEJ,EAAA,IAAI,CAACA,sBAAA,CAAiB,cAAc,CAAA,EAAG;AACrC,IAAA;AAAA,EACF;AAEA,EAAA,MAAM,iBAAA,GAAoBC,uCAAA,CAA6B,CAAC,EAAE,QAAO,KAAM;AACrE,IAAA,MAAM,QAAQ,MAAA,CAAO,OAAA,CAAQ,MAAA,CAAO,OAAA,CAAQ,SAAS,CAAC,CAAA;AACtD,IAAA,IAAI,CAAC,KAAA,EAAO;AACV,MAAA;AAAA,IACF;AACA,IAAA,kBAAA,GAAqB,MAAA,CAAO,KAAA;AAC5B,IAAA,kBAAA,GAAqB,KAAA;AAAA,EACvB,GAAG,IAAI,CAAA;AAEP,EAAAC,mCAAA,CAA8B,MAAA,EAAQ,CAAC,WAAA,EAAa,cAAA,KAAmB;AACrE,IAAA,sBAAA,CAAuB,kBAAA,EAAoB,kBAAA,EAAoB,cAAA,EAAgB,WAAW,CAAA;AAC1F,IAAA,iBAAA,EAAkB;AAAA,EACpB,CAAC,CAAA;AACH;AAKO,SAAS,sBAAA,CACd,QAAA,EACA,KAAA,EACA,cAAA,EACA,WAAA,EACA;AACA,EAAAC,sBAAA,IAAeC,UAAA,CAAM,GAAA,CAAI,CAAA,kBAAA,EAAqB,QAAQ,CAAA,CAAA,CAAG,CAAA;AAEzD,EAAA,MAAM,SAAA,GAAY,QAAQC,aAAA,CAAA,CAASC,iCAAA,MAAkC,CAAA,IAAK,KAAA,CAAM,SAAS,CAAA,GAAIC,uBAAA,EAAmB;AAChH,EAAA,MAAM,SAAA,GAAYC,oBAAA,EAAgB,CAAE,YAAA,EAAa,CAAE,eAAA;AAEnD,EAAA,MAAM,IAAA,GAAO,QAAQC,iCAAA,CAAiB,KAAA,CAAM,QAAQ,CAAC,CAAA,EAAG,IAAI,CAAA,GAAI,cAAA;AAEhE,EAAA,MAAM,UAAA,GAA6B;AAAA,IACjC,CAACC,qCAAgC,GAAG,uBAAA;AAAA,IACpC,CAACC,iCAA4B,GAAG,iBAAA;AAAA,IAChC,CAACC,sCAAiC,GAAG,CAAA;AAAA;AAAA,IAErC,yBAAA,EAA2B,cAAA;AAAA;AAAA,IAE3B,qBAAA,EAAuB;AAAA,GACzB;AAIA,EAAA,IAAI,OAAO,OAAA,EAAS;AAClB,IAAA,KAAA,CAAM,OAAA,CAAQ,OAAA,CAAQ,CAAC,MAAA,EAAQ,KAAA,KAAU;AACvC,MAAA,UAAA,CAAW,cAAc,KAAA,GAAQ,CAAC,EAAE,CAAA,GAAIH,iCAAA,CAAiB,OAAO,IAAI,CAAA;AAAA,IACtE,CAAC,CAAA;AAAA,EACH;AAEA,EAAA,MAAM,OAAOI,iCAAA,CAA4B;AAAA,IACvC,IAAA;AAAA,IACA,WAAA,EAAa,SAAA;AAAA,IACb,UAAA;AAAA,IACA;AAAA,GACD,CAAA;AAED,EAAA,IAAI,IAAA,EAAM;AACR,IAAA,IAAA,CAAK,SAAS,KAAA,EAAO;AAAA,MACnB,CAACC,+CAA0C,GAAG,EAAA;AAAA,MAC9C,CAACC,gDAA2C,GAAG;AAAA,KAChD,CAAA;AAID,IAAA,IAAA,CAAK,IAAI,SAAS,CAAA;AAAA,EACpB;AACF;;;;;"}
@@ -0,0 +1,72 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+
3
+ const core = require('@sentry/core');
4
+ const instrument = require('./instrument.js');
5
+ const utils = require('./utils.js');
6
+
7
+ const INTEGRATION_NAME = "ElementTiming";
8
+ const _elementTimingIntegration = (() => {
9
+ return {
10
+ name: INTEGRATION_NAME,
11
+ setup() {
12
+ const performance = utils.getBrowserPerformanceAPI();
13
+ if (!performance || !core.browserPerformanceTimeOrigin()) {
14
+ return;
15
+ }
16
+ instrument.addPerformanceInstrumentationHandler("element", ({ entries }) => {
17
+ for (const entry of entries) {
18
+ const elementEntry = entry;
19
+ if (!elementEntry.identifier) {
20
+ continue;
21
+ }
22
+ const identifier = elementEntry.identifier;
23
+ const paintType = elementEntry.name;
24
+ const renderTime = elementEntry.renderTime;
25
+ const loadTime = elementEntry.loadTime;
26
+ const metricAttributes = {
27
+ "sentry.origin": "auto.ui.browser.element_timing",
28
+ "ui.element.identifier": identifier
29
+ };
30
+ if (paintType) {
31
+ metricAttributes["ui.element.paint_type"] = paintType;
32
+ }
33
+ if (elementEntry.id) {
34
+ metricAttributes["ui.element.id"] = elementEntry.id;
35
+ }
36
+ if (elementEntry.element) {
37
+ metricAttributes["ui.element.type"] = elementEntry.element.tagName.toLowerCase();
38
+ }
39
+ if (elementEntry.url) {
40
+ metricAttributes["ui.element.url"] = elementEntry.url;
41
+ }
42
+ if (elementEntry.naturalWidth) {
43
+ metricAttributes["ui.element.width"] = elementEntry.naturalWidth;
44
+ }
45
+ if (elementEntry.naturalHeight) {
46
+ metricAttributes["ui.element.height"] = elementEntry.naturalHeight;
47
+ }
48
+ if (renderTime > 0) {
49
+ core.metrics.distribution(`ui.element.render_time`, renderTime, {
50
+ unit: "millisecond",
51
+ attributes: metricAttributes
52
+ });
53
+ }
54
+ if (loadTime > 0) {
55
+ core.metrics.distribution(`ui.element.load_time`, loadTime, {
56
+ unit: "millisecond",
57
+ attributes: metricAttributes
58
+ });
59
+ }
60
+ }
61
+ });
62
+ }
63
+ };
64
+ });
65
+ const elementTimingIntegration = core.defineIntegration(_elementTimingIntegration);
66
+ function startTrackingElementTiming() {
67
+ return () => void 0;
68
+ }
69
+
70
+ exports.elementTimingIntegration = elementTimingIntegration;
71
+ exports.startTrackingElementTiming = startTrackingElementTiming;
72
+ //# sourceMappingURL=elementTiming.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"elementTiming.js","sources":["../../../src/metrics/elementTiming.ts"],"sourcesContent":["import type { IntegrationFn } from '@sentry/core';\nimport { browserPerformanceTimeOrigin, defineIntegration, metrics } from '@sentry/core';\nimport { addPerformanceInstrumentationHandler } from './instrument';\nimport { getBrowserPerformanceAPI } from './utils';\n\n// ElementTiming interface based on the W3C spec\ninterface PerformanceElementTiming extends PerformanceEntry {\n renderTime: number;\n loadTime: number;\n intersectionRect: DOMRectReadOnly;\n identifier: string;\n naturalWidth: number;\n naturalHeight: number;\n id: string;\n element: Element | null;\n url?: string;\n}\n\nconst INTEGRATION_NAME = 'ElementTiming';\n\nconst _elementTimingIntegration = (() => {\n return {\n name: INTEGRATION_NAME,\n setup() {\n const performance = getBrowserPerformanceAPI();\n if (!performance || !browserPerformanceTimeOrigin()) {\n return;\n }\n\n addPerformanceInstrumentationHandler('element', ({ entries }) => {\n for (const entry of entries) {\n const elementEntry = entry as PerformanceElementTiming;\n\n if (!elementEntry.identifier) {\n continue;\n }\n\n const identifier = elementEntry.identifier;\n const paintType = elementEntry.name as 'image-paint' | 'text-paint' | undefined;\n const renderTime = elementEntry.renderTime;\n const loadTime = elementEntry.loadTime;\n\n const metricAttributes: Record<string, string | number> = {\n 'sentry.origin': 'auto.ui.browser.element_timing',\n 'ui.element.identifier': identifier,\n };\n\n if (paintType) {\n metricAttributes['ui.element.paint_type'] = paintType;\n }\n\n if (elementEntry.id) {\n metricAttributes['ui.element.id'] = elementEntry.id;\n }\n\n if (elementEntry.element) {\n metricAttributes['ui.element.type'] = elementEntry.element.tagName.toLowerCase();\n }\n\n if (elementEntry.url) {\n metricAttributes['ui.element.url'] = elementEntry.url;\n }\n\n if (elementEntry.naturalWidth) {\n metricAttributes['ui.element.width'] = elementEntry.naturalWidth;\n }\n\n if (elementEntry.naturalHeight) {\n metricAttributes['ui.element.height'] = elementEntry.naturalHeight;\n }\n\n if (renderTime > 0) {\n metrics.distribution(`ui.element.render_time`, renderTime, {\n unit: 'millisecond',\n attributes: metricAttributes,\n });\n }\n\n if (loadTime > 0) {\n metrics.distribution(`ui.element.load_time`, loadTime, {\n unit: 'millisecond',\n attributes: metricAttributes,\n });\n }\n }\n });\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * Captures [Element Timing API](https://developer.mozilla.org/en-US/docs/Web/API/PerformanceElementTiming)\n * data as Sentry metrics.\n *\n * To mark an element for tracking, add the `elementtiming` HTML attribute:\n * ```html\n * <img src=\"hero.jpg\" elementtiming=\"hero-image\" />\n * <p elementtiming=\"hero-text\">Welcome!</p>\n * ```\n *\n * This emits `ui.element.render_time` and `ui.element.load_time` (for images)\n * as distribution metrics, tagged with the element's identifier and paint type.\n */\nexport const elementTimingIntegration = defineIntegration(_elementTimingIntegration);\n\n/**\n * @deprecated Use `elementTimingIntegration` instead. This function is a no-op and will be removed in a future version.\n */\nexport function startTrackingElementTiming(): () => void {\n return () => undefined;\n}\n"],"names":["getBrowserPerformanceAPI","browserPerformanceTimeOrigin","addPerformanceInstrumentationHandler","metrics","defineIntegration"],"mappings":";;;;;;AAkBA,MAAM,gBAAA,GAAmB,eAAA;AAEzB,MAAM,6BAA6B,MAAM;AACvC,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,gBAAA;AAAA,IACN,KAAA,GAAQ;AACN,MAAA,MAAM,cAAcA,8BAAA,EAAyB;AAC7C,MAAA,IAAI,CAAC,WAAA,IAAe,CAACC,iCAAA,EAA6B,EAAG;AACnD,QAAA;AAAA,MACF;AAEA,MAAAC,+CAAA,CAAqC,SAAA,EAAW,CAAC,EAAE,OAAA,EAAQ,KAAM;AAC/D,QAAA,KAAA,MAAW,SAAS,OAAA,EAAS;AAC3B,UAAA,MAAM,YAAA,GAAe,KAAA;AAErB,UAAA,IAAI,CAAC,aAAa,UAAA,EAAY;AAC5B,YAAA;AAAA,UACF;AAEA,UAAA,MAAM,aAAa,YAAA,CAAa,UAAA;AAChC,UAAA,MAAM,YAAY,YAAA,CAAa,IAAA;AAC/B,UAAA,MAAM,aAAa,YAAA,CAAa,UAAA;AAChC,UAAA,MAAM,WAAW,YAAA,CAAa,QAAA;AAE9B,UAAA,MAAM,gBAAA,GAAoD;AAAA,YACxD,eAAA,EAAiB,gCAAA;AAAA,YACjB,uBAAA,EAAyB;AAAA,WAC3B;AAEA,UAAA,IAAI,SAAA,EAAW;AACb,YAAA,gBAAA,CAAiB,uBAAuB,CAAA,GAAI,SAAA;AAAA,UAC9C;AAEA,UAAA,IAAI,aAAa,EAAA,EAAI;AACnB,YAAA,gBAAA,CAAiB,eAAe,IAAI,YAAA,CAAa,EAAA;AAAA,UACnD;AAEA,UAAA,IAAI,aAAa,OAAA,EAAS;AACxB,YAAA,gBAAA,CAAiB,iBAAiB,CAAA,GAAI,YAAA,CAAa,OAAA,CAAQ,QAAQ,WAAA,EAAY;AAAA,UACjF;AAEA,UAAA,IAAI,aAAa,GAAA,EAAK;AACpB,YAAA,gBAAA,CAAiB,gBAAgB,IAAI,YAAA,CAAa,GAAA;AAAA,UACpD;AAEA,UAAA,IAAI,aAAa,YAAA,EAAc;AAC7B,YAAA,gBAAA,CAAiB,kBAAkB,IAAI,YAAA,CAAa,YAAA;AAAA,UACtD;AAEA,UAAA,IAAI,aAAa,aAAA,EAAe;AAC9B,YAAA,gBAAA,CAAiB,mBAAmB,IAAI,YAAA,CAAa,aAAA;AAAA,UACvD;AAEA,UAAA,IAAI,aAAa,CAAA,EAAG;AAClB,YAAAC,YAAA,CAAQ,YAAA,CAAa,0BAA0B,UAAA,EAAY;AAAA,cACzD,IAAA,EAAM,aAAA;AAAA,cACN,UAAA,EAAY;AAAA,aACb,CAAA;AAAA,UACH;AAEA,UAAA,IAAI,WAAW,CAAA,EAAG;AAChB,YAAAA,YAAA,CAAQ,YAAA,CAAa,wBAAwB,QAAA,EAAU;AAAA,cACrD,IAAA,EAAM,aAAA;AAAA,cACN,UAAA,EAAY;AAAA,aACb,CAAA;AAAA,UACH;AAAA,QACF;AAAA,MACF,CAAC,CAAA;AAAA,IACH;AAAA,GACF;AACF,CAAA,CAAA;AAeO,MAAM,wBAAA,GAA2BC,uBAAkB,yBAAyB;AAK5E,SAAS,0BAAA,GAAyC;AACvD,EAAA,OAAO,MAAM,MAAA;AACf;;;;;"}
@@ -0,0 +1,170 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+
3
+ const core = require('@sentry/core');
4
+ const htmlTreeAsString = require('../htmlTreeAsString.js');
5
+ const types = require('../types.js');
6
+ const instrument = require('./instrument.js');
7
+ const utils = require('./utils.js');
8
+
9
+ const LAST_INTERACTIONS = [];
10
+ const INTERACTIONS_SPAN_MAP = /* @__PURE__ */ new Map();
11
+ const ELEMENT_NAME_TIMESTAMP_MAP = /* @__PURE__ */ new Map();
12
+ const MAX_PLAUSIBLE_INP_DURATION = 60;
13
+ function startTrackingINP() {
14
+ const performance = utils.getBrowserPerformanceAPI();
15
+ if (performance && core.browserPerformanceTimeOrigin()) {
16
+ const inpCallback = _trackINP();
17
+ return () => {
18
+ inpCallback();
19
+ };
20
+ }
21
+ return () => void 0;
22
+ }
23
+ const INP_ENTRY_MAP = {
24
+ click: "click",
25
+ pointerdown: "click",
26
+ pointerup: "click",
27
+ mousedown: "click",
28
+ mouseup: "click",
29
+ touchstart: "click",
30
+ touchend: "click",
31
+ mouseover: "hover",
32
+ mouseout: "hover",
33
+ mouseenter: "hover",
34
+ mouseleave: "hover",
35
+ pointerover: "hover",
36
+ pointerout: "hover",
37
+ pointerenter: "hover",
38
+ pointerleave: "hover",
39
+ dragstart: "drag",
40
+ dragend: "drag",
41
+ drag: "drag",
42
+ dragenter: "drag",
43
+ dragleave: "drag",
44
+ dragover: "drag",
45
+ drop: "drag",
46
+ keydown: "press",
47
+ keyup: "press",
48
+ keypress: "press",
49
+ input: "press"
50
+ };
51
+ function _trackINP() {
52
+ return instrument.addInpInstrumentationHandler(_onInp);
53
+ }
54
+ const _onInp = ({ metric }) => {
55
+ if (metric.value == void 0) {
56
+ return;
57
+ }
58
+ const duration = utils.msToSec(metric.value);
59
+ if (duration > MAX_PLAUSIBLE_INP_DURATION) {
60
+ return;
61
+ }
62
+ const entry = metric.entries.find((entry2) => entry2.duration === metric.value && INP_ENTRY_MAP[entry2.name]);
63
+ if (!entry) {
64
+ return;
65
+ }
66
+ const { interactionId } = entry;
67
+ const interactionType = INP_ENTRY_MAP[entry.name];
68
+ const startTime = utils.msToSec(core.browserPerformanceTimeOrigin() + entry.startTime);
69
+ const activeSpan = core.getActiveSpan();
70
+ const rootSpan = activeSpan ? core.getRootSpan(activeSpan) : void 0;
71
+ const cachedInteractionContext = interactionId != null ? INTERACTIONS_SPAN_MAP.get(interactionId) : void 0;
72
+ const spanToUse = cachedInteractionContext?.span || rootSpan;
73
+ const routeName = spanToUse ? core.spanToJSON(spanToUse).description : core.getCurrentScope().getScopeData().transactionName;
74
+ const name = cachedInteractionContext?.elementName || htmlTreeAsString.htmlTreeAsString(entry.target);
75
+ const attributes = {
76
+ [core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: "auto.http.browser.inp",
77
+ [core.SEMANTIC_ATTRIBUTE_SENTRY_OP]: `ui.interaction.${interactionType}`,
78
+ [core.SEMANTIC_ATTRIBUTE_EXCLUSIVE_TIME]: entry.duration
79
+ };
80
+ const span = utils.startStandaloneWebVitalSpan({
81
+ name,
82
+ transaction: routeName,
83
+ attributes,
84
+ startTime
85
+ });
86
+ if (span) {
87
+ span.addEvent("inp", {
88
+ [core.SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_UNIT]: "millisecond",
89
+ [core.SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_VALUE]: metric.value
90
+ });
91
+ span.end(startTime + duration);
92
+ }
93
+ };
94
+ function getCachedInteractionContext(interactionId) {
95
+ return interactionId != null ? INTERACTIONS_SPAN_MAP.get(interactionId) : void 0;
96
+ }
97
+ function registerInpInteractionListener() {
98
+ const interactionEvents = Object.keys(INP_ENTRY_MAP);
99
+ if (core.isBrowser()) {
100
+ interactionEvents.forEach((eventType) => {
101
+ types.WINDOW.addEventListener(eventType, captureElementFromEvent, { capture: true, passive: true });
102
+ });
103
+ }
104
+ function captureElementFromEvent(event) {
105
+ const target = event.target;
106
+ if (!target) {
107
+ return;
108
+ }
109
+ const elementName = htmlTreeAsString.htmlTreeAsString(target);
110
+ const timestamp = Math.round(event.timeStamp);
111
+ ELEMENT_NAME_TIMESTAMP_MAP.set(timestamp, elementName);
112
+ if (ELEMENT_NAME_TIMESTAMP_MAP.size > 50) {
113
+ const firstKey = ELEMENT_NAME_TIMESTAMP_MAP.keys().next().value;
114
+ if (firstKey !== void 0) {
115
+ ELEMENT_NAME_TIMESTAMP_MAP.delete(firstKey);
116
+ }
117
+ }
118
+ }
119
+ function resolveElementNameFromEntry(entry) {
120
+ const timestamp = Math.round(entry.startTime);
121
+ let elementName = ELEMENT_NAME_TIMESTAMP_MAP.get(timestamp);
122
+ if (!elementName) {
123
+ for (let offset = -5; offset <= 5; offset++) {
124
+ const nearbyName = ELEMENT_NAME_TIMESTAMP_MAP.get(timestamp + offset);
125
+ if (nearbyName) {
126
+ elementName = nearbyName;
127
+ break;
128
+ }
129
+ }
130
+ }
131
+ return elementName || "<unknown>";
132
+ }
133
+ const handleEntries = ({ entries }) => {
134
+ const activeSpan = core.getActiveSpan();
135
+ const activeRootSpan = activeSpan && core.getRootSpan(activeSpan);
136
+ entries.forEach((entry) => {
137
+ if (!instrument.isPerformanceEventTiming(entry)) {
138
+ return;
139
+ }
140
+ const interactionId = entry.interactionId;
141
+ if (interactionId == null) {
142
+ return;
143
+ }
144
+ if (INTERACTIONS_SPAN_MAP.has(interactionId)) {
145
+ return;
146
+ }
147
+ const elementName = entry.target ? htmlTreeAsString.htmlTreeAsString(entry.target) : resolveElementNameFromEntry(entry);
148
+ if (LAST_INTERACTIONS.length > 10) {
149
+ const last = LAST_INTERACTIONS.shift();
150
+ INTERACTIONS_SPAN_MAP.delete(last);
151
+ }
152
+ LAST_INTERACTIONS.push(interactionId);
153
+ INTERACTIONS_SPAN_MAP.set(interactionId, {
154
+ span: activeRootSpan,
155
+ elementName
156
+ });
157
+ });
158
+ };
159
+ instrument.addPerformanceInstrumentationHandler("event", handleEntries);
160
+ instrument.addPerformanceInstrumentationHandler("first-input", handleEntries);
161
+ }
162
+
163
+ exports.INP_ENTRY_MAP = INP_ENTRY_MAP;
164
+ exports.MAX_PLAUSIBLE_INP_DURATION = MAX_PLAUSIBLE_INP_DURATION;
165
+ exports._onInp = _onInp;
166
+ exports._trackINP = _trackINP;
167
+ exports.getCachedInteractionContext = getCachedInteractionContext;
168
+ exports.registerInpInteractionListener = registerInpInteractionListener;
169
+ exports.startTrackingINP = startTrackingINP;
170
+ //# sourceMappingURL=inp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inp.js","sources":["../../../src/metrics/inp.ts"],"sourcesContent":["import type { Span, SpanAttributes } from '@sentry/core';\nimport {\n browserPerformanceTimeOrigin,\n getActiveSpan,\n getCurrentScope,\n getRootSpan,\n isBrowser,\n SEMANTIC_ATTRIBUTE_EXCLUSIVE_TIME,\n SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_UNIT,\n SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_VALUE,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n spanToJSON,\n} from '@sentry/core';\nimport { htmlTreeAsString } from '../htmlTreeAsString';\nimport { WINDOW } from '../types';\nimport type { InstrumentationHandlerCallback } from './instrument';\nimport {\n addInpInstrumentationHandler,\n addPerformanceInstrumentationHandler,\n isPerformanceEventTiming,\n} from './instrument';\nimport { getBrowserPerformanceAPI, msToSec, startStandaloneWebVitalSpan } from './utils';\n\ninterface InteractionContext {\n span: Span | undefined;\n elementName: string;\n}\n\nconst LAST_INTERACTIONS: number[] = [];\nconst INTERACTIONS_SPAN_MAP = new Map<number, InteractionContext>();\n\n// Map to store element names by timestamp, since we get the DOM event before the PerformanceObserver entry\nconst ELEMENT_NAME_TIMESTAMP_MAP = new Map<number, string>();\n\n/**\n * 60 seconds is the maximum for a plausible INP value\n * (source: Me)\n */\nexport const MAX_PLAUSIBLE_INP_DURATION = 60;\n/**\n * Start tracking INP webvital events.\n */\nexport function startTrackingINP(): () => void {\n const performance = getBrowserPerformanceAPI();\n if (performance && browserPerformanceTimeOrigin()) {\n const inpCallback = _trackINP();\n\n return (): void => {\n inpCallback();\n };\n }\n\n return () => undefined;\n}\n\nexport const INP_ENTRY_MAP: Record<string, 'click' | 'hover' | 'drag' | 'press'> = {\n click: 'click',\n pointerdown: 'click',\n pointerup: 'click',\n mousedown: 'click',\n mouseup: 'click',\n touchstart: 'click',\n touchend: 'click',\n mouseover: 'hover',\n mouseout: 'hover',\n mouseenter: 'hover',\n mouseleave: 'hover',\n pointerover: 'hover',\n pointerout: 'hover',\n pointerenter: 'hover',\n pointerleave: 'hover',\n dragstart: 'drag',\n dragend: 'drag',\n drag: 'drag',\n dragenter: 'drag',\n dragleave: 'drag',\n dragover: 'drag',\n drop: 'drag',\n keydown: 'press',\n keyup: 'press',\n keypress: 'press',\n input: 'press',\n};\n\n/** Starts tracking the Interaction to Next Paint on the current page. #\n * exported only for testing\n */\nexport function _trackINP(): () => void {\n return addInpInstrumentationHandler(_onInp);\n}\n\n/**\n * exported only for testing\n */\nexport const _onInp: InstrumentationHandlerCallback = ({ metric }) => {\n if (metric.value == undefined) {\n return;\n }\n\n const duration = msToSec(metric.value);\n\n // We received occasional reports of hour-long INP values.\n // Therefore, we add a sanity check to avoid creating spans for\n // unrealistically long INP durations.\n if (duration > MAX_PLAUSIBLE_INP_DURATION) {\n return;\n }\n\n const entry = metric.entries.find(entry => entry.duration === metric.value && INP_ENTRY_MAP[entry.name]);\n\n if (!entry) {\n return;\n }\n\n const { interactionId } = entry;\n const interactionType = INP_ENTRY_MAP[entry.name];\n\n /** Build the INP span, create an envelope from the span, and then send the envelope */\n const startTime = msToSec((browserPerformanceTimeOrigin() as number) + entry.startTime);\n const activeSpan = getActiveSpan();\n const rootSpan = activeSpan ? getRootSpan(activeSpan) : undefined;\n\n // We first try to lookup the interaction context from our INTERACTIONS_SPAN_MAP,\n // where we cache the route and element name per interactionId\n const cachedInteractionContext = interactionId != null ? INTERACTIONS_SPAN_MAP.get(interactionId) : undefined;\n\n const spanToUse = cachedInteractionContext?.span || rootSpan;\n\n // Else, we try to use the active span.\n // Finally, we fall back to look at the transactionName on the scope\n const routeName = spanToUse ? spanToJSON(spanToUse).description : getCurrentScope().getScopeData().transactionName;\n\n const name = cachedInteractionContext?.elementName || htmlTreeAsString(entry.target);\n const attributes: SpanAttributes = {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.browser.inp',\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: `ui.interaction.${interactionType}`,\n [SEMANTIC_ATTRIBUTE_EXCLUSIVE_TIME]: entry.duration,\n };\n\n const span = startStandaloneWebVitalSpan({\n name,\n transaction: routeName,\n attributes,\n startTime,\n });\n\n if (span) {\n span.addEvent('inp', {\n [SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_UNIT]: 'millisecond',\n [SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_VALUE]: metric.value,\n });\n\n span.end(startTime + duration);\n }\n};\n\n/**\n * Look up a cached interaction context (element name + root span) by interactionId.\n * Returns undefined if no context was cached for this interaction.\n */\nexport function getCachedInteractionContext(interactionId: number | undefined): InteractionContext | undefined {\n return interactionId != null ? INTERACTIONS_SPAN_MAP.get(interactionId) : undefined;\n}\n\n/**\n * Register a listener to cache route information for INP interactions.\n */\nexport function registerInpInteractionListener(): void {\n // Listen for all interaction events that could contribute to INP\n const interactionEvents = Object.keys(INP_ENTRY_MAP);\n if (isBrowser()) {\n interactionEvents.forEach(eventType => {\n WINDOW.addEventListener(eventType, captureElementFromEvent, { capture: true, passive: true });\n });\n }\n\n /**\n * Captures the element name from a DOM event and stores it in the ELEMENT_NAME_TIMESTAMP_MAP.\n */\n function captureElementFromEvent(event: Event): void {\n const target = event.target as HTMLElement | null;\n if (!target) {\n return;\n }\n\n const elementName = htmlTreeAsString(target);\n const timestamp = Math.round(event.timeStamp);\n\n // Store the element name by timestamp so we can match it with the PerformanceEntry\n ELEMENT_NAME_TIMESTAMP_MAP.set(timestamp, elementName);\n\n // Clean up old\n if (ELEMENT_NAME_TIMESTAMP_MAP.size > 50) {\n const firstKey = ELEMENT_NAME_TIMESTAMP_MAP.keys().next().value;\n if (firstKey !== undefined) {\n ELEMENT_NAME_TIMESTAMP_MAP.delete(firstKey);\n }\n }\n }\n\n /**\n * Tries to get the element name from the timestamp map.\n */\n function resolveElementNameFromEntry(entry: PerformanceEntry): string {\n const timestamp = Math.round(entry.startTime);\n let elementName = ELEMENT_NAME_TIMESTAMP_MAP.get(timestamp);\n\n // try nearby timestamps (±5ms)\n if (!elementName) {\n for (let offset = -5; offset <= 5; offset++) {\n const nearbyName = ELEMENT_NAME_TIMESTAMP_MAP.get(timestamp + offset);\n if (nearbyName) {\n elementName = nearbyName;\n break;\n }\n }\n }\n\n return elementName || '<unknown>';\n }\n\n const handleEntries = ({ entries }: { entries: PerformanceEntry[] }): void => {\n const activeSpan = getActiveSpan();\n const activeRootSpan = activeSpan && getRootSpan(activeSpan);\n\n entries.forEach(entry => {\n if (!isPerformanceEventTiming(entry)) {\n return;\n }\n\n const interactionId = entry.interactionId;\n if (interactionId == null) {\n return;\n }\n\n // If the interaction was already recorded before, nothing more to do\n if (INTERACTIONS_SPAN_MAP.has(interactionId)) {\n return;\n }\n\n const elementName = entry.target ? htmlTreeAsString(entry.target) : resolveElementNameFromEntry(entry);\n\n // We keep max. 10 interactions in the list, then remove the oldest one & clean up\n if (LAST_INTERACTIONS.length > 10) {\n const last = LAST_INTERACTIONS.shift() as number;\n INTERACTIONS_SPAN_MAP.delete(last);\n }\n\n // We add the interaction to the list of recorded interactions\n // and store both the span and element name for this interaction\n LAST_INTERACTIONS.push(interactionId);\n INTERACTIONS_SPAN_MAP.set(interactionId, {\n span: activeRootSpan,\n elementName,\n });\n });\n };\n\n addPerformanceInstrumentationHandler('event', handleEntries);\n addPerformanceInstrumentationHandler('first-input', handleEntries);\n}\n"],"names":["getBrowserPerformanceAPI","browserPerformanceTimeOrigin","addInpInstrumentationHandler","msToSec","entry","getActiveSpan","getRootSpan","spanToJSON","getCurrentScope","htmlTreeAsString","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","SEMANTIC_ATTRIBUTE_SENTRY_OP","SEMANTIC_ATTRIBUTE_EXCLUSIVE_TIME","startStandaloneWebVitalSpan","SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_UNIT","SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_VALUE","isBrowser","WINDOW","isPerformanceEventTiming","addPerformanceInstrumentationHandler"],"mappings":"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"}
@@ -0,0 +1,152 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+
3
+ const core = require('@sentry/core');
4
+ const debugBuild = require('../debug-build.js');
5
+ const getCLS = require('./web-vitals/getCLS.js');
6
+ const getINP = require('./web-vitals/getINP.js');
7
+ const getLCP = require('./web-vitals/getLCP.js');
8
+ const observe = require('./web-vitals/lib/observe.js');
9
+ const onTTFB = require('./web-vitals/onTTFB.js');
10
+
11
+ const handlers = {};
12
+ const instrumented = {};
13
+ let _previousCls;
14
+ let _previousLcp;
15
+ let _previousTtfb;
16
+ let _previousInp;
17
+ function addClsInstrumentationHandler(callback, stopOnCallback = false) {
18
+ return addMetricObserver("cls", callback, instrumentCls, _previousCls, stopOnCallback);
19
+ }
20
+ function addLcpInstrumentationHandler(callback, stopOnCallback = false) {
21
+ return addMetricObserver("lcp", callback, instrumentLcp, _previousLcp, stopOnCallback);
22
+ }
23
+ function addTtfbInstrumentationHandler(callback) {
24
+ return addMetricObserver("ttfb", callback, instrumentTtfb, _previousTtfb);
25
+ }
26
+ function addInpInstrumentationHandler(callback) {
27
+ return addMetricObserver("inp", callback, instrumentInp, _previousInp);
28
+ }
29
+ function addPerformanceInstrumentationHandler(type, callback) {
30
+ addHandler(type, callback);
31
+ if (!instrumented[type]) {
32
+ instrumentPerformanceObserver(type);
33
+ instrumented[type] = true;
34
+ }
35
+ return getCleanupCallback(type, callback);
36
+ }
37
+ function triggerHandlers(type, data) {
38
+ const typeHandlers = handlers[type];
39
+ if (!typeHandlers?.length) {
40
+ return;
41
+ }
42
+ for (const handler of typeHandlers) {
43
+ try {
44
+ handler(data);
45
+ } catch (e) {
46
+ debugBuild.DEBUG_BUILD && core.debug.error(
47
+ `Error while triggering instrumentation handler.
48
+ Type: ${type}
49
+ Name: ${core.getFunctionName(handler)}
50
+ Error:`,
51
+ e
52
+ );
53
+ }
54
+ }
55
+ }
56
+ function instrumentCls() {
57
+ return getCLS.onCLS(
58
+ (metric) => {
59
+ triggerHandlers("cls", {
60
+ metric
61
+ });
62
+ _previousCls = metric;
63
+ },
64
+ // We want the callback to be called whenever the CLS value updates.
65
+ // By default, the callback is only called when the tab goes to the background.
66
+ { reportAllChanges: true }
67
+ );
68
+ }
69
+ function instrumentLcp() {
70
+ return getLCP.onLCP(
71
+ (metric) => {
72
+ triggerHandlers("lcp", {
73
+ metric
74
+ });
75
+ _previousLcp = metric;
76
+ },
77
+ // We want the callback to be called whenever the LCP value updates.
78
+ // By default, the callback is only called when the tab goes to the background.
79
+ { reportAllChanges: true }
80
+ );
81
+ }
82
+ function instrumentTtfb() {
83
+ return onTTFB.onTTFB((metric) => {
84
+ triggerHandlers("ttfb", {
85
+ metric
86
+ });
87
+ _previousTtfb = metric;
88
+ });
89
+ }
90
+ function instrumentInp() {
91
+ return getINP.onINP((metric) => {
92
+ triggerHandlers("inp", {
93
+ metric
94
+ });
95
+ _previousInp = metric;
96
+ });
97
+ }
98
+ function addMetricObserver(type, callback, instrumentFn, previousValue, stopOnCallback = false) {
99
+ addHandler(type, callback);
100
+ let stopListening;
101
+ if (!instrumented[type]) {
102
+ stopListening = instrumentFn();
103
+ instrumented[type] = true;
104
+ }
105
+ if (previousValue) {
106
+ callback({ metric: previousValue });
107
+ }
108
+ return getCleanupCallback(type, callback, stopOnCallback ? stopListening : void 0);
109
+ }
110
+ function instrumentPerformanceObserver(type) {
111
+ const options = {};
112
+ if (type === "event") {
113
+ options.durationThreshold = 0;
114
+ }
115
+ observe.observe(
116
+ type,
117
+ (entries) => {
118
+ triggerHandlers(type, { entries });
119
+ },
120
+ options
121
+ );
122
+ }
123
+ function addHandler(type, handler) {
124
+ handlers[type] = handlers[type] || [];
125
+ handlers[type].push(handler);
126
+ }
127
+ function getCleanupCallback(type, callback, stopListening) {
128
+ return () => {
129
+ if (stopListening) {
130
+ stopListening();
131
+ }
132
+ const typeHandlers = handlers[type];
133
+ if (!typeHandlers) {
134
+ return;
135
+ }
136
+ const index = typeHandlers.indexOf(callback);
137
+ if (index !== -1) {
138
+ typeHandlers.splice(index, 1);
139
+ }
140
+ };
141
+ }
142
+ function isPerformanceEventTiming(entry) {
143
+ return "duration" in entry;
144
+ }
145
+
146
+ exports.addClsInstrumentationHandler = addClsInstrumentationHandler;
147
+ exports.addInpInstrumentationHandler = addInpInstrumentationHandler;
148
+ exports.addLcpInstrumentationHandler = addLcpInstrumentationHandler;
149
+ exports.addPerformanceInstrumentationHandler = addPerformanceInstrumentationHandler;
150
+ exports.addTtfbInstrumentationHandler = addTtfbInstrumentationHandler;
151
+ exports.isPerformanceEventTiming = isPerformanceEventTiming;
152
+ //# sourceMappingURL=instrument.js.map