@newrelic/browser-agent 1.234.0 → 1.236.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 (372) hide show
  1. package/README.md +42 -2
  2. package/dist/cjs/common/config/state/init.js +3 -0
  3. package/dist/cjs/common/config/state/runtime.js +4 -4
  4. package/dist/cjs/common/constants/env.cdn.js +2 -2
  5. package/dist/cjs/common/constants/env.npm.js +1 -1
  6. package/dist/cjs/common/constants/runtime.js +52 -0
  7. package/dist/cjs/common/constants/shared-channel.js +19 -0
  8. package/dist/cjs/common/event-listener/event-listener-opts.js +3 -3
  9. package/dist/cjs/common/harvest/harvest-scheduler.js +35 -16
  10. package/dist/cjs/common/harvest/harvest.js +163 -144
  11. package/dist/cjs/common/harvest/types.js +54 -0
  12. package/dist/cjs/common/ids/id.js +2 -2
  13. package/dist/cjs/common/ids/unique-id.js +3 -3
  14. package/dist/cjs/common/session/session-entity.js +21 -13
  15. package/dist/cjs/common/timer/interaction-timer.js +3 -3
  16. package/dist/cjs/common/unload/eol.js +10 -11
  17. package/dist/cjs/common/url/canonicalize-url.js +2 -2
  18. package/dist/cjs/common/url/parse-url.js +3 -3
  19. package/dist/cjs/common/url/protocol.js +2 -2
  20. package/dist/cjs/common/util/feature-flags.js +23 -12
  21. package/dist/cjs/common/util/obfuscate.js +2 -2
  22. package/dist/cjs/common/util/submit-data.js +61 -79
  23. package/dist/cjs/common/window/nreum.js +14 -14
  24. package/dist/cjs/common/wrap/wrap-events.js +3 -3
  25. package/dist/cjs/common/wrap/wrap-fetch.js +5 -5
  26. package/dist/cjs/common/wrap/wrap-history.js +2 -2
  27. package/dist/cjs/common/wrap/wrap-jsonp.js +2 -2
  28. package/dist/cjs/common/wrap/wrap-mutation.js +2 -2
  29. package/dist/cjs/common/wrap/wrap-promise.js +2 -2
  30. package/dist/cjs/common/wrap/wrap-raf.js +3 -3
  31. package/dist/cjs/common/wrap/wrap-timer.js +5 -5
  32. package/dist/cjs/common/wrap/wrap-xhr.js +3 -3
  33. package/dist/cjs/features/ajax/aggregate/index.js +1 -1
  34. package/dist/cjs/features/ajax/instrument/distributed-tracing.js +2 -2
  35. package/dist/cjs/features/ajax/instrument/index.js +6 -7
  36. package/dist/cjs/features/jserrors/aggregate/index.js +11 -4
  37. package/dist/cjs/features/jserrors/instrument/index.js +6 -19
  38. package/dist/cjs/features/metrics/aggregate/framework-detection.js +2 -2
  39. package/dist/cjs/features/metrics/aggregate/index.js +3 -3
  40. package/dist/cjs/features/page_action/aggregate/index.js +3 -3
  41. package/dist/cjs/features/page_view_event/aggregate/index.js +10 -11
  42. package/dist/cjs/features/page_view_event/instrument/index.js +2 -2
  43. package/dist/cjs/features/page_view_timing/aggregate/index.js +3 -5
  44. package/dist/cjs/features/page_view_timing/instrument/index.js +2 -2
  45. package/dist/cjs/features/session_replay/aggregate/index.js +99 -82
  46. package/dist/cjs/features/session_replay/replay-mode.js +28 -0
  47. package/dist/cjs/features/session_trace/aggregate/index.js +222 -99
  48. package/dist/cjs/features/session_trace/constants.js +1 -3
  49. package/dist/cjs/features/session_trace/instrument/index.js +2 -18
  50. package/dist/cjs/features/spa/aggregate/index.js +1 -1
  51. package/dist/cjs/features/spa/constants.js +0 -1
  52. package/dist/cjs/features/spa/instrument/index.js +2 -2
  53. package/dist/cjs/features/utils/agent-session.js +20 -36
  54. package/dist/cjs/features/utils/aggregate-base.js +7 -12
  55. package/dist/cjs/features/utils/handler-cache.js +28 -23
  56. package/dist/cjs/features/utils/instrument-base.js +58 -40
  57. package/dist/cjs/index.js +7 -0
  58. package/dist/cjs/loaders/agent.js +7 -1
  59. package/dist/cjs/loaders/api/api.js +2 -2
  60. package/dist/cjs/loaders/api/apiAsync.js +6 -4
  61. package/dist/cjs/loaders/configure/configure.js +2 -2
  62. package/dist/cjs/loaders/features/featureDependencies.js +2 -0
  63. package/dist/cjs/loaders/micro-agent.js +29 -38
  64. package/dist/esm/common/config/state/init.js +3 -0
  65. package/dist/esm/common/config/state/runtime.js +1 -1
  66. package/dist/esm/common/constants/env.cdn.js +2 -2
  67. package/dist/esm/common/constants/env.npm.js +1 -1
  68. package/dist/esm/common/constants/runtime.js +38 -0
  69. package/dist/esm/common/constants/shared-channel.js +12 -0
  70. package/dist/esm/common/event-listener/event-listener-opts.js +1 -1
  71. package/dist/esm/common/harvest/harvest-scheduler.js +34 -17
  72. package/dist/esm/common/harvest/harvest.js +160 -142
  73. package/dist/esm/common/harvest/types.js +47 -0
  74. package/dist/esm/common/ids/id.js +1 -1
  75. package/dist/esm/common/ids/unique-id.js +1 -1
  76. package/dist/esm/common/session/session-entity.js +18 -12
  77. package/dist/esm/common/timer/interaction-timer.js +2 -2
  78. package/dist/esm/common/unload/eol.js +1 -2
  79. package/dist/esm/common/url/canonicalize-url.js +1 -1
  80. package/dist/esm/common/url/parse-url.js +1 -1
  81. package/dist/esm/common/url/protocol.js +1 -1
  82. package/dist/esm/common/util/feature-flags.js +23 -12
  83. package/dist/esm/common/util/obfuscate.js +2 -2
  84. package/dist/esm/common/util/submit-data.js +58 -76
  85. package/dist/esm/common/window/nreum.js +1 -1
  86. package/dist/esm/common/wrap/wrap-events.js +1 -1
  87. package/dist/esm/common/wrap/wrap-fetch.js +1 -1
  88. package/dist/esm/common/wrap/wrap-history.js +1 -1
  89. package/dist/esm/common/wrap/wrap-jsonp.js +1 -1
  90. package/dist/esm/common/wrap/wrap-mutation.js +1 -1
  91. package/dist/esm/common/wrap/wrap-promise.js +1 -1
  92. package/dist/esm/common/wrap/wrap-raf.js +2 -2
  93. package/dist/esm/common/wrap/wrap-timer.js +2 -2
  94. package/dist/esm/common/wrap/wrap-xhr.js +1 -1
  95. package/dist/esm/features/ajax/aggregate/index.js +1 -1
  96. package/dist/esm/features/ajax/instrument/distributed-tracing.js +1 -1
  97. package/dist/esm/features/ajax/instrument/index.js +1 -2
  98. package/dist/esm/features/jserrors/aggregate/index.js +10 -3
  99. package/dist/esm/features/jserrors/instrument/index.js +3 -16
  100. package/dist/esm/features/metrics/aggregate/framework-detection.js +1 -1
  101. package/dist/esm/features/metrics/aggregate/index.js +1 -1
  102. package/dist/esm/features/page_action/aggregate/index.js +1 -1
  103. package/dist/esm/features/page_view_event/aggregate/index.js +1 -2
  104. package/dist/esm/features/page_view_event/instrument/index.js +1 -1
  105. package/dist/esm/features/page_view_timing/aggregate/index.js +2 -4
  106. package/dist/esm/features/page_view_timing/instrument/index.js +1 -1
  107. package/dist/esm/features/session_replay/aggregate/index.js +92 -78
  108. package/dist/esm/features/session_replay/replay-mode.js +23 -0
  109. package/dist/esm/features/session_trace/aggregate/index.js +223 -100
  110. package/dist/esm/features/session_trace/constants.js +0 -1
  111. package/dist/esm/features/session_trace/instrument/index.js +2 -18
  112. package/dist/esm/features/spa/aggregate/index.js +1 -1
  113. package/dist/esm/features/spa/constants.js +0 -1
  114. package/dist/esm/features/spa/instrument/index.js +1 -1
  115. package/dist/esm/features/utils/agent-session.js +21 -37
  116. package/dist/esm/features/utils/aggregate-base.js +7 -12
  117. package/dist/esm/features/utils/handler-cache.js +28 -23
  118. package/dist/esm/features/utils/instrument-base.js +57 -39
  119. package/dist/esm/index.js +1 -4
  120. package/dist/esm/loaders/agent.js +7 -1
  121. package/dist/esm/loaders/api/api.js +2 -2
  122. package/dist/esm/loaders/api/apiAsync.js +3 -3
  123. package/dist/esm/loaders/configure/configure.js +1 -1
  124. package/dist/esm/loaders/features/featureDependencies.js +2 -0
  125. package/dist/esm/loaders/micro-agent.js +29 -38
  126. package/dist/types/common/config/state/init.d.ts.map +1 -1
  127. package/dist/types/common/constants/runtime.d.ts +29 -0
  128. package/dist/types/common/constants/runtime.d.ts.map +1 -0
  129. package/dist/types/common/constants/shared-channel.d.ts +5 -0
  130. package/dist/types/common/constants/shared-channel.d.ts.map +1 -0
  131. package/dist/types/common/harvest/harvest-scheduler.d.ts +5 -1
  132. package/dist/types/common/harvest/harvest-scheduler.d.ts.map +1 -1
  133. package/dist/types/common/harvest/harvest.d.ts +49 -38
  134. package/dist/types/common/harvest/harvest.d.ts.map +1 -1
  135. package/dist/types/common/harvest/types.d.ts +100 -0
  136. package/dist/types/common/harvest/types.d.ts.map +1 -0
  137. package/dist/types/common/session/session-entity.d.ts +9 -5
  138. package/dist/types/common/session/session-entity.d.ts.map +1 -1
  139. package/dist/types/common/unload/eol.d.ts.map +1 -1
  140. package/dist/types/common/util/feature-flags.d.ts +1 -0
  141. package/dist/types/common/util/feature-flags.d.ts.map +1 -1
  142. package/dist/types/common/util/submit-data.d.ts +62 -64
  143. package/dist/types/common/util/submit-data.d.ts.map +1 -1
  144. package/dist/types/features/ajax/instrument/index.d.ts.map +1 -1
  145. package/dist/types/features/jserrors/aggregate/index.d.ts +2 -1
  146. package/dist/types/features/jserrors/aggregate/index.d.ts.map +1 -1
  147. package/dist/types/features/jserrors/instrument/index.d.ts +1 -1
  148. package/dist/types/features/jserrors/instrument/index.d.ts.map +1 -1
  149. package/dist/types/features/page_view_event/aggregate/index.d.ts.map +1 -1
  150. package/dist/types/features/page_view_timing/aggregate/index.d.ts.map +1 -1
  151. package/dist/types/features/session_replay/aggregate/index.d.ts +14 -5
  152. package/dist/types/features/session_replay/aggregate/index.d.ts.map +1 -1
  153. package/dist/types/features/session_replay/instrument/index.d.ts.map +1 -1
  154. package/dist/types/features/session_replay/replay-mode.d.ts +9 -0
  155. package/dist/types/features/session_replay/replay-mode.d.ts.map +1 -0
  156. package/dist/types/features/session_trace/aggregate/index.d.ts +21 -3
  157. package/dist/types/features/session_trace/aggregate/index.d.ts.map +1 -1
  158. package/dist/types/features/session_trace/constants.d.ts +0 -1
  159. package/dist/types/features/session_trace/constants.d.ts.map +1 -1
  160. package/dist/types/features/session_trace/instrument/index.d.ts +0 -2
  161. package/dist/types/features/session_trace/instrument/index.d.ts.map +1 -1
  162. package/dist/types/features/spa/constants.d.ts.map +1 -1
  163. package/dist/types/features/utils/agent-session.d.ts.map +1 -1
  164. package/dist/types/features/utils/aggregate-base.d.ts +6 -1
  165. package/dist/types/features/utils/aggregate-base.d.ts.map +1 -1
  166. package/dist/types/features/utils/handler-cache.d.ts +12 -11
  167. package/dist/types/features/utils/handler-cache.d.ts.map +1 -1
  168. package/dist/types/features/utils/instrument-base.d.ts +17 -1
  169. package/dist/types/features/utils/instrument-base.d.ts.map +1 -1
  170. package/dist/types/index.d.ts +1 -0
  171. package/dist/types/loaders/agent.d.ts +4 -4
  172. package/dist/types/loaders/agent.d.ts.map +1 -1
  173. package/dist/types/loaders/features/featureDependencies.d.ts.map +1 -1
  174. package/dist/types/loaders/micro-agent.d.ts +3 -4
  175. package/dist/types/loaders/micro-agent.d.ts.map +1 -1
  176. package/package.json +14 -7
  177. package/src/common/config/__mocks__/config.js +11 -0
  178. package/src/common/config/state/init.js +1 -0
  179. package/src/common/config/state/runtime.js +1 -1
  180. package/src/common/constants/__mocks__/env.js +3 -0
  181. package/src/common/constants/__mocks__/runtime.js +8 -0
  182. package/src/common/constants/env.cdn.test.js +7 -0
  183. package/src/common/constants/env.npm.test.js +7 -0
  184. package/src/common/constants/env.test.js +7 -0
  185. package/src/common/constants/runtime.js +71 -0
  186. package/src/common/constants/runtime.test.js +168 -0
  187. package/src/common/constants/shared-channel.js +13 -0
  188. package/src/common/context/__mocks__/shared-context.js +8 -0
  189. package/src/common/event-listener/__mocks__/event-listener-opts.js +7 -0
  190. package/src/common/event-listener/event-listener-opts.js +1 -1
  191. package/src/common/harvest/__mocks__/harvest.js +13 -0
  192. package/src/common/harvest/harvest-scheduler.js +31 -19
  193. package/src/common/harvest/harvest-scheduler.test.js +491 -20
  194. package/src/common/harvest/harvest.js +147 -130
  195. package/src/common/harvest/harvest.test.js +788 -139
  196. package/src/common/harvest/types.js +47 -0
  197. package/src/common/ids/id.js +1 -1
  198. package/src/common/ids/unique-id.js +1 -1
  199. package/src/common/session/__mocks__/session-entity.js +25 -0
  200. package/src/common/session/{session-entity.test.js → session-entity.component-test.js} +71 -48
  201. package/src/common/session/session-entity.js +16 -13
  202. package/src/common/timer/interaction-timer.js +2 -2
  203. package/src/common/timing/__mocks__/now.js +1 -0
  204. package/src/common/unload/__mocks__/eol.js +1 -0
  205. package/src/common/unload/eol.js +1 -2
  206. package/src/common/url/__mocks__/clean-url.js +1 -0
  207. package/src/common/url/__mocks__/encode.js +7 -0
  208. package/src/common/url/__mocks__/location.js +1 -0
  209. package/src/common/url/canonicalize-url.js +1 -1
  210. package/src/common/url/canonicalize-url.test.js +32 -21
  211. package/src/common/url/parse-url.js +1 -1
  212. package/src/common/url/parse-url.test.js +3 -3
  213. package/src/common/url/protocol.js +1 -1
  214. package/src/common/util/__mocks__/obfuscate.js +10 -0
  215. package/src/common/util/__mocks__/stringify.js +1 -0
  216. package/src/common/util/__mocks__/submit-data.js +6 -0
  217. package/src/common/util/__mocks__/traverse.js +1 -0
  218. package/src/common/util/data-size.test.js +27 -20
  219. package/src/common/util/feature-flags.js +24 -12
  220. package/src/common/util/feature-flags.test.js +98 -0
  221. package/src/common/util/obfuscate.component-test.js +173 -0
  222. package/src/common/util/obfuscate.js +2 -2
  223. package/src/common/util/submit-data.js +42 -56
  224. package/src/common/util/submit-data.test.js +158 -137
  225. package/src/common/window/nreum.js +1 -1
  226. package/src/common/wrap/wrap-events.js +1 -1
  227. package/src/common/wrap/wrap-fetch.js +1 -1
  228. package/src/common/wrap/wrap-history.js +1 -1
  229. package/src/common/wrap/wrap-jsonp.js +1 -1
  230. package/src/common/wrap/wrap-mutation.js +1 -1
  231. package/src/common/wrap/wrap-promise.js +1 -1
  232. package/src/common/wrap/wrap-promise.test.js +2 -2
  233. package/src/common/wrap/wrap-raf.js +2 -2
  234. package/src/common/wrap/wrap-timer.js +2 -2
  235. package/src/common/wrap/wrap-xhr.js +1 -1
  236. package/src/features/ajax/aggregate/index.js +1 -1
  237. package/src/features/ajax/instrument/distributed-tracing.js +1 -1
  238. package/src/features/ajax/instrument/index.js +1 -2
  239. package/src/features/jserrors/aggregate/compute-stack-trace.test.js +1 -1
  240. package/src/features/jserrors/aggregate/index.js +12 -3
  241. package/src/features/jserrors/instrument/index.js +3 -16
  242. package/src/features/metrics/aggregate/framework-detection.js +1 -1
  243. package/src/features/metrics/aggregate/framework-detection.test.js +2 -2
  244. package/src/features/metrics/aggregate/index.js +1 -1
  245. package/src/features/page_action/aggregate/index.js +1 -1
  246. package/src/features/page_view_event/aggregate/index.js +1 -2
  247. package/src/features/page_view_event/instrument/index.js +1 -1
  248. package/src/features/page_view_timing/aggregate/index.js +2 -4
  249. package/src/features/page_view_timing/instrument/index.js +1 -1
  250. package/src/features/session_replay/aggregate/index.component-test.js +368 -0
  251. package/src/features/session_replay/aggregate/index.js +96 -71
  252. package/src/features/session_replay/instrument/index.js +0 -1
  253. package/src/features/session_replay/replay-mode.js +23 -0
  254. package/src/features/session_trace/aggregate/index.js +198 -79
  255. package/src/features/session_trace/constants.js +0 -1
  256. package/src/features/session_trace/instrument/index.js +3 -20
  257. package/src/features/spa/aggregate/index.js +1 -1
  258. package/src/features/spa/constants.js +0 -1
  259. package/src/features/spa/instrument/index.js +1 -1
  260. package/src/features/utils/agent-session.js +22 -34
  261. package/src/features/utils/agent-session.test.js +194 -0
  262. package/src/features/utils/aggregate-base.js +12 -9
  263. package/src/features/utils/aggregate-base.test.js +122 -0
  264. package/src/features/utils/feature-base.test.js +45 -0
  265. package/src/features/utils/handler-cache.js +29 -23
  266. package/src/features/utils/handler-cache.test.js +72 -0
  267. package/src/features/utils/instrument-base.js +45 -29
  268. package/src/features/utils/instrument-base.test.js +209 -0
  269. package/src/features/utils/lazy-feature-loader.test.js +37 -0
  270. package/src/index.js +1 -3
  271. package/src/loaders/agent.js +8 -1
  272. package/src/loaders/api/api.js +2 -2
  273. package/src/loaders/api/apiAsync.js +3 -3
  274. package/src/loaders/configure/configure.js +1 -1
  275. package/src/loaders/features/featureDependencies.js +2 -0
  276. package/src/loaders/micro-agent.js +26 -30
  277. package/dist/cjs/common/browser-version/firefox-version.js +0 -17
  278. package/dist/cjs/common/browser-version/ios-version.js +0 -19
  279. package/dist/cjs/common/event-emitter/contextual-ee.test.js +0 -282
  280. package/dist/cjs/common/event-emitter/handle.test.js +0 -58
  281. package/dist/cjs/common/event-emitter/register-handler.test.js +0 -55
  282. package/dist/cjs/common/harvest/harvest-scheduler.test.js +0 -39
  283. package/dist/cjs/common/harvest/harvest.test.js +0 -224
  284. package/dist/cjs/common/ids/id.test.js +0 -85
  285. package/dist/cjs/common/ids/unique-id.test.js +0 -49
  286. package/dist/cjs/common/session/session-entity.test.js +0 -460
  287. package/dist/cjs/common/storage/local-memory.js +0 -35
  288. package/dist/cjs/common/storage/local-memory.test.js +0 -20
  289. package/dist/cjs/common/storage/local-storage.test.js +0 -14
  290. package/dist/cjs/common/timer/interaction-timer.test.js +0 -216
  291. package/dist/cjs/common/timer/timer.test.js +0 -105
  292. package/dist/cjs/common/timing/nav-timing.test.js +0 -192
  293. package/dist/cjs/common/url/canonicalize-url.test.js +0 -42
  294. package/dist/cjs/common/url/clean-url.test.js +0 -9
  295. package/dist/cjs/common/url/encode.test.js +0 -74
  296. package/dist/cjs/common/url/location.test.js +0 -13
  297. package/dist/cjs/common/url/parse-url.test.js +0 -111
  298. package/dist/cjs/common/url/protocol.test.js +0 -15
  299. package/dist/cjs/common/util/console.test.js +0 -30
  300. package/dist/cjs/common/util/data-size.test.js +0 -47
  301. package/dist/cjs/common/util/get-or-set.test.js +0 -47
  302. package/dist/cjs/common/util/global-scope.js +0 -58
  303. package/dist/cjs/common/util/invoke.test.js +0 -49
  304. package/dist/cjs/common/util/map-own.test.js +0 -49
  305. package/dist/cjs/common/util/stringify.test.js +0 -48
  306. package/dist/cjs/common/util/submit-data.test.js +0 -221
  307. package/dist/cjs/common/util/traverse.test.js +0 -44
  308. package/dist/cjs/common/wrap/wrap-promise.test.js +0 -119
  309. package/dist/cjs/features/jserrors/aggregate/canonical-function-name.test.js +0 -31
  310. package/dist/cjs/features/jserrors/aggregate/compute-stack-trace.test.js +0 -383
  311. package/dist/cjs/features/jserrors/aggregate/format-stack-trace.test.js +0 -40
  312. package/dist/cjs/features/jserrors/aggregate/string-hash-code.test.js +0 -27
  313. package/dist/cjs/features/metrics/aggregate/framework-detection.test.js +0 -137
  314. package/dist/cjs/features/metrics/aggregate/polyfill-detection.es5.test.js +0 -17
  315. package/dist/cjs/features/metrics/aggregate/polyfill-detection.test.js +0 -165
  316. package/dist/cjs/features/spa/aggregate/interaction-node.test.js +0 -16
  317. package/dist/esm/common/browser-version/firefox-version.js +0 -10
  318. package/dist/esm/common/browser-version/ios-version.js +0 -11
  319. package/dist/esm/common/event-emitter/contextual-ee.test.js +0 -278
  320. package/dist/esm/common/event-emitter/handle.test.js +0 -54
  321. package/dist/esm/common/event-emitter/register-handler.test.js +0 -51
  322. package/dist/esm/common/harvest/harvest-scheduler.test.js +0 -37
  323. package/dist/esm/common/harvest/harvest.test.js +0 -222
  324. package/dist/esm/common/ids/id.test.js +0 -81
  325. package/dist/esm/common/ids/unique-id.test.js +0 -44
  326. package/dist/esm/common/session/session-entity.test.js +0 -458
  327. package/dist/esm/common/storage/local-memory.js +0 -28
  328. package/dist/esm/common/storage/local-memory.test.js +0 -18
  329. package/dist/esm/common/storage/local-storage.test.js +0 -12
  330. package/dist/esm/common/timer/interaction-timer.test.js +0 -214
  331. package/dist/esm/common/timer/timer.test.js +0 -103
  332. package/dist/esm/common/timing/nav-timing.test.js +0 -190
  333. package/dist/esm/common/url/canonicalize-url.test.js +0 -38
  334. package/dist/esm/common/url/clean-url.test.js +0 -7
  335. package/dist/esm/common/url/encode.test.js +0 -70
  336. package/dist/esm/common/url/location.test.js +0 -11
  337. package/dist/esm/common/url/parse-url.test.js +0 -107
  338. package/dist/esm/common/url/protocol.test.js +0 -13
  339. package/dist/esm/common/util/console.test.js +0 -28
  340. package/dist/esm/common/util/data-size.test.js +0 -45
  341. package/dist/esm/common/util/get-or-set.test.js +0 -45
  342. package/dist/esm/common/util/global-scope.js +0 -45
  343. package/dist/esm/common/util/invoke.test.js +0 -47
  344. package/dist/esm/common/util/map-own.test.js +0 -47
  345. package/dist/esm/common/util/stringify.test.js +0 -46
  346. package/dist/esm/common/util/submit-data.test.js +0 -219
  347. package/dist/esm/common/util/traverse.test.js +0 -42
  348. package/dist/esm/common/wrap/wrap-promise.test.js +0 -115
  349. package/dist/esm/features/jserrors/aggregate/canonical-function-name.test.js +0 -29
  350. package/dist/esm/features/jserrors/aggregate/compute-stack-trace.test.js +0 -379
  351. package/dist/esm/features/jserrors/aggregate/format-stack-trace.test.js +0 -38
  352. package/dist/esm/features/jserrors/aggregate/string-hash-code.test.js +0 -25
  353. package/dist/esm/features/metrics/aggregate/framework-detection.test.js +0 -133
  354. package/dist/esm/features/metrics/aggregate/polyfill-detection.es5.test.js +0 -15
  355. package/dist/esm/features/metrics/aggregate/polyfill-detection.test.js +0 -163
  356. package/dist/esm/features/spa/aggregate/interaction-node.test.js +0 -14
  357. package/dist/types/common/browser-version/firefox-version.d.ts +0 -2
  358. package/dist/types/common/browser-version/firefox-version.d.ts.map +0 -1
  359. package/dist/types/common/browser-version/ios-version.d.ts +0 -3
  360. package/dist/types/common/browser-version/ios-version.d.ts.map +0 -1
  361. package/dist/types/common/storage/local-memory.d.ts +0 -8
  362. package/dist/types/common/storage/local-memory.d.ts.map +0 -1
  363. package/dist/types/common/util/global-scope.d.ts +0 -14
  364. package/dist/types/common/util/global-scope.d.ts.map +0 -1
  365. package/src/common/browser-version/firefox-version.js +0 -10
  366. package/src/common/browser-version/ios-version.js +0 -11
  367. package/src/common/storage/local-memory.js +0 -30
  368. package/src/common/storage/local-memory.test.js +0 -19
  369. package/src/common/util/global-scope.js +0 -49
  370. /package/src/common/timer/{interaction-timer.test.js → interaction-timer.component-test.js} +0 -0
  371. /package/src/common/url/{encode.test.js → encode.component-test.js} +0 -0
  372. /package/src/common/url/{protocol.test.js → protocol.component-test.js} +0 -0
@@ -4,13 +4,14 @@
4
4
  */
5
5
  import { registerHandler } from '../../../common/event-emitter/register-handler';
6
6
  import { HarvestScheduler } from '../../../common/harvest/harvest-scheduler';
7
- import { stringify } from '../../../common/util/stringify';
8
7
  import { parseUrl } from '../../../common/url/parse-url';
9
- import { getConfigurationValue, getInfo, getRuntime } from '../../../common/config/config';
8
+ import { getConfigurationValue, getRuntime } from '../../../common/config/config';
10
9
  import { now } from '../../../common/timing/now';
11
10
  import { FEATURE_NAME } from '../constants';
12
11
  import { drain } from '../../../common/drain/drain';
13
12
  import { HandlerCache } from '../../utils/handler-cache';
13
+ import { MODE, SESSION_EVENTS } from '../../../common/session/session-entity';
14
+ import { getSessionReplayMode } from '../../session_replay/replay-mode';
14
15
  import { AggregateBase } from '../../utils/aggregate-base';
15
16
  const ignoredEvents = {
16
17
  // we find that certain events make the data too noisy to be useful
@@ -34,16 +35,21 @@ const toAggregate = {
34
35
  mousing: [1000, 2000],
35
36
  touching: [1000, 2000]
36
37
  };
37
- const MAX_TRACE_DURATION = 15 * 60 * 1000; // 15 minutes
38
+ const MAX_TRACE_DURATION = 10 * 60 * 1000; // 10 minutes
39
+ const REQ_THRESHOLD_TO_SEND = 30;
40
+ const ERROR_MODE_SECONDS_WINDOW = 30 * 1000; // sliding window of nodes to track when simply monitoring (but not harvesting) in error mode
38
41
 
39
42
  export class Aggregate extends AggregateBase {
40
43
  static featureName = FEATURE_NAME;
44
+ #scheduler;
41
45
  constructor(agentIdentifier, aggregator, argsObj) {
42
46
  var _this;
43
- // Very unlikely, but in case the existing XMLHttpRequest.prototype object on the page couldn't be wrapped.
44
47
  super(agentIdentifier, aggregator, FEATURE_NAME);
45
48
  _this = this;
46
- if (!getRuntime(agentIdentifier).xhrWrappable) return;
49
+ this.agentRuntime = getRuntime(agentIdentifier);
50
+
51
+ // Very unlikely, but in case the existing XMLHttpRequest.prototype object on the page couldn't be wrapped.
52
+ if (!this.agentRuntime.xhrWrappable) return;
47
53
  this.resourceObserver = argsObj?.resourceObserver; // undefined if observer couldn't be created
48
54
  this.ptid = '';
49
55
  this.trace = {};
@@ -51,105 +57,217 @@ export class Aggregate extends AggregateBase {
51
57
  this.sentTrace = null;
52
58
  this.harvestTimeSeconds = getConfigurationValue(agentIdentifier, 'session_trace.harvestTimeSeconds') || 10;
53
59
  this.maxNodesPerHarvest = getConfigurationValue(agentIdentifier, 'session_trace.maxNodesPerHarvest') || 1000;
54
- this.laststart = 0;
55
- const handlerCache = new HandlerCache();
56
- registerHandler('feat-stn', () => {
57
- if (typeof PerformanceNavigationTiming !== 'undefined') {
58
- this.storeTiming(window.performance.getEntriesByType('navigation')[0]);
59
- } else {
60
- this.storeTiming(window.performance.timing);
60
+ this.isStandalone = false;
61
+ const operationalGate = new HandlerCache(); // acts as a controller-intermediary that can enable or disable this feature's collection dynamically
62
+ const sessionEntity = this.agentRuntime.session;
63
+
64
+ /* --- The following section deals with user sessions concept & contains non-trivial control flow. --- */
65
+ const controlTraceOp = traceMode => {
66
+ switch (traceMode) {
67
+ case MODE.ERROR:
68
+ this.startTracing(operationalGate, true);
69
+ break;
70
+ case MODE.FULL:
71
+ case true:
72
+ this.startTracing(operationalGate);
73
+ break;
74
+ case MODE.OFF:
75
+ case false:
76
+ default:
77
+ // this feature becomes "off" (does nothing & nothing is sent)
78
+ operationalGate.decide(false);
79
+ break;
61
80
  }
62
- const scheduler = new HarvestScheduler('resources', {
63
- onFinished: onHarvestFinished.bind(this),
64
- retryDelay: this.harvestTimeSeconds
65
- }, this);
66
- scheduler.harvest.on('resources', prepareHarvest.bind(this));
67
- scheduler.runHarvest({
68
- needResponse: true
69
- }); // sends first stn harvest immediately
70
- handlerCache.decide(true);
71
- function onHarvestFinished(result) {
72
- if (result.sent && result.responseText && !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;
75
- scheduler.startTimer(this.harvestTimeSeconds);
81
+ };
82
+ if (!sessionEntity) {
83
+ // Since session manager isn't around, do the old Trace behavior of waiting for RUM response to decide feature activation.
84
+ this.isStandalone = true;
85
+ registerHandler('rumresp-stn', on => controlTraceOp(on), this.featureName, this.ee);
86
+ } else {
87
+ let seenAnError = false;
88
+ let mostRecentModeKnown;
89
+ registerHandler('errorAgg', () => {
90
+ // Switch to full capture mode on next harvest on first exception thrown only. Only done once so that sessionTraceMode isn't constantly overwritten after decision block.
91
+ if (!seenAnError) {
92
+ seenAnError = true;
93
+ /* If this cb executes before Trace has started, then no further action needed. But if...
94
+ - startTracing already ran under ERROR mode, then it will NOT have kicked off the harvest-scheduler so that needs to be done & switch mode.
95
+ - startTracing never ran because mode is OFF or Replay aborted or Traced turned off elsewhere OR trace already in FULL, then this should do nothing. */
96
+ if (sessionEntity.state.sessionTraceMode === MODE.ERROR && this.#scheduler) {
97
+ sessionEntity.write({
98
+ sessionTraceMode: mostRecentModeKnown = MODE.FULL
99
+ });
100
+ this.trimSTNs(ERROR_MODE_SECONDS_WINDOW); // up until now, Trace would've been just buffering nodes up to max, which needs to be trimmed to last X seconds
101
+ this.#scheduler.runHarvest({
102
+ needResponse: true
103
+ });
104
+ }
76
105
  }
77
- if (result.sent && result.retry && this.sentTrace) {
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
+ }, this.featureName, this.ee);
107
+ const stopTracePerm = () => {
108
+ if (sessionEntity.state.sessionTraceMode !== MODE.OFF) sessionEntity.write({
109
+ sessionTraceMode: MODE.OFF
110
+ });
111
+ operationalGate.permanentlyDecide(false);
112
+ this.#scheduler?.stopTimer(true);
113
+ if (mostRecentModeKnown === MODE.FULL) this.#scheduler?.runHarvest(); // allow queued nodes (past opGate) to final harvest, unless they were buffered in other modes
114
+ this.#scheduler = null;
115
+ };
116
+
117
+ // CAUTION: everything inside this promise runs post-load; event subscribers must be pre-load aka synchronous with constructor
118
+ this.waitForFlags(['stn', 'sr']).then(async _ref => {
119
+ let [traceOn, replayOn] = _ref;
120
+ if (!replayOn) {
121
+ // When sr = 0 from BCS, also do the old Trace behavior:
122
+ this.isStandalone = true;
123
+ controlTraceOp(traceOn);
124
+ } else {
125
+ this.ee.on('REPLAY_ABORTED', () => stopTracePerm());
126
+ /* Assuming on page visible that the trace mode is updated from shared session,
127
+ - if trace is turned off from the other page, it should be likewise here.
128
+ - if trace switches to Full mode, harvest should start (prev: Error) if not already running (prev: Full). */
129
+ this.ee.on(SESSION_EVENTS.RESUME, () => {
130
+ const updatedTraceMode = sessionEntity.state.sessionTraceMode;
131
+ if (updatedTraceMode === MODE.OFF) stopTracePerm();else if (updatedTraceMode === MODE.FULL && this.#scheduler && !this.#scheduler.started) this.#scheduler.runHarvest({
132
+ needResponse: true
133
+ });
134
+ mostRecentModeKnown = updatedTraceMode;
84
135
  });
85
- this.sentTrace = null;
86
- }
87
- }
88
- function prepareHarvest(options) {
89
- if (now() > MAX_TRACE_DURATION) {
90
- // been collecting for over 15 min, empty trace object and bail
91
- scheduler.stopTimer();
92
- this.trace = {};
93
- return;
136
+ this.ee.on(SESSION_EVENTS.PAUSE, () => mostRecentModeKnown = sessionEntity.state.sessionTraceMode);
137
+ if (!sessionEntity.isNew) {
138
+ // inherit the same mode as existing session's Trace
139
+ const existingTraceMode = mostRecentModeKnown = sessionEntity.state.sessionTraceMode;
140
+ if (existingTraceMode === MODE.OFF) this.isStandalone = true;
141
+ controlTraceOp(existingTraceMode);
142
+ } else {
143
+ // for new sessions, see the truth table associated with NEWRELIC-8662 wrt the new Trace behavior under session management
144
+ const replayMode = await getSessionReplayMode(agentIdentifier);
145
+ if (replayMode === MODE.OFF) this.isStandalone = true; // without SR, Traces are still subject to old harvest limits
146
+
147
+ let startingMode;
148
+ if (traceOn === true) {
149
+ // CASE: both trace (entitlement+sampling) & replay (entitlement) flags are true from RUM
150
+ startingMode = MODE.FULL; // always full capture regardless of replay sampling decisions
151
+ } else {
152
+ // CASE: trace flag is off, BUT it must still run if replay is on (possibly)
153
+ // At this point, it's possible that 1 or more exception was thrown, in which case just start in full if Replay originally started in ERROR mode.
154
+ if (replayMode === MODE.ERROR && seenAnError) startingMode = MODE.FULL;else startingMode = replayMode;
155
+ }
156
+ sessionEntity.write({
157
+ sessionTraceMode: mostRecentModeKnown = startingMode
158
+ });
159
+ controlTraceOp(startingMode);
160
+ }
94
161
  }
95
- // Only harvest when there are more than 30 nodes to send after the very first.
96
- if (this.ptid && this.nodeCount <= 30) return;
97
- return this.takeSTNs(options.retry);
98
- }
99
- }, this.featureName, this.ee);
100
- registerHandler('block-stn', () => handlerCache.decide(false), this.featureName, this.ee);
162
+ });
163
+ }
164
+ /* --- EoS --- */
101
165
 
102
166
  // register the handlers immediately... but let the handlerCache decide if the data should actually get stored...
103
167
  registerHandler('bst', function () {
104
168
  for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
105
169
  args[_key] = arguments[_key];
106
170
  }
107
- return handlerCache.settle(() => _this.storeEvent(...args));
171
+ return operationalGate.settle(() => _this.storeEvent(...args));
108
172
  }, this.featureName, this.ee);
109
- registerHandler('bstTimer', function () {
173
+ registerHandler('bstResource', function () {
110
174
  for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
111
175
  args[_key2] = arguments[_key2];
112
176
  }
113
- return handlerCache.settle(() => _this.storeTimer(...args));
177
+ return operationalGate.settle(() => _this.storeResources(...args));
114
178
  }, this.featureName, this.ee);
115
- registerHandler('bstResource', function () {
179
+ registerHandler('bstHist', function () {
116
180
  for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
117
181
  args[_key3] = arguments[_key3];
118
182
  }
119
- return handlerCache.settle(() => _this.storeResources(...args));
183
+ return operationalGate.settle(() => _this.storeHist(...args));
120
184
  }, this.featureName, this.ee);
121
- registerHandler('bstHist', function () {
185
+ registerHandler('bstXhrAgg', function () {
122
186
  for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
123
187
  args[_key4] = arguments[_key4];
124
188
  }
125
- return handlerCache.settle(() => _this.storeHist(...args));
189
+ return operationalGate.settle(() => _this.storeXhrAgg(...args));
126
190
  }, this.featureName, this.ee);
127
- registerHandler('bstXhrAgg', function () {
191
+ registerHandler('bstApi', function () {
128
192
  for (var _len5 = arguments.length, args = new Array(_len5), _key5 = 0; _key5 < _len5; _key5++) {
129
193
  args[_key5] = arguments[_key5];
130
194
  }
131
- return handlerCache.settle(() => _this.storeXhrAgg(...args));
195
+ return operationalGate.settle(() => _this.storeSTN(...args));
132
196
  }, this.featureName, this.ee);
133
- registerHandler('bstApi', function () {
197
+ registerHandler('errorAgg', function () {
134
198
  for (var _len6 = arguments.length, args = new Array(_len6), _key6 = 0; _key6 < _len6; _key6++) {
135
199
  args[_key6] = arguments[_key6];
136
200
  }
137
- return handlerCache.settle(() => _this.storeSTN(...args));
201
+ return operationalGate.settle(() => _this.storeErrorAgg(...args));
138
202
  }, this.featureName, this.ee);
139
- registerHandler('errorAgg', function () {
203
+ registerHandler('pvtAdded', function () {
140
204
  for (var _len7 = arguments.length, args = new Array(_len7), _key7 = 0; _key7 < _len7; _key7++) {
141
205
  args[_key7] = arguments[_key7];
142
206
  }
143
- return handlerCache.settle(() => _this.storeErrorAgg(...args));
144
- }, this.featureName, this.ee);
145
- registerHandler('pvtAdded', function () {
146
- for (var _len8 = arguments.length, args = new Array(_len8), _key8 = 0; _key8 < _len8; _key8++) {
147
- args[_key8] = arguments[_key8];
148
- }
149
- return handlerCache.settle(() => _this.processPVT(...args));
207
+ return operationalGate.settle(() => _this.processPVT(...args));
150
208
  }, this.featureName, this.ee);
151
209
  drain(this.agentIdentifier, this.featureName);
152
210
  }
211
+ startTracing(startupBuffer) {
212
+ let dontStartHarvestYet = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
213
+ if (typeof PerformanceNavigationTiming !== 'undefined') {
214
+ this.storeTiming(window.performance.getEntriesByType('navigation')[0]);
215
+ } else {
216
+ this.storeTiming(window.performance.timing);
217
+ }
218
+ this.#scheduler = new HarvestScheduler('resources', {
219
+ onFinished: this.#onHarvestFinished.bind(this),
220
+ retryDelay: this.harvestTimeSeconds
221
+ }, this);
222
+ this.#scheduler.harvest.on('resources', this.#prepareHarvest.bind(this));
223
+ if (dontStartHarvestYet === false) this.#scheduler.runHarvest({
224
+ needResponse: true
225
+ }); // sends first stn harvest immediately
226
+ startupBuffer.decide(true); // signal to ALLOW & process data in EE's buffer into internal nodes queued for next harvest
227
+ }
228
+
229
+ #onHarvestFinished(result) {
230
+ if (result.sent && result.responseText && !this.ptid) {
231
+ // continue interval harvest only if ptid was returned by server on the first
232
+ this.agentRuntime.ptid = this.ptid = result.responseText;
233
+ this.#scheduler.startTimer(this.harvestTimeSeconds);
234
+ }
235
+ if (result.sent && result.retry && this.sentTrace) {
236
+ // merge previous trace back into buffer to retry for next harvest
237
+ Object.entries(this.sentTrace).forEach(_ref2 => {
238
+ let [name, listOfSTNodes] = _ref2;
239
+ if (this.nodeCount >= this.maxNodesPerHarvest) return;
240
+ this.nodeCount += listOfSTNodes.length;
241
+ this.trace[name] = this.trace[name] ? listOfSTNodes.concat(this.trace[name]) : listOfSTNodes;
242
+ });
243
+ this.sentTrace = null;
244
+ }
245
+ }
246
+ #prepareHarvest(options) {
247
+ /* Standalone refers to the legacy version of ST before the idea of 'session' or the Replay feature existed.
248
+ It has a different behavior on returning a payload for harvest than when used in tandem with either of those concepts. */
249
+ if (this.isStandalone) {
250
+ if (now() > MAX_TRACE_DURATION) {
251
+ // been collecting for over the longest duration we should run for, empty trace object so ST has nothing to send
252
+ this.#scheduler.stopTimer();
253
+ this.trace = {};
254
+ return;
255
+ }
256
+ // Only harvest when more than some threshold of nodes are pending, after the very first harvest.
257
+ if (this.ptid && this.nodeCount <= REQ_THRESHOLD_TO_SEND) return;
258
+ } else {
259
+ // -- *cli May '26 - Update: Not rate limiting backgrounded pages either for now.
260
+ // if (this.ptid && document.visibilityState === 'hidden' && this.nodeCount <= REQ_THRESHOLD_TO_SEND) return
261
+
262
+ const currentMode = this.agentRuntime.session.state.sessionTraceMode;
263
+ /* There could still be nodes previously collected even after Trace (w/ session mgmt) is turned off. Hence, continue to send the last batch.
264
+ * The intermediary controller SHOULD be already switched off so that no nodes are further queued. */
265
+ if (currentMode === MODE.OFF && Object.keys(this.trace).length === 0) return;
266
+ if (currentMode === MODE.ERROR) return; // Trace in this mode should never be harvesting, even on unload
267
+ }
268
+
269
+ return this.takeSTNs(options.retry);
270
+ }
153
271
 
154
272
  // PageViewTiming (FEATURE) events and metrics, such as 'load', 'lcp', etc. pipes into ST here.
155
273
  processPVT(name, value, attrs) {
@@ -191,18 +309,6 @@ export class Aggregate extends AggregateBase {
191
309
  }
192
310
  }
193
311
 
194
- // Tracks duration of native APIs wrapped by wrap-timer & wrap-raf.
195
- storeTimer(target, start, end, type) {
196
- const evt = {
197
- n: type,
198
- s: start,
199
- e: end,
200
- o: 'window',
201
- t: type === 'requestAnimationFrame' ? type : 'timer'
202
- };
203
- this.storeSTN(evt);
204
- }
205
-
206
312
  // Tracks the events and their listener's duration on objects wrapped by wrap-events.
207
313
  storeEvent(currentEvent, target, start, end) {
208
314
  if (this.shouldIgnoreEvent(currentEvent, target)) return;
@@ -283,12 +389,12 @@ export class Aggregate extends AggregateBase {
283
389
  };
284
390
  this.storeSTN(node);
285
391
  }
286
-
392
+ #laststart = 0;
287
393
  // Processes all the PerformanceResourceTiming entries captured (by observer).
288
394
  storeResources(resources) {
289
395
  if (!resources || resources.length === 0) return;
290
396
  resources.forEach(currentResource => {
291
- if ((currentResource.fetchStart | 0) <= this.laststart) return; // don't recollect already-seen resources
397
+ if ((currentResource.fetchStart | 0) <= this.#laststart) return; // don't recollect already-seen resources
292
398
 
293
399
  const parsed = parseUrl(currentResource.name);
294
400
  const res = {
@@ -301,7 +407,7 @@ export class Aggregate extends AggregateBase {
301
407
  };
302
408
  this.storeSTN(res);
303
409
  });
304
- this.laststart = resources[resources.length - 1].fetchStart | 0;
410
+ this.#laststart = resources[resources.length - 1].fetchStart | 0;
305
411
  }
306
412
 
307
413
  // JavascriptError (FEATURE) events pipes into ST here.
@@ -332,20 +438,50 @@ export class Aggregate extends AggregateBase {
332
438
 
333
439
  // Central function called by all the other store__ & addToTrace API to append a trace node.
334
440
  storeSTN(stn) {
335
- if (this.nodeCount >= this.maxNodesPerHarvest) return; // limit the amount of data that is stored at once
336
-
441
+ if (this.nodeCount >= this.maxNodesPerHarvest) {
442
+ // limit the amount of pending data awaiting next harvest
443
+ if (this.isStandalone || this.agentRuntime.session.state.sessionTraceMode !== MODE.ERROR) return;
444
+ const openedSpace = this.trimSTNs(ERROR_MODE_SECONDS_WINDOW); // but maybe we could make some space by discarding irrelevant nodes if we're in sessioned Error mode
445
+ if (openedSpace == 0) return;
446
+ }
337
447
  if (this.trace[stn.n]) this.trace[stn.n].push(stn);else this.trace[stn.n] = [stn];
338
448
  this.nodeCount++;
339
449
  }
340
450
 
451
+ /**
452
+ * Trim the collection of nodes awaiting harvest such that those seen outside a certain span of time are discarded.
453
+ * @param {number} lookbackDuration Past length of time until now for which we care about nodes, in milliseconds
454
+ * @returns {number} However many nodes were discarded after trimming.
455
+ */
456
+ trimSTNs(lookbackDuration) {
457
+ let prunedNodes = 0;
458
+ const cutoffHighResTime = Math.max(now() - lookbackDuration, 0);
459
+ Object.keys(this.trace).forEach(nameCategory => {
460
+ const nodeList = this.trace[nameCategory];
461
+ /* Notice nodes are appending under their name's list as they end and are stored. This means each list is already (roughly) sorted in chronological order by end time.
462
+ * This isn't exact since nodes go through some processing & EE handlers chain, but it's close enough as we still capture nodes whose duration overlaps the lookback window.
463
+ * ASSUMPTION: all 'end' timings stored are relative to timeOrigin (DOMHighResTimeStamp) and not Unix epoch based. */
464
+ let cutoffIdx = nodeList.findIndex(node => cutoffHighResTime <= node.e);
465
+ if (cutoffIdx == 0) return;else if (cutoffIdx < 0) {
466
+ // whole list falls outside lookback window and is irrelevant
467
+ cutoffIdx = nodeList.length;
468
+ delete this.trace[nameCategory];
469
+ } else nodeList.splice(0, cutoffIdx); // chop off everything outside our window i.e. before the last <lookbackDuration> timeframe
470
+
471
+ this.nodeCount -= cutoffIdx;
472
+ prunedNodes += cutoffIdx;
473
+ });
474
+ return prunedNodes;
475
+ }
476
+
341
477
  // Used by session trace's harvester to create the payload body.
342
478
  takeSTNs(retry) {
343
479
  if (!this.resourceObserver) {
344
480
  // if PO isn't supported, this checks resourcetiming buffer every harvest.
345
481
  this.storeResources(window.performance.getEntriesByType('resource'));
346
482
  }
347
- const stns = Object.entries(this.trace).flatMap(_ref2 => {
348
- let [name, listOfSTNodes] = _ref2;
483
+ const stns = Object.entries(this.trace).flatMap(_ref3 => {
484
+ let [name, listOfSTNodes] = _ref3;
349
485
  // basically take the "this.trace" map-obj and concat all the list-type values
350
486
  if (!(name in toAggregate)) return listOfSTNodes;
351
487
  // Special processing for event nodes dealing with user inputs:
@@ -359,7 +495,7 @@ export class Aggregate extends AggregateBase {
359
495
  }
360
496
  this.trace = {};
361
497
  this.nodeCount = 0;
362
- const stnInfo = {
498
+ return {
363
499
  qs: {
364
500
  st: String(getRuntime(this.agentIdentifier).offset)
365
501
  },
@@ -367,19 +503,6 @@ export class Aggregate extends AggregateBase {
367
503
  res: stns
368
504
  }
369
505
  };
370
- if (!this.ptid) {
371
- // send custom and user attributes on the very first ST harvest only
372
- const {
373
- userAttributes,
374
- atts,
375
- jsAttributes
376
- } = getInfo(this.agentIdentifier);
377
- stnInfo.qs.ua = userAttributes;
378
- stnInfo.qs.at = atts;
379
- const ja = stringify(jsAttributes);
380
- stnInfo.qs.ja = ja === '{}' ? null : ja;
381
- }
382
- return stnInfo;
383
506
  }
384
507
  smearEvtsByOrigin(name) {
385
508
  const maxGap = toAggregate[name][0];
@@ -6,5 +6,4 @@ export const START = '-start';
6
6
  export const END = '-end';
7
7
  export const FN_START = 'fn' + START;
8
8
  export const FN_END = 'fn' + END;
9
- export const BST_TIMER = 'bstTimer';
10
9
  export const PUSH_STATE = 'pushState';
@@ -3,16 +3,15 @@
3
3
  * SPDX-License-Identifier: Apache-2.0
4
4
  */
5
5
  import { handle } from '../../../common/event-emitter/handle';
6
- import { wrapHistory, wrapEvents, wrapTimer, wrapRaf } from '../../../common/wrap';
6
+ import { wrapHistory, wrapEvents } from '../../../common/wrap';
7
7
  import { now } from '../../../common/timing/now';
8
8
  import { InstrumentBase } from '../../utils/instrument-base';
9
9
  import * as CONSTANTS from '../constants';
10
10
  import { FEATURE_NAMES } from '../../../loaders/features/features';
11
- import { isBrowserScope } from '../../../common/util/global-scope';
11
+ import { isBrowserScope } from '../../../common/constants/runtime';
12
12
  const {
13
13
  BST_RESOURCE,
14
14
  RESOURCE,
15
- BST_TIMER,
16
15
  START,
17
16
  END,
18
17
  FEATURE_NAME,
@@ -28,8 +27,6 @@ export class Instrument extends InstrumentBase {
28
27
  if (!isBrowserScope) return; // session traces not supported outside web env
29
28
 
30
29
  const thisInstrumentEE = this.ee;
31
- this.timerEE = wrapTimer(thisInstrumentEE);
32
- this.rafEE = wrapRaf(thisInstrumentEE);
33
30
  wrapHistory(thisInstrumentEE);
34
31
  this.eventsEE = wrapEvents(thisInstrumentEE);
35
32
  this.eventsEE.on(FN_START, function (args, target) {
@@ -40,19 +37,6 @@ export class Instrument extends InstrumentBase {
40
37
  // When ajax is disabled, this may fail without making ajax a dependency of session_trace
41
38
  handle('bst', [args[0], target, this.bstStart, now()], undefined, FEATURE_NAMES.sessionTrace, thisInstrumentEE);
42
39
  });
43
- this.timerEE.on(FN_START, function (args, obj, type) {
44
- this.bstStart = now();
45
- this.bstType = type;
46
- });
47
- this.timerEE.on(FN_END, function (args, target) {
48
- handle(BST_TIMER, [target, this.bstStart, now(), this.bstType], undefined, FEATURE_NAMES.sessionTrace, thisInstrumentEE);
49
- });
50
- this.rafEE.on(FN_START, function () {
51
- this.bstStart = now();
52
- });
53
- this.rafEE.on(FN_END, function (args, target) {
54
- handle(BST_TIMER, [target, this.bstStart, now(), 'requestAnimationFrame'], undefined, FEATURE_NAMES.sessionTrace, thisInstrumentEE);
55
- });
56
40
  thisInstrumentEE.on(PUSH_STATE + START, function (args) {
57
41
  this.time = now();
58
42
  this.startPath = location.pathname + location.hash;
@@ -619,7 +619,7 @@ export class Aggregate extends AggregateBase {
619
619
  function onHarvestFinished(result) {
620
620
  if (result.sent && result.retry && state.interactionsSent.length > 0) {
621
621
  state.interactionsSent.forEach(function (interaction) {
622
- state.interactionsToHarvest.push(interaction);
622
+ state.interactionsToHarvest.unshift(interaction);
623
623
  });
624
624
  state.interactionsSent = [];
625
625
  }
@@ -1,5 +1,4 @@
1
1
  import { originals } from '../../common/config/config';
2
- import { globalScope } from '../../common/util/global-scope';
3
2
  import { FEATURE_NAMES } from '../../loaders/features/features';
4
3
  export const FEATURE_NAME = FEATURE_NAMES.spa;
5
4
  export const INTERACTION_EVENTS = ['click', 'submit', 'keypress', 'keydown', 'keyup', 'change'];
@@ -8,7 +8,7 @@ import { InstrumentBase } from '../../utils/instrument-base';
8
8
  import { getRuntime } from '../../../common/config/config';
9
9
  import { now } from '../../../common/timing/now';
10
10
  import * as CONSTANTS from '../constants';
11
- import { isBrowserScope } from '../../../common/util/global-scope';
11
+ import { isBrowserScope } from '../../../common/constants/runtime';
12
12
  const {
13
13
  FEATURE_NAME,
14
14
  START,
@@ -1,8 +1,7 @@
1
- import { getConfigurationValue, getInfo, getRuntime, setInfo } from '../../common/config/config';
1
+ import { getConfiguration, getInfo, getRuntime } from '../../common/config/config';
2
2
  import { drain } from '../../common/drain/drain';
3
3
  import { ee } from '../../common/event-emitter/contextual-ee';
4
4
  import { registerHandler } from '../../common/event-emitter/register-handler';
5
- import { isBrowserScope } from '../../common/util/global-scope';
6
5
  import { SessionEntity } from '../../common/session/session-entity';
7
6
  import { LocalStorage } from '../../common/storage/local-storage.js';
8
7
  import { FirstPartyCookies } from '../../common/storage/first-party-cookies';
@@ -10,43 +9,28 @@ let ranOnce = 0;
10
9
  export function setupAgentSession(agentIdentifier) {
11
10
  const agentRuntime = getRuntime(agentIdentifier);
12
11
  if (ranOnce++) return agentRuntime.session;
13
- const sharedEE = ee.get(agentIdentifier);
12
+ const sessionInit = getConfiguration(agentIdentifier).session;
13
+ /* Domain is a string that can be specified by customer. The only way to keep the session object across subdomains is using first party cookies.
14
+ This determines which storage wrapper the session manager will use to keep state. */
15
+ const storageTypeInst = sessionInit?.domain ? new FirstPartyCookies(sessionInit.domain) : new LocalStorage();
16
+ agentRuntime.session = new SessionEntity({
17
+ agentIdentifier,
18
+ key: 'SESSION',
19
+ storage: storageTypeInst,
20
+ expiresMs: sessionInit?.expiresMs,
21
+ inactiveMs: sessionInit?.inactiveMs
22
+ });
14
23
 
15
- // domain is a string that can be specified by customer.
16
- // only way to keep the session object across subdomains is using first party cookies
17
- // This determines which storage wrapper the session manager will use to keep state
18
- let storageAPI;
19
- const cookiesEnabled = getConfigurationValue(agentIdentifier, 'privacy.cookies_enabled') === true;
20
- if (cookiesEnabled && isBrowserScope) {
21
- storageAPI = getConfigurationValue(agentIdentifier, 'session.domain') ? new FirstPartyCookies(getConfigurationValue(agentIdentifier, 'session.domain')) : new LocalStorage();
22
- }
23
- if (cookiesEnabled) {
24
- // defaults to "LocalMemory" if storageAPI is undefined, such as in Worker build
25
- agentRuntime.session = new SessionEntity({
26
- agentIdentifier,
27
- key: 'SESSION',
28
- storageAPI,
29
- expiresMs: getConfigurationValue(agentIdentifier, 'session.expiresMs'),
30
- inactiveMs: getConfigurationValue(agentIdentifier, 'session.inactiveMs')
31
- });
32
- }
33
-
34
- // The first time the agent runs on a page, it should put everything
35
- // that's currently stored in the storage API into the local info.jsAttributes object
36
- if (isBrowserScope) {
37
- // retrieve & re-add all of the persisted setCustomAttribute|setUserId k-v from previous page load(s)
38
- const customSessionData = agentRuntime.session.state.custom;
39
- const agentInfo = getInfo(agentIdentifier);
40
- if (customSessionData) {
41
- setInfo(agentIdentifier, {
42
- ...agentInfo,
43
- jsAttributes: {
44
- ...agentInfo.jsAttributes,
45
- ...customSessionData
46
- }
47
- });
48
- }
24
+ // Retrieve & re-add all of the persisted setCustomAttribute|setUserId k-v from previous page load(s), if any was stored.
25
+ const customSessionData = agentRuntime.session.state.custom;
26
+ const agentInfo = getInfo(agentIdentifier);
27
+ if (customSessionData) {
28
+ agentInfo.jsAttributes = {
29
+ ...agentInfo.jsAttributes,
30
+ ...customSessionData
31
+ };
49
32
  }
33
+ const sharedEE = ee.get(agentIdentifier);
50
34
 
51
35
  // any calls to newrelic.setCustomAttribute(<persisted>) will need to be added to:
52
36
  // local info.jsAttributes {}
@@ -8,21 +8,16 @@ export class AggregateBase extends FeatureBase {
8
8
  super(...arguments);
9
9
  this.checkConfiguration();
10
10
  }
11
+
12
+ /**
13
+ * New handler for waiting for multiple flags. Useful when expecting multiple flags simultaneously (ex. stn vs sr)
14
+ * @param {string[]} flagNames
15
+ * @returns
16
+ */
11
17
  waitForFlags() {
12
18
  let flagNames = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
13
19
  return Promise.all(flagNames.map(fName => new Promise(resolve => {
14
- registerHandler("feat-".concat(fName), () => {
15
- resolve({
16
- name: fName,
17
- value: true
18
- });
19
- }, this.featureName, this.ee);
20
- registerHandler("block-".concat(fName), () => {
21
- resolve({
22
- name: fName,
23
- value: false
24
- });
25
- }, this.feature, this.ee);
20
+ registerHandler("rumresp-".concat(fName), isOn => resolve(isOn), this.featureName, this.ee);
26
21
  })));
27
22
  }
28
23