@newrelic/browser-agent 1.238.0 → 1.239.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (249) hide show
  1. package/dist/cjs/common/config/state/init.js +21 -13
  2. package/dist/cjs/common/config/state/runtime.js +0 -4
  3. package/dist/cjs/common/constants/env.cdn.js +1 -1
  4. package/dist/cjs/common/constants/env.npm.js +1 -1
  5. package/dist/cjs/common/constants/runtime.js +3 -3
  6. package/dist/cjs/common/constants/shared-channel.js +3 -1
  7. package/dist/cjs/common/deny-list/deny-list.js +2 -8
  8. package/dist/cjs/common/drain/drain.js +1 -1
  9. package/dist/cjs/common/event-emitter/contextual-ee.js +6 -6
  10. package/dist/cjs/common/harvest/harvest-scheduler.js +2 -4
  11. package/dist/cjs/common/harvest/harvest.js +2 -6
  12. package/dist/cjs/common/serialize/bel-serializer.js +1 -1
  13. package/dist/cjs/common/session/session-entity.js +16 -12
  14. package/dist/cjs/common/storage/first-party-cookies.js +5 -4
  15. package/dist/cjs/common/storage/local-storage.js +3 -2
  16. package/dist/cjs/common/timer/interaction-timer.js +14 -6
  17. package/dist/cjs/common/timing/nav-timing.js +1 -1
  18. package/dist/cjs/common/unload/eol.js +4 -30
  19. package/dist/cjs/common/util/feature-flags.js +14 -15
  20. package/dist/cjs/common/util/invoke.js +3 -1
  21. package/dist/cjs/common/util/obfuscate.js +3 -5
  22. package/dist/cjs/common/util/traverse.js +1 -0
  23. package/dist/cjs/common/window/page-visibility.js +1 -2
  24. package/dist/cjs/common/wrap/wrap-jsonp.js +1 -1
  25. package/dist/cjs/features/ajax/aggregate/index.js +5 -7
  26. package/dist/cjs/features/ajax/instrument/distributed-tracing.js +8 -8
  27. package/dist/cjs/features/ajax/instrument/index.js +47 -15
  28. package/dist/cjs/features/jserrors/aggregate/canonical-function-name.js +0 -1
  29. package/dist/cjs/features/jserrors/aggregate/compute-stack-trace.js +4 -4
  30. package/dist/cjs/features/jserrors/aggregate/index.js +4 -5
  31. package/dist/cjs/features/metrics/aggregate/framework-detection.js +103 -7
  32. package/dist/cjs/features/metrics/aggregate/index.js +20 -37
  33. package/dist/cjs/features/metrics/instrument/index.js +0 -2
  34. package/dist/cjs/features/page_action/aggregate/index.js +17 -19
  35. package/dist/cjs/features/page_view_event/aggregate/index.js +1 -2
  36. package/dist/cjs/features/page_view_event/instrument/index.js +4 -2
  37. package/dist/cjs/features/page_view_timing/aggregate/index.js +6 -7
  38. package/dist/cjs/features/session_replay/aggregate/index.js +3 -3
  39. package/dist/cjs/features/session_trace/aggregate/index.js +8 -8
  40. package/dist/cjs/features/spa/aggregate/index.js +14 -20
  41. package/dist/cjs/features/spa/aggregate/interaction.js +0 -2
  42. package/dist/cjs/features/spa/aggregate/serializer.js +1 -1
  43. package/dist/cjs/features/utils/aggregate-base.js +4 -0
  44. package/dist/cjs/features/utils/handler-cache.js +3 -1
  45. package/dist/cjs/features/utils/instrument-base.js +24 -6
  46. package/dist/cjs/loaders/agent-base.js +11 -0
  47. package/dist/cjs/loaders/agent.js +7 -7
  48. package/dist/cjs/loaders/api/api.js +21 -4
  49. package/dist/cjs/loaders/api/apiAsync.js +19 -20
  50. package/dist/cjs/loaders/configure/configure.js +3 -0
  51. package/dist/cjs/loaders/micro-agent.js +20 -3
  52. package/dist/esm/common/config/state/init.js +21 -13
  53. package/dist/esm/common/config/state/runtime.js +0 -4
  54. package/dist/esm/common/constants/env.cdn.js +1 -1
  55. package/dist/esm/common/constants/env.npm.js +1 -1
  56. package/dist/esm/common/constants/runtime.js +1 -1
  57. package/dist/esm/common/constants/shared-channel.js +3 -1
  58. package/dist/esm/common/deny-list/deny-list.js +2 -8
  59. package/dist/esm/common/drain/drain.js +1 -1
  60. package/dist/esm/common/event-emitter/contextual-ee.js +6 -6
  61. package/dist/esm/common/harvest/harvest-scheduler.js +2 -4
  62. package/dist/esm/common/harvest/harvest.js +2 -6
  63. package/dist/esm/common/serialize/bel-serializer.js +1 -1
  64. package/dist/esm/common/session/session-entity.js +16 -12
  65. package/dist/esm/common/storage/first-party-cookies.js +5 -4
  66. package/dist/esm/common/storage/local-storage.js +3 -2
  67. package/dist/esm/common/timer/interaction-timer.js +14 -6
  68. package/dist/esm/common/timing/nav-timing.js +1 -1
  69. package/dist/esm/common/unload/eol.js +5 -31
  70. package/dist/esm/common/util/feature-flags.js +14 -15
  71. package/dist/esm/common/util/invoke.js +3 -1
  72. package/dist/esm/common/util/obfuscate.js +3 -5
  73. package/dist/esm/common/util/traverse.js +1 -0
  74. package/dist/esm/common/window/page-visibility.js +1 -2
  75. package/dist/esm/common/wrap/wrap-jsonp.js +1 -1
  76. package/dist/esm/features/ajax/aggregate/index.js +5 -7
  77. package/dist/esm/features/ajax/instrument/distributed-tracing.js +8 -8
  78. package/dist/esm/features/ajax/instrument/index.js +47 -15
  79. package/dist/esm/features/jserrors/aggregate/canonical-function-name.js +0 -1
  80. package/dist/esm/features/jserrors/aggregate/compute-stack-trace.js +4 -4
  81. package/dist/esm/features/jserrors/aggregate/index.js +4 -5
  82. package/dist/esm/features/metrics/aggregate/framework-detection.js +103 -7
  83. package/dist/esm/features/metrics/aggregate/index.js +22 -39
  84. package/dist/esm/features/metrics/instrument/index.js +1 -3
  85. package/dist/esm/features/page_action/aggregate/index.js +17 -19
  86. package/dist/esm/features/page_view_event/aggregate/index.js +1 -2
  87. package/dist/esm/features/page_view_event/instrument/index.js +4 -2
  88. package/dist/esm/features/page_view_timing/aggregate/index.js +7 -8
  89. package/dist/esm/features/session_replay/aggregate/index.js +2 -2
  90. package/dist/esm/features/session_trace/aggregate/index.js +8 -8
  91. package/dist/esm/features/spa/aggregate/index.js +14 -20
  92. package/dist/esm/features/spa/aggregate/interaction.js +0 -2
  93. package/dist/esm/features/spa/aggregate/serializer.js +1 -1
  94. package/dist/esm/features/utils/aggregate-base.js +4 -0
  95. package/dist/esm/features/utils/handler-cache.js +3 -1
  96. package/dist/esm/features/utils/instrument-base.js +24 -6
  97. package/dist/esm/loaders/agent-base.js +11 -0
  98. package/dist/esm/loaders/agent.js +7 -7
  99. package/dist/esm/loaders/api/api.js +21 -4
  100. package/dist/esm/loaders/api/apiAsync.js +19 -20
  101. package/dist/esm/loaders/configure/configure.js +3 -0
  102. package/dist/esm/loaders/features/enabled-features.js +1 -1
  103. package/dist/esm/loaders/micro-agent.js +21 -4
  104. package/dist/types/common/config/state/init.d.ts.map +1 -1
  105. package/dist/types/common/config/state/runtime.d.ts.map +1 -1
  106. package/dist/types/common/constants/runtime.d.ts +1 -1
  107. package/dist/types/common/constants/runtime.d.ts.map +1 -1
  108. package/dist/types/common/harvest/harvest-scheduler.d.ts.map +1 -1
  109. package/dist/types/common/harvest/harvest.d.ts.map +1 -1
  110. package/dist/types/common/session/session-entity.d.ts +6 -9
  111. package/dist/types/common/session/session-entity.d.ts.map +1 -1
  112. package/dist/types/common/storage/first-party-cookies.d.ts +1 -1
  113. package/dist/types/common/storage/first-party-cookies.d.ts.map +1 -1
  114. package/dist/types/common/storage/local-storage.d.ts.map +1 -1
  115. package/dist/types/common/timer/interaction-timer.d.ts +3 -0
  116. package/dist/types/common/timer/interaction-timer.d.ts.map +1 -1
  117. package/dist/types/common/unload/eol.d.ts +1 -2
  118. package/dist/types/common/unload/eol.d.ts.map +1 -1
  119. package/dist/types/common/util/feature-flags.d.ts.map +1 -1
  120. package/dist/types/common/util/obfuscate.d.ts.map +1 -1
  121. package/dist/types/common/util/traverse.d.ts.map +1 -1
  122. package/dist/types/common/window/page-visibility.d.ts.map +1 -1
  123. package/dist/types/features/ajax/aggregate/index.d.ts.map +1 -1
  124. package/dist/types/features/ajax/instrument/index.d.ts.map +1 -1
  125. package/dist/types/features/jserrors/aggregate/canonical-function-name.d.ts.map +1 -1
  126. package/dist/types/features/jserrors/aggregate/index.d.ts +1 -1
  127. package/dist/types/features/jserrors/aggregate/index.d.ts.map +1 -1
  128. package/dist/types/features/metrics/aggregate/framework-detection.d.ts.map +1 -1
  129. package/dist/types/features/metrics/aggregate/index.d.ts.map +1 -1
  130. package/dist/types/features/metrics/instrument/index.d.ts.map +1 -1
  131. package/dist/types/features/page_action/aggregate/index.d.ts +2 -2
  132. package/dist/types/features/page_action/aggregate/index.d.ts.map +1 -1
  133. package/dist/types/features/page_view_event/aggregate/index.d.ts.map +1 -1
  134. package/dist/types/features/page_view_timing/aggregate/index.d.ts.map +1 -1
  135. package/dist/types/features/session_replay/aggregate/index.d.ts.map +1 -1
  136. package/dist/types/features/session_trace/aggregate/index.d.ts.map +1 -1
  137. package/dist/types/features/spa/aggregate/index.d.ts.map +1 -1
  138. package/dist/types/features/spa/aggregate/interaction.d.ts.map +1 -1
  139. package/dist/types/features/utils/aggregate-base.d.ts +1 -0
  140. package/dist/types/features/utils/aggregate-base.d.ts.map +1 -1
  141. package/dist/types/features/utils/handler-cache.d.ts.map +1 -1
  142. package/dist/types/features/utils/instrument-base.d.ts.map +1 -1
  143. package/dist/types/loaders/agent-base.d.ts +6 -0
  144. package/dist/types/loaders/agent-base.d.ts.map +1 -1
  145. package/dist/types/loaders/agent.d.ts +1 -1
  146. package/dist/types/loaders/agent.d.ts.map +1 -1
  147. package/dist/types/loaders/api/api.d.ts +1 -0
  148. package/dist/types/loaders/api/api.d.ts.map +1 -1
  149. package/dist/types/loaders/api/apiAsync.d.ts.map +1 -1
  150. package/dist/types/loaders/configure/configure.d.ts +1 -0
  151. package/dist/types/loaders/configure/configure.d.ts.map +1 -1
  152. package/dist/types/loaders/micro-agent.d.ts +7 -1
  153. package/dist/types/loaders/micro-agent.d.ts.map +1 -1
  154. package/package.json +41 -12
  155. package/src/common/aggregate/aggregator.test.js +107 -0
  156. package/src/common/config/state/configurable.test.js +73 -0
  157. package/src/common/config/state/info.test.js +31 -0
  158. package/src/common/config/state/init.js +13 -12
  159. package/src/common/config/state/init.test.js +28 -0
  160. package/src/common/config/state/loader-config.test.js +21 -0
  161. package/src/common/config/state/runtime.js +0 -2
  162. package/src/common/config/state/runtime.test.js +21 -0
  163. package/src/common/constants/__mocks__/runtime.js +1 -1
  164. package/src/common/constants/runtime.js +1 -1
  165. package/src/common/constants/runtime.test.js +2 -2
  166. package/src/common/constants/shared-channel.js +1 -1
  167. package/src/common/deny-list/deny-list.js +2 -10
  168. package/src/common/drain/drain.js +1 -1
  169. package/src/common/drain/drain.test.js +74 -0
  170. package/src/common/event-emitter/contextual-ee.js +6 -6
  171. package/src/common/harvest/harvest-scheduler.js +2 -5
  172. package/src/common/harvest/harvest-scheduler.test.js +2 -6
  173. package/src/common/harvest/harvest.js +2 -6
  174. package/src/common/harvest/harvest.test.js +0 -2
  175. package/src/common/ids/id.test.js +6 -6
  176. package/src/common/serialize/bel-serializer.js +1 -1
  177. package/src/common/session/session-entity.component-test.js +3 -2
  178. package/src/common/session/session-entity.js +11 -9
  179. package/src/common/storage/first-party-cookies.js +5 -4
  180. package/src/common/storage/local-storage.js +3 -2
  181. package/src/common/timer/interaction-timer.component-test.js +52 -7
  182. package/src/common/timer/interaction-timer.js +15 -6
  183. package/src/common/timer/timer.test.js +0 -1
  184. package/src/common/timing/nav-timing.js +1 -1
  185. package/src/common/unload/eol.js +5 -31
  186. package/src/common/url/encode.test.js +1 -0
  187. package/src/common/util/__mocks__/invoke.js +1 -0
  188. package/src/common/util/data-size.test.js +0 -1
  189. package/src/common/util/feature-flags.js +15 -17
  190. package/src/common/util/feature-flags.test.js +4 -8
  191. package/src/common/util/invoke.js +1 -1
  192. package/src/common/util/obfuscate.js +3 -5
  193. package/src/common/util/submit-data.test.js +1 -1
  194. package/src/common/util/traverse.js +1 -0
  195. package/src/common/window/__mocks__/nreum.js +3 -1
  196. package/src/common/window/page-visibility.js +1 -2
  197. package/src/common/wrap/wrap-jsonp.js +1 -1
  198. package/src/features/ajax/aggregate/index.js +5 -7
  199. package/src/features/ajax/instrument/distributed-tracing.js +8 -8
  200. package/src/features/ajax/instrument/index.js +40 -17
  201. package/src/features/jserrors/aggregate/canonical-function-name.js +0 -2
  202. package/src/features/jserrors/aggregate/compute-stack-trace.js +4 -4
  203. package/src/features/jserrors/aggregate/compute-stack-trace.test.js +1 -1
  204. package/src/features/jserrors/aggregate/index.js +4 -5
  205. package/src/features/metrics/aggregate/framework-detection.js +129 -8
  206. package/src/features/metrics/aggregate/framework-detection.test.js +213 -82
  207. package/src/features/metrics/aggregate/index.js +22 -45
  208. package/src/features/metrics/instrument/index.js +1 -3
  209. package/src/features/page_action/aggregate/index.js +12 -13
  210. package/src/features/page_view_event/aggregate/index.js +1 -2
  211. package/src/features/page_view_event/instrument/index.js +2 -2
  212. package/src/features/page_view_timing/aggregate/index.js +7 -8
  213. package/src/features/session_replay/aggregate/index.component-test.js +3 -15
  214. package/src/features/session_replay/aggregate/index.js +2 -2
  215. package/src/features/session_trace/aggregate/index.js +6 -9
  216. package/src/features/spa/aggregate/index.js +14 -20
  217. package/src/features/spa/aggregate/interaction.js +0 -2
  218. package/src/features/spa/aggregate/serializer.js +1 -1
  219. package/src/features/utils/aggregate-base.js +5 -0
  220. package/src/features/utils/aggregate-base.test.js +2 -1
  221. package/src/features/utils/handler-cache.js +3 -2
  222. package/src/features/utils/instrument-base.js +25 -6
  223. package/src/features/utils/instrument-base.test.js +2 -2
  224. package/src/loaders/agent-base.js +11 -0
  225. package/src/loaders/agent.js +7 -7
  226. package/src/loaders/api/api.js +21 -4
  227. package/src/loaders/api/api.test.js +85 -0
  228. package/src/loaders/api/apiAsync.js +19 -20
  229. package/src/loaders/api/apiAsync.test.js +17 -0
  230. package/src/loaders/configure/configure.js +3 -0
  231. package/src/loaders/features/enabled-features.js +1 -1
  232. package/src/loaders/micro-agent.js +22 -4
  233. package/dist/cjs/features/metrics/aggregate/endpoint-map.js +0 -14
  234. package/dist/cjs/features/metrics/aggregate/polyfill-detection.es5.js +0 -14
  235. package/dist/cjs/features/metrics/aggregate/polyfill-detection.js +0 -53
  236. package/dist/esm/features/metrics/aggregate/endpoint-map.js +0 -7
  237. package/dist/esm/features/metrics/aggregate/polyfill-detection.es5.js +0 -8
  238. package/dist/esm/features/metrics/aggregate/polyfill-detection.js +0 -47
  239. package/dist/types/features/metrics/aggregate/endpoint-map.d.ts +0 -8
  240. package/dist/types/features/metrics/aggregate/endpoint-map.d.ts.map +0 -1
  241. package/dist/types/features/metrics/aggregate/polyfill-detection.d.ts +0 -6
  242. package/dist/types/features/metrics/aggregate/polyfill-detection.d.ts.map +0 -1
  243. package/dist/types/features/metrics/aggregate/polyfill-detection.es5.d.ts +0 -7
  244. package/dist/types/features/metrics/aggregate/polyfill-detection.es5.d.ts.map +0 -1
  245. package/src/features/metrics/aggregate/endpoint-map.js +0 -7
  246. package/src/features/metrics/aggregate/polyfill-detection.es5.js +0 -8
  247. package/src/features/metrics/aggregate/polyfill-detection.es5.test.js +0 -16
  248. package/src/features/metrics/aggregate/polyfill-detection.js +0 -48
  249. package/src/features/metrics/aggregate/polyfill-detection.test.js +0 -163
@@ -9,8 +9,6 @@ const model = () => {
9
9
  }
10
10
  };
11
11
  return {
12
- allow_bfcache: true,
13
- // *cli - temporary feature flag for BFCache work
14
12
  privacy: {
15
13
  cookies_enabled: true
16
14
  },
@@ -19,7 +17,8 @@ const model = () => {
19
17
  deny_list: undefined,
20
18
  block_internal: true,
21
19
  enabled: true,
22
- harvestTimeSeconds: 10
20
+ harvestTimeSeconds: 10,
21
+ autoStart: true
23
22
  },
24
23
  distributed_tracing: {
25
24
  enabled: undefined,
@@ -38,32 +37,39 @@ const model = () => {
38
37
  obfuscate: undefined,
39
38
  jserrors: {
40
39
  enabled: true,
41
- harvestTimeSeconds: 10
40
+ harvestTimeSeconds: 10,
41
+ autoStart: true
42
42
  },
43
43
  metrics: {
44
- enabled: true
44
+ enabled: true,
45
+ autoStart: true
45
46
  },
46
47
  page_action: {
47
48
  enabled: true,
48
- harvestTimeSeconds: 30
49
+ harvestTimeSeconds: 30,
50
+ autoStart: true
49
51
  },
50
52
  page_view_event: {
51
- enabled: true
53
+ enabled: true,
54
+ autoStart: true
52
55
  },
53
56
  page_view_timing: {
54
57
  enabled: true,
55
58
  harvestTimeSeconds: 30,
56
- long_task: false
59
+ long_task: false,
60
+ autoStart: true
57
61
  },
58
62
  session_trace: {
59
63
  enabled: true,
60
- harvestTimeSeconds: 10
64
+ harvestTimeSeconds: 10,
65
+ autoStart: true
61
66
  },
62
67
  harvest: {
63
68
  tooManyRequestsDelay: 60
64
69
  },
65
70
  session_replay: {
66
71
  // feature settings
72
+ autoStart: true,
67
73
  enabled: false,
68
74
  harvestTimeSeconds: 60,
69
75
  sampleRate: 0.1,
@@ -102,23 +108,25 @@ const model = () => {
102
108
  },
103
109
  spa: {
104
110
  enabled: true,
105
- harvestTimeSeconds: 10
111
+ harvestTimeSeconds: 10,
112
+ autoStart: true
106
113
  }
107
114
  };
108
115
  };
109
116
  const _cache = {};
117
+ const missingAgentIdError = 'All configuration objects require an agent identifier!';
110
118
  export function getConfiguration(id) {
111
- if (!id) throw new Error('All configuration objects require an agent identifier!');
119
+ if (!id) throw new Error(missingAgentIdError);
112
120
  if (!_cache[id]) throw new Error("Configuration for ".concat(id, " was never set"));
113
121
  return _cache[id];
114
122
  }
115
123
  export function setConfiguration(id, obj) {
116
- if (!id) throw new Error('All configuration objects require an agent identifier!');
124
+ if (!id) throw new Error(missingAgentIdError);
117
125
  _cache[id] = getModeledObject(obj, model());
118
126
  gosNREUMInitializedAgents(id, _cache[id], 'config');
119
127
  }
120
128
  export function getConfigurationValue(id, path) {
121
- if (!id) throw new Error('All configuration objects require an agent identifier!');
129
+ if (!id) throw new Error(missingAgentIdError);
122
130
  var val = getConfiguration(id);
123
131
  if (val) {
124
132
  var parts = path.split('.');
@@ -4,10 +4,6 @@ import { globalScope } from '../../constants/runtime';
4
4
  import { BUILD_ENV, DIST_METHOD, VERSION } from "../../constants/env.npm";
5
5
  const model = {
6
6
  buildEnv: BUILD_ENV,
7
- bytesSent: {},
8
- // Used for SM to capture body bytes sent per endpoint
9
- queryBytesSent: {},
10
- // Used for SM to capture query parameter bytes sent per endpoint
11
7
  customTransaction: undefined,
12
8
  disabled: false,
13
9
  distMethod: DIST_METHOD,
@@ -6,7 +6,7 @@
6
6
  /**
7
7
  * Exposes the version of the agent
8
8
  */
9
- export const VERSION = "1.238.0";
9
+ export const VERSION = "1.239.1";
10
10
 
11
11
  /**
12
12
  * Exposes the build type of the agent
@@ -6,7 +6,7 @@
6
6
  /**
7
7
  * Exposes the version of the agent
8
8
  */
9
- export const VERSION = "1.238.0";
9
+ export const VERSION = "1.239.1";
10
10
 
11
11
  /**
12
12
  * Exposes the build type of the agent
@@ -25,7 +25,7 @@ export const isiOS = /iPad|iPhone|iPod/.test(navigator.userAgent);
25
25
  * did not work. This affects our onFCP metric in particular since web-vitals uses that flag to retrieve paint timing entries.
26
26
  * This was fixed in v16+.
27
27
  */
28
- export const iOS_below16 = isiOS && typeof SharedWorker === 'undefined';
28
+ export const iOSBelow16 = isiOS && typeof SharedWorker === 'undefined';
29
29
  export const ffVersion = (() => {
30
30
  const match = navigator.userAgent.match(/Firefox[/\s](\d+\.\d+)/);
31
31
  if (Array.isArray(match) && match.length >= 2) {
@@ -5,7 +5,9 @@
5
5
  */
6
6
 
7
7
  let onReplayReady;
8
- const sessionReplayInitialized = new Promise(resolve => onReplayReady = resolve);
8
+ const sessionReplayInitialized = new Promise(resolve => {
9
+ onReplayReady = resolve;
10
+ });
9
11
  export const sharedChannel = Object.freeze({
10
12
  onReplayReady,
11
13
  sessionReplayInitialized
@@ -74,10 +74,7 @@ function domainMatchesPattern(pattern, domain) {
74
74
  if (pattern.length > domain.length) {
75
75
  return false;
76
76
  }
77
- if (domain.indexOf(pattern) === domain.length - pattern.length) {
78
- return true;
79
- }
80
- return false;
77
+ return domain.indexOf(pattern) === domain.length - pattern.length;
81
78
  }
82
79
 
83
80
  /**
@@ -98,8 +95,5 @@ function comparePath(pattern, path) {
98
95
  if (pattern === '') {
99
96
  return true;
100
97
  }
101
- if (pattern === path) {
102
- return true;
103
- }
104
- return false;
98
+ return pattern === path;
105
99
  }
@@ -48,7 +48,6 @@ export function drain() {
48
48
  let agentIdentifier = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
49
49
  let featureName = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'feature';
50
50
  curateRegistry(agentIdentifier);
51
-
52
51
  // If the feature for the specified agent is not in the registry, that means the instrument file was bypassed.
53
52
  // This could happen in tests, or loaders that directly import the aggregator. In these cases it is safe to
54
53
  // drain the feature group immediately rather than waiting to drain all at once.
@@ -67,6 +66,7 @@ export function drain() {
67
66
  items.sort((a, b) => a[1].priority - b[1].priority);
68
67
  items.forEach(_ref2 => {
69
68
  let [group] = _ref2;
69
+ registry[agentIdentifier].delete(group);
70
70
  drainGroup(group);
71
71
  });
72
72
  }
@@ -38,16 +38,16 @@ function ee(old, debugId) {
38
38
  }
39
39
  var emitter = {
40
40
  on: addEventListener,
41
- addEventListener: addEventListener,
42
- removeEventListener: removeEventListener,
43
- emit: emit,
41
+ addEventListener,
42
+ removeEventListener,
43
+ emit,
44
44
  get: getOrCreate,
45
- listeners: listeners,
46
- context: context,
45
+ listeners,
46
+ context,
47
47
  buffer: bufferEventsByGroup,
48
48
  abort,
49
49
  aborted: false,
50
- isBuffering: isBuffering,
50
+ isBuffering,
51
51
  debugId,
52
52
  backlog: isolatedBacklog ? {} : old && typeof old.backlog === 'object' ? old.backlog : {}
53
53
  };
@@ -7,7 +7,6 @@ import * as submitData from '../util/submit-data';
7
7
  import { SharedContext } from '../context/shared-context';
8
8
  import { Harvest } from './harvest';
9
9
  import { subscribeToEOL } from '../unload/eol';
10
- import { getConfigurationValue } from '../config/config';
11
10
  import { SESSION_EVENTS } from '../session/session-entity';
12
11
 
13
12
  /**
@@ -36,7 +35,7 @@ export class HarvestScheduler extends SharedContext {
36
35
  this.harvest = new Harvest(this.sharedContext);
37
36
 
38
37
  // unload if EOL mechanism fires
39
- subscribeToEOL(this.unload.bind(this), getConfigurationValue(this.sharedContext.agentIdentifier, 'allow_bfcache')); // TO DO: remove feature flag after rls stable
38
+ subscribeToEOL(this.unload.bind(this));
40
39
 
41
40
  /* Flush all buffered data if session resets and give up retries. This should be synchronous to ensure that the correct `session` value is sent.
42
41
  Since session-reset generates a new session ID and the ID is grabbed at send-time, any delays or retries would cause the payload to be sent under
@@ -103,7 +102,7 @@ export class HarvestScheduler extends SharedContext {
103
102
  if (!submitMethod) return false;
104
103
  const retry = !opts?.unload && submitMethod === submitData.xhr;
105
104
  payload = this.opts.getPayload({
106
- retry: retry
105
+ retry
107
106
  });
108
107
  if (!payload) {
109
108
  if (this.started) {
@@ -139,7 +138,6 @@ export class HarvestScheduler extends SharedContext {
139
138
  if (this.started) {
140
139
  this.scheduleHarvest();
141
140
  }
142
- return;
143
141
  }
144
142
  onHarvestFinished(opts, result) {
145
143
  if (this.opts.onFinished) {
@@ -123,7 +123,8 @@ export class Harvest extends SharedContext {
123
123
  }
124
124
  return false;
125
125
  }
126
- let url = "".concat(this.getScheme(), "://").concat(info.errorBeacon).concat(endpoint !== 'rum' ? "/".concat(endpoint) : '', "/1/").concat(info.licenseKey);
126
+ const endpointURLPart = endpoint !== 'rum' ? "/".concat(endpoint) : '';
127
+ let url = "".concat(this.getScheme(), "://").concat(info.errorBeacon).concat(endpointURLPart, "/1/").concat(info.licenseKey);
127
128
  if (customUrl) url = customUrl;
128
129
  if (raw) url = "".concat(this.getScheme(), "://").concat(info.errorBeacon, "/").concat(endpoint);
129
130
  const baseParams = !raw && includeBaseParams ? this.baseQueryString() : '';
@@ -151,11 +152,6 @@ export class Harvest extends SharedContext {
151
152
  // If body is null, undefined, or an empty object or array, send an empty string instead
152
153
  body = '';
153
154
  }
154
-
155
- // Get bytes harvested per endpoint as a supportability metric. See metrics aggregator (on unload).
156
- agentRuntime.bytesSent[endpoint] = (agentRuntime.bytesSent[endpoint] || 0) + body?.length || 0;
157
- // Get query bytes harvested per endpoint as a supportability metric. See metrics aggregator (on unload).
158
- agentRuntime.queryBytesSent[endpoint] = (agentRuntime.queryBytesSent[endpoint] || 0) + fullUrl.split('?').slice(-1)[0]?.length || 0;
159
155
  const headers = [];
160
156
  headers.push({
161
157
  key: 'content-type',
@@ -25,7 +25,7 @@ export function getAddStringContext(agentIdentifier) {
25
25
  function addString(str) {
26
26
  if (typeof str === 'undefined' || str === '') return '';
27
27
  var obfuscator = new Obfuscator({
28
- agentIdentifier: agentIdentifier
28
+ agentIdentifier
29
29
  });
30
30
  str = String(str);
31
31
  if (obfuscator.shouldObfuscate()) str = obfuscator.obfuscateString(str);
@@ -40,33 +40,37 @@ export class SessionEntity {
40
40
  * expiresMs and inactiveMs are used to "expire" the session, but can be overridden in the constructor. Pass 0 to disable expiration timers.
41
41
  */
42
42
  constructor(opts) {
43
- this.setup(opts);
44
- }
45
- setup(_ref) {
46
- let {
43
+ const {
47
44
  agentIdentifier,
48
45
  key,
49
- storage,
50
- value = generateRandomHexString(16),
51
- expiresMs = DEFAULT_EXPIRES_MS,
52
- inactiveMs = DEFAULT_INACTIVE_MS
53
- } = _ref;
46
+ storage
47
+ } = opts;
54
48
  if (!agentIdentifier || !key || !storage) {
55
49
  throw new Error("Missing required field(s):".concat(!agentIdentifier ? ' agentID' : '').concat(!key ? ' key' : '').concat(!storage ? ' storage' : ''));
56
50
  }
57
51
  this.agentIdentifier = agentIdentifier;
58
52
  this.storage = storage;
59
53
  this.state = {};
60
- this.sync(model);
61
54
 
62
55
  // key is intended to act as the k=v pair
63
56
  this.key = key;
57
+ this.ee = ee.get(agentIdentifier);
58
+ wrapEvents(this.ee);
59
+ this.setup(opts);
60
+ }
61
+ setup(_ref) {
62
+ let {
63
+ value = generateRandomHexString(16),
64
+ expiresMs = DEFAULT_EXPIRES_MS,
65
+ inactiveMs = DEFAULT_INACTIVE_MS
66
+ } = _ref;
67
+ this.state = {};
68
+ this.sync(model);
69
+
64
70
  // value is intended to act as the primary value of the k=v pair
65
71
  this.state.value = value;
66
72
  this.expiresMs = expiresMs;
67
73
  this.inactiveMs = inactiveMs;
68
- this.ee = ee.get(agentIdentifier);
69
- wrapEvents(this.ee);
70
74
 
71
75
  // the first time the session entity class is instantiated, we check the storage API for an existing
72
76
  // object. If it exists, the values inside the object are used to inform the timers that run locally.
@@ -7,22 +7,23 @@ export class FirstPartyCookies {
7
7
  var match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)'));
8
8
  if (match) return match[2];
9
9
  } catch (err) {
10
+ // Error is ignored
10
11
  return '';
11
12
  }
12
13
  }
13
14
  set(key, value) {
14
15
  try {
15
- const cookie = "".concat(key, "=").concat(value, "; Domain=").concat(domain, "; Path=/");
16
+ const cookie = "".concat(key, "=").concat(value, "; Domain=").concat(this.domain, "; Path=/");
16
17
  document.cookie = cookie;
17
18
  } catch (err) {
18
- return;
19
+ // Error is ignored
19
20
  }
20
21
  }
21
22
  remove(key) {
22
23
  try {
23
- return document.cookie = "".concat(key, "=; expires=Thu, 01 Jan 1970 00:00:00 UTC; Domain=").concat(domain, "; Path=/");
24
+ document.cookie = "".concat(key, "=; expires=Thu, 01 Jan 1970 00:00:00 UTC; Domain=").concat(this.domain, "; Path=/");
24
25
  } catch (err) {
25
- return;
26
+ // Error is ignored
26
27
  }
27
28
  }
28
29
  }
@@ -5,6 +5,7 @@ export class LocalStorage {
5
5
  // Cast it back to undefined if it doesnt exist
6
6
  return localStorage.getItem(key) || undefined;
7
7
  } catch (err) {
8
+ // Error is ignored
8
9
  return '';
9
10
  }
10
11
  }
@@ -13,14 +14,14 @@ export class LocalStorage {
13
14
  if (value === undefined || value === null) return this.remove(key);
14
15
  return localStorage.setItem(key, value);
15
16
  } catch (err) {
16
- return;
17
+ // Error is ignored
17
18
  }
18
19
  }
19
20
  remove(key) {
20
21
  try {
21
22
  localStorage.removeItem(key);
22
23
  } catch (err) {
23
- return;
24
+ // Error is ignored
24
25
  }
25
26
  }
26
27
  }
@@ -21,14 +21,16 @@ export class InteractionTimer extends Timer {
21
21
  }
22
22
  if (isBrowserScope && opts.ee) {
23
23
  if (opts.ee) {
24
+ this.ee = opts.ee;
24
25
  const debouncedRefresh = debounce(this.refresh.bind(this), 500, {
25
26
  leading: true
26
27
  });
27
- opts.ee.on('fn-end', evts => {
28
+ this.refreshHandler = evts => {
28
29
  if (opts.refreshEvents.includes(evts?.[0]?.type)) {
29
30
  debouncedRefresh();
30
31
  }
31
- });
32
+ };
33
+ opts.ee.on('fn-end', this.refreshHandler);
32
34
  }
33
35
 
34
36
  // watch for the vis state changing. If the page is hidden, the local inactivity timer should be paused
@@ -42,22 +44,28 @@ export class InteractionTimer extends Timer {
42
44
  subscribeToVisibilityChange(state => {
43
45
  if (state === 'hidden') this.pause();
44
46
  // vis change --> visible is treated like a new interaction with the page
45
- else {
46
- this.refresh();
47
- this.onResume(); // emit resume event after state updated
48
- }
47
+ else this.resume();
49
48
  }, false, false, this.abortController?.signal);
50
49
  }
51
50
  }
52
51
  abort() {
53
52
  this.clear();
54
53
  this.abortController?.abort();
54
+ if (this.refreshHandler) {
55
+ this.ee.removeEventListener('fn-end', this.refreshHandler);
56
+ this.refreshHandler = this.ee = null;
57
+ }
55
58
  }
56
59
  pause() {
57
60
  this.onPause();
58
61
  clearTimeout(this.timer);
59
62
  this.remainingMs = this.initialMs - (Date.now() - this.startTimestamp);
60
63
  }
64
+ resume() {
65
+ this.refresh();
66
+ this.onResume(); // emit resume event after state updated
67
+ }
68
+
61
69
  refresh(cb, ms) {
62
70
  this.clear();
63
71
  this.timer = this.create(cb, ms);
@@ -26,7 +26,7 @@ var LOAD_EVENT = 'loadEvent';
26
26
  var DOM_CONTENT_LOAD_EVENT = 'domContentLoadedEvent';
27
27
  export var navTimingValues = [];
28
28
  function getPntType(type) {
29
- if (typeof type == 'number') return type;
29
+ if (typeof type === 'number') return type;
30
30
  const types = {
31
31
  navigate: undefined,
32
32
  reload: 1,
@@ -3,8 +3,7 @@
3
3
  * SPDX-License-Identifier: Apache-2.0
4
4
  */
5
5
  import { windowAddEventListener } from '../event-listener/event-listener-opts';
6
- import { single } from '../util/invoke';
7
- import { ffVersion, globalScope, isWorkerScope, isBrowserScope } from '../constants/runtime';
6
+ import { globalScope, isWorkerScope, isBrowserScope } from '../constants/runtime';
8
7
  import { subscribeToVisibilityChange } from '../window/page-visibility';
9
8
  if (isWorkerScope) {
10
9
  globalScope.cleanupTasks = []; // create new list on WorkerGlobalScope to track funcs to run before exiting thread
@@ -23,37 +22,12 @@ if (isWorkerScope) {
23
22
  * Subscribes a provided callback to the time/event when the agent should treat it as end-of-life.
24
23
  * This is used, for example, to submit a final harvest and send all remaining data on best-effort.
25
24
  * @param {function} cb - func to run before or during the last reliable event or time of an env's life span
26
- * @param {boolean} allowBFCache - (temp) feature flag to gate new v1222 BFC support
27
25
  */
28
- export function subscribeToEOL(cb, allowBFCache) {
26
+ export function subscribeToEOL(cb) {
29
27
  if (isBrowserScope) {
30
- if (allowBFCache) {
31
- subscribeToVisibilityChange(cb, true); // when user switches tab or hides window, esp. mobile scenario
32
- windowAddEventListener('pagehide', cb); // when user navigates away, and because safari iOS v14.4- doesn't fully support vis change
33
- // --this ought to be removed once support for version below 14.5 phases out
34
- } else {
35
- var oneCall = single(cb);
36
-
37
- // Firefox has a bug wherein a slow-loading resource loaded from the 'pagehide'
38
- // or 'unload' event will delay the 'load' event firing on the next page load.
39
- // In Firefox versions that support sendBeacon, this doesn't matter, because
40
- // we'll use it instead of an image load for our final harvest.
41
- //
42
- // Some Safari versions never fire the 'unload' event for pages that are being
43
- // put into the WebKit page cache, so we *need* to use the pagehide event for
44
- // the final submission from Safari.
45
- //
46
- // Generally speaking, we will try to submit our final harvest from either
47
- // pagehide or unload, whichever comes first, but in Firefox, we need to avoid
48
- // attempting to submit from pagehide to ensure that we don't slow down loading
49
- // of the next page.
50
- if (!ffVersion || navigator.sendBeacon) {
51
- windowAddEventListener('pagehide', oneCall);
52
- } else {
53
- windowAddEventListener('beforeunload', oneCall);
54
- }
55
- windowAddEventListener('unload', oneCall);
56
- }
28
+ subscribeToVisibilityChange(cb, true); // when user switches tab or hides window, esp. mobile scenario
29
+ windowAddEventListener('pagehide', cb); // when user navigates away, and because safari iOS v14.4- doesn't fully support vis change
30
+ // --this ought to be removed once support for version below 14.5 phases out
57
31
  } else if (isWorkerScope) {
58
32
  globalScope.cleanupTasks.push(cb); // close() should run these tasks before quitting thread
59
33
  }
@@ -4,7 +4,6 @@
4
4
  */
5
5
  import { ee } from '../event-emitter/contextual-ee';
6
6
  import { handle } from '../event-emitter/handle';
7
- import { drain } from '../drain/drain';
8
7
  import { FEATURE_NAMES } from '../../loaders/features/features';
9
8
  const bucketMap = {
10
9
  stn: [FEATURE_NAMES.sessionTrace],
@@ -13,24 +12,24 @@ const bucketMap = {
13
12
  spa: [FEATURE_NAMES.spa],
14
13
  sr: [FEATURE_NAMES.sessionReplay, FEATURE_NAMES.sessionTrace]
15
14
  };
15
+ const sentIds = new Set();
16
16
 
17
17
  /** Note that this function only processes each unique flag ONCE, with the first occurrence of each flag and numeric value determining its switch on/off setting. */
18
18
  export function activateFeatures(flags, agentIdentifier) {
19
19
  const sharedEE = ee.get(agentIdentifier);
20
20
  if (!(flags && typeof flags === 'object')) return;
21
- Object.entries(flags).forEach(_ref => {
22
- let [flag, num] = _ref;
23
- if (activatedFeatures[flag] !== undefined) return;
24
- if (bucketMap[flag]) {
25
- bucketMap[flag].forEach(feat => {
26
- if (!num) handle('block-' + flag, [], undefined, feat, sharedEE);else handle('feat-' + flag, [], undefined, feat, sharedEE);
27
- handle('rumresp-' + flag, [Boolean(num)], undefined, feat, sharedEE); // this is a duplicate of feat-/block- but makes awaiting for 1 event easier than 2
28
- });
29
- } else if (num) handle('feat-' + flag, [], undefined, undefined, sharedEE); // not sure what other flags are overlooked, but there's a test for ones not in the map --
30
- // ^^^ THIS DOESN'T ACTUALLY DO ANYTHHING AS UNDEFINED/FEATURE GROUP ISN'T DRAINED
31
-
32
- activatedFeatures[flag] = Boolean(num);
33
- });
21
+ if (!sentIds.has(agentIdentifier)) {
22
+ Object.entries(flags).forEach(_ref => {
23
+ let [flag, num] = _ref;
24
+ if (bucketMap[flag]) {
25
+ bucketMap[flag].forEach(feat => {
26
+ if (!num) handle('block-' + flag, [], undefined, feat, sharedEE);else handle('feat-' + flag, [], undefined, feat, sharedEE);
27
+ handle('rumresp-' + flag, [Boolean(num)], undefined, feat, sharedEE); // this is a duplicate of feat-/block- but makes awaiting for 1 event easier than 2
28
+ });
29
+ } else if (num) handle('feat-' + flag, [], undefined, undefined, sharedEE); // not sure what other flags are overlooked, but there's a test for ones not in the map --
30
+ activatedFeatures[flag] = Boolean(num);
31
+ });
32
+ }
34
33
 
35
34
  // Let the features waiting on their respective flags know that RUM response was received and that any missing flags are interpreted as bad entitlement / "off".
36
35
  // Hence, those features will not be hanging forever if their flags aren't included in the response.
@@ -40,6 +39,6 @@ export function activateFeatures(flags, agentIdentifier) {
40
39
  activatedFeatures[flag] = false;
41
40
  }
42
41
  });
43
- drain(agentIdentifier, FEATURE_NAMES.pageViewEvent);
42
+ sentIds.add(agentIdentifier);
44
43
  }
45
44
  export const activatedFeatures = {};
@@ -32,7 +32,9 @@ export function debounce(func) {
32
32
  }
33
33
  if (leading && timer === undefined) {
34
34
  func.apply(_this, args);
35
- timer = setTimeout(() => timer = clearTimeout(timer), timeout);
35
+ timer = setTimeout(() => {
36
+ timer = clearTimeout(timer);
37
+ }, timeout);
36
38
  }
37
39
  if (!leading) {
38
40
  clearTimeout(timer);
@@ -52,11 +52,9 @@ export function validateRules(rules) {
52
52
  invalidRegexDetected = true;
53
53
  }
54
54
  var replacement = rules[i].replacement;
55
- if (replacement) {
56
- if (typeof replacement !== 'string') {
57
- warn('An obfuscation replacement rule contains a "replacement" value with an invalid type (must be a string)');
58
- invalidReplacementDetected = true;
59
- }
55
+ if (replacement && typeof replacement !== 'string') {
56
+ warn('An obfuscation replacement rule contains a "replacement" value with an invalid type (must be a string)');
57
+ invalidReplacementDetected = true;
60
58
  }
61
59
  }
62
60
  return !invalidReplacementDetected && !invalidRegexDetected;
@@ -20,6 +20,7 @@ export function applyFnToProps(obj, fn) {
20
20
  if (typeof obj[property] === 'object') {
21
21
  applyFnToProps(obj[property], fn, type, ignoreKeys);
22
22
  } else {
23
+ // eslint-disable-next-line valid-typeof
23
24
  if (typeof obj[property] === type && !ignoreKeys.includes(property)) obj[property] = fn(obj[property]);
24
25
  }
25
26
  });
@@ -15,11 +15,10 @@ export function subscribeToVisibilityChange(cb) {
15
15
  let capture = arguments.length > 2 ? arguments[2] : undefined;
16
16
  let abortSignal = arguments.length > 3 ? arguments[3] : undefined;
17
17
  documentAddEventListener('visibilitychange', handleVisibilityChange, capture, abortSignal);
18
- return;
19
18
  function handleVisibilityChange() {
20
19
  if (toHiddenOnly) {
21
20
  // trigger cb on change to hidden state only
22
- if (document.visibilityState == 'hidden') cb();
21
+ if (document.visibilityState === 'hidden') cb();
23
22
  return;
24
23
  }
25
24
  cb(document.visibilityState);
@@ -110,7 +110,7 @@ export function wrapJsonP(sharedEE) {
110
110
  };
111
111
  }
112
112
  return {
113
- key: key,
113
+ key,
114
114
  parent: window
115
115
  };
116
116
  }
@@ -10,7 +10,6 @@ import { getConfiguration, getInfo, getRuntime } from '../../../common/config/co
10
10
  import { HarvestScheduler } from '../../../common/harvest/harvest-scheduler';
11
11
  import { setDenyList, shouldCollectEvent } from '../../../common/deny-list/deny-list';
12
12
  import { FEATURE_NAME } from '../constants';
13
- import { drain } from '../../../common/drain/drain';
14
13
  import { FEATURE_NAMES } from '../../../loaders/features/features';
15
14
  import { SUPPORTABILITY_METRIC_CHANNEL } from '../../metrics/constants';
16
15
  import { AggregateBase } from '../../utils/aggregate-base';
@@ -22,7 +21,7 @@ export class Aggregate extends AggregateBase {
22
21
  const allAjaxIsEnabled = agentInit.ajax.enabled !== false;
23
22
  register('xhr', storeXhr, this.featureName, this.ee);
24
23
  if (!allAjaxIsEnabled) {
25
- drain(this.agentIdentifier, this.featureName);
24
+ this.drain();
26
25
  return; // feature will only collect timeslice metrics & ajax trace nodes if it's not fully enabled
27
26
  }
28
27
 
@@ -64,8 +63,7 @@ export class Aggregate extends AggregateBase {
64
63
  ee.on("drain-".concat(this.featureName), () => {
65
64
  scheduler.startTimer(harvestTimeSeconds);
66
65
  });
67
- drain(this.agentIdentifier, this.featureName);
68
- return;
66
+ this.drain();
69
67
  function storeXhr(params, metrics, startTime, endTime, type) {
70
68
  metrics.time = startTime;
71
69
 
@@ -97,9 +95,9 @@ export class Aggregate extends AggregateBase {
97
95
  path: params.pathname,
98
96
  requestSize: metrics.txSize,
99
97
  responseSize: metrics.rxSize,
100
- type: type,
101
- startTime: startTime,
102
- endTime: endTime,
98
+ type,
99
+ startTime,
100
+ endTime,
103
101
  callbackDuration: metrics.cbTime
104
102
  };
105
103
  if (xhrContext.dt) {