@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
@@ -3,11 +3,12 @@
3
3
  * SPDX-License-Identifier: Apache-2.0
4
4
  */
5
5
 
6
- import { submitData } from '../util/submit-data';
6
+ import * as submitData from '../util/submit-data';
7
7
  import { SharedContext } from '../context/shared-context';
8
- import { Harvest, getSubmitMethod } from './harvest';
8
+ import { Harvest } from './harvest';
9
9
  import { subscribeToEOL } from '../unload/eol';
10
10
  import { getConfigurationValue } from '../config/config';
11
+ import { SESSION_EVENTS } from '../session/session-entity';
11
12
 
12
13
  /**
13
14
  * Periodically invokes harvest calls and handles retries
@@ -37,9 +38,18 @@ export class HarvestScheduler extends SharedContext {
37
38
  // unload if EOL mechanism fires
38
39
  subscribeToEOL(this.unload.bind(this), getConfigurationValue(this.sharedContext.agentIdentifier, 'allow_bfcache')); // TO DO: remove feature flag after rls stable
39
40
 
40
- // unload if session resets
41
- this.sharedContext?.ee.on('session-reset', this.unload.bind(this));
41
+ /* 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
+ 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
43
+ the wrong session ID. */
44
+ this.sharedContext?.ee.on(SESSION_EVENTS.RESET, () => this.runHarvest({
45
+ forceNoRetry: true
46
+ }));
42
47
  }
48
+
49
+ /**
50
+ * This function is only meant for the last outgoing harvest cycle of a page. It trickles down to using sendBeacon, which should not be used
51
+ * to send payloads while the page is still active, due to limitations on how much data can be buffered in the API at any one time.
52
+ */
43
53
  unload() {
44
54
  if (this.aborted) return;
45
55
  // If opts.onUnload is defined, these are special actions to execute before attempting to send the final payload.
@@ -63,26 +73,36 @@ export class HarvestScheduler extends SharedContext {
63
73
  }
64
74
  scheduleHarvest(delay, opts) {
65
75
  if (this.timeoutHandle) return;
66
- var timer = this;
67
76
  if (delay == null) {
68
77
  delay = this.interval;
69
78
  }
70
79
  this.timeoutHandle = setTimeout(() => {
71
- timer.timeoutHandle = null;
72
- timer.runHarvest(opts);
80
+ this.timeoutHandle = null;
81
+ this.runHarvest(opts);
73
82
  }, delay * 1000);
74
83
  }
75
84
  runHarvest(opts) {
76
85
  if (this.aborted) return;
77
- var scheduler = this;
86
+
87
+ /**
88
+ * This is executed immediately after harvest sends the data via XHR, or if there's nothing to send. Note that this excludes on unloading / sendBeacon.
89
+ * @param {Object} result
90
+ */
91
+ const cbRanAfterSend = result => {
92
+ if (opts?.forceNoRetry) result.retry = false; // discard unsent data rather than re-queuing for next harvest attempt
93
+ this.onHarvestFinished(opts, result);
94
+ };
78
95
  let harvests = [];
79
96
  let submitMethod;
97
+ let payload;
80
98
  if (this.opts.getPayload) {
81
- // Ajax & PVT & SR
82
- submitMethod = getSubmitMethod(this.endpoint, opts);
99
+ // Ajax & PVT & SR features provide a callback function to get data for harvesting
100
+ submitMethod = submitData.getSubmitMethod({
101
+ isFinalHarvest: opts?.unload
102
+ });
83
103
  if (!submitMethod) return false;
84
- const retry = submitMethod.method === submitData.xhr;
85
- var payload = this.opts.getPayload({
104
+ const retry = !opts?.unload && submitMethod === submitData.xhr;
105
+ payload = this.opts.getPayload({
86
106
  retry: retry
87
107
  });
88
108
  if (!payload) {
@@ -111,7 +131,7 @@ export class HarvestScheduler extends SharedContext {
111
131
  payload,
112
132
  opts,
113
133
  submitMethod,
114
- cbFinished: onHarvestFinished,
134
+ cbFinished: cbRanAfterSend,
115
135
  customUrl: this.opts.customUrl,
116
136
  raw: this.opts.raw
117
137
  });
@@ -120,16 +140,13 @@ export class HarvestScheduler extends SharedContext {
120
140
  this.scheduleHarvest();
121
141
  }
122
142
  return;
123
- function onHarvestFinished(result) {
124
- if (result.blocked) scheduler.onHarvestBlocked(opts, result);else scheduler.onHarvestFinished(opts, result);
125
- }
126
143
  }
127
144
  onHarvestFinished(opts, result) {
128
145
  if (this.opts.onFinished) {
129
146
  this.opts.onFinished(result);
130
147
  }
131
148
  if (result.sent && result.retry) {
132
- var delay = result.delay || this.opts.retryDelay;
149
+ const delay = result.delay || this.opts.retryDelay;
133
150
  // reschedule next harvest if should be delayed longer
134
151
  if (this.started && delay) {
135
152
  clearTimeout(this.timeoutHandle);
@@ -3,10 +3,9 @@
3
3
  * SPDX-License-Identifier: Apache-2.0
4
4
  */
5
5
 
6
- import { mapOwn } from '../util/map-own';
7
6
  import { obj as encodeObj, param as encodeParam } from '../url/encode';
8
7
  import { stringify } from '../util/stringify';
9
- import { submitData } from '../util/submit-data';
8
+ import * as submitData from '../util/submit-data';
10
9
  import { getLocation } from '../url/location';
11
10
  import { getInfo, getConfigurationValue, getRuntime } from '../config/config';
12
11
  import { cleanURL } from '../url/clean-url';
@@ -16,27 +15,16 @@ import { Obfuscator } from '../util/obfuscate';
16
15
  import { applyFnToProps } from '../util/traverse';
17
16
  import { SharedContext } from '../context/shared-context';
18
17
  import { VERSION } from "../constants/env.npm";
19
- import { isBrowserScope, isWorkerScope } from '../util/global-scope';
18
+ import { isWorkerScope, isIE } from '../constants/runtime';
20
19
 
21
20
  /**
22
- * @typedef {object} NetworkSendSpec
23
- * @param {string} endpoint The endpoint to use (jserrors, events, resources etc.)
24
- * @param {object} payload Object representing payload.
25
- * @param {object} payload.qs Map of values that should be sent as part of the request query string.
26
- * @param {string} payload.body String that should be sent as the body of the request.
27
- * @param {string} payload.body.e Special case of body used for browser interactions.
28
- * @param {object} opts Additional options for sending data
29
- * @param {boolean} opts.needResponse Specify whether the caller expects a response data.
30
- * @param {boolean} opts.unload Specify whether the call is a final harvest during page unload.
31
- * @param {boolean} opts.sendEmptyBody Specify whether the call should be made even if the body is empty. Useful for rum calls.
32
- * @param {function} submitMethod The submit method to use {@link ../util/submit-data}
33
- * @param {string} customUrl Override the beacon url the data is sent to; must include protocol if defined
34
- * @param {boolean} gzip Enabled gzip compression on the body of the request before it is sent
35
- * @param {boolean} includeBaseParams Enables the use of base query parameters in the beacon url {@see Harvest.baseQueryString}
21
+ * @typedef {import('./types.js').NetworkSendSpec} NetworkSendSpec
22
+ * @typedef {import('./types.js').HarvestEndpointIdentifier} HarvestEndpointIdentifier
23
+ * @typedef {import('./types.js').HarvestPayload} HarvestPayload
24
+ * @typedef {import('./types.js').FeatureHarvestCallback} FeatureHarvestCallback
25
+ * @typedef {import('./types.js').FeatureHarvestCallbackOptions} FeatureHarvestCallbackOptions
36
26
  */
37
27
 
38
- const haveSendBeacon = !!navigator.sendBeacon; // only the web window obj has sendBeacon at this time, so 'false' for other envs
39
-
40
28
  export class Harvest extends SharedContext {
41
29
  constructor(parent) {
42
30
  super(parent); // gets any allowed properties from the parent and stores them in `sharedContext`
@@ -50,20 +38,19 @@ export class Harvest extends SharedContext {
50
38
  /**
51
39
  * Initiate a harvest from multiple sources. An event that corresponds to the endpoint
52
40
  * name is emitted, which gives any listeners the opportunity to provide payload data.
41
+ * Note: Used by page_action
53
42
  * @param {NetworkSendSpec} spec Specification for sending data
54
43
  */
55
- sendX(spec) {
56
- const {
57
- endpoint,
58
- opts
59
- } = spec;
60
- var submitMethod = getSubmitMethod(endpoint, opts);
61
- if (!submitMethod) return false;
62
- var options = {
63
- retry: submitMethod.method === submitData.xhr
44
+ sendX() {
45
+ let spec = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
46
+ const submitMethod = submitData.getSubmitMethod({
47
+ isFinalHarvest: spec.opts?.unload
48
+ });
49
+ const options = {
50
+ retry: !spec.opts?.unload && submitMethod === submitData.xhr
64
51
  };
65
- const payload = this.createPayload(endpoint, options);
66
- var caller = this.obfuscator.shouldObfuscate() ? this.obfuscateAndSend.bind(this) : this._send.bind(this);
52
+ const payload = this.createPayload(spec.endpoint, options);
53
+ const caller = this.obfuscator.shouldObfuscate() ? this.obfuscateAndSend.bind(this) : this._send.bind(this);
67
54
  return caller({
68
55
  ...spec,
69
56
  payload,
@@ -75,31 +62,19 @@ export class Harvest extends SharedContext {
75
62
  * Initiate a harvest call.
76
63
  * @param {NetworkSendSpec} spec Specification for sending data
77
64
  */
78
- send(spec) {
79
- const {
80
- payload = {}
81
- } = spec;
82
- var makeBody = createAccumulator();
83
- var makeQueryString = createAccumulator();
84
- if (payload.body) mapOwn(payload.body, makeBody);
85
- if (payload.qs) mapOwn(payload.qs, makeQueryString);
86
- var newPayload = {
87
- body: makeBody(),
88
- qs: makeQueryString()
89
- };
90
- var caller = this.obfuscator.shouldObfuscate() ? this.obfuscateAndSend.bind(this) : this._send.bind(this);
91
- return caller({
92
- ...spec,
93
- payload: newPayload
94
- });
65
+ send() {
66
+ let spec = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
67
+ const caller = this.obfuscator.shouldObfuscate() ? this.obfuscateAndSend.bind(this) : this._send.bind(this);
68
+ return caller(spec);
95
69
  }
96
70
 
97
71
  /**
98
72
  * Apply obfuscation rules to the payload and then initial the harvest network call.
99
73
  * @param {NetworkSendSpec} spec Specification for sending data
100
74
  */
101
- obfuscateAndSend(spec) {
75
+ obfuscateAndSend() {
102
76
  var _this = this;
77
+ let spec = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
103
78
  const {
104
79
  payload = {}
105
80
  } = spec;
@@ -111,6 +86,14 @@ export class Harvest extends SharedContext {
111
86
  payload
112
87
  });
113
88
  }
89
+
90
+ /**
91
+ * Initiate a harvest call. Typically used by `sendX` and `send` methods or called directly
92
+ * for raw network calls.
93
+ * @param {NetworkSendSpec} param0 Specification for sending data
94
+ * @returns {boolean} True if the network call succeeded. For final harvest calls, the return
95
+ * value should not be relied upon because network calls will be made asynchronously.
96
+ */
114
97
  _send(_ref) {
115
98
  let {
116
99
  endpoint,
@@ -122,10 +105,14 @@ export class Harvest extends SharedContext {
122
105
  raw,
123
106
  includeBaseParams = true
124
107
  } = _ref;
125
- var info = getInfo(this.sharedContext.agentIdentifier);
108
+ const info = getInfo(this.sharedContext.agentIdentifier);
126
109
  if (!info.errorBeacon) return false;
127
- var agentRuntime = getRuntime(this.sharedContext.agentIdentifier);
128
- if (!payload.body && !opts?.sendEmptyBody) {
110
+ const agentRuntime = getRuntime(this.sharedContext.agentIdentifier);
111
+ let {
112
+ body,
113
+ qs
114
+ } = this.cleanPayload(payload);
115
+ if (Object.keys(body).length === 0 && !opts?.sendEmptyBody) {
129
116
  // no payload body? nothing to send, just run onfinish stuff and return
130
117
  if (cbFinished) {
131
118
  cbFinished({
@@ -134,27 +121,32 @@ export class Harvest extends SharedContext {
134
121
  }
135
122
  return false;
136
123
  }
137
- let url = '';
138
- if (customUrl) url = customUrl;else if (raw) url = "".concat(this.getScheme(), "://").concat(info.errorBeacon, "/").concat(endpoint);else url = "".concat(this.getScheme(), "://").concat(info.errorBeacon).concat(endpoint !== 'rum' ? "/".concat(endpoint) : '', "/1/").concat(info.licenseKey);
139
- var baseParams = !raw && includeBaseParams ? this.baseQueryString() : '';
140
- var payloadParams = payload.qs ? encodeObj(payload.qs, agentRuntime.maxBytes) : '';
124
+ let url = "".concat(this.getScheme(), "://").concat(info.errorBeacon).concat(endpoint !== 'rum' ? "/".concat(endpoint) : '', "/1/").concat(info.licenseKey);
125
+ if (customUrl) url = customUrl;
126
+ if (raw) url = "".concat(this.getScheme(), "://").concat(info.errorBeacon, "/").concat(endpoint);
127
+ const baseParams = !raw && includeBaseParams ? this.baseQueryString() : '';
128
+ let payloadParams = encodeObj(qs, agentRuntime.maxBytes);
141
129
  if (!submitMethod) {
142
- submitMethod = getSubmitMethod(endpoint, opts);
130
+ submitMethod = submitData.getSubmitMethod({
131
+ isFinalHarvest: opts.unload
132
+ });
133
+ }
134
+ if (baseParams === '' && payloadParams.startsWith('&')) {
135
+ payloadParams = payloadParams.substring(1);
143
136
  }
144
- var method = submitMethod.method;
145
- var useBody = submitMethod.useBody;
146
- var body;
147
- var fullUrl = "".concat(url, "?").concat(baseParams).concat(payloadParams);
148
- const gzip = payload?.qs?.content_encoding === 'gzip';
137
+ const fullUrl = "".concat(url, "?").concat(baseParams).concat(payloadParams);
138
+ const gzip = qs.content_encoding === 'gzip';
149
139
  if (!gzip) {
150
- if (useBody && endpoint === 'events') {
151
- body = payload.body.e;
152
- } else if (useBody) {
153
- body = stringify(payload.body);
140
+ if (endpoint === 'events') {
141
+ body = body.e;
154
142
  } else {
155
- fullUrl = fullUrl + encodeObj(payload.body, agentRuntime.maxBytes);
143
+ body = stringify(body);
156
144
  }
157
- } else body = payload.body;
145
+ }
146
+ if (!body || body.length === 0 || body === '{}' || body === '[]') {
147
+ // If body is null, undefined, or an empty object or array, send an empty string instead
148
+ body = '';
149
+ }
158
150
 
159
151
  // Get bytes harvested per endpoint as a supportability metric. See metrics aggregator (on unload).
160
152
  agentRuntime.bytesSent[endpoint] = (agentRuntime.bytesSent[endpoint] || 0) + body?.length || 0;
@@ -166,101 +158,141 @@ export class Harvest extends SharedContext {
166
158
  value: 'text/plain'
167
159
  });
168
160
 
169
- /* Since workers don't support sendBeacon right now, or Image(), they can only use XHR method.
161
+ /* Since workers don't support sendBeacon right now, they can only use XHR method.
170
162
  Because they still do permit synch XHR, the idea is that at final harvest time (worker is closing),
171
- we just make a BLOCKING request--trivial impact--with the remaining data as a temp fill-in for sendBeacon. */
172
-
173
- var result = method({
163
+ we just make a BLOCKING request--trivial impact--with the remaining data as a temp fill-in for sendBeacon.
164
+ Following the removal of img-element method, IE will also use sync XHR on page dismissal to ensure final analytics are sent. */
165
+ let result = submitMethod({
174
166
  url: fullUrl,
175
167
  body,
176
- sync: opts.unload && isWorkerScope,
168
+ sync: opts.unload && (isWorkerScope || isIE),
177
169
  headers
178
170
  });
179
- if (cbFinished && method === submitData.xhr) {
180
- var xhr = result;
181
- xhr.addEventListener('load', function () {
182
- var result = {
171
+ if (!opts.unload && cbFinished && submitMethod === submitData.xhr) {
172
+ const harvestScope = this;
173
+ result.addEventListener('load', function () {
174
+ // `this` refers to the XHR object in this scope, do not change this to a fat arrow
175
+ const cbResult = {
183
176
  sent: true,
184
177
  status: this.status
185
178
  };
186
179
  if (this.status === 429) {
187
- result.retry = true;
188
- result.delay = this.tooManyRequestsDelay;
180
+ cbResult.retry = true;
181
+ cbResult.delay = harvestScope.tooManyRequestsDelay;
189
182
  } else if (this.status === 408 || this.status === 500 || this.status === 503) {
190
- result.retry = true;
183
+ cbResult.retry = true;
191
184
  }
192
185
  if (opts.needResponse) {
193
- result.responseText = this.responseText;
186
+ cbResult.responseText = this.responseText;
194
187
  }
195
- cbFinished(result);
188
+ cbFinished(cbResult);
196
189
  }, eventListenerOpts(false));
197
190
  }
198
191
 
199
192
  // if beacon request failed, retry with an alternative method -- will not happen for workers
200
- if (!result && method === submitData.beacon) {
201
- method = submitData.img;
202
- result = method({
203
- url: fullUrl + encodeObj(payload.body, agentRuntime.maxBytes)
204
- });
193
+ if (!result && submitMethod === submitData.beacon) {
194
+ // browsers that support sendBeacon also support fetch with keepalive - IE will not retry unload calls
195
+ submitMethod = submitData.fetchKeepAlive;
196
+ try {
197
+ submitMethod({
198
+ url: fullUrl,
199
+ body,
200
+ headers
201
+ });
202
+ } catch (e) {
203
+ // Ignore error in final harvest
204
+ } finally {
205
+ result = true;
206
+ }
205
207
  }
206
208
  return result;
207
209
  }
208
210
 
209
211
  // The stuff that gets sent every time.
210
212
  baseQueryString() {
211
- var runtime = getRuntime(this.sharedContext.agentIdentifier);
212
- var info = getInfo(this.sharedContext.agentIdentifier);
213
- var location = cleanURL(getLocation());
214
- var ref = this.obfuscator.shouldObfuscate() ? this.obfuscator.obfuscateString(location) : location;
213
+ const runtime = getRuntime(this.sharedContext.agentIdentifier);
214
+ const info = getInfo(this.sharedContext.agentIdentifier);
215
+ const location = cleanURL(getLocation());
216
+ const ref = this.obfuscator.shouldObfuscate() ? this.obfuscator.obfuscateString(location) : location;
215
217
  return ['a=' + info.applicationID, encodeParam('sa', info.sa ? '' + info.sa : ''), encodeParam('v', VERSION), transactionNameParam(info), encodeParam('ct', runtime.customTransaction), '&rst=' + now(), '&ck=0',
216
218
  // ck param DEPRECATED - still expected by backend
217
219
  '&s=' + (runtime.session?.state.value || '0'),
218
220
  // the 0 id encaps all untrackable and default traffic
219
221
  encodeParam('ref', ref), encodeParam('ptid', runtime.ptid ? '' + runtime.ptid : '')].join('');
220
222
  }
221
- createPayload(type, options) {
222
- var makeBody = createAccumulator();
223
- var makeQueryString = createAccumulator();
224
- var listeners = this._events[type] && this._events[type] || [];
225
- for (var i = 0; i < listeners.length; i++) {
226
- var singlePayload = listeners[i](options);
227
- if (!singlePayload) continue;
228
- if (singlePayload.body) mapOwn(singlePayload.body, makeBody);
229
- if (singlePayload.qs) mapOwn(singlePayload.qs, makeQueryString);
223
+
224
+ /**
225
+ * Calls and accumulates data from registered harvesting functions based on
226
+ * the endpoint being harvested.
227
+ * @param {HarvestEndpointIdentifier} endpoint BAM endpoint identifier.
228
+ * @param {FeatureHarvestCallbackOptions} options Options to be passed to the
229
+ * feature harvest listener callback.
230
+ * @returns {HarvestPayload} Payload object to transmit to the bam endpoint.
231
+ */
232
+ createPayload(endpoint, options) {
233
+ const listeners = this._events[endpoint];
234
+ const payload = {
235
+ body: {},
236
+ qs: {}
237
+ };
238
+ if (Array.isArray(listeners) && listeners.length > 0) {
239
+ for (let i = 0; i < listeners.length; i++) {
240
+ const singlePayload = listeners[i](options);
241
+ if (singlePayload) {
242
+ payload.body = {
243
+ ...payload.body,
244
+ ...(singlePayload.body || {})
245
+ };
246
+ payload.qs = {
247
+ ...payload.qs,
248
+ ...(singlePayload.qs || {})
249
+ };
250
+ }
251
+ }
230
252
  }
253
+ return payload;
254
+ }
255
+
256
+ /**
257
+ * Cleans and returns a payload object containing a body and qs
258
+ * object with key/value pairs. KV pairs where the value is null,
259
+ * undefined, or an empty string are removed to save on transmission
260
+ * size.
261
+ * @param {HarvestPayload} payload Payload to be sent to the endpoint.
262
+ * @returns {HarvestPayload} Cleaned payload payload to be sent to the endpoint.
263
+ */
264
+ cleanPayload() {
265
+ let payload = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
266
+ const clean = input => {
267
+ if (typeof Uint8Array !== 'undefined' && input instanceof Uint8Array) {
268
+ return input.length > 0 ? input : null;
269
+ }
270
+ return Object.entries(input || {}).reduce((accumulator, _ref2) => {
271
+ let [key, value] = _ref2;
272
+ if (typeof value === 'number' || typeof value === 'string' && value.length > 0 || typeof value === 'object' && Object.keys(value || {}).length > 0) {
273
+ accumulator[key] = value;
274
+ }
275
+ return accumulator;
276
+ }, {});
277
+ };
231
278
  return {
232
- body: makeBody(),
233
- qs: makeQueryString()
279
+ body: clean(payload.body),
280
+ qs: clean(payload.qs)
234
281
  };
235
282
  }
236
- on(type, listener) {
237
- var listeners = this._events[type] || (this._events[type] = []);
238
- listeners.push(listener);
239
- }
240
- resetListeners() {
241
- mapOwn(this._events, key => {
242
- this._events[key] = [];
243
- });
244
- }
245
- }
246
- export function getSubmitMethod(endpoint, opts) {
247
- opts = opts || {};
248
- var method;
249
- var useBody;
250
- if (opts.unload && isBrowserScope) {
251
- // all the features' final harvest; neither methods work outside window context
252
- useBody = haveSendBeacon;
253
- method = haveSendBeacon ? submitData.beacon : submitData.img; // really only IE doesn't have Beacon API for web browsers
254
- } else {
255
- // `submitData.beacon` was removed, there is an upper limit to the
256
- // number of data allowed before it starts failing, so we save it only for page unloading
257
- useBody = true;
258
- method = submitData.xhr;
283
+
284
+ /**
285
+ * Registers a function to be called when harvesting is triggered for a specific
286
+ * endpoint.
287
+ * @param {HarvestEndpointIdentifier} endpoint
288
+ * @param {FeatureHarvestCallback} listener
289
+ */
290
+ on(endpoint, listener) {
291
+ if (!Array.isArray(this._events[endpoint])) {
292
+ this._events[endpoint] = [];
293
+ }
294
+ this._events[endpoint].push(listener);
259
295
  }
260
- return {
261
- method: method,
262
- useBody: useBody
263
- };
264
296
  }
265
297
 
266
298
  // Constructs the transaction name param for the beacon URL.
@@ -269,18 +301,4 @@ export function getSubmitMethod(endpoint, opts) {
269
301
  function transactionNameParam(info) {
270
302
  if (info.transactionName) return encodeParam('to', info.transactionName);
271
303
  return encodeParam('t', info.tNamePlain || 'Unnamed Transaction');
272
- }
273
-
274
- // returns a function that can be called to accumulate values to a single object
275
- // when the function is called without parameters, then the accumulator is returned
276
- function createAccumulator() {
277
- var accumulator = {};
278
- var hasData = false;
279
- return function (key, val) {
280
- if (val !== null && val !== undefined && val.toString()?.length) {
281
- accumulator[key] = val;
282
- hasData = true;
283
- }
284
- if (hasData) return accumulator;
285
- };
286
304
  }
@@ -0,0 +1,47 @@
1
+ /**
2
+ * @file Contains types related to harvesting data.
3
+ * @copyright 2023 New Relic Corporation. All rights reserved.
4
+ * @license Apache-2.0
5
+ */
6
+
7
+ /**
8
+ * @typedef {'rum'|'jserrors'|'events'|'ins'|'resources'|'blob'} HarvestEndpointIdentifier
9
+ */
10
+
11
+ /**
12
+ * @typedef {object} HarvestPayload
13
+ * @property {object} qs Map of values that should be sent as part of the request query string.
14
+ * @property {object} body Map of values that should be sent as the body of the request.
15
+ * @property {string} body.e Special case of body used for browser interactions.
16
+ */
17
+
18
+ /**
19
+ * @typedef {object} FeatureHarvestCallbackOptions Options for aggregating data for harvesting.
20
+ * @property {boolean} options.retry Indicates if the feature should store the aggregated
21
+ * data in anticipation of a possible need to retry the transmission.
22
+ */
23
+
24
+ /**
25
+ * @callback FeatureHarvestCallback
26
+ * @param {FeatureHarvestCallbackOptions} options Options for aggregating data for harvesting.
27
+ * @returns {HarvestPayload} Payload of data to transmit to bam endpoint.
28
+ */
29
+
30
+ /**
31
+ * @typedef {object} NetworkSendSpec
32
+ * @property {HarvestEndpointIdentifier} endpoint The endpoint to use (jserrors, events, resources etc.)
33
+ * @property {HarvestPayload} payload Object representing payload.
34
+ * @property {object} opts Additional options for sending data
35
+ * @property {boolean} opts.needResponse Specify whether the caller expects a response data.
36
+ * @property {boolean} opts.unload Specify whether the call is a final harvest during page unload.
37
+ * @property {boolean} opts.sendEmptyBody Specify whether the call should be made even if the body is empty. Useful for rum calls.
38
+ * @property {boolean} opts.retry Indicates if the feature should store the aggregated data in anticipation of a possible need to
39
+ * retry the transmission.
40
+ * @property {import('../util/submit-data.js').NetworkMethods} submitMethod The network method to use {@link ../util/submit-data.js}
41
+ * @property {string} customUrl Override the beacon url the data is sent to; must include protocol if defined
42
+ * @property {boolean} raw If true, disables adding the license key to the url
43
+ * @property {boolean} includeBaseParams Enables the use of base query parameters in the beacon url
44
+ */
45
+
46
+ /* istanbul ignore next */
47
+ export const unused = {};
@@ -4,7 +4,7 @@
4
4
  */
5
5
 
6
6
  import { getOrSet } from '../util/get-or-set';
7
- import { globalScope } from '../util/global-scope';
7
+ import { globalScope } from '../constants/runtime';
8
8
 
9
9
  // Start assigning ids at 1 so 0 can always be used for Window or WorkerGlobalScope, without
10
10
  // actually setting it (which would create a global variable).
@@ -3,7 +3,7 @@
3
3
  * SPDX-License-Identifier: Apache-2.0
4
4
  */
5
5
 
6
- import { globalScope } from '../util/global-scope';
6
+ import { globalScope } from '../constants/runtime';
7
7
  const uuidv4Template = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx';
8
8
 
9
9
  /**