@newrelic/browser-agent 1.232.0 → 1.233.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (273) hide show
  1. package/dist/cjs/cdn/polyfills.js +5 -2
  2. package/dist/cjs/common/config/state/configurable.js +15 -26
  3. package/dist/cjs/common/config/state/info.js +1 -1
  4. package/dist/cjs/common/config/state/init.js +101 -56
  5. package/dist/cjs/common/config/state/loader-config.js +1 -1
  6. package/dist/cjs/common/config/state/runtime.js +1 -5
  7. package/dist/cjs/common/constants/env.cdn.js +1 -1
  8. package/dist/cjs/common/constants/env.npm.js +1 -1
  9. package/dist/cjs/common/drain/drain.js +1 -1
  10. package/dist/cjs/common/harvest/harvest-scheduler.js +30 -10
  11. package/dist/cjs/common/harvest/harvest.js +119 -55
  12. package/dist/cjs/common/session/session-entity.js +35 -22
  13. package/dist/cjs/common/session/session-entity.test.js +73 -49
  14. package/dist/cjs/common/timer/interaction-timer.js +9 -12
  15. package/dist/cjs/common/url/canonicalize-url.js +32 -0
  16. package/dist/cjs/common/url/canonicalize-url.test.js +42 -0
  17. package/dist/cjs/common/url/clean-url.js +10 -3
  18. package/dist/cjs/common/url/protocol.test.js +0 -1
  19. package/dist/cjs/common/util/feature-flags.js +2 -1
  20. package/dist/cjs/common/util/global-scope.js +4 -2
  21. package/dist/cjs/common/util/submit-data.js +57 -18
  22. package/dist/cjs/common/wrap/wrap-fetch.js +1 -3
  23. package/dist/cjs/common/wrap/wrap-function.js +1 -3
  24. package/dist/cjs/common/wrap/wrap-promise.js +1 -1
  25. package/dist/cjs/features/ajax/aggregate/index.js +2 -2
  26. package/dist/cjs/features/ajax/instrument/index.js +1 -1
  27. package/dist/cjs/features/jserrors/aggregate/canonical-function-name.js +12 -4
  28. package/dist/cjs/features/jserrors/aggregate/compute-stack-trace.js +93 -10
  29. package/dist/cjs/features/jserrors/aggregate/compute-stack-trace.test.js +164 -38
  30. package/dist/cjs/features/jserrors/aggregate/index.js +29 -48
  31. package/dist/cjs/features/jserrors/instrument/index.js +0 -2
  32. package/dist/cjs/features/metrics/aggregate/framework-detection.js +67 -0
  33. package/dist/cjs/features/metrics/aggregate/framework-detection.test.js +137 -0
  34. package/dist/cjs/features/metrics/aggregate/index.js +7 -3
  35. package/dist/cjs/features/metrics/aggregate/polyfill-detection.es5.js +14 -0
  36. package/dist/cjs/features/metrics/aggregate/polyfill-detection.es5.test.js +17 -0
  37. package/dist/cjs/features/metrics/aggregate/polyfill-detection.js +53 -0
  38. package/dist/cjs/features/metrics/aggregate/polyfill-detection.test.js +165 -0
  39. package/dist/cjs/features/page_action/aggregate/index.js +2 -2
  40. package/dist/cjs/features/page_view_event/aggregate/index.js +6 -3
  41. package/dist/cjs/features/page_view_timing/aggregate/index.js +2 -2
  42. package/dist/cjs/features/session_replay/aggregate/index.js +333 -0
  43. package/dist/cjs/features/session_replay/constants.js +9 -0
  44. package/dist/cjs/features/session_replay/index.js +12 -0
  45. package/dist/cjs/features/session_replay/instrument/index.js +29 -0
  46. package/dist/cjs/features/session_trace/aggregate/index.js +163 -164
  47. package/dist/cjs/features/session_trace/constants.js +2 -9
  48. package/dist/cjs/features/session_trace/instrument/index.js +24 -66
  49. package/dist/cjs/features/spa/aggregate/index.js +2 -2
  50. package/dist/cjs/features/utils/agent-session.js +1 -2
  51. package/dist/cjs/features/utils/aggregate-base.js +64 -0
  52. package/dist/cjs/features/utils/feature-base.js +0 -31
  53. package/dist/cjs/features/utils/handler-cache.js +3 -4
  54. package/dist/cjs/features/utils/instrument-base.js +42 -10
  55. package/dist/cjs/features/utils/{lazy-loader.js → lazy-feature-loader.js} +4 -2
  56. package/dist/cjs/loaders/agent.js +1 -1
  57. package/dist/cjs/loaders/api/apiAsync.js +3 -1
  58. package/dist/cjs/loaders/configure/configure.js +3 -3
  59. package/dist/cjs/loaders/features/featureDependencies.js +0 -12
  60. package/dist/cjs/loaders/features/features.js +3 -1
  61. package/dist/cjs/loaders/micro-agent.js +6 -6
  62. package/dist/esm/cdn/polyfills.js +5 -2
  63. package/dist/esm/common/config/state/configurable.js +14 -24
  64. package/dist/esm/common/config/state/info.js +2 -2
  65. package/dist/esm/common/config/state/init.js +102 -57
  66. package/dist/esm/common/config/state/loader-config.js +2 -2
  67. package/dist/esm/common/config/state/runtime.js +2 -4
  68. package/dist/esm/common/constants/env.cdn.js +1 -1
  69. package/dist/esm/common/constants/env.npm.js +1 -1
  70. package/dist/esm/common/drain/drain.js +1 -1
  71. package/dist/esm/common/harvest/harvest-scheduler.js +30 -10
  72. package/dist/esm/common/harvest/harvest.js +121 -56
  73. package/dist/esm/common/session/session-entity.js +35 -22
  74. package/dist/esm/common/session/session-entity.test.js +73 -49
  75. package/dist/esm/common/timer/interaction-timer.js +9 -12
  76. package/dist/esm/common/url/canonicalize-url.js +27 -0
  77. package/dist/esm/common/url/canonicalize-url.test.js +38 -0
  78. package/dist/esm/common/url/clean-url.js +10 -3
  79. package/dist/esm/common/url/protocol.test.js +0 -1
  80. package/dist/esm/common/util/feature-flags.js +2 -1
  81. package/dist/esm/common/util/global-scope.js +1 -0
  82. package/dist/esm/common/util/submit-data.js +57 -18
  83. package/dist/esm/common/wrap/wrap-fetch.js +1 -2
  84. package/dist/esm/common/wrap/wrap-function.js +1 -2
  85. package/dist/esm/common/wrap/wrap-promise.js +1 -1
  86. package/dist/esm/features/ajax/aggregate/index.js +2 -2
  87. package/dist/esm/features/ajax/instrument/index.js +1 -1
  88. package/dist/esm/features/jserrors/aggregate/canonical-function-name.js +12 -4
  89. package/dist/esm/features/jserrors/aggregate/compute-stack-trace.js +93 -10
  90. package/dist/esm/features/jserrors/aggregate/compute-stack-trace.test.js +149 -25
  91. package/dist/esm/features/jserrors/aggregate/index.js +30 -48
  92. package/dist/esm/features/jserrors/instrument/index.js +0 -1
  93. package/dist/esm/features/metrics/aggregate/framework-detection.js +61 -0
  94. package/dist/esm/features/metrics/aggregate/framework-detection.test.js +133 -0
  95. package/dist/esm/features/metrics/aggregate/index.js +7 -3
  96. package/dist/esm/features/metrics/aggregate/polyfill-detection.es5.js +8 -0
  97. package/dist/esm/features/metrics/aggregate/polyfill-detection.es5.test.js +15 -0
  98. package/dist/esm/features/metrics/aggregate/polyfill-detection.js +47 -0
  99. package/dist/esm/features/metrics/aggregate/polyfill-detection.test.js +163 -0
  100. package/dist/esm/features/page_action/aggregate/index.js +2 -2
  101. package/dist/esm/features/page_view_event/aggregate/index.js +6 -3
  102. package/dist/esm/features/page_view_timing/aggregate/index.js +2 -2
  103. package/dist/esm/features/session_replay/aggregate/index.js +327 -0
  104. package/dist/esm/features/session_replay/constants.js +2 -0
  105. package/dist/esm/features/session_replay/index.js +12 -0
  106. package/dist/esm/features/session_replay/instrument/index.js +21 -0
  107. package/dist/esm/features/session_trace/aggregate/index.js +163 -163
  108. package/dist/esm/features/session_trace/constants.js +1 -5
  109. package/dist/esm/features/session_trace/instrument/index.js +24 -66
  110. package/dist/esm/features/spa/aggregate/index.js +2 -2
  111. package/dist/esm/features/utils/agent-session.js +1 -2
  112. package/dist/esm/features/utils/aggregate-base.js +57 -0
  113. package/dist/esm/features/utils/feature-base.js +1 -32
  114. package/dist/esm/features/utils/handler-cache.js +3 -4
  115. package/dist/esm/features/utils/instrument-base.js +42 -10
  116. package/dist/esm/features/utils/{lazy-loader.js → lazy-feature-loader.js} +3 -1
  117. package/dist/esm/loaders/agent.js +1 -1
  118. package/dist/esm/loaders/api/apiAsync.js +3 -1
  119. package/dist/esm/loaders/configure/configure.js +3 -3
  120. package/dist/esm/loaders/features/featureDependencies.js +0 -11
  121. package/dist/esm/loaders/features/features.js +3 -1
  122. package/dist/esm/loaders/micro-agent.js +6 -6
  123. package/dist/types/common/config/state/configurable.d.ts +1 -3
  124. package/dist/types/common/config/state/configurable.d.ts.map +1 -1
  125. package/dist/types/common/config/state/init.d.ts.map +1 -1
  126. package/dist/types/common/config/state/runtime.d.ts.map +1 -1
  127. package/dist/types/common/harvest/harvest-scheduler.d.ts.map +1 -1
  128. package/dist/types/common/harvest/harvest.d.ts +37 -34
  129. package/dist/types/common/harvest/harvest.d.ts.map +1 -1
  130. package/dist/types/common/session/session-entity.d.ts +6 -3
  131. package/dist/types/common/session/session-entity.d.ts.map +1 -1
  132. package/dist/types/common/timer/interaction-timer.d.ts +2 -1
  133. package/dist/types/common/timer/interaction-timer.d.ts.map +1 -1
  134. package/dist/types/common/url/canonicalize-url.d.ts +9 -0
  135. package/dist/types/common/url/canonicalize-url.d.ts.map +1 -0
  136. package/dist/types/common/url/clean-url.d.ts +7 -1
  137. package/dist/types/common/url/clean-url.d.ts.map +1 -1
  138. package/dist/types/common/util/feature-flags.d.ts.map +1 -1
  139. package/dist/types/common/util/global-scope.d.ts +1 -0
  140. package/dist/types/common/util/global-scope.d.ts.map +1 -1
  141. package/dist/types/common/util/submit-data.d.ts +40 -14
  142. package/dist/types/common/util/submit-data.d.ts.map +1 -1
  143. package/dist/types/common/wrap/wrap-fetch.d.ts.map +1 -1
  144. package/dist/types/common/wrap/wrap-function.d.ts.map +1 -1
  145. package/dist/types/features/ajax/aggregate/index.d.ts +2 -2
  146. package/dist/types/features/ajax/aggregate/index.d.ts.map +1 -1
  147. package/dist/types/features/jserrors/aggregate/canonical-function-name.d.ts +8 -1
  148. package/dist/types/features/jserrors/aggregate/canonical-function-name.d.ts.map +1 -1
  149. package/dist/types/features/jserrors/aggregate/compute-stack-trace.d.ts +48 -19
  150. package/dist/types/features/jserrors/aggregate/compute-stack-trace.d.ts.map +1 -1
  151. package/dist/types/features/jserrors/aggregate/index.d.ts +14 -5
  152. package/dist/types/features/jserrors/aggregate/index.d.ts.map +1 -1
  153. package/dist/types/features/jserrors/instrument/index.d.ts.map +1 -1
  154. package/dist/types/features/metrics/aggregate/framework-detection.d.ts.map +1 -0
  155. package/dist/types/features/metrics/aggregate/index.d.ts +2 -2
  156. package/dist/types/features/metrics/aggregate/index.d.ts.map +1 -1
  157. package/dist/types/features/metrics/aggregate/polyfill-detection.d.ts +6 -0
  158. package/dist/types/features/metrics/aggregate/polyfill-detection.d.ts.map +1 -0
  159. package/dist/types/features/metrics/aggregate/polyfill-detection.es5.d.ts +7 -0
  160. package/dist/types/features/metrics/aggregate/polyfill-detection.es5.d.ts.map +1 -0
  161. package/dist/types/features/page_action/aggregate/index.d.ts +3 -3
  162. package/dist/types/features/page_action/aggregate/index.d.ts.map +1 -1
  163. package/dist/types/features/page_view_event/aggregate/index.d.ts +2 -2
  164. package/dist/types/features/page_view_event/aggregate/index.d.ts.map +1 -1
  165. package/dist/types/features/page_view_timing/aggregate/index.d.ts +2 -2
  166. package/dist/types/features/page_view_timing/aggregate/index.d.ts.map +1 -1
  167. package/dist/types/features/session_replay/aggregate/index.d.ts +96 -0
  168. package/dist/types/features/session_replay/aggregate/index.d.ts.map +1 -0
  169. package/dist/types/features/session_replay/constants.d.ts +2 -0
  170. package/dist/types/features/session_replay/constants.d.ts.map +1 -0
  171. package/dist/types/features/session_replay/index.d.ts +2 -0
  172. package/dist/types/features/session_replay/index.d.ts.map +1 -0
  173. package/dist/types/features/session_replay/instrument/index.d.ts +6 -0
  174. package/dist/types/features/session_replay/instrument/index.d.ts.map +1 -0
  175. package/dist/types/features/session_trace/aggregate/index.d.ts +8 -57
  176. package/dist/types/features/session_trace/aggregate/index.d.ts.map +1 -1
  177. package/dist/types/features/session_trace/constants.d.ts +0 -3
  178. package/dist/types/features/session_trace/constants.d.ts.map +1 -1
  179. package/dist/types/features/session_trace/instrument/index.d.ts +1 -3
  180. package/dist/types/features/session_trace/instrument/index.d.ts.map +1 -1
  181. package/dist/types/features/spa/aggregate/index.d.ts +2 -2
  182. package/dist/types/features/spa/aggregate/index.d.ts.map +1 -1
  183. package/dist/types/features/utils/agent-session.d.ts.map +1 -1
  184. package/dist/types/features/utils/aggregate-base.d.ts +11 -0
  185. package/dist/types/features/utils/aggregate-base.d.ts.map +1 -0
  186. package/dist/types/features/utils/feature-base.d.ts +0 -5
  187. package/dist/types/features/utils/feature-base.d.ts.map +1 -1
  188. package/dist/types/features/utils/handler-cache.d.ts.map +1 -1
  189. package/dist/types/features/utils/instrument-base.d.ts +3 -1
  190. package/dist/types/features/utils/instrument-base.d.ts.map +1 -1
  191. package/dist/types/features/utils/{lazy-loader.d.ts → lazy-feature-loader.d.ts} +2 -2
  192. package/dist/types/features/utils/lazy-feature-loader.d.ts.map +1 -0
  193. package/dist/types/loaders/configure/configure.d.ts.map +1 -1
  194. package/dist/types/loaders/features/featureDependencies.d.ts +0 -1
  195. package/dist/types/loaders/features/featureDependencies.d.ts.map +1 -1
  196. package/dist/types/loaders/features/features.d.ts +1 -0
  197. package/dist/types/loaders/features/features.d.ts.map +1 -1
  198. package/package.json +31 -22
  199. package/src/cdn/polyfills.js +4 -1
  200. package/src/common/config/state/configurable.js +18 -24
  201. package/src/common/config/state/info.js +2 -2
  202. package/src/common/config/state/init.js +62 -28
  203. package/src/common/config/state/loader-config.js +2 -2
  204. package/src/common/config/state/runtime.js +2 -4
  205. package/src/common/drain/drain.js +1 -1
  206. package/src/common/harvest/harvest-scheduler.js +35 -10
  207. package/src/common/harvest/harvest.js +73 -50
  208. package/src/common/session/session-entity.js +34 -23
  209. package/src/common/session/session-entity.test.js +57 -51
  210. package/src/common/timer/interaction-timer.js +9 -12
  211. package/src/common/url/canonicalize-url.js +28 -0
  212. package/src/common/url/canonicalize-url.test.js +34 -0
  213. package/src/common/url/clean-url.js +10 -3
  214. package/src/common/url/protocol.test.js +0 -1
  215. package/src/common/util/feature-flags.js +2 -2
  216. package/src/common/util/global-scope.js +2 -0
  217. package/src/common/util/submit-data.js +28 -17
  218. package/src/common/wrap/wrap-fetch.js +1 -2
  219. package/src/common/wrap/wrap-function.js +1 -2
  220. package/src/common/wrap/wrap-promise.js +1 -1
  221. package/src/features/ajax/aggregate/index.js +2 -2
  222. package/src/features/ajax/instrument/index.js +1 -1
  223. package/src/features/jserrors/aggregate/canonical-function-name.js +12 -4
  224. package/src/features/jserrors/aggregate/compute-stack-trace.js +85 -11
  225. package/src/features/jserrors/aggregate/compute-stack-trace.test.js +141 -24
  226. package/src/features/jserrors/aggregate/index.js +28 -52
  227. package/src/features/jserrors/instrument/index.js +0 -1
  228. package/src/features/metrics/aggregate/framework-detection.js +73 -0
  229. package/src/features/metrics/aggregate/framework-detection.test.js +201 -0
  230. package/src/features/metrics/aggregate/index.js +8 -3
  231. package/src/features/metrics/aggregate/polyfill-detection.es5.js +9 -0
  232. package/src/features/metrics/aggregate/polyfill-detection.es5.test.js +16 -0
  233. package/src/features/metrics/aggregate/polyfill-detection.js +48 -0
  234. package/src/features/metrics/aggregate/polyfill-detection.test.js +163 -0
  235. package/src/features/page_action/aggregate/index.js +2 -2
  236. package/src/features/page_view_event/aggregate/index.js +5 -5
  237. package/src/features/page_view_timing/aggregate/index.js +2 -2
  238. package/src/features/session_replay/aggregate/index.js +314 -0
  239. package/src/features/session_replay/constants.js +3 -0
  240. package/src/features/session_replay/index.js +12 -0
  241. package/src/features/session_replay/instrument/index.js +22 -0
  242. package/src/features/session_trace/aggregate/index.js +148 -188
  243. package/src/features/session_trace/constants.js +0 -4
  244. package/src/features/session_trace/instrument/index.js +17 -69
  245. package/src/features/spa/aggregate/index.js +2 -2
  246. package/src/features/utils/agent-session.js +1 -2
  247. package/src/features/utils/aggregate-base.js +51 -0
  248. package/src/features/utils/feature-base.js +1 -31
  249. package/src/features/utils/handler-cache.js +3 -4
  250. package/src/features/utils/instrument-base.js +40 -8
  251. package/src/features/utils/{lazy-loader.js → lazy-feature-loader.js} +3 -1
  252. package/src/loaders/agent.js +1 -1
  253. package/src/loaders/api/apiAsync.js +1 -1
  254. package/src/loaders/configure/configure.js +4 -3
  255. package/src/loaders/features/featureDependencies.js +0 -12
  256. package/src/loaders/features/features.js +3 -1
  257. package/src/loaders/micro-agent.js +4 -4
  258. package/dist/cjs/common/metrics/framework-detection.js +0 -72
  259. package/dist/cjs/common/util/user-agent.js +0 -57
  260. package/dist/cjs/common/window/supports-performance-observer.js +0 -15
  261. package/dist/esm/common/metrics/framework-detection.js +0 -66
  262. package/dist/esm/common/util/user-agent.js +0 -48
  263. package/dist/esm/common/window/supports-performance-observer.js +0 -9
  264. package/dist/types/common/metrics/framework-detection.d.ts.map +0 -1
  265. package/dist/types/common/util/user-agent.d.ts +0 -5
  266. package/dist/types/common/util/user-agent.d.ts.map +0 -1
  267. package/dist/types/common/window/supports-performance-observer.d.ts +0 -2
  268. package/dist/types/common/window/supports-performance-observer.d.ts.map +0 -1
  269. package/dist/types/features/utils/lazy-loader.d.ts.map +0 -1
  270. package/src/common/metrics/framework-detection.js +0 -71
  271. package/src/common/util/user-agent.js +0 -56
  272. package/src/common/window/supports-performance-observer.js +0 -10
  273. /package/dist/types/{common/metrics → features/metrics/aggregate}/framework-detection.d.ts +0 -0
@@ -0,0 +1,21 @@
1
+ /*
2
+ * Copyright 2023 New Relic Corporation. All rights reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+ /**
6
+ * @file Primes the Session Replay feature for lazy loading.
7
+ *
8
+ * NOTE: This code is under development and dormant. It will not download to instrumented pages or record any data.
9
+ * It is not production ready, and is not intended to be imported or implemented in any build of the browser agent until
10
+ * functionality is validated and a full user experience is curated.
11
+ */
12
+ import { InstrumentBase } from '../../utils/instrument-base';
13
+ import { FEATURE_NAME } from '../constants';
14
+ export class Instrument extends InstrumentBase {
15
+ static featureName = FEATURE_NAME;
16
+ constructor(agentIdentifier, aggregator) {
17
+ let auto = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
18
+ super(agentIdentifier, aggregator, FEATURE_NAME, auto);
19
+ this.importAggregator();
20
+ }
21
+ }
@@ -4,87 +4,62 @@
4
4
  */
5
5
  import { registerHandler } from '../../../common/event-emitter/register-handler';
6
6
  import { HarvestScheduler } from '../../../common/harvest/harvest-scheduler';
7
- import { mapOwn } from '../../../common/util/map-own';
8
7
  import { stringify } from '../../../common/util/stringify';
9
8
  import { parseUrl } from '../../../common/url/parse-url';
10
- import { supportsPerformanceObserver } from '../../../common/window/supports-performance-observer';
11
- import slice from 'lodash._slice';
12
9
  import { getConfigurationValue, getInfo, getRuntime } from '../../../common/config/config';
13
10
  import { now } from '../../../common/timing/now';
14
11
  import { FEATURE_NAME } from '../constants';
15
12
  import { drain } from '../../../common/drain/drain';
16
13
  import { HandlerCache } from '../../utils/handler-cache';
17
- import { FeatureBase } from '../../utils/feature-base';
18
- export class Aggregate extends FeatureBase {
14
+ import { AggregateBase } from '../../utils/aggregate-base';
15
+ const ignoredEvents = {
16
+ // we find that certain events make the data too noisy to be useful
17
+ global: {
18
+ mouseup: true,
19
+ mousedown: true
20
+ },
21
+ // certain events are present both in the window and in PVT metrics. PVT metrics are prefered so the window events should be ignored
22
+ window: {
23
+ load: true,
24
+ pagehide: true
25
+ },
26
+ // when ajax instrumentation is disabled, all XMLHttpRequest events will return with origin = xhrOriginMissing and should be ignored
27
+ xhrOriginMissing: {
28
+ ignoreAll: true
29
+ }
30
+ };
31
+ const toAggregate = {
32
+ typing: [1000, 2000],
33
+ scrolling: [100, 1000],
34
+ mousing: [1000, 2000],
35
+ touching: [1000, 2000]
36
+ };
37
+ const MAX_TRACE_DURATION = 15 * 60 * 1000; // 15 minutes
38
+
39
+ export class Aggregate extends AggregateBase {
19
40
  static featureName = FEATURE_NAME;
20
- constructor(agentIdentifier, aggregator) {
41
+ constructor(agentIdentifier, aggregator, argsObj) {
21
42
  var _this;
22
43
  // Very unlikely, but in case the existing XMLHttpRequest.prototype object on the page couldn't be wrapped.
23
44
  super(agentIdentifier, aggregator, FEATURE_NAME);
24
45
  _this = this;
25
46
  if (!getRuntime(agentIdentifier).xhrWrappable) return;
26
- const handlerCache = new HandlerCache();
47
+ this.resourceObserver = argsObj?.resourceObserver; // undefined if observer couldn't be created
27
48
  this.ptid = '';
28
- this.ignoredEvents = {
29
- // we find that certain events make the data too noisy to be useful
30
- global: {
31
- mouseup: true,
32
- mousedown: true
33
- },
34
- // certain events are present both in the window and in PVT metrics. PVT metrics are prefered so the window events should be ignored
35
- window: {
36
- load: true,
37
- pagehide: true
38
- },
39
- // when ajax instrumentation is disabled, all XMLHttpRequest events will return with origin = xhrOriginMissing and should be ignored
40
- xhrOriginMissing: {
41
- ignoreAll: true
42
- }
43
- };
44
- this.toAggregate = {
45
- typing: [1000, 2000],
46
- scrolling: [100, 1000],
47
- mousing: [1000, 2000],
48
- touching: [1000, 2000]
49
- };
50
- this.rename = {
51
- typing: {
52
- keydown: true,
53
- keyup: true,
54
- keypress: true
55
- },
56
- mousing: {
57
- mousemove: true,
58
- mouseenter: true,
59
- mouseleave: true,
60
- mouseover: true,
61
- mouseout: true
62
- },
63
- scrolling: {
64
- scroll: true
65
- },
66
- touching: {
67
- touchstart: true,
68
- touchmove: true,
69
- touchend: true,
70
- touchcancel: true,
71
- touchenter: true,
72
- touchleave: true
73
- }
74
- };
75
49
  this.trace = {};
76
50
  this.nodeCount = 0;
77
51
  this.sentTrace = null;
78
52
  this.harvestTimeSeconds = getConfigurationValue(agentIdentifier, 'session_trace.harvestTimeSeconds') || 10;
79
53
  this.maxNodesPerHarvest = getConfigurationValue(agentIdentifier, 'session_trace.maxNodesPerHarvest') || 1000;
80
54
  this.laststart = 0;
55
+ const handlerCache = new HandlerCache();
81
56
  registerHandler('feat-stn', () => {
82
57
  if (typeof PerformanceNavigationTiming !== 'undefined') {
83
- this.storeTiming(window.performance?.getEntriesByType('navigation')?.[0] || {});
58
+ this.storeTiming(window.performance.getEntriesByType('navigation')[0]);
84
59
  } else {
85
- this.storeTiming(window.performance?.timing);
60
+ this.storeTiming(window.performance.timing);
86
61
  }
87
- var scheduler = new HarvestScheduler('resources', {
62
+ const scheduler = new HarvestScheduler('resources', {
88
63
  onFinished: onHarvestFinished.bind(this),
89
64
  retryDelay: this.harvestTimeSeconds
90
65
  }, this);
@@ -92,38 +67,37 @@ export class Aggregate extends FeatureBase {
92
67
  scheduler.runHarvest({
93
68
  needResponse: true
94
69
  }); // sends first stn harvest immediately
95
-
70
+ handlerCache.decide(true);
96
71
  function onHarvestFinished(result) {
97
- // start timer only if ptid was returned by server
98
72
  if (result.sent && result.responseText && !this.ptid) {
99
- this.ptid = result.responseText;
100
- getRuntime(this.agentIdentifier).ptid = this.ptid;
73
+ // continue interval harvest only if ptid was returned by server on the first
74
+ getRuntime(this.agentIdentifier).ptid = this.ptid = result.responseText;
101
75
  scheduler.startTimer(this.harvestTimeSeconds);
102
76
  }
103
77
  if (result.sent && result.retry && this.sentTrace) {
104
- mapOwn(this.sentTrace, (name, nodes) => {
105
- this.mergeSTNs(name, nodes);
78
+ // merge previous trace back into buffer to retry for next harvest
79
+ Object.entries(this.sentTrace).forEach(_ref => {
80
+ let [name, listOfSTNodes] = _ref;
81
+ if (this.nodeCount >= this.maxNodesPerHarvest) return;
82
+ this.nodeCount += listOfSTNodes.length;
83
+ this.trace[name] = this.trace[name] ? listOfSTNodes.concat(this.trace[name]) : listOfSTNodes;
106
84
  });
107
85
  this.sentTrace = null;
108
86
  }
109
87
  }
110
88
  function prepareHarvest(options) {
111
- if (now() > 15 * 60 * 1000) {
89
+ if (now() > MAX_TRACE_DURATION) {
112
90
  // been collecting for over 15 min, empty trace object and bail
113
91
  scheduler.stopTimer();
114
92
  this.trace = {};
115
93
  return;
116
94
  }
117
-
118
- // only send when there are more than 30 nodes to send
95
+ // Only harvest when there are more than 30 nodes to send after the very first.
119
96
  if (this.ptid && this.nodeCount <= 30) return;
120
97
  return this.takeSTNs(options.retry);
121
98
  }
122
- handlerCache.decide(true);
123
- }, this.featureName, this.ee);
124
- registerHandler('block-stn', () => {
125
- handlerCache.decide(false);
126
99
  }, this.featureName, this.ee);
100
+ registerHandler('block-stn', () => handlerCache.decide(false), this.featureName, this.ee);
127
101
 
128
102
  // register the handlers immediately... but let the handlerCache decide if the data should actually get stored...
129
103
  registerHandler('bst', function () {
@@ -176,19 +150,28 @@ export class Aggregate extends FeatureBase {
176
150
  }, this.featureName, this.ee);
177
151
  drain(this.agentIdentifier, this.featureName);
178
152
  }
153
+
154
+ // PageViewTiming (FEATURE) events and metrics, such as 'load', 'lcp', etc. pipes into ST here.
179
155
  processPVT(name, value, attrs) {
180
- var t = {};
181
- t[name] = value;
182
- this.storeTiming(t);
183
- if (this.hasFID(name, attrs)) this.storeEvent({
156
+ this.storeTiming({
157
+ [name]: value
158
+ });
159
+ if (hasFID(name, attrs)) this.storeEvent({
184
160
  type: 'fid',
185
161
  target: 'document'
186
162
  }, 'document', value, value + attrs.fid);
163
+ function hasFID(name, attrs) {
164
+ return name === 'fi' && !!attrs && typeof attrs.fid === 'number';
165
+ }
187
166
  }
188
- storeTiming(_t) {
167
+
168
+ // This processes the aforementioned PVT and the first navigation entry of the page.
169
+ storeTiming(timingEntry) {
170
+ if (!timingEntry) return;
171
+
189
172
  // loop iterates through prototype also (for FF)
190
- for (let key in _t) {
191
- const val = _t[key];
173
+ for (let key in timingEntry) {
174
+ let val = timingEntry[key];
192
175
 
193
176
  // ignore size and status type nodes that do not map to timestamp metrics
194
177
  const lck = key.toLowerCase();
@@ -197,31 +180,33 @@ export class Aggregate extends FeatureBase {
197
180
  // ignore inherited methods, meaningless 0 values, and bogus timestamps
198
181
  // that are in the future (Microsoft Edge seems to sometimes produce these)
199
182
  if (!(typeof val === 'number' && val >= 0)) continue;
200
- const timeOffset = Math.round(_t[key]);
183
+ val = Math.round(val);
201
184
  this.storeSTN({
202
185
  n: key,
203
- s: timeOffset,
204
- e: timeOffset,
186
+ s: val,
187
+ e: val,
205
188
  o: 'document',
206
189
  t: 'timing'
207
190
  });
208
191
  }
209
192
  }
193
+
194
+ // Tracks duration of native APIs wrapped by wrap-timer & wrap-raf.
210
195
  storeTimer(target, start, end, type) {
211
- var category = 'timer';
212
- if (type === 'requestAnimationFrame') category = type;
213
- var evt = {
196
+ const evt = {
214
197
  n: type,
215
198
  s: start,
216
199
  e: end,
217
200
  o: 'window',
218
- t: category
201
+ t: type === 'requestAnimationFrame' ? type : 'timer'
219
202
  };
220
203
  this.storeSTN(evt);
221
204
  }
205
+
206
+ // Tracks the events and their listener's duration on objects wrapped by wrap-events.
222
207
  storeEvent(currentEvent, target, start, end) {
223
- if (this.shouldIgnoreEvent(currentEvent, target)) return false;
224
- var evt = {
208
+ if (this.shouldIgnoreEvent(currentEvent, target)) return;
209
+ const evt = {
225
210
  n: this.evtName(currentEvent.type),
226
211
  s: start,
227
212
  e: end,
@@ -236,31 +221,60 @@ export class Aggregate extends FeatureBase {
236
221
  }
237
222
  this.storeSTN(evt);
238
223
  }
224
+ shouldIgnoreEvent(event, target) {
225
+ const origin = this.evtOrigin(event.target, target);
226
+ if (event.type in ignoredEvents.global) return true;
227
+ if (!!ignoredEvents[origin] && ignoredEvents[origin].ignoreAll) return true;
228
+ if (!!ignoredEvents[origin] && event.type in ignoredEvents[origin]) return true;
229
+ return false;
230
+ }
239
231
  evtName(type) {
240
- var name = type;
241
- mapOwn(this.rename, function (key, val) {
242
- if (type in val) name = key;
243
- });
244
- return name;
232
+ switch (type) {
233
+ case 'keydown':
234
+ case 'keyup':
235
+ case 'keypress':
236
+ return 'typing';
237
+ case 'mousemove':
238
+ case 'mouseenter':
239
+ case 'mouseleave':
240
+ case 'mouseover':
241
+ case 'mouseout':
242
+ return 'mousing';
243
+ case 'scroll':
244
+ return 'scrolling';
245
+ case 'touchstart':
246
+ case 'touchmove':
247
+ case 'touchend':
248
+ case 'touchcancel':
249
+ case 'touchenter':
250
+ case 'touchleave':
251
+ return 'touching';
252
+ default:
253
+ return type;
254
+ }
245
255
  }
246
256
  evtOrigin(t, target) {
247
- var origin = 'unknown';
257
+ let origin = 'unknown';
248
258
  if (t && t instanceof XMLHttpRequest) {
249
- var params = this.ee.context(t).params;
259
+ const params = this.ee.context(t).params;
250
260
  if (!params || !params.status || !params.method || !params.host || !params.pathname) return 'xhrOriginMissing';
251
261
  origin = params.status + ' ' + params.method + ': ' + params.host + params.pathname;
252
262
  } else if (t && typeof t.tagName === 'string') {
253
263
  origin = t.tagName.toLowerCase();
254
264
  if (t.id) origin += '#' + t.id;
255
- if (t.className) origin += '.' + slice(t.classList).join('.');
265
+ if (t.className) {
266
+ for (let i = 0; i < t.classList.length; i++) origin += '.' + t.classList[i];
267
+ }
256
268
  }
257
269
  if (origin === 'unknown') {
258
270
  if (typeof target === 'string') origin = target;else if (target === document) origin = 'document';else if (target === window) origin = 'window';else if (target instanceof FileReader) origin = 'FileReader';
259
271
  }
260
272
  return origin;
261
273
  }
274
+
275
+ // Tracks when the window history API specified by wrap-history is used.
262
276
  storeHist(path, old, time) {
263
- var node = {
277
+ const node = {
264
278
  n: 'history.pushState',
265
279
  s: time,
266
280
  e: time,
@@ -269,11 +283,15 @@ export class Aggregate extends FeatureBase {
269
283
  };
270
284
  this.storeSTN(node);
271
285
  }
286
+
287
+ // Processes all the PerformanceResourceTiming entries captured (by observer).
272
288
  storeResources(resources) {
273
289
  if (!resources || resources.length === 0) return;
274
290
  resources.forEach(currentResource => {
275
- var parsed = parseUrl(currentResource.name);
276
- var res = {
291
+ if ((currentResource.fetchStart | 0) <= this.laststart) return; // don't recollect already-seen resources
292
+
293
+ const parsed = parseUrl(currentResource.name);
294
+ const res = {
277
295
  n: currentResource.initiatorType,
278
296
  s: currentResource.fetchStart | 0,
279
297
  e: currentResource.responseEnd | 0,
@@ -281,16 +299,15 @@ export class Aggregate extends FeatureBase {
281
299
  // resource.name is actually a URL so it's the source
282
300
  t: currentResource.entryType
283
301
  };
284
-
285
- // don't recollect old resources
286
- if (res.s <= this.laststart) return;
287
302
  this.storeSTN(res);
288
303
  });
289
304
  this.laststart = resources[resources.length - 1].fetchStart | 0;
290
305
  }
306
+
307
+ // JavascriptError (FEATURE) events pipes into ST here.
291
308
  storeErrorAgg(type, name, params, metrics) {
292
- if (type !== 'err') return;
293
- var node = {
309
+ if (type !== 'err') return; // internal errors are purposefully ignored
310
+ const node = {
294
311
  n: 'error',
295
312
  s: metrics.time,
296
313
  e: metrics.time,
@@ -299,9 +316,11 @@ export class Aggregate extends FeatureBase {
299
316
  };
300
317
  this.storeSTN(node);
301
318
  }
319
+
320
+ // Ajax (FEATURE) events--XML & fetches--pipes into ST here.
302
321
  storeXhrAgg(type, name, params, metrics) {
303
322
  if (type !== 'xhr') return;
304
- var node = {
323
+ const node = {
305
324
  n: 'Ajax',
306
325
  s: metrics.time,
307
326
  e: metrics.time + metrics.duration,
@@ -310,46 +329,46 @@ export class Aggregate extends FeatureBase {
310
329
  };
311
330
  this.storeSTN(node);
312
331
  }
332
+
333
+ // Central function called by all the other store__ & addToTrace API to append a trace node.
313
334
  storeSTN(stn) {
314
- // limit the number of data that is stored
315
- if (this.nodeCount >= this.maxNodesPerHarvest) return;
316
- var traceArr = this.trace[stn.n];
317
- if (!traceArr) traceArr = this.trace[stn.n] = [];
318
- traceArr.push(stn);
335
+ if (this.nodeCount >= this.maxNodesPerHarvest) return; // limit the amount of data that is stored at once
336
+
337
+ if (this.trace[stn.n]) this.trace[stn.n].push(stn);else this.trace[stn.n] = [stn];
319
338
  this.nodeCount++;
320
339
  }
321
- mergeSTNs(key, nodes) {
322
- // limit the number of data that is stored
323
- if (this.nodeCount >= this.maxNodesPerHarvest) return;
324
- var traceArr = this.trace[key];
325
- if (!traceArr) traceArr = this.trace[key] = [];
326
- this.trace[key] = nodes.concat(traceArr);
327
- this.nodeCount += nodes.length;
328
- }
340
+
341
+ // Used by session trace's harvester to create the payload body.
329
342
  takeSTNs(retry) {
330
- // if the observer is not being used, this checks resourcetiming buffer every harvest
331
- if (!supportsPerformanceObserver()) {
343
+ if (!this.resourceObserver) {
344
+ // if PO isn't supported, this checks resourcetiming buffer every harvest.
332
345
  this.storeResources(window.performance.getEntriesByType('resource'));
333
346
  }
334
- var stns = mapOwn(this.trace, (name, nodes) => {
335
- if (!(name in this.toAggregate)) return nodes;
336
- return mapOwn(nodes.sort(this.byStart).reduce(this.smearEvtsByOrigin(name), {}), this.val).reduce(this.flatten, []);
337
- }).reduce(this.flatten, []);
347
+ const stns = Object.entries(this.trace).flatMap(_ref2 => {
348
+ let [name, listOfSTNodes] = _ref2;
349
+ // basically take the "this.trace" map-obj and concat all the list-type values
350
+ if (!(name in toAggregate)) return listOfSTNodes;
351
+ // Special processing for event nodes dealing with user inputs:
352
+ const reindexByOriginFn = this.smearEvtsByOrigin(name);
353
+ const partitionListByOriginMap = listOfSTNodes.sort((a, b) => a.s - b.s).reduce(reindexByOriginFn, {});
354
+ return Object.values(partitionListByOriginMap).flat(); // join the partitions back into 1-D, now ordered by origin then start time
355
+ }, this);
338
356
  if (stns.length === 0) return {};
339
357
  if (retry) {
340
358
  this.sentTrace = this.trace;
341
359
  }
342
360
  this.trace = {};
343
361
  this.nodeCount = 0;
344
- var stnInfo = {
362
+ const stnInfo = {
345
363
  qs: {
346
- st: '' + getRuntime(this.agentIdentifier).offset
364
+ st: String(getRuntime(this.agentIdentifier).offset)
347
365
  },
348
366
  body: {
349
367
  res: stns
350
368
  }
351
369
  };
352
370
  if (!this.ptid) {
371
+ // send custom and user attributes on the very first ST harvest only
353
372
  const {
354
373
  userAttributes,
355
374
  atts,
@@ -357,53 +376,34 @@ export class Aggregate extends FeatureBase {
357
376
  } = getInfo(this.agentIdentifier);
358
377
  stnInfo.qs.ua = userAttributes;
359
378
  stnInfo.qs.at = atts;
360
- var ja = stringify(jsAttributes);
379
+ const ja = stringify(jsAttributes);
361
380
  stnInfo.qs.ja = ja === '{}' ? null : ja;
362
381
  }
363
382
  return stnInfo;
364
383
  }
365
- byStart(a, b) {
366
- return a.s - b.s;
367
- }
368
384
  smearEvtsByOrigin(name) {
369
- var maxGap = this.toAggregate[name][0];
370
- var maxLen = this.toAggregate[name][1];
371
- var lastO = {};
372
- return (byOrigin, evt) => {
373
- var lastArr = byOrigin[evt.o];
374
- lastArr || (lastArr = byOrigin[evt.o] = []);
375
- var last = lastO[evt.o];
376
- if (name === 'scrolling' && !this.trivial(evt)) {
377
- lastO[evt.o] = null;
378
- evt.n = 'scroll';
379
- lastArr.push(evt);
380
- } else if (last && evt.s - last.s < maxLen && last.e > evt.s - maxGap) {
381
- last.e = evt.e;
385
+ const maxGap = toAggregate[name][0];
386
+ const maxLen = toAggregate[name][1];
387
+ const lastO = {};
388
+ return (byOrigin, evtNode) => {
389
+ let lastArr = byOrigin[evtNode.o];
390
+ if (!lastArr) lastArr = byOrigin[evtNode.o] = [];
391
+ const last = lastO[evtNode.o];
392
+ if (name === 'scrolling' && !trivial(evtNode)) {
393
+ lastO[evtNode.o] = null;
394
+ evtNode.n = 'scroll';
395
+ lastArr.push(evtNode);
396
+ } else if (last && evtNode.s - last.s < maxLen && last.e > evtNode.s - maxGap) {
397
+ last.e = evtNode.e;
382
398
  } else {
383
- lastO[evt.o] = evt;
384
- lastArr.push(evt);
399
+ lastO[evtNode.o] = evtNode;
400
+ lastArr.push(evtNode);
385
401
  }
386
402
  return byOrigin;
387
403
  };
388
- }
389
- val(key, value) {
390
- return value;
391
- }
392
- flatten(a, b) {
393
- return a.concat(b);
394
- }
395
- hasFID(name, attrs) {
396
- return name === 'fi' && !!attrs && typeof attrs.fid === 'number';
397
- }
398
- trivial(node) {
399
- var limit = 4;
400
- if (node && typeof node.e === 'number' && typeof node.s === 'number' && node.e - node.s < limit) return true;else return false;
401
- }
402
- shouldIgnoreEvent(event, target) {
403
- var origin = this.evtOrigin(event.target, target);
404
- if (event.type in this.ignoredEvents.global) return true;
405
- if (!!this.ignoredEvents[origin] && this.ignoredEvents[origin].ignoreAll) return true;
406
- if (!!this.ignoredEvents[origin] && event.type in this.ignoredEvents[origin]) return true;
407
- return false;
404
+ function trivial(node) {
405
+ const limit = 4;
406
+ if (node && typeof node.e === 'number' && typeof node.s === 'number' && node.e - node.s < limit) return true;else return false;
407
+ }
408
408
  }
409
409
  }
@@ -1,7 +1,5 @@
1
- import { originals } from '../../common/config/config';
2
1
  import { FEATURE_NAMES } from '../../loaders/features/features';
3
2
  export const FEATURE_NAME = FEATURE_NAMES.sessionTrace;
4
- export const RESOURCE_TIMING_BUFFER_FULL = 'resourcetimingbufferfull';
5
3
  export const BST_RESOURCE = 'bstResource';
6
4
  export const RESOURCE = 'resource';
7
5
  export const START = '-start';
@@ -9,6 +7,4 @@ export const END = '-end';
9
7
  export const FN_START = 'fn' + START;
10
8
  export const FN_END = 'fn' + END;
11
9
  export const BST_TIMER = 'bstTimer';
12
- export const PUSH_STATE = 'pushState';
13
- export const ORIG_EVENT = originals.EV;
14
- export const ADD_EVENT_LISTENER = 'addEventListener';
10
+ export const PUSH_STATE = 'pushState';