@kubesense/kubesense-browser-rum 1.0.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 (540) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +34 -0
  3. package/bundle/chunks/profiler-b64730a2109c3ddbc539-kubesense-rum.js +1 -0
  4. package/bundle/chunks/recorder-9ae532a18bac5f4280da-kubesense-rum.js +1 -0
  5. package/bundle/kubesense-rum.js +1 -0
  6. package/cjs/boot/isBrowserSupported.d.ts +4 -0
  7. package/cjs/boot/isBrowserSupported.js +17 -0
  8. package/cjs/boot/isBrowserSupported.js.map +1 -0
  9. package/cjs/boot/lazyLoadProfiler.d.ts +4 -0
  10. package/cjs/boot/lazyLoadProfiler.js +54 -0
  11. package/cjs/boot/lazyLoadProfiler.js.map +1 -0
  12. package/cjs/boot/lazyLoadRecorder.d.ts +4 -0
  13. package/cjs/boot/lazyLoadRecorder.js +54 -0
  14. package/cjs/boot/lazyLoadRecorder.js.map +1 -0
  15. package/cjs/boot/postStartStrategy.d.ts +33 -0
  16. package/cjs/boot/postStartStrategy.js +98 -0
  17. package/cjs/boot/postStartStrategy.js.map +1 -0
  18. package/cjs/boot/preStartStrategy.d.ts +6 -0
  19. package/cjs/boot/preStartStrategy.js +24 -0
  20. package/cjs/boot/preStartStrategy.js.map +1 -0
  21. package/cjs/boot/profilerApi.d.ts +2 -0
  22. package/cjs/boot/profilerApi.js +53 -0
  23. package/cjs/boot/profilerApi.js.map +1 -0
  24. package/cjs/boot/recorderApi.d.ts +4 -0
  25. package/cjs/boot/recorderApi.js +73 -0
  26. package/cjs/boot/recorderApi.js.map +1 -0
  27. package/cjs/boot/startRecording.d.ts +6 -0
  28. package/cjs/boot/startRecording.js +45 -0
  29. package/cjs/boot/startRecording.js.map +1 -0
  30. package/cjs/domain/deflate/deflateEncoder.d.ts +3 -0
  31. package/cjs/domain/deflate/deflateEncoder.js +110 -0
  32. package/cjs/domain/deflate/deflateEncoder.js.map +1 -0
  33. package/cjs/domain/deflate/deflateWorker.d.ts +30 -0
  34. package/cjs/domain/deflate/deflateWorker.js +104 -0
  35. package/cjs/domain/deflate/deflateWorker.js.map +1 -0
  36. package/cjs/domain/deflate/index.d.ts +3 -0
  37. package/cjs/domain/deflate/index.js +10 -0
  38. package/cjs/domain/deflate/index.js.map +1 -0
  39. package/cjs/domain/getSessionReplayLink.d.ts +2 -0
  40. package/cjs/domain/getSessionReplayLink.js +35 -0
  41. package/cjs/domain/getSessionReplayLink.js.map +1 -0
  42. package/cjs/domain/profiling/profiler.d.ts +7 -0
  43. package/cjs/domain/profiling/profiler.js +244 -0
  44. package/cjs/domain/profiling/profiler.js.map +1 -0
  45. package/cjs/domain/profiling/profilingContext.d.ts +6 -0
  46. package/cjs/domain/profiling/profilingContext.js +28 -0
  47. package/cjs/domain/profiling/profilingContext.js.map +1 -0
  48. package/cjs/domain/profiling/profilingSupported.d.ts +1 -0
  49. package/cjs/domain/profiling/profilingSupported.js +11 -0
  50. package/cjs/domain/profiling/profilingSupported.js.map +1 -0
  51. package/cjs/domain/profiling/test-utils/mockedTrace.d.ts +3 -0
  52. package/cjs/domain/profiling/test-utils/mockedTrace.js +57 -0
  53. package/cjs/domain/profiling/test-utils/mockedTrace.js.map +1 -0
  54. package/cjs/domain/profiling/transport/assembly.d.ts +21 -0
  55. package/cjs/domain/profiling/transport/assembly.js +45 -0
  56. package/cjs/domain/profiling/transport/assembly.js.map +1 -0
  57. package/cjs/domain/profiling/transport/buildProfileEventAttributes.d.ts +25 -0
  58. package/cjs/domain/profiling/transport/buildProfileEventAttributes.js +50 -0
  59. package/cjs/domain/profiling/transport/buildProfileEventAttributes.js.map +1 -0
  60. package/cjs/domain/profiling/types/index.d.ts +2 -0
  61. package/cjs/domain/profiling/types/index.js +3 -0
  62. package/cjs/domain/profiling/types/index.js.map +1 -0
  63. package/cjs/domain/profiling/types/profilerApi.types.d.ts +58 -0
  64. package/cjs/domain/profiling/types/profilerApi.types.js +5 -0
  65. package/cjs/domain/profiling/types/profilerApi.types.js.map +1 -0
  66. package/cjs/domain/profiling/types/rumProfiler.types.d.ts +72 -0
  67. package/cjs/domain/profiling/types/rumProfiler.types.js +3 -0
  68. package/cjs/domain/profiling/types/rumProfiler.types.js.map +1 -0
  69. package/cjs/domain/profiling/utils/getCustomOrDefaultViewName.d.ts +1 -0
  70. package/cjs/domain/profiling/utils/getCustomOrDefaultViewName.js +7 -0
  71. package/cjs/domain/profiling/utils/getCustomOrDefaultViewName.js.map +1 -0
  72. package/cjs/domain/profiling/utils/getDefaultViewName.d.ts +1 -0
  73. package/cjs/domain/profiling/utils/getDefaultViewName.js +14 -0
  74. package/cjs/domain/profiling/utils/getDefaultViewName.js.map +1 -0
  75. package/cjs/domain/profiling/utils/getNumberOfSamples.d.ts +7 -0
  76. package/cjs/domain/profiling/utils/getNumberOfSamples.js +18 -0
  77. package/cjs/domain/profiling/utils/getNumberOfSamples.js.map +1 -0
  78. package/cjs/domain/record/assembly.d.ts +2 -0
  79. package/cjs/domain/record/assembly.js +16 -0
  80. package/cjs/domain/record/assembly.js.map +1 -0
  81. package/cjs/domain/record/elementsScrollPositions.d.ts +10 -0
  82. package/cjs/domain/record/elementsScrollPositions.js +23 -0
  83. package/cjs/domain/record/elementsScrollPositions.js.map +1 -0
  84. package/cjs/domain/record/eventIds.d.ts +4 -0
  85. package/cjs/domain/record/eventIds.js +16 -0
  86. package/cjs/domain/record/eventIds.js.map +1 -0
  87. package/cjs/domain/record/eventsUtils.d.ts +2 -0
  88. package/cjs/domain/record/eventsUtils.js +15 -0
  89. package/cjs/domain/record/eventsUtils.js.map +1 -0
  90. package/cjs/domain/record/index.d.ts +7 -0
  91. package/cjs/domain/record/index.js +17 -0
  92. package/cjs/domain/record/index.js.map +1 -0
  93. package/cjs/domain/record/internalApi.d.ts +22 -0
  94. package/cjs/domain/record/internalApi.js +57 -0
  95. package/cjs/domain/record/internalApi.js.map +1 -0
  96. package/cjs/domain/record/mutationBatch.d.ts +12 -0
  97. package/cjs/domain/record/mutationBatch.js +44 -0
  98. package/cjs/domain/record/mutationBatch.js.map +1 -0
  99. package/cjs/domain/record/nodeIds.d.ts +15 -0
  100. package/cjs/domain/record/nodeIds.js +32 -0
  101. package/cjs/domain/record/nodeIds.js.map +1 -0
  102. package/cjs/domain/record/record.d.ts +16 -0
  103. package/cjs/domain/record/record.js +90 -0
  104. package/cjs/domain/record/record.js.map +1 -0
  105. package/cjs/domain/record/record.types.d.ts +4 -0
  106. package/cjs/domain/record/record.types.js +3 -0
  107. package/cjs/domain/record/record.types.js.map +1 -0
  108. package/cjs/domain/record/recordingScope.d.ts +19 -0
  109. package/cjs/domain/record/recordingScope.js +13 -0
  110. package/cjs/domain/record/recordingScope.js.map +1 -0
  111. package/cjs/domain/record/serialization/index.d.ts +8 -0
  112. package/cjs/domain/record/serialization/index.js +18 -0
  113. package/cjs/domain/record/serialization/index.js.map +1 -0
  114. package/cjs/domain/record/serialization/serialization.types.d.ts +28 -0
  115. package/cjs/domain/record/serialization/serialization.types.js +3 -0
  116. package/cjs/domain/record/serialization/serialization.types.js.map +1 -0
  117. package/cjs/domain/record/serialization/serializationStats.d.ts +12 -0
  118. package/cjs/domain/record/serialization/serializationStats.js +32 -0
  119. package/cjs/domain/record/serialization/serializationStats.js.map +1 -0
  120. package/cjs/domain/record/serialization/serializationTransaction.d.ts +45 -0
  121. package/cjs/domain/record/serialization/serializationTransaction.js +38 -0
  122. package/cjs/domain/record/serialization/serializationTransaction.js.map +1 -0
  123. package/cjs/domain/record/serialization/serializationUtils.d.ts +18 -0
  124. package/cjs/domain/record/serialization/serializationUtils.js +88 -0
  125. package/cjs/domain/record/serialization/serializationUtils.js.map +1 -0
  126. package/cjs/domain/record/serialization/serializeAttribute.d.ts +4 -0
  127. package/cjs/domain/record/serialization/serializeAttribute.js +42 -0
  128. package/cjs/domain/record/serialization/serializeAttribute.js.map +1 -0
  129. package/cjs/domain/record/serialization/serializeAttributes.d.ts +7 -0
  130. package/cjs/domain/record/serialization/serializeAttributes.js +167 -0
  131. package/cjs/domain/record/serialization/serializeAttributes.js.map +1 -0
  132. package/cjs/domain/record/serialization/serializeDocument.d.ts +3 -0
  133. package/cjs/domain/record/serialization/serializeDocument.js +11 -0
  134. package/cjs/domain/record/serialization/serializeDocument.js.map +1 -0
  135. package/cjs/domain/record/serialization/serializeNode.d.ts +7 -0
  136. package/cjs/domain/record/serialization/serializeNode.js +154 -0
  137. package/cjs/domain/record/serialization/serializeNode.js.map +1 -0
  138. package/cjs/domain/record/serialization/serializeStyleSheets.d.ts +2 -0
  139. package/cjs/domain/record/serialization/serializeStyleSheets.js +19 -0
  140. package/cjs/domain/record/serialization/serializeStyleSheets.js.map +1 -0
  141. package/cjs/domain/record/shadowRootsController.d.ts +11 -0
  142. package/cjs/domain/record/shadowRootsController.js +45 -0
  143. package/cjs/domain/record/shadowRootsController.js.map +1 -0
  144. package/cjs/domain/record/startFullSnapshots.d.ts +9 -0
  145. package/cjs/domain/record/startFullSnapshots.js +59 -0
  146. package/cjs/domain/record/startFullSnapshots.js.map +1 -0
  147. package/cjs/domain/record/trackers/index.d.ts +12 -0
  148. package/cjs/domain/record/trackers/index.js +27 -0
  149. package/cjs/domain/record/trackers/index.js.map +1 -0
  150. package/cjs/domain/record/trackers/trackFocus.d.ts +5 -0
  151. package/cjs/domain/record/trackers/trackFocus.js +15 -0
  152. package/cjs/domain/record/trackers/trackFocus.js.map +1 -0
  153. package/cjs/domain/record/trackers/trackFrustration.d.ts +7 -0
  154. package/cjs/domain/record/trackers/trackFrustration.js +31 -0
  155. package/cjs/domain/record/trackers/trackFrustration.js.map +1 -0
  156. package/cjs/domain/record/trackers/trackInput.d.ts +4 -0
  157. package/cjs/domain/record/trackers/trackInput.js +104 -0
  158. package/cjs/domain/record/trackers/trackInput.js.map +1 -0
  159. package/cjs/domain/record/trackers/trackMediaInteraction.d.ts +5 -0
  160. package/cjs/domain/record/trackers/trackMediaInteraction.js +29 -0
  161. package/cjs/domain/record/trackers/trackMediaInteraction.js.map +1 -0
  162. package/cjs/domain/record/trackers/trackMouseInteraction.d.ts +5 -0
  163. package/cjs/domain/record/trackers/trackMouseInteraction.js +59 -0
  164. package/cjs/domain/record/trackers/trackMouseInteraction.js.map +1 -0
  165. package/cjs/domain/record/trackers/trackMove.d.ts +9 -0
  166. package/cjs/domain/record/trackers/trackMove.js +55 -0
  167. package/cjs/domain/record/trackers/trackMove.js.map +1 -0
  168. package/cjs/domain/record/trackers/trackMutation.d.ts +11 -0
  169. package/cjs/domain/record/trackers/trackMutation.js +270 -0
  170. package/cjs/domain/record/trackers/trackMutation.js.map +1 -0
  171. package/cjs/domain/record/trackers/trackScroll.d.ts +5 -0
  172. package/cjs/domain/record/trackers/trackScroll.js +48 -0
  173. package/cjs/domain/record/trackers/trackScroll.js.map +1 -0
  174. package/cjs/domain/record/trackers/trackStyleSheet.d.ts +6 -0
  175. package/cjs/domain/record/trackers/trackStyleSheet.js +89 -0
  176. package/cjs/domain/record/trackers/trackStyleSheet.js.map +1 -0
  177. package/cjs/domain/record/trackers/trackViewEnd.d.ts +5 -0
  178. package/cjs/domain/record/trackers/trackViewEnd.js +20 -0
  179. package/cjs/domain/record/trackers/trackViewEnd.js.map +1 -0
  180. package/cjs/domain/record/trackers/trackViewportResize.d.ts +6 -0
  181. package/cjs/domain/record/trackers/trackViewportResize.js +46 -0
  182. package/cjs/domain/record/trackers/trackViewportResize.js.map +1 -0
  183. package/cjs/domain/record/trackers/tracker.types.d.ts +3 -0
  184. package/cjs/domain/record/trackers/tracker.types.js +3 -0
  185. package/cjs/domain/record/trackers/tracker.types.js.map +1 -0
  186. package/cjs/domain/record/viewports.d.ts +20 -0
  187. package/cjs/domain/record/viewports.js +60 -0
  188. package/cjs/domain/record/viewports.js.map +1 -0
  189. package/cjs/domain/replayStats.d.ts +8 -0
  190. package/cjs/domain/replayStats.js +60 -0
  191. package/cjs/domain/replayStats.js.map +1 -0
  192. package/cjs/domain/scriptLoadingError.d.ts +6 -0
  193. package/cjs/domain/scriptLoadingError.js +26 -0
  194. package/cjs/domain/scriptLoadingError.js.map +1 -0
  195. package/cjs/domain/segmentCollection/buildReplayPayload.d.ts +15 -0
  196. package/cjs/domain/segmentCollection/buildReplayPayload.js +26 -0
  197. package/cjs/domain/segmentCollection/buildReplayPayload.js.map +1 -0
  198. package/cjs/domain/segmentCollection/index.d.ts +4 -0
  199. package/cjs/domain/segmentCollection/index.js +11 -0
  200. package/cjs/domain/segmentCollection/index.js.map +1 -0
  201. package/cjs/domain/segmentCollection/segment.d.ts +16 -0
  202. package/cjs/domain/segmentCollection/segment.js +82 -0
  203. package/cjs/domain/segmentCollection/segment.js.map +1 -0
  204. package/cjs/domain/segmentCollection/segmentCollection.d.ts +31 -0
  205. package/cjs/domain/segmentCollection/segmentCollection.js +113 -0
  206. package/cjs/domain/segmentCollection/segmentCollection.js.map +1 -0
  207. package/cjs/domain/segmentCollection/startSegmentTelemetry.d.ts +6 -0
  208. package/cjs/domain/segmentCollection/startSegmentTelemetry.js +47 -0
  209. package/cjs/domain/segmentCollection/startSegmentTelemetry.js.map +1 -0
  210. package/cjs/domain/startRecordBridge.d.ts +5 -0
  211. package/cjs/domain/startRecordBridge.js +17 -0
  212. package/cjs/domain/startRecordBridge.js.map +1 -0
  213. package/cjs/domain/startRecorderInitTelemetry.d.ts +15 -0
  214. package/cjs/domain/startRecorderInitTelemetry.js +55 -0
  215. package/cjs/domain/startRecorderInitTelemetry.js.map +1 -0
  216. package/cjs/entries/internal.d.ts +11 -0
  217. package/cjs/entries/internal.js +28 -0
  218. package/cjs/entries/internal.js.map +1 -0
  219. package/cjs/entries/internalSynthetics.d.ts +2 -0
  220. package/cjs/entries/internalSynthetics.js +27 -0
  221. package/cjs/entries/internalSynthetics.js.map +1 -0
  222. package/cjs/entries/main.d.ts +23 -0
  223. package/cjs/entries/main.js +35 -0
  224. package/cjs/entries/main.js.map +1 -0
  225. package/cjs/types/index.d.ts +2 -0
  226. package/cjs/types/index.js +18 -0
  227. package/cjs/types/index.js.map +1 -0
  228. package/cjs/types/sessionReplay.d.ts +703 -0
  229. package/cjs/types/sessionReplay.js +7 -0
  230. package/cjs/types/sessionReplay.js.map +1 -0
  231. package/cjs/types/sessionReplayConstants.d.ts +49 -0
  232. package/cjs/types/sessionReplayConstants.js +49 -0
  233. package/cjs/types/sessionReplayConstants.js.map +1 -0
  234. package/esm/boot/isBrowserSupported.d.ts +4 -0
  235. package/esm/boot/isBrowserSupported.js +14 -0
  236. package/esm/boot/isBrowserSupported.js.map +1 -0
  237. package/esm/boot/lazyLoadProfiler.d.ts +4 -0
  238. package/esm/boot/lazyLoadProfiler.js +18 -0
  239. package/esm/boot/lazyLoadProfiler.js.map +1 -0
  240. package/esm/boot/lazyLoadRecorder.d.ts +4 -0
  241. package/esm/boot/lazyLoadRecorder.js +18 -0
  242. package/esm/boot/lazyLoadRecorder.js.map +1 -0
  243. package/esm/boot/postStartStrategy.d.ts +33 -0
  244. package/esm/boot/postStartStrategy.js +95 -0
  245. package/esm/boot/postStartStrategy.js.map +1 -0
  246. package/esm/boot/preStartStrategy.d.ts +6 -0
  247. package/esm/boot/preStartStrategy.js +21 -0
  248. package/esm/boot/preStartStrategy.js.map +1 -0
  249. package/esm/boot/profilerApi.d.ts +2 -0
  250. package/esm/boot/profilerApi.js +50 -0
  251. package/esm/boot/profilerApi.js.map +1 -0
  252. package/esm/boot/recorderApi.d.ts +4 -0
  253. package/esm/boot/recorderApi.js +70 -0
  254. package/esm/boot/recorderApi.js.map +1 -0
  255. package/esm/boot/startRecording.d.ts +6 -0
  256. package/esm/boot/startRecording.js +42 -0
  257. package/esm/boot/startRecording.js.map +1 -0
  258. package/esm/domain/deflate/deflateEncoder.d.ts +3 -0
  259. package/esm/domain/deflate/deflateEncoder.js +107 -0
  260. package/esm/domain/deflate/deflateEncoder.js.map +1 -0
  261. package/esm/domain/deflate/deflateWorker.d.ts +30 -0
  262. package/esm/domain/deflate/deflateWorker.js +97 -0
  263. package/esm/domain/deflate/deflateWorker.js.map +1 -0
  264. package/esm/domain/deflate/index.d.ts +3 -0
  265. package/esm/domain/deflate/index.js +3 -0
  266. package/esm/domain/deflate/index.js.map +1 -0
  267. package/esm/domain/getSessionReplayLink.d.ts +2 -0
  268. package/esm/domain/getSessionReplayLink.js +32 -0
  269. package/esm/domain/getSessionReplayLink.js.map +1 -0
  270. package/esm/domain/profiling/profiler.d.ts +7 -0
  271. package/esm/domain/profiling/profiler.js +240 -0
  272. package/esm/domain/profiling/profiler.js.map +1 -0
  273. package/esm/domain/profiling/profilingContext.d.ts +6 -0
  274. package/esm/domain/profiling/profilingContext.js +25 -0
  275. package/esm/domain/profiling/profilingContext.js.map +1 -0
  276. package/esm/domain/profiling/profilingSupported.d.ts +1 -0
  277. package/esm/domain/profiling/profilingSupported.js +8 -0
  278. package/esm/domain/profiling/profilingSupported.js.map +1 -0
  279. package/esm/domain/profiling/test-utils/mockedTrace.d.ts +3 -0
  280. package/esm/domain/profiling/test-utils/mockedTrace.js +54 -0
  281. package/esm/domain/profiling/test-utils/mockedTrace.js.map +1 -0
  282. package/esm/domain/profiling/transport/assembly.d.ts +21 -0
  283. package/esm/domain/profiling/transport/assembly.js +42 -0
  284. package/esm/domain/profiling/transport/assembly.js.map +1 -0
  285. package/esm/domain/profiling/transport/buildProfileEventAttributes.d.ts +25 -0
  286. package/esm/domain/profiling/transport/buildProfileEventAttributes.js +47 -0
  287. package/esm/domain/profiling/transport/buildProfileEventAttributes.js.map +1 -0
  288. package/esm/domain/profiling/types/index.d.ts +2 -0
  289. package/esm/domain/profiling/types/index.js +2 -0
  290. package/esm/domain/profiling/types/index.js.map +1 -0
  291. package/esm/domain/profiling/types/profilerApi.types.d.ts +58 -0
  292. package/esm/domain/profiling/types/profilerApi.types.js +4 -0
  293. package/esm/domain/profiling/types/profilerApi.types.js.map +1 -0
  294. package/esm/domain/profiling/types/rumProfiler.types.d.ts +72 -0
  295. package/esm/domain/profiling/types/rumProfiler.types.js +2 -0
  296. package/esm/domain/profiling/types/rumProfiler.types.js.map +1 -0
  297. package/esm/domain/profiling/utils/getCustomOrDefaultViewName.d.ts +1 -0
  298. package/esm/domain/profiling/utils/getCustomOrDefaultViewName.js +3 -0
  299. package/esm/domain/profiling/utils/getCustomOrDefaultViewName.js.map +1 -0
  300. package/esm/domain/profiling/utils/getDefaultViewName.d.ts +1 -0
  301. package/esm/domain/profiling/utils/getDefaultViewName.js +11 -0
  302. package/esm/domain/profiling/utils/getDefaultViewName.js.map +1 -0
  303. package/esm/domain/profiling/utils/getNumberOfSamples.d.ts +7 -0
  304. package/esm/domain/profiling/utils/getNumberOfSamples.js +15 -0
  305. package/esm/domain/profiling/utils/getNumberOfSamples.js.map +1 -0
  306. package/esm/domain/record/assembly.d.ts +2 -0
  307. package/esm/domain/record/assembly.js +13 -0
  308. package/esm/domain/record/assembly.js.map +1 -0
  309. package/esm/domain/record/elementsScrollPositions.d.ts +10 -0
  310. package/esm/domain/record/elementsScrollPositions.js +20 -0
  311. package/esm/domain/record/elementsScrollPositions.js.map +1 -0
  312. package/esm/domain/record/eventIds.d.ts +4 -0
  313. package/esm/domain/record/eventIds.js +13 -0
  314. package/esm/domain/record/eventIds.js.map +1 -0
  315. package/esm/domain/record/eventsUtils.d.ts +2 -0
  316. package/esm/domain/record/eventsUtils.js +11 -0
  317. package/esm/domain/record/eventsUtils.js.map +1 -0
  318. package/esm/domain/record/index.d.ts +7 -0
  319. package/esm/domain/record/index.js +6 -0
  320. package/esm/domain/record/index.js.map +1 -0
  321. package/esm/domain/record/internalApi.d.ts +22 -0
  322. package/esm/domain/record/internalApi.js +53 -0
  323. package/esm/domain/record/internalApi.js.map +1 -0
  324. package/esm/domain/record/mutationBatch.d.ts +12 -0
  325. package/esm/domain/record/mutationBatch.js +40 -0
  326. package/esm/domain/record/mutationBatch.js.map +1 -0
  327. package/esm/domain/record/nodeIds.d.ts +15 -0
  328. package/esm/domain/record/nodeIds.js +29 -0
  329. package/esm/domain/record/nodeIds.js.map +1 -0
  330. package/esm/domain/record/record.d.ts +16 -0
  331. package/esm/domain/record/record.js +54 -0
  332. package/esm/domain/record/record.js.map +1 -0
  333. package/esm/domain/record/record.types.d.ts +4 -0
  334. package/esm/domain/record/record.types.js +2 -0
  335. package/esm/domain/record/record.types.js.map +1 -0
  336. package/esm/domain/record/recordingScope.d.ts +19 -0
  337. package/esm/domain/record/recordingScope.js +10 -0
  338. package/esm/domain/record/recordingScope.js.map +1 -0
  339. package/esm/domain/record/serialization/index.d.ts +8 -0
  340. package/esm/domain/record/serialization/index.js +7 -0
  341. package/esm/domain/record/serialization/index.js.map +1 -0
  342. package/esm/domain/record/serialization/serialization.types.d.ts +28 -0
  343. package/esm/domain/record/serialization/serialization.types.js +2 -0
  344. package/esm/domain/record/serialization/serialization.types.js.map +1 -0
  345. package/esm/domain/record/serialization/serializationStats.d.ts +12 -0
  346. package/esm/domain/record/serialization/serializationStats.js +27 -0
  347. package/esm/domain/record/serialization/serializationStats.js.map +1 -0
  348. package/esm/domain/record/serialization/serializationTransaction.d.ts +45 -0
  349. package/esm/domain/record/serialization/serializationTransaction.js +35 -0
  350. package/esm/domain/record/serialization/serializationTransaction.js.map +1 -0
  351. package/esm/domain/record/serialization/serializationUtils.d.ts +18 -0
  352. package/esm/domain/record/serialization/serializationUtils.js +80 -0
  353. package/esm/domain/record/serialization/serializationUtils.js.map +1 -0
  354. package/esm/domain/record/serialization/serializeAttribute.d.ts +4 -0
  355. package/esm/domain/record/serialization/serializeAttribute.js +38 -0
  356. package/esm/domain/record/serialization/serializeAttribute.js.map +1 -0
  357. package/esm/domain/record/serialization/serializeAttributes.d.ts +7 -0
  358. package/esm/domain/record/serialization/serializeAttributes.js +161 -0
  359. package/esm/domain/record/serialization/serializeAttributes.js.map +1 -0
  360. package/esm/domain/record/serialization/serializeDocument.d.ts +3 -0
  361. package/esm/domain/record/serialization/serializeDocument.js +8 -0
  362. package/esm/domain/record/serialization/serializeDocument.js.map +1 -0
  363. package/esm/domain/record/serialization/serializeNode.d.ts +7 -0
  364. package/esm/domain/record/serialization/serializeNode.js +149 -0
  365. package/esm/domain/record/serialization/serializeNode.js.map +1 -0
  366. package/esm/domain/record/serialization/serializeStyleSheets.d.ts +2 -0
  367. package/esm/domain/record/serialization/serializeStyleSheets.js +16 -0
  368. package/esm/domain/record/serialization/serializeStyleSheets.js.map +1 -0
  369. package/esm/domain/record/shadowRootsController.d.ts +11 -0
  370. package/esm/domain/record/shadowRootsController.js +41 -0
  371. package/esm/domain/record/shadowRootsController.js.map +1 -0
  372. package/esm/domain/record/startFullSnapshots.d.ts +9 -0
  373. package/esm/domain/record/startFullSnapshots.js +55 -0
  374. package/esm/domain/record/startFullSnapshots.js.map +1 -0
  375. package/esm/domain/record/trackers/index.d.ts +12 -0
  376. package/esm/domain/record/trackers/index.js +12 -0
  377. package/esm/domain/record/trackers/index.js.map +1 -0
  378. package/esm/domain/record/trackers/trackFocus.d.ts +5 -0
  379. package/esm/domain/record/trackers/trackFocus.js +12 -0
  380. package/esm/domain/record/trackers/trackFocus.js.map +1 -0
  381. package/esm/domain/record/trackers/trackFrustration.d.ts +7 -0
  382. package/esm/domain/record/trackers/trackFrustration.js +28 -0
  383. package/esm/domain/record/trackers/trackFrustration.js.map +1 -0
  384. package/esm/domain/record/trackers/trackInput.d.ts +4 -0
  385. package/esm/domain/record/trackers/trackInput.js +101 -0
  386. package/esm/domain/record/trackers/trackInput.js.map +1 -0
  387. package/esm/domain/record/trackers/trackMediaInteraction.d.ts +5 -0
  388. package/esm/domain/record/trackers/trackMediaInteraction.js +26 -0
  389. package/esm/domain/record/trackers/trackMediaInteraction.js.map +1 -0
  390. package/esm/domain/record/trackers/trackMouseInteraction.d.ts +5 -0
  391. package/esm/domain/record/trackers/trackMouseInteraction.js +56 -0
  392. package/esm/domain/record/trackers/trackMouseInteraction.js.map +1 -0
  393. package/esm/domain/record/trackers/trackMove.d.ts +9 -0
  394. package/esm/domain/record/trackers/trackMove.js +51 -0
  395. package/esm/domain/record/trackers/trackMove.js.map +1 -0
  396. package/esm/domain/record/trackers/trackMutation.d.ts +11 -0
  397. package/esm/domain/record/trackers/trackMutation.js +266 -0
  398. package/esm/domain/record/trackers/trackMutation.js.map +1 -0
  399. package/esm/domain/record/trackers/trackScroll.d.ts +5 -0
  400. package/esm/domain/record/trackers/trackScroll.js +45 -0
  401. package/esm/domain/record/trackers/trackScroll.js.map +1 -0
  402. package/esm/domain/record/trackers/trackStyleSheet.d.ts +6 -0
  403. package/esm/domain/record/trackers/trackStyleSheet.js +85 -0
  404. package/esm/domain/record/trackers/trackStyleSheet.js.map +1 -0
  405. package/esm/domain/record/trackers/trackViewEnd.d.ts +5 -0
  406. package/esm/domain/record/trackers/trackViewEnd.js +17 -0
  407. package/esm/domain/record/trackers/trackViewEnd.js.map +1 -0
  408. package/esm/domain/record/trackers/trackViewportResize.d.ts +6 -0
  409. package/esm/domain/record/trackers/trackViewportResize.js +42 -0
  410. package/esm/domain/record/trackers/trackViewportResize.js.map +1 -0
  411. package/esm/domain/record/trackers/tracker.types.d.ts +3 -0
  412. package/esm/domain/record/trackers/tracker.types.js +2 -0
  413. package/esm/domain/record/trackers/tracker.types.js.map +1 -0
  414. package/esm/domain/record/viewports.d.ts +20 -0
  415. package/esm/domain/record/viewports.js +55 -0
  416. package/esm/domain/record/viewports.js.map +1 -0
  417. package/esm/domain/replayStats.d.ts +8 -0
  418. package/esm/domain/replayStats.js +51 -0
  419. package/esm/domain/replayStats.js.map +1 -0
  420. package/esm/domain/scriptLoadingError.d.ts +6 -0
  421. package/esm/domain/scriptLoadingError.js +23 -0
  422. package/esm/domain/scriptLoadingError.js.map +1 -0
  423. package/esm/domain/segmentCollection/buildReplayPayload.d.ts +15 -0
  424. package/esm/domain/segmentCollection/buildReplayPayload.js +23 -0
  425. package/esm/domain/segmentCollection/buildReplayPayload.js.map +1 -0
  426. package/esm/domain/segmentCollection/index.d.ts +4 -0
  427. package/esm/domain/segmentCollection/index.js +4 -0
  428. package/esm/domain/segmentCollection/index.js.map +1 -0
  429. package/esm/domain/segmentCollection/segment.d.ts +16 -0
  430. package/esm/domain/segmentCollection/segment.js +46 -0
  431. package/esm/domain/segmentCollection/segment.js.map +1 -0
  432. package/esm/domain/segmentCollection/segmentCollection.d.ts +31 -0
  433. package/esm/domain/segmentCollection/segmentCollection.js +106 -0
  434. package/esm/domain/segmentCollection/segmentCollection.js.map +1 -0
  435. package/esm/domain/segmentCollection/startSegmentTelemetry.d.ts +6 -0
  436. package/esm/domain/segmentCollection/startSegmentTelemetry.js +44 -0
  437. package/esm/domain/segmentCollection/startSegmentTelemetry.js.map +1 -0
  438. package/esm/domain/startRecordBridge.d.ts +5 -0
  439. package/esm/domain/startRecordBridge.js +14 -0
  440. package/esm/domain/startRecordBridge.js.map +1 -0
  441. package/esm/domain/startRecorderInitTelemetry.d.ts +15 -0
  442. package/esm/domain/startRecorderInitTelemetry.js +52 -0
  443. package/esm/domain/startRecorderInitTelemetry.js.map +1 -0
  444. package/esm/entries/internal.d.ts +11 -0
  445. package/esm/entries/internal.js +4 -0
  446. package/esm/entries/internal.js.map +1 -0
  447. package/esm/entries/internalSynthetics.d.ts +2 -0
  448. package/esm/entries/internalSynthetics.js +23 -0
  449. package/esm/entries/internalSynthetics.js.map +1 -0
  450. package/esm/entries/main.d.ts +23 -0
  451. package/esm/entries/main.js +31 -0
  452. package/esm/entries/main.js.map +1 -0
  453. package/esm/types/index.d.ts +2 -0
  454. package/esm/types/index.js +2 -0
  455. package/esm/types/index.js.map +1 -0
  456. package/esm/types/sessionReplay.d.ts +703 -0
  457. package/esm/types/sessionReplay.js +6 -0
  458. package/esm/types/sessionReplay.js.map +1 -0
  459. package/esm/types/sessionReplayConstants.d.ts +49 -0
  460. package/esm/types/sessionReplayConstants.js +46 -0
  461. package/esm/types/sessionReplayConstants.js.map +1 -0
  462. package/internal/package.json +6 -0
  463. package/internal-synthetics/package.json +6 -0
  464. package/package.json +40 -0
  465. package/src/boot/isBrowserSupported.ts +14 -0
  466. package/src/boot/lazyLoadProfiler.ts +21 -0
  467. package/src/boot/lazyLoadRecorder.ts +21 -0
  468. package/src/boot/postStartStrategy.ts +176 -0
  469. package/src/boot/preStartStrategy.ts +34 -0
  470. package/src/boot/profilerApi.ts +86 -0
  471. package/src/boot/recorderApi.ts +124 -0
  472. package/src/boot/startRecording.ts +70 -0
  473. package/src/domain/deflate/deflateEncoder.ts +144 -0
  474. package/src/domain/deflate/deflateWorker.ts +157 -0
  475. package/src/domain/deflate/index.ts +8 -0
  476. package/src/domain/getSessionReplayLink.ts +40 -0
  477. package/src/domain/profiling/profiler.ts +338 -0
  478. package/src/domain/profiling/profilingContext.ts +34 -0
  479. package/src/domain/profiling/profilingSupported.ts +10 -0
  480. package/src/domain/profiling/test-utils/mockedTrace.ts +58 -0
  481. package/src/domain/profiling/transport/assembly.ts +78 -0
  482. package/src/domain/profiling/transport/buildProfileEventAttributes.ts +66 -0
  483. package/src/domain/profiling/types/index.ts +2 -0
  484. package/src/domain/profiling/types/profilerApi.types.ts +87 -0
  485. package/src/domain/profiling/types/rumProfiler.types.ts +81 -0
  486. package/src/domain/profiling/utils/getCustomOrDefaultViewName.ts +4 -0
  487. package/src/domain/profiling/utils/getDefaultViewName.ts +12 -0
  488. package/src/domain/profiling/utils/getNumberOfSamples.ts +16 -0
  489. package/src/domain/record/assembly.ts +17 -0
  490. package/src/domain/record/elementsScrollPositions.ts +28 -0
  491. package/src/domain/record/eventIds.ts +17 -0
  492. package/src/domain/record/eventsUtils.ts +12 -0
  493. package/src/domain/record/index.ts +7 -0
  494. package/src/domain/record/internalApi.ts +88 -0
  495. package/src/domain/record/mutationBatch.ts +47 -0
  496. package/src/domain/record/nodeIds.ts +46 -0
  497. package/src/domain/record/record.ts +98 -0
  498. package/src/domain/record/record.types.ts +5 -0
  499. package/src/domain/record/recordingScope.ts +36 -0
  500. package/src/domain/record/serialization/index.ts +8 -0
  501. package/src/domain/record/serialization/serialization.types.ts +43 -0
  502. package/src/domain/record/serialization/serializationStats.ts +43 -0
  503. package/src/domain/record/serialization/serializationTransaction.ts +94 -0
  504. package/src/domain/record/serialization/serializationUtils.ts +103 -0
  505. package/src/domain/record/serialization/serializeAttribute.ts +55 -0
  506. package/src/domain/record/serialization/serializeAttributes.ts +194 -0
  507. package/src/domain/record/serialization/serializeDocument.ts +13 -0
  508. package/src/domain/record/serialization/serializeNode.ts +229 -0
  509. package/src/domain/record/serialization/serializeStyleSheets.ts +18 -0
  510. package/src/domain/record/shadowRootsController.ts +62 -0
  511. package/src/domain/record/startFullSnapshots.ts +84 -0
  512. package/src/domain/record/trackers/index.ts +12 -0
  513. package/src/domain/record/trackers/trackFocus.ts +16 -0
  514. package/src/domain/record/trackers/trackFrustration.ts +41 -0
  515. package/src/domain/record/trackers/trackInput.ts +128 -0
  516. package/src/domain/record/trackers/trackMediaInteraction.ts +43 -0
  517. package/src/domain/record/trackers/trackMouseInteraction.ts +74 -0
  518. package/src/domain/record/trackers/trackMove.ts +78 -0
  519. package/src/domain/record/trackers/trackMutation.ts +399 -0
  520. package/src/domain/record/trackers/trackScroll.ts +61 -0
  521. package/src/domain/record/trackers/trackStyleSheet.ts +117 -0
  522. package/src/domain/record/trackers/trackViewEnd.ts +27 -0
  523. package/src/domain/record/trackers/trackViewportResize.ts +69 -0
  524. package/src/domain/record/trackers/tracker.types.ts +3 -0
  525. package/src/domain/record/viewports.ts +68 -0
  526. package/src/domain/replayStats.ts +61 -0
  527. package/src/domain/scriptLoadingError.ts +36 -0
  528. package/src/domain/segmentCollection/buildReplayPayload.ts +52 -0
  529. package/src/domain/segmentCollection/index.ts +4 -0
  530. package/src/domain/segmentCollection/segment.ts +78 -0
  531. package/src/domain/segmentCollection/segmentCollection.ts +200 -0
  532. package/src/domain/segmentCollection/startSegmentTelemetry.ts +82 -0
  533. package/src/domain/startRecordBridge.ts +17 -0
  534. package/src/domain/startRecorderInitTelemetry.ts +90 -0
  535. package/src/entries/internal.ts +18 -0
  536. package/src/entries/internalSynthetics.ts +24 -0
  537. package/src/entries/main.ts +95 -0
  538. package/src/types/index.ts +2 -0
  539. package/src/types/sessionReplay.ts +734 -0
  540. package/src/types/sessionReplayConstants.ts +86 -0
@@ -0,0 +1,338 @@
1
+ import type { Encoder } from '@kubesense/kubesense-browser-core'
2
+ import {
3
+ addEventListener,
4
+ clearTimeout,
5
+ setTimeout,
6
+ DOM_EVENT,
7
+ monitorError,
8
+ display,
9
+ getGlobalObject,
10
+ clocksOrigin,
11
+ clocksNow,
12
+ elapsed,
13
+ DeflateEncoderStreamId,
14
+ } from '@kubesense/kubesense-browser-core'
15
+
16
+ import type {
17
+ LifeCycle,
18
+ LongTaskContexts,
19
+ RumConfiguration,
20
+ RumSessionManager,
21
+ TransportPayload,
22
+ ViewHistory,
23
+ } from '@kubesense/kubesense-browser-rum-core'
24
+ import { createFormDataTransport, LifeCycleEventType } from '@kubesense/kubesense-browser-rum-core'
25
+ import type {
26
+ RumProfilerTrace,
27
+ RumProfilerInstance,
28
+ Profiler,
29
+ RUMProfiler,
30
+ RUMProfilerConfiguration,
31
+ RumProfilerStoppedInstance,
32
+ RumViewEntry,
33
+ } from './types'
34
+ import { getNumberOfSamples } from './utils/getNumberOfSamples'
35
+ import type { ProfilingContextManager } from './profilingContext'
36
+ import { getCustomOrDefaultViewName } from './utils/getCustomOrDefaultViewName'
37
+ import { assembleProfilingPayload } from './transport/assembly'
38
+
39
+ export const DEFAULT_RUM_PROFILER_CONFIGURATION: RUMProfilerConfiguration = {
40
+ sampleIntervalMs: 10, // Sample stack trace every 10ms
41
+ collectIntervalMs: 60000, // Collect data every minute
42
+ minProfileDurationMs: 5000, // Require at least 5 seconds of profile data to reduce noise and cost
43
+ minNumberOfSamples: 50, // Require at least 50 samples (~500 ms) to report a profile to reduce noise and cost
44
+ }
45
+
46
+ export function createRumProfiler(
47
+ configuration: RumConfiguration,
48
+ lifeCycle: LifeCycle,
49
+ session: RumSessionManager,
50
+ profilingContextManager: ProfilingContextManager,
51
+ longTaskContexts: LongTaskContexts,
52
+ createEncoder: (streamId: DeflateEncoderStreamId) => Encoder,
53
+ viewHistory: ViewHistory,
54
+ profilerConfiguration: RUMProfilerConfiguration = DEFAULT_RUM_PROFILER_CONFIGURATION
55
+ ): RUMProfiler {
56
+ const transport = createFormDataTransport(configuration, lifeCycle, createEncoder, DeflateEncoderStreamId.PROFILING)
57
+
58
+ let lastViewEntry: RumViewEntry | undefined
59
+
60
+ // Global clean-up tasks for listeners that are not specific to a profiler instance (eg. visibility change, before unload)
61
+ const globalCleanupTasks: Array<() => void> = []
62
+
63
+ let instance: RumProfilerInstance = { state: 'stopped', stateReason: 'initializing' }
64
+
65
+ // Stops the profiler when session expires
66
+ lifeCycle.subscribe(LifeCycleEventType.SESSION_EXPIRED, () => {
67
+ stopProfiling('session-expired').catch(monitorError)
68
+ })
69
+
70
+ // Start the profiler again when session is renewed
71
+ lifeCycle.subscribe(LifeCycleEventType.SESSION_RENEWED, () => {
72
+ if (instance.state === 'stopped' && instance.stateReason === 'session-expired') {
73
+ start() // Only restart the profiler if it was stopped due to session expiration. Avoid restarting the profiler if it was stopped manually by the user.
74
+ }
75
+ })
76
+
77
+ // Public API to start the profiler.
78
+ function start(): void {
79
+ if (instance.state === 'running') {
80
+ return
81
+ }
82
+
83
+ const viewEntry = viewHistory.findView()
84
+
85
+ // Add initial view
86
+ // Note: `viewEntry.name` is only filled when users use manual view creation via `startView` method.
87
+ lastViewEntry = viewEntry
88
+ ? {
89
+ startClocks: viewEntry.startClocks,
90
+ viewId: viewEntry.id,
91
+ viewName: getCustomOrDefaultViewName(viewEntry.name, document.location.pathname),
92
+ }
93
+ : undefined
94
+
95
+ // Add global clean-up tasks for listeners that are not specific to a profiler instance (eg. visibility change, before unload)
96
+ globalCleanupTasks.push(
97
+ addEventListener(configuration, window, DOM_EVENT.VISIBILITY_CHANGE, handleVisibilityChange).stop,
98
+ addEventListener(configuration, window, DOM_EVENT.BEFORE_UNLOAD, handleBeforeUnload).stop
99
+ )
100
+
101
+ // Start profiler instance
102
+ startNextProfilerInstance()
103
+ }
104
+
105
+ // Public API to manually stop the profiler.
106
+ async function stop() {
107
+ await stopProfiling('stopped-by-user')
108
+ }
109
+
110
+ async function stopProfiling(reason: RumProfilerStoppedInstance['stateReason']) {
111
+ // Stop current profiler instance
112
+ await stopProfilerInstance(reason)
113
+
114
+ // Cleanup global listeners
115
+ globalCleanupTasks.forEach((task) => task())
116
+
117
+ // Update Profiling status once the Profiler has been stopped.
118
+ profilingContextManager.set({ status: 'stopped', error_reason: undefined })
119
+ }
120
+
121
+ /**
122
+ * Whenever a new Profiler instance is started, we need to add event listeners to surroundings (RUM Events, Long Tasks, etc) to enrich the Profiler data.
123
+ * If the instance is already running, we can keep the same event listeners.
124
+ */
125
+ function addEventListeners(existingInstance: RumProfilerInstance) {
126
+ if (existingInstance.state === 'running') {
127
+ // Instance is already running, so we can keep same event listeners.
128
+ return {
129
+ cleanupTasks: existingInstance.cleanupTasks,
130
+ }
131
+ }
132
+
133
+ // Store clean-up tasks for this instance (tasks to be executed when the Profiler is stopped or paused.)
134
+ const cleanupTasks = []
135
+
136
+ // Whenever the View is updated, we add a views entry to the profiler instance.
137
+ const viewUpdatedSubscription = lifeCycle.subscribe(LifeCycleEventType.VIEW_CREATED, (view) => {
138
+ const viewEntry = {
139
+ viewId: view.id,
140
+ // Note: `viewName` is only filled when users use manual view creation via `startView` method.
141
+ viewName: getCustomOrDefaultViewName(view.name, document.location.pathname),
142
+ startClocks: view.startClocks,
143
+ }
144
+
145
+ collectViewEntry(viewEntry)
146
+
147
+ // Update last view entry
148
+ lastViewEntry = viewEntry
149
+ })
150
+ cleanupTasks.push(viewUpdatedSubscription.unsubscribe)
151
+
152
+ return {
153
+ cleanupTasks,
154
+ }
155
+ }
156
+
157
+ function startNextProfilerInstance(): void {
158
+ // These APIs might be unavailable in some browsers
159
+ const globalThisProfiler: Profiler | undefined = getGlobalObject<any>().Profiler
160
+
161
+ if (!globalThisProfiler) {
162
+ profilingContextManager.set({ status: 'error', error_reason: 'not-supported-by-browser' })
163
+ throw new Error('RUM Profiler is not supported in this browser.')
164
+ }
165
+
166
+ // Don't wait for data collection to start next instance
167
+ collectProfilerInstance(instance).catch(monitorError)
168
+
169
+ const { cleanupTasks } = addEventListeners(instance)
170
+
171
+ let profiler: Profiler
172
+ try {
173
+ // We have to create new Profiler each time we start a new instance
174
+ profiler = new globalThisProfiler({
175
+ sampleInterval: profilerConfiguration.sampleIntervalMs,
176
+ // Keep buffer size at 1.5 times of minimum required to collect data for a profiling instance
177
+ maxBufferSize: Math.round(
178
+ (profilerConfiguration.collectIntervalMs * 1.5) / profilerConfiguration.sampleIntervalMs
179
+ ),
180
+ })
181
+ } catch (e) {
182
+ if (e instanceof Error && e.message.includes('disabled by Document Policy')) {
183
+ // Missing Response Header (`js-profiling`) that is required to enable the profiler.
184
+ // We should suggest the user to enable the Response Header in their server configuration.
185
+ display.warn(
186
+ '[KUBESENSE_SDK] Profiler startup failed. Ensure your server includes the `Document-Policy: js-profiling` response header when serving HTML pages.',
187
+ e
188
+ )
189
+ profilingContextManager.set({ status: 'error', error_reason: 'missing-document-policy-header' })
190
+ } else {
191
+ profilingContextManager.set({ status: 'error', error_reason: 'unexpected-exception' })
192
+ }
193
+ return
194
+ }
195
+
196
+ profilingContextManager.set({ status: 'running', error_reason: undefined })
197
+
198
+ // Kick-off the new instance
199
+ instance = {
200
+ state: 'running',
201
+ startClocks: clocksNow(),
202
+ profiler,
203
+ timeoutId: setTimeout(startNextProfilerInstance, profilerConfiguration.collectIntervalMs),
204
+ views: [],
205
+ cleanupTasks,
206
+ longTasks: [],
207
+ }
208
+
209
+ // Add last view entry
210
+ collectViewEntry(lastViewEntry)
211
+
212
+ // Add event handler case we overflow the buffer
213
+ profiler.addEventListener('samplebufferfull', handleSampleBufferFull)
214
+ }
215
+
216
+ async function collectProfilerInstance(lastInstance: RumProfilerInstance) {
217
+ if (lastInstance.state !== 'running') {
218
+ return
219
+ }
220
+
221
+ // Cleanup instance
222
+ clearTimeout(lastInstance.timeoutId)
223
+ lastInstance.profiler.removeEventListener('samplebufferfull', handleSampleBufferFull)
224
+
225
+ // Store instance data snapshot in local variables to use in async callback
226
+ const { startClocks, views } = lastInstance
227
+
228
+ // Stop current profiler to get trace
229
+ await lastInstance.profiler
230
+ .stop()
231
+ .then((trace) => {
232
+ const endClocks = clocksNow()
233
+ const longTasks = longTaskContexts.findLongTasks(startClocks.relative)
234
+ const isBelowDurationThreshold =
235
+ elapsed(startClocks.timeStamp, endClocks.timeStamp) < profilerConfiguration.minProfileDurationMs
236
+ const isBelowSampleThreshold = getNumberOfSamples(trace.samples) < profilerConfiguration.minNumberOfSamples
237
+
238
+ if (longTasks.length === 0 && (isBelowDurationThreshold || isBelowSampleThreshold)) {
239
+ // Skip very short profiles to reduce noise and cost, but keep them if they contain long tasks.
240
+ return
241
+ }
242
+
243
+ handleProfilerTrace(
244
+ // Enrich trace with time and instance data
245
+ Object.assign(trace, {
246
+ startClocks,
247
+ endClocks,
248
+ clocksOrigin: clocksOrigin(),
249
+ longTasks,
250
+ views,
251
+ sampleInterval: profilerConfiguration.sampleIntervalMs,
252
+ })
253
+ )
254
+ })
255
+ .catch(monitorError)
256
+ }
257
+
258
+ async function stopProfilerInstance(stateReason: RumProfilerStoppedInstance['stateReason']) {
259
+ if (instance.state !== 'running') {
260
+ return
261
+ }
262
+ await onPauseOrStopProfilerInstance()
263
+ instance = { state: 'stopped', stateReason }
264
+ }
265
+
266
+ async function pauseProfilerInstance() {
267
+ if (instance.state !== 'running') {
268
+ return
269
+ }
270
+ await onPauseOrStopProfilerInstance()
271
+ instance = { state: 'paused' }
272
+ }
273
+
274
+ async function onPauseOrStopProfilerInstance() {
275
+ if (instance.state !== 'running') {
276
+ return
277
+ }
278
+ // Cleanup tasks
279
+ instance.cleanupTasks.forEach((cleanupTask) => cleanupTask())
280
+
281
+ await collectProfilerInstance(instance)
282
+ }
283
+
284
+ function collectViewEntry(viewEntry: RumViewEntry | undefined): void {
285
+ if (instance.state !== 'running' || !viewEntry) {
286
+ return
287
+ }
288
+
289
+ // Add entry to views
290
+ instance.views.push(viewEntry)
291
+ }
292
+
293
+ function handleProfilerTrace(trace: RumProfilerTrace): void {
294
+ // Find current session to assign it to the Profile.
295
+ const sessionId = session.findTrackedSession()?.id
296
+ const payload = assembleProfilingPayload(trace, configuration, sessionId)
297
+
298
+ void transport.send(payload as unknown as TransportPayload)
299
+ }
300
+
301
+ function handleSampleBufferFull(): void {
302
+ startNextProfilerInstance()
303
+ }
304
+
305
+ function handleVisibilityChange(): void {
306
+ if (document.visibilityState === 'hidden' && instance.state === 'running') {
307
+ // Pause when tab is hidden. We use paused state to distinguish between
308
+ // paused by visibility change and stopped by user.
309
+ // If profiler is paused by the visibility change, we should resume when
310
+ // tab becomes visible again. That's not the case when user stops the profiler.
311
+ pauseProfilerInstance().catch(monitorError)
312
+ } else if (document.visibilityState === 'visible' && instance.state === 'paused') {
313
+ // Resume when tab becomes visible again
314
+ startNextProfilerInstance()
315
+ }
316
+ }
317
+
318
+ function handleBeforeUnload(): void {
319
+ // `unload` can in some cases be triggered while the page is still active (link to a different protocol like mailto:).
320
+ // We can immediately flush (by starting a new profiler instance) to make sure we receive the data, and at the same time keep the profiler active.
321
+ // In case of the regular unload, the profiler will be shut down anyway.
322
+ startNextProfilerInstance()
323
+ }
324
+
325
+ function isStopped() {
326
+ return instance.state === 'stopped'
327
+ }
328
+
329
+ function isRunning() {
330
+ return instance.state === 'running'
331
+ }
332
+
333
+ function isPaused() {
334
+ return instance.state === 'paused'
335
+ }
336
+
337
+ return { start, stop, isStopped, isRunning, isPaused }
338
+ }
@@ -0,0 +1,34 @@
1
+ import { HookNames, SKIPPED } from '@kubesense/kubesense-browser-core'
2
+ import type { Hooks, ProfilingInternalContextSchema } from '@kubesense/kubesense-browser-rum-core'
3
+ import { RumEventType } from '@kubesense/kubesense-browser-rum-core'
4
+
5
+ export interface ProfilingContextManager {
6
+ set: (next: ProfilingInternalContextSchema) => void
7
+ get: () => ProfilingInternalContextSchema | undefined
8
+ }
9
+
10
+ export function startProfilingContext(hooks: Hooks): ProfilingContextManager {
11
+ let currentContext: ProfilingInternalContextSchema = {
12
+ status: 'starting',
13
+ }
14
+
15
+ hooks.register(HookNames.Assemble, ({ eventType }) => {
16
+ if (eventType !== RumEventType.VIEW && eventType !== RumEventType.LONG_TASK) {
17
+ return SKIPPED
18
+ }
19
+
20
+ return {
21
+ type: eventType,
22
+ _kubesense: {
23
+ profiling: currentContext,
24
+ },
25
+ }
26
+ })
27
+
28
+ return {
29
+ get: () => currentContext,
30
+ set: (newContext: ProfilingInternalContextSchema) => {
31
+ currentContext = newContext
32
+ },
33
+ }
34
+ }
@@ -0,0 +1,10 @@
1
+ import { getGlobalObject } from '@kubesense/kubesense-browser-core'
2
+ import type { Profiler } from './types'
3
+
4
+ export function isProfilingSupported(): boolean {
5
+ const globalThis = getGlobalObject()
6
+
7
+ // This API might be unavailable in some browsers
8
+ const globalThisProfiler: Profiler | undefined = (globalThis as any).Profiler
9
+ return globalThisProfiler !== undefined
10
+ }
@@ -0,0 +1,58 @@
1
+ import type { ProfilerTrace } from '../types'
2
+
3
+ const generateFiftyRandomSamples = () => {
4
+ const samples = []
5
+ for (let i = 0; i < 50; i++) {
6
+ samples.push({
7
+ timestamp: i,
8
+ stackId: i % 3,
9
+ })
10
+ }
11
+ return samples
12
+ }
13
+
14
+ // eslint-disable-next-line local-rules/disallow-side-effects
15
+ const randomSamples = generateFiftyRandomSamples()
16
+
17
+ export const mockedEmptyTrace: ProfilerTrace = {
18
+ resources: [],
19
+ frames: [],
20
+ stacks: [],
21
+ samples: [],
22
+ }
23
+
24
+ export const mockedTrace: ProfilerTrace = {
25
+ resources: ['resource1', 'resource2', 'resource3'],
26
+ frames: [
27
+ {
28
+ name: 'frame-0',
29
+ line: 1,
30
+ column: 1,
31
+ resourceId: 0,
32
+ },
33
+ {
34
+ name: 'frame-1',
35
+ line: 2,
36
+ column: 2,
37
+ resourceId: 1,
38
+ },
39
+ {
40
+ name: 'frame-2',
41
+ line: 3,
42
+ column: 3,
43
+ resourceId: 2,
44
+ },
45
+ ],
46
+ stacks: [
47
+ {
48
+ frameId: 0,
49
+ },
50
+ {
51
+ frameId: 1,
52
+ },
53
+ {
54
+ frameId: 2,
55
+ },
56
+ ],
57
+ samples: randomSamples,
58
+ }
@@ -0,0 +1,78 @@
1
+ import { buildTags, currentDrift } from '@kubesense/kubesense-browser-core'
2
+ import type { RumConfiguration } from '@kubesense/kubesense-browser-rum-core'
3
+ import type { RumProfilerTrace } from '../types'
4
+ import { buildProfileEventAttributes } from './buildProfileEventAttributes'
5
+ import type { ProfileEventAttributes } from './buildProfileEventAttributes'
6
+
7
+ export interface ProfileEvent extends ProfileEventAttributes {
8
+ attachments: string[]
9
+ start: string // ISO date
10
+ end: string // ISO date
11
+ family: 'chrome'
12
+ runtime: 'chrome'
13
+ format: 'json'
14
+ version: 4
15
+ tags_profiler: string
16
+ _kubesense: {
17
+ clock_drift: number
18
+ }
19
+ }
20
+
21
+ export interface ProfileEventPayload {
22
+ event: ProfileEvent
23
+ 'wall-time.json': RumProfilerTrace
24
+ }
25
+
26
+ export function assembleProfilingPayload(
27
+ profilerTrace: RumProfilerTrace,
28
+ configuration: RumConfiguration,
29
+ sessionId: string | undefined
30
+ ): ProfileEventPayload {
31
+ const event = buildProfileEvent(profilerTrace, configuration, sessionId)
32
+
33
+ return {
34
+ event,
35
+ 'wall-time.json': profilerTrace,
36
+ }
37
+ }
38
+
39
+ function buildProfileEvent(
40
+ profilerTrace: RumProfilerTrace,
41
+ configuration: RumConfiguration,
42
+ sessionId: string | undefined
43
+ ): ProfileEvent {
44
+ const tags = buildTags(configuration) // TODO: get that from the tagContext hook
45
+ const profileAttributes = buildProfileEventAttributes(profilerTrace, configuration.applicationId, sessionId)
46
+ const profileEventTags = buildProfileEventTags(tags)
47
+
48
+ const profileEvent: ProfileEvent = {
49
+ ...profileAttributes,
50
+ attachments: ['wall-time.json'],
51
+ start: new Date(profilerTrace.startClocks.timeStamp).toISOString(),
52
+ end: new Date(profilerTrace.endClocks.timeStamp).toISOString(),
53
+ family: 'chrome',
54
+ runtime: 'chrome',
55
+ format: 'json',
56
+ version: 4, // Ingestion event version (not the version application tag)
57
+ tags_profiler: profileEventTags.join(','),
58
+ _kubesense: {
59
+ clock_drift: currentDrift(),
60
+ },
61
+ }
62
+
63
+ return profileEvent
64
+ }
65
+
66
+ /**
67
+ * Builds tags for the Profile Event.
68
+ *
69
+ * @param tags - RUM tags
70
+ * @returns Combined tags for the Profile Event.
71
+ */
72
+ function buildProfileEventTags(tags: string[]): string[] {
73
+ // Tags already contains the common tags for all events. (service, env, version, etc.)
74
+ // Here we are adding some specific-to-profiling tags.
75
+ const profileEventTags = tags.concat(['language:javascript', 'runtime:chrome', 'family:chrome', 'host:browser'])
76
+
77
+ return profileEventTags
78
+ }
@@ -0,0 +1,66 @@
1
+ import type { RumProfilerTrace, RumViewEntry } from '../types'
2
+
3
+ export interface ProfileEventAttributes {
4
+ application: { id: string }
5
+ session?: { id: string }
6
+ view?: { id: string[]; name: string[] }
7
+ long_task?: { id: string[] }
8
+ }
9
+
10
+ /**
11
+ * Builds attributes for the Profile Event.
12
+ *
13
+ * @param profilerTrace - Profiler trace
14
+ * @param applicationId - application id.
15
+ * @param sessionId - session id.
16
+ * @returns Additional attributes.
17
+ */
18
+ export function buildProfileEventAttributes(
19
+ profilerTrace: RumProfilerTrace,
20
+ applicationId: string,
21
+ sessionId: string | undefined
22
+ ): ProfileEventAttributes {
23
+ const attributes: ProfileEventAttributes = {
24
+ application: {
25
+ id: applicationId,
26
+ },
27
+ }
28
+ if (sessionId) {
29
+ attributes.session = {
30
+ id: sessionId,
31
+ }
32
+ }
33
+
34
+ // Extract view ids and names from the profiler trace and add them as attributes of the profile event.
35
+ // This will be used to filter the profiles by @view.id and/or @view.name.
36
+ const { ids, names } = extractViewIdsAndNames(profilerTrace.views)
37
+
38
+ if (ids.length) {
39
+ attributes.view = {
40
+ id: ids,
41
+ name: names,
42
+ }
43
+ }
44
+ const longTaskIds: string[] = profilerTrace.longTasks.map((longTask) => longTask.id).filter((id) => id !== undefined)
45
+
46
+ if (longTaskIds.length) {
47
+ attributes.long_task = { id: longTaskIds }
48
+ }
49
+ return attributes
50
+ }
51
+
52
+ function extractViewIdsAndNames(views: RumViewEntry[]): { ids: string[]; names: string[] } {
53
+ const result: { ids: string[]; names: string[] } = { ids: [], names: [] }
54
+ for (const view of views) {
55
+ result.ids.push(view.viewId)
56
+
57
+ if (view.viewName) {
58
+ result.names.push(view.viewName)
59
+ }
60
+ }
61
+
62
+ // Remove duplicates
63
+ result.names = Array.from(new Set(result.names))
64
+
65
+ return result
66
+ }
@@ -0,0 +1,2 @@
1
+ export type * from './profilerApi.types'
2
+ export type * from './rumProfiler.types'
@@ -0,0 +1,87 @@
1
+ // Define types for the new Profiler API
2
+ // https://wicg.github.io/js-self-profiling/
3
+
4
+ export interface ProfilerFrame {
5
+ /** A function instance name. */
6
+ readonly name: string
7
+ /** Index in the trace.resources array. */
8
+ readonly resourceId?: number
9
+ /** 1-based index of the line. */
10
+ readonly line?: number
11
+ /** 1-based index of the column. */
12
+ readonly column?: number
13
+ }
14
+
15
+ export interface ProfilerStack {
16
+ /** Index in the trace.stacks array. */
17
+ readonly parentId?: number
18
+ /** Index in the trace.frames array. */
19
+ readonly frameId: number
20
+ }
21
+
22
+ export interface ProfilerSample {
23
+ /** High resolution time relative to the profiling session's time origin. */
24
+ readonly timestamp: number
25
+ /** Index in the trace.stacks array. */
26
+ readonly stackId?: number
27
+ }
28
+
29
+ export type ProfilerResource = string
30
+
31
+ export interface ProfilerTrace {
32
+ /** An array of profiler resources. */
33
+ readonly resources: ProfilerResource[]
34
+ /** An array of profiler frames. */
35
+ readonly frames: ProfilerFrame[]
36
+ /** An array of profiler stacks. */
37
+ readonly stacks: ProfilerStack[]
38
+ /** An array of profiler samples. */
39
+ readonly samples: ProfilerSample[]
40
+ }
41
+
42
+ export interface ProfilerInitOptions {
43
+ /** Sample interval in ms. */
44
+ readonly sampleInterval: number
45
+ /** Max buffer size in number of samples. */
46
+ readonly maxBufferSize: number
47
+ }
48
+
49
+ export interface Profiler extends EventTarget {
50
+ /** Sample interval in ms. */
51
+ readonly sampleInterval: number
52
+ /** True if profiler is stopped. */
53
+ readonly stopped: boolean
54
+
55
+ // eslint-disable-next-line @typescript-eslint/no-misused-new
56
+ new (options: ProfilerInitOptions): Profiler
57
+ stop(): Promise<ProfilerTrace>
58
+
59
+ addEventListener<K extends keyof ProfilerEventMap>(
60
+ type: K,
61
+ listener: (this: typeof globalThis, ev: ProfilerEventMap[K]) => any,
62
+ options?: boolean | AddEventListenerOptions
63
+ ): void
64
+ addEventListener(
65
+ type: string,
66
+ listener: EventListenerOrEventListenerObject,
67
+ options?: boolean | AddEventListenerOptions
68
+ ): void
69
+ removeEventListener<K extends keyof ProfilerEventMap>(
70
+ type: K,
71
+ listener: (this: typeof globalThis, ev: ProfilerEventMap[K]) => any,
72
+ options?: boolean | EventListenerOptions
73
+ ): void
74
+ removeEventListener(
75
+ type: string,
76
+ listener: EventListenerOrEventListenerObject,
77
+ options?: boolean | EventListenerOptions
78
+ ): void
79
+ }
80
+
81
+ interface ProfilerEventMap {
82
+ samplebufferfull: SampleBufferFullEvent
83
+ }
84
+
85
+ export interface SampleBufferFullEvent extends Event {
86
+ readonly target: Profiler
87
+ }