@newrelic/browser-agent 0.0.9 → 0.1.229

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 (339) hide show
  1. package/README.md +84 -207
  2. package/dist/cjs/cdn/lite.js +14 -0
  3. package/dist/cjs/cdn/polyfills/lite.js +4 -0
  4. package/dist/cjs/cdn/polyfills/pro.js +4 -0
  5. package/dist/cjs/cdn/polyfills/spa.js +4 -0
  6. package/dist/cjs/cdn/polyfills.js +14 -0
  7. package/dist/cjs/cdn/pro.js +19 -0
  8. package/dist/cjs/cdn/spa.js +19 -0
  9. package/dist/cjs/cdn/worker.js +16 -0
  10. package/dist/cjs/common/aggregate/aggregator.js +168 -0
  11. package/dist/cjs/common/browser-version/firefox-version.js +17 -0
  12. package/dist/cjs/common/browser-version/ios-version.js +18 -0
  13. package/dist/cjs/common/config/config.js +76 -0
  14. package/dist/cjs/common/config/state/configurable.js +32 -0
  15. package/dist/cjs/common/config/state/info.js +50 -0
  16. package/dist/cjs/common/config/state/init.js +86 -0
  17. package/dist/cjs/common/config/state/loader-config.js +28 -0
  18. package/dist/cjs/common/config/state/originals.js +9 -0
  19. package/dist/cjs/common/config/state/runtime.js +50 -0
  20. package/dist/cjs/common/constants/environment-variables.js +20 -0
  21. package/dist/cjs/common/context/shared-context.js +25 -0
  22. package/dist/cjs/common/deny-list/deny-list.js +108 -0
  23. package/dist/cjs/common/drain/drain.js +126 -0
  24. package/dist/cjs/common/event-emitter/contextual-ee.js +149 -0
  25. package/dist/cjs/common/event-emitter/handle.js +24 -0
  26. package/dist/cjs/common/event-emitter/register-handler.js +24 -0
  27. package/dist/cjs/common/event-listener/event-listener-opts.js +46 -0
  28. package/dist/cjs/common/harvest/harvest-scheduler.js +111 -0
  29. package/dist/cjs/common/harvest/harvest.js +236 -0
  30. package/dist/cjs/common/ids/id.js +30 -0
  31. package/dist/cjs/common/ids/unique-id.js +84 -0
  32. package/dist/cjs/common/metrics/framework-detection.js +72 -0
  33. package/dist/cjs/common/metrics/paint-metrics.js +13 -0
  34. package/dist/cjs/common/serialize/bel-serializer.js +89 -0
  35. package/dist/cjs/common/timing/nav-timing.js +77 -0
  36. package/dist/cjs/common/timing/now.js +15 -0
  37. package/dist/cjs/common/unload/eol.js +69 -0
  38. package/dist/cjs/common/url/clean-url.js +16 -0
  39. package/dist/cjs/common/url/encode.js +79 -0
  40. package/dist/cjs/common/url/location.js +14 -0
  41. package/dist/cjs/common/url/parse-url.js +66 -0
  42. package/dist/cjs/common/url/protocol.js +25 -0
  43. package/dist/cjs/common/util/console.js +17 -0
  44. package/dist/cjs/common/util/data-size.js +25 -0
  45. package/dist/cjs/common/util/feature-flags.js +42 -0
  46. package/dist/cjs/common/util/get-or-set.js +39 -0
  47. package/dist/cjs/common/util/global-scope.js +56 -0
  48. package/dist/cjs/common/util/map-own.js +24 -0
  49. package/dist/cjs/common/util/obfuscate.js +76 -0
  50. package/dist/cjs/common/util/reduce.js +22 -0
  51. package/dist/cjs/common/util/s-hash.js +19 -0
  52. package/dist/cjs/common/util/single.js +23 -0
  53. package/dist/cjs/common/util/stringify.js +47 -0
  54. package/dist/cjs/common/util/submit-data.js +99 -0
  55. package/dist/cjs/common/util/traverse.js +41 -0
  56. package/dist/cjs/common/util/user-agent.js +57 -0
  57. package/dist/cjs/common/window/load.js +19 -0
  58. package/dist/cjs/common/window/nreum.js +107 -0
  59. package/dist/cjs/common/window/page-visibility.js +28 -0
  60. package/dist/cjs/common/window/session-storage.js +42 -0
  61. package/dist/cjs/common/window/supports-performance-observer.js +15 -0
  62. package/dist/cjs/common/window/top-level-callers.js +23 -0
  63. package/dist/cjs/common/wrap/index.js +68 -0
  64. package/dist/cjs/common/wrap/wrap-events.js +105 -0
  65. package/dist/cjs/common/wrap/wrap-fetch.js +114 -0
  66. package/dist/cjs/common/wrap/wrap-function.js +269 -0
  67. package/dist/cjs/common/wrap/wrap-history.js +56 -0
  68. package/dist/cjs/common/wrap/wrap-jsonp.js +129 -0
  69. package/dist/cjs/common/wrap/wrap-mutation.js +61 -0
  70. package/dist/cjs/common/wrap/wrap-promise.js +160 -0
  71. package/dist/cjs/common/wrap/wrap-raf.js +55 -0
  72. package/dist/cjs/common/wrap/wrap-timer.js +70 -0
  73. package/dist/cjs/common/wrap/wrap-xhr.js +206 -0
  74. package/dist/cjs/features/ajax/aggregate/index.js +226 -0
  75. package/dist/cjs/features/ajax/constants.js +9 -0
  76. package/dist/cjs/features/ajax/index.js +12 -0
  77. package/dist/cjs/features/ajax/instrument/distributed-tracing.js +145 -0
  78. package/dist/cjs/features/ajax/instrument/index.js +338 -0
  79. package/dist/cjs/features/ajax/instrument/response-size.js +26 -0
  80. package/dist/cjs/features/jserrors/aggregate/canonical-function-name.js +18 -0
  81. package/dist/cjs/features/jserrors/aggregate/canonical-function-name.test.js +30 -0
  82. package/dist/cjs/features/jserrors/aggregate/compute-stack-trace.js +216 -0
  83. package/dist/cjs/features/jserrors/aggregate/compute-stack-trace.test.js +257 -0
  84. package/dist/cjs/features/jserrors/aggregate/format-stack-trace.js +36 -0
  85. package/dist/cjs/features/jserrors/aggregate/format-stack-trace.test.js +39 -0
  86. package/dist/cjs/features/jserrors/aggregate/index.js +267 -0
  87. package/dist/cjs/features/jserrors/aggregate/string-hash-code.js +23 -0
  88. package/dist/cjs/features/jserrors/aggregate/string-hash-code.test.js +26 -0
  89. package/dist/cjs/features/jserrors/constants.js +11 -0
  90. package/dist/cjs/features/jserrors/index.js +12 -0
  91. package/dist/cjs/features/jserrors/instrument/debug.js +40 -0
  92. package/dist/cjs/features/jserrors/instrument/index.js +158 -0
  93. package/dist/cjs/features/metrics/aggregate/index.js +136 -0
  94. package/dist/cjs/features/metrics/constants.js +17 -0
  95. package/dist/cjs/features/metrics/index.js +12 -0
  96. package/dist/cjs/features/metrics/instrument/index.js +20 -0
  97. package/dist/cjs/features/metrics/instrument/workers-helper.js +121 -0
  98. package/dist/cjs/features/page_action/aggregate/index.js +112 -0
  99. package/dist/cjs/features/page_action/constants.js +9 -0
  100. package/dist/cjs/features/page_action/index.js +12 -0
  101. package/dist/cjs/features/page_action/instrument/index.js +21 -0
  102. package/dist/cjs/features/page_view_event/aggregate/index.js +133 -0
  103. package/dist/cjs/features/page_view_event/aggregate/initialized-features.js +39 -0
  104. package/dist/cjs/features/page_view_event/constants.js +15 -0
  105. package/dist/cjs/features/page_view_event/index.js +12 -0
  106. package/dist/cjs/features/page_view_event/instrument/index.js +38 -0
  107. package/dist/cjs/features/page_view_timing/aggregate/index.js +265 -0
  108. package/dist/cjs/features/page_view_timing/constants.js +9 -0
  109. package/dist/cjs/features/page_view_timing/first-paint.js +50 -0
  110. package/dist/cjs/features/page_view_timing/index.js +12 -0
  111. package/dist/cjs/features/page_view_timing/instrument/index.js +36 -0
  112. package/dist/cjs/features/page_view_timing/long-tasks.js +75 -0
  113. package/dist/cjs/features/session_trace/aggregate/index.js +375 -0
  114. package/dist/cjs/features/session_trace/constants.js +32 -0
  115. package/dist/cjs/features/session_trace/index.js +12 -0
  116. package/dist/cjs/features/session_trace/instrument/index.js +133 -0
  117. package/dist/cjs/features/spa/aggregate/index.js +684 -0
  118. package/dist/cjs/features/spa/aggregate/interaction-node.js +84 -0
  119. package/dist/cjs/features/spa/aggregate/interaction-node.test.js +16 -0
  120. package/dist/cjs/features/spa/aggregate/interaction.js +98 -0
  121. package/dist/cjs/features/spa/aggregate/serializer.js +147 -0
  122. package/dist/cjs/features/spa/constants.js +53 -0
  123. package/dist/cjs/features/spa/index.js +12 -0
  124. package/dist/cjs/features/spa/instrument/index.js +114 -0
  125. package/dist/cjs/features/utils/aggregate-base.js +13 -0
  126. package/dist/cjs/features/utils/feature-base.js +58 -0
  127. package/dist/cjs/features/utils/handler-cache.js +64 -0
  128. package/dist/cjs/features/utils/instrument-base.js +71 -0
  129. package/dist/cjs/features/utils/lazy-loader.js +44 -0
  130. package/dist/cjs/index.js +81 -58
  131. package/dist/cjs/loaders/agent.js +86 -0
  132. package/dist/cjs/loaders/api/api.js +109 -0
  133. package/dist/cjs/loaders/api/apiAsync.js +94 -0
  134. package/dist/cjs/loaders/browser-agent.js +29 -0
  135. package/dist/cjs/loaders/configure/configure.js +47 -0
  136. package/dist/cjs/loaders/features/enabled-features.js +19 -0
  137. package/dist/cjs/loaders/features/featureDependencies.js +32 -0
  138. package/dist/cjs/loaders/features/features.js +33 -0
  139. package/dist/cjs/loaders/micro-agent.js +93 -0
  140. package/dist/cjs/loaders/worker-agent.js +24 -0
  141. package/dist/esm/cdn/lite.js +12 -0
  142. package/dist/esm/cdn/polyfills/lite.js +7 -0
  143. package/dist/esm/cdn/polyfills/pro.js +7 -0
  144. package/dist/esm/cdn/polyfills/spa.js +7 -0
  145. package/dist/esm/cdn/polyfills.js +17 -0
  146. package/dist/esm/cdn/pro.js +17 -0
  147. package/dist/esm/cdn/spa.js +17 -0
  148. package/dist/esm/cdn/worker.js +14 -0
  149. package/dist/esm/common/aggregate/aggregator.js +161 -0
  150. package/dist/esm/common/browser-version/firefox-version.js +10 -0
  151. package/dist/esm/common/browser-version/ios-version.js +10 -0
  152. package/dist/esm/common/config/config.js +11 -0
  153. package/dist/esm/common/config/state/configurable.js +25 -0
  154. package/dist/esm/common/config/state/info.js +42 -0
  155. package/dist/esm/common/config/state/init.js +78 -0
  156. package/dist/esm/common/config/state/loader-config.js +21 -0
  157. package/dist/esm/common/config/state/originals.js +2 -0
  158. package/dist/esm/common/config/state/runtime.js +41 -0
  159. package/dist/esm/common/constants/environment-variables.js +11 -0
  160. package/dist/esm/common/context/shared-context.js +18 -0
  161. package/dist/esm/common/deny-list/deny-list.js +101 -0
  162. package/dist/esm/common/drain/drain.js +119 -0
  163. package/dist/esm/common/event-emitter/contextual-ee.js +142 -0
  164. package/dist/esm/common/event-emitter/handle.js +16 -0
  165. package/dist/esm/common/event-emitter/register-handler.js +19 -0
  166. package/dist/esm/common/event-listener/event-listener-opts.js +39 -0
  167. package/dist/esm/common/harvest/harvest-scheduler.js +105 -0
  168. package/dist/esm/common/harvest/harvest.js +228 -0
  169. package/dist/esm/common/ids/id.js +23 -0
  170. package/dist/esm/common/ids/unique-id.js +75 -0
  171. package/dist/esm/common/metrics/framework-detection.js +66 -0
  172. package/dist/esm/common/metrics/paint-metrics.js +6 -0
  173. package/dist/esm/common/serialize/bel-serializer.js +80 -0
  174. package/dist/esm/common/timing/nav-timing.js +67 -0
  175. package/dist/esm/common/timing/now.js +9 -0
  176. package/dist/esm/common/unload/eol.js +62 -0
  177. package/dist/esm/common/url/clean-url.js +10 -0
  178. package/dist/esm/common/url/encode.js +71 -0
  179. package/dist/esm/common/url/location.js +8 -0
  180. package/dist/esm/common/url/parse-url.js +60 -0
  181. package/dist/esm/common/url/protocol.js +17 -0
  182. package/dist/esm/common/util/console.js +11 -0
  183. package/dist/esm/common/util/data-size.js +19 -0
  184. package/dist/esm/common/util/feature-flags.js +33 -0
  185. package/dist/esm/common/util/get-or-set.js +33 -0
  186. package/dist/esm/common/util/global-scope.js +44 -0
  187. package/dist/esm/common/util/map-own.js +18 -0
  188. package/dist/esm/common/util/obfuscate.js +67 -0
  189. package/dist/esm/common/util/reduce.js +16 -0
  190. package/dist/esm/common/util/s-hash.js +13 -0
  191. package/dist/esm/common/util/single.js +16 -0
  192. package/dist/esm/common/util/stringify.js +42 -0
  193. package/dist/esm/common/util/submit-data.js +91 -0
  194. package/dist/esm/common/util/traverse.js +35 -0
  195. package/dist/esm/common/util/user-agent.js +48 -0
  196. package/dist/esm/common/window/load.js +12 -0
  197. package/dist/esm/common/window/nreum.js +91 -0
  198. package/dist/esm/common/window/page-visibility.js +23 -0
  199. package/dist/esm/common/window/session-storage.js +36 -0
  200. package/dist/esm/common/window/supports-performance-observer.js +9 -0
  201. package/dist/esm/common/window/top-level-callers.js +17 -0
  202. package/dist/esm/common/wrap/index.js +14 -0
  203. package/dist/esm/common/wrap/wrap-events.js +97 -0
  204. package/dist/esm/common/wrap/wrap-fetch.js +105 -0
  205. package/dist/esm/common/wrap/wrap-function.js +257 -0
  206. package/dist/esm/common/wrap/wrap-history.js +48 -0
  207. package/dist/esm/common/wrap/wrap-jsonp.js +122 -0
  208. package/dist/esm/common/wrap/wrap-mutation.js +54 -0
  209. package/dist/esm/common/wrap/wrap-promise.js +153 -0
  210. package/dist/esm/common/wrap/wrap-raf.js +48 -0
  211. package/dist/esm/common/wrap/wrap-timer.js +63 -0
  212. package/dist/esm/common/wrap/wrap-xhr.js +199 -0
  213. package/dist/esm/features/ajax/aggregate/index.js +218 -0
  214. package/dist/esm/features/ajax/constants.js +2 -0
  215. package/dist/esm/features/ajax/index.js +1 -0
  216. package/dist/esm/features/ajax/instrument/distributed-tracing.js +137 -0
  217. package/dist/esm/features/ajax/instrument/index.js +330 -0
  218. package/dist/esm/features/ajax/instrument/response-size.js +19 -0
  219. package/dist/esm/features/jserrors/aggregate/canonical-function-name.js +12 -0
  220. package/dist/esm/features/jserrors/aggregate/canonical-function-name.test.js +28 -0
  221. package/dist/esm/features/jserrors/aggregate/compute-stack-trace.js +209 -0
  222. package/dist/esm/features/jserrors/aggregate/compute-stack-trace.test.js +255 -0
  223. package/dist/esm/features/jserrors/aggregate/format-stack-trace.js +29 -0
  224. package/dist/esm/features/jserrors/aggregate/format-stack-trace.test.js +37 -0
  225. package/dist/esm/features/jserrors/aggregate/index.js +260 -0
  226. package/dist/esm/features/jserrors/aggregate/string-hash-code.js +17 -0
  227. package/dist/esm/features/jserrors/aggregate/string-hash-code.test.js +24 -0
  228. package/dist/esm/features/jserrors/constants.js +3 -0
  229. package/dist/esm/features/jserrors/index.js +1 -0
  230. package/dist/esm/features/jserrors/instrument/debug.js +38 -0
  231. package/dist/esm/features/jserrors/instrument/index.js +150 -0
  232. package/dist/esm/features/metrics/aggregate/index.js +129 -0
  233. package/dist/esm/features/metrics/constants.js +6 -0
  234. package/dist/esm/features/metrics/index.js +1 -0
  235. package/dist/esm/features/metrics/instrument/index.js +13 -0
  236. package/dist/esm/features/metrics/instrument/workers-helper.js +116 -0
  237. package/dist/esm/features/page_action/aggregate/index.js +105 -0
  238. package/dist/esm/features/page_action/constants.js +2 -0
  239. package/dist/esm/features/page_action/index.js +1 -0
  240. package/dist/esm/features/page_action/instrument/index.js +14 -0
  241. package/dist/esm/features/page_view_event/aggregate/index.js +124 -0
  242. package/dist/esm/features/page_view_event/aggregate/initialized-features.js +34 -0
  243. package/dist/esm/features/page_view_event/constants.js +5 -0
  244. package/dist/esm/features/page_view_event/index.js +1 -0
  245. package/dist/esm/features/page_view_event/instrument/index.js +29 -0
  246. package/dist/esm/features/page_view_timing/aggregate/index.js +258 -0
  247. package/dist/esm/features/page_view_timing/constants.js +2 -0
  248. package/dist/esm/features/page_view_timing/first-paint.js +43 -0
  249. package/dist/esm/features/page_view_timing/index.js +1 -0
  250. package/dist/esm/features/page_view_timing/instrument/index.js +28 -0
  251. package/dist/esm/features/page_view_timing/long-tasks.js +69 -0
  252. package/dist/esm/features/session_trace/aggregate/index.js +366 -0
  253. package/dist/esm/features/session_trace/constants.js +14 -0
  254. package/dist/esm/features/session_trace/index.js +1 -0
  255. package/dist/esm/features/session_trace/instrument/index.js +123 -0
  256. package/dist/esm/features/spa/aggregate/index.js +674 -0
  257. package/dist/esm/features/spa/aggregate/interaction-node.js +78 -0
  258. package/dist/esm/features/spa/aggregate/interaction-node.test.js +14 -0
  259. package/dist/esm/features/spa/aggregate/interaction.js +92 -0
  260. package/dist/esm/features/spa/aggregate/serializer.js +139 -0
  261. package/dist/esm/features/spa/constants.js +25 -0
  262. package/dist/esm/features/spa/index.js +1 -0
  263. package/dist/esm/features/spa/instrument/index.js +104 -0
  264. package/dist/esm/features/utils/aggregate-base.js +6 -0
  265. package/dist/esm/features/utils/feature-base.js +51 -0
  266. package/dist/esm/features/utils/handler-cache.js +57 -0
  267. package/dist/esm/features/utils/instrument-base.js +69 -0
  268. package/dist/esm/features/utils/lazy-loader.js +37 -0
  269. package/dist/esm/index.js +15 -0
  270. package/dist/esm/loaders/agent.js +77 -0
  271. package/dist/esm/loaders/api/api.js +104 -0
  272. package/dist/esm/loaders/api/apiAsync.js +88 -0
  273. package/dist/esm/loaders/browser-agent.js +23 -0
  274. package/dist/esm/loaders/configure/configure.js +41 -0
  275. package/dist/esm/loaders/features/enabled-features.js +13 -0
  276. package/dist/esm/loaders/features/featureDependencies.js +25 -0
  277. package/dist/esm/loaders/features/features.js +25 -0
  278. package/dist/esm/loaders/micro-agent.js +86 -0
  279. package/dist/esm/loaders/worker-agent.js +18 -0
  280. package/package.json +204 -71
  281. package/types.ts +221 -0
  282. package/dist/bundled/es5/index.js +0 -2
  283. package/dist/bundled/es5/index.js.map +0 -1
  284. package/dist/bundled/es6/index.js +0 -2
  285. package/dist/bundled/es6/index.js.map +0 -1
  286. package/dist/cjs/index.d.ts +0 -19
  287. package/dist/cjs/index.js.map +0 -1
  288. package/dist/cjs/types.d.ts +0 -94
  289. package/dist/cjs/types.js +0 -28
  290. package/dist/cjs/types.js.map +0 -1
  291. package/dist/cjs/utils/api/api.d.ts +0 -10
  292. package/dist/cjs/utils/api/api.js +0 -40
  293. package/dist/cjs/utils/api/api.js.map +0 -1
  294. package/dist/cjs/utils/config/build-configs.d.ts +0 -6
  295. package/dist/cjs/utils/config/build-configs.js +0 -68
  296. package/dist/cjs/utils/config/build-configs.js.map +0 -1
  297. package/dist/cjs/utils/features/features.d.ts +0 -5
  298. package/dist/cjs/utils/features/features.js +0 -14
  299. package/dist/cjs/utils/features/features.js.map +0 -1
  300. package/dist/cjs/utils/features/initialize.d.ts +0 -5
  301. package/dist/cjs/utils/features/initialize.js +0 -51
  302. package/dist/cjs/utils/features/initialize.js.map +0 -1
  303. package/dist/es/index.d.ts +0 -19
  304. package/dist/es/index.js +0 -55
  305. package/dist/es/index.js.map +0 -1
  306. package/dist/es/types.d.ts +0 -94
  307. package/dist/es/types.js +0 -24
  308. package/dist/es/types.js.map +0 -1
  309. package/dist/es/utils/api/api.d.ts +0 -10
  310. package/dist/es/utils/api/api.js +0 -36
  311. package/dist/es/utils/api/api.js.map +0 -1
  312. package/dist/es/utils/config/build-configs.d.ts +0 -6
  313. package/dist/es/utils/config/build-configs.js +0 -64
  314. package/dist/es/utils/config/build-configs.js.map +0 -1
  315. package/dist/es/utils/features/features.d.ts +0 -5
  316. package/dist/es/utils/features/features.js +0 -10
  317. package/dist/es/utils/features/features.js.map +0 -1
  318. package/dist/es/utils/features/initialize.d.ts +0 -5
  319. package/dist/es/utils/features/initialize.js +0 -24
  320. package/dist/es/utils/features/initialize.js.map +0 -1
  321. package/dist/umd/index.d.ts +0 -19
  322. package/dist/umd/index.js +0 -69
  323. package/dist/umd/index.js.map +0 -1
  324. package/dist/umd/types.d.ts +0 -94
  325. package/dist/umd/types.js +0 -38
  326. package/dist/umd/types.js.map +0 -1
  327. package/dist/umd/utils/api/api.d.ts +0 -10
  328. package/dist/umd/utils/api/api.js +0 -50
  329. package/dist/umd/utils/api/api.js.map +0 -1
  330. package/dist/umd/utils/config/build-configs.d.ts +0 -6
  331. package/dist/umd/utils/config/build-configs.js +0 -78
  332. package/dist/umd/utils/config/build-configs.js.map +0 -1
  333. package/dist/umd/utils/features/features.d.ts +0 -5
  334. package/dist/umd/utils/features/features.js +0 -24
  335. package/dist/umd/utils/features/features.js.map +0 -1
  336. package/dist/umd/utils/features/initialize.d.ts +0 -5
  337. package/dist/umd/utils/features/initialize.js +0 -63
  338. package/dist/umd/utils/features/initialize.js.map +0 -1
  339. package/dist/webpack-analysis.html +0 -38
@@ -0,0 +1,684 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.Aggregate = void 0;
7
+ var _registerHandler = require("../../../common/event-emitter/register-handler");
8
+ var _parseUrl = require("../../../common/url/parse-url");
9
+ var _denyList = require("../../../common/deny-list/deny-list");
10
+ var _mapOwn = require("../../../common/util/map-own");
11
+ var _navTiming = require("../../../common/timing/nav-timing");
12
+ var _uniqueId = require("../../../common/ids/unique-id");
13
+ var _paintMetrics = require("../../../common/metrics/paint-metrics");
14
+ var _interaction = require("./interaction");
15
+ var _config = require("../../../common/config/config");
16
+ var _eventListenerOpts = require("../../../common/event-listener/event-listener-opts");
17
+ var _aggregateBase = require("../../utils/aggregate-base");
18
+ var _harvestScheduler = require("../../../common/harvest/harvest-scheduler");
19
+ var _serializer = require("./serializer");
20
+ var _contextualEe = require("../../../common/event-emitter/contextual-ee");
21
+ var CONSTANTS = _interopRequireWildcard(require("../constants"));
22
+ var _drain = require("../../../common/drain/drain");
23
+ var _features = require("../../../loaders/features/features");
24
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
25
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
26
+ /*
27
+ * Copyright 2020 New Relic Corporation. All rights reserved.
28
+ * SPDX-License-Identifier: Apache-2.0
29
+ */
30
+ /*eslint no-undef: "error"*/
31
+
32
+ const {
33
+ FEATURE_NAME,
34
+ INTERACTION_EVENTS,
35
+ MAX_TIMER_BUDGET,
36
+ FN_START,
37
+ FN_END,
38
+ CB_START,
39
+ INTERACTION_API,
40
+ REMAINING,
41
+ INTERACTION,
42
+ SPA_NODE,
43
+ JSONP_NODE,
44
+ FETCH_START,
45
+ FETCH_DONE,
46
+ FETCH_BODY,
47
+ JSONP_END,
48
+ originalSetTimeout
49
+ } = CONSTANTS;
50
+ class Aggregate extends _aggregateBase.AggregateBase {
51
+ static featureName = FEATURE_NAME;
52
+ constructor(agentIdentifier, aggregator) {
53
+ super(agentIdentifier, aggregator, FEATURE_NAME);
54
+ this.state = {
55
+ initialPageURL: (0, _config.getRuntime)(agentIdentifier).origin,
56
+ lastSeenUrl: (0, _config.getRuntime)(agentIdentifier).origin,
57
+ lastSeenRouteName: null,
58
+ timerMap: {},
59
+ timerBudget: MAX_TIMER_BUDGET,
60
+ currentNode: null,
61
+ prevNode: null,
62
+ nodeOnLastHashUpdate: null,
63
+ initialPageLoad: null,
64
+ pageLoaded: false,
65
+ childTime: 0,
66
+ depth: 0,
67
+ harvestTimeSeconds: (0, _config.getConfigurationValue)(agentIdentifier, 'spa.harvestTimeSeconds') || 10,
68
+ interactionsToHarvest: [],
69
+ interactionsSent: []
70
+ };
71
+ this.serializer = new _serializer.Serializer(this);
72
+ const {
73
+ state,
74
+ serializer
75
+ } = this;
76
+ let {
77
+ blocked
78
+ } = this;
79
+ const baseEE = _contextualEe.ee.get(agentIdentifier); // <-- parent baseEE
80
+ const mutationEE = baseEE.get('mutation');
81
+ const promiseEE = baseEE.get('promise');
82
+ const historyEE = baseEE.get('history');
83
+ const eventsEE = baseEE.get('events'); // ajax --> ee(123).emit() ee()
84
+ const timerEE = baseEE.get('timer');
85
+ const fetchEE = baseEE.get('fetch');
86
+ const jsonpEE = baseEE.get('jsonp');
87
+ const xhrEE = baseEE.get('xhr');
88
+ const tracerEE = baseEE.get('tracer');
89
+ const scheduler = new _harvestScheduler.HarvestScheduler('events', {
90
+ onFinished: onHarvestFinished,
91
+ retryDelay: state.harvestTimeSeconds
92
+ }, {
93
+ agentIdentifier
94
+ });
95
+ scheduler.harvest.on('events', onHarvestStarted);
96
+
97
+ // childTime is used when calculating exclusive time for a cb duration.
98
+ //
99
+ // Exclusive time will be different than the total time for either callbacks
100
+ // which synchronously invoke a customTracer callback or, trigger a synchronous
101
+ // event (eg. onreadystate=1 or popstate).
102
+ //
103
+ // At fn-end, childTime will contain the total time of all timed callbacks and
104
+ // event handlers which executed as a child of the current callback. At the
105
+ // begining of every callback, childTime is saved to the event context (which at
106
+ // that time contains the sum of its preceeding siblings) and is reset to 0. The
107
+ // callback is then executed, and its children may increase childTime. At the
108
+ // end of the callback, it reports its exclusive time as its
109
+ // execution time - exlcuded. childTime is then reset to its previous
110
+ // value, and the totalTime of the callback that just finished executing is
111
+ // added to the childTime time.
112
+ // | clock | childTime | ctx.ct | totalTime | exclusive |
113
+ // click fn-start | 0 | 0 | 0 | | |
114
+ // | click begining: | 5 | 0 | 0 | | |
115
+ // | | custom-1 fn-start | 10 | 0 | 0 | | |
116
+ // | | | custom-1 begining | 15 | 0 | 0 | | |
117
+ // | | | | custom-2 fn-start | 20 | 0 | 0 | | |
118
+ // | | | | | custom-2 | 25 | 0 | 0 | | |
119
+ // | | | | custom-2 fn-end | 30 | 10 | 0 | 10 | 10 |
120
+ // | | | custom-1 middle | 35 | 10 | 0 | | |
121
+ // | | | | custom-3 fn-start | 40 | 0 | 10 | | |
122
+ // | | | | | custom-3 | 45 | 0 | 10 | | |
123
+ // | | | | custom-3 fn-end | 50 | 20 | 0 | 10 | 10 |
124
+ // | | | custom-1 ending | 55 | 20 | 0 | | |
125
+ // | custom-1 fn-end | 60 | 50 | 0 | 50 | 30 |
126
+ // | click ending: | 65 | 50 | | | |
127
+ // click fn-end | 70 | 0 | 0 | 70 | 20 |
128
+
129
+ // if rum response determines that customer lacks entitlements for spa endpoint, block it
130
+ (0, _registerHandler.registerHandler)('block-spa', () => {
131
+ blocked = true;
132
+ scheduler.stopTimer(true);
133
+ }, this.featureName, baseEE);
134
+ if (!isEnabled()) return;
135
+ state.initialPageLoad = new _interaction.Interaction('initialPageLoad', 0, state.lastSeenUrl, state.lastSeenRouteName, onInteractionFinished, agentIdentifier);
136
+ state.initialPageLoad.save = true;
137
+ state.prevInteraction = state.initialPageLoad;
138
+ state.currentNode = state.initialPageLoad.root; // hint
139
+ // ensure that checkFinish calls are safe during initialPageLoad
140
+ state.initialPageLoad[REMAINING]++;
141
+ (0, _registerHandler.registerHandler)(FN_START, callbackStart, this.featureName, baseEE);
142
+ (0, _registerHandler.registerHandler)(CB_START, callbackStart, this.featureName, promiseEE);
143
+
144
+ // register plugins
145
+ var pluginApi = {
146
+ getCurrentNode: getCurrentNode,
147
+ setCurrentNode: setCurrentNode
148
+ };
149
+ (0, _registerHandler.registerHandler)('spa-register', function (init) {
150
+ if (typeof init === 'function') {
151
+ init(pluginApi);
152
+ }
153
+ }, _features.FEATURE_NAMES.spa, baseEE);
154
+ function callbackStart() {
155
+ state.depth++;
156
+ this.prevNode = state.currentNode;
157
+ this.ct = state.childTime;
158
+ state.childTime = 0;
159
+ state.timerBudget = MAX_TIMER_BUDGET;
160
+ }
161
+ (0, _registerHandler.registerHandler)(FN_END, callbackEnd, this.featureName, baseEE);
162
+ (0, _registerHandler.registerHandler)('cb-end', callbackEnd, this.featureName, promiseEE);
163
+ function callbackEnd() {
164
+ state.depth--;
165
+ var totalTime = this.jsTime || 0;
166
+ var exclusiveTime = totalTime - state.childTime;
167
+ state.childTime = this.ct + totalTime;
168
+ if (state.currentNode) {
169
+ // transfer accumulated callback time to the active interaction node
170
+ // run even if jsTime is 0 to update jsEnd
171
+ state.currentNode.callback(exclusiveTime, this[FN_END]);
172
+ if (this.isTraced) {
173
+ state.currentNode.attrs.tracedTime = exclusiveTime;
174
+ }
175
+ }
176
+ this.jsTime = state.currentNode ? 0 : exclusiveTime;
177
+ setCurrentNode(this.prevNode);
178
+ this.prevNode = null;
179
+ state.timerBudget = MAX_TIMER_BUDGET;
180
+ }
181
+ (0, _registerHandler.registerHandler)(FN_START, function (args, eventSource) {
182
+ var ev = args[0];
183
+ var evName = ev.type;
184
+ var eventNode = ev.__nrNode;
185
+ if (!state.pageLoaded && evName === 'load' && eventSource === window) {
186
+ state.pageLoaded = true;
187
+ // set to null so prevNode is set correctly
188
+ this.prevNode = state.currentNode = null;
189
+ if (state.initialPageLoad) {
190
+ eventNode = state.initialPageLoad.root;
191
+
192
+ // Even if initialPageLoad has remaining callbacks, force the initialPageLoad
193
+ // interaction to complete when the page load event occurs.
194
+ state.initialPageLoad[REMAINING] = 0;
195
+ originalSetTimeout(function () {
196
+ INTERACTION_EVENTS.push('popstate');
197
+ });
198
+ }
199
+ }
200
+ if (eventNode) {
201
+ // If we've already seen a previous handler for this specific event object,
202
+ // just restore that. We want multiple handlers for the same event to share
203
+ // a node.
204
+ setCurrentNode(eventNode);
205
+ } else if (evName === 'hashchange') {
206
+ setCurrentNode(state.nodeOnLastHashUpdate);
207
+ state.nodeOnLastHashUpdate = null;
208
+ } else if (eventSource instanceof XMLHttpRequest) {
209
+ // If this event was emitted by an XHR, restore the node ID associated with
210
+ // that XHR.
211
+ setCurrentNode(baseEE.context(eventSource).spaNode);
212
+ } else if (!state.currentNode) {
213
+ // Otherwise, if no interaction is currently active, create a new node ID,
214
+ // and let the aggregator know that we entered a new event handler callback
215
+ // so that it has a chance to possibly start an interaction.
216
+ if (INTERACTION_EVENTS.indexOf(evName) !== -1) {
217
+ var ixn = new _interaction.Interaction(evName, this[FN_START], state.lastSeenUrl, state.lastSeenRouteName, onInteractionFinished, agentIdentifier);
218
+
219
+ // Store the interaction as prevInteraction in case it is prematurely discarded
220
+ state.prevInteraction = ixn;
221
+ setCurrentNode(ixn.root);
222
+ if (evName === 'click') {
223
+ var value = getActionText(ev.target);
224
+ if (value) {
225
+ state.currentNode.attrs.custom['actionText'] = value;
226
+ }
227
+ }
228
+ }
229
+ }
230
+ ev.__nrNode = state.currentNode;
231
+ }, this.featureName, eventsEE);
232
+
233
+ /**
234
+ * *** TIMERS ***
235
+ * setTimeout call needs to keep the interaction active in case a node is started
236
+ * in its callback.
237
+ */
238
+
239
+ // The context supplied to this callback will be shared with the fn-start/fn-end
240
+ // callbacks that fire around the callback passed to setTimeout originally.
241
+ (0, _registerHandler.registerHandler)('setTimeout-end', function saveId(args, obj, timerId) {
242
+ if (!state.currentNode || state.timerBudget - this.timerDuration < 0) return;
243
+ if (args && !(args[0] instanceof Function)) return;
244
+ state.currentNode[INTERACTION][REMAINING]++;
245
+ this.timerId = timerId;
246
+ state.timerMap[timerId] = state.currentNode;
247
+ this.timerBudget = state.timerBudget - 50;
248
+ }, this.featureName, timerEE);
249
+ (0, _registerHandler.registerHandler)('clearTimeout-start', function clear(args) {
250
+ var timerId = args[0];
251
+ var node = state.timerMap[timerId];
252
+ if (node) {
253
+ var interaction = node[INTERACTION];
254
+ interaction[REMAINING]--;
255
+ interaction.checkFinish();
256
+ delete state.timerMap[timerId];
257
+ }
258
+ }, this.featureName, timerEE);
259
+ (0, _registerHandler.registerHandler)(FN_START, function () {
260
+ state.timerBudget = this.timerBudget || MAX_TIMER_BUDGET;
261
+ var id = this.timerId;
262
+ var node = state.timerMap[id];
263
+ setCurrentNode(node);
264
+ delete state.timerMap[id];
265
+ if (node) node[INTERACTION][REMAINING]--;
266
+ }, this.featureName, timerEE);
267
+
268
+ /**
269
+ * *** XHR ***
270
+ * - `new-xhr` event is fired when new instance of XHR is created. Here we create
271
+ * a new node and store it on the XHR object.
272
+ * - When the send method is called (`send-xhr-start` event), we tell the interaction
273
+ * to wait for this XHR to complete.
274
+ * - When any direct event handlers are invoked (`fn-start` on the `xhr` emitter),
275
+ * we restore the node in case other child nodes are started here.
276
+ * - Callbacks attached using `addEventListener` are handled using `fn-start` on the
277
+ * `events` emitter.
278
+ * - When `xhr-resolved` is emitted, we end the node. The node.finish() call also
279
+ * instructs the interaction to stop waiting for this node.
280
+ */
281
+
282
+ // context is shared with new-xhr event, and is stored on the xhr iteself.
283
+ (0, _registerHandler.registerHandler)(FN_START, function () {
284
+ setCurrentNode(this[SPA_NODE]);
285
+ }, this.featureName, xhrEE);
286
+
287
+ // context is stored on the xhr and is shared with all callbacks associated
288
+ // with the new xhr
289
+ (0, _registerHandler.registerHandler)('new-xhr', function () {
290
+ if (!state.currentNode && state.prevInteraction && !state.prevInteraction.ignored) {
291
+ /*
292
+ * The previous interaction was discarded before a route change. Restore the interaction
293
+ * in case this XHR is associated with a route change.
294
+ */
295
+ const interaction = state.prevInteraction;
296
+ state.currentNode = interaction.root;
297
+ interaction.root.end = null;
298
+ }
299
+ if (state.currentNode) {
300
+ this[SPA_NODE] = state.currentNode.child('ajax', null, null, true);
301
+ }
302
+ }, this.featureName, xhrEE);
303
+ (0, _registerHandler.registerHandler)('send-xhr-start', function () {
304
+ var node = this[SPA_NODE];
305
+ if (node && !this.sent) {
306
+ this.sent = true;
307
+ node.dt = this.dt;
308
+ node.jsEnd = node.start = this.startTime;
309
+ node[INTERACTION][REMAINING]++;
310
+ }
311
+ }, this.featureName, xhrEE);
312
+ (0, _registerHandler.registerHandler)('xhr-resolved', function () {
313
+ var node = this[SPA_NODE];
314
+ if (node) {
315
+ if (!(0, _denyList.shouldCollectEvent)(this.params)) {
316
+ node.cancel();
317
+ return;
318
+ }
319
+ var attrs = node.attrs;
320
+ attrs.params = this.params;
321
+ attrs.metrics = this.metrics;
322
+ node.finish(this.endTime);
323
+ if (!!this.currentNode && !!this.currentNode.interaction) this.currentNode.interaction.checkFinish();
324
+ }
325
+ }, this.featureName, baseEE);
326
+
327
+ /**
328
+ * *** JSONP ***
329
+ *
330
+ */
331
+
332
+ (0, _registerHandler.registerHandler)('new-jsonp', function (url) {
333
+ if (state.currentNode) {
334
+ var node = this[JSONP_NODE] = state.currentNode.child('ajax', this[FETCH_START]);
335
+ node.start = this['new-jsonp'];
336
+ this.url = url;
337
+ this.status = null;
338
+ }
339
+ }, this.featureName, jsonpEE);
340
+ (0, _registerHandler.registerHandler)('cb-start', function (args) {
341
+ var node = this[JSONP_NODE];
342
+ if (node) {
343
+ setCurrentNode(node);
344
+ this.status = 200;
345
+ }
346
+ }, this.featureName, jsonpEE);
347
+ (0, _registerHandler.registerHandler)('jsonp-error', function () {
348
+ var node = this[JSONP_NODE];
349
+ if (node) {
350
+ setCurrentNode(node);
351
+ this.status = 0;
352
+ }
353
+ }, this.featureName, jsonpEE);
354
+ (0, _registerHandler.registerHandler)(JSONP_END, function () {
355
+ var node = this[JSONP_NODE];
356
+ if (node) {
357
+ // if no status is set then cb never fired - so it's not a valid JSONP
358
+ if (this.status === null) {
359
+ node.cancel();
360
+ return;
361
+ }
362
+ var attrs = node.attrs;
363
+ var params = attrs.params = {};
364
+ var parsed = (0, _parseUrl.parseUrl)(this.url);
365
+ params.method = 'GET';
366
+ params.pathname = parsed.pathname;
367
+ params.host = parsed.hostname + ':' + parsed.port;
368
+ params.status = this.status;
369
+ attrs.metrics = {
370
+ txSize: 0,
371
+ rxSize: 0
372
+ };
373
+ attrs.isJSONP = true;
374
+ node.jsEnd = this[JSONP_END];
375
+ node.jsTime = this[CB_START] ? this[JSONP_END] - this[CB_START] : 0;
376
+ node.finish(node.jsEnd);
377
+ }
378
+ }, this.featureName, jsonpEE);
379
+ (0, _registerHandler.registerHandler)(FETCH_START, function (fetchArguments, dtPayload) {
380
+ if (fetchArguments) {
381
+ if (!state.currentNode && state.prevInteraction && !state.prevInteraction.ignored) {
382
+ /*
383
+ * The previous interaction was discarded before a route change. Restore the interaction
384
+ * in case this XHR is associated with a route change.
385
+ */
386
+ const interaction = state.prevInteraction;
387
+ state.currentNode = interaction.root;
388
+ interaction.root.end = null;
389
+ }
390
+ if (state.currentNode) {
391
+ this[SPA_NODE] = state.currentNode.child('ajax', this[FETCH_START]);
392
+ if (dtPayload && this[SPA_NODE]) this[SPA_NODE].dt = dtPayload;
393
+ }
394
+ }
395
+ }, this.featureName, fetchEE);
396
+ (0, _registerHandler.registerHandler)(FETCH_BODY + 'start', function (args) {
397
+ if (state.currentNode) {
398
+ this[SPA_NODE] = state.currentNode;
399
+ state.currentNode[INTERACTION][REMAINING]++;
400
+ }
401
+ }, this.featureName, fetchEE);
402
+ (0, _registerHandler.registerHandler)(FETCH_BODY + 'end', function (args, ctx, bodyPromise) {
403
+ var node = this[SPA_NODE];
404
+ if (node) node[INTERACTION][REMAINING]--;
405
+ }, this.featureName, fetchEE);
406
+ (0, _registerHandler.registerHandler)(FETCH_DONE, function (err, res) {
407
+ var node = this[SPA_NODE];
408
+ if (node) {
409
+ if (err) {
410
+ node.cancel();
411
+ return;
412
+ }
413
+ var attrs = node.attrs;
414
+ attrs.params = this.params;
415
+ attrs.metrics = {
416
+ txSize: this.txSize,
417
+ rxSize: this.rxSize
418
+ };
419
+ attrs.isFetch = true;
420
+ node.finish(this[FETCH_DONE]);
421
+ }
422
+ }, this.featureName, fetchEE);
423
+ (0, _registerHandler.registerHandler)('newURL', function (url, hashChangedDuringCb) {
424
+ if (state.currentNode) {
425
+ state.currentNode[INTERACTION].setNewURL(url);
426
+ } else if (state.prevInteraction && !state.prevInteraction.ignored) {
427
+ /*
428
+ * The previous interaction was discarded before the route was changed. This can happen in SPA
429
+ * frameworks when using lazy loading. We have also seen this in version 11+ of Nextjs where
430
+ * some route changes re-use cached resolved promises.
431
+ */
432
+ const interaction = state.prevInteraction;
433
+ interaction.setNewURL(url);
434
+ interaction.root.end = null;
435
+ setCurrentNode(interaction.root);
436
+ }
437
+ if (state.currentNode) {
438
+ if (state.lastSeenUrl !== url) {
439
+ state.currentNode[INTERACTION].routeChange = true;
440
+ }
441
+ if (hashChangedDuringCb) {
442
+ state.nodeOnLastHashUpdate = state.currentNode;
443
+ }
444
+ }
445
+ state.lastSeenUrl = url;
446
+ }, this.featureName, historyEE);
447
+
448
+ /**
449
+ * SCRIPTS
450
+ * This is only needed to keep the interaction open while external scripts are being loaded.
451
+ * The script that is loaded could continue the interaction by making additional AJAX
452
+ * calls or changing the URL. The interaction context (currentNode) needs to be
453
+ * restored somehow, but this differs based on the specific customer code. In some cases, we
454
+ * could wrap a JSONP callback, in other cases we could wrap a higher-level API, and in
455
+ * some cases we may not be able to restore context automatically (customer would need
456
+ * to instrument their code manually).
457
+ *
458
+ * - We do not restore the original context in the load/error callbacks. This would not
459
+ * work for the scripts themselves because by the time the load event fires, the
460
+ * script content has already been executed.
461
+ */
462
+
463
+ // dom-start is emitted when appendChild or replaceChild are called. If the element being
464
+ // inserted is script and we are inside an interaction, we will keep the interaction open
465
+ // until the script is loaded.
466
+ jsonpEE.on('dom-start', function (args) {
467
+ if (!state.currentNode) return;
468
+ var el = args[0];
469
+ var isScript = el && el.nodeName === 'SCRIPT' && el.src !== '';
470
+ var interaction = state.currentNode.interaction;
471
+ if (isScript) {
472
+ // increase remaining count to keep the interaction open
473
+ interaction[REMAINING]++;
474
+ el.addEventListener('load', onload, (0, _eventListenerOpts.eventListenerOpts)(false));
475
+ el.addEventListener('error', onerror, (0, _eventListenerOpts.eventListenerOpts)(false));
476
+ }
477
+ function onload() {
478
+ // decrease remaining to allow interaction to finish
479
+ interaction[REMAINING]--;
480
+
481
+ // checkFinish is what initiates closing interaction, but is only called
482
+ // when setCurrentNode is called. Since we are not restoring a node here,
483
+ // we need to initiate the check manually.
484
+ // The reason we are not restoring the node here is because 1) this is not
485
+ // where the code of the external script runs (by the time the load event
486
+ // fires, it has already executed), and 2) it would require storing the context
487
+ // probably on the DOM node and restoring in all callbacks, which is a different
488
+ // use case than lazy loading.
489
+ interaction.checkFinish();
490
+ }
491
+ function onerror() {
492
+ interaction[REMAINING]--;
493
+ interaction.checkFinish();
494
+ }
495
+ });
496
+ (0, _registerHandler.registerHandler)(FN_START, function () {
497
+ setCurrentNode(state.prevNode);
498
+ }, this.featureName, mutationEE);
499
+ (0, _registerHandler.registerHandler)('resolve-start', resolvePromise, this.featureName, promiseEE);
500
+ (0, _registerHandler.registerHandler)('executor-err', resolvePromise, this.featureName, promiseEE);
501
+ (0, _registerHandler.registerHandler)('propagate', saveNode, this.featureName, promiseEE);
502
+ (0, _registerHandler.registerHandler)(CB_START, function () {
503
+ var ctx = this.getCtx ? this.getCtx() : this;
504
+ setCurrentNode(ctx[SPA_NODE]);
505
+ }, this.featureName, promiseEE);
506
+ (0, _registerHandler.registerHandler)(INTERACTION_API + 'get', function (t) {
507
+ var interaction;
508
+ if (state?.currentNode?.[INTERACTION]) interaction = this.ixn = state.currentNode[INTERACTION];else if (state?.prevNode?.end === null && state?.prevNode?.[INTERACTION]?.root?.[INTERACTION]?.eventName != 'initialPageLoad') interaction = this.ixn = state.prevNode[INTERACTION];else interaction = this.ixn = new _interaction.Interaction('api', t, state.lastSeenUrl, state.lastSeenRouteName, onInteractionFinished, agentIdentifier);
509
+ if (!state.currentNode) {
510
+ interaction.checkFinish();
511
+ if (state.depth) setCurrentNode(interaction.root);
512
+ }
513
+ }, this.featureName, baseEE);
514
+ (0, _registerHandler.registerHandler)(INTERACTION_API + 'actionText', function (t, actionText) {
515
+ var customAttrs = this.ixn.root.attrs.custom;
516
+ if (actionText) customAttrs.actionText = actionText;
517
+ }, this.featureName, baseEE);
518
+ (0, _registerHandler.registerHandler)(INTERACTION_API + 'setName', function (t, name, trigger) {
519
+ var attrs = this.ixn.root.attrs;
520
+ if (name) attrs.customName = name;
521
+ if (trigger) attrs.trigger = trigger;
522
+ }, this.featureName, baseEE);
523
+ (0, _registerHandler.registerHandler)(INTERACTION_API + 'setAttribute', function (t, name, value) {
524
+ this.ixn.root.attrs.custom[name] = value;
525
+ }, this.featureName, baseEE);
526
+ (0, _registerHandler.registerHandler)(INTERACTION_API + 'end', function (timestamp) {
527
+ var interaction = this.ixn;
528
+ var node = activeNodeFor(interaction);
529
+ setCurrentNode(null);
530
+ node.child('customEnd', timestamp).finish(timestamp);
531
+ interaction.finish();
532
+ }, this.featureName, baseEE);
533
+ (0, _registerHandler.registerHandler)(INTERACTION_API + 'ignore', function (t) {
534
+ this.ixn.ignored = true;
535
+ }, this.featureName, baseEE);
536
+ (0, _registerHandler.registerHandler)(INTERACTION_API + 'save', function (t) {
537
+ this.ixn.save = true;
538
+ }, this.featureName, baseEE);
539
+ (0, _registerHandler.registerHandler)(INTERACTION_API + 'tracer', function (timestamp, name, store) {
540
+ var interaction = this.ixn;
541
+ var parent = activeNodeFor(interaction);
542
+ var ctx = baseEE.context(store);
543
+ if (!name) {
544
+ ctx.inc = ++interaction[REMAINING];
545
+ return ctx[SPA_NODE] = parent;
546
+ }
547
+ ctx[SPA_NODE] = parent.child('customTracer', timestamp, name);
548
+ }, this.featureName, baseEE);
549
+ (0, _registerHandler.registerHandler)(FN_START, tracerDone, this.featureName, tracerEE);
550
+ (0, _registerHandler.registerHandler)('no-' + FN_START, tracerDone, this.featureName, tracerEE);
551
+ function tracerDone(timestamp, interactionContext, hasCb) {
552
+ var node = this[SPA_NODE];
553
+ if (!node) return;
554
+ var interaction = node[INTERACTION];
555
+ var inc = this.inc;
556
+ this.isTraced = true;
557
+ if (inc) {
558
+ interaction[REMAINING]--;
559
+ } else if (node) {
560
+ node.finish(timestamp);
561
+ }
562
+ hasCb ? setCurrentNode(node) : interaction.checkFinish();
563
+ }
564
+ (0, _registerHandler.registerHandler)(INTERACTION_API + 'getContext', function (t, cb) {
565
+ var store = this.ixn.root.attrs.store;
566
+ setTimeout(function () {
567
+ cb(store);
568
+ }, 0);
569
+ }, this.featureName, baseEE);
570
+ (0, _registerHandler.registerHandler)(INTERACTION_API + 'onEnd', function (t, cb) {
571
+ this.ixn.handlers.push(cb);
572
+ }, this.featureName, baseEE);
573
+ (0, _registerHandler.registerHandler)('api-routeName', function (t, currentRouteName) {
574
+ state.lastSeenRouteName = currentRouteName;
575
+ if (state.currentNode) state.currentNode[INTERACTION].setNewRoute(currentRouteName);
576
+ }, this.featureName, baseEE);
577
+ function activeNodeFor(interaction) {
578
+ return state.currentNode && state.currentNode[INTERACTION] === interaction ? state.currentNode : interaction.root;
579
+ }
580
+ function saveNode(val, overwrite) {
581
+ if (overwrite || !this[SPA_NODE]) this[SPA_NODE] = state.currentNode;
582
+ }
583
+ function resolvePromise() {
584
+ if (!this.resolved) {
585
+ this.resolved = true;
586
+ this[SPA_NODE] = state.currentNode;
587
+ }
588
+ }
589
+ function getCurrentNode() {
590
+ return state.currentNode;
591
+ }
592
+ function setCurrentNode(newNode) {
593
+ if (!state.pageLoaded && !newNode && state.initialPageLoad) newNode = state.initialPageLoad.root;
594
+ if (state.currentNode) {
595
+ state.currentNode[INTERACTION].checkFinish();
596
+ }
597
+ state.prevNode = state.currentNode;
598
+ state.currentNode = newNode && !newNode[INTERACTION].root.end ? newNode : null;
599
+ }
600
+ function onInteractionFinished(interaction) {
601
+ if (interaction === state.initialPageLoad) state.initialPageLoad = null;
602
+ var root = interaction.root;
603
+ var attrs = root.attrs;
604
+
605
+ // make sure that newrelic[INTERACTION]() works in end handler
606
+ state.currentNode = root;
607
+ (0, _mapOwn.mapOwn)(interaction.handlers, function (i, cb) {
608
+ cb(attrs.store);
609
+ });
610
+ setCurrentNode(null);
611
+ }
612
+ function onHarvestStarted(options) {
613
+ if (state.interactionsToHarvest.length === 0 || blocked) return {};
614
+ var payload = serializer.serializeMultiple(state.interactionsToHarvest, 0, _navTiming.navTimingValues);
615
+ if (options.retry) {
616
+ state.interactionsToHarvest.forEach(function (interaction) {
617
+ state.interactionsSent.push(interaction);
618
+ });
619
+ }
620
+ state.interactionsToHarvest = [];
621
+ return {
622
+ body: {
623
+ e: payload
624
+ }
625
+ };
626
+ }
627
+ function onHarvestFinished(result) {
628
+ if (result.sent && result.retry && state.interactionsSent.length > 0) {
629
+ state.interactionsSent.forEach(function (interaction) {
630
+ state.interactionsToHarvest.push(interaction);
631
+ });
632
+ state.interactionsSent = [];
633
+ }
634
+ }
635
+ baseEE.on('errorAgg', function (type, name, params, metrics) {
636
+ if (!state.currentNode) return;
637
+ params._interactionId = state.currentNode.interaction.id;
638
+ // do not capture parentNodeId when in root node
639
+ if (state.currentNode.type && state.currentNode.type !== 'interaction') {
640
+ params._interactionNodeId = state.currentNode.id;
641
+ }
642
+ });
643
+ baseEE.on('interaction', saveInteraction);
644
+ function getActionText(node) {
645
+ var nodeType = node.tagName.toLowerCase();
646
+ var goodNodeTypes = ['a', 'button', 'input'];
647
+ var isGoodNode = goodNodeTypes.indexOf(nodeType) !== -1;
648
+ if (isGoodNode) {
649
+ return node.title || node.value || node.innerText;
650
+ }
651
+ }
652
+ function saveInteraction(interaction) {
653
+ if (interaction.ignored || !interaction.save && !interaction.routeChange) {
654
+ baseEE.emit('interactionDiscarded', [interaction]);
655
+ return;
656
+ }
657
+ if (state.prevInteraction === interaction) {
658
+ // If the interaction is being saved, remove it from prevInteraction variable
659
+ // to prevent the interaction from possibly being sent twice or causing an internal
660
+ // recursive loop issue.
661
+ state.prevInteraction = null;
662
+ }
663
+
664
+ // assign unique id, this is serialized and used to link interactions with errors
665
+ interaction.root.attrs.id = (0, _uniqueId.generateUuid)();
666
+ if (interaction.root.attrs.trigger === 'initialPageLoad') {
667
+ interaction.root.attrs.firstPaint = _paintMetrics.paintMetrics['first-paint'];
668
+ interaction.root.attrs.firstContentfulPaint = _paintMetrics.paintMetrics['first-contentful-paint'];
669
+ }
670
+ baseEE.emit('interactionSaved', [interaction]);
671
+ state.interactionsToHarvest.push(interaction);
672
+ scheduler.scheduleHarvest(0);
673
+ }
674
+ function isEnabled() {
675
+ var enabled = (0, _config.getConfigurationValue)(agentIdentifier, 'spa.enabled');
676
+ if (enabled === false) {
677
+ return false;
678
+ }
679
+ return true;
680
+ }
681
+ (0, _drain.drain)(this.agentIdentifier, this.featureName);
682
+ }
683
+ }
684
+ exports.Aggregate = Aggregate;