@safaricom-mxl/web-sdk 0.0.14 → 0.0.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (266) hide show
  1. package/dist/api-logs/api/LogAPI/LogAPI.cjs.map +1 -1
  2. package/dist/api-logs/api/LogAPI/LogAPI.js.map +1 -1
  3. package/dist/api-logs/logAPI.cjs.map +1 -1
  4. package/dist/api-logs/logAPI.js.map +1 -1
  5. package/dist/api-logs/manager/NoOpLogManager/NoOpLogManager.cjs.map +1 -1
  6. package/dist/api-logs/manager/NoOpLogManager/NoOpLogManager.js.map +1 -1
  7. package/dist/api-logs/manager/ProxyLogManager/ProxyLogManager.cjs.map +1 -1
  8. package/dist/api-logs/manager/ProxyLogManager/ProxyLogManager.js.map +1 -1
  9. package/dist/api-page/api/PageAPI/PageAPI.cjs.map +1 -1
  10. package/dist/api-page/api/PageAPI/PageAPI.js.map +1 -1
  11. package/dist/api-page/manager/NoOpPageManager/NoOpPageManager.cjs.map +1 -1
  12. package/dist/api-page/manager/NoOpPageManager/NoOpPageManager.js.map +1 -1
  13. package/dist/api-page/manager/ProxyPageManager/ProxyPageManager.cjs.map +1 -1
  14. package/dist/api-page/manager/ProxyPageManager/ProxyPageManager.js.map +1 -1
  15. package/dist/api-page/pageAPI.cjs.map +1 -1
  16. package/dist/api-page/pageAPI.js.map +1 -1
  17. package/dist/api-sessions/api/SessionAPI/SessionAPI.cjs.map +1 -1
  18. package/dist/api-sessions/api/SessionAPI/SessionAPI.d.cts.map +1 -1
  19. package/dist/api-sessions/api/SessionAPI/SessionAPI.d.ts.map +1 -1
  20. package/dist/api-sessions/api/SessionAPI/SessionAPI.js.map +1 -1
  21. package/dist/api-sessions/manager/NoOpSpanSessionManager/NoOpSpanSessionManager.cjs.map +1 -1
  22. package/dist/api-sessions/manager/NoOpSpanSessionManager/NoOpSpanSessionManager.js.map +1 -1
  23. package/dist/api-sessions/manager/ProxySpanSessionManager/ProxySpanSessionManager.cjs.map +1 -1
  24. package/dist/api-sessions/manager/ProxySpanSessionManager/ProxySpanSessionManager.js.map +1 -1
  25. package/dist/api-sessions/sessionAPI.cjs.map +1 -1
  26. package/dist/api-sessions/sessionAPI.js.map +1 -1
  27. package/dist/api-traces/api/TraceAPI/TraceAPI.cjs.map +1 -1
  28. package/dist/api-traces/api/TraceAPI/TraceAPI.js.map +1 -1
  29. package/dist/api-traces/manager/NoOpTraceManager/NoOpTraceManager.cjs.map +1 -1
  30. package/dist/api-traces/manager/NoOpTraceManager/NoOpTraceManager.js.map +1 -1
  31. package/dist/api-traces/manager/NoOpTraceManager/NonRecordingExtendedSpan.cjs.map +1 -1
  32. package/dist/api-traces/manager/NoOpTraceManager/NonRecordingExtendedSpan.d.cts.map +1 -1
  33. package/dist/api-traces/manager/NoOpTraceManager/NonRecordingExtendedSpan.d.ts.map +1 -1
  34. package/dist/api-traces/manager/NoOpTraceManager/NonRecordingExtendedSpan.js.map +1 -1
  35. package/dist/api-traces/manager/ProxyTraceManager/ProxyTraceManager.cjs.map +1 -1
  36. package/dist/api-traces/manager/ProxyTraceManager/ProxyTraceManager.js.map +1 -1
  37. package/dist/api-traces/traceAPI.cjs.map +1 -1
  38. package/dist/api-traces/traceAPI.js.map +1 -1
  39. package/dist/api-users/api/UserAPI/UserAPI.cjs.map +1 -1
  40. package/dist/api-users/api/UserAPI/UserAPI.js.map +1 -1
  41. package/dist/api-users/manager/NoOpUserManager/NoOpUserManager.cjs.map +1 -1
  42. package/dist/api-users/manager/NoOpUserManager/NoOpUserManager.js.map +1 -1
  43. package/dist/api-users/manager/ProxyUserManager/ProxyUserManager.cjs.map +1 -1
  44. package/dist/api-users/manager/ProxyUserManager/ProxyUserManager.js.map +1 -1
  45. package/dist/api-users/userAPI.cjs.map +1 -1
  46. package/dist/api-users/userAPI.js.map +1 -1
  47. package/dist/common/attributes.cjs.map +1 -1
  48. package/dist/common/attributes.js.map +1 -1
  49. package/dist/constants/attributes.cjs +2 -0
  50. package/dist/constants/attributes.cjs.map +1 -1
  51. package/dist/constants/attributes.d.cts +2 -1
  52. package/dist/constants/attributes.d.cts.map +1 -1
  53. package/dist/constants/attributes.d.ts +2 -1
  54. package/dist/constants/attributes.d.ts.map +1 -1
  55. package/dist/constants/attributes.js +2 -1
  56. package/dist/constants/attributes.js.map +1 -1
  57. package/dist/constants/index.cjs +1 -0
  58. package/dist/constants/index.d.cts +2 -2
  59. package/dist/constants/index.d.ts +2 -2
  60. package/dist/constants/index.js +2 -2
  61. package/dist/exporters/MXLLogExporter/MXLLogExporter.cjs.map +1 -1
  62. package/dist/exporters/MXLLogExporter/MXLLogExporter.js.map +1 -1
  63. package/dist/exporters/MXLLogExporter/OTLPFetchLogExporter.cjs.map +1 -1
  64. package/dist/exporters/MXLLogExporter/OTLPFetchLogExporter.js.map +1 -1
  65. package/dist/exporters/MXLLogExporter/utils.cjs.map +1 -1
  66. package/dist/exporters/MXLLogExporter/utils.js.map +1 -1
  67. package/dist/exporters/MXLTraceExporter/MXLTraceExporter.cjs.map +1 -1
  68. package/dist/exporters/MXLTraceExporter/MXLTraceExporter.js.map +1 -1
  69. package/dist/exporters/MXLTraceExporter/OTLPFetchTraceExporter.cjs.map +1 -1
  70. package/dist/exporters/MXLTraceExporter/OTLPFetchTraceExporter.js.map +1 -1
  71. package/dist/exporters/MXLTraceExporter/utils.cjs.map +1 -1
  72. package/dist/exporters/MXLTraceExporter/utils.js.map +1 -1
  73. package/dist/exporters/otlpBrowserFetchExportDelegate.cjs.map +1 -1
  74. package/dist/exporters/otlpBrowserFetchExportDelegate.d.cts.map +1 -1
  75. package/dist/exporters/otlpBrowserFetchExportDelegate.d.ts.map +1 -1
  76. package/dist/exporters/otlpBrowserFetchExportDelegate.js.map +1 -1
  77. package/dist/instrumentations/MXLInstrumentationBase/MXLInstrumentationBase.cjs.map +1 -1
  78. package/dist/instrumentations/MXLInstrumentationBase/MXLInstrumentationBase.js.map +1 -1
  79. package/dist/instrumentations/clicks/ClicksInstrumentation/ClicksInstrumentation.cjs.map +1 -1
  80. package/dist/instrumentations/clicks/ClicksInstrumentation/ClicksInstrumentation.js.map +1 -1
  81. package/dist/instrumentations/document-load/DocumentLoadInstrumentation/DocumentLoadInstrumentation.cjs.map +1 -1
  82. package/dist/instrumentations/document-load/DocumentLoadInstrumentation/DocumentLoadInstrumentation.d.cts.map +1 -1
  83. package/dist/instrumentations/document-load/DocumentLoadInstrumentation/DocumentLoadInstrumentation.d.ts.map +1 -1
  84. package/dist/instrumentations/document-load/DocumentLoadInstrumentation/DocumentLoadInstrumentation.js.map +1 -1
  85. package/dist/instrumentations/document-load/DocumentLoadInstrumentation/utils.cjs.map +1 -1
  86. package/dist/instrumentations/document-load/DocumentLoadInstrumentation/utils.js.map +1 -1
  87. package/dist/instrumentations/element-timing/ElementTimingInstrumentation/ElementTimingInstrumentation.cjs.map +1 -1
  88. package/dist/instrumentations/element-timing/ElementTimingInstrumentation/ElementTimingInstrumentation.js.map +1 -1
  89. package/dist/instrumentations/empty-root/EmptyRootInstrumentation/EmptyRootInstrumentation.cjs.map +1 -1
  90. package/dist/instrumentations/empty-root/EmptyRootInstrumentation/EmptyRootInstrumentation.js.map +1 -1
  91. package/dist/instrumentations/exceptions/GlobalExceptionInstrumentation/GlobalExceptionInstrumentation.cjs.map +1 -1
  92. package/dist/instrumentations/exceptions/GlobalExceptionInstrumentation/GlobalExceptionInstrumentation.js.map +1 -1
  93. package/dist/instrumentations/exceptions/react/MXLErrorBoundary/MXLErrorBoundary.cjs +1 -1
  94. package/dist/instrumentations/exceptions/react/MXLErrorBoundary/MXLErrorBoundary.cjs.map +1 -1
  95. package/dist/instrumentations/exceptions/react/MXLErrorBoundary/MXLErrorBoundary.d.cts.map +1 -1
  96. package/dist/instrumentations/exceptions/react/MXLErrorBoundary/MXLErrorBoundary.d.ts.map +1 -1
  97. package/dist/instrumentations/exceptions/react/MXLErrorBoundary/MXLErrorBoundary.js +2 -2
  98. package/dist/instrumentations/exceptions/react/MXLErrorBoundary/MXLErrorBoundary.js.map +1 -1
  99. package/dist/instrumentations/fetch/MXLFetchInstrumentation/MXLFetchInstrumentation.cjs.map +1 -1
  100. package/dist/instrumentations/fetch/MXLFetchInstrumentation/MXLFetchInstrumentation.js.map +1 -1
  101. package/dist/instrumentations/loaf/LoafInstrumentation/LoafInstrumentation.cjs.map +1 -1
  102. package/dist/instrumentations/loaf/LoafInstrumentation/LoafInstrumentation.js.map +1 -1
  103. package/dist/instrumentations/navigation/NavigationInstrumentation/NavigationInstrumentation.cjs.map +1 -1
  104. package/dist/instrumentations/navigation/NavigationInstrumentation/NavigationInstrumentation.js.map +1 -1
  105. package/dist/instrumentations/navigation/NavigationInstrumentation/instance.cjs.map +1 -1
  106. package/dist/instrumentations/navigation/NavigationInstrumentation/instance.js.map +1 -1
  107. package/dist/instrumentations/navigation/NavigationInstrumentation/react/createReactRouterNavigationInstrumentation.cjs.map +1 -1
  108. package/dist/instrumentations/navigation/NavigationInstrumentation/react/createReactRouterNavigationInstrumentation.js.map +1 -1
  109. package/dist/instrumentations/navigation/NavigationInstrumentation/react/reactRouterV5/withMXLRoutingLegacy.cjs.map +1 -1
  110. package/dist/instrumentations/navigation/NavigationInstrumentation/react/reactRouterV5/withMXLRoutingLegacy.d.cts.map +1 -1
  111. package/dist/instrumentations/navigation/NavigationInstrumentation/react/reactRouterV5/withMXLRoutingLegacy.d.ts.map +1 -1
  112. package/dist/instrumentations/navigation/NavigationInstrumentation/react/reactRouterV5/withMXLRoutingLegacy.js.map +1 -1
  113. package/dist/instrumentations/navigation/NavigationInstrumentation/react/reactRouterV6Data/listenToRouterChanges.cjs.map +1 -1
  114. package/dist/instrumentations/navigation/NavigationInstrumentation/react/reactRouterV6Data/listenToRouterChanges.js.map +1 -1
  115. package/dist/instrumentations/navigation/NavigationInstrumentation/react/reactRouterV6Declarative/withMXLRouting.cjs.map +1 -1
  116. package/dist/instrumentations/navigation/NavigationInstrumentation/react/reactRouterV6Declarative/withMXLRouting.js.map +1 -1
  117. package/dist/instrumentations/server-timing/ServerTimingInstrumentation/ServerTimingInstrumentation.cjs.map +1 -1
  118. package/dist/instrumentations/server-timing/ServerTimingInstrumentation/ServerTimingInstrumentation.js.map +1 -1
  119. package/dist/instrumentations/session/SpanSessionBrowserActivityInstrumentation/SpanSessionBrowserActivityInstrumentation.cjs.map +1 -1
  120. package/dist/instrumentations/session/SpanSessionBrowserActivityInstrumentation/SpanSessionBrowserActivityInstrumentation.js.map +1 -1
  121. package/dist/instrumentations/session/SpanSessionOnLoadInstrumentation/SpanSessionOnLoadInstrumentation.cjs.map +1 -1
  122. package/dist/instrumentations/session/SpanSessionOnLoadInstrumentation/SpanSessionOnLoadInstrumentation.js.map +1 -1
  123. package/dist/instrumentations/session/SpanSessionTimeoutInstrumentation/SpanSessionTimeoutInstrumentation.cjs.map +1 -1
  124. package/dist/instrumentations/session/SpanSessionTimeoutInstrumentation/SpanSessionTimeoutInstrumentation.js.map +1 -1
  125. package/dist/instrumentations/session/SpanSessionVisibilityInstrumentation/SpanSessionVisibilityInstrumentation.cjs.map +1 -1
  126. package/dist/instrumentations/session/SpanSessionVisibilityInstrumentation/SpanSessionVisibilityInstrumentation.js.map +1 -1
  127. package/dist/instrumentations/user-timing/UserTimingInstrumentation/UserTimingInstrumentation.cjs.map +1 -1
  128. package/dist/instrumentations/user-timing/UserTimingInstrumentation/UserTimingInstrumentation.js.map +1 -1
  129. package/dist/instrumentations/web-vitals/WebVitalsInstrumentation/WebVitalsInstrumentation.cjs.map +1 -1
  130. package/dist/instrumentations/web-vitals/WebVitalsInstrumentation/WebVitalsInstrumentation.d.cts.map +1 -1
  131. package/dist/instrumentations/web-vitals/WebVitalsInstrumentation/WebVitalsInstrumentation.d.ts.map +1 -1
  132. package/dist/instrumentations/web-vitals/WebVitalsInstrumentation/WebVitalsInstrumentation.js.map +1 -1
  133. package/dist/instrumentations/xhr/MXLXHRInstrumentation/MXLXHRInstrumentation.cjs.map +1 -1
  134. package/dist/instrumentations/xhr/MXLXHRInstrumentation/MXLXHRInstrumentation.js.map +1 -1
  135. package/dist/managers/MXLConfigManager/MXLDynamicConfigManager.cjs +1 -1
  136. package/dist/managers/MXLConfigManager/MXLDynamicConfigManager.cjs.map +1 -1
  137. package/dist/managers/MXLConfigManager/MXLDynamicConfigManager.d.cts.map +1 -1
  138. package/dist/managers/MXLConfigManager/MXLDynamicConfigManager.d.ts.map +1 -1
  139. package/dist/managers/MXLConfigManager/MXLDynamicConfigManager.js +1 -1
  140. package/dist/managers/MXLConfigManager/MXLDynamicConfigManager.js.map +1 -1
  141. package/dist/managers/MXLConfigManager/constants.cjs.map +1 -1
  142. package/dist/managers/MXLConfigManager/constants.js.map +1 -1
  143. package/dist/managers/MXLConfigManager/utils.cjs.map +1 -1
  144. package/dist/managers/MXLConfigManager/utils.js.map +1 -1
  145. package/dist/managers/MXLLimitManager/MXLLimitManager.cjs.map +1 -1
  146. package/dist/managers/MXLLimitManager/MXLLimitManager.js.map +1 -1
  147. package/dist/managers/MXLLimitManager/constants.cjs.map +1 -1
  148. package/dist/managers/MXLLimitManager/constants.js.map +1 -1
  149. package/dist/managers/MXLLogManager/MXLLogManager.cjs +3 -1
  150. package/dist/managers/MXLLogManager/MXLLogManager.cjs.map +1 -1
  151. package/dist/managers/MXLLogManager/MXLLogManager.d.cts.map +1 -1
  152. package/dist/managers/MXLLogManager/MXLLogManager.d.ts.map +1 -1
  153. package/dist/managers/MXLLogManager/MXLLogManager.js +4 -2
  154. package/dist/managers/MXLLogManager/MXLLogManager.js.map +1 -1
  155. package/dist/managers/MXLPageManager/MXLPageManager.cjs.map +1 -1
  156. package/dist/managers/MXLPageManager/MXLPageManager.js.map +1 -1
  157. package/dist/managers/MXLSDKFeaturesManager/MXLSDKFeaturesManager.cjs.map +1 -1
  158. package/dist/managers/MXLSDKFeaturesManager/MXLSDKFeaturesManager.js.map +1 -1
  159. package/dist/managers/MXLSpanSessionManager/MXLSpanSessionManager.cjs.map +1 -1
  160. package/dist/managers/MXLSpanSessionManager/MXLSpanSessionManager.d.cts.map +1 -1
  161. package/dist/managers/MXLSpanSessionManager/MXLSpanSessionManager.d.ts.map +1 -1
  162. package/dist/managers/MXLSpanSessionManager/MXLSpanSessionManager.js.map +1 -1
  163. package/dist/managers/MXLTraceManager/MXLExtendedSpan.cjs.map +1 -1
  164. package/dist/managers/MXLTraceManager/MXLExtendedSpan.d.cts.map +1 -1
  165. package/dist/managers/MXLTraceManager/MXLExtendedSpan.d.ts.map +1 -1
  166. package/dist/managers/MXLTraceManager/MXLExtendedSpan.js.map +1 -1
  167. package/dist/managers/MXLTraceManager/MXLTraceManager.cjs.map +1 -1
  168. package/dist/managers/MXLTraceManager/MXLTraceManager.js.map +1 -1
  169. package/dist/managers/MXLUserManager/MXLUserManager.cjs.map +1 -1
  170. package/dist/managers/MXLUserManager/MXLUserManager.js.map +1 -1
  171. package/dist/managers/MXLUserManager/types.cjs.map +1 -1
  172. package/dist/managers/MXLUserManager/types.js.map +1 -1
  173. package/dist/mxl-web-sdk.js +3 -38
  174. package/dist/mxl-web-sdk.js.map +1 -1
  175. package/dist/processors/BrowserLogRecordProcessor/BrowserLogRecordProcessor.cjs.map +1 -1
  176. package/dist/processors/BrowserLogRecordProcessor/BrowserLogRecordProcessor.js.map +1 -1
  177. package/dist/processors/BrowserSpanProcessor/BrowserSpanProcessor.cjs.map +1 -1
  178. package/dist/processors/BrowserSpanProcessor/BrowserSpanProcessor.js.map +1 -1
  179. package/dist/processors/IdentifiableSessionLogRecordProcessor/IdentifiableSessionLogRecordProcessor.cjs.map +1 -1
  180. package/dist/processors/IdentifiableSessionLogRecordProcessor/IdentifiableSessionLogRecordProcessor.js.map +1 -1
  181. package/dist/processors/LogRecordScrubProcessor/LogRecordScrubProcessor.cjs.map +1 -1
  182. package/dist/processors/LogRecordScrubProcessor/LogRecordScrubProcessor.js.map +1 -1
  183. package/dist/processors/MXLLogRecordProcessor/MXLLogRecordProcessor.cjs.map +1 -1
  184. package/dist/processors/MXLLogRecordProcessor/MXLLogRecordProcessor.js.map +1 -1
  185. package/dist/processors/MXLNetworkSpanProcessor/MXLNetworkSpanProcessor.cjs.map +1 -1
  186. package/dist/processors/MXLNetworkSpanProcessor/MXLNetworkSpanProcessor.js.map +1 -1
  187. package/dist/processors/MXLSessionBatchedSpanProcessor/MXLSessionBatchedSpanProcessor.cjs.map +1 -1
  188. package/dist/processors/MXLSessionBatchedSpanProcessor/MXLSessionBatchedSpanProcessor.js.map +1 -1
  189. package/dist/processors/PageLogRecordProcessor/PageLogRecordProcessor.cjs.map +1 -1
  190. package/dist/processors/PageLogRecordProcessor/PageLogRecordProcessor.js.map +1 -1
  191. package/dist/processors/PageSpanProcessor/PageSpanProcessor.cjs.map +1 -1
  192. package/dist/processors/PageSpanProcessor/PageSpanProcessor.js.map +1 -1
  193. package/dist/processors/SpanScrubProcessor/SpanScrubProcessor.cjs.map +1 -1
  194. package/dist/processors/SpanScrubProcessor/SpanScrubProcessor.js.map +1 -1
  195. package/dist/processors/UserLogRecordProcessor/UserLogRecordProcessor.cjs.map +1 -1
  196. package/dist/processors/UserLogRecordProcessor/UserLogRecordProcessor.js.map +1 -1
  197. package/dist/processors/UserSpanProcessor/UserSpanProcessor.cjs.map +1 -1
  198. package/dist/processors/UserSpanProcessor/UserSpanProcessor.js.map +1 -1
  199. package/dist/propagators/MXLW3CTraceContextPropagator/MXLW3CTraceContextPropagator.cjs.map +1 -1
  200. package/dist/propagators/MXLW3CTraceContextPropagator/MXLW3CTraceContextPropagator.js.map +1 -1
  201. package/dist/resources/appInstanceId.cjs.map +1 -1
  202. package/dist/resources/appInstanceId.js.map +1 -1
  203. package/dist/resources/constants/index.cjs +1 -1
  204. package/dist/resources/constants/index.cjs.map +1 -1
  205. package/dist/resources/constants/index.d.cts +1 -1
  206. package/dist/resources/constants/index.d.ts +1 -1
  207. package/dist/resources/constants/index.js +1 -1
  208. package/dist/resources/constants/index.js.map +1 -1
  209. package/dist/resources/webSdkResource.cjs.map +1 -1
  210. package/dist/resources/webSdkResource.d.cts.map +1 -1
  211. package/dist/resources/webSdkResource.d.ts.map +1 -1
  212. package/dist/resources/webSdkResource.js.map +1 -1
  213. package/dist/sdk/defaultAttributeScrubbers.cjs.map +1 -1
  214. package/dist/sdk/defaultAttributeScrubbers.js.map +1 -1
  215. package/dist/sdk/initSDK.cjs +13 -11
  216. package/dist/sdk/initSDK.cjs.map +1 -1
  217. package/dist/sdk/initSDK.d.cts.map +1 -1
  218. package/dist/sdk/initSDK.d.ts.map +1 -1
  219. package/dist/sdk/initSDK.js +14 -12
  220. package/dist/sdk/initSDK.js.map +1 -1
  221. package/dist/sdk/noopSessionRecording.cjs +10 -0
  222. package/dist/sdk/noopSessionRecording.cjs.map +1 -0
  223. package/dist/sdk/noopSessionRecording.d.cts +7 -0
  224. package/dist/sdk/noopSessionRecording.d.cts.map +1 -0
  225. package/dist/sdk/noopSessionRecording.d.ts +7 -0
  226. package/dist/sdk/noopSessionRecording.d.ts.map +1 -0
  227. package/dist/sdk/noopSessionRecording.js +9 -0
  228. package/dist/sdk/noopSessionRecording.js.map +1 -0
  229. package/dist/sdk/registry.cjs.map +1 -1
  230. package/dist/sdk/registry.js.map +1 -1
  231. package/dist/sdk/setupDefaultInstrumentations.cjs.map +1 -1
  232. package/dist/sdk/setupDefaultInstrumentations.js.map +1 -1
  233. package/dist/sdk/setupSessionRecorder.cjs +64 -22
  234. package/dist/sdk/setupSessionRecorder.cjs.map +1 -1
  235. package/dist/sdk/setupSessionRecorder.d.cts +16 -7
  236. package/dist/sdk/setupSessionRecorder.d.cts.map +1 -1
  237. package/dist/sdk/setupSessionRecorder.d.ts +16 -7
  238. package/dist/sdk/setupSessionRecorder.d.ts.map +1 -1
  239. package/dist/sdk/setupSessionRecorder.js +62 -21
  240. package/dist/sdk/setupSessionRecorder.js.map +1 -1
  241. package/dist/sdk/types.d.cts.map +1 -1
  242. package/dist/sdk/types.d.ts +1 -1
  243. package/dist/sdk/types.d.ts.map +1 -1
  244. package/dist/sdk/utils.cjs.map +1 -1
  245. package/dist/sdk/utils.js.map +1 -1
  246. package/dist/transport/FetchTransport/FetchTransport.cjs.map +1 -1
  247. package/dist/transport/FetchTransport/FetchTransport.js.map +1 -1
  248. package/dist/transport/FetchTransport/createFetchTransport.cjs.map +1 -1
  249. package/dist/transport/FetchTransport/createFetchTransport.js.map +1 -1
  250. package/dist/transport/RetryingTransport/RetryingTransport.cjs.map +1 -1
  251. package/dist/transport/RetryingTransport/RetryingTransport.js.map +1 -1
  252. package/dist/transport/RetryingTransport/createRetryingTransport.cjs.map +1 -1
  253. package/dist/transport/RetryingTransport/createRetryingTransport.js.map +1 -1
  254. package/dist/utils/MXLSpanStorage/MXLSpanStorage.cjs.map +1 -1
  255. package/dist/utils/MXLSpanStorage/MXLSpanStorage.js.map +1 -1
  256. package/dist/utils/PerformanceManager/OTelPerformanceManager.cjs.map +1 -1
  257. package/dist/utils/PerformanceManager/OTelPerformanceManager.js.map +1 -1
  258. package/dist/utils/bulkAddEventListener/bulkAddEventListener.cjs.map +1 -1
  259. package/dist/utils/bulkAddEventListener/bulkAddEventListener.js.map +1 -1
  260. package/dist/utils/bulkRemoveEventListener/bulkRemoveEventListener.cjs.map +1 -1
  261. package/dist/utils/bulkRemoveEventListener/bulkRemoveEventListener.js.map +1 -1
  262. package/dist/utils/getVisibilityState.cjs.map +1 -1
  263. package/dist/utils/getVisibilityState.js.map +1 -1
  264. package/dist/utils/nsfConfigValidation.cjs.map +1 -1
  265. package/dist/utils/nsfConfigValidation.js.map +1 -1
  266. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"WebVitalsInstrumentation.js","names":[],"sources":["../../../../src/instrumentations/web-vitals/WebVitalsInstrumentation/WebVitalsInstrumentation.ts"],"sourcesContent":["import type {\n Attributes,\n AttributeValue,\n DiagLogger,\n} from '@opentelemetry/api';\nimport { ATTR_URL_FULL } from '@opentelemetry/semantic-conventions';\nimport type {\n CLSMetricWithAttribution,\n INPAttribution,\n Metric,\n MetricWithAttribution,\n TTFBAttribution,\n} from 'web-vitals/attribution';\nimport type { PageManager } from '../../../api-page/index.ts';\nimport { page } from '../../../api-page/index.ts';\nimport type { URLDocument } from '../../../common/index.ts';\nimport {\n MXL_TYPES,\n KEY_APP_SURFACE_LABEL,\n KEY_BROWSER_URL_FULL,\n KEY_MXL_PAGE_ID,\n KEY_MXL_PAGE_PATH,\n KEY_MXL_TYPE,\n} from '../../../constants/index.ts';\nimport { MXLInstrumentationBase } from '../../MXLInstrumentationBase/index.ts';\nimport {\n KEY_MXL_WEB_VITAL_ATTRIBUTION_PREFIX,\n KEY_MXL_WEB_VITAL_DELTA,\n KEY_MXL_WEB_VITAL_ID,\n KEY_MXL_WEB_VITAL_NAME,\n KEY_MXL_WEB_VITAL_NAVIGATION_TYPE,\n KEY_MXL_WEB_VITAL_RATING,\n KEY_MXL_WEB_VITAL_VALUE,\n} from './attributes.ts';\nimport {\n ALL_WEB_VITALS,\n MXL_WEB_VITALS_PREFIX,\n MAX_LOAF_SCRIPT_ENTRIES,\n MAX_LOAF_SCRIPT_URL_LENGTH,\n WEB_VITALS_ID_TO_LISTENER,\n} from './constants.ts';\nimport type {\n WebVitalListeners,\n WebVitalsInstrumentationArgs,\n} from './types.ts';\n\ntype AttributedPage = {\n fullURL: string;\n path?: string;\n pageID?: string;\n label?: string;\n};\n\nconst isPrimitiveValue = (value: unknown): value is AttributeValue => {\n const type = typeof value;\n return type === 'number' || type === 'string' || type === 'boolean';\n};\n\nconst roundClamp = (value: number): number => Math.round(Math.max(0, value));\n\nconst webVitalAttributionToReport = (\n metric: MetricWithAttribution,\n): Attributes => {\n const attributes: Attributes = {};\n const attribution = metric.attribution;\n\n if (!attribution || typeof attribution !== 'object') {\n return attributes;\n }\n\n for (const [key, value] of Object.entries(attribution)) {\n if (isPrimitiveValue(value)) {\n attributes[`${KEY_MXL_WEB_VITAL_ATTRIBUTION_PREFIX}${key}`] = value;\n }\n }\n\n return attributes;\n};\n\nconst loafScriptsAttribution = (\n metric: MetricWithAttribution,\n diag: DiagLogger,\n): Attributes => {\n const attributes: Attributes = {};\n const attribution = metric.attribution as INPAttribution;\n\n try {\n // suppress LoAF baseline errors\n /* eslint-disable baseline-js/use-baseline */\n if (attribution.longAnimationFrameEntries.length > 0) {\n const scripts = new Map<\n string,\n {\n totalDuration: number;\n styleAndLayoutDuration: number;\n count: number;\n }\n >();\n for (const entry of attribution.longAnimationFrameEntries) {\n for (const script of entry.scripts) {\n let url = script.sourceURL || '(inline)';\n if (url.length > MAX_LOAF_SCRIPT_URL_LENGTH) {\n url = `${url.substring(0, MAX_LOAF_SCRIPT_URL_LENGTH)}...`;\n }\n const existing = scripts.get(url);\n if (existing) {\n existing.totalDuration += script.duration;\n existing.styleAndLayoutDuration +=\n script.forcedStyleAndLayoutDuration;\n existing.count++;\n } else {\n scripts.set(url, {\n totalDuration: script.duration,\n styleAndLayoutDuration: script.forcedStyleAndLayoutDuration,\n count: 1,\n });\n }\n }\n }\n if (scripts.size > 0) {\n attributes[`${KEY_MXL_WEB_VITAL_ATTRIBUTION_PREFIX}loaf_scripts`] =\n JSON.stringify(\n Object.fromEntries(\n [...scripts]\n .sort((a, b) => b[1].totalDuration - a[1].totalDuration)\n .slice(0, MAX_LOAF_SCRIPT_ENTRIES)\n .map(([url, script]) => [\n url,\n {\n total_duration: Math.round(script.totalDuration),\n style_and_layout_duration: Math.round(\n script.styleAndLayoutDuration,\n ),\n count: script.count,\n },\n ]),\n ),\n );\n }\n }\n /* eslint-enable baseline-js/use-baseline */\n } catch (e) {\n diag.error('error building loaf scripts for INP', e);\n }\n\n return attributes;\n};\n\nconst ttfbSubPartsAttribution = (\n metric: MetricWithAttribution,\n diag: DiagLogger,\n): Attributes => {\n const attributes: Attributes = {};\n const attribution = metric.attribution as TTFBAttribution;\n const entry = attribution.navigationEntry as\n | PerformanceNavigationTiming\n | undefined;\n\n if (entry) {\n try {\n const redirect = roundClamp(entry.redirectEnd - entry.redirectStart);\n const domainLookup = roundClamp(\n entry.domainLookupEnd - entry.domainLookupStart,\n );\n const tcpConnection = roundClamp(\n entry.secureConnectionStart > 0\n ? entry.secureConnectionStart - entry.connectStart\n : entry.connectEnd - entry.connectStart,\n );\n const tlsNegotiation = roundClamp(\n entry.secureConnectionStart > 0\n ? entry.connectEnd - entry.secureConnectionStart\n : 0,\n );\n const effectiveResponseStart = Math.max(\n // @ts-expect-error 103 Early hints are not supported in all browsers\n // https://developer.mozilla.org/en-US/docs/Web/API/PerformanceResourceTiming/finalResponseHeadersStart\n entry.finalResponseHeadersStart ?? 0,\n entry.responseStart,\n );\n const serverResponse = roundClamp(\n effectiveResponseStart - entry.requestStart,\n );\n const total = Math.round(entry.responseEnd - entry.startTime);\n const unattributed = roundClamp(\n total -\n redirect -\n domainLookup -\n tcpConnection -\n tlsNegotiation -\n serverResponse,\n );\n const prefix = KEY_MXL_WEB_VITAL_ATTRIBUTION_PREFIX;\n attributes[`${prefix}redirect`] = redirect;\n attributes[`${prefix}domainLookup`] = domainLookup;\n attributes[`${prefix}tcpConnection`] = tcpConnection;\n attributes[`${prefix}tlsNegotiation`] = tlsNegotiation;\n attributes[`${prefix}serverResponse`] = serverResponse;\n attributes[`${prefix}unattributed`] = unattributed;\n } catch (e) {\n diag.error('error computing TTFB timing breakdown', e);\n }\n } else {\n diag.debug('TTFB navigationEntry unavailable, skipping timing breakdown');\n }\n\n return attributes;\n};\n\nexport class WebVitalsInstrumentation extends MXLInstrumentationBase {\n private readonly _listeners: WebVitalListeners;\n private readonly _urlDocument: URLDocument;\n private readonly _urlAttribution: boolean;\n private readonly _pageManager: PageManager;\n private readonly _attributedPage: Record<\n Metric['name'],\n AttributedPage | undefined\n > = {\n INP: undefined,\n LCP: undefined,\n CLS: undefined,\n FCP: undefined,\n TTFB: undefined,\n };\n private _largestShiftTargetForCLS: string | undefined;\n private _listenersRegistered = false;\n private _isEnabled = false;\n\n // instrumentation that adds an event to the session span for each web vital report\n public constructor({\n diag,\n perf,\n listeners = WEB_VITALS_ID_TO_LISTENER,\n urlDocument = window.document,\n urlAttribution = true,\n pageManager,\n }: WebVitalsInstrumentationArgs = {}) {\n super({\n instrumentationName: 'WebVitalsInstrumentation',\n instrumentationVersion: '1.0.0',\n diag,\n perf,\n config: {},\n });\n this._listeners = listeners;\n this._urlDocument = urlDocument;\n this._urlAttribution = urlAttribution;\n this._pageManager = pageManager ?? page.getPageManager();\n\n if (this._config.enabled) {\n this.enable();\n }\n }\n\n public override disable(): void {\n // web-vitals library doesn't support removing listeners, so we just pause emission\n // https://github.com/GoogleChrome/web-vitals/issues/357#issuecomment-1593439036\n this._isEnabled = false;\n this._diag.debug('WebVitalsInstrumentation disabled, pausing emission');\n }\n\n public enable(): void {\n this._isEnabled = true;\n\n // web-vitals library doesn't support removing listeners, so only register once\n if (this._listenersRegistered) {\n this._diag.debug(\n 'WebVitalsInstrumentation listeners already registered, resuming emission',\n );\n return;\n }\n this._listenersRegistered = true;\n\n ALL_WEB_VITALS.forEach((name) => {\n this._listeners[name]?.((metric) => {\n if (!this._isEnabled) {\n return;\n }\n\n const currentSessionSpan = this.sessionManager.getSessionSpan();\n\n if (!currentSessionSpan) {\n return;\n }\n\n // first thing record the time when this cb was invoked\n const metricTime = this._getTimeForMetric(metric);\n\n const attributedPage = this._getAttributedPageForMetric(metric);\n\n const attrs: Attributes = {\n [KEY_MXL_TYPE]: MXL_TYPES.WebVital,\n [ATTR_URL_FULL]: attributedPage.fullURL,\n [KEY_BROWSER_URL_FULL]: attributedPage.fullURL,\n [KEY_MXL_WEB_VITAL_NAVIGATION_TYPE]: metric.navigationType,\n [KEY_MXL_WEB_VITAL_NAME]: metric.name,\n [KEY_MXL_WEB_VITAL_RATING]: metric.rating,\n [KEY_MXL_WEB_VITAL_ID]: metric.id,\n [KEY_MXL_WEB_VITAL_DELTA]: metric.delta,\n [KEY_MXL_WEB_VITAL_VALUE]: metric.value,\n ...webVitalAttributionToReport(metric),\n ...(name === 'INP' ? loafScriptsAttribution(metric, this._diag) : {}),\n ...(name === 'TTFB'\n ? ttfbSubPartsAttribution(metric, this._diag)\n : {}),\n };\n\n // Add page attributes if route and page ID exist\n if (attributedPage.path && attributedPage.pageID) {\n attrs[KEY_MXL_PAGE_PATH] = attributedPage.path;\n attrs[KEY_MXL_PAGE_ID] = attributedPage.pageID;\n }\n\n if (attributedPage.label) {\n attrs[KEY_APP_SURFACE_LABEL] = attributedPage.label;\n }\n\n currentSessionSpan.addEvent(\n `${MXL_WEB_VITALS_PREFIX}-report-${name}`,\n attrs,\n metricTime,\n );\n });\n });\n\n if (this._urlAttribution) {\n // When these web vitals make their final report (e.g. when the listeners w/ reportAllChanges=false trigger) the\n // document's URL at that time may not match what it was at the time the scores were last updated. Instead, listen\n // for updates to the scores and keep track of the Page information to attribute for each\n this._listeners.TTFB?.(\n () => {\n this._attributedPage.TTFB = this._currentAttributedPage();\n },\n {\n reportAllChanges: true,\n },\n );\n this._listeners.FCP?.(\n () => {\n this._attributedPage.FCP = this._currentAttributedPage();\n },\n {\n reportAllChanges: true,\n },\n );\n this._listeners.INP?.(\n () => {\n this._attributedPage.INP = this._currentAttributedPage();\n },\n {\n reportAllChanges: true,\n },\n );\n this._listeners.LCP?.(\n () => {\n this._attributedPage.LCP = this._currentAttributedPage();\n },\n {\n reportAllChanges: true,\n },\n );\n this._listeners.CLS?.(\n (metric: MetricWithAttribution) => {\n const clsMetric = metric as CLSMetricWithAttribution;\n // A layout shift could cause CLS to change its rating but because the score is cumulative this might not\n // correspond with an updated `largestShiftTarget`. Since we want to tie the attributed URL to the page that\n // the `largestShiftTarget` was on we only update the attributed URL if that target has changed\n if (\n this._largestShiftTargetForCLS !==\n clsMetric.attribution.largestShiftTarget\n ) {\n this._largestShiftTargetForCLS =\n clsMetric.attribution.largestShiftTarget;\n this._attributedPage.CLS = this._currentAttributedPage();\n }\n },\n {\n reportAllChanges: true,\n },\n );\n }\n }\n\n private _getTimeForMetric(metric: MetricWithAttribution): number {\n if (metric.name === 'CLS' && metric.attribution.largestShiftTime) {\n return this.perf.epochMillisFromOriginOffset(\n metric.attribution.largestShiftTime,\n );\n }\n\n if (metric.name === 'INP' && metric.attribution.interactionTime) {\n return this.perf.epochMillisFromOriginOffset(\n metric.attribution.interactionTime,\n );\n }\n\n return this.perf.getNowMillis();\n }\n\n private _currentAttributedPage(): AttributedPage {\n const attributed: AttributedPage = {\n fullURL: this._urlDocument.URL,\n };\n\n const currentRoute = this._pageManager.getCurrentRoute();\n const currentPageId = this._pageManager.getCurrentPageId();\n if (currentRoute && currentPageId) {\n attributed.path = currentRoute.path;\n attributed.pageID = currentPageId;\n }\n\n const pageLabel = this._pageManager.getPageLabel();\n if (pageLabel) {\n attributed.label = pageLabel;\n }\n\n return attributed;\n }\n\n private _getAttributedPageForMetric(\n metric: MetricWithAttribution,\n ): AttributedPage {\n if (metric.name === 'FCP' && this._attributedPage.FCP) {\n return this._attributedPage.FCP;\n }\n\n if (metric.name === 'TTFB' && this._attributedPage.TTFB) {\n return this._attributedPage.TTFB;\n }\n\n if (metric.name === 'INP' && this._attributedPage.INP) {\n return this._attributedPage.INP;\n }\n\n if (metric.name === 'LCP' && this._attributedPage.LCP) {\n return this._attributedPage.LCP;\n }\n\n if (\n metric.name === 'CLS' &&\n this._attributedPage.CLS &&\n metric.attribution.largestShiftTarget === this._largestShiftTargetForCLS\n ) {\n return this._attributedPage.CLS;\n }\n\n return this._currentAttributedPage();\n }\n}\n"],"mappings":";;;;;;;AAqDA,MAAM,oBAAoB,UAA4C;CACpE,MAAM,OAAO,OAAO;AACpB,QAAO,SAAS,YAAY,SAAS,YAAY,SAAS;;AAG5D,MAAM,cAAc,UAA0B,KAAK,MAAM,KAAK,IAAI,GAAG,MAAM,CAAC;AAE5E,MAAM,+BACJ,WACe;CACf,MAAM,aAAyB,EAAE;CACjC,MAAM,cAAc,OAAO;AAE3B,KAAI,CAAC,eAAe,OAAO,gBAAgB,SACzC,QAAO;AAGT,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,YAAY,CACpD,KAAI,iBAAiB,MAAM,CACzB,YAAW,GAAG,uCAAuC,SAAS;AAIlE,QAAO;;AAGT,MAAM,0BACJ,QACA,SACe;CACf,MAAM,aAAyB,EAAE;CACjC,MAAM,cAAc,OAAO;AAE3B,KAAI;AAGF,MAAI,YAAY,0BAA0B,SAAS,GAAG;GACpD,MAAM,0BAAU,IAAI,KAOjB;AACH,QAAK,MAAM,SAAS,YAAY,0BAC9B,MAAK,MAAM,UAAU,MAAM,SAAS;IAClC,IAAI,MAAM,OAAO,aAAa;AAC9B,QAAI,IAAI,SAAA,KACN,OAAM,GAAG,IAAI,UAAU,GAAG,2BAA2B,CAAC;IAExD,MAAM,WAAW,QAAQ,IAAI,IAAI;AACjC,QAAI,UAAU;AACZ,cAAS,iBAAiB,OAAO;AACjC,cAAS,0BACP,OAAO;AACT,cAAS;UAET,SAAQ,IAAI,KAAK;KACf,eAAe,OAAO;KACtB,wBAAwB,OAAO;KAC/B,OAAO;KACR,CAAC;;AAIR,OAAI,QAAQ,OAAO,EACjB,YAAW,GAAG,qCAAqC,iBACjD,KAAK,UACH,OAAO,YACL,CAAC,GAAG,QAAQ,CACT,MAAM,GAAG,MAAM,EAAE,GAAG,gBAAgB,EAAE,GAAG,cAAc,CACvD,MAAM,GAAA,IAA2B,CACjC,KAAK,CAAC,KAAK,YAAY,CACtB,KACA;IACE,gBAAgB,KAAK,MAAM,OAAO,cAAc;IAChD,2BAA2B,KAAK,MAC9B,OAAO,uBACR;IACD,OAAO,OAAO;IACf,CACF,CAAC,CACL,CACF;;UAIA,GAAG;AACV,OAAK,MAAM,uCAAuC,EAAE;;AAGtD,QAAO;;AAGT,MAAM,2BACJ,QACA,SACe;CACf,MAAM,aAAyB,EAAE;CAEjC,MAAM,QADc,OAAO,YACD;AAI1B,KAAI,MACF,KAAI;EACF,MAAM,WAAW,WAAW,MAAM,cAAc,MAAM,cAAc;EACpE,MAAM,eAAe,WACnB,MAAM,kBAAkB,MAAM,kBAC/B;EACD,MAAM,gBAAgB,WACpB,MAAM,wBAAwB,IAC1B,MAAM,wBAAwB,MAAM,eACpC,MAAM,aAAa,MAAM,aAC9B;EACD,MAAM,iBAAiB,WACrB,MAAM,wBAAwB,IAC1B,MAAM,aAAa,MAAM,wBACzB,EACL;EAOD,MAAM,iBAAiB,WANQ,KAAK,IAGlC,MAAM,6BAA6B,GACnC,MAAM,cAGgB,GAAG,MAAM,aAChC;EAED,MAAM,eAAe,WADP,KAAK,MAAM,MAAM,cAAc,MAAM,UAE5C,GACH,WACA,eACA,gBACA,iBACA,eACH;EACD,MAAM,SAAS;AACf,aAAW,GAAG,OAAO,aAAa;AAClC,aAAW,GAAG,OAAO,iBAAiB;AACtC,aAAW,GAAG,OAAO,kBAAkB;AACvC,aAAW,GAAG,OAAO,mBAAmB;AACxC,aAAW,GAAG,OAAO,mBAAmB;AACxC,aAAW,GAAG,OAAO,iBAAiB;UAC/B,GAAG;AACV,OAAK,MAAM,yCAAyC,EAAE;;KAGxD,MAAK,MAAM,8DAA8D;AAG3E,QAAO;;AAGT,IAAa,2BAAb,cAA8C,uBAAuB;CACnE;CACA;CACA;CACA;CACA,kBAGI;EACF,KAAK,KAAA;EACL,KAAK,KAAA;EACL,KAAK,KAAA;EACL,KAAK,KAAA;EACL,MAAM,KAAA;EACP;CACD;CACA,uBAA+B;CAC/B,aAAqB;CAGrB,YAAmB,EACjB,MACA,MACA,YAAY,2BACZ,cAAc,OAAO,UACrB,iBAAiB,MACjB,gBACgC,EAAE,EAAE;AACpC,QAAM;GACJ,qBAAqB;GACrB,wBAAwB;GACxB;GACA;GACA,QAAQ,EAAE;GACX,CAAC;AACF,OAAK,aAAa;AAClB,OAAK,eAAe;AACpB,OAAK,kBAAkB;AACvB,OAAK,eAAe,eAAe,KAAK,gBAAgB;AAExD,MAAI,KAAK,QAAQ,QACf,MAAK,QAAQ;;CAIjB,UAAgC;AAG9B,OAAK,aAAa;AAClB,OAAK,MAAM,MAAM,sDAAsD;;CAGzE,SAAsB;AACpB,OAAK,aAAa;AAGlB,MAAI,KAAK,sBAAsB;AAC7B,QAAK,MAAM,MACT,2EACD;AACD;;AAEF,OAAK,uBAAuB;AAE5B,iBAAe,SAAS,SAAS;AAC/B,QAAK,WAAW,SAAS,WAAW;AAClC,QAAI,CAAC,KAAK,WACR;IAGF,MAAM,qBAAqB,KAAK,eAAe,gBAAgB;AAE/D,QAAI,CAAC,mBACH;IAIF,MAAM,aAAa,KAAK,kBAAkB,OAAO;IAEjD,MAAM,iBAAiB,KAAK,4BAA4B,OAAO;IAE/D,MAAM,QAAoB;MACvB,eAAA;MACA,gBAAgB,eAAe;MAC/B,uBAAuB,eAAe;MACtC,oCAAoC,OAAO;MAC3C,yBAAyB,OAAO;MAChC,2BAA2B,OAAO;MAClC,uBAAuB,OAAO;MAC9B,0BAA0B,OAAO;MACjC,0BAA0B,OAAO;KAClC,GAAG,4BAA4B,OAAO;KACtC,GAAI,SAAS,QAAQ,uBAAuB,QAAQ,KAAK,MAAM,GAAG,EAAE;KACpE,GAAI,SAAS,SACT,wBAAwB,QAAQ,KAAK,MAAM,GAC3C,EAAE;KACP;AAGD,QAAI,eAAe,QAAQ,eAAe,QAAQ;AAChD,WAAM,qBAAqB,eAAe;AAC1C,WAAM,mBAAmB,eAAe;;AAG1C,QAAI,eAAe,MACjB,OAAM,yBAAyB,eAAe;AAGhD,uBAAmB,SACjB,GAAG,sBAAsB,UAAU,QACnC,OACA,WACD;KACD;IACF;AAEF,MAAI,KAAK,iBAAiB;AAIxB,QAAK,WAAW,aACR;AACJ,SAAK,gBAAgB,OAAO,KAAK,wBAAwB;MAE3D,EACE,kBAAkB,MACnB,CACF;AACD,QAAK,WAAW,YACR;AACJ,SAAK,gBAAgB,MAAM,KAAK,wBAAwB;MAE1D,EACE,kBAAkB,MACnB,CACF;AACD,QAAK,WAAW,YACR;AACJ,SAAK,gBAAgB,MAAM,KAAK,wBAAwB;MAE1D,EACE,kBAAkB,MACnB,CACF;AACD,QAAK,WAAW,YACR;AACJ,SAAK,gBAAgB,MAAM,KAAK,wBAAwB;MAE1D,EACE,kBAAkB,MACnB,CACF;AACD,QAAK,WAAW,OACb,WAAkC;IACjC,MAAM,YAAY;AAIlB,QACE,KAAK,8BACL,UAAU,YAAY,oBACtB;AACA,UAAK,4BACH,UAAU,YAAY;AACxB,UAAK,gBAAgB,MAAM,KAAK,wBAAwB;;MAG5D,EACE,kBAAkB,MACnB,CACF;;;CAIL,kBAA0B,QAAuC;AAC/D,MAAI,OAAO,SAAS,SAAS,OAAO,YAAY,iBAC9C,QAAO,KAAK,KAAK,4BACf,OAAO,YAAY,iBACpB;AAGH,MAAI,OAAO,SAAS,SAAS,OAAO,YAAY,gBAC9C,QAAO,KAAK,KAAK,4BACf,OAAO,YAAY,gBACpB;AAGH,SAAO,KAAK,KAAK,cAAc;;CAGjC,yBAAiD;EAC/C,MAAM,aAA6B,EACjC,SAAS,KAAK,aAAa,KAC5B;EAED,MAAM,eAAe,KAAK,aAAa,iBAAiB;EACxD,MAAM,gBAAgB,KAAK,aAAa,kBAAkB;AAC1D,MAAI,gBAAgB,eAAe;AACjC,cAAW,OAAO,aAAa;AAC/B,cAAW,SAAS;;EAGtB,MAAM,YAAY,KAAK,aAAa,cAAc;AAClD,MAAI,UACF,YAAW,QAAQ;AAGrB,SAAO;;CAGT,4BACE,QACgB;AAChB,MAAI,OAAO,SAAS,SAAS,KAAK,gBAAgB,IAChD,QAAO,KAAK,gBAAgB;AAG9B,MAAI,OAAO,SAAS,UAAU,KAAK,gBAAgB,KACjD,QAAO,KAAK,gBAAgB;AAG9B,MAAI,OAAO,SAAS,SAAS,KAAK,gBAAgB,IAChD,QAAO,KAAK,gBAAgB;AAG9B,MAAI,OAAO,SAAS,SAAS,KAAK,gBAAgB,IAChD,QAAO,KAAK,gBAAgB;AAG9B,MACE,OAAO,SAAS,SAChB,KAAK,gBAAgB,OACrB,OAAO,YAAY,uBAAuB,KAAK,0BAE/C,QAAO,KAAK,gBAAgB;AAG9B,SAAO,KAAK,wBAAwB"}
1
+ {"version":3,"file":"WebVitalsInstrumentation.js","names":[],"sources":["../../../../src/instrumentations/web-vitals/WebVitalsInstrumentation/WebVitalsInstrumentation.ts"],"sourcesContent":["import type {\n Attributes,\n AttributeValue,\n DiagLogger,\n} from '@opentelemetry/api';\nimport { ATTR_URL_FULL } from '@opentelemetry/semantic-conventions';\nimport type {\n CLSMetricWithAttribution,\n INPAttribution,\n Metric,\n MetricWithAttribution,\n TTFBAttribution,\n} from 'web-vitals/attribution';\nimport type { PageManager } from '../../../api-page';\nimport { page } from '../../../api-page';\nimport type { URLDocument } from '../../../common';\nimport {\n KEY_APP_SURFACE_LABEL,\n KEY_BROWSER_URL_FULL,\n KEY_MXL_PAGE_ID,\n KEY_MXL_PAGE_PATH,\n KEY_MXL_TYPE,\n MXL_TYPES,\n} from '../../../constants';\nimport { MXLInstrumentationBase } from '../../MXLInstrumentationBase';\nimport {\n KEY_MXL_WEB_VITAL_ATTRIBUTION_PREFIX,\n KEY_MXL_WEB_VITAL_DELTA,\n KEY_MXL_WEB_VITAL_ID,\n KEY_MXL_WEB_VITAL_NAME,\n KEY_MXL_WEB_VITAL_NAVIGATION_TYPE,\n KEY_MXL_WEB_VITAL_RATING,\n KEY_MXL_WEB_VITAL_VALUE,\n} from './attributes';\nimport {\n ALL_WEB_VITALS,\n MAX_LOAF_SCRIPT_ENTRIES,\n MAX_LOAF_SCRIPT_URL_LENGTH,\n MXL_WEB_VITALS_PREFIX,\n WEB_VITALS_ID_TO_LISTENER,\n} from './constants';\nimport type { WebVitalListeners, WebVitalsInstrumentationArgs } from './types';\n\ntype AttributedPage = {\n fullURL: string;\n path?: string;\n pageID?: string;\n label?: string;\n};\n\nconst isPrimitiveValue = (value: unknown): value is AttributeValue => {\n const type = typeof value;\n return type === 'number' || type === 'string' || type === 'boolean';\n};\n\nconst roundClamp = (value: number): number => Math.round(Math.max(0, value));\n\nconst webVitalAttributionToReport = (\n metric: MetricWithAttribution,\n): Attributes => {\n const attributes: Attributes = {};\n const attribution = metric.attribution;\n\n if (!attribution || typeof attribution !== 'object') {\n return attributes;\n }\n\n for (const [key, value] of Object.entries(attribution)) {\n if (isPrimitiveValue(value)) {\n attributes[`${KEY_MXL_WEB_VITAL_ATTRIBUTION_PREFIX}${key}`] = value;\n }\n }\n\n return attributes;\n};\n\nconst loafScriptsAttribution = (\n metric: MetricWithAttribution,\n diag: DiagLogger,\n): Attributes => {\n const attributes: Attributes = {};\n const attribution = metric.attribution as INPAttribution;\n\n try {\n // suppress LoAF baseline errors\n /* eslint-disable baseline-js/use-baseline */\n if (attribution.longAnimationFrameEntries.length > 0) {\n const scripts = new Map<\n string,\n {\n totalDuration: number;\n styleAndLayoutDuration: number;\n count: number;\n }\n >();\n for (const entry of attribution.longAnimationFrameEntries) {\n for (const script of entry.scripts) {\n let url = script.sourceURL || '(inline)';\n if (url.length > MAX_LOAF_SCRIPT_URL_LENGTH) {\n url = `${url.substring(0, MAX_LOAF_SCRIPT_URL_LENGTH)}...`;\n }\n const existing = scripts.get(url);\n if (existing) {\n existing.totalDuration += script.duration;\n existing.styleAndLayoutDuration +=\n script.forcedStyleAndLayoutDuration;\n existing.count++;\n } else {\n scripts.set(url, {\n totalDuration: script.duration,\n styleAndLayoutDuration: script.forcedStyleAndLayoutDuration,\n count: 1,\n });\n }\n }\n }\n if (scripts.size > 0) {\n attributes[`${KEY_MXL_WEB_VITAL_ATTRIBUTION_PREFIX}loaf_scripts`] =\n JSON.stringify(\n Object.fromEntries(\n [...scripts]\n .sort((a, b) => b[1].totalDuration - a[1].totalDuration)\n .slice(0, MAX_LOAF_SCRIPT_ENTRIES)\n .map(([url, script]) => [\n url,\n {\n total_duration: Math.round(script.totalDuration),\n style_and_layout_duration: Math.round(\n script.styleAndLayoutDuration,\n ),\n count: script.count,\n },\n ]),\n ),\n );\n }\n }\n /* eslint-enable baseline-js/use-baseline */\n } catch (e) {\n diag.error('error building loaf scripts for INP', e);\n }\n\n return attributes;\n};\n\nconst ttfbSubPartsAttribution = (\n metric: MetricWithAttribution,\n diag: DiagLogger,\n): Attributes => {\n const attributes: Attributes = {};\n const attribution = metric.attribution as TTFBAttribution;\n const entry = attribution.navigationEntry as\n | PerformanceNavigationTiming\n | undefined;\n\n if (entry) {\n try {\n const redirect = roundClamp(entry.redirectEnd - entry.redirectStart);\n const domainLookup = roundClamp(\n entry.domainLookupEnd - entry.domainLookupStart,\n );\n const tcpConnection = roundClamp(\n entry.secureConnectionStart > 0\n ? entry.secureConnectionStart - entry.connectStart\n : entry.connectEnd - entry.connectStart,\n );\n const tlsNegotiation = roundClamp(\n entry.secureConnectionStart > 0\n ? entry.connectEnd - entry.secureConnectionStart\n : 0,\n );\n const effectiveResponseStart = Math.max(\n // @ts-expect-error 103 Early hints are not supported in all browsers\n // https://developer.mozilla.org/en-US/docs/Web/API/PerformanceResourceTiming/finalResponseHeadersStart\n entry.finalResponseHeadersStart ?? 0,\n entry.responseStart,\n );\n const serverResponse = roundClamp(\n effectiveResponseStart - entry.requestStart,\n );\n const total = Math.round(entry.responseEnd - entry.startTime);\n const unattributed = roundClamp(\n total -\n redirect -\n domainLookup -\n tcpConnection -\n tlsNegotiation -\n serverResponse,\n );\n const prefix = KEY_MXL_WEB_VITAL_ATTRIBUTION_PREFIX;\n attributes[`${prefix}redirect`] = redirect;\n attributes[`${prefix}domainLookup`] = domainLookup;\n attributes[`${prefix}tcpConnection`] = tcpConnection;\n attributes[`${prefix}tlsNegotiation`] = tlsNegotiation;\n attributes[`${prefix}serverResponse`] = serverResponse;\n attributes[`${prefix}unattributed`] = unattributed;\n } catch (e) {\n diag.error('error computing TTFB timing breakdown', e);\n }\n } else {\n diag.debug('TTFB navigationEntry unavailable, skipping timing breakdown');\n }\n\n return attributes;\n};\n\nexport class WebVitalsInstrumentation extends MXLInstrumentationBase {\n private readonly _listeners: WebVitalListeners;\n private readonly _urlDocument: URLDocument;\n private readonly _urlAttribution: boolean;\n private readonly _pageManager: PageManager;\n private readonly _attributedPage: Record<\n Metric['name'],\n AttributedPage | undefined\n > = {\n INP: undefined,\n LCP: undefined,\n CLS: undefined,\n FCP: undefined,\n TTFB: undefined,\n };\n private _largestShiftTargetForCLS: string | undefined;\n private _listenersRegistered = false;\n private _isEnabled = false;\n\n // instrumentation that adds an event to the session span for each web vital report\n public constructor({\n diag,\n perf,\n listeners = WEB_VITALS_ID_TO_LISTENER,\n urlDocument = window.document,\n urlAttribution = true,\n pageManager,\n }: WebVitalsInstrumentationArgs = {}) {\n super({\n instrumentationName: 'WebVitalsInstrumentation',\n instrumentationVersion: '1.0.0',\n diag,\n perf,\n config: {},\n });\n this._listeners = listeners;\n this._urlDocument = urlDocument;\n this._urlAttribution = urlAttribution;\n this._pageManager = pageManager ?? page.getPageManager();\n\n if (this._config.enabled) {\n this.enable();\n }\n }\n\n public override disable(): void {\n // web-vitals library doesn't support removing listeners, so we just pause emission\n // https://github.com/GoogleChrome/web-vitals/issues/357#issuecomment-1593439036\n this._isEnabled = false;\n this._diag.debug('WebVitalsInstrumentation disabled, pausing emission');\n }\n\n public enable(): void {\n this._isEnabled = true;\n\n // web-vitals library doesn't support removing listeners, so only register once\n if (this._listenersRegistered) {\n this._diag.debug(\n 'WebVitalsInstrumentation listeners already registered, resuming emission',\n );\n return;\n }\n this._listenersRegistered = true;\n\n ALL_WEB_VITALS.forEach((name) => {\n this._listeners[name]?.((metric) => {\n if (!this._isEnabled) {\n return;\n }\n\n const currentSessionSpan = this.sessionManager.getSessionSpan();\n\n if (!currentSessionSpan) {\n return;\n }\n\n // first thing record the time when this cb was invoked\n const metricTime = this._getTimeForMetric(metric);\n\n const attributedPage = this._getAttributedPageForMetric(metric);\n\n const attrs: Attributes = {\n [KEY_MXL_TYPE]: MXL_TYPES.WebVital,\n [ATTR_URL_FULL]: attributedPage.fullURL,\n [KEY_BROWSER_URL_FULL]: attributedPage.fullURL,\n [KEY_MXL_WEB_VITAL_NAVIGATION_TYPE]: metric.navigationType,\n [KEY_MXL_WEB_VITAL_NAME]: metric.name,\n [KEY_MXL_WEB_VITAL_RATING]: metric.rating,\n [KEY_MXL_WEB_VITAL_ID]: metric.id,\n [KEY_MXL_WEB_VITAL_DELTA]: metric.delta,\n [KEY_MXL_WEB_VITAL_VALUE]: metric.value,\n ...webVitalAttributionToReport(metric),\n ...(name === 'INP' ? loafScriptsAttribution(metric, this._diag) : {}),\n ...(name === 'TTFB'\n ? ttfbSubPartsAttribution(metric, this._diag)\n : {}),\n };\n\n // Add page attributes if route and page ID exist\n if (attributedPage.path && attributedPage.pageID) {\n attrs[KEY_MXL_PAGE_PATH] = attributedPage.path;\n attrs[KEY_MXL_PAGE_ID] = attributedPage.pageID;\n }\n\n if (attributedPage.label) {\n attrs[KEY_APP_SURFACE_LABEL] = attributedPage.label;\n }\n\n currentSessionSpan.addEvent(\n `${MXL_WEB_VITALS_PREFIX}-report-${name}`,\n attrs,\n metricTime,\n );\n });\n });\n\n if (this._urlAttribution) {\n // When these web vitals make their final report (e.g. when the listeners w/ reportAllChanges=false trigger) the\n // document's URL at that time may not match what it was at the time the scores were last updated. Instead, listen\n // for updates to the scores and keep track of the Page information to attribute for each\n this._listeners.TTFB?.(\n () => {\n this._attributedPage.TTFB = this._currentAttributedPage();\n },\n {\n reportAllChanges: true,\n },\n );\n this._listeners.FCP?.(\n () => {\n this._attributedPage.FCP = this._currentAttributedPage();\n },\n {\n reportAllChanges: true,\n },\n );\n this._listeners.INP?.(\n () => {\n this._attributedPage.INP = this._currentAttributedPage();\n },\n {\n reportAllChanges: true,\n },\n );\n this._listeners.LCP?.(\n () => {\n this._attributedPage.LCP = this._currentAttributedPage();\n },\n {\n reportAllChanges: true,\n },\n );\n this._listeners.CLS?.(\n (metric: MetricWithAttribution) => {\n const clsMetric = metric as CLSMetricWithAttribution;\n // A layout shift could cause CLS to change its rating but because the score is cumulative this might not\n // correspond with an updated `largestShiftTarget`. Since we want to tie the attributed URL to the page that\n // the `largestShiftTarget` was on we only update the attributed URL if that target has changed\n if (\n this._largestShiftTargetForCLS !==\n clsMetric.attribution.largestShiftTarget\n ) {\n this._largestShiftTargetForCLS =\n clsMetric.attribution.largestShiftTarget;\n this._attributedPage.CLS = this._currentAttributedPage();\n }\n },\n {\n reportAllChanges: true,\n },\n );\n }\n }\n\n private _getTimeForMetric(metric: MetricWithAttribution): number {\n if (metric.name === 'CLS' && metric.attribution.largestShiftTime) {\n return this.perf.epochMillisFromOriginOffset(\n metric.attribution.largestShiftTime,\n );\n }\n\n if (metric.name === 'INP' && metric.attribution.interactionTime) {\n return this.perf.epochMillisFromOriginOffset(\n metric.attribution.interactionTime,\n );\n }\n\n return this.perf.getNowMillis();\n }\n\n private _currentAttributedPage(): AttributedPage {\n const attributed: AttributedPage = {\n fullURL: this._urlDocument.URL,\n };\n\n const currentRoute = this._pageManager.getCurrentRoute();\n const currentPageId = this._pageManager.getCurrentPageId();\n if (currentRoute && currentPageId) {\n attributed.path = currentRoute.path;\n attributed.pageID = currentPageId;\n }\n\n const pageLabel = this._pageManager.getPageLabel();\n if (pageLabel) {\n attributed.label = pageLabel;\n }\n\n return attributed;\n }\n\n private _getAttributedPageForMetric(\n metric: MetricWithAttribution,\n ): AttributedPage {\n if (metric.name === 'FCP' && this._attributedPage.FCP) {\n return this._attributedPage.FCP;\n }\n\n if (metric.name === 'TTFB' && this._attributedPage.TTFB) {\n return this._attributedPage.TTFB;\n }\n\n if (metric.name === 'INP' && this._attributedPage.INP) {\n return this._attributedPage.INP;\n }\n\n if (metric.name === 'LCP' && this._attributedPage.LCP) {\n return this._attributedPage.LCP;\n }\n\n if (\n metric.name === 'CLS' &&\n this._attributedPage.CLS &&\n metric.attribution.largestShiftTarget === this._largestShiftTargetForCLS\n ) {\n return this._attributedPage.CLS;\n }\n\n return this._currentAttributedPage();\n }\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"MXLXHRInstrumentation.cjs","names":["XMLHttpRequestInstrumentation"],"sources":["../../../../src/instrumentations/xhr/MXLXHRInstrumentation/MXLXHRInstrumentation.ts"],"sourcesContent":["import { isWrapped } from '@opentelemetry/instrumentation';\nimport { XMLHttpRequestInstrumentation } from '@opentelemetry/instrumentation-xml-http-request';\nimport type { MXLXHRInstrumentationArgs } from './types.ts';\n\nexport class MXLXHRInstrumentation extends XMLHttpRequestInstrumentation {\n private readonly _omitIfAlreadyPatched?: boolean;\n\n public constructor({\n omitIfAlreadyPatched,\n ...rest\n }: MXLXHRInstrumentationArgs = {}) {\n // Base constructor automatically calls this.enable() if enabled is true, but we need to run our overridden constructor\n // first so force enabled false here and call it ourselves later\n super({ ...rest, enabled: false });\n\n this._omitIfAlreadyPatched = omitIfAlreadyPatched;\n\n if (rest.enabled) {\n this.enable();\n }\n }\n\n public override enable(): void {\n // The base implementation always removes and then re-patches, this means the last instrumentation to run \"wins\":\n // https://github.com/open-telemetry/opentelemetry-js/blob/2d7eecbb19aec17bf2d8b9a4e4b2d84dc92c2d88/experimental/packages/opentelemetry-instrumentation-xml-http-request/src/xhr.ts#L639\n // Exposing an option in this class to allow leaving the existing patch in place and letting a previous instrumentation\n // control the global\n if (\n this._omitIfAlreadyPatched &&\n (isWrapped(XMLHttpRequest.prototype.open) ||\n isWrapped(XMLHttpRequest.prototype.send))\n ) {\n this._diag.debug(\n 'XMLHttpRequest is already passed and `omitIfAlreadyPatched` is true, skipping enabling this instrumentation',\n );\n return;\n }\n\n super.enable();\n }\n}\n"],"mappings":";;;;;AAIA,IAAa,wBAAb,cAA2CA,gDAAAA,8BAA8B;CACvE;CAEA,YAAmB,EACjB,sBACA,GAAG,SAC0B,EAAE,EAAE;AAGjC,QAAM;GAAE,GAAG;GAAM,SAAS;GAAO,CAAC;AAElC,OAAK,wBAAwB;AAE7B,MAAI,KAAK,QACP,MAAK,QAAQ;;CAIjB,SAA+B;AAK7B,MACE,KAAK,2BAAA,GAAA,+BAAA,WACM,eAAe,UAAU,KAAK,KAAA,GAAA,+BAAA,WAC7B,eAAe,UAAU,KAAK,GAC1C;AACA,QAAK,MAAM,MACT,8GACD;AACD;;AAGF,QAAM,QAAQ"}
1
+ {"version":3,"file":"MXLXHRInstrumentation.cjs","names":["XMLHttpRequestInstrumentation"],"sources":["../../../../src/instrumentations/xhr/MXLXHRInstrumentation/MXLXHRInstrumentation.ts"],"sourcesContent":["import { isWrapped } from '@opentelemetry/instrumentation';\nimport { XMLHttpRequestInstrumentation } from '@opentelemetry/instrumentation-xml-http-request';\nimport type { MXLXHRInstrumentationArgs } from './types';\n\nexport class MXLXHRInstrumentation extends XMLHttpRequestInstrumentation {\n private readonly _omitIfAlreadyPatched?: boolean;\n\n public constructor({\n omitIfAlreadyPatched,\n ...rest\n }: MXLXHRInstrumentationArgs = {}) {\n // Base constructor automatically calls this.enable() if enabled is true, but we need to run our overridden constructor\n // first so force enabled false here and call it ourselves later\n super({ ...rest, enabled: false });\n\n this._omitIfAlreadyPatched = omitIfAlreadyPatched;\n\n if (rest.enabled) {\n this.enable();\n }\n }\n\n public override enable(): void {\n // The base implementation always removes and then re-patches, this means the last instrumentation to run \"wins\":\n // https://github.com/open-telemetry/opentelemetry-js/blob/2d7eecbb19aec17bf2d8b9a4e4b2d84dc92c2d88/experimental/packages/opentelemetry-instrumentation-xml-http-request/src/xhr.ts#L639\n // Exposing an option in this class to allow leaving the existing patch in place and letting a previous instrumentation\n // control the global\n if (\n this._omitIfAlreadyPatched &&\n (isWrapped(XMLHttpRequest.prototype.open) ||\n isWrapped(XMLHttpRequest.prototype.send))\n ) {\n this._diag.debug(\n 'XMLHttpRequest is already passed and `omitIfAlreadyPatched` is true, skipping enabling this instrumentation',\n );\n return;\n }\n\n super.enable();\n }\n}\n"],"mappings":";;;;;AAIA,IAAa,wBAAb,cAA2CA,gDAAAA,8BAA8B;CACvE;CAEA,YAAmB,EACjB,sBACA,GAAG,SAC0B,EAAE,EAAE;AAGjC,QAAM;GAAE,GAAG;GAAM,SAAS;GAAO,CAAC;AAElC,OAAK,wBAAwB;AAE7B,MAAI,KAAK,QACP,MAAK,QAAQ;;CAIjB,SAA+B;AAK7B,MACE,KAAK,2BAAA,GAAA,+BAAA,WACM,eAAe,UAAU,KAAK,KAAA,GAAA,+BAAA,WAC7B,eAAe,UAAU,KAAK,GAC1C;AACA,QAAK,MAAM,MACT,8GACD;AACD;;AAGF,QAAM,QAAQ"}
@@ -1 +1 @@
1
- {"version":3,"file":"MXLXHRInstrumentation.js","names":[],"sources":["../../../../src/instrumentations/xhr/MXLXHRInstrumentation/MXLXHRInstrumentation.ts"],"sourcesContent":["import { isWrapped } from '@opentelemetry/instrumentation';\nimport { XMLHttpRequestInstrumentation } from '@opentelemetry/instrumentation-xml-http-request';\nimport type { MXLXHRInstrumentationArgs } from './types.ts';\n\nexport class MXLXHRInstrumentation extends XMLHttpRequestInstrumentation {\n private readonly _omitIfAlreadyPatched?: boolean;\n\n public constructor({\n omitIfAlreadyPatched,\n ...rest\n }: MXLXHRInstrumentationArgs = {}) {\n // Base constructor automatically calls this.enable() if enabled is true, but we need to run our overridden constructor\n // first so force enabled false here and call it ourselves later\n super({ ...rest, enabled: false });\n\n this._omitIfAlreadyPatched = omitIfAlreadyPatched;\n\n if (rest.enabled) {\n this.enable();\n }\n }\n\n public override enable(): void {\n // The base implementation always removes and then re-patches, this means the last instrumentation to run \"wins\":\n // https://github.com/open-telemetry/opentelemetry-js/blob/2d7eecbb19aec17bf2d8b9a4e4b2d84dc92c2d88/experimental/packages/opentelemetry-instrumentation-xml-http-request/src/xhr.ts#L639\n // Exposing an option in this class to allow leaving the existing patch in place and letting a previous instrumentation\n // control the global\n if (\n this._omitIfAlreadyPatched &&\n (isWrapped(XMLHttpRequest.prototype.open) ||\n isWrapped(XMLHttpRequest.prototype.send))\n ) {\n this._diag.debug(\n 'XMLHttpRequest is already passed and `omitIfAlreadyPatched` is true, skipping enabling this instrumentation',\n );\n return;\n }\n\n super.enable();\n }\n}\n"],"mappings":";;;AAIA,IAAa,wBAAb,cAA2C,8BAA8B;CACvE;CAEA,YAAmB,EACjB,sBACA,GAAG,SAC0B,EAAE,EAAE;AAGjC,QAAM;GAAE,GAAG;GAAM,SAAS;GAAO,CAAC;AAElC,OAAK,wBAAwB;AAE7B,MAAI,KAAK,QACP,MAAK,QAAQ;;CAIjB,SAA+B;AAK7B,MACE,KAAK,0BACJ,UAAU,eAAe,UAAU,KAAK,IACvC,UAAU,eAAe,UAAU,KAAK,GAC1C;AACA,QAAK,MAAM,MACT,8GACD;AACD;;AAGF,QAAM,QAAQ"}
1
+ {"version":3,"file":"MXLXHRInstrumentation.js","names":[],"sources":["../../../../src/instrumentations/xhr/MXLXHRInstrumentation/MXLXHRInstrumentation.ts"],"sourcesContent":["import { isWrapped } from '@opentelemetry/instrumentation';\nimport { XMLHttpRequestInstrumentation } from '@opentelemetry/instrumentation-xml-http-request';\nimport type { MXLXHRInstrumentationArgs } from './types';\n\nexport class MXLXHRInstrumentation extends XMLHttpRequestInstrumentation {\n private readonly _omitIfAlreadyPatched?: boolean;\n\n public constructor({\n omitIfAlreadyPatched,\n ...rest\n }: MXLXHRInstrumentationArgs = {}) {\n // Base constructor automatically calls this.enable() if enabled is true, but we need to run our overridden constructor\n // first so force enabled false here and call it ourselves later\n super({ ...rest, enabled: false });\n\n this._omitIfAlreadyPatched = omitIfAlreadyPatched;\n\n if (rest.enabled) {\n this.enable();\n }\n }\n\n public override enable(): void {\n // The base implementation always removes and then re-patches, this means the last instrumentation to run \"wins\":\n // https://github.com/open-telemetry/opentelemetry-js/blob/2d7eecbb19aec17bf2d8b9a4e4b2d84dc92c2d88/experimental/packages/opentelemetry-instrumentation-xml-http-request/src/xhr.ts#L639\n // Exposing an option in this class to allow leaving the existing patch in place and letting a previous instrumentation\n // control the global\n if (\n this._omitIfAlreadyPatched &&\n (isWrapped(XMLHttpRequest.prototype.open) ||\n isWrapped(XMLHttpRequest.prototype.send))\n ) {\n this._diag.debug(\n 'XMLHttpRequest is already passed and `omitIfAlreadyPatched` is true, skipping enabling this instrumentation',\n );\n return;\n }\n\n super.enable();\n }\n}\n"],"mappings":";;;AAIA,IAAa,wBAAb,cAA2C,8BAA8B;CACvE;CAEA,YAAmB,EACjB,sBACA,GAAG,SAC0B,EAAE,EAAE;AAGjC,QAAM;GAAE,GAAG;GAAM,SAAS;GAAO,CAAC;AAElC,OAAK,wBAAwB;AAE7B,MAAI,KAAK,QACP,MAAK,QAAQ;;CAIjB,SAA+B;AAK7B,MACE,KAAK,0BACJ,UAAU,eAAe,UAAU,KAAK,IACvC,UAAU,eAAe,UAAU,KAAK,GAC1C;AACA,QAAK,MAAM,MACT,8GACD;AACD;;AAGF,QAAM,QAAQ"}
@@ -1,7 +1,7 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  require("../../_virtual/_rolldown/runtime.cjs");
3
- const require_managers_MXLConfigManager_constants = require("./constants.cjs");
4
3
  const require_resources_webSdkResource = require("../../resources/webSdkResource.cjs");
4
+ const require_managers_MXLConfigManager_constants = require("./constants.cjs");
5
5
  const require_managers_MXLConfigManager_utils = require("./utils.cjs");
6
6
  let _opentelemetry_api = require("@opentelemetry/api");
7
7
  //#region src/managers/MXLConfigManager/MXLDynamicConfigManager.ts
@@ -1 +1 @@
1
- {"version":3,"file":"MXLDynamicConfigManager.cjs","names":["diag","getConfigURL","DEFAULT_CONFIG","OTEL_DEFAULT_SERVICE_NAME","LOCAL_STORAGE_REMOTE_CONFIG_KEY"],"sources":["../../../src/managers/MXLConfigManager/MXLDynamicConfigManager.ts"],"sourcesContent":["import type { DiagLogger } from '@opentelemetry/api';\nimport { diag } from '@opentelemetry/api';\nimport type {\n DynamicConfigManager,\n DynamicSDKConfig,\n} from '../../sdk/index.ts';\nimport {\n DEFAULT_CONFIG,\n LOCAL_STORAGE_REMOTE_CONFIG_KEY,\n} from './constants.ts';\nimport { OTEL_DEFAULT_SERVICE_NAME } from '../../resources/webSdkResource.ts';\nimport type {\n MXLDynamicConfigManagerArgs,\n RemoteConfig,\n StoredRemoteConfig,\n} from './types.ts';\nimport { getConfigURL } from './utils.ts';\n\nconst parseRemoteConfig = (remoteConfig: RemoteConfig): DynamicSDKConfig => {\n const parsed: DynamicSDKConfig = {\n samplingPct: remoteConfig.threshold,\n };\n\n if (remoteConfig.network_span_forwarding !== undefined) {\n parsed.networkSpansForwardingThreshold =\n remoteConfig.network_span_forwarding.pct_enabled;\n }\n\n if (remoteConfig.empty_session_avoidance_enabled_pct !== undefined) {\n parsed.emptySessionAvoidanceEnabledPct =\n remoteConfig.empty_session_avoidance_enabled_pct;\n }\n\n if (\n remoteConfig.service_name !== undefined &&\n remoteConfig.service_name !== ''\n ) {\n parsed.serviceName = remoteConfig.service_name;\n }\n\n return parsed;\n};\n\nexport class MXLDynamicConfigManager implements DynamicConfigManager {\n // Set to null if appID is not provided, in that case only rely on local config\n private readonly _remoteConfigURL: string | null = null;\n private readonly _diag: DiagLogger;\n private readonly _storage: Storage;\n /** Defaults + user's `dynamicSDKConfig` / init-time merge; survives remote refresh merges. */\n private readonly _baseConfig: DynamicSDKConfig;\n\n private _sdkConfig: DynamicSDKConfig;\n private _etag: string | null = null;\n /** Non-empty `service_name` from the last persisted or fetched remote payload (if any). */\n private _remoteSourceServiceName: string | undefined;\n\n public constructor({\n appID,\n appVersion,\n deviceId,\n diag: diagParam = diag.createComponentLogger({\n namespace: 'mxl-config-manager',\n }),\n storage = window.localStorage,\n defaultConfig = {},\n mxlConfigURL,\n }: MXLDynamicConfigManagerArgs = {}) {\n if (appID && appVersion && deviceId) {\n this._remoteConfigURL = getConfigURL(\n appID,\n {\n appVersion,\n deviceId,\n // TODO: Replace with actual OS version once we start capturing it\n osVersion: '1',\n },\n mxlConfigURL,\n );\n }\n\n this._diag = diagParam;\n this._storage = storage;\n\n const storedRemoteConfig = this._getRemoteConfigFromStorage();\n\n if (storedRemoteConfig) {\n this._etag = storedRemoteConfig.etag;\n this._captureRemoteServiceName(storedRemoteConfig.config);\n }\n\n // Default config merged with any user-provided defaults; user-provided values take precedence.\n // Kept around so refreshRemoteConfig can re-merge against it instead of dropping defaults.\n this._baseConfig = {\n ...DEFAULT_CONFIG,\n ...defaultConfig,\n };\n\n this._sdkConfig = {\n ...this._baseConfig,\n // Stored remote config values will override both defaults and user-provided defaults\n ...(storedRemoteConfig\n ? parseRemoteConfig(storedRemoteConfig.config)\n : {}),\n };\n }\n\n public setConfig(config: Partial<DynamicSDKConfig>): void {\n this._sdkConfig = {\n ...this._sdkConfig,\n ...config,\n };\n }\n\n public getConfig(): DynamicSDKConfig {\n return this._sdkConfig;\n }\n\n /**\n * OpenTelemetry `service.name`: remote `service_name` wins, then explicit init `serviceName`,\n * then bootstrap {@link DynamicSDKConfig.serviceName}, then `unknown_service`.\n */\n public resolveApplicationServiceName(initServiceName?: string): string {\n const remote = this._remoteSourceServiceName?.trim();\n if (remote) {\n return remote;\n }\n const fromInit = initServiceName?.trim();\n if (fromInit) {\n return fromInit;\n }\n const fromBootstrap = this._baseConfig.serviceName?.trim();\n if (fromBootstrap) {\n return fromBootstrap;\n }\n return OTEL_DEFAULT_SERVICE_NAME;\n }\n\n private _captureRemoteServiceName(raw: RemoteConfig): void {\n if (raw.service_name === undefined) {\n return;\n }\n const sn = raw.service_name.trim();\n this._remoteSourceServiceName = sn.length > 0 ? sn : undefined;\n }\n\n // No-op if not sending data to mxl\n public async refreshRemoteConfig(): Promise<void> {\n if (!this._remoteConfigURL) {\n return;\n }\n\n try {\n const remoteConfigResponse = await this._fetchRemoteConfig(\n this._remoteConfigURL,\n );\n\n if (!remoteConfigResponse) {\n this._diag.debug('No changes in remote config, skipping update');\n return;\n }\n\n const [remoteConfig, etag] = remoteConfigResponse;\n this._captureRemoteServiceName(remoteConfig);\n this._storage.setItem(\n LOCAL_STORAGE_REMOTE_CONFIG_KEY,\n JSON.stringify({\n config: remoteConfig,\n etag,\n } as StoredRemoteConfig),\n );\n\n this._sdkConfig = {\n ...this._baseConfig,\n ...parseRemoteConfig(remoteConfig),\n };\n this._etag = etag;\n } catch (error: unknown) {\n this._diag.warn(\n `Failed to refresh remote config: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n\n private _getRemoteConfigFromStorage(): StoredRemoteConfig | null {\n try {\n const configString = this._storage.getItem(\n LOCAL_STORAGE_REMOTE_CONFIG_KEY,\n );\n\n if (configString) {\n return JSON.parse(configString) as StoredRemoteConfig;\n }\n\n return null;\n } catch (error) {\n this._diag.warn(\n `Failed to parse remote config from storage: ${error instanceof Error ? error.message : String(error)}`,\n );\n\n return null;\n }\n }\n\n private async _fetchRemoteConfig(\n url: string,\n ): Promise<[RemoteConfig, string | null] | null> {\n const response = await fetch(url, {\n headers: this._etag ? { 'If-None-Match': this._etag } : {},\n });\n\n const etag = response.headers.get('etag');\n\n // Nothing changed, return null\n if (response.status === 304) {\n return null;\n }\n\n if (!response.ok) {\n this._diag.warn(\n `Failed to fetch remote config from ${url}: ${response.statusText}`,\n );\n\n return null;\n }\n\n const remoteConfig = (await response.json()) as RemoteConfig;\n\n return [remoteConfig, etag];\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"MXLDynamicConfigManager.cjs","names":["diag","getConfigURL","DEFAULT_CONFIG","OTEL_DEFAULT_SERVICE_NAME","LOCAL_STORAGE_REMOTE_CONFIG_KEY"],"sources":["../../../src/managers/MXLConfigManager/MXLDynamicConfigManager.ts"],"sourcesContent":["import type { DiagLogger } from '@opentelemetry/api';\nimport { diag } from '@opentelemetry/api';\nimport { OTEL_DEFAULT_SERVICE_NAME } from '../../resources/webSdkResource';\nimport type { DynamicConfigManager, DynamicSDKConfig } from '../../sdk';\nimport { DEFAULT_CONFIG, LOCAL_STORAGE_REMOTE_CONFIG_KEY } from './constants';\nimport type {\n MXLDynamicConfigManagerArgs,\n RemoteConfig,\n StoredRemoteConfig,\n} from './types';\nimport { getConfigURL } from './utils';\n\nconst parseRemoteConfig = (remoteConfig: RemoteConfig): DynamicSDKConfig => {\n const parsed: DynamicSDKConfig = {\n samplingPct: remoteConfig.threshold,\n };\n\n if (remoteConfig.network_span_forwarding !== undefined) {\n parsed.networkSpansForwardingThreshold =\n remoteConfig.network_span_forwarding.pct_enabled;\n }\n\n if (remoteConfig.empty_session_avoidance_enabled_pct !== undefined) {\n parsed.emptySessionAvoidanceEnabledPct =\n remoteConfig.empty_session_avoidance_enabled_pct;\n }\n\n if (\n remoteConfig.service_name !== undefined &&\n remoteConfig.service_name !== ''\n ) {\n parsed.serviceName = remoteConfig.service_name;\n }\n\n return parsed;\n};\n\nexport class MXLDynamicConfigManager implements DynamicConfigManager {\n // Set to null if appID is not provided, in that case only rely on local config\n private readonly _remoteConfigURL: string | null = null;\n private readonly _diag: DiagLogger;\n private readonly _storage: Storage;\n /** Defaults + user's `dynamicSDKConfig` / init-time merge; survives remote refresh merges. */\n private readonly _baseConfig: DynamicSDKConfig;\n\n private _sdkConfig: DynamicSDKConfig;\n private _etag: string | null = null;\n /** Non-empty `service_name` from the last persisted or fetched remote payload (if any). */\n private _remoteSourceServiceName: string | undefined;\n\n public constructor({\n appID,\n appVersion,\n deviceId,\n diag: diagParam = diag.createComponentLogger({\n namespace: 'mxl-config-manager',\n }),\n storage = window.localStorage,\n defaultConfig = {},\n mxlConfigURL,\n }: MXLDynamicConfigManagerArgs = {}) {\n if (appID && appVersion && deviceId) {\n this._remoteConfigURL = getConfigURL(\n appID,\n {\n appVersion,\n deviceId,\n // TODO: Replace with actual OS version once we start capturing it\n osVersion: '1',\n },\n mxlConfigURL,\n );\n }\n\n this._diag = diagParam;\n this._storage = storage;\n\n const storedRemoteConfig = this._getRemoteConfigFromStorage();\n\n if (storedRemoteConfig) {\n this._etag = storedRemoteConfig.etag;\n this._captureRemoteServiceName(storedRemoteConfig.config);\n }\n\n // Default config merged with any user-provided defaults; user-provided values take precedence.\n // Kept around so refreshRemoteConfig can re-merge against it instead of dropping defaults.\n this._baseConfig = {\n ...DEFAULT_CONFIG,\n ...defaultConfig,\n };\n\n this._sdkConfig = {\n ...this._baseConfig,\n // Stored remote config values will override both defaults and user-provided defaults\n ...(storedRemoteConfig\n ? parseRemoteConfig(storedRemoteConfig.config)\n : {}),\n };\n }\n\n public setConfig(config: Partial<DynamicSDKConfig>): void {\n this._sdkConfig = {\n ...this._sdkConfig,\n ...config,\n };\n }\n\n public getConfig(): DynamicSDKConfig {\n return this._sdkConfig;\n }\n\n /**\n * OpenTelemetry `service.name`: remote `service_name` wins, then explicit init `serviceName`,\n * then bootstrap {@link DynamicSDKConfig.serviceName}, then `unknown_service`.\n */\n public resolveApplicationServiceName(initServiceName?: string): string {\n const remote = this._remoteSourceServiceName?.trim();\n if (remote) {\n return remote;\n }\n const fromInit = initServiceName?.trim();\n if (fromInit) {\n return fromInit;\n }\n const fromBootstrap = this._baseConfig.serviceName?.trim();\n if (fromBootstrap) {\n return fromBootstrap;\n }\n return OTEL_DEFAULT_SERVICE_NAME;\n }\n\n private _captureRemoteServiceName(raw: RemoteConfig): void {\n if (raw.service_name === undefined) {\n return;\n }\n const sn = raw.service_name.trim();\n this._remoteSourceServiceName = sn.length > 0 ? sn : undefined;\n }\n\n // No-op if not sending data to mxl\n public async refreshRemoteConfig(): Promise<void> {\n if (!this._remoteConfigURL) {\n return;\n }\n\n try {\n const remoteConfigResponse = await this._fetchRemoteConfig(\n this._remoteConfigURL,\n );\n\n if (!remoteConfigResponse) {\n this._diag.debug('No changes in remote config, skipping update');\n return;\n }\n\n const [remoteConfig, etag] = remoteConfigResponse;\n this._captureRemoteServiceName(remoteConfig);\n this._storage.setItem(\n LOCAL_STORAGE_REMOTE_CONFIG_KEY,\n JSON.stringify({\n config: remoteConfig,\n etag,\n } as StoredRemoteConfig),\n );\n\n this._sdkConfig = {\n ...this._baseConfig,\n ...parseRemoteConfig(remoteConfig),\n };\n this._etag = etag;\n } catch (error: unknown) {\n this._diag.warn(\n `Failed to refresh remote config: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n\n private _getRemoteConfigFromStorage(): StoredRemoteConfig | null {\n try {\n const configString = this._storage.getItem(\n LOCAL_STORAGE_REMOTE_CONFIG_KEY,\n );\n\n if (configString) {\n return JSON.parse(configString) as StoredRemoteConfig;\n }\n\n return null;\n } catch (error) {\n this._diag.warn(\n `Failed to parse remote config from storage: ${error instanceof Error ? error.message : String(error)}`,\n );\n\n return null;\n }\n }\n\n private async _fetchRemoteConfig(\n url: string,\n ): Promise<[RemoteConfig, string | null] | null> {\n const response = await fetch(url, {\n headers: this._etag ? { 'If-None-Match': this._etag } : {},\n });\n\n const etag = response.headers.get('etag');\n\n // Nothing changed, return null\n if (response.status === 304) {\n return null;\n }\n\n if (!response.ok) {\n this._diag.warn(\n `Failed to fetch remote config from ${url}: ${response.statusText}`,\n );\n\n return null;\n }\n\n const remoteConfig = (await response.json()) as RemoteConfig;\n\n return [remoteConfig, etag];\n }\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"MXLDynamicConfigManager.d.cts","names":[],"sources":["../../../src/managers/MXLConfigManager/MXLDynamicConfigManager.ts"],"mappings":";;;;cA2Ca,uBAAA,YAAmC,oBAAA;EAAA,iBAE7B,gBAAA;EAAA,iBACA,KAAA;EAAA,iBACA,QAAA;EAJkB;EAAA,iBAMlB,WAAA;EAAA,QAET,UAAA;EAAA,QACA,KAAA;EAON;EAAA,QALM,wBAAA;;IAGN,KAAA;IACA,UAAA;IACA,QAAA;IACA,IAAA,EAAM,SAAA;IAGN,OAAA;IACA,aAAA;IACA;EAAA,IACC,2BAAA;EAwCI,SAAA,CAAU,MAAA,EAAQ,OAAA,CAAQ,gBAAA;EAO1B,SAAA,CAAA,GAAa,gBAAA;EA/CjB;;;;EAuDI,6BAAA,CAA8B,eAAA;EAAA,QAgB7B,yBAAA;EASK,mBAAA,CAAA,GAAuB,OAAA;EAAA,QAqC5B,2BAAA;EAAA,QAoBM,kBAAA;AAAA"}
1
+ {"version":3,"file":"MXLDynamicConfigManager.d.cts","names":[],"sources":["../../../src/managers/MXLConfigManager/MXLDynamicConfigManager.ts"],"mappings":";;;;cAqCa,uBAAA,YAAmC,oBAAA;EAAA,iBAE7B,gBAAA;EAAA,iBACA,KAAA;EAAA,iBACA,QAAA;EAJkB;EAAA,iBAMlB,WAAA;EAAA,QAET,UAAA;EAAA,QACA,KAAA;EAON;EAAA,QALM,wBAAA;;IAGN,KAAA;IACA,UAAA;IACA,QAAA;IACA,IAAA,EAAM,SAAA;IAGN,OAAA;IACA,aAAA;IACA;EAAA,IACC,2BAAA;EAwCI,SAAA,CAAU,MAAA,EAAQ,OAAA,CAAQ,gBAAA;EAO1B,SAAA,CAAA,GAAa,gBAAA;EA/CjB;;;;EAuDI,6BAAA,CAA8B,eAAA;EAAA,QAgB7B,yBAAA;EASK,mBAAA,CAAA,GAAuB,OAAA;EAAA,QAqC5B,2BAAA;EAAA,QAoBM,kBAAA;AAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"MXLDynamicConfigManager.d.ts","names":[],"sources":["../../../src/managers/MXLConfigManager/MXLDynamicConfigManager.ts"],"mappings":";;;;cA2Ca,uBAAA,YAAmC,oBAAA;EAAA,iBAE7B,gBAAA;EAAA,iBACA,KAAA;EAAA,iBACA,QAAA;EAJkB;EAAA,iBAMlB,WAAA;EAAA,QAET,UAAA;EAAA,QACA,KAAA;EAON;EAAA,QALM,wBAAA;;IAGN,KAAA;IACA,UAAA;IACA,QAAA;IACA,IAAA,EAAM,SAAA;IAGN,OAAA;IACA,aAAA;IACA;EAAA,IACC,2BAAA;EAwCI,SAAA,CAAU,MAAA,EAAQ,OAAA,CAAQ,gBAAA;EAO1B,SAAA,CAAA,GAAa,gBAAA;EA/CjB;;;;EAuDI,6BAAA,CAA8B,eAAA;EAAA,QAgB7B,yBAAA;EASK,mBAAA,CAAA,GAAuB,OAAA;EAAA,QAqC5B,2BAAA;EAAA,QAoBM,kBAAA;AAAA"}
1
+ {"version":3,"file":"MXLDynamicConfigManager.d.ts","names":[],"sources":["../../../src/managers/MXLConfigManager/MXLDynamicConfigManager.ts"],"mappings":";;;;cAqCa,uBAAA,YAAmC,oBAAA;EAAA,iBAE7B,gBAAA;EAAA,iBACA,KAAA;EAAA,iBACA,QAAA;EAJkB;EAAA,iBAMlB,WAAA;EAAA,QAET,UAAA;EAAA,QACA,KAAA;EAON;EAAA,QALM,wBAAA;;IAGN,KAAA;IACA,UAAA;IACA,QAAA;IACA,IAAA,EAAM,SAAA;IAGN,OAAA;IACA,aAAA;IACA;EAAA,IACC,2BAAA;EAwCI,SAAA,CAAU,MAAA,EAAQ,OAAA,CAAQ,gBAAA;EAO1B,SAAA,CAAA,GAAa,gBAAA;EA/CjB;;;;EAuDI,6BAAA,CAA8B,eAAA;EAAA,QAgB7B,yBAAA;EASK,mBAAA,CAAA,GAAuB,OAAA;EAAA,QAqC5B,2BAAA;EAAA,QAoBM,kBAAA;AAAA"}
@@ -1,5 +1,5 @@
1
- import { DEFAULT_CONFIG, LOCAL_STORAGE_REMOTE_CONFIG_KEY } from "./constants.js";
2
1
  import { OTEL_DEFAULT_SERVICE_NAME } from "../../resources/webSdkResource.js";
2
+ import { DEFAULT_CONFIG, LOCAL_STORAGE_REMOTE_CONFIG_KEY } from "./constants.js";
3
3
  import { getConfigURL } from "./utils.js";
4
4
  import { diag } from "@opentelemetry/api";
5
5
  //#region src/managers/MXLConfigManager/MXLDynamicConfigManager.ts
@@ -1 +1 @@
1
- {"version":3,"file":"MXLDynamicConfigManager.js","names":[],"sources":["../../../src/managers/MXLConfigManager/MXLDynamicConfigManager.ts"],"sourcesContent":["import type { DiagLogger } from '@opentelemetry/api';\nimport { diag } from '@opentelemetry/api';\nimport type {\n DynamicConfigManager,\n DynamicSDKConfig,\n} from '../../sdk/index.ts';\nimport {\n DEFAULT_CONFIG,\n LOCAL_STORAGE_REMOTE_CONFIG_KEY,\n} from './constants.ts';\nimport { OTEL_DEFAULT_SERVICE_NAME } from '../../resources/webSdkResource.ts';\nimport type {\n MXLDynamicConfigManagerArgs,\n RemoteConfig,\n StoredRemoteConfig,\n} from './types.ts';\nimport { getConfigURL } from './utils.ts';\n\nconst parseRemoteConfig = (remoteConfig: RemoteConfig): DynamicSDKConfig => {\n const parsed: DynamicSDKConfig = {\n samplingPct: remoteConfig.threshold,\n };\n\n if (remoteConfig.network_span_forwarding !== undefined) {\n parsed.networkSpansForwardingThreshold =\n remoteConfig.network_span_forwarding.pct_enabled;\n }\n\n if (remoteConfig.empty_session_avoidance_enabled_pct !== undefined) {\n parsed.emptySessionAvoidanceEnabledPct =\n remoteConfig.empty_session_avoidance_enabled_pct;\n }\n\n if (\n remoteConfig.service_name !== undefined &&\n remoteConfig.service_name !== ''\n ) {\n parsed.serviceName = remoteConfig.service_name;\n }\n\n return parsed;\n};\n\nexport class MXLDynamicConfigManager implements DynamicConfigManager {\n // Set to null if appID is not provided, in that case only rely on local config\n private readonly _remoteConfigURL: string | null = null;\n private readonly _diag: DiagLogger;\n private readonly _storage: Storage;\n /** Defaults + user's `dynamicSDKConfig` / init-time merge; survives remote refresh merges. */\n private readonly _baseConfig: DynamicSDKConfig;\n\n private _sdkConfig: DynamicSDKConfig;\n private _etag: string | null = null;\n /** Non-empty `service_name` from the last persisted or fetched remote payload (if any). */\n private _remoteSourceServiceName: string | undefined;\n\n public constructor({\n appID,\n appVersion,\n deviceId,\n diag: diagParam = diag.createComponentLogger({\n namespace: 'mxl-config-manager',\n }),\n storage = window.localStorage,\n defaultConfig = {},\n mxlConfigURL,\n }: MXLDynamicConfigManagerArgs = {}) {\n if (appID && appVersion && deviceId) {\n this._remoteConfigURL = getConfigURL(\n appID,\n {\n appVersion,\n deviceId,\n // TODO: Replace with actual OS version once we start capturing it\n osVersion: '1',\n },\n mxlConfigURL,\n );\n }\n\n this._diag = diagParam;\n this._storage = storage;\n\n const storedRemoteConfig = this._getRemoteConfigFromStorage();\n\n if (storedRemoteConfig) {\n this._etag = storedRemoteConfig.etag;\n this._captureRemoteServiceName(storedRemoteConfig.config);\n }\n\n // Default config merged with any user-provided defaults; user-provided values take precedence.\n // Kept around so refreshRemoteConfig can re-merge against it instead of dropping defaults.\n this._baseConfig = {\n ...DEFAULT_CONFIG,\n ...defaultConfig,\n };\n\n this._sdkConfig = {\n ...this._baseConfig,\n // Stored remote config values will override both defaults and user-provided defaults\n ...(storedRemoteConfig\n ? parseRemoteConfig(storedRemoteConfig.config)\n : {}),\n };\n }\n\n public setConfig(config: Partial<DynamicSDKConfig>): void {\n this._sdkConfig = {\n ...this._sdkConfig,\n ...config,\n };\n }\n\n public getConfig(): DynamicSDKConfig {\n return this._sdkConfig;\n }\n\n /**\n * OpenTelemetry `service.name`: remote `service_name` wins, then explicit init `serviceName`,\n * then bootstrap {@link DynamicSDKConfig.serviceName}, then `unknown_service`.\n */\n public resolveApplicationServiceName(initServiceName?: string): string {\n const remote = this._remoteSourceServiceName?.trim();\n if (remote) {\n return remote;\n }\n const fromInit = initServiceName?.trim();\n if (fromInit) {\n return fromInit;\n }\n const fromBootstrap = this._baseConfig.serviceName?.trim();\n if (fromBootstrap) {\n return fromBootstrap;\n }\n return OTEL_DEFAULT_SERVICE_NAME;\n }\n\n private _captureRemoteServiceName(raw: RemoteConfig): void {\n if (raw.service_name === undefined) {\n return;\n }\n const sn = raw.service_name.trim();\n this._remoteSourceServiceName = sn.length > 0 ? sn : undefined;\n }\n\n // No-op if not sending data to mxl\n public async refreshRemoteConfig(): Promise<void> {\n if (!this._remoteConfigURL) {\n return;\n }\n\n try {\n const remoteConfigResponse = await this._fetchRemoteConfig(\n this._remoteConfigURL,\n );\n\n if (!remoteConfigResponse) {\n this._diag.debug('No changes in remote config, skipping update');\n return;\n }\n\n const [remoteConfig, etag] = remoteConfigResponse;\n this._captureRemoteServiceName(remoteConfig);\n this._storage.setItem(\n LOCAL_STORAGE_REMOTE_CONFIG_KEY,\n JSON.stringify({\n config: remoteConfig,\n etag,\n } as StoredRemoteConfig),\n );\n\n this._sdkConfig = {\n ...this._baseConfig,\n ...parseRemoteConfig(remoteConfig),\n };\n this._etag = etag;\n } catch (error: unknown) {\n this._diag.warn(\n `Failed to refresh remote config: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n\n private _getRemoteConfigFromStorage(): StoredRemoteConfig | null {\n try {\n const configString = this._storage.getItem(\n LOCAL_STORAGE_REMOTE_CONFIG_KEY,\n );\n\n if (configString) {\n return JSON.parse(configString) as StoredRemoteConfig;\n }\n\n return null;\n } catch (error) {\n this._diag.warn(\n `Failed to parse remote config from storage: ${error instanceof Error ? error.message : String(error)}`,\n );\n\n return null;\n }\n }\n\n private async _fetchRemoteConfig(\n url: string,\n ): Promise<[RemoteConfig, string | null] | null> {\n const response = await fetch(url, {\n headers: this._etag ? { 'If-None-Match': this._etag } : {},\n });\n\n const etag = response.headers.get('etag');\n\n // Nothing changed, return null\n if (response.status === 304) {\n return null;\n }\n\n if (!response.ok) {\n this._diag.warn(\n `Failed to fetch remote config from ${url}: ${response.statusText}`,\n );\n\n return null;\n }\n\n const remoteConfig = (await response.json()) as RemoteConfig;\n\n return [remoteConfig, etag];\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"MXLDynamicConfigManager.js","names":[],"sources":["../../../src/managers/MXLConfigManager/MXLDynamicConfigManager.ts"],"sourcesContent":["import type { DiagLogger } from '@opentelemetry/api';\nimport { diag } from '@opentelemetry/api';\nimport { OTEL_DEFAULT_SERVICE_NAME } from '../../resources/webSdkResource';\nimport type { DynamicConfigManager, DynamicSDKConfig } from '../../sdk';\nimport { DEFAULT_CONFIG, LOCAL_STORAGE_REMOTE_CONFIG_KEY } from './constants';\nimport type {\n MXLDynamicConfigManagerArgs,\n RemoteConfig,\n StoredRemoteConfig,\n} from './types';\nimport { getConfigURL } from './utils';\n\nconst parseRemoteConfig = (remoteConfig: RemoteConfig): DynamicSDKConfig => {\n const parsed: DynamicSDKConfig = {\n samplingPct: remoteConfig.threshold,\n };\n\n if (remoteConfig.network_span_forwarding !== undefined) {\n parsed.networkSpansForwardingThreshold =\n remoteConfig.network_span_forwarding.pct_enabled;\n }\n\n if (remoteConfig.empty_session_avoidance_enabled_pct !== undefined) {\n parsed.emptySessionAvoidanceEnabledPct =\n remoteConfig.empty_session_avoidance_enabled_pct;\n }\n\n if (\n remoteConfig.service_name !== undefined &&\n remoteConfig.service_name !== ''\n ) {\n parsed.serviceName = remoteConfig.service_name;\n }\n\n return parsed;\n};\n\nexport class MXLDynamicConfigManager implements DynamicConfigManager {\n // Set to null if appID is not provided, in that case only rely on local config\n private readonly _remoteConfigURL: string | null = null;\n private readonly _diag: DiagLogger;\n private readonly _storage: Storage;\n /** Defaults + user's `dynamicSDKConfig` / init-time merge; survives remote refresh merges. */\n private readonly _baseConfig: DynamicSDKConfig;\n\n private _sdkConfig: DynamicSDKConfig;\n private _etag: string | null = null;\n /** Non-empty `service_name` from the last persisted or fetched remote payload (if any). */\n private _remoteSourceServiceName: string | undefined;\n\n public constructor({\n appID,\n appVersion,\n deviceId,\n diag: diagParam = diag.createComponentLogger({\n namespace: 'mxl-config-manager',\n }),\n storage = window.localStorage,\n defaultConfig = {},\n mxlConfigURL,\n }: MXLDynamicConfigManagerArgs = {}) {\n if (appID && appVersion && deviceId) {\n this._remoteConfigURL = getConfigURL(\n appID,\n {\n appVersion,\n deviceId,\n // TODO: Replace with actual OS version once we start capturing it\n osVersion: '1',\n },\n mxlConfigURL,\n );\n }\n\n this._diag = diagParam;\n this._storage = storage;\n\n const storedRemoteConfig = this._getRemoteConfigFromStorage();\n\n if (storedRemoteConfig) {\n this._etag = storedRemoteConfig.etag;\n this._captureRemoteServiceName(storedRemoteConfig.config);\n }\n\n // Default config merged with any user-provided defaults; user-provided values take precedence.\n // Kept around so refreshRemoteConfig can re-merge against it instead of dropping defaults.\n this._baseConfig = {\n ...DEFAULT_CONFIG,\n ...defaultConfig,\n };\n\n this._sdkConfig = {\n ...this._baseConfig,\n // Stored remote config values will override both defaults and user-provided defaults\n ...(storedRemoteConfig\n ? parseRemoteConfig(storedRemoteConfig.config)\n : {}),\n };\n }\n\n public setConfig(config: Partial<DynamicSDKConfig>): void {\n this._sdkConfig = {\n ...this._sdkConfig,\n ...config,\n };\n }\n\n public getConfig(): DynamicSDKConfig {\n return this._sdkConfig;\n }\n\n /**\n * OpenTelemetry `service.name`: remote `service_name` wins, then explicit init `serviceName`,\n * then bootstrap {@link DynamicSDKConfig.serviceName}, then `unknown_service`.\n */\n public resolveApplicationServiceName(initServiceName?: string): string {\n const remote = this._remoteSourceServiceName?.trim();\n if (remote) {\n return remote;\n }\n const fromInit = initServiceName?.trim();\n if (fromInit) {\n return fromInit;\n }\n const fromBootstrap = this._baseConfig.serviceName?.trim();\n if (fromBootstrap) {\n return fromBootstrap;\n }\n return OTEL_DEFAULT_SERVICE_NAME;\n }\n\n private _captureRemoteServiceName(raw: RemoteConfig): void {\n if (raw.service_name === undefined) {\n return;\n }\n const sn = raw.service_name.trim();\n this._remoteSourceServiceName = sn.length > 0 ? sn : undefined;\n }\n\n // No-op if not sending data to mxl\n public async refreshRemoteConfig(): Promise<void> {\n if (!this._remoteConfigURL) {\n return;\n }\n\n try {\n const remoteConfigResponse = await this._fetchRemoteConfig(\n this._remoteConfigURL,\n );\n\n if (!remoteConfigResponse) {\n this._diag.debug('No changes in remote config, skipping update');\n return;\n }\n\n const [remoteConfig, etag] = remoteConfigResponse;\n this._captureRemoteServiceName(remoteConfig);\n this._storage.setItem(\n LOCAL_STORAGE_REMOTE_CONFIG_KEY,\n JSON.stringify({\n config: remoteConfig,\n etag,\n } as StoredRemoteConfig),\n );\n\n this._sdkConfig = {\n ...this._baseConfig,\n ...parseRemoteConfig(remoteConfig),\n };\n this._etag = etag;\n } catch (error: unknown) {\n this._diag.warn(\n `Failed to refresh remote config: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n\n private _getRemoteConfigFromStorage(): StoredRemoteConfig | null {\n try {\n const configString = this._storage.getItem(\n LOCAL_STORAGE_REMOTE_CONFIG_KEY,\n );\n\n if (configString) {\n return JSON.parse(configString) as StoredRemoteConfig;\n }\n\n return null;\n } catch (error) {\n this._diag.warn(\n `Failed to parse remote config from storage: ${error instanceof Error ? error.message : String(error)}`,\n );\n\n return null;\n }\n }\n\n private async _fetchRemoteConfig(\n url: string,\n ): Promise<[RemoteConfig, string | null] | null> {\n const response = await fetch(url, {\n headers: this._etag ? { 'If-None-Match': this._etag } : {},\n });\n\n const etag = response.headers.get('etag');\n\n // Nothing changed, return null\n if (response.status === 304) {\n return null;\n }\n\n if (!response.ok) {\n this._diag.warn(\n `Failed to fetch remote config from ${url}: ${response.statusText}`,\n );\n\n return null;\n }\n\n const remoteConfig = (await response.json()) as RemoteConfig;\n\n return [remoteConfig, etag];\n }\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"constants.cjs","names":[],"sources":["../../../src/managers/MXLConfigManager/constants.ts"],"sourcesContent":["import type { DynamicSDKConfig } from '../../sdk/index.ts';\n\nexport const DEFAULT_CONFIG: DynamicSDKConfig = {\n samplingPct: 100,\n networkSpansForwardingThreshold: 0,\n};\n\nexport const LOCAL_STORAGE_REMOTE_CONFIG_KEY = 'mxl_remote_config';\n"],"mappings":";;AAEA,MAAa,iBAAmC;CAC9C,aAAa;CACb,iCAAiC;CAClC;AAED,MAAa,kCAAkC"}
1
+ {"version":3,"file":"constants.cjs","names":[],"sources":["../../../src/managers/MXLConfigManager/constants.ts"],"sourcesContent":["import type { DynamicSDKConfig } from '../../sdk';\n\nexport const DEFAULT_CONFIG: DynamicSDKConfig = {\n samplingPct: 100,\n networkSpansForwardingThreshold: 0,\n};\n\nexport const LOCAL_STORAGE_REMOTE_CONFIG_KEY = 'mxl_remote_config';\n"],"mappings":";;AAEA,MAAa,iBAAmC;CAC9C,aAAa;CACb,iCAAiC;CAClC;AAED,MAAa,kCAAkC"}
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","names":[],"sources":["../../../src/managers/MXLConfigManager/constants.ts"],"sourcesContent":["import type { DynamicSDKConfig } from '../../sdk/index.ts';\n\nexport const DEFAULT_CONFIG: DynamicSDKConfig = {\n samplingPct: 100,\n networkSpansForwardingThreshold: 0,\n};\n\nexport const LOCAL_STORAGE_REMOTE_CONFIG_KEY = 'mxl_remote_config';\n"],"mappings":";AAEA,MAAa,iBAAmC;CAC9C,aAAa;CACb,iCAAiC;CAClC;AAED,MAAa,kCAAkC"}
1
+ {"version":3,"file":"constants.js","names":[],"sources":["../../../src/managers/MXLConfigManager/constants.ts"],"sourcesContent":["import type { DynamicSDKConfig } from '../../sdk';\n\nexport const DEFAULT_CONFIG: DynamicSDKConfig = {\n samplingPct: 100,\n networkSpansForwardingThreshold: 0,\n};\n\nexport const LOCAL_STORAGE_REMOTE_CONFIG_KEY = 'mxl_remote_config';\n"],"mappings":";AAEA,MAAa,iBAAmC;CAC9C,aAAa;CACb,iCAAiC;CAClC;AAED,MAAa,kCAAkC"}
@@ -1 +1 @@
1
- {"version":3,"file":"utils.cjs","names":[],"sources":["../../../src/managers/MXLConfigManager/utils.ts"],"sourcesContent":["import type { RemoteConfigURLParams } from './types.ts';\n\nexport const getConfigURL = (\n appId: string,\n { osVersion, appVersion, deviceId }: RemoteConfigURLParams,\n mxlConfigURL?: string,\n): string =>\n `${mxlConfigURL || `https://mxl-basket.apps.ocpthikadev01.safaricom.net`}/config?appId=${appId}&osVersion=${osVersion}&appVersion=${appVersion}&deviceId=${deviceId}`;\n"],"mappings":";;AAEA,MAAa,gBACX,OACA,EAAE,WAAW,YAAY,YACzB,iBAEA,GAAG,gBAAgB,sDAAsD,gBAAgB,MAAM,aAAa,UAAU,cAAc,WAAW,YAAY"}
1
+ {"version":3,"file":"utils.cjs","names":[],"sources":["../../../src/managers/MXLConfigManager/utils.ts"],"sourcesContent":["import type { RemoteConfigURLParams } from './types';\n\nexport const getConfigURL = (\n appId: string,\n { osVersion, appVersion, deviceId }: RemoteConfigURLParams,\n mxlConfigURL?: string,\n): string =>\n `${mxlConfigURL || `https://mxl-basket.apps.ocpthikadev01.safaricom.net`}/config?appId=${appId}&osVersion=${osVersion}&appVersion=${appVersion}&deviceId=${deviceId}`;\n"],"mappings":";;AAEA,MAAa,gBACX,OACA,EAAE,WAAW,YAAY,YACzB,iBAEA,GAAG,gBAAgB,sDAAsD,gBAAgB,MAAM,aAAa,UAAU,cAAc,WAAW,YAAY"}
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","names":[],"sources":["../../../src/managers/MXLConfigManager/utils.ts"],"sourcesContent":["import type { RemoteConfigURLParams } from './types.ts';\n\nexport const getConfigURL = (\n appId: string,\n { osVersion, appVersion, deviceId }: RemoteConfigURLParams,\n mxlConfigURL?: string,\n): string =>\n `${mxlConfigURL || `https://mxl-basket.apps.ocpthikadev01.safaricom.net`}/config?appId=${appId}&osVersion=${osVersion}&appVersion=${appVersion}&deviceId=${deviceId}`;\n"],"mappings":";AAEA,MAAa,gBACX,OACA,EAAE,WAAW,YAAY,YACzB,iBAEA,GAAG,gBAAgB,sDAAsD,gBAAgB,MAAM,aAAa,UAAU,cAAc,WAAW,YAAY"}
1
+ {"version":3,"file":"utils.js","names":[],"sources":["../../../src/managers/MXLConfigManager/utils.ts"],"sourcesContent":["import type { RemoteConfigURLParams } from './types';\n\nexport const getConfigURL = (\n appId: string,\n { osVersion, appVersion, deviceId }: RemoteConfigURLParams,\n mxlConfigURL?: string,\n): string =>\n `${mxlConfigURL || `https://mxl-basket.apps.ocpthikadev01.safaricom.net`}/config?appId=${appId}&osVersion=${osVersion}&appVersion=${appVersion}&deviceId=${deviceId}`;\n"],"mappings":";AAEA,MAAa,gBACX,OACA,EAAE,WAAW,YAAY,YACzB,iBAEA,GAAG,gBAAgB,sDAAsD,gBAAgB,MAAM,aAAa,UAAU,cAAc,WAAW,YAAY"}
@@ -1 +1 @@
1
- {"version":3,"file":"MXLLimitManager.cjs","names":["diag"],"sources":["../../../src/managers/MXLLimitManager/MXLLimitManager.ts"],"sourcesContent":["import type { AttributeValue, DiagLogger } from '@opentelemetry/api';\nimport { diag } from '@opentelemetry/api';\nimport type { ReadableSpan } from '@opentelemetry/sdk-trace-web';\nimport type { LogSeverity } from '../../api-logs/index.ts';\nimport { KEY_MXL_TYPE, MXL_TYPES } from '../../constants/index.ts';\nimport type {\n AttributeLimitedType,\n LengthLimitedType,\n LimitedBreadcrumb,\n LimitedException,\n LimitedLog,\n LimitedSessionProperty,\n LimitedType,\n LimitManagerInternal,\n LimitOperation,\n LogLimitedType,\n MaxLimitedType,\n MXLLimitManagerArgs,\n} from './types.ts';\n\nconst LogSeverityToLimitType: Record<LogSeverity, LogLimitedType> = {\n info: 'info_log',\n warning: 'warning_log',\n error: 'error_log',\n};\n\nexport class MXLLimitManager implements LimitManagerInternal {\n private readonly _diag: DiagLogger;\n\n private _diagnosticCounts: Record<string, number> = {};\n private _currentCount: Record<MaxLimitedType, number> = {\n exception: 0,\n error_log: 0,\n warning_log: 0,\n info_log: 0,\n breadcrumb: 0,\n session_property: 0,\n span: 0,\n network_request: 0,\n element_timing: 0,\n server_timing: 0,\n user_timing_mark: 0,\n user_timing_measure: 0,\n };\n private readonly _maxAllowed: Record<MaxLimitedType, number>;\n private readonly _maxLength: Record<LengthLimitedType, number>;\n private readonly _maxAttributes: Record<AttributeLimitedType, number>;\n\n public constructor({\n diag: diagParam,\n maxAllowed,\n maxLength,\n maxAttributes,\n }: MXLLimitManagerArgs) {\n this._diag =\n diagParam ??\n diag.createComponentLogger({\n namespace: 'MXLLimitManager',\n });\n\n this._maxAllowed = maxAllowed;\n this._maxLength = maxLength;\n this._maxAttributes = maxAttributes;\n }\n\n private _dropIfMaxReached(type: MaxLimitedType): boolean {\n if (this._currentCount[type] >= this._maxAllowed[type]) {\n this._diag.warn(\n `disallowing ${type} because the maximum number of ${this._maxAllowed[type].toString()} has already been reached for this session`,\n );\n\n this._incrDiagnosticCount(type, 'drop');\n return true;\n }\n\n this._currentCount[type] = (this._currentCount[type] || 0) + 1;\n return false;\n }\n\n public truncateString(type: LengthLimitedType, body: string) {\n if (body.length > this._maxLength[type]) {\n this._diag.warn(\n `truncating ${type} because it is longer than ${this._maxLength[type].toString()} characters: \"${body}\"`,\n );\n\n this._incrDiagnosticCount(type, 'truncate_string');\n return body.substring(0, this._maxLength[type]);\n }\n\n return body;\n }\n\n private _truncateAttributes(\n type: AttributeLimitedType,\n attributes: Record<string, AttributeValue | undefined>,\n keyType: LengthLimitedType,\n valueType: LengthLimitedType,\n ) {\n const keys = Object.keys(attributes);\n\n if (keys.length > this._maxAttributes[type]) {\n this._diag.warn(\n `truncating ${type} attributes because there are more than ${this._maxAttributes[type].toString()} set`,\n );\n this._incrDiagnosticCount(type, 'truncate_attributes');\n }\n\n const truncatedAttributes: Record<string, AttributeValue | undefined> = {};\n\n for (let i = 0; i < Math.min(keys.length, this._maxAttributes[type]); i++) {\n const truncatedKey = this.truncateString(keyType, keys[i]);\n truncatedAttributes[truncatedKey] = this.truncateString(\n valueType,\n attributes[keys[i]]?.toString() || '',\n );\n }\n\n return truncatedAttributes;\n }\n\n public limitBreadcrumb(name: string): LimitedBreadcrumb | 'dropped' {\n if (this._dropIfMaxReached('breadcrumb')) {\n return 'dropped';\n }\n\n return {\n name: this.truncateString('breadcrumb', name),\n };\n }\n\n public limitException(\n message: string,\n attributes: Record<string, AttributeValue | undefined>,\n ): LimitedException | 'dropped' {\n if (this._dropIfMaxReached('exception')) {\n return 'dropped';\n }\n\n return {\n message: this.truncateString('exception', message),\n attributes: this._truncateAttributes(\n 'exception',\n attributes,\n 'exception_attribute_key',\n 'exception_attribute_value',\n ),\n };\n }\n\n public limitLog(\n message: string,\n severity: LogSeverity,\n attributes: Record<string, AttributeValue | undefined>,\n ): LimitedLog | 'dropped' {\n const logType = LogSeverityToLimitType[severity];\n\n if (this._dropIfMaxReached(logType)) {\n return 'dropped';\n }\n\n return {\n message: this.truncateString(logType, message),\n attributes: this._truncateAttributes(\n logType,\n attributes,\n 'log_attribute_key',\n 'log_attribute_value',\n ),\n };\n }\n\n public limitSessionProperty(\n key: string,\n value: string,\n ): LimitedSessionProperty | 'dropped' {\n if (this._dropIfMaxReached('session_property')) {\n return 'dropped';\n }\n\n return {\n key: this.truncateString('session_property_key', key),\n value: this.truncateString('session_property_value', value),\n };\n }\n\n public limitElementTimingEntry(): boolean {\n return this._dropIfMaxReached('element_timing');\n }\n\n public limitServerTimingEntry(): boolean {\n return this._dropIfMaxReached('server_timing');\n }\n\n public limitUserTimingEntry(entryType: 'mark' | 'measure'): boolean {\n return this._dropIfMaxReached(\n entryType === 'mark' ? 'user_timing_mark' : 'user_timing_measure',\n );\n }\n\n public dropReadableSpan(span: ReadableSpan): boolean {\n const type =\n span.attributes[KEY_MXL_TYPE] === MXL_TYPES.Network\n ? 'network_request'\n : 'span';\n\n return this._dropIfMaxReached(type);\n }\n\n public reset(): void {\n this._diagnosticCounts = {};\n this._currentCount = {\n exception: 0,\n error_log: 0,\n warning_log: 0,\n info_log: 0,\n breadcrumb: 0,\n session_property: 0,\n span: 0,\n network_request: 0,\n element_timing: 0,\n server_timing: 0,\n user_timing_mark: 0,\n user_timing_measure: 0,\n };\n }\n\n private _incrDiagnosticCount(type: LimitedType, operation: LimitOperation) {\n const key = `mxl.app.applied_limit.${type}.${operation}.count`;\n\n this._diagnosticCounts[key] = (this._diagnosticCounts[key] || 0) + 1;\n }\n public getDiagnosticCounts(): Record<string, number> {\n return this._diagnosticCounts;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"MXLLimitManager.cjs","names":["diag"],"sources":["../../../src/managers/MXLLimitManager/MXLLimitManager.ts"],"sourcesContent":["import type { AttributeValue, DiagLogger } from '@opentelemetry/api';\nimport { diag } from '@opentelemetry/api';\nimport type { ReadableSpan } from '@opentelemetry/sdk-trace-web';\nimport type { LogSeverity } from '../../api-logs';\nimport { KEY_MXL_TYPE, MXL_TYPES } from '../../constants';\nimport type {\n AttributeLimitedType,\n LengthLimitedType,\n LimitedBreadcrumb,\n LimitedException,\n LimitedLog,\n LimitedSessionProperty,\n LimitedType,\n LimitManagerInternal,\n LimitOperation,\n LogLimitedType,\n MaxLimitedType,\n MXLLimitManagerArgs,\n} from './types';\n\nconst LogSeverityToLimitType: Record<LogSeverity, LogLimitedType> = {\n info: 'info_log',\n warning: 'warning_log',\n error: 'error_log',\n};\n\nexport class MXLLimitManager implements LimitManagerInternal {\n private readonly _diag: DiagLogger;\n\n private _diagnosticCounts: Record<string, number> = {};\n private _currentCount: Record<MaxLimitedType, number> = {\n exception: 0,\n error_log: 0,\n warning_log: 0,\n info_log: 0,\n breadcrumb: 0,\n session_property: 0,\n span: 0,\n network_request: 0,\n element_timing: 0,\n server_timing: 0,\n user_timing_mark: 0,\n user_timing_measure: 0,\n };\n private readonly _maxAllowed: Record<MaxLimitedType, number>;\n private readonly _maxLength: Record<LengthLimitedType, number>;\n private readonly _maxAttributes: Record<AttributeLimitedType, number>;\n\n public constructor({\n diag: diagParam,\n maxAllowed,\n maxLength,\n maxAttributes,\n }: MXLLimitManagerArgs) {\n this._diag =\n diagParam ??\n diag.createComponentLogger({\n namespace: 'MXLLimitManager',\n });\n\n this._maxAllowed = maxAllowed;\n this._maxLength = maxLength;\n this._maxAttributes = maxAttributes;\n }\n\n private _dropIfMaxReached(type: MaxLimitedType): boolean {\n if (this._currentCount[type] >= this._maxAllowed[type]) {\n this._diag.warn(\n `disallowing ${type} because the maximum number of ${this._maxAllowed[type].toString()} has already been reached for this session`,\n );\n\n this._incrDiagnosticCount(type, 'drop');\n return true;\n }\n\n this._currentCount[type] = (this._currentCount[type] || 0) + 1;\n return false;\n }\n\n public truncateString(type: LengthLimitedType, body: string) {\n if (body.length > this._maxLength[type]) {\n this._diag.warn(\n `truncating ${type} because it is longer than ${this._maxLength[type].toString()} characters: \"${body}\"`,\n );\n\n this._incrDiagnosticCount(type, 'truncate_string');\n return body.substring(0, this._maxLength[type]);\n }\n\n return body;\n }\n\n private _truncateAttributes(\n type: AttributeLimitedType,\n attributes: Record<string, AttributeValue | undefined>,\n keyType: LengthLimitedType,\n valueType: LengthLimitedType,\n ) {\n const keys = Object.keys(attributes);\n\n if (keys.length > this._maxAttributes[type]) {\n this._diag.warn(\n `truncating ${type} attributes because there are more than ${this._maxAttributes[type].toString()} set`,\n );\n this._incrDiagnosticCount(type, 'truncate_attributes');\n }\n\n const truncatedAttributes: Record<string, AttributeValue | undefined> = {};\n\n for (let i = 0; i < Math.min(keys.length, this._maxAttributes[type]); i++) {\n const truncatedKey = this.truncateString(keyType, keys[i]);\n truncatedAttributes[truncatedKey] = this.truncateString(\n valueType,\n attributes[keys[i]]?.toString() || '',\n );\n }\n\n return truncatedAttributes;\n }\n\n public limitBreadcrumb(name: string): LimitedBreadcrumb | 'dropped' {\n if (this._dropIfMaxReached('breadcrumb')) {\n return 'dropped';\n }\n\n return {\n name: this.truncateString('breadcrumb', name),\n };\n }\n\n public limitException(\n message: string,\n attributes: Record<string, AttributeValue | undefined>,\n ): LimitedException | 'dropped' {\n if (this._dropIfMaxReached('exception')) {\n return 'dropped';\n }\n\n return {\n message: this.truncateString('exception', message),\n attributes: this._truncateAttributes(\n 'exception',\n attributes,\n 'exception_attribute_key',\n 'exception_attribute_value',\n ),\n };\n }\n\n public limitLog(\n message: string,\n severity: LogSeverity,\n attributes: Record<string, AttributeValue | undefined>,\n ): LimitedLog | 'dropped' {\n const logType = LogSeverityToLimitType[severity];\n\n if (this._dropIfMaxReached(logType)) {\n return 'dropped';\n }\n\n return {\n message: this.truncateString(logType, message),\n attributes: this._truncateAttributes(\n logType,\n attributes,\n 'log_attribute_key',\n 'log_attribute_value',\n ),\n };\n }\n\n public limitSessionProperty(\n key: string,\n value: string,\n ): LimitedSessionProperty | 'dropped' {\n if (this._dropIfMaxReached('session_property')) {\n return 'dropped';\n }\n\n return {\n key: this.truncateString('session_property_key', key),\n value: this.truncateString('session_property_value', value),\n };\n }\n\n public limitElementTimingEntry(): boolean {\n return this._dropIfMaxReached('element_timing');\n }\n\n public limitServerTimingEntry(): boolean {\n return this._dropIfMaxReached('server_timing');\n }\n\n public limitUserTimingEntry(entryType: 'mark' | 'measure'): boolean {\n return this._dropIfMaxReached(\n entryType === 'mark' ? 'user_timing_mark' : 'user_timing_measure',\n );\n }\n\n public dropReadableSpan(span: ReadableSpan): boolean {\n const type =\n span.attributes[KEY_MXL_TYPE] === MXL_TYPES.Network\n ? 'network_request'\n : 'span';\n\n return this._dropIfMaxReached(type);\n }\n\n public reset(): void {\n this._diagnosticCounts = {};\n this._currentCount = {\n exception: 0,\n error_log: 0,\n warning_log: 0,\n info_log: 0,\n breadcrumb: 0,\n session_property: 0,\n span: 0,\n network_request: 0,\n element_timing: 0,\n server_timing: 0,\n user_timing_mark: 0,\n user_timing_measure: 0,\n };\n }\n\n private _incrDiagnosticCount(type: LimitedType, operation: LimitOperation) {\n const key = `mxl.app.applied_limit.${type}.${operation}.count`;\n\n this._diagnosticCounts[key] = (this._diagnosticCounts[key] || 0) + 1;\n }\n public getDiagnosticCounts(): Record<string, number> {\n return this._diagnosticCounts;\n }\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"MXLLimitManager.js","names":[],"sources":["../../../src/managers/MXLLimitManager/MXLLimitManager.ts"],"sourcesContent":["import type { AttributeValue, DiagLogger } from '@opentelemetry/api';\nimport { diag } from '@opentelemetry/api';\nimport type { ReadableSpan } from '@opentelemetry/sdk-trace-web';\nimport type { LogSeverity } from '../../api-logs/index.ts';\nimport { KEY_MXL_TYPE, MXL_TYPES } from '../../constants/index.ts';\nimport type {\n AttributeLimitedType,\n LengthLimitedType,\n LimitedBreadcrumb,\n LimitedException,\n LimitedLog,\n LimitedSessionProperty,\n LimitedType,\n LimitManagerInternal,\n LimitOperation,\n LogLimitedType,\n MaxLimitedType,\n MXLLimitManagerArgs,\n} from './types.ts';\n\nconst LogSeverityToLimitType: Record<LogSeverity, LogLimitedType> = {\n info: 'info_log',\n warning: 'warning_log',\n error: 'error_log',\n};\n\nexport class MXLLimitManager implements LimitManagerInternal {\n private readonly _diag: DiagLogger;\n\n private _diagnosticCounts: Record<string, number> = {};\n private _currentCount: Record<MaxLimitedType, number> = {\n exception: 0,\n error_log: 0,\n warning_log: 0,\n info_log: 0,\n breadcrumb: 0,\n session_property: 0,\n span: 0,\n network_request: 0,\n element_timing: 0,\n server_timing: 0,\n user_timing_mark: 0,\n user_timing_measure: 0,\n };\n private readonly _maxAllowed: Record<MaxLimitedType, number>;\n private readonly _maxLength: Record<LengthLimitedType, number>;\n private readonly _maxAttributes: Record<AttributeLimitedType, number>;\n\n public constructor({\n diag: diagParam,\n maxAllowed,\n maxLength,\n maxAttributes,\n }: MXLLimitManagerArgs) {\n this._diag =\n diagParam ??\n diag.createComponentLogger({\n namespace: 'MXLLimitManager',\n });\n\n this._maxAllowed = maxAllowed;\n this._maxLength = maxLength;\n this._maxAttributes = maxAttributes;\n }\n\n private _dropIfMaxReached(type: MaxLimitedType): boolean {\n if (this._currentCount[type] >= this._maxAllowed[type]) {\n this._diag.warn(\n `disallowing ${type} because the maximum number of ${this._maxAllowed[type].toString()} has already been reached for this session`,\n );\n\n this._incrDiagnosticCount(type, 'drop');\n return true;\n }\n\n this._currentCount[type] = (this._currentCount[type] || 0) + 1;\n return false;\n }\n\n public truncateString(type: LengthLimitedType, body: string) {\n if (body.length > this._maxLength[type]) {\n this._diag.warn(\n `truncating ${type} because it is longer than ${this._maxLength[type].toString()} characters: \"${body}\"`,\n );\n\n this._incrDiagnosticCount(type, 'truncate_string');\n return body.substring(0, this._maxLength[type]);\n }\n\n return body;\n }\n\n private _truncateAttributes(\n type: AttributeLimitedType,\n attributes: Record<string, AttributeValue | undefined>,\n keyType: LengthLimitedType,\n valueType: LengthLimitedType,\n ) {\n const keys = Object.keys(attributes);\n\n if (keys.length > this._maxAttributes[type]) {\n this._diag.warn(\n `truncating ${type} attributes because there are more than ${this._maxAttributes[type].toString()} set`,\n );\n this._incrDiagnosticCount(type, 'truncate_attributes');\n }\n\n const truncatedAttributes: Record<string, AttributeValue | undefined> = {};\n\n for (let i = 0; i < Math.min(keys.length, this._maxAttributes[type]); i++) {\n const truncatedKey = this.truncateString(keyType, keys[i]);\n truncatedAttributes[truncatedKey] = this.truncateString(\n valueType,\n attributes[keys[i]]?.toString() || '',\n );\n }\n\n return truncatedAttributes;\n }\n\n public limitBreadcrumb(name: string): LimitedBreadcrumb | 'dropped' {\n if (this._dropIfMaxReached('breadcrumb')) {\n return 'dropped';\n }\n\n return {\n name: this.truncateString('breadcrumb', name),\n };\n }\n\n public limitException(\n message: string,\n attributes: Record<string, AttributeValue | undefined>,\n ): LimitedException | 'dropped' {\n if (this._dropIfMaxReached('exception')) {\n return 'dropped';\n }\n\n return {\n message: this.truncateString('exception', message),\n attributes: this._truncateAttributes(\n 'exception',\n attributes,\n 'exception_attribute_key',\n 'exception_attribute_value',\n ),\n };\n }\n\n public limitLog(\n message: string,\n severity: LogSeverity,\n attributes: Record<string, AttributeValue | undefined>,\n ): LimitedLog | 'dropped' {\n const logType = LogSeverityToLimitType[severity];\n\n if (this._dropIfMaxReached(logType)) {\n return 'dropped';\n }\n\n return {\n message: this.truncateString(logType, message),\n attributes: this._truncateAttributes(\n logType,\n attributes,\n 'log_attribute_key',\n 'log_attribute_value',\n ),\n };\n }\n\n public limitSessionProperty(\n key: string,\n value: string,\n ): LimitedSessionProperty | 'dropped' {\n if (this._dropIfMaxReached('session_property')) {\n return 'dropped';\n }\n\n return {\n key: this.truncateString('session_property_key', key),\n value: this.truncateString('session_property_value', value),\n };\n }\n\n public limitElementTimingEntry(): boolean {\n return this._dropIfMaxReached('element_timing');\n }\n\n public limitServerTimingEntry(): boolean {\n return this._dropIfMaxReached('server_timing');\n }\n\n public limitUserTimingEntry(entryType: 'mark' | 'measure'): boolean {\n return this._dropIfMaxReached(\n entryType === 'mark' ? 'user_timing_mark' : 'user_timing_measure',\n );\n }\n\n public dropReadableSpan(span: ReadableSpan): boolean {\n const type =\n span.attributes[KEY_MXL_TYPE] === MXL_TYPES.Network\n ? 'network_request'\n : 'span';\n\n return this._dropIfMaxReached(type);\n }\n\n public reset(): void {\n this._diagnosticCounts = {};\n this._currentCount = {\n exception: 0,\n error_log: 0,\n warning_log: 0,\n info_log: 0,\n breadcrumb: 0,\n session_property: 0,\n span: 0,\n network_request: 0,\n element_timing: 0,\n server_timing: 0,\n user_timing_mark: 0,\n user_timing_measure: 0,\n };\n }\n\n private _incrDiagnosticCount(type: LimitedType, operation: LimitOperation) {\n const key = `mxl.app.applied_limit.${type}.${operation}.count`;\n\n this._diagnosticCounts[key] = (this._diagnosticCounts[key] || 0) + 1;\n }\n public getDiagnosticCounts(): Record<string, number> {\n return this._diagnosticCounts;\n }\n}\n"],"mappings":";;;AAoBA,MAAM,yBAA8D;CAClE,MAAM;CACN,SAAS;CACT,OAAO;CACR;AAED,IAAa,kBAAb,MAA6D;CAC3D;CAEA,oBAAoD,EAAE;CACtD,gBAAwD;EACtD,WAAW;EACX,WAAW;EACX,aAAa;EACb,UAAU;EACV,YAAY;EACZ,kBAAkB;EAClB,MAAM;EACN,iBAAiB;EACjB,gBAAgB;EAChB,eAAe;EACf,kBAAkB;EAClB,qBAAqB;EACtB;CACD;CACA;CACA;CAEA,YAAmB,EACjB,MAAM,WACN,YACA,WACA,iBACsB;AACtB,OAAK,QACH,aACA,KAAK,sBAAsB,EACzB,WAAW,mBACZ,CAAC;AAEJ,OAAK,cAAc;AACnB,OAAK,aAAa;AAClB,OAAK,iBAAiB;;CAGxB,kBAA0B,MAA+B;AACvD,MAAI,KAAK,cAAc,SAAS,KAAK,YAAY,OAAO;AACtD,QAAK,MAAM,KACT,eAAe,KAAK,iCAAiC,KAAK,YAAY,MAAM,UAAU,CAAC,4CACxF;AAED,QAAK,qBAAqB,MAAM,OAAO;AACvC,UAAO;;AAGT,OAAK,cAAc,SAAS,KAAK,cAAc,SAAS,KAAK;AAC7D,SAAO;;CAGT,eAAsB,MAAyB,MAAc;AAC3D,MAAI,KAAK,SAAS,KAAK,WAAW,OAAO;AACvC,QAAK,MAAM,KACT,cAAc,KAAK,6BAA6B,KAAK,WAAW,MAAM,UAAU,CAAC,gBAAgB,KAAK,GACvG;AAED,QAAK,qBAAqB,MAAM,kBAAkB;AAClD,UAAO,KAAK,UAAU,GAAG,KAAK,WAAW,MAAM;;AAGjD,SAAO;;CAGT,oBACE,MACA,YACA,SACA,WACA;EACA,MAAM,OAAO,OAAO,KAAK,WAAW;AAEpC,MAAI,KAAK,SAAS,KAAK,eAAe,OAAO;AAC3C,QAAK,MAAM,KACT,cAAc,KAAK,0CAA0C,KAAK,eAAe,MAAM,UAAU,CAAC,MACnG;AACD,QAAK,qBAAqB,MAAM,sBAAsB;;EAGxD,MAAM,sBAAkE,EAAE;AAE1E,OAAK,IAAI,IAAI,GAAG,IAAI,KAAK,IAAI,KAAK,QAAQ,KAAK,eAAe,MAAM,EAAE,KAAK;GACzE,MAAM,eAAe,KAAK,eAAe,SAAS,KAAK,GAAG;AAC1D,uBAAoB,gBAAgB,KAAK,eACvC,WACA,WAAW,KAAK,KAAK,UAAU,IAAI,GACpC;;AAGH,SAAO;;CAGT,gBAAuB,MAA6C;AAClE,MAAI,KAAK,kBAAkB,aAAa,CACtC,QAAO;AAGT,SAAO,EACL,MAAM,KAAK,eAAe,cAAc,KAAK,EAC9C;;CAGH,eACE,SACA,YAC8B;AAC9B,MAAI,KAAK,kBAAkB,YAAY,CACrC,QAAO;AAGT,SAAO;GACL,SAAS,KAAK,eAAe,aAAa,QAAQ;GAClD,YAAY,KAAK,oBACf,aACA,YACA,2BACA,4BACD;GACF;;CAGH,SACE,SACA,UACA,YACwB;EACxB,MAAM,UAAU,uBAAuB;AAEvC,MAAI,KAAK,kBAAkB,QAAQ,CACjC,QAAO;AAGT,SAAO;GACL,SAAS,KAAK,eAAe,SAAS,QAAQ;GAC9C,YAAY,KAAK,oBACf,SACA,YACA,qBACA,sBACD;GACF;;CAGH,qBACE,KACA,OACoC;AACpC,MAAI,KAAK,kBAAkB,mBAAmB,CAC5C,QAAO;AAGT,SAAO;GACL,KAAK,KAAK,eAAe,wBAAwB,IAAI;GACrD,OAAO,KAAK,eAAe,0BAA0B,MAAM;GAC5D;;CAGH,0BAA0C;AACxC,SAAO,KAAK,kBAAkB,iBAAiB;;CAGjD,yBAAyC;AACvC,SAAO,KAAK,kBAAkB,gBAAgB;;CAGhD,qBAA4B,WAAwC;AAClE,SAAO,KAAK,kBACV,cAAc,SAAS,qBAAqB,sBAC7C;;CAGH,iBAAwB,MAA6B;EACnD,MAAM,OACJ,KAAK,WAAA,gBAAA,yBACD,oBACA;AAEN,SAAO,KAAK,kBAAkB,KAAK;;CAGrC,QAAqB;AACnB,OAAK,oBAAoB,EAAE;AAC3B,OAAK,gBAAgB;GACnB,WAAW;GACX,WAAW;GACX,aAAa;GACb,UAAU;GACV,YAAY;GACZ,kBAAkB;GAClB,MAAM;GACN,iBAAiB;GACjB,gBAAgB;GAChB,eAAe;GACf,kBAAkB;GAClB,qBAAqB;GACtB;;CAGH,qBAA6B,MAAmB,WAA2B;EACzE,MAAM,MAAM,yBAAyB,KAAK,GAAG,UAAU;AAEvD,OAAK,kBAAkB,QAAQ,KAAK,kBAAkB,QAAQ,KAAK;;CAErE,sBAAqD;AACnD,SAAO,KAAK"}
1
+ {"version":3,"file":"MXLLimitManager.js","names":[],"sources":["../../../src/managers/MXLLimitManager/MXLLimitManager.ts"],"sourcesContent":["import type { AttributeValue, DiagLogger } from '@opentelemetry/api';\nimport { diag } from '@opentelemetry/api';\nimport type { ReadableSpan } from '@opentelemetry/sdk-trace-web';\nimport type { LogSeverity } from '../../api-logs';\nimport { KEY_MXL_TYPE, MXL_TYPES } from '../../constants';\nimport type {\n AttributeLimitedType,\n LengthLimitedType,\n LimitedBreadcrumb,\n LimitedException,\n LimitedLog,\n LimitedSessionProperty,\n LimitedType,\n LimitManagerInternal,\n LimitOperation,\n LogLimitedType,\n MaxLimitedType,\n MXLLimitManagerArgs,\n} from './types';\n\nconst LogSeverityToLimitType: Record<LogSeverity, LogLimitedType> = {\n info: 'info_log',\n warning: 'warning_log',\n error: 'error_log',\n};\n\nexport class MXLLimitManager implements LimitManagerInternal {\n private readonly _diag: DiagLogger;\n\n private _diagnosticCounts: Record<string, number> = {};\n private _currentCount: Record<MaxLimitedType, number> = {\n exception: 0,\n error_log: 0,\n warning_log: 0,\n info_log: 0,\n breadcrumb: 0,\n session_property: 0,\n span: 0,\n network_request: 0,\n element_timing: 0,\n server_timing: 0,\n user_timing_mark: 0,\n user_timing_measure: 0,\n };\n private readonly _maxAllowed: Record<MaxLimitedType, number>;\n private readonly _maxLength: Record<LengthLimitedType, number>;\n private readonly _maxAttributes: Record<AttributeLimitedType, number>;\n\n public constructor({\n diag: diagParam,\n maxAllowed,\n maxLength,\n maxAttributes,\n }: MXLLimitManagerArgs) {\n this._diag =\n diagParam ??\n diag.createComponentLogger({\n namespace: 'MXLLimitManager',\n });\n\n this._maxAllowed = maxAllowed;\n this._maxLength = maxLength;\n this._maxAttributes = maxAttributes;\n }\n\n private _dropIfMaxReached(type: MaxLimitedType): boolean {\n if (this._currentCount[type] >= this._maxAllowed[type]) {\n this._diag.warn(\n `disallowing ${type} because the maximum number of ${this._maxAllowed[type].toString()} has already been reached for this session`,\n );\n\n this._incrDiagnosticCount(type, 'drop');\n return true;\n }\n\n this._currentCount[type] = (this._currentCount[type] || 0) + 1;\n return false;\n }\n\n public truncateString(type: LengthLimitedType, body: string) {\n if (body.length > this._maxLength[type]) {\n this._diag.warn(\n `truncating ${type} because it is longer than ${this._maxLength[type].toString()} characters: \"${body}\"`,\n );\n\n this._incrDiagnosticCount(type, 'truncate_string');\n return body.substring(0, this._maxLength[type]);\n }\n\n return body;\n }\n\n private _truncateAttributes(\n type: AttributeLimitedType,\n attributes: Record<string, AttributeValue | undefined>,\n keyType: LengthLimitedType,\n valueType: LengthLimitedType,\n ) {\n const keys = Object.keys(attributes);\n\n if (keys.length > this._maxAttributes[type]) {\n this._diag.warn(\n `truncating ${type} attributes because there are more than ${this._maxAttributes[type].toString()} set`,\n );\n this._incrDiagnosticCount(type, 'truncate_attributes');\n }\n\n const truncatedAttributes: Record<string, AttributeValue | undefined> = {};\n\n for (let i = 0; i < Math.min(keys.length, this._maxAttributes[type]); i++) {\n const truncatedKey = this.truncateString(keyType, keys[i]);\n truncatedAttributes[truncatedKey] = this.truncateString(\n valueType,\n attributes[keys[i]]?.toString() || '',\n );\n }\n\n return truncatedAttributes;\n }\n\n public limitBreadcrumb(name: string): LimitedBreadcrumb | 'dropped' {\n if (this._dropIfMaxReached('breadcrumb')) {\n return 'dropped';\n }\n\n return {\n name: this.truncateString('breadcrumb', name),\n };\n }\n\n public limitException(\n message: string,\n attributes: Record<string, AttributeValue | undefined>,\n ): LimitedException | 'dropped' {\n if (this._dropIfMaxReached('exception')) {\n return 'dropped';\n }\n\n return {\n message: this.truncateString('exception', message),\n attributes: this._truncateAttributes(\n 'exception',\n attributes,\n 'exception_attribute_key',\n 'exception_attribute_value',\n ),\n };\n }\n\n public limitLog(\n message: string,\n severity: LogSeverity,\n attributes: Record<string, AttributeValue | undefined>,\n ): LimitedLog | 'dropped' {\n const logType = LogSeverityToLimitType[severity];\n\n if (this._dropIfMaxReached(logType)) {\n return 'dropped';\n }\n\n return {\n message: this.truncateString(logType, message),\n attributes: this._truncateAttributes(\n logType,\n attributes,\n 'log_attribute_key',\n 'log_attribute_value',\n ),\n };\n }\n\n public limitSessionProperty(\n key: string,\n value: string,\n ): LimitedSessionProperty | 'dropped' {\n if (this._dropIfMaxReached('session_property')) {\n return 'dropped';\n }\n\n return {\n key: this.truncateString('session_property_key', key),\n value: this.truncateString('session_property_value', value),\n };\n }\n\n public limitElementTimingEntry(): boolean {\n return this._dropIfMaxReached('element_timing');\n }\n\n public limitServerTimingEntry(): boolean {\n return this._dropIfMaxReached('server_timing');\n }\n\n public limitUserTimingEntry(entryType: 'mark' | 'measure'): boolean {\n return this._dropIfMaxReached(\n entryType === 'mark' ? 'user_timing_mark' : 'user_timing_measure',\n );\n }\n\n public dropReadableSpan(span: ReadableSpan): boolean {\n const type =\n span.attributes[KEY_MXL_TYPE] === MXL_TYPES.Network\n ? 'network_request'\n : 'span';\n\n return this._dropIfMaxReached(type);\n }\n\n public reset(): void {\n this._diagnosticCounts = {};\n this._currentCount = {\n exception: 0,\n error_log: 0,\n warning_log: 0,\n info_log: 0,\n breadcrumb: 0,\n session_property: 0,\n span: 0,\n network_request: 0,\n element_timing: 0,\n server_timing: 0,\n user_timing_mark: 0,\n user_timing_measure: 0,\n };\n }\n\n private _incrDiagnosticCount(type: LimitedType, operation: LimitOperation) {\n const key = `mxl.app.applied_limit.${type}.${operation}.count`;\n\n this._diagnosticCounts[key] = (this._diagnosticCounts[key] || 0) + 1;\n }\n public getDiagnosticCounts(): Record<string, number> {\n return this._diagnosticCounts;\n }\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"constants.cjs","names":[],"sources":["../../../src/managers/MXLLimitManager/constants.ts"],"sourcesContent":["import type { MXLLimitManagerArgs } from './types.ts';\n\nexport const DEFAULT_MAX_LOG_ATTRIBUTES = 50;\n\nexport const DEFAULT_LIMITS: MXLLimitManagerArgs = {\n // These are per session limits, the counts of items against these maximums start over when `reset` is called on the\n // limit manager which is done whenever a session ends\n maxAllowed: {\n error_log: 500,\n warning_log: 200,\n info_log: 100,\n exception: 500,\n breadcrumb: 100,\n session_property: 100,\n span: 1_000,\n network_request: 10_000,\n element_timing: 500,\n server_timing: 500,\n user_timing_mark: 500,\n user_timing_measure: 500,\n },\n maxLength: {\n error_log: 128,\n warning_log: 128,\n info_log: 128,\n exception: 1024,\n breadcrumb: 256,\n session_property_key: 128,\n session_property_value: 256,\n log_attribute_key: 128,\n log_attribute_value: 256,\n exception_attribute_key: 128,\n exception_attribute_value: 256,\n },\n maxAttributes: {\n error_log: DEFAULT_MAX_LOG_ATTRIBUTES,\n warning_log: DEFAULT_MAX_LOG_ATTRIBUTES,\n info_log: DEFAULT_MAX_LOG_ATTRIBUTES,\n exception: DEFAULT_MAX_LOG_ATTRIBUTES,\n },\n};\n"],"mappings":";;AAEA,MAAa,6BAA6B;AAE1C,MAAa,iBAAsC;CAGjD,YAAY;EACV,WAAW;EACX,aAAa;EACb,UAAU;EACV,WAAW;EACX,YAAY;EACZ,kBAAkB;EAClB,MAAM;EACN,iBAAiB;EACjB,gBAAgB;EAChB,eAAe;EACf,kBAAkB;EAClB,qBAAqB;EACtB;CACD,WAAW;EACT,WAAW;EACX,aAAa;EACb,UAAU;EACV,WAAW;EACX,YAAY;EACZ,sBAAsB;EACtB,wBAAwB;EACxB,mBAAmB;EACnB,qBAAqB;EACrB,yBAAyB;EACzB,2BAA2B;EAC5B;CACD,eAAe;EACb,WAAA;EACA,aAAA;EACA,UAAA;EACA,WAAA;EACD;CACF"}
1
+ {"version":3,"file":"constants.cjs","names":[],"sources":["../../../src/managers/MXLLimitManager/constants.ts"],"sourcesContent":["import type { MXLLimitManagerArgs } from './types';\n\nexport const DEFAULT_MAX_LOG_ATTRIBUTES = 50;\n\nexport const DEFAULT_LIMITS: MXLLimitManagerArgs = {\n // These are per session limits, the counts of items against these maximums start over when `reset` is called on the\n // limit manager which is done whenever a session ends\n maxAllowed: {\n error_log: 500,\n warning_log: 200,\n info_log: 100,\n exception: 500,\n breadcrumb: 100,\n session_property: 100,\n span: 1_000,\n network_request: 10_000,\n element_timing: 500,\n server_timing: 500,\n user_timing_mark: 500,\n user_timing_measure: 500,\n },\n maxLength: {\n error_log: 128,\n warning_log: 128,\n info_log: 128,\n exception: 1024,\n breadcrumb: 256,\n session_property_key: 128,\n session_property_value: 256,\n log_attribute_key: 128,\n log_attribute_value: 256,\n exception_attribute_key: 128,\n exception_attribute_value: 256,\n },\n maxAttributes: {\n error_log: DEFAULT_MAX_LOG_ATTRIBUTES,\n warning_log: DEFAULT_MAX_LOG_ATTRIBUTES,\n info_log: DEFAULT_MAX_LOG_ATTRIBUTES,\n exception: DEFAULT_MAX_LOG_ATTRIBUTES,\n },\n};\n"],"mappings":";;AAEA,MAAa,6BAA6B;AAE1C,MAAa,iBAAsC;CAGjD,YAAY;EACV,WAAW;EACX,aAAa;EACb,UAAU;EACV,WAAW;EACX,YAAY;EACZ,kBAAkB;EAClB,MAAM;EACN,iBAAiB;EACjB,gBAAgB;EAChB,eAAe;EACf,kBAAkB;EAClB,qBAAqB;EACtB;CACD,WAAW;EACT,WAAW;EACX,aAAa;EACb,UAAU;EACV,WAAW;EACX,YAAY;EACZ,sBAAsB;EACtB,wBAAwB;EACxB,mBAAmB;EACnB,qBAAqB;EACrB,yBAAyB;EACzB,2BAA2B;EAC5B;CACD,eAAe;EACb,WAAA;EACA,aAAA;EACA,UAAA;EACA,WAAA;EACD;CACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","names":[],"sources":["../../../src/managers/MXLLimitManager/constants.ts"],"sourcesContent":["import type { MXLLimitManagerArgs } from './types.ts';\n\nexport const DEFAULT_MAX_LOG_ATTRIBUTES = 50;\n\nexport const DEFAULT_LIMITS: MXLLimitManagerArgs = {\n // These are per session limits, the counts of items against these maximums start over when `reset` is called on the\n // limit manager which is done whenever a session ends\n maxAllowed: {\n error_log: 500,\n warning_log: 200,\n info_log: 100,\n exception: 500,\n breadcrumb: 100,\n session_property: 100,\n span: 1_000,\n network_request: 10_000,\n element_timing: 500,\n server_timing: 500,\n user_timing_mark: 500,\n user_timing_measure: 500,\n },\n maxLength: {\n error_log: 128,\n warning_log: 128,\n info_log: 128,\n exception: 1024,\n breadcrumb: 256,\n session_property_key: 128,\n session_property_value: 256,\n log_attribute_key: 128,\n log_attribute_value: 256,\n exception_attribute_key: 128,\n exception_attribute_value: 256,\n },\n maxAttributes: {\n error_log: DEFAULT_MAX_LOG_ATTRIBUTES,\n warning_log: DEFAULT_MAX_LOG_ATTRIBUTES,\n info_log: DEFAULT_MAX_LOG_ATTRIBUTES,\n exception: DEFAULT_MAX_LOG_ATTRIBUTES,\n },\n};\n"],"mappings":";AAEA,MAAa,6BAA6B;AAE1C,MAAa,iBAAsC;CAGjD,YAAY;EACV,WAAW;EACX,aAAa;EACb,UAAU;EACV,WAAW;EACX,YAAY;EACZ,kBAAkB;EAClB,MAAM;EACN,iBAAiB;EACjB,gBAAgB;EAChB,eAAe;EACf,kBAAkB;EAClB,qBAAqB;EACtB;CACD,WAAW;EACT,WAAW;EACX,aAAa;EACb,UAAU;EACV,WAAW;EACX,YAAY;EACZ,sBAAsB;EACtB,wBAAwB;EACxB,mBAAmB;EACnB,qBAAqB;EACrB,yBAAyB;EACzB,2BAA2B;EAC5B;CACD,eAAe;EACb,WAAA;EACA,aAAA;EACA,UAAA;EACA,WAAA;EACD;CACF"}
1
+ {"version":3,"file":"constants.js","names":[],"sources":["../../../src/managers/MXLLimitManager/constants.ts"],"sourcesContent":["import type { MXLLimitManagerArgs } from './types';\n\nexport const DEFAULT_MAX_LOG_ATTRIBUTES = 50;\n\nexport const DEFAULT_LIMITS: MXLLimitManagerArgs = {\n // These are per session limits, the counts of items against these maximums start over when `reset` is called on the\n // limit manager which is done whenever a session ends\n maxAllowed: {\n error_log: 500,\n warning_log: 200,\n info_log: 100,\n exception: 500,\n breadcrumb: 100,\n session_property: 100,\n span: 1_000,\n network_request: 10_000,\n element_timing: 500,\n server_timing: 500,\n user_timing_mark: 500,\n user_timing_measure: 500,\n },\n maxLength: {\n error_log: 128,\n warning_log: 128,\n info_log: 128,\n exception: 1024,\n breadcrumb: 256,\n session_property_key: 128,\n session_property_value: 256,\n log_attribute_key: 128,\n log_attribute_value: 256,\n exception_attribute_key: 128,\n exception_attribute_value: 256,\n },\n maxAttributes: {\n error_log: DEFAULT_MAX_LOG_ATTRIBUTES,\n warning_log: DEFAULT_MAX_LOG_ATTRIBUTES,\n info_log: DEFAULT_MAX_LOG_ATTRIBUTES,\n exception: DEFAULT_MAX_LOG_ATTRIBUTES,\n },\n};\n"],"mappings":";AAEA,MAAa,6BAA6B;AAE1C,MAAa,iBAAsC;CAGjD,YAAY;EACV,WAAW;EACX,aAAa;EACb,UAAU;EACV,WAAW;EACX,YAAY;EACZ,kBAAkB;EAClB,MAAM;EACN,iBAAiB;EACjB,gBAAgB;EAChB,eAAe;EACf,kBAAkB;EAClB,qBAAqB;EACtB;CACD,WAAW;EACT,WAAW;EACX,aAAa;EACb,UAAU;EACV,WAAW;EACX,YAAY;EACZ,sBAAsB;EACtB,wBAAwB;EACxB,mBAAmB;EACnB,qBAAqB;EACrB,yBAAyB;EACzB,2BAA2B;EAC5B;CACD,eAAe;EACb,WAAA;EACA,aAAA;EACA,UAAA;EACA,WAAA;EACD;CACF"}
@@ -66,7 +66,8 @@ var MXLLogManager = class MXLLogManager {
66
66
  errMessage = String(error).trim();
67
67
  }
68
68
  else errMessage = String(error).trim();
69
- const limited = this._limitManager.limitException(errMessage, validAttrs);
69
+ const { [require_constants_attributes.KEY_REACT_COMPONENT_STACK]: reactComponentStack, ...attrsForLimiting } = validAttrs;
70
+ const limited = this._limitManager.limitException(errMessage, attrsForLimiting);
70
71
  if (limited === "dropped") return;
71
72
  this._logger.emit({
72
73
  timestamp,
@@ -75,6 +76,7 @@ var MXLLogManager = class MXLLogManager {
75
76
  body: limited.message,
76
77
  attributes: {
77
78
  ...limited.attributes,
79
+ ...reactComponentStack !== void 0 ? { [require_constants_attributes.KEY_REACT_COMPONENT_STACK]: String(reactComponentStack) } : {},
78
80
  [require_constants_attributes.KEY_MXL_TYPE]: "sys.exception",
79
81
  [require_constants_attributes.KEY_MXL_EXCEPTION_HANDLING]: MXLLogManager._exceptionHandlingType(handled, handler),
80
82
  [require_constants_attributes.KEY_MXL_EXCEPTION_CAUSE]: errCause,
@@ -1 +1 @@
1
- {"version":3,"file":"MXLLogManager.cjs","names":["GLOBAL_CONFIG","logs","diag","OTelPerformanceManager","SeverityNumber","KEY_MXL_UNHANDLED_EXCEPTIONS_COUNT","KEY_MXL_TYPE","KEY_MXL_EXCEPTION_HANDLING","KEY_MXL_EXCEPTION_CAUSE","ATTR_EXCEPTION_TYPE","ATTR_EXCEPTION_MESSAGE","ATTR_EXCEPTION_STACKTRACE","KEY_MXL_JS_FILE_BUNDLE_IDS","KEY_MXL_STATE","getVisibilityState","KEY_MXL_EXCEPTION_NUMBER","getIncrementedCount","KEY_MXL_ERROR_LOG_COUNT","KEY_MXL_JS_EXCEPTION_STACKTRACE"],"sources":["../../../src/managers/MXLLogManager/MXLLogManager.ts"],"sourcesContent":["import type { Attributes, DiagLogger } from '@opentelemetry/api';\nimport { diag } from '@opentelemetry/api';\nimport type { Logger } from '@opentelemetry/api-logs';\nimport { logs, SeverityNumber } from '@opentelemetry/api-logs';\nimport {\n ATTR_EXCEPTION_MESSAGE,\n ATTR_EXCEPTION_STACKTRACE,\n ATTR_EXCEPTION_TYPE,\n} from '@opentelemetry/semantic-conventions';\nimport type { LogManager, LogSeverity } from '../../api-logs/index.ts';\nimport type {\n LogExceptionOptions,\n LogMessageOptions,\n} from '../../api-logs/manager/index.ts';\nimport type { ExceptionHandlerType } from '../../api-logs/manager/types.ts';\nimport type { VisibilityStateDocument } from '../../common/index.ts';\nimport {\n KEY_MXL_ERROR_LOG_COUNT,\n KEY_MXL_EXCEPTION_CAUSE,\n KEY_MXL_JS_FILE_BUNDLE_IDS,\n KEY_MXL_UNHANDLED_EXCEPTIONS_COUNT,\n} from '../../constants/attributes.ts';\nimport {\n KEY_MXL_EXCEPTION_HANDLING,\n KEY_MXL_EXCEPTION_NUMBER,\n KEY_MXL_JS_EXCEPTION_STACKTRACE,\n KEY_MXL_STATE,\n KEY_MXL_TYPE,\n MXL_TYPES,\n} from '../../constants/index.ts';\nimport type { PerformanceManager } from '../../utils/index.ts';\nimport {\n GLOBAL_CONFIG,\n getIncrementedCount,\n getVisibilityState,\n OTelPerformanceManager,\n} from '../../utils/index.ts';\nimport type { LimitManagerInternal } from '../MXLLimitManager/index.ts';\nimport type { SpanSessionManagerInternal } from '../MXLSpanSessionManager/index.ts';\nimport type { MXLLogManagerArgs } from './types.ts';\n\nconst MXL_EXCEPTION_NUMBER_STORAGE_KEY = 'mxl_exception_number';\n/**\n * GLOBAL_CONFIG._MXLFileBundleIDs is populated at runtime when each file is loaded,\n * based on the contents injected by the mxl-web-cli.\n */\nconst getJSFileBundleIDs = () =>\n JSON.stringify(\n GLOBAL_CONFIG._MXLFileBundleIDs ||\n GLOBAL_CONFIG._MXLFileBundleIDs ||\n {},\n );\n\nexport class MXLLogManager implements LogManager {\n private readonly _diag: DiagLogger;\n private readonly _perf: PerformanceManager;\n private readonly _logger: Logger;\n private readonly _spanSessionManager: SpanSessionManagerInternal;\n private readonly _limitManager: LimitManagerInternal;\n private readonly _visibilityDoc: VisibilityStateDocument;\n private readonly _storage: Storage;\n\n public constructor({\n diag: diagParam,\n perf,\n spanSessionManager,\n limitManager,\n loggerProvider: globalLoggerProviderOverride,\n visibilityDoc = window.document,\n storage = window.localStorage,\n }: MXLLogManagerArgs) {\n const loggerProvider = globalLoggerProviderOverride ?? logs;\n\n this._diag =\n diagParam ??\n diag.createComponentLogger({\n namespace: 'MXLLogManager',\n });\n this._perf = perf ?? new OTelPerformanceManager();\n this._logger = loggerProvider.getLogger('mxl-web-sdk-logs');\n this._spanSessionManager = spanSessionManager;\n this._limitManager = limitManager;\n this._visibilityDoc = visibilityDoc;\n this._storage = storage;\n }\n\n private _validateAttributes(attributes: unknown): Attributes {\n if (Object.prototype.toString.call(attributes) !== '[object Object]') {\n this._diag.warn('attributes must be a plain object', attributes);\n return {};\n }\n return attributes as Attributes;\n }\n\n private static _logSeverityToSeverityNumber(\n severity: LogSeverity,\n ): SeverityNumber {\n switch (severity) {\n case 'info':\n return SeverityNumber.INFO;\n case 'warning':\n return SeverityNumber.WARN;\n default:\n return SeverityNumber.ERROR;\n }\n }\n\n public logException(\n error: unknown,\n {\n handled = true,\n attributes = {},\n timestamp = this._perf.getNowMillis(),\n handler = 'manual',\n }: LogExceptionOptions = {},\n ) {\n const validAttrs = this._validateAttributes(attributes);\n\n if (!handled) {\n this._spanSessionManager.incrSessionCountForKey(\n KEY_MXL_UNHANDLED_EXCEPTIONS_COUNT,\n );\n }\n\n const type = error?.constructor?.name || typeof error;\n let errMessage = '';\n let errName = type;\n let errStack = '';\n let errCause = '';\n\n if (error instanceof Error) {\n errMessage = String(error.message || '').trim();\n errName = error.name || '';\n errStack = error.stack || '';\n errCause = error.cause ? 'present' : '';\n } else if (error && typeof error === 'object') {\n try {\n errMessage = JSON.stringify(error);\n } catch {\n errMessage = String(error).trim();\n }\n } else {\n errMessage = String(error).trim();\n }\n\n const limited = this._limitManager.limitException(errMessage, validAttrs);\n if (limited === 'dropped') {\n return;\n }\n\n this._logger.emit({\n timestamp,\n severityNumber: SeverityNumber.ERROR,\n severityText: 'ERROR',\n body: limited.message,\n attributes: {\n ...limited.attributes,\n [KEY_MXL_TYPE]: MXL_TYPES.SystemException,\n [KEY_MXL_EXCEPTION_HANDLING]: MXLLogManager._exceptionHandlingType(\n handled,\n handler,\n ),\n [KEY_MXL_EXCEPTION_CAUSE]: errCause,\n [ATTR_EXCEPTION_TYPE]: type,\n ['exception.name']: errName,\n [ATTR_EXCEPTION_MESSAGE]: limited.message,\n [ATTR_EXCEPTION_STACKTRACE]: errStack,\n [KEY_MXL_JS_FILE_BUNDLE_IDS]: getJSFileBundleIDs(),\n [KEY_MXL_STATE]: getVisibilityState(this._visibilityDoc),\n [KEY_MXL_EXCEPTION_NUMBER]: getIncrementedCount(\n this._storage,\n MXL_EXCEPTION_NUMBER_STORAGE_KEY,\n this._diag,\n ),\n },\n });\n }\n\n public message(\n message: string,\n severity: LogSeverity,\n {\n attributes = {},\n includeStacktrace = true,\n stacktrace,\n }: LogMessageOptions = {},\n ) {\n if (typeof message !== 'string' || !message.trim()) {\n this._diag.warn('Message must be a non-empty string');\n return;\n }\n\n if (!['info', 'warning', 'error'].includes(severity)) {\n this._diag.warn('Severity must be info, warning, or error');\n return;\n }\n\n const validAttrs = this._validateAttributes(attributes);\n\n if (severity === 'error') {\n this._spanSessionManager.incrSessionCountForKey(KEY_MXL_ERROR_LOG_COUNT);\n }\n\n let stack = '';\n if (severity !== 'info') {\n if (typeof stacktrace === 'string') {\n stack = stacktrace;\n } else if (includeStacktrace) {\n stack = new Error().stack || '';\n }\n }\n\n this._logMessage({\n message: message.trim(),\n severity,\n timestamp: this._perf.getNowMillis(),\n attributes: validAttrs,\n stack,\n });\n }\n\n private _logMessage({\n message,\n severity,\n timestamp,\n attributes = {},\n stack,\n }: {\n message: string;\n severity: LogSeverity;\n timestamp: number;\n attributes?: Attributes;\n stack?: string;\n }) {\n const limitedLog = this._limitManager.limitLog(\n message,\n severity,\n attributes,\n );\n\n if (limitedLog === 'dropped') {\n return;\n }\n\n this._logger.emit({\n timestamp,\n severityNumber: MXLLogManager._logSeverityToSeverityNumber(severity),\n severityText: severity.toUpperCase(),\n body: limitedLog.message,\n attributes: {\n ...limitedLog.attributes,\n [KEY_MXL_TYPE]: MXL_TYPES.SystemLog,\n ...(stack\n ? {\n [KEY_MXL_JS_EXCEPTION_STACKTRACE]: stack,\n [KEY_MXL_JS_FILE_BUNDLE_IDS]: getJSFileBundleIDs(),\n }\n : {}),\n [KEY_MXL_STATE]: getVisibilityState(this._visibilityDoc),\n },\n });\n }\n\n private static _exceptionHandlingType(\n handled: boolean,\n handler: ExceptionHandlerType,\n ): string {\n if (handled) {\n return 'handled';\n }\n\n if (handler === 'global_exception') {\n return 'unhandled_error';\n }\n\n if (handler === 'promise_rejection') {\n return 'unhandled_rejection';\n }\n\n return 'unhandled';\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"MXLLogManager.cjs","names":["GLOBAL_CONFIG","logs","diag","OTelPerformanceManager","SeverityNumber","KEY_MXL_UNHANDLED_EXCEPTIONS_COUNT","KEY_REACT_COMPONENT_STACK","KEY_MXL_TYPE","KEY_MXL_EXCEPTION_HANDLING","KEY_MXL_EXCEPTION_CAUSE","ATTR_EXCEPTION_TYPE","ATTR_EXCEPTION_MESSAGE","ATTR_EXCEPTION_STACKTRACE","KEY_MXL_JS_FILE_BUNDLE_IDS","KEY_MXL_STATE","getVisibilityState","KEY_MXL_EXCEPTION_NUMBER","getIncrementedCount","KEY_MXL_ERROR_LOG_COUNT","KEY_MXL_JS_EXCEPTION_STACKTRACE"],"sources":["../../../src/managers/MXLLogManager/MXLLogManager.ts"],"sourcesContent":["import type { Attributes, DiagLogger } from '@opentelemetry/api';\nimport { diag } from '@opentelemetry/api';\nimport type { Logger } from '@opentelemetry/api-logs';\nimport { logs, SeverityNumber } from '@opentelemetry/api-logs';\nimport {\n ATTR_EXCEPTION_MESSAGE,\n ATTR_EXCEPTION_STACKTRACE,\n ATTR_EXCEPTION_TYPE,\n} from '@opentelemetry/semantic-conventions';\nimport type { LogManager, LogSeverity } from '../../api-logs';\nimport type {\n LogExceptionOptions,\n LogMessageOptions,\n} from '../../api-logs/manager';\nimport type { ExceptionHandlerType } from '../../api-logs/manager/types';\nimport type { VisibilityStateDocument } from '../../common';\nimport {\n KEY_MXL_EXCEPTION_HANDLING,\n KEY_MXL_EXCEPTION_NUMBER,\n KEY_MXL_JS_EXCEPTION_STACKTRACE,\n KEY_MXL_STATE,\n KEY_MXL_TYPE,\n MXL_TYPES,\n} from '../../constants';\nimport {\n KEY_MXL_ERROR_LOG_COUNT,\n KEY_MXL_EXCEPTION_CAUSE,\n KEY_MXL_JS_FILE_BUNDLE_IDS,\n KEY_MXL_UNHANDLED_EXCEPTIONS_COUNT,\n KEY_REACT_COMPONENT_STACK,\n} from '../../constants/attributes';\nimport type { PerformanceManager } from '../../utils';\nimport {\n GLOBAL_CONFIG,\n getIncrementedCount,\n getVisibilityState,\n OTelPerformanceManager,\n} from '../../utils';\nimport type { LimitManagerInternal } from '../MXLLimitManager';\nimport type { SpanSessionManagerInternal } from '../MXLSpanSessionManager';\nimport type { MXLLogManagerArgs } from './types';\n\nconst MXL_EXCEPTION_NUMBER_STORAGE_KEY = 'mxl_exception_number';\n/**\n * GLOBAL_CONFIG._MXLFileBundleIDs is populated at runtime when each file is loaded,\n * based on the contents injected by the mxl-web-cli.\n */\nconst getJSFileBundleIDs = () =>\n JSON.stringify(\n GLOBAL_CONFIG._MXLFileBundleIDs || GLOBAL_CONFIG._MXLFileBundleIDs || {},\n );\n\nexport class MXLLogManager implements LogManager {\n private readonly _diag: DiagLogger;\n private readonly _perf: PerformanceManager;\n private readonly _logger: Logger;\n private readonly _spanSessionManager: SpanSessionManagerInternal;\n private readonly _limitManager: LimitManagerInternal;\n private readonly _visibilityDoc: VisibilityStateDocument;\n private readonly _storage: Storage;\n\n public constructor({\n diag: diagParam,\n perf,\n spanSessionManager,\n limitManager,\n loggerProvider: globalLoggerProviderOverride,\n visibilityDoc = window.document,\n storage = window.localStorage,\n }: MXLLogManagerArgs) {\n const loggerProvider = globalLoggerProviderOverride ?? logs;\n\n this._diag =\n diagParam ??\n diag.createComponentLogger({\n namespace: 'MXLLogManager',\n });\n this._perf = perf ?? new OTelPerformanceManager();\n this._logger = loggerProvider.getLogger('mxl-web-sdk-logs');\n this._spanSessionManager = spanSessionManager;\n this._limitManager = limitManager;\n this._visibilityDoc = visibilityDoc;\n this._storage = storage;\n }\n\n private _validateAttributes(attributes: unknown): Attributes {\n if (Object.prototype.toString.call(attributes) !== '[object Object]') {\n this._diag.warn('attributes must be a plain object', attributes);\n return {};\n }\n return attributes as Attributes;\n }\n\n private static _logSeverityToSeverityNumber(\n severity: LogSeverity,\n ): SeverityNumber {\n switch (severity) {\n case 'info':\n return SeverityNumber.INFO;\n case 'warning':\n return SeverityNumber.WARN;\n default:\n return SeverityNumber.ERROR;\n }\n }\n\n public logException(\n error: unknown,\n {\n handled = true,\n attributes = {},\n timestamp = this._perf.getNowMillis(),\n handler = 'manual',\n }: LogExceptionOptions = {},\n ) {\n const validAttrs = this._validateAttributes(attributes);\n\n if (!handled) {\n this._spanSessionManager.incrSessionCountForKey(\n KEY_MXL_UNHANDLED_EXCEPTIONS_COUNT,\n );\n }\n\n const type = error?.constructor?.name || typeof error;\n let errMessage = '';\n let errName = type;\n let errStack = '';\n let errCause = '';\n\n if (error instanceof Error) {\n errMessage = String(error.message || '').trim();\n errName = error.name || '';\n errStack = error.stack || '';\n errCause = error.cause ? 'present' : '';\n } else if (error && typeof error === 'object') {\n try {\n errMessage = JSON.stringify(error);\n } catch {\n errMessage = String(error).trim();\n }\n } else {\n errMessage = String(error).trim();\n }\n\n const {\n [KEY_REACT_COMPONENT_STACK]: reactComponentStack,\n ...attrsForLimiting\n } = validAttrs;\n\n const limited = this._limitManager.limitException(\n errMessage,\n attrsForLimiting,\n );\n if (limited === 'dropped') {\n return;\n }\n\n this._logger.emit({\n timestamp,\n severityNumber: SeverityNumber.ERROR,\n severityText: 'ERROR',\n body: limited.message,\n attributes: {\n ...limited.attributes,\n ...(reactComponentStack !== undefined\n ? { [KEY_REACT_COMPONENT_STACK]: String(reactComponentStack) }\n : {}),\n [KEY_MXL_TYPE]: MXL_TYPES.SystemException,\n [KEY_MXL_EXCEPTION_HANDLING]: MXLLogManager._exceptionHandlingType(\n handled,\n handler,\n ),\n [KEY_MXL_EXCEPTION_CAUSE]: errCause,\n [ATTR_EXCEPTION_TYPE]: type,\n ['exception.name']: errName,\n [ATTR_EXCEPTION_MESSAGE]: limited.message,\n [ATTR_EXCEPTION_STACKTRACE]: errStack,\n [KEY_MXL_JS_FILE_BUNDLE_IDS]: getJSFileBundleIDs(),\n [KEY_MXL_STATE]: getVisibilityState(this._visibilityDoc),\n [KEY_MXL_EXCEPTION_NUMBER]: getIncrementedCount(\n this._storage,\n MXL_EXCEPTION_NUMBER_STORAGE_KEY,\n this._diag,\n ),\n },\n });\n }\n\n public message(\n message: string,\n severity: LogSeverity,\n {\n attributes = {},\n includeStacktrace = true,\n stacktrace,\n }: LogMessageOptions = {},\n ) {\n if (typeof message !== 'string' || !message.trim()) {\n this._diag.warn('Message must be a non-empty string');\n return;\n }\n\n if (!['info', 'warning', 'error'].includes(severity)) {\n this._diag.warn('Severity must be info, warning, or error');\n return;\n }\n\n const validAttrs = this._validateAttributes(attributes);\n\n if (severity === 'error') {\n this._spanSessionManager.incrSessionCountForKey(KEY_MXL_ERROR_LOG_COUNT);\n }\n\n let stack = '';\n if (severity !== 'info') {\n if (typeof stacktrace === 'string') {\n stack = stacktrace;\n } else if (includeStacktrace) {\n stack = new Error().stack || '';\n }\n }\n\n this._logMessage({\n message: message.trim(),\n severity,\n timestamp: this._perf.getNowMillis(),\n attributes: validAttrs,\n stack,\n });\n }\n\n private _logMessage({\n message,\n severity,\n timestamp,\n attributes = {},\n stack,\n }: {\n message: string;\n severity: LogSeverity;\n timestamp: number;\n attributes?: Attributes;\n stack?: string;\n }) {\n const limitedLog = this._limitManager.limitLog(\n message,\n severity,\n attributes,\n );\n\n if (limitedLog === 'dropped') {\n return;\n }\n\n this._logger.emit({\n timestamp,\n severityNumber: MXLLogManager._logSeverityToSeverityNumber(severity),\n severityText: severity.toUpperCase(),\n body: limitedLog.message,\n attributes: {\n ...limitedLog.attributes,\n [KEY_MXL_TYPE]: MXL_TYPES.SystemLog,\n ...(stack\n ? {\n [KEY_MXL_JS_EXCEPTION_STACKTRACE]: stack,\n [KEY_MXL_JS_FILE_BUNDLE_IDS]: getJSFileBundleIDs(),\n }\n : {}),\n [KEY_MXL_STATE]: getVisibilityState(this._visibilityDoc),\n },\n });\n }\n\n private static _exceptionHandlingType(\n handled: boolean,\n handler: ExceptionHandlerType,\n ): string {\n if (handled) {\n return 'handled';\n }\n\n if (handler === 'global_exception') {\n return 'unhandled_error';\n }\n\n if (handler === 'promise_rejection') {\n return 'unhandled_rejection';\n }\n\n return 'unhandled';\n }\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"MXLLogManager.d.cts","names":[],"sources":["../../../src/managers/MXLLogManager/MXLLogManager.ts"],"mappings":";;;;cAqDa,aAAA,YAAyB,UAAA;EAAA,iBACnB,KAAA;EAAA,iBACA,KAAA;EAAA,iBACA,OAAA;EAAA,iBACA,mBAAA;EAAA,iBACA,aAAA;EAAA,iBACA,cAAA;EAAA,iBACA,QAAA;;IAGf,IAAA,EAAM,SAAA;IACN,IAAA;IACA,kBAAA;IACA,YAAA;IACA,cAAA,EAAgB,4BAAA;IAChB,aAAA;IACA;EAAA,GACC,iBAAA;EAAA,QAgBK,mBAAA;EAAA,eAQO,4BAAA;EAaR,YAAA,CACL,KAAA;IAEE,OAAA;IACA,UAAA;IACA,SAAA;IACA;EAAA,IACC,mBAAA;EAgEE,OAAA,CACL,OAAA,UACA,QAAA,EAAU,WAAA;IAER,UAAA;IACA,iBAAA;IACA;EAAA,IACC,iBAAA;EAAA,QAoCG,WAAA;EAAA,eA0CO,sBAAA;AAAA"}
1
+ {"version":3,"file":"MXLLogManager.d.cts","names":[],"sources":["../../../src/managers/MXLLogManager/MXLLogManager.ts"],"mappings":";;;;cAoDa,aAAA,YAAyB,UAAA;EAAA,iBACnB,KAAA;EAAA,iBACA,KAAA;EAAA,iBACA,OAAA;EAAA,iBACA,mBAAA;EAAA,iBACA,aAAA;EAAA,iBACA,cAAA;EAAA,iBACA,QAAA;;IAGf,IAAA,EAAM,SAAA;IACN,IAAA;IACA,kBAAA;IACA,YAAA;IACA,cAAA,EAAgB,4BAAA;IAChB,aAAA;IACA;EAAA,GACC,iBAAA;EAAA,QAgBK,mBAAA;EAAA,eAQO,4BAAA;EAaR,YAAA,CACL,KAAA;IAEE,OAAA;IACA,UAAA;IACA,SAAA;IACA;EAAA,IACC,mBAAA;EA2EE,OAAA,CACL,OAAA,UACA,QAAA,EAAU,WAAA;IAER,UAAA;IACA,iBAAA;IACA;EAAA,IACC,iBAAA;EAAA,QAoCG,WAAA;EAAA,eA0CO,sBAAA;AAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"MXLLogManager.d.ts","names":[],"sources":["../../../src/managers/MXLLogManager/MXLLogManager.ts"],"mappings":";;;;cAqDa,aAAA,YAAyB,UAAA;EAAA,iBACnB,KAAA;EAAA,iBACA,KAAA;EAAA,iBACA,OAAA;EAAA,iBACA,mBAAA;EAAA,iBACA,aAAA;EAAA,iBACA,cAAA;EAAA,iBACA,QAAA;;IAGf,IAAA,EAAM,SAAA;IACN,IAAA;IACA,kBAAA;IACA,YAAA;IACA,cAAA,EAAgB,4BAAA;IAChB,aAAA;IACA;EAAA,GACC,iBAAA;EAAA,QAgBK,mBAAA;EAAA,eAQO,4BAAA;EAaR,YAAA,CACL,KAAA;IAEE,OAAA;IACA,UAAA;IACA,SAAA;IACA;EAAA,IACC,mBAAA;EAgEE,OAAA,CACL,OAAA,UACA,QAAA,EAAU,WAAA;IAER,UAAA;IACA,iBAAA;IACA;EAAA,IACC,iBAAA;EAAA,QAoCG,WAAA;EAAA,eA0CO,sBAAA;AAAA"}
1
+ {"version":3,"file":"MXLLogManager.d.ts","names":[],"sources":["../../../src/managers/MXLLogManager/MXLLogManager.ts"],"mappings":";;;;cAoDa,aAAA,YAAyB,UAAA;EAAA,iBACnB,KAAA;EAAA,iBACA,KAAA;EAAA,iBACA,OAAA;EAAA,iBACA,mBAAA;EAAA,iBACA,aAAA;EAAA,iBACA,cAAA;EAAA,iBACA,QAAA;;IAGf,IAAA,EAAM,SAAA;IACN,IAAA;IACA,kBAAA;IACA,YAAA;IACA,cAAA,EAAgB,4BAAA;IAChB,aAAA;IACA;EAAA,GACC,iBAAA;EAAA,QAgBK,mBAAA;EAAA,eAQO,4BAAA;EAaR,YAAA,CACL,KAAA;IAEE,OAAA;IACA,UAAA;IACA,SAAA;IACA;EAAA,IACC,mBAAA;EA2EE,OAAA,CACL,OAAA,UACA,QAAA,EAAU,WAAA;IAER,UAAA;IACA,iBAAA;IACA;EAAA,IACC,iBAAA;EAAA,QAoCG,WAAA;EAAA,eA0CO,sBAAA;AAAA"}
@@ -1,5 +1,5 @@
1
1
  import { getIncrementedCount } from "../../utils/getIncrementedCount.js";
2
- import { KEY_MXL_ERROR_LOG_COUNT, KEY_MXL_EXCEPTION_CAUSE, KEY_MXL_EXCEPTION_HANDLING, KEY_MXL_EXCEPTION_NUMBER, KEY_MXL_JS_EXCEPTION_STACKTRACE, KEY_MXL_JS_FILE_BUNDLE_IDS, KEY_MXL_STATE, KEY_MXL_TYPE, KEY_MXL_UNHANDLED_EXCEPTIONS_COUNT } from "../../constants/attributes.js";
2
+ import { KEY_MXL_ERROR_LOG_COUNT, KEY_MXL_EXCEPTION_CAUSE, KEY_MXL_EXCEPTION_HANDLING, KEY_MXL_EXCEPTION_NUMBER, KEY_MXL_JS_EXCEPTION_STACKTRACE, KEY_MXL_JS_FILE_BUNDLE_IDS, KEY_MXL_STATE, KEY_MXL_TYPE, KEY_MXL_UNHANDLED_EXCEPTIONS_COUNT, KEY_REACT_COMPONENT_STACK } from "../../constants/attributes.js";
3
3
  import { getVisibilityState } from "../../utils/getVisibilityState.js";
4
4
  import { GLOBAL_CONFIG } from "../../utils/globalConfig.js";
5
5
  import { OTelPerformanceManager } from "../../utils/PerformanceManager/OTelPerformanceManager.js";
@@ -64,7 +64,8 @@ var MXLLogManager = class MXLLogManager {
64
64
  errMessage = String(error).trim();
65
65
  }
66
66
  else errMessage = String(error).trim();
67
- const limited = this._limitManager.limitException(errMessage, validAttrs);
67
+ const { [KEY_REACT_COMPONENT_STACK]: reactComponentStack, ...attrsForLimiting } = validAttrs;
68
+ const limited = this._limitManager.limitException(errMessage, attrsForLimiting);
68
69
  if (limited === "dropped") return;
69
70
  this._logger.emit({
70
71
  timestamp,
@@ -73,6 +74,7 @@ var MXLLogManager = class MXLLogManager {
73
74
  body: limited.message,
74
75
  attributes: {
75
76
  ...limited.attributes,
77
+ ...reactComponentStack !== void 0 ? { [KEY_REACT_COMPONENT_STACK]: String(reactComponentStack) } : {},
76
78
  [KEY_MXL_TYPE]: "sys.exception",
77
79
  [KEY_MXL_EXCEPTION_HANDLING]: MXLLogManager._exceptionHandlingType(handled, handler),
78
80
  [KEY_MXL_EXCEPTION_CAUSE]: errCause,
@@ -1 +1 @@
1
- {"version":3,"file":"MXLLogManager.js","names":[],"sources":["../../../src/managers/MXLLogManager/MXLLogManager.ts"],"sourcesContent":["import type { Attributes, DiagLogger } from '@opentelemetry/api';\nimport { diag } from '@opentelemetry/api';\nimport type { Logger } from '@opentelemetry/api-logs';\nimport { logs, SeverityNumber } from '@opentelemetry/api-logs';\nimport {\n ATTR_EXCEPTION_MESSAGE,\n ATTR_EXCEPTION_STACKTRACE,\n ATTR_EXCEPTION_TYPE,\n} from '@opentelemetry/semantic-conventions';\nimport type { LogManager, LogSeverity } from '../../api-logs/index.ts';\nimport type {\n LogExceptionOptions,\n LogMessageOptions,\n} from '../../api-logs/manager/index.ts';\nimport type { ExceptionHandlerType } from '../../api-logs/manager/types.ts';\nimport type { VisibilityStateDocument } from '../../common/index.ts';\nimport {\n KEY_MXL_ERROR_LOG_COUNT,\n KEY_MXL_EXCEPTION_CAUSE,\n KEY_MXL_JS_FILE_BUNDLE_IDS,\n KEY_MXL_UNHANDLED_EXCEPTIONS_COUNT,\n} from '../../constants/attributes.ts';\nimport {\n KEY_MXL_EXCEPTION_HANDLING,\n KEY_MXL_EXCEPTION_NUMBER,\n KEY_MXL_JS_EXCEPTION_STACKTRACE,\n KEY_MXL_STATE,\n KEY_MXL_TYPE,\n MXL_TYPES,\n} from '../../constants/index.ts';\nimport type { PerformanceManager } from '../../utils/index.ts';\nimport {\n GLOBAL_CONFIG,\n getIncrementedCount,\n getVisibilityState,\n OTelPerformanceManager,\n} from '../../utils/index.ts';\nimport type { LimitManagerInternal } from '../MXLLimitManager/index.ts';\nimport type { SpanSessionManagerInternal } from '../MXLSpanSessionManager/index.ts';\nimport type { MXLLogManagerArgs } from './types.ts';\n\nconst MXL_EXCEPTION_NUMBER_STORAGE_KEY = 'mxl_exception_number';\n/**\n * GLOBAL_CONFIG._MXLFileBundleIDs is populated at runtime when each file is loaded,\n * based on the contents injected by the mxl-web-cli.\n */\nconst getJSFileBundleIDs = () =>\n JSON.stringify(\n GLOBAL_CONFIG._MXLFileBundleIDs ||\n GLOBAL_CONFIG._MXLFileBundleIDs ||\n {},\n );\n\nexport class MXLLogManager implements LogManager {\n private readonly _diag: DiagLogger;\n private readonly _perf: PerformanceManager;\n private readonly _logger: Logger;\n private readonly _spanSessionManager: SpanSessionManagerInternal;\n private readonly _limitManager: LimitManagerInternal;\n private readonly _visibilityDoc: VisibilityStateDocument;\n private readonly _storage: Storage;\n\n public constructor({\n diag: diagParam,\n perf,\n spanSessionManager,\n limitManager,\n loggerProvider: globalLoggerProviderOverride,\n visibilityDoc = window.document,\n storage = window.localStorage,\n }: MXLLogManagerArgs) {\n const loggerProvider = globalLoggerProviderOverride ?? logs;\n\n this._diag =\n diagParam ??\n diag.createComponentLogger({\n namespace: 'MXLLogManager',\n });\n this._perf = perf ?? new OTelPerformanceManager();\n this._logger = loggerProvider.getLogger('mxl-web-sdk-logs');\n this._spanSessionManager = spanSessionManager;\n this._limitManager = limitManager;\n this._visibilityDoc = visibilityDoc;\n this._storage = storage;\n }\n\n private _validateAttributes(attributes: unknown): Attributes {\n if (Object.prototype.toString.call(attributes) !== '[object Object]') {\n this._diag.warn('attributes must be a plain object', attributes);\n return {};\n }\n return attributes as Attributes;\n }\n\n private static _logSeverityToSeverityNumber(\n severity: LogSeverity,\n ): SeverityNumber {\n switch (severity) {\n case 'info':\n return SeverityNumber.INFO;\n case 'warning':\n return SeverityNumber.WARN;\n default:\n return SeverityNumber.ERROR;\n }\n }\n\n public logException(\n error: unknown,\n {\n handled = true,\n attributes = {},\n timestamp = this._perf.getNowMillis(),\n handler = 'manual',\n }: LogExceptionOptions = {},\n ) {\n const validAttrs = this._validateAttributes(attributes);\n\n if (!handled) {\n this._spanSessionManager.incrSessionCountForKey(\n KEY_MXL_UNHANDLED_EXCEPTIONS_COUNT,\n );\n }\n\n const type = error?.constructor?.name || typeof error;\n let errMessage = '';\n let errName = type;\n let errStack = '';\n let errCause = '';\n\n if (error instanceof Error) {\n errMessage = String(error.message || '').trim();\n errName = error.name || '';\n errStack = error.stack || '';\n errCause = error.cause ? 'present' : '';\n } else if (error && typeof error === 'object') {\n try {\n errMessage = JSON.stringify(error);\n } catch {\n errMessage = String(error).trim();\n }\n } else {\n errMessage = String(error).trim();\n }\n\n const limited = this._limitManager.limitException(errMessage, validAttrs);\n if (limited === 'dropped') {\n return;\n }\n\n this._logger.emit({\n timestamp,\n severityNumber: SeverityNumber.ERROR,\n severityText: 'ERROR',\n body: limited.message,\n attributes: {\n ...limited.attributes,\n [KEY_MXL_TYPE]: MXL_TYPES.SystemException,\n [KEY_MXL_EXCEPTION_HANDLING]: MXLLogManager._exceptionHandlingType(\n handled,\n handler,\n ),\n [KEY_MXL_EXCEPTION_CAUSE]: errCause,\n [ATTR_EXCEPTION_TYPE]: type,\n ['exception.name']: errName,\n [ATTR_EXCEPTION_MESSAGE]: limited.message,\n [ATTR_EXCEPTION_STACKTRACE]: errStack,\n [KEY_MXL_JS_FILE_BUNDLE_IDS]: getJSFileBundleIDs(),\n [KEY_MXL_STATE]: getVisibilityState(this._visibilityDoc),\n [KEY_MXL_EXCEPTION_NUMBER]: getIncrementedCount(\n this._storage,\n MXL_EXCEPTION_NUMBER_STORAGE_KEY,\n this._diag,\n ),\n },\n });\n }\n\n public message(\n message: string,\n severity: LogSeverity,\n {\n attributes = {},\n includeStacktrace = true,\n stacktrace,\n }: LogMessageOptions = {},\n ) {\n if (typeof message !== 'string' || !message.trim()) {\n this._diag.warn('Message must be a non-empty string');\n return;\n }\n\n if (!['info', 'warning', 'error'].includes(severity)) {\n this._diag.warn('Severity must be info, warning, or error');\n return;\n }\n\n const validAttrs = this._validateAttributes(attributes);\n\n if (severity === 'error') {\n this._spanSessionManager.incrSessionCountForKey(KEY_MXL_ERROR_LOG_COUNT);\n }\n\n let stack = '';\n if (severity !== 'info') {\n if (typeof stacktrace === 'string') {\n stack = stacktrace;\n } else if (includeStacktrace) {\n stack = new Error().stack || '';\n }\n }\n\n this._logMessage({\n message: message.trim(),\n severity,\n timestamp: this._perf.getNowMillis(),\n attributes: validAttrs,\n stack,\n });\n }\n\n private _logMessage({\n message,\n severity,\n timestamp,\n attributes = {},\n stack,\n }: {\n message: string;\n severity: LogSeverity;\n timestamp: number;\n attributes?: Attributes;\n stack?: string;\n }) {\n const limitedLog = this._limitManager.limitLog(\n message,\n severity,\n attributes,\n );\n\n if (limitedLog === 'dropped') {\n return;\n }\n\n this._logger.emit({\n timestamp,\n severityNumber: MXLLogManager._logSeverityToSeverityNumber(severity),\n severityText: severity.toUpperCase(),\n body: limitedLog.message,\n attributes: {\n ...limitedLog.attributes,\n [KEY_MXL_TYPE]: MXL_TYPES.SystemLog,\n ...(stack\n ? {\n [KEY_MXL_JS_EXCEPTION_STACKTRACE]: stack,\n [KEY_MXL_JS_FILE_BUNDLE_IDS]: getJSFileBundleIDs(),\n }\n : {}),\n [KEY_MXL_STATE]: getVisibilityState(this._visibilityDoc),\n },\n });\n }\n\n private static _exceptionHandlingType(\n handled: boolean,\n handler: ExceptionHandlerType,\n ): string {\n if (handled) {\n return 'handled';\n }\n\n if (handler === 'global_exception') {\n return 'unhandled_error';\n }\n\n if (handler === 'promise_rejection') {\n return 'unhandled_rejection';\n }\n\n return 'unhandled';\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"MXLLogManager.js","names":[],"sources":["../../../src/managers/MXLLogManager/MXLLogManager.ts"],"sourcesContent":["import type { Attributes, DiagLogger } from '@opentelemetry/api';\nimport { diag } from '@opentelemetry/api';\nimport type { Logger } from '@opentelemetry/api-logs';\nimport { logs, SeverityNumber } from '@opentelemetry/api-logs';\nimport {\n ATTR_EXCEPTION_MESSAGE,\n ATTR_EXCEPTION_STACKTRACE,\n ATTR_EXCEPTION_TYPE,\n} from '@opentelemetry/semantic-conventions';\nimport type { LogManager, LogSeverity } from '../../api-logs';\nimport type {\n LogExceptionOptions,\n LogMessageOptions,\n} from '../../api-logs/manager';\nimport type { ExceptionHandlerType } from '../../api-logs/manager/types';\nimport type { VisibilityStateDocument } from '../../common';\nimport {\n KEY_MXL_EXCEPTION_HANDLING,\n KEY_MXL_EXCEPTION_NUMBER,\n KEY_MXL_JS_EXCEPTION_STACKTRACE,\n KEY_MXL_STATE,\n KEY_MXL_TYPE,\n MXL_TYPES,\n} from '../../constants';\nimport {\n KEY_MXL_ERROR_LOG_COUNT,\n KEY_MXL_EXCEPTION_CAUSE,\n KEY_MXL_JS_FILE_BUNDLE_IDS,\n KEY_MXL_UNHANDLED_EXCEPTIONS_COUNT,\n KEY_REACT_COMPONENT_STACK,\n} from '../../constants/attributes';\nimport type { PerformanceManager } from '../../utils';\nimport {\n GLOBAL_CONFIG,\n getIncrementedCount,\n getVisibilityState,\n OTelPerformanceManager,\n} from '../../utils';\nimport type { LimitManagerInternal } from '../MXLLimitManager';\nimport type { SpanSessionManagerInternal } from '../MXLSpanSessionManager';\nimport type { MXLLogManagerArgs } from './types';\n\nconst MXL_EXCEPTION_NUMBER_STORAGE_KEY = 'mxl_exception_number';\n/**\n * GLOBAL_CONFIG._MXLFileBundleIDs is populated at runtime when each file is loaded,\n * based on the contents injected by the mxl-web-cli.\n */\nconst getJSFileBundleIDs = () =>\n JSON.stringify(\n GLOBAL_CONFIG._MXLFileBundleIDs || GLOBAL_CONFIG._MXLFileBundleIDs || {},\n );\n\nexport class MXLLogManager implements LogManager {\n private readonly _diag: DiagLogger;\n private readonly _perf: PerformanceManager;\n private readonly _logger: Logger;\n private readonly _spanSessionManager: SpanSessionManagerInternal;\n private readonly _limitManager: LimitManagerInternal;\n private readonly _visibilityDoc: VisibilityStateDocument;\n private readonly _storage: Storage;\n\n public constructor({\n diag: diagParam,\n perf,\n spanSessionManager,\n limitManager,\n loggerProvider: globalLoggerProviderOverride,\n visibilityDoc = window.document,\n storage = window.localStorage,\n }: MXLLogManagerArgs) {\n const loggerProvider = globalLoggerProviderOverride ?? logs;\n\n this._diag =\n diagParam ??\n diag.createComponentLogger({\n namespace: 'MXLLogManager',\n });\n this._perf = perf ?? new OTelPerformanceManager();\n this._logger = loggerProvider.getLogger('mxl-web-sdk-logs');\n this._spanSessionManager = spanSessionManager;\n this._limitManager = limitManager;\n this._visibilityDoc = visibilityDoc;\n this._storage = storage;\n }\n\n private _validateAttributes(attributes: unknown): Attributes {\n if (Object.prototype.toString.call(attributes) !== '[object Object]') {\n this._diag.warn('attributes must be a plain object', attributes);\n return {};\n }\n return attributes as Attributes;\n }\n\n private static _logSeverityToSeverityNumber(\n severity: LogSeverity,\n ): SeverityNumber {\n switch (severity) {\n case 'info':\n return SeverityNumber.INFO;\n case 'warning':\n return SeverityNumber.WARN;\n default:\n return SeverityNumber.ERROR;\n }\n }\n\n public logException(\n error: unknown,\n {\n handled = true,\n attributes = {},\n timestamp = this._perf.getNowMillis(),\n handler = 'manual',\n }: LogExceptionOptions = {},\n ) {\n const validAttrs = this._validateAttributes(attributes);\n\n if (!handled) {\n this._spanSessionManager.incrSessionCountForKey(\n KEY_MXL_UNHANDLED_EXCEPTIONS_COUNT,\n );\n }\n\n const type = error?.constructor?.name || typeof error;\n let errMessage = '';\n let errName = type;\n let errStack = '';\n let errCause = '';\n\n if (error instanceof Error) {\n errMessage = String(error.message || '').trim();\n errName = error.name || '';\n errStack = error.stack || '';\n errCause = error.cause ? 'present' : '';\n } else if (error && typeof error === 'object') {\n try {\n errMessage = JSON.stringify(error);\n } catch {\n errMessage = String(error).trim();\n }\n } else {\n errMessage = String(error).trim();\n }\n\n const {\n [KEY_REACT_COMPONENT_STACK]: reactComponentStack,\n ...attrsForLimiting\n } = validAttrs;\n\n const limited = this._limitManager.limitException(\n errMessage,\n attrsForLimiting,\n );\n if (limited === 'dropped') {\n return;\n }\n\n this._logger.emit({\n timestamp,\n severityNumber: SeverityNumber.ERROR,\n severityText: 'ERROR',\n body: limited.message,\n attributes: {\n ...limited.attributes,\n ...(reactComponentStack !== undefined\n ? { [KEY_REACT_COMPONENT_STACK]: String(reactComponentStack) }\n : {}),\n [KEY_MXL_TYPE]: MXL_TYPES.SystemException,\n [KEY_MXL_EXCEPTION_HANDLING]: MXLLogManager._exceptionHandlingType(\n handled,\n handler,\n ),\n [KEY_MXL_EXCEPTION_CAUSE]: errCause,\n [ATTR_EXCEPTION_TYPE]: type,\n ['exception.name']: errName,\n [ATTR_EXCEPTION_MESSAGE]: limited.message,\n [ATTR_EXCEPTION_STACKTRACE]: errStack,\n [KEY_MXL_JS_FILE_BUNDLE_IDS]: getJSFileBundleIDs(),\n [KEY_MXL_STATE]: getVisibilityState(this._visibilityDoc),\n [KEY_MXL_EXCEPTION_NUMBER]: getIncrementedCount(\n this._storage,\n MXL_EXCEPTION_NUMBER_STORAGE_KEY,\n this._diag,\n ),\n },\n });\n }\n\n public message(\n message: string,\n severity: LogSeverity,\n {\n attributes = {},\n includeStacktrace = true,\n stacktrace,\n }: LogMessageOptions = {},\n ) {\n if (typeof message !== 'string' || !message.trim()) {\n this._diag.warn('Message must be a non-empty string');\n return;\n }\n\n if (!['info', 'warning', 'error'].includes(severity)) {\n this._diag.warn('Severity must be info, warning, or error');\n return;\n }\n\n const validAttrs = this._validateAttributes(attributes);\n\n if (severity === 'error') {\n this._spanSessionManager.incrSessionCountForKey(KEY_MXL_ERROR_LOG_COUNT);\n }\n\n let stack = '';\n if (severity !== 'info') {\n if (typeof stacktrace === 'string') {\n stack = stacktrace;\n } else if (includeStacktrace) {\n stack = new Error().stack || '';\n }\n }\n\n this._logMessage({\n message: message.trim(),\n severity,\n timestamp: this._perf.getNowMillis(),\n attributes: validAttrs,\n stack,\n });\n }\n\n private _logMessage({\n message,\n severity,\n timestamp,\n attributes = {},\n stack,\n }: {\n message: string;\n severity: LogSeverity;\n timestamp: number;\n attributes?: Attributes;\n stack?: string;\n }) {\n const limitedLog = this._limitManager.limitLog(\n message,\n severity,\n attributes,\n );\n\n if (limitedLog === 'dropped') {\n return;\n }\n\n this._logger.emit({\n timestamp,\n severityNumber: MXLLogManager._logSeverityToSeverityNumber(severity),\n severityText: severity.toUpperCase(),\n body: limitedLog.message,\n attributes: {\n ...limitedLog.attributes,\n [KEY_MXL_TYPE]: MXL_TYPES.SystemLog,\n ...(stack\n ? {\n [KEY_MXL_JS_EXCEPTION_STACKTRACE]: stack,\n [KEY_MXL_JS_FILE_BUNDLE_IDS]: getJSFileBundleIDs(),\n }\n : {}),\n [KEY_MXL_STATE]: getVisibilityState(this._visibilityDoc),\n },\n });\n }\n\n private static _exceptionHandlingType(\n handled: boolean,\n handler: ExceptionHandlerType,\n ): string {\n if (handled) {\n return 'handled';\n }\n\n if (handler === 'global_exception') {\n return 'unhandled_error';\n }\n\n if (handler === 'promise_rejection') {\n return 'unhandled_rejection';\n }\n\n return 'unhandled';\n }\n}\n"],"mappings":"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"}