@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,330 @@
1
+ /*
2
+ * Copyright 2020 New Relic Corporation. All rights reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+ import { originals, getLoaderConfig, getRuntime } from '../../../common/config/config';
6
+ import { handle } from '../../../common/event-emitter/handle';
7
+ import { id } from '../../../common/ids/id';
8
+ import { ffVersion } from '../../../common/browser-version/firefox-version';
9
+ import { dataSize } from '../../../common/util/data-size';
10
+ import { eventListenerOpts } from '../../../common/event-listener/event-listener-opts';
11
+ import { now } from '../../../common/timing/now';
12
+ import { wrapFetch, wrapXhr } from '../../../common/wrap';
13
+ import { parseUrl } from '../../../common/url/parse-url';
14
+ import { DT } from './distributed-tracing';
15
+ import { responseSizeFromXhr } from './response-size';
16
+ import { InstrumentBase } from '../../utils/instrument-base';
17
+ import { FEATURE_NAME } from '../constants';
18
+ import { FEATURE_NAMES } from '../../../loaders/features/features';
19
+ import { globalScope } from '../../../common/util/global-scope';
20
+ var handlers = ['load', 'error', 'abort', 'timeout'];
21
+ var handlersLen = handlers.length;
22
+ var origRequest = originals.REQ;
23
+ var origXHR = globalScope.XMLHttpRequest;
24
+ export class Instrument extends InstrumentBase {
25
+ static featureName = FEATURE_NAME;
26
+ constructor(agentIdentifier, aggregator, auto = true) {
27
+ super(agentIdentifier, aggregator, FEATURE_NAME, auto);
28
+
29
+ // Very unlikely, but in case the existing XMLHttpRequest.prototype object on the page couldn't be wrapped.
30
+ if (!getRuntime(agentIdentifier).xhrWrappable) return;
31
+ this.dt = new DT(agentIdentifier);
32
+ this.handler = (type, args, ctx, group) => handle(type, args, ctx, group, this.ee);
33
+ wrapFetch(this.ee);
34
+ wrapXhr(this.ee);
35
+ subscribeToEvents(agentIdentifier, this.ee, this.handler, this.dt);
36
+ this.importAggregator();
37
+ }
38
+ }
39
+ function subscribeToEvents(agentIdentifier, ee, handler, dt) {
40
+ ee.on('new-xhr', onNewXhr);
41
+ ee.on('open-xhr-start', onOpenXhrStart);
42
+ ee.on('open-xhr-end', onOpenXhrEnd);
43
+ ee.on('send-xhr-start', onSendXhrStart);
44
+ ee.on('xhr-cb-time', onXhrCbTime);
45
+ ee.on('xhr-load-added', onXhrLoadAdded);
46
+ ee.on('xhr-load-removed', onXhrLoadRemoved);
47
+ ee.on('xhr-resolved', onXhrResolved);
48
+ ee.on('addEventListener-end', onAddEventListenerEnd);
49
+ ee.on('removeEventListener-end', onRemoveEventListenerEnd);
50
+ ee.on('fn-end', onFnEnd);
51
+ ee.on('fetch-before-start', onFetchBeforeStart);
52
+ ee.on('fetch-start', onFetchStart);
53
+ ee.on('fn-start', onFnStart);
54
+ ee.on('fetch-done', onFetchDone);
55
+
56
+ // Setup the context for each new xhr object
57
+ function onNewXhr(xhr) {
58
+ var ctx = this;
59
+ ctx.totalCbs = 0;
60
+ ctx.called = 0;
61
+ ctx.cbTime = 0;
62
+ ctx.end = end;
63
+ ctx.ended = false;
64
+ ctx.xhrGuids = {};
65
+ ctx.lastSize = null;
66
+ ctx.loadCaptureCalled = false;
67
+ ctx.params = this.params || {};
68
+ ctx.metrics = this.metrics || {};
69
+ xhr.addEventListener('load', function (event) {
70
+ captureXhrData(ctx, xhr);
71
+ }, eventListenerOpts(false));
72
+
73
+ // In Firefox (v34+), XHR ProgressEvents report pre-content-decoding sizes via
74
+ // their 'loaded' property, rather than post-decoding sizes. We want
75
+ // post-decoding sizes for consistency with browsers where that's all we have.
76
+ // See: https://bugzilla.mozilla.org/show_bug.cgi?id=1227674
77
+ //
78
+ // So we don't use ProgressEvents to measure XHR sizes for FF.
79
+ if (ffVersion) return;
80
+ xhr.addEventListener('progress', function (event) {
81
+ ctx.lastSize = event.loaded;
82
+ }, eventListenerOpts(false));
83
+ }
84
+ function onOpenXhrStart(args) {
85
+ this.params = {
86
+ method: args[0]
87
+ };
88
+ addUrl(this, args[1]);
89
+ this.metrics = {};
90
+ }
91
+ function onOpenXhrEnd(args, xhr) {
92
+ var loader_config = getLoaderConfig(agentIdentifier);
93
+ if ('xpid' in loader_config && this.sameOrigin) {
94
+ xhr.setRequestHeader('X-NewRelic-ID', loader_config.xpid);
95
+ }
96
+ var payload = dt.generateTracePayload(this.parsedOrigin);
97
+ if (payload) {
98
+ var added = false;
99
+ if (payload.newrelicHeader) {
100
+ xhr.setRequestHeader('newrelic', payload.newrelicHeader);
101
+ added = true;
102
+ }
103
+ if (payload.traceContextParentHeader) {
104
+ xhr.setRequestHeader('traceparent', payload.traceContextParentHeader);
105
+ if (payload.traceContextStateHeader) {
106
+ xhr.setRequestHeader('tracestate', payload.traceContextStateHeader);
107
+ }
108
+ added = true;
109
+ }
110
+ if (added) {
111
+ this.dt = payload;
112
+ }
113
+ }
114
+ }
115
+ function onSendXhrStart(args, xhr) {
116
+ var metrics = this.metrics;
117
+ var data = args[0];
118
+ var context = this;
119
+ if (metrics && data) {
120
+ var size = dataSize(data);
121
+ if (size) metrics.txSize = size;
122
+ }
123
+ this.startTime = now();
124
+ this.listener = function (evt) {
125
+ try {
126
+ if (evt.type === 'abort' && !context.loadCaptureCalled) {
127
+ context.params.aborted = true;
128
+ }
129
+ if (evt.type !== 'load' || context.called === context.totalCbs && (context.onloadCalled || typeof xhr.onload !== 'function') && typeof context.end === 'function') context.end(xhr);
130
+ } catch (e) {
131
+ try {
132
+ ee.emit('internal-error', [e]);
133
+ } catch (err) {
134
+ // do nothing
135
+ }
136
+ }
137
+ };
138
+ for (var i = 0; i < handlersLen; i++) {
139
+ xhr.addEventListener(handlers[i], this.listener, eventListenerOpts(false));
140
+ }
141
+ }
142
+ function onXhrCbTime(time, onload, xhr) {
143
+ this.cbTime += time;
144
+ if (onload) this.onloadCalled = true;else this.called += 1;
145
+ if (this.called === this.totalCbs && (this.onloadCalled || typeof xhr.onload !== 'function') && typeof this.end === 'function') this.end(xhr);
146
+ }
147
+ function onXhrLoadAdded(cb, useCapture) {
148
+ // Ignore if the same arguments are passed to addEventListener twice
149
+ var idString = '' + id(cb) + !!useCapture;
150
+ if (!this.xhrGuids || this.xhrGuids[idString]) return;
151
+ this.xhrGuids[idString] = true;
152
+ this.totalCbs += 1;
153
+ }
154
+ function onXhrLoadRemoved(cb, useCapture) {
155
+ // Ignore if event listener didn't exist for this xhr object
156
+ var idString = '' + id(cb) + !!useCapture;
157
+ if (!this.xhrGuids || !this.xhrGuids[idString]) return;
158
+ delete this.xhrGuids[idString];
159
+ this.totalCbs -= 1;
160
+ }
161
+ function onXhrResolved() {
162
+ this.endTime = now();
163
+ }
164
+
165
+ // Listen for load listeners to be added to xhr objects
166
+ function onAddEventListenerEnd(args, xhr) {
167
+ if (xhr instanceof origXHR && args[0] === 'load') ee.emit('xhr-load-added', [args[1], args[2]], xhr);
168
+ }
169
+ function onRemoveEventListenerEnd(args, xhr) {
170
+ if (xhr instanceof origXHR && args[0] === 'load') ee.emit('xhr-load-removed', [args[1], args[2]], xhr);
171
+ }
172
+
173
+ // Listen for those load listeners to be called.
174
+ function onFnStart(args, xhr, methodName) {
175
+ if (xhr instanceof origXHR) {
176
+ if (methodName === 'onload') this.onload = true;
177
+ if ((args[0] && args[0].type) === 'load' || this.onload) this.xhrCbStart = now();
178
+ }
179
+ }
180
+ function onFnEnd(args, xhr) {
181
+ if (this.xhrCbStart) ee.emit('xhr-cb-time', [now() - this.xhrCbStart, this.onload, xhr], xhr);
182
+ }
183
+
184
+ // this event only handles DT
185
+ function onFetchBeforeStart(args) {
186
+ var opts = args[1] || {};
187
+ var url;
188
+ // argument is USVString
189
+ if (typeof args[0] === 'string') {
190
+ url = args[0];
191
+ // argument is Request object
192
+ } else if (args[0] && args[0].url) {
193
+ url = args[0].url;
194
+ // argument is URL object
195
+ } else if (globalScope?.URL && args[0] && args[0] instanceof URL) {
196
+ url = args[0].href;
197
+ }
198
+ if (url) {
199
+ this.parsedOrigin = parseUrl(url);
200
+ this.sameOrigin = this.parsedOrigin.sameOrigin;
201
+ }
202
+ var payload = dt.generateTracePayload(this.parsedOrigin);
203
+ if (!payload || !payload.newrelicHeader && !payload.traceContextParentHeader) {
204
+ return;
205
+ }
206
+ if (typeof args[0] === 'string' || globalScope?.URL && args[0] && args[0] instanceof URL) {
207
+ var clone = {};
208
+ for (var key in opts) {
209
+ clone[key] = opts[key];
210
+ }
211
+ clone.headers = new Headers(opts.headers || {});
212
+ if (addHeaders(clone.headers, payload)) {
213
+ this.dt = payload;
214
+ }
215
+ if (args.length > 1) {
216
+ args[1] = clone;
217
+ } else {
218
+ args.push(clone);
219
+ }
220
+ } else if (args[0] && args[0].headers) {
221
+ if (addHeaders(args[0].headers, payload)) {
222
+ this.dt = payload;
223
+ }
224
+ }
225
+ function addHeaders(headersObj, payload) {
226
+ var added = false;
227
+ if (payload.newrelicHeader) {
228
+ headersObj.set('newrelic', payload.newrelicHeader);
229
+ added = true;
230
+ }
231
+ if (payload.traceContextParentHeader) {
232
+ headersObj.set('traceparent', payload.traceContextParentHeader);
233
+ if (payload.traceContextStateHeader) {
234
+ headersObj.set('tracestate', payload.traceContextStateHeader);
235
+ }
236
+ added = true;
237
+ }
238
+ return added;
239
+ }
240
+ }
241
+ function onFetchStart(fetchArguments, dtPayload) {
242
+ this.params = {};
243
+ this.metrics = {};
244
+ this.startTime = now();
245
+ this.dt = dtPayload;
246
+ if (fetchArguments.length >= 1) this.target = fetchArguments[0];
247
+ if (fetchArguments.length >= 2) this.opts = fetchArguments[1];
248
+ var opts = this.opts || {};
249
+ var target = this.target;
250
+ var url;
251
+ if (typeof target === 'string') {
252
+ url = target;
253
+ } else if (typeof target === 'object' && target instanceof origRequest) {
254
+ url = target.url;
255
+ } else if (globalScope?.URL && typeof target === 'object' && target instanceof URL) {
256
+ url = target.href;
257
+ }
258
+ addUrl(this, url);
259
+ var method = ('' + (target && target instanceof origRequest && target.method || opts.method || 'GET')).toUpperCase();
260
+ this.params.method = method;
261
+ this.txSize = dataSize(opts.body) || 0;
262
+ }
263
+
264
+ // we capture failed call as status 0, the actual error is ignored
265
+ // eslint-disable-next-line handle-callback-err
266
+ function onFetchDone(err, res) {
267
+ this.endTime = now();
268
+ if (!this.params) {
269
+ this.params = {};
270
+ }
271
+ this.params.status = res ? res.status : 0;
272
+
273
+ // convert rxSize to a number
274
+ var responseSize;
275
+ if (typeof this.rxSize === 'string' && this.rxSize.length > 0) {
276
+ responseSize = +this.rxSize;
277
+ }
278
+ var metrics = {
279
+ txSize: this.txSize,
280
+ rxSize: responseSize,
281
+ duration: now() - this.startTime
282
+ };
283
+ handler('xhr', [this.params, metrics, this.startTime, this.endTime, 'fetch'], this, FEATURE_NAMES.ajax);
284
+ }
285
+
286
+ // Create report for XHR request that has finished
287
+ function end(xhr) {
288
+ var params = this.params;
289
+ var metrics = this.metrics;
290
+ if (this.ended) return;
291
+ this.ended = true;
292
+ for (var i = 0; i < handlersLen; i++) {
293
+ xhr.removeEventListener(handlers[i], this.listener, false);
294
+ }
295
+ if (params.aborted) return;
296
+ metrics.duration = now() - this.startTime;
297
+ if (!this.loadCaptureCalled && xhr.readyState === 4) {
298
+ captureXhrData(this, xhr);
299
+ } else if (params.status == null) {
300
+ params.status = 0;
301
+ }
302
+
303
+ // Always send cbTime, even if no noticeable time was taken.
304
+ metrics.cbTime = this.cbTime;
305
+ handler('xhr', [params, metrics, this.startTime, this.endTime, 'xhr'], this, FEATURE_NAMES.ajax);
306
+ }
307
+ function addUrl(ctx, url) {
308
+ var parsed = parseUrl(url);
309
+ var params = ctx.params;
310
+ params.hostname = parsed.hostname;
311
+ params.port = parsed.port;
312
+ params.protocol = parsed.protocol;
313
+ params.host = parsed.hostname + ':' + parsed.port;
314
+ params.pathname = parsed.pathname;
315
+ ctx.parsedOrigin = parsed;
316
+ ctx.sameOrigin = parsed.sameOrigin;
317
+ }
318
+ function captureXhrData(ctx, xhr) {
319
+ ctx.params.status = xhr.status;
320
+ var size = responseSizeFromXhr(xhr, ctx.lastSize);
321
+ if (size) ctx.metrics.rxSize = size;
322
+ if (ctx.sameOrigin) {
323
+ var header = xhr.getResponseHeader('X-NewRelic-App-Data');
324
+ if (header) {
325
+ ctx.params.cat = header.split(', ').pop();
326
+ }
327
+ }
328
+ ctx.loadCaptureCalled = true;
329
+ }
330
+ }
@@ -0,0 +1,19 @@
1
+ /*
2
+ * Copyright 2020 New Relic Corporation. All rights reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+ import { dataSize } from '../../../common/util/data-size';
6
+ export function responseSizeFromXhr(xhr, lastSize) {
7
+ var type = xhr.responseType;
8
+ if (type === 'json' && lastSize !== null) return lastSize;
9
+ // Caution! Chrome throws an error if you try to access xhr.responseText for binary data
10
+ if (type === 'arraybuffer' || type === 'blob' || type === 'json') {
11
+ return dataSize(xhr.response);
12
+ } else if (type === 'text' || type === '' || type === undefined) {
13
+ // empty string type defaults to 'text'
14
+ return dataSize(xhr.responseText);
15
+ } else {
16
+ // e.g. ms-stream and document (we do not currently determine the size of Document objects)
17
+ return undefined;
18
+ }
19
+ }
@@ -0,0 +1,12 @@
1
+ /*
2
+ * Copyright 2020 New Relic Corporation. All rights reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+
6
+ var canonicalFunctionNameRe = /([a-z0-9]+)$/i;
7
+ export function canonicalFunctionName(orig) {
8
+ if (!orig) return;
9
+ var match = orig.match(canonicalFunctionNameRe);
10
+ if (match) return match[1];
11
+ return;
12
+ }
@@ -0,0 +1,28 @@
1
+ import { canonicalFunctionName } from './canonical-function-name';
2
+ test.each([{
3
+ input: null,
4
+ expected: undefined,
5
+ title: 'Return undefined if no function name'
6
+ }, {
7
+ input: 'test',
8
+ expected: 'test',
9
+ title: 'Simple function name'
10
+ }, {
11
+ input: 'scope1/scope2/func',
12
+ expected: 'func',
13
+ title: 'Remove Firefox scopes'
14
+ }, {
15
+ input: 'scope1.func',
16
+ expected: 'func',
17
+ title: 'Remove Chrome scopes'
18
+ }, {
19
+ input: '<anonymous>',
20
+ expected: undefined,
21
+ title: 'Return undefined ending is non-alphanumeric'
22
+ }])('$title', ({
23
+ input,
24
+ expected
25
+ }) => {
26
+ const result = canonicalFunctionName(input);
27
+ expect(result).toEqual(expected);
28
+ });
@@ -0,0 +1,209 @@
1
+ /*
2
+ * Copyright 2020 New Relic Corporation. All rights reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+
6
+ /* eslint-disable no-useless-escape */
7
+
8
+ // computeStackTrace: cross-browser stack traces in JavaScript
9
+ //
10
+ // Syntax:
11
+ // s = computeStackTrace(exception) // consider using TraceKit.report instead
12
+ // Returns:
13
+ // s.name - exception name
14
+ // s.message - exception message
15
+ // s.stack[i].url - JavaScript or HTML file URL
16
+ // s.stack[i].func - function name, or empty for anonymous functions
17
+ // s.stack[i].line - line number, if known
18
+ // s.stack[i].column - column number, if known
19
+ // s.stack[i].context - an array of source code lines; the middle element corresponds to the correct line#
20
+ // s.mode - 'stack', 'stacktrace', 'multiline', 'callers', 'onerror', or 'failed' -- method used to collect the stack trace
21
+ //
22
+ // Supports:
23
+ // - Firefox: full stack trace with line numbers and unreliable column
24
+ // number on top frame
25
+ // - Chrome: full stack trace with line and column numbers
26
+ // - Safari: line and column number for the topmost stacktrace element
27
+ // only
28
+ // - IE: no line numbers whatsoever
29
+
30
+ // Contents of Exception in various browsers.
31
+ //
32
+ // SAFARI:
33
+ // ex.message = Can't find variable: qq
34
+ // ex.line = 59
35
+ // ex.sourceId = 580238192
36
+ // ex.sourceURL = http://...
37
+ // ex.expressionBeginOffset = 96
38
+ // ex.expressionCaretOffset = 98
39
+ // ex.expressionEndOffset = 98
40
+ // ex.name = ReferenceError
41
+ //
42
+ // FIREFOX:
43
+ // ex.message = qq is not defined
44
+ // ex.fileName = http://...
45
+ // ex.lineNumber = 59
46
+ // ex.stack = ...stack trace... (see the example below)
47
+ // ex.name = ReferenceError
48
+ //
49
+ // CHROME:
50
+ // ex.message = qq is not defined
51
+ // ex.name = ReferenceError
52
+ // ex.type = not_defined
53
+ // ex.arguments = ['aa']
54
+ // ex.stack = ...stack trace...
55
+ //
56
+ // INTERNET EXPLORER:
57
+ // ex.message = ...
58
+ // ex.name = ReferenceError
59
+ import { reduce } from '../../../common/util/reduce';
60
+ import { formatStackTrace } from './format-stack-trace';
61
+ var debug = false;
62
+ var classNameRegex = /function (.+?)\s*\(/;
63
+ var chrome = /^\s*at (?:((?:\[object object\])?(?:[^(]*\([^)]*\))*[^()]*(?: \[as \S+\])?) )?\(?((?:file|http|https|chrome-extension):.*?)?:(\d+)(?::(\d+))?\)?\s*$/i;
64
+ var gecko = /^\s*(?:(\S*|global code)(?:\(.*?\))?@)?((?:file|http|https|chrome|safari-extension).*?):(\d+)(?::(\d+))?\s*$/i;
65
+ var chrome_eval = /^\s*at .+ \(eval at \S+ \((?:(?:file|http|https):[^)]+)?\)(?:, [^:]*:\d+:\d+)?\)$/i;
66
+ var ie_eval = /^\s*at Function code \(Function code:\d+:\d+\)\s*/i;
67
+ export function computeStackTrace(ex) {
68
+ var stack = null;
69
+ try {
70
+ stack = computeStackTraceFromStackProp(ex);
71
+ if (stack) {
72
+ return stack;
73
+ }
74
+ } catch (e) {
75
+ if (debug) {
76
+ throw e;
77
+ }
78
+ }
79
+ try {
80
+ stack = computeStackTraceBySourceAndLine(ex);
81
+ if (stack) {
82
+ return stack;
83
+ }
84
+ } catch (e) {
85
+ if (debug) {
86
+ throw e;
87
+ }
88
+ }
89
+ try {
90
+ stack = computeStackTraceWithMessageOnly(ex);
91
+ if (stack) {
92
+ return stack;
93
+ }
94
+ } catch (e) {
95
+ if (debug) {
96
+ throw e;
97
+ }
98
+ }
99
+ return {
100
+ mode: 'failed',
101
+ stackString: '',
102
+ frames: []
103
+ };
104
+ }
105
+
106
+ /**
107
+ * Computes stack trace information from the stack property.
108
+ * Chrome and Gecko use this property.
109
+ * @param {Error} ex
110
+ * @return {?Object.<string, *>} Stack trace information.
111
+ */
112
+ function computeStackTraceFromStackProp(ex) {
113
+ if (!ex.stack) {
114
+ return null;
115
+ }
116
+ var errorInfo = reduce(ex.stack.split('\n'), parseStackProp, {
117
+ frames: [],
118
+ stackLines: [],
119
+ wrapperSeen: false
120
+ });
121
+ if (!errorInfo.frames.length) return null;
122
+ return {
123
+ mode: 'stack',
124
+ name: ex.name || getClassName(ex),
125
+ message: ex.message,
126
+ stackString: formatStackTrace(errorInfo.stackLines),
127
+ frames: errorInfo.frames
128
+ };
129
+ }
130
+ function parseStackProp(info, line) {
131
+ var element = getElement(line);
132
+ if (!element) {
133
+ info.stackLines.push(line);
134
+ return info;
135
+ }
136
+ if (isWrapper(element.func)) info.wrapperSeen = true;else info.stackLines.push(line);
137
+ if (!info.wrapperSeen) info.frames.push(element);
138
+ return info;
139
+ }
140
+ function getElement(line) {
141
+ var parts = line.match(gecko);
142
+ if (!parts) parts = line.match(chrome);
143
+ if (parts) {
144
+ return {
145
+ url: parts[2],
146
+ func: parts[1] !== 'Anonymous function' && parts[1] !== 'global code' && parts[1] || null,
147
+ line: +parts[3],
148
+ column: parts[4] ? +parts[4] : null
149
+ };
150
+ }
151
+ if (line.match(chrome_eval) || line.match(ie_eval) || line === 'anonymous') {
152
+ return {
153
+ func: 'evaluated code'
154
+ };
155
+ }
156
+ }
157
+ function computeStackTraceBySourceAndLine(ex) {
158
+ if (!('line' in ex)) return null;
159
+ var className = ex.name || getClassName(ex);
160
+
161
+ // Safari does not provide a URL for errors in eval'd code
162
+ if (!ex.sourceURL) {
163
+ return {
164
+ mode: 'sourceline',
165
+ name: className,
166
+ message: ex.message,
167
+ stackString: getClassName(ex) + ': ' + ex.message + '\n in evaluated code',
168
+ frames: [{
169
+ func: 'evaluated code'
170
+ }]
171
+ };
172
+ }
173
+ var stackString = className + ': ' + ex.message + '\n at ' + ex.sourceURL;
174
+ if (ex.line) {
175
+ stackString += ':' + ex.line;
176
+ if (ex.column) {
177
+ stackString += ':' + ex.column;
178
+ }
179
+ }
180
+ return {
181
+ mode: 'sourceline',
182
+ name: className,
183
+ message: ex.message,
184
+ stackString: stackString,
185
+ frames: [{
186
+ url: ex.sourceURL,
187
+ line: ex.line,
188
+ column: ex.column
189
+ }]
190
+ };
191
+ }
192
+ function computeStackTraceWithMessageOnly(ex) {
193
+ var className = ex.name || getClassName(ex);
194
+ if (!className) return null;
195
+ return {
196
+ mode: 'nameonly',
197
+ name: className,
198
+ message: ex.message,
199
+ stackString: className + ': ' + ex.message,
200
+ frames: []
201
+ };
202
+ }
203
+ function getClassName(obj) {
204
+ var results = classNameRegex.exec(String(obj.constructor));
205
+ return results && results.length > 1 ? results[1] : 'unknown';
206
+ }
207
+ function isWrapper(functionName) {
208
+ return functionName && functionName.indexOf('nrWrapper') >= 0;
209
+ }