@newrelic/browser-agent 1.235.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 (332) hide show
  1. package/README.md +41 -1
  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/event-listener/event-listener-opts.js +3 -3
  8. package/dist/cjs/common/harvest/harvest-scheduler.js +22 -19
  9. package/dist/cjs/common/harvest/harvest.js +163 -144
  10. package/dist/cjs/common/harvest/types.js +54 -0
  11. package/dist/cjs/common/ids/id.js +2 -2
  12. package/dist/cjs/common/ids/unique-id.js +3 -3
  13. package/dist/cjs/common/session/session-entity.js +2 -2
  14. package/dist/cjs/common/timer/interaction-timer.js +2 -2
  15. package/dist/cjs/common/unload/eol.js +10 -11
  16. package/dist/cjs/common/url/canonicalize-url.js +2 -2
  17. package/dist/cjs/common/url/parse-url.js +3 -3
  18. package/dist/cjs/common/url/protocol.js +2 -2
  19. package/dist/cjs/common/util/submit-data.js +58 -76
  20. package/dist/cjs/common/window/nreum.js +14 -14
  21. package/dist/cjs/common/wrap/wrap-events.js +3 -3
  22. package/dist/cjs/common/wrap/wrap-fetch.js +5 -5
  23. package/dist/cjs/common/wrap/wrap-history.js +2 -2
  24. package/dist/cjs/common/wrap/wrap-jsonp.js +2 -2
  25. package/dist/cjs/common/wrap/wrap-mutation.js +2 -2
  26. package/dist/cjs/common/wrap/wrap-promise.js +2 -2
  27. package/dist/cjs/common/wrap/wrap-raf.js +2 -2
  28. package/dist/cjs/common/wrap/wrap-timer.js +4 -4
  29. package/dist/cjs/common/wrap/wrap-xhr.js +3 -3
  30. package/dist/cjs/features/ajax/aggregate/index.js +1 -1
  31. package/dist/cjs/features/ajax/instrument/distributed-tracing.js +2 -2
  32. package/dist/cjs/features/ajax/instrument/index.js +6 -7
  33. package/dist/cjs/features/jserrors/aggregate/index.js +7 -4
  34. package/dist/cjs/features/jserrors/instrument/index.js +4 -4
  35. package/dist/cjs/features/metrics/aggregate/framework-detection.js +2 -2
  36. package/dist/cjs/features/metrics/aggregate/index.js +3 -3
  37. package/dist/cjs/features/page_action/aggregate/index.js +3 -3
  38. package/dist/cjs/features/page_view_event/aggregate/index.js +10 -11
  39. package/dist/cjs/features/page_view_event/instrument/index.js +2 -2
  40. package/dist/cjs/features/page_view_timing/aggregate/index.js +3 -5
  41. package/dist/cjs/features/page_view_timing/instrument/index.js +2 -2
  42. package/dist/cjs/features/session_replay/replay-mode.js +2 -2
  43. package/dist/cjs/features/session_trace/instrument/index.js +2 -2
  44. package/dist/cjs/features/spa/aggregate/index.js +1 -1
  45. package/dist/cjs/features/spa/instrument/index.js +2 -2
  46. package/dist/cjs/features/utils/instrument-base.js +6 -7
  47. package/dist/cjs/index.js +7 -0
  48. package/dist/cjs/loaders/agent.js +7 -0
  49. package/dist/cjs/loaders/api/api.js +2 -2
  50. package/dist/cjs/loaders/api/apiAsync.js +6 -4
  51. package/dist/cjs/loaders/configure/configure.js +2 -2
  52. package/dist/cjs/loaders/micro-agent.js +29 -38
  53. package/dist/esm/common/config/state/init.js +3 -0
  54. package/dist/esm/common/config/state/runtime.js +1 -1
  55. package/dist/esm/common/constants/env.cdn.js +2 -2
  56. package/dist/esm/common/constants/env.npm.js +1 -1
  57. package/dist/esm/common/constants/runtime.js +38 -0
  58. package/dist/esm/common/event-listener/event-listener-opts.js +1 -1
  59. package/dist/esm/common/harvest/harvest-scheduler.js +21 -20
  60. package/dist/esm/common/harvest/harvest.js +160 -142
  61. package/dist/esm/common/harvest/types.js +47 -0
  62. package/dist/esm/common/ids/id.js +1 -1
  63. package/dist/esm/common/ids/unique-id.js +1 -1
  64. package/dist/esm/common/session/session-entity.js +1 -1
  65. package/dist/esm/common/timer/interaction-timer.js +1 -1
  66. package/dist/esm/common/unload/eol.js +1 -2
  67. package/dist/esm/common/url/canonicalize-url.js +1 -1
  68. package/dist/esm/common/url/parse-url.js +1 -1
  69. package/dist/esm/common/url/protocol.js +1 -1
  70. package/dist/esm/common/util/submit-data.js +55 -73
  71. package/dist/esm/common/window/nreum.js +1 -1
  72. package/dist/esm/common/wrap/wrap-events.js +1 -1
  73. package/dist/esm/common/wrap/wrap-fetch.js +1 -1
  74. package/dist/esm/common/wrap/wrap-history.js +1 -1
  75. package/dist/esm/common/wrap/wrap-jsonp.js +1 -1
  76. package/dist/esm/common/wrap/wrap-mutation.js +1 -1
  77. package/dist/esm/common/wrap/wrap-promise.js +1 -1
  78. package/dist/esm/common/wrap/wrap-raf.js +1 -1
  79. package/dist/esm/common/wrap/wrap-timer.js +1 -1
  80. package/dist/esm/common/wrap/wrap-xhr.js +1 -1
  81. package/dist/esm/features/ajax/aggregate/index.js +1 -1
  82. package/dist/esm/features/ajax/instrument/distributed-tracing.js +1 -1
  83. package/dist/esm/features/ajax/instrument/index.js +1 -2
  84. package/dist/esm/features/jserrors/aggregate/index.js +6 -3
  85. package/dist/esm/features/jserrors/instrument/index.js +1 -1
  86. package/dist/esm/features/metrics/aggregate/framework-detection.js +1 -1
  87. package/dist/esm/features/metrics/aggregate/index.js +1 -1
  88. package/dist/esm/features/page_action/aggregate/index.js +1 -1
  89. package/dist/esm/features/page_view_event/aggregate/index.js +1 -2
  90. package/dist/esm/features/page_view_event/instrument/index.js +1 -1
  91. package/dist/esm/features/page_view_timing/aggregate/index.js +2 -4
  92. package/dist/esm/features/page_view_timing/instrument/index.js +1 -1
  93. package/dist/esm/features/session_replay/replay-mode.js +2 -2
  94. package/dist/esm/features/session_trace/instrument/index.js +1 -1
  95. package/dist/esm/features/spa/aggregate/index.js +1 -1
  96. package/dist/esm/features/spa/instrument/index.js +1 -1
  97. package/dist/esm/features/utils/instrument-base.js +4 -5
  98. package/dist/esm/index.js +1 -4
  99. package/dist/esm/loaders/agent.js +7 -0
  100. package/dist/esm/loaders/api/api.js +1 -1
  101. package/dist/esm/loaders/api/apiAsync.js +3 -3
  102. package/dist/esm/loaders/configure/configure.js +1 -1
  103. package/dist/esm/loaders/micro-agent.js +29 -38
  104. package/dist/types/common/config/state/init.d.ts.map +1 -1
  105. package/dist/types/common/constants/runtime.d.ts +29 -0
  106. package/dist/types/common/constants/runtime.d.ts.map +1 -0
  107. package/dist/types/common/harvest/harvest-scheduler.d.ts +1 -1
  108. package/dist/types/common/harvest/harvest-scheduler.d.ts.map +1 -1
  109. package/dist/types/common/harvest/harvest.d.ts +49 -38
  110. package/dist/types/common/harvest/harvest.d.ts.map +1 -1
  111. package/dist/types/common/harvest/types.d.ts +100 -0
  112. package/dist/types/common/harvest/types.d.ts.map +1 -0
  113. package/dist/types/common/unload/eol.d.ts.map +1 -1
  114. package/dist/types/common/util/submit-data.d.ts +62 -64
  115. package/dist/types/common/util/submit-data.d.ts.map +1 -1
  116. package/dist/types/features/ajax/instrument/index.d.ts.map +1 -1
  117. package/dist/types/features/jserrors/aggregate/index.d.ts +1 -1
  118. package/dist/types/features/jserrors/aggregate/index.d.ts.map +1 -1
  119. package/dist/types/features/jserrors/instrument/index.d.ts +1 -1
  120. package/dist/types/features/jserrors/instrument/index.d.ts.map +1 -1
  121. package/dist/types/features/page_view_event/aggregate/index.d.ts.map +1 -1
  122. package/dist/types/features/page_view_timing/aggregate/index.d.ts.map +1 -1
  123. package/dist/types/index.d.ts +1 -0
  124. package/dist/types/loaders/agent.d.ts +4 -4
  125. package/dist/types/loaders/agent.d.ts.map +1 -1
  126. package/dist/types/loaders/micro-agent.d.ts +3 -4
  127. package/dist/types/loaders/micro-agent.d.ts.map +1 -1
  128. package/package.json +6 -1
  129. package/src/common/config/__mocks__/config.js +11 -0
  130. package/src/common/config/state/init.js +1 -0
  131. package/src/common/config/state/runtime.js +1 -1
  132. package/src/common/constants/__mocks__/env.js +3 -0
  133. package/src/common/constants/__mocks__/runtime.js +8 -0
  134. package/src/common/constants/env.cdn.test.js +7 -0
  135. package/src/common/constants/env.npm.test.js +7 -0
  136. package/src/common/constants/env.test.js +7 -0
  137. package/src/common/constants/runtime.js +71 -0
  138. package/src/common/constants/runtime.test.js +168 -0
  139. package/src/common/context/__mocks__/shared-context.js +8 -0
  140. package/src/common/event-listener/__mocks__/event-listener-opts.js +7 -0
  141. package/src/common/event-listener/event-listener-opts.js +1 -1
  142. package/src/common/harvest/__mocks__/harvest.js +13 -0
  143. package/src/common/harvest/harvest-scheduler.js +21 -20
  144. package/src/common/harvest/harvest-scheduler.test.js +496 -0
  145. package/src/common/harvest/harvest.js +147 -130
  146. package/src/common/harvest/harvest.test.js +818 -0
  147. package/src/common/harvest/types.js +47 -0
  148. package/src/common/ids/id.js +1 -1
  149. package/src/common/ids/unique-id.js +1 -1
  150. package/src/common/session/__mocks__/session-entity.js +25 -0
  151. package/src/common/session/session-entity.component-test.js +1 -1
  152. package/src/common/session/session-entity.js +1 -1
  153. package/src/common/timer/interaction-timer.js +1 -1
  154. package/src/common/timing/__mocks__/now.js +1 -0
  155. package/src/common/unload/__mocks__/eol.js +1 -0
  156. package/src/common/unload/eol.js +1 -2
  157. package/src/common/url/__mocks__/clean-url.js +1 -0
  158. package/src/common/url/__mocks__/encode.js +7 -0
  159. package/src/common/url/__mocks__/location.js +1 -0
  160. package/src/common/url/canonicalize-url.js +1 -1
  161. package/src/common/url/canonicalize-url.test.js +2 -2
  162. package/src/common/url/parse-url.js +1 -1
  163. package/src/common/url/parse-url.test.js +3 -3
  164. package/src/common/url/protocol.js +1 -1
  165. package/src/common/util/__mocks__/obfuscate.js +10 -0
  166. package/src/common/util/__mocks__/stringify.js +1 -0
  167. package/src/common/util/__mocks__/submit-data.js +6 -0
  168. package/src/common/util/__mocks__/traverse.js +1 -0
  169. package/src/common/util/submit-data.js +39 -53
  170. package/src/common/util/submit-data.test.js +81 -68
  171. package/src/common/window/nreum.js +1 -1
  172. package/src/common/wrap/wrap-events.js +1 -1
  173. package/src/common/wrap/wrap-fetch.js +1 -1
  174. package/src/common/wrap/wrap-history.js +1 -1
  175. package/src/common/wrap/wrap-jsonp.js +1 -1
  176. package/src/common/wrap/wrap-mutation.js +1 -1
  177. package/src/common/wrap/wrap-promise.js +1 -1
  178. package/src/common/wrap/wrap-promise.test.js +2 -2
  179. package/src/common/wrap/wrap-raf.js +1 -1
  180. package/src/common/wrap/wrap-timer.js +1 -1
  181. package/src/common/wrap/wrap-xhr.js +1 -1
  182. package/src/features/ajax/aggregate/index.js +1 -1
  183. package/src/features/ajax/instrument/distributed-tracing.js +1 -1
  184. package/src/features/ajax/instrument/index.js +1 -2
  185. package/src/features/jserrors/aggregate/compute-stack-trace.test.js +1 -1
  186. package/src/features/jserrors/aggregate/index.js +7 -3
  187. package/src/features/jserrors/instrument/index.js +1 -1
  188. package/src/features/metrics/aggregate/framework-detection.js +1 -1
  189. package/src/features/metrics/aggregate/framework-detection.test.js +2 -2
  190. package/src/features/metrics/aggregate/index.js +1 -1
  191. package/src/features/page_action/aggregate/index.js +1 -1
  192. package/src/features/page_view_event/aggregate/index.js +1 -2
  193. package/src/features/page_view_event/instrument/index.js +1 -1
  194. package/src/features/page_view_timing/aggregate/index.js +2 -4
  195. package/src/features/page_view_timing/instrument/index.js +1 -1
  196. package/src/features/session_replay/replay-mode.js +2 -2
  197. package/src/features/session_trace/instrument/index.js +1 -1
  198. package/src/features/spa/aggregate/index.js +1 -1
  199. package/src/features/spa/instrument/index.js +1 -1
  200. package/src/features/utils/agent-session.test.js +2 -2
  201. package/src/features/utils/instrument-base.js +5 -5
  202. package/src/features/utils/instrument-base.test.js +22 -3
  203. package/src/index.js +1 -3
  204. package/src/loaders/agent.js +8 -0
  205. package/src/loaders/api/api.js +1 -1
  206. package/src/loaders/api/apiAsync.js +3 -3
  207. package/src/loaders/configure/configure.js +1 -1
  208. package/src/loaders/micro-agent.js +26 -30
  209. package/dist/cjs/common/browser-version/firefox-version.js +0 -17
  210. package/dist/cjs/common/browser-version/ios-version.js +0 -19
  211. package/dist/cjs/common/event-emitter/contextual-ee.test.js +0 -282
  212. package/dist/cjs/common/event-emitter/handle.test.js +0 -58
  213. package/dist/cjs/common/event-emitter/register-handler.test.js +0 -55
  214. package/dist/cjs/common/harvest/harvest-scheduler.component-test.js +0 -39
  215. package/dist/cjs/common/harvest/harvest.component-test.js +0 -224
  216. package/dist/cjs/common/ids/id.test.js +0 -85
  217. package/dist/cjs/common/ids/unique-id.test.js +0 -49
  218. package/dist/cjs/common/session/session-entity.component-test.js +0 -497
  219. package/dist/cjs/common/storage/local-storage.test.js +0 -14
  220. package/dist/cjs/common/timer/interaction-timer.component-test.js +0 -216
  221. package/dist/cjs/common/timer/timer.test.js +0 -105
  222. package/dist/cjs/common/timing/nav-timing.test.js +0 -192
  223. package/dist/cjs/common/url/canonicalize-url.test.js +0 -38
  224. package/dist/cjs/common/url/clean-url.test.js +0 -9
  225. package/dist/cjs/common/url/encode.component-test.js +0 -74
  226. package/dist/cjs/common/url/location.test.js +0 -13
  227. package/dist/cjs/common/url/parse-url.test.js +0 -111
  228. package/dist/cjs/common/url/protocol.component-test.js +0 -15
  229. package/dist/cjs/common/util/console.test.js +0 -30
  230. package/dist/cjs/common/util/data-size.test.js +0 -64
  231. package/dist/cjs/common/util/feature-flags.test.js +0 -84
  232. package/dist/cjs/common/util/get-or-set.test.js +0 -47
  233. package/dist/cjs/common/util/global-scope.js +0 -27
  234. package/dist/cjs/common/util/global-scope.test.js +0 -72
  235. package/dist/cjs/common/util/invoke.test.js +0 -49
  236. package/dist/cjs/common/util/map-own.test.js +0 -49
  237. package/dist/cjs/common/util/obfuscate.component-test.js +0 -129
  238. package/dist/cjs/common/util/stringify.test.js +0 -48
  239. package/dist/cjs/common/util/submit-data.test.js +0 -245
  240. package/dist/cjs/common/util/traverse.test.js +0 -44
  241. package/dist/cjs/common/wrap/wrap-promise.test.js +0 -119
  242. package/dist/cjs/features/jserrors/aggregate/canonical-function-name.test.js +0 -31
  243. package/dist/cjs/features/jserrors/aggregate/compute-stack-trace.test.js +0 -383
  244. package/dist/cjs/features/jserrors/aggregate/format-stack-trace.test.js +0 -40
  245. package/dist/cjs/features/jserrors/aggregate/string-hash-code.test.js +0 -27
  246. package/dist/cjs/features/metrics/aggregate/framework-detection.test.js +0 -137
  247. package/dist/cjs/features/metrics/aggregate/polyfill-detection.es5.test.js +0 -17
  248. package/dist/cjs/features/metrics/aggregate/polyfill-detection.test.js +0 -165
  249. package/dist/cjs/features/session_replay/aggregate/index.component-test.js +0 -457
  250. package/dist/cjs/features/spa/aggregate/interaction-node.test.js +0 -16
  251. package/dist/cjs/features/utils/agent-session.test.js +0 -211
  252. package/dist/cjs/features/utils/aggregate-base.test.js +0 -110
  253. package/dist/cjs/features/utils/feature-base.test.js +0 -42
  254. package/dist/cjs/features/utils/handler-cache.test.js +0 -53
  255. package/dist/cjs/features/utils/instrument-base.test.js +0 -179
  256. package/dist/cjs/features/utils/lazy-feature-loader.test.js +0 -30
  257. package/dist/esm/common/browser-version/firefox-version.js +0 -10
  258. package/dist/esm/common/browser-version/ios-version.js +0 -11
  259. package/dist/esm/common/event-emitter/contextual-ee.test.js +0 -278
  260. package/dist/esm/common/event-emitter/handle.test.js +0 -54
  261. package/dist/esm/common/event-emitter/register-handler.test.js +0 -51
  262. package/dist/esm/common/harvest/harvest-scheduler.component-test.js +0 -37
  263. package/dist/esm/common/harvest/harvest.component-test.js +0 -222
  264. package/dist/esm/common/ids/id.test.js +0 -81
  265. package/dist/esm/common/ids/unique-id.test.js +0 -44
  266. package/dist/esm/common/session/session-entity.component-test.js +0 -495
  267. package/dist/esm/common/storage/local-storage.test.js +0 -12
  268. package/dist/esm/common/timer/interaction-timer.component-test.js +0 -214
  269. package/dist/esm/common/timer/timer.test.js +0 -103
  270. package/dist/esm/common/timing/nav-timing.test.js +0 -190
  271. package/dist/esm/common/url/canonicalize-url.test.js +0 -34
  272. package/dist/esm/common/url/clean-url.test.js +0 -7
  273. package/dist/esm/common/url/encode.component-test.js +0 -70
  274. package/dist/esm/common/url/location.test.js +0 -11
  275. package/dist/esm/common/url/parse-url.test.js +0 -107
  276. package/dist/esm/common/url/protocol.component-test.js +0 -13
  277. package/dist/esm/common/util/console.test.js +0 -28
  278. package/dist/esm/common/util/data-size.test.js +0 -60
  279. package/dist/esm/common/util/feature-flags.test.js +0 -80
  280. package/dist/esm/common/util/get-or-set.test.js +0 -45
  281. package/dist/esm/common/util/global-scope.js +0 -17
  282. package/dist/esm/common/util/global-scope.test.js +0 -70
  283. package/dist/esm/common/util/invoke.test.js +0 -47
  284. package/dist/esm/common/util/map-own.test.js +0 -47
  285. package/dist/esm/common/util/obfuscate.component-test.js +0 -125
  286. package/dist/esm/common/util/stringify.test.js +0 -46
  287. package/dist/esm/common/util/submit-data.test.js +0 -241
  288. package/dist/esm/common/util/traverse.test.js +0 -42
  289. package/dist/esm/common/wrap/wrap-promise.test.js +0 -115
  290. package/dist/esm/features/jserrors/aggregate/canonical-function-name.test.js +0 -29
  291. package/dist/esm/features/jserrors/aggregate/compute-stack-trace.test.js +0 -379
  292. package/dist/esm/features/jserrors/aggregate/format-stack-trace.test.js +0 -38
  293. package/dist/esm/features/jserrors/aggregate/string-hash-code.test.js +0 -25
  294. package/dist/esm/features/metrics/aggregate/framework-detection.test.js +0 -133
  295. package/dist/esm/features/metrics/aggregate/polyfill-detection.es5.test.js +0 -15
  296. package/dist/esm/features/metrics/aggregate/polyfill-detection.test.js +0 -163
  297. package/dist/esm/features/session_replay/aggregate/index.component-test.js +0 -453
  298. package/dist/esm/features/spa/aggregate/interaction-node.test.js +0 -14
  299. package/dist/esm/features/utils/agent-session.test.js +0 -207
  300. package/dist/esm/features/utils/aggregate-base.test.js +0 -108
  301. package/dist/esm/features/utils/feature-base.test.js +0 -40
  302. package/dist/esm/features/utils/handler-cache.test.js +0 -51
  303. package/dist/esm/features/utils/instrument-base.test.js +0 -175
  304. package/dist/esm/features/utils/lazy-feature-loader.test.js +0 -29
  305. package/dist/types/common/browser-version/firefox-version.d.ts +0 -2
  306. package/dist/types/common/browser-version/firefox-version.d.ts.map +0 -1
  307. package/dist/types/common/browser-version/ios-version.d.ts +0 -3
  308. package/dist/types/common/browser-version/ios-version.d.ts.map +0 -1
  309. package/dist/types/common/harvest/harvest-scheduler.component-test.d.ts +0 -2
  310. package/dist/types/common/harvest/harvest-scheduler.component-test.d.ts.map +0 -1
  311. package/dist/types/common/harvest/harvest.component-test.d.ts +0 -2
  312. package/dist/types/common/harvest/harvest.component-test.d.ts.map +0 -1
  313. package/dist/types/common/session/session-entity.component-test.d.ts +0 -2
  314. package/dist/types/common/session/session-entity.component-test.d.ts.map +0 -1
  315. package/dist/types/common/timer/interaction-timer.component-test.d.ts +0 -2
  316. package/dist/types/common/timer/interaction-timer.component-test.d.ts.map +0 -1
  317. package/dist/types/common/url/encode.component-test.d.ts +0 -2
  318. package/dist/types/common/url/encode.component-test.d.ts.map +0 -1
  319. package/dist/types/common/url/protocol.component-test.d.ts +0 -2
  320. package/dist/types/common/url/protocol.component-test.d.ts.map +0 -1
  321. package/dist/types/common/util/global-scope.d.ts +0 -5
  322. package/dist/types/common/util/global-scope.d.ts.map +0 -1
  323. package/dist/types/common/util/obfuscate.component-test.d.ts +0 -2
  324. package/dist/types/common/util/obfuscate.component-test.d.ts.map +0 -1
  325. package/dist/types/features/session_replay/aggregate/index.component-test.d.ts +0 -2
  326. package/dist/types/features/session_replay/aggregate/index.component-test.d.ts.map +0 -1
  327. package/src/common/browser-version/firefox-version.js +0 -10
  328. package/src/common/browser-version/ios-version.js +0 -11
  329. package/src/common/harvest/harvest-scheduler.component-test.js +0 -25
  330. package/src/common/harvest/harvest.component-test.js +0 -169
  331. package/src/common/util/global-scope.js +0 -23
  332. package/src/common/util/global-scope.test.js +0 -87
@@ -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
 
8
8
  const uuidv4Template = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'
9
9
 
@@ -0,0 +1,25 @@
1
+ export const SESSION_EVENTS = {
2
+ PAUSE: 'session-pause',
3
+ RESET: 'session-reset',
4
+ RESUME: 'session-resume'
5
+ }
6
+
7
+ export const SessionEntity = jest.fn(function () {
8
+ this.setup = jest.fn()
9
+ this.sync = jest.fn()
10
+ this.read = jest.fn()
11
+ this.write = jest.fn()
12
+ this.reset = jest.fn()
13
+ this.refresh = jest.fn()
14
+ this.isExpired = jest.fn(() => false)
15
+ this.isInvalid = jest.fn(() => false)
16
+ this.collectSM = jest.fn()
17
+ this.getFutureTimestamp = jest.fn()
18
+ this.syncCustomAttribute = jest.fn()
19
+
20
+ Object.defineProperty(this, 'lookupKey', {
21
+ configurable: true,
22
+ enumerable: true,
23
+ get: jest.fn()
24
+ })
25
+ })
@@ -40,7 +40,7 @@ jest.mock('../timer/interaction-timer')
40
40
  jest.useFakeTimers()
41
41
 
42
42
  const mockBrowserScope = jest.fn().mockImplementation(() => true)
43
- jest.mock('../util/global-scope', () => ({
43
+ jest.mock('../constants/runtime', () => ({
44
44
  __esModule: true,
45
45
  get isBrowserScope () {
46
46
  return mockBrowserScope()
@@ -3,7 +3,7 @@ import { warn } from '../util/console'
3
3
  import { stringify } from '../util/stringify'
4
4
  import { ee } from '../event-emitter/contextual-ee'
5
5
  import { Timer } from '../timer/timer'
6
- import { isBrowserScope } from '../util/global-scope'
6
+ import { isBrowserScope } from '../constants/runtime'
7
7
  import { DEFAULT_EXPIRES_MS, DEFAULT_INACTIVE_MS, PREFIX } from './constants'
8
8
  import { InteractionTimer } from '../timer/interaction-timer'
9
9
  import { wrapEvents } from '../wrap'
@@ -1,7 +1,7 @@
1
1
  import { Timer } from './timer'
2
2
  import { subscribeToVisibilityChange } from '../window/page-visibility'
3
3
  import { debounce } from '../util/invoke'
4
- import { isBrowserScope } from '../util/global-scope'
4
+ import { isBrowserScope } from '../constants/runtime'
5
5
 
6
6
  export class InteractionTimer extends Timer {
7
7
  constructor (opts, ms) {
@@ -0,0 +1 @@
1
+ export const now = jest.fn(() => performance.now())
@@ -0,0 +1 @@
1
+ export const subscribeToEOL = jest.fn()
@@ -2,10 +2,9 @@
2
2
  * Copyright 2020 New Relic Corporation. All rights reserved.
3
3
  * SPDX-License-Identifier: Apache-2.0
4
4
  */
5
- import { ffVersion } from '../browser-version/firefox-version'
6
5
  import { windowAddEventListener } from '../event-listener/event-listener-opts'
7
6
  import { single } from '../util/invoke'
8
- import { globalScope, isWorkerScope, isBrowserScope } from '../util/global-scope'
7
+ import { ffVersion, globalScope, isWorkerScope, isBrowserScope } from '../constants/runtime'
9
8
  import { subscribeToVisibilityChange } from '../window/page-visibility'
10
9
 
11
10
  if (isWorkerScope) {
@@ -0,0 +1 @@
1
+ export const cleanURL = jest.fn((input) => input)
@@ -0,0 +1,7 @@
1
+ export const qs = jest.fn((input) => encodeURIComponent(input))
2
+ export const fromArray = jest.fn((input) => input.join(''))
3
+ export const obj = jest.fn((input) => Object.entries(input)
4
+ .map(([key, value]) => `${key}=${encodeURIComponent(value)}`)
5
+ .join('&')
6
+ )
7
+ export const param = jest.fn((name, value) => `&${name}=${encodeURIComponent(value)}`)
@@ -0,0 +1 @@
1
+ export const getLocation = jest.fn(() => location)
@@ -3,7 +3,7 @@
3
3
  * SPDX-License-Identifier: Apache-2.0
4
4
  */
5
5
 
6
- import { initialLocation } from '../util/global-scope'
6
+ import { initialLocation } from '../constants/runtime'
7
7
  import { cleanURL } from './clean-url'
8
8
 
9
9
  /**
@@ -1,9 +1,9 @@
1
1
  import { faker } from '@faker-js/faker'
2
- import * as globalScopeModule from '../util/global-scope'
2
+ import * as globalScopeModule from '../constants/runtime'
3
3
  import * as cleanUrlModule from './clean-url'
4
4
  import { canonicalizeUrl } from './canonicalize-url'
5
5
 
6
- jest.mock('../util/global-scope')
6
+ jest.mock('../constants/runtime')
7
7
  jest.mock('./clean-url')
8
8
 
9
9
  beforeEach(() => {
@@ -3,7 +3,7 @@
3
3
  * SPDX-License-Identifier: Apache-2.0
4
4
  */
5
5
 
6
- import { globalScope, isBrowserScope } from '../util/global-scope'
6
+ import { globalScope, isBrowserScope } from '../constants/runtime'
7
7
 
8
8
  var stringsToParsedUrls = {}
9
9
 
@@ -63,7 +63,7 @@ const urlTests = [
63
63
  ]
64
64
 
65
65
  test.each(urlTests)('verify url parsing inside browser scope', async ({ input, expected }) => {
66
- jest.doMock('../util/global-scope', () => ({
66
+ jest.doMock('../constants/runtime', () => ({
67
67
  __esModule: true,
68
68
  isBrowserScope: true,
69
69
  globalScope: global
@@ -74,7 +74,7 @@ test.each(urlTests)('verify url parsing inside browser scope', async ({ input, e
74
74
  })
75
75
 
76
76
  test.each(urlTests)('verify url parsing outside browser scope', async ({ input, expected }) => {
77
- jest.doMock('../util/global-scope', () => ({
77
+ jest.doMock('../constants/runtime', () => ({
78
78
  __esModule: true,
79
79
  isBrowserScope: false,
80
80
  globalScope: global
@@ -85,7 +85,7 @@ test.each(urlTests)('verify url parsing outside browser scope', async ({ input,
85
85
  })
86
86
 
87
87
  test('should cache parsed urls', async () => {
88
- jest.doMock('../util/global-scope', () => ({
88
+ jest.doMock('../constants/runtime', () => ({
89
89
  __esModule: true,
90
90
  isBrowserScope: true,
91
91
  globalScope: global
@@ -2,7 +2,7 @@
2
2
  * Copyright 2020 New Relic Corporation. All rights reserved.
3
3
  * SPDX-License-Identifier: Apache-2.0
4
4
  */
5
- import { globalScope } from '../util/global-scope'
5
+ import { globalScope } from '../constants/runtime'
6
6
 
7
7
  export function isFileProtocol () {
8
8
  return Boolean(globalScope?.location?.protocol === 'file:')
@@ -0,0 +1,10 @@
1
+ export const Obfuscator = jest.fn(function () {
2
+ this.sharedContext = {
3
+ agentIdentifier: 'abcd'
4
+ }
5
+
6
+ this.shouldObfuscate = jest.fn(() => false)
7
+ this.obfuscateString = jest.fn((input) => input)
8
+ })
9
+ export const getRules = jest.fn(() => ([]))
10
+ export const validateRules = jest.fn(() => true)
@@ -0,0 +1 @@
1
+ export const stringify = jest.fn((input) => JSON.stringify(input))
@@ -0,0 +1,6 @@
1
+ export const getSubmitMethod = jest.fn(() => jest.fn())
2
+ export const xhr = jest.fn(() => ({
3
+ addEventListener: jest.fn()
4
+ }))
5
+ export const fetchKeepAlive = jest.fn().mockResolvedValue({})
6
+ export const beacon = jest.fn(() => true)
@@ -0,0 +1 @@
1
+ export const applyFnToProps = jest.fn((input, fn) => fn(input))
@@ -1,51 +1,28 @@
1
- /*
2
- * Copyright 2020 New Relic Corporation. All rights reserved.
3
- * SPDX-License-Identifier: Apache-2.0
1
+ /**
2
+ * @file Contains common methods used to transmit harvested data.
3
+ * @copyright 2023 New Relic Corporation. All rights reserved.
4
+ * @license Apache-2.0
4
5
  */
5
- import { isWorkerScope } from './global-scope'
6
- export const submitData = {}
6
+
7
+ import { isBrowserScope, supportsSendBeacon } from '../constants/runtime'
7
8
 
8
9
  /**
9
- * Send via JSONP. Do NOT call this function outside of a guaranteed web window environment.
10
- * @param {Object} args - The args
11
- * @param {string} args.url - The URL to send to
12
- * @param {string} args.jsonp - The string name of the jsonp cb method
13
- * @returns {XMLHttpRequest}
14
- * @returns {Element}
10
+ * @typedef {xhr|fetchKeepAlive|beacon} NetworkMethods
15
11
  */
16
- submitData.jsonp = function jsonp ({ url, jsonp }) {
17
- try {
18
- if (isWorkerScope) {
19
- try {
20
- return importScripts(url + '&jsonp=' + jsonp)
21
- } catch (e) {
22
- // for now theres no other way to execute the callback from ingest without jsonp, or unsafe eval / new Function calls
23
- // future work needs to be conducted to allow ingest to return a more traditional JSON API-like experience for the entitlement flags
24
- submitData.xhrGet({ url: url + '&jsonp=' + jsonp })
25
- return false
26
- }
27
- } else {
28
- var element = document.createElement('script')
29
- element.type = 'text/javascript'
30
- element.src = url + '&jsonp=' + jsonp
31
- var firstScript = document.getElementsByTagName('script')[0]
32
- firstScript.parentNode.insertBefore(element, firstScript)
33
- return element
34
- }
35
- } catch (err) {
36
- // do nothing
37
- }
38
- }
39
12
 
40
13
  /**
41
- * Performs an asynchronous GET request using XMLHttpRequest.
42
- *
43
- * @param {Object} args - An object containing a `url` property.
44
- * @param {string} args.url - The URL to send the GET request to.
45
- * @returns {XMLHttpRequest} - An XMLHttpRequest object.
14
+ * Determines the submit method to use based on options.
15
+ * @param {object} opts Options used to determine submit method.
16
+ * @param {boolean} opts.isFinalHarvest Indicates if the data submission is due to
17
+ * a final harvest within the agent.
46
18
  */
47
- submitData.xhrGet = function xhrGet ({ url }) {
48
- return submitData.xhr({ url, sync: false, method: 'GET' })
19
+ export function getSubmitMethod ({ isFinalHarvest = false } = {}) {
20
+ return isFinalHarvest && isBrowserScope && supportsSendBeacon
21
+ // Use sendBeacon for final harvest
22
+ ? beacon
23
+ // Only IE does not support sendBeacon for final harvest
24
+ // If not final harvest, or not browserScope, always use xhr post
25
+ : xhr
49
26
  }
50
27
 
51
28
  /**
@@ -58,8 +35,8 @@ submitData.xhrGet = function xhrGet ({ url }) {
58
35
  * @param {{key: string, value: string}[]} [args.headers] - The headers to attach.
59
36
  * @returns {XMLHttpRequest}
60
37
  */
61
- submitData.xhr = function xhr ({ url, body = null, sync, method = 'POST', headers = [{ key: 'content-type', value: 'text/plain' }] }) {
62
- var request = new XMLHttpRequest()
38
+ export function xhr ({ url, body = null, sync, method = 'POST', headers = [{ key: 'content-type', value: 'text/plain' }] }) {
39
+ const request = new XMLHttpRequest()
63
40
 
64
41
  request.open(method, url, !sync)
65
42
  try {
@@ -78,15 +55,24 @@ submitData.xhr = function xhr ({ url, body = null, sync, method = 'POST', header
78
55
  }
79
56
 
80
57
  /**
81
- * Send by appending an <img> element to the page. Do NOT call this function outside of a guaranteed web window environment.
82
- * @param {Object} args - The args
83
- * @param {string} args.url - The URL to send to
84
- * @returns {HTMLImageElement}
58
+ * Send via fetch with keepalive true
59
+ * @param {Object} args - The args.
60
+ * @param {string} args.url - The URL to send to.
61
+ * @param {string=} args.body - The Stringified body.
62
+ * @param {string=} [args.method=POST] - The XHR method to use.
63
+ * @param {{key: string, value: string}[]} [args.headers] - The headers to attach.
64
+ * @returns {XMLHttpRequest}
85
65
  */
86
- submitData.img = function img ({ url }) {
87
- var element = new Image()
88
- element.src = url
89
- return element
66
+ export function fetchKeepAlive ({ url, body = null, method = 'POST', headers = [{ key: 'content-type', value: 'text/plain' }] }) {
67
+ return fetch(url, {
68
+ method,
69
+ headers: headers.reduce((aggregator, header) => {
70
+ aggregator.push([header.key, header.value])
71
+ return aggregator
72
+ }, []),
73
+ body,
74
+ keepalive: true
75
+ })
90
76
  }
91
77
 
92
78
  /**
@@ -96,7 +82,7 @@ submitData.img = function img ({ url }) {
96
82
  * @param {string=} args.body - The Stringified body
97
83
  * @returns {boolean}
98
84
  */
99
- submitData.beacon = function ({ url, body }) {
85
+ export function beacon ({ url, body }) {
100
86
  try {
101
87
  // Navigator has to be bound to ensure it does not error in some browsers
102
88
  // https://xgwang.me/posts/you-may-not-know-beacon/#it-may-throw-error%2C-be-sure-to-catch
@@ -105,7 +91,7 @@ submitData.beacon = function ({ url, body }) {
105
91
  } catch (err) {
106
92
  // if sendBeacon still trys to throw an illegal invocation error,
107
93
  // we can catch here and return. The harvest module will fallback to use
108
- // .img to try to send
94
+ // fetchKeepAlive to try to send
109
95
  return false
110
96
  }
111
97
  }
@@ -4,90 +4,58 @@
4
4
  */
5
5
 
6
6
  import { faker } from '@faker-js/faker'
7
- import { submitData } from './submit-data'
8
- import * as globalScope from './global-scope'
7
+ import * as runtimeModule from '../constants/runtime'
8
+ import * as submitData from './submit-data'
9
9
 
10
- jest.mock('./global-scope')
10
+ jest.enableAutomock()
11
+ jest.unmock('./submit-data')
11
12
 
12
13
  const url = 'https://example.com/api'
13
14
 
14
15
  afterEach(() => {
15
- jest.restoreAllMocks()
16
+ jest.clearAllMocks()
16
17
  })
17
18
 
18
- describe('submitData.jsonp', () => {
19
- beforeEach(() => {
20
- jest.replaceProperty(globalScope, 'isWorkerScope', false)
21
- })
22
-
23
- afterEach(() => {
24
- delete global.importScripts
25
- })
26
-
27
- // This test requires a script tag to exist in the html set by this file's jest-environment-options header block.
28
- test('should return an HTMLScriptElement when called from a web window environment', () => {
29
- const jsonp = faker.datatype.uuid()
30
- const result = submitData.jsonp({ url, jsonp })
31
-
32
- expect(result).toBeInstanceOf(HTMLScriptElement)
33
- expect(result.type).toBe('text/javascript')
34
- expect(result.src).toBe(url + '&jsonp=' + jsonp)
35
- })
36
-
37
- test('should try to use importScripts when called from a worker scope', () => {
38
- jest.replaceProperty(globalScope, 'isWorkerScope', true)
39
- global.importScripts = jest.fn()
40
-
41
- const jsonp = faker.datatype.uuid()
42
- submitData.jsonp({ url, jsonp })
19
+ describe('getSubmitMethod', () => {
20
+ test('should use xhr for final harvest when isBrowserScope is false', () => {
21
+ jest.replaceProperty(runtimeModule, 'isBrowserScope', false)
22
+ jest.replaceProperty(runtimeModule, 'supportsSendBeacon', true)
43
23
 
44
- expect(global.importScripts).toHaveBeenCalledWith(url + '&jsonp=' + jsonp)
24
+ expect(submitData.getSubmitMethod({ isFinalHarvest: true })).toEqual(submitData.xhr)
45
25
  })
46
26
 
47
- test('should fall back to an xhrGet call and return false when importScripts throws an error', () => {
48
- jest.replaceProperty(globalScope, 'isWorkerScope', true)
49
- jest.spyOn(submitData, 'xhrGet').mockImplementation(jest.fn())
50
- global.importScripts = jest.fn().mockImplementation(() => { throw new Error(faker.lorem.sentence()) })
27
+ test('should use xhr for final harvest when supportsSendBeacon is false', () => {
28
+ jest.replaceProperty(runtimeModule, 'isBrowserScope', true)
29
+ jest.replaceProperty(runtimeModule, 'supportsSendBeacon', false)
51
30
 
52
- const jsonp = faker.datatype.uuid()
53
- const result = submitData.jsonp({ url, jsonp })
54
-
55
- expect(result).toBe(false)
56
- expect(global.importScripts).toHaveBeenCalledWith(url + '&jsonp=' + jsonp)
57
- expect(submitData.xhrGet).toHaveBeenCalledWith({ url: url + '&jsonp=' + jsonp })
31
+ expect(submitData.getSubmitMethod({ isFinalHarvest: true })).toEqual(submitData.xhr)
58
32
  })
59
33
 
60
- test('should not throw an error when xhrGet throws an error', () => {
61
- jest.replaceProperty(globalScope, 'isWorkerScope', true)
62
- jest.spyOn(submitData, 'xhrGet').mockImplementation(() => { throw new Error(faker.lorem.sentence()) })
63
- global.importScripts = jest.fn().mockImplementation(() => { throw new Error(faker.lorem.sentence()) })
64
-
65
- const jsonp = faker.datatype.uuid()
34
+ test('should use beacon for final harvest when isBrowserScope and supportsSendBeacon is true', () => {
35
+ jest.replaceProperty(runtimeModule, 'isBrowserScope', true)
36
+ jest.replaceProperty(runtimeModule, 'supportsSendBeacon', true)
66
37
 
67
- expect(() => submitData.jsonp({ url, jsonp })).not.toThrow()
38
+ expect(submitData.getSubmitMethod({ isFinalHarvest: true })).toEqual(submitData.beacon)
68
39
  })
69
40
 
70
- test('should not throw an error when element insertion fails', () => {
71
- jest.spyOn(document, 'createElement').mockImplementation(() => { throw new Error(faker.lorem.sentence()) })
41
+ test.each([
42
+ null, undefined, false
43
+ ])('should use xhr when final harvest is %s', (isFinalHarvest) => {
44
+ jest.replaceProperty(runtimeModule, 'isBrowserScope', true)
45
+ jest.replaceProperty(runtimeModule, 'supportsSendBeacon', true)
72
46
 
73
- const jsonp = faker.datatype.uuid()
74
-
75
- expect(() => submitData.jsonp({ url, jsonp })).not.toThrow()
47
+ expect(submitData.getSubmitMethod({ isFinalHarvest })).toEqual(submitData.xhr)
76
48
  })
77
- })
78
49
 
79
- describe('submitData.xhrGet', () => {
80
- test('xhrGet should call xhr with GET as the method', () => {
81
- jest.spyOn(submitData, 'xhr').mockReturnValue(new XMLHttpRequest())
50
+ test('should use xhr when opts is undefined', () => {
51
+ jest.replaceProperty(runtimeModule, 'isBrowserScope', true)
52
+ jest.replaceProperty(runtimeModule, 'supportsSendBeacon', true)
82
53
 
83
- const result = submitData.xhrGet({ url })
84
-
85
- expect(result).toBeInstanceOf(XMLHttpRequest)
86
- expect(submitData.xhr).toHaveBeenCalledWith({ url, sync: false, method: 'GET' })
54
+ expect(submitData.getSubmitMethod()).toEqual(submitData.xhr)
87
55
  })
88
56
  })
89
57
 
90
- describe('submitData.xhr', () => {
58
+ describe('xhr', () => {
91
59
  beforeEach(() => {
92
60
  jest.spyOn(global, 'XMLHttpRequest').mockImplementation(function () {
93
61
  this.prototype = XMLHttpRequest.prototype
@@ -173,18 +141,63 @@ describe('submitData.xhr', () => {
173
141
  })
174
142
  })
175
143
 
176
- describe('submitData.img', () => {
177
- test('should return an HTMLImageElement', () => {
178
- const imageUrl = 'https://example.com/image.png'
144
+ describe('fetchKeepAlive', () => {
145
+ beforeEach(() => {
146
+ global.fetch = jest.fn().mockReturnValue(Promise.resolve())
147
+ })
148
+
149
+ afterEach(() => {
150
+ delete global.fetch
151
+ })
152
+
153
+ test('should make a fetch with default values', () => {
154
+ submitData.fetchKeepAlive({ url })
155
+
156
+ expect(global.fetch).toHaveBeenCalledWith(url, {
157
+ method: 'POST',
158
+ body: null,
159
+ keepalive: true,
160
+ headers: [['content-type', 'text/plain']]
161
+ })
162
+ })
163
+
164
+ test('should send the body when provided', () => {
165
+ const body = faker.lorem.paragraph()
166
+ submitData.fetchKeepAlive({ url, body })
167
+
168
+ expect(global.fetch).toHaveBeenCalledWith(url, {
169
+ method: 'POST',
170
+ body,
171
+ keepalive: true,
172
+ headers: [['content-type', 'text/plain']]
173
+ })
174
+ })
175
+
176
+ test('should use the provided method', () => {
177
+ submitData.fetchKeepAlive({ url, method: 'HEAD' })
178
+
179
+ expect(global.fetch).toHaveBeenCalledWith(url, {
180
+ method: 'HEAD',
181
+ body: null,
182
+ keepalive: true,
183
+ headers: [['content-type', 'text/plain']]
184
+ })
185
+ })
179
186
 
180
- const result = submitData.img({ url: imageUrl })
187
+ test('should use the provided headers', () => {
188
+ const headers = [{ key: faker.lorem.word(), value: faker.datatype.uuid() }]
189
+ submitData.fetchKeepAlive({ url, headers })
181
190
 
182
- expect(result).toBeInstanceOf(HTMLImageElement)
183
- expect(result.src).toBe(imageUrl)
191
+ expect(global.fetch).toHaveBeenCalledWith(url, {
192
+ method: 'POST',
193
+ body: null,
194
+ keepalive: true,
195
+ headers: [[headers[0].key, headers[0].value]]
196
+ })
184
197
  })
185
198
  })
186
199
 
187
- describe('submitData.beacon', () => {
200
+ describe('beacon', () => {
188
201
  afterEach(() => {
189
202
  delete window.navigator.sendBeacon
190
203
  })
@@ -1,5 +1,5 @@
1
1
  import { now } from '../timing/now'
2
- import { globalScope } from '../util/global-scope'
2
+ import { globalScope } from '../constants/runtime'
3
3
 
4
4
  export const defaults = {
5
5
  beacon: 'bam.nr-data.net',
@@ -10,7 +10,7 @@
10
10
  import { ee as baseEE } from '../event-emitter/contextual-ee'
11
11
  import { createWrapperWithEmitter as wfn } from './wrap-function'
12
12
  import { getOrSet } from '../util/get-or-set'
13
- import { globalScope, isBrowserScope } from '../util/global-scope'
13
+ import { globalScope, isBrowserScope } from '../constants/runtime'
14
14
 
15
15
  const wrapped = {}
16
16
  const XHR = XMLHttpRequest
@@ -7,7 +7,7 @@
7
7
  * This module is used by: ajax, spa.
8
8
  */
9
9
  import { ee as baseEE } from '../event-emitter/contextual-ee'
10
- import { globalScope } from '../util/global-scope'
10
+ import { globalScope } from '../constants/runtime'
11
11
  import { flag } from './wrap-function'
12
12
 
13
13
  var prefix = 'fetch-'
@@ -8,7 +8,7 @@
8
8
  */
9
9
  import { ee as globalEE } from '../event-emitter/contextual-ee'
10
10
  import { createWrapperWithEmitter as wfn } from './wrap-function'
11
- import { isBrowserScope } from '../util/global-scope'
11
+ import { isBrowserScope } from '../constants/runtime'
12
12
 
13
13
  const wrapped = {}
14
14
  const HISTORY_FNS = ['pushState', 'replaceState']
@@ -10,7 +10,7 @@
10
10
  import { eventListenerOpts } from '../event-listener/event-listener-opts'
11
11
  import { ee as baseEE } from '../event-emitter/contextual-ee'
12
12
  import { createWrapperWithEmitter as wfn } from './wrap-function'
13
- import { isBrowserScope } from '../util/global-scope'
13
+ import { isBrowserScope } from '../constants/runtime'
14
14
 
15
15
  const wrapped = {}
16
16
  const domInsertMethods = ['appendChild', 'insertBefore', 'replaceChild']
@@ -10,7 +10,7 @@
10
10
  import { ee as baseEE } from '../event-emitter/contextual-ee'
11
11
  import { createWrapperWithEmitter as wfn } from './wrap-function'
12
12
  import { originals } from '../config/config'
13
- import { isBrowserScope } from '../util/global-scope'
13
+ import { isBrowserScope } from '../constants/runtime'
14
14
 
15
15
  const wrapped = {}
16
16