@newrelic/browser-agent 1.263.0 → 1.265.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (478) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/README.md +2 -2
  3. package/dist/cjs/cdn/experimental.js +3 -7
  4. package/dist/cjs/cdn/pro.js +2 -2
  5. package/dist/cjs/cdn/spa.js +2 -2
  6. package/dist/cjs/common/aggregate/aggregator.js +2 -3
  7. package/dist/cjs/common/config/{state/configurable.js → configurable.js} +1 -1
  8. package/dist/cjs/common/config/{state/info.js → info.js} +1 -1
  9. package/dist/cjs/common/config/{state/init.js → init.js} +11 -8
  10. package/dist/cjs/common/config/{state/loader-config.js → loader-config.js} +1 -1
  11. package/dist/cjs/common/config/{state/runtime.js → runtime.js} +16 -5
  12. package/dist/cjs/common/constants/agent-constants.js +8 -0
  13. package/dist/cjs/common/constants/env.cdn.js +1 -1
  14. package/dist/cjs/common/constants/env.npm.js +1 -1
  15. package/dist/cjs/common/constants/runtime.js +1 -3
  16. package/dist/cjs/common/context/shared-context.js +1 -2
  17. package/dist/cjs/common/dispatch/global-event.js +1 -2
  18. package/dist/cjs/common/drain/drain.js +12 -18
  19. package/dist/cjs/common/event-emitter/contextual-ee.js +3 -4
  20. package/dist/cjs/common/event-listener/event-listener-opts.js +2 -6
  21. package/dist/cjs/common/harvest/harvest-scheduler.js +1 -2
  22. package/dist/cjs/common/harvest/harvest.js +30 -57
  23. package/dist/cjs/common/serialize/bel-serializer.js +6 -11
  24. package/dist/cjs/common/session/session-entity.js +10 -13
  25. package/dist/cjs/common/timing/nav-timing.js +1 -3
  26. package/dist/cjs/common/timing/time-keeper.js +16 -6
  27. package/dist/cjs/common/url/encode.js +3 -7
  28. package/dist/cjs/common/util/console.js +2 -0
  29. package/dist/cjs/common/util/invoke.js +6 -16
  30. package/dist/cjs/common/util/obfuscate.js +97 -53
  31. package/dist/cjs/common/util/submit-data.js +17 -21
  32. package/dist/cjs/common/util/text.js +9 -0
  33. package/dist/cjs/common/util/traverse.js +1 -3
  34. package/dist/cjs/common/vitals/cumulative-layout-shift.js +5 -6
  35. package/dist/cjs/common/vitals/first-contentful-paint.js +4 -5
  36. package/dist/cjs/common/vitals/first-input-delay.js +4 -5
  37. package/dist/cjs/common/vitals/interaction-to-next-paint.js +5 -6
  38. package/dist/cjs/common/vitals/largest-contentful-paint.js +4 -5
  39. package/dist/cjs/common/vitals/time-to-first-byte.js +4 -5
  40. package/dist/cjs/common/vitals/vital-metric.js +5 -7
  41. package/dist/cjs/common/window/nreum.js +2 -1
  42. package/dist/cjs/common/window/page-visibility.js +1 -4
  43. package/dist/cjs/common/wrap/wrap-events.js +1 -4
  44. package/dist/cjs/common/wrap/wrap-promise.js +1 -4
  45. package/dist/cjs/common/wrap/wrap-websocket.js +74 -0
  46. package/dist/cjs/features/ajax/aggregate/chunk.js +4 -3
  47. package/dist/cjs/features/ajax/aggregate/gql.js +4 -5
  48. package/dist/cjs/features/ajax/aggregate/index.js +19 -22
  49. package/dist/cjs/features/ajax/constants.js +2 -3
  50. package/dist/cjs/features/ajax/instrument/distributed-tracing.js +9 -8
  51. package/dist/cjs/features/ajax/instrument/index.js +14 -12
  52. package/dist/cjs/features/generic_events/aggregate/index.js +128 -0
  53. package/dist/cjs/features/generic_events/constants.js +10 -0
  54. package/dist/cjs/features/generic_events/index.js +12 -0
  55. package/dist/cjs/features/generic_events/instrument/index.js +27 -0
  56. package/dist/cjs/features/jserrors/aggregate/index.js +25 -44
  57. package/dist/cjs/features/jserrors/instrument/index.js +4 -4
  58. package/dist/cjs/features/logging/aggregate/index.js +33 -36
  59. package/dist/cjs/features/logging/constants.js +2 -3
  60. package/dist/cjs/features/logging/instrument/index.js +5 -6
  61. package/dist/cjs/features/logging/shared/log.js +1 -3
  62. package/dist/cjs/features/logging/shared/utils.js +2 -4
  63. package/dist/cjs/features/metrics/aggregate/index.js +34 -17
  64. package/dist/cjs/features/metrics/aggregate/websocket-detection.js +34 -0
  65. package/dist/cjs/features/metrics/constants.js +4 -2
  66. package/dist/cjs/features/metrics/instrument/index.js +12 -4
  67. package/dist/cjs/features/page_action/instrument/index.js +14 -10
  68. package/dist/cjs/features/page_view_event/aggregate/index.js +19 -39
  69. package/dist/cjs/features/page_view_event/aggregate/initialized-features.js +1 -1
  70. package/dist/cjs/features/page_view_event/instrument/index.js +4 -4
  71. package/dist/cjs/features/page_view_timing/aggregate/index.js +23 -39
  72. package/dist/cjs/features/page_view_timing/instrument/index.js +4 -4
  73. package/dist/cjs/features/session_replay/aggregate/index.js +35 -42
  74. package/dist/cjs/features/session_replay/constants.js +1 -5
  75. package/dist/cjs/features/session_replay/instrument/index.js +5 -9
  76. package/dist/cjs/features/session_replay/shared/recorder-events.js +25 -20
  77. package/dist/cjs/features/session_replay/shared/recorder.js +17 -13
  78. package/dist/cjs/features/session_replay/shared/stylesheet-evaluator.js +2 -2
  79. package/dist/cjs/features/session_replay/shared/utils.js +5 -4
  80. package/dist/cjs/features/session_trace/aggregate/index.js +25 -42
  81. package/dist/cjs/features/session_trace/aggregate/trace/storage.js +5 -3
  82. package/dist/cjs/features/session_trace/instrument/index.js +8 -7
  83. package/dist/cjs/features/soft_navigations/aggregate/ajax-node.js +1 -1
  84. package/dist/cjs/features/soft_navigations/aggregate/index.js +22 -30
  85. package/dist/cjs/features/soft_navigations/aggregate/initial-page-load-interaction.js +2 -2
  86. package/dist/cjs/features/soft_navigations/aggregate/interaction.js +4 -5
  87. package/dist/cjs/features/soft_navigations/instrument/index.js +14 -13
  88. package/dist/cjs/features/spa/aggregate/index.js +17 -28
  89. package/dist/cjs/features/spa/aggregate/interaction.js +7 -6
  90. package/dist/cjs/features/spa/aggregate/serializer.js +4 -5
  91. package/dist/cjs/features/spa/constants.js +2 -2
  92. package/dist/cjs/features/spa/instrument/index.js +20 -19
  93. package/dist/cjs/features/utils/agent-session.js +6 -4
  94. package/dist/cjs/features/utils/aggregate-base.js +17 -10
  95. package/dist/cjs/features/utils/event-buffer.js +132 -0
  96. package/dist/cjs/features/utils/feature-gates.js +2 -2
  97. package/dist/cjs/features/utils/instrument-base.js +7 -8
  98. package/dist/cjs/features/utils/lazy-feature-loader.js +12 -12
  99. package/dist/cjs/features/utils/nr1-debugger.js +1 -3
  100. package/dist/cjs/index.js +21 -0
  101. package/dist/cjs/loaders/agent-base.js +4 -12
  102. package/dist/cjs/loaders/agent.js +7 -2
  103. package/dist/cjs/loaders/api/api.js +23 -35
  104. package/dist/cjs/loaders/api/apiAsync.js +10 -13
  105. package/dist/cjs/loaders/browser-agent.js +4 -3
  106. package/dist/cjs/loaders/configure/configure.js +16 -15
  107. package/dist/cjs/loaders/features/enabled-features.js +2 -2
  108. package/dist/cjs/loaders/features/features.js +8 -4
  109. package/dist/cjs/loaders/micro-agent.js +16 -15
  110. package/dist/esm/cdn/experimental.js +2 -5
  111. package/dist/esm/cdn/pro.js +2 -2
  112. package/dist/esm/cdn/spa.js +2 -2
  113. package/dist/esm/common/aggregate/aggregator.js +2 -3
  114. package/dist/esm/common/config/{state/configurable.js → configurable.js} +1 -1
  115. package/dist/esm/common/config/{state/info.js → info.js} +1 -1
  116. package/dist/esm/common/config/{state/init.js → init.js} +11 -8
  117. package/dist/esm/common/config/{state/loader-config.js → loader-config.js} +1 -1
  118. package/dist/esm/common/config/{state/runtime.js → runtime.js} +17 -5
  119. package/dist/esm/common/constants/agent-constants.js +2 -0
  120. package/dist/esm/common/constants/env.cdn.js +1 -1
  121. package/dist/esm/common/constants/env.npm.js +1 -1
  122. package/dist/esm/common/constants/runtime.js +0 -2
  123. package/dist/esm/common/context/shared-context.js +1 -2
  124. package/dist/esm/common/dispatch/global-event.js +1 -2
  125. package/dist/esm/common/drain/drain.js +12 -18
  126. package/dist/esm/common/event-emitter/contextual-ee.js +2 -3
  127. package/dist/esm/common/event-listener/event-listener-opts.js +2 -6
  128. package/dist/esm/common/harvest/harvest-scheduler.js +1 -2
  129. package/dist/esm/common/harvest/harvest.js +24 -51
  130. package/dist/esm/common/serialize/bel-serializer.js +6 -11
  131. package/dist/esm/common/session/session-entity.js +10 -13
  132. package/dist/esm/common/timing/nav-timing.js +1 -3
  133. package/dist/esm/common/timing/time-keeper.js +15 -5
  134. package/dist/esm/common/url/encode.js +3 -7
  135. package/dist/esm/common/util/console.js +2 -0
  136. package/dist/esm/common/util/invoke.js +6 -16
  137. package/dist/esm/common/util/obfuscate.js +96 -49
  138. package/dist/esm/common/util/submit-data.js +17 -21
  139. package/dist/esm/common/util/text.js +3 -0
  140. package/dist/esm/common/util/traverse.js +1 -3
  141. package/dist/esm/common/vitals/cumulative-layout-shift.js +5 -6
  142. package/dist/esm/common/vitals/first-contentful-paint.js +4 -5
  143. package/dist/esm/common/vitals/first-input-delay.js +4 -5
  144. package/dist/esm/common/vitals/interaction-to-next-paint.js +5 -6
  145. package/dist/esm/common/vitals/largest-contentful-paint.js +4 -5
  146. package/dist/esm/common/vitals/time-to-first-byte.js +4 -5
  147. package/dist/esm/common/vitals/vital-metric.js +5 -7
  148. package/dist/esm/common/window/nreum.js +2 -1
  149. package/dist/esm/common/window/page-visibility.js +1 -4
  150. package/dist/esm/common/wrap/wrap-events.js +1 -4
  151. package/dist/esm/common/wrap/wrap-promise.js +1 -4
  152. package/dist/esm/common/wrap/wrap-websocket.js +67 -0
  153. package/dist/esm/features/ajax/aggregate/chunk.js +3 -2
  154. package/dist/esm/features/ajax/aggregate/gql.js +4 -5
  155. package/dist/esm/features/ajax/aggregate/index.js +16 -19
  156. package/dist/esm/features/ajax/constants.js +1 -2
  157. package/dist/esm/features/ajax/instrument/distributed-tracing.js +2 -1
  158. package/dist/esm/features/ajax/instrument/index.js +10 -8
  159. package/dist/esm/features/generic_events/aggregate/index.js +120 -0
  160. package/dist/esm/features/generic_events/constants.js +4 -0
  161. package/dist/esm/features/generic_events/index.js +1 -0
  162. package/dist/esm/features/generic_events/instrument/index.js +20 -0
  163. package/dist/esm/features/jserrors/aggregate/index.js +20 -39
  164. package/dist/esm/features/jserrors/instrument/index.js +3 -3
  165. package/dist/esm/features/logging/aggregate/index.js +31 -34
  166. package/dist/esm/features/logging/constants.js +1 -2
  167. package/dist/esm/features/logging/instrument/index.js +4 -5
  168. package/dist/esm/features/logging/shared/log.js +1 -3
  169. package/dist/esm/features/logging/shared/utils.js +2 -4
  170. package/dist/esm/features/metrics/aggregate/index.js +28 -11
  171. package/dist/esm/features/metrics/aggregate/websocket-detection.js +29 -0
  172. package/dist/esm/features/metrics/constants.js +3 -1
  173. package/dist/esm/features/metrics/instrument/index.js +12 -4
  174. package/dist/esm/features/page_action/instrument/index.js +14 -9
  175. package/dist/esm/features/page_view_event/aggregate/index.js +17 -37
  176. package/dist/esm/features/page_view_event/aggregate/initialized-features.js +1 -1
  177. package/dist/esm/features/page_view_event/instrument/index.js +3 -3
  178. package/dist/esm/features/page_view_timing/aggregate/index.js +20 -36
  179. package/dist/esm/features/page_view_timing/instrument/index.js +3 -3
  180. package/dist/esm/features/session_replay/aggregate/index.js +25 -32
  181. package/dist/esm/features/session_replay/constants.js +0 -4
  182. package/dist/esm/features/session_replay/index.js +1 -7
  183. package/dist/esm/features/session_replay/instrument/index.js +5 -8
  184. package/dist/esm/features/session_replay/shared/recorder-events.js +25 -20
  185. package/dist/esm/features/session_replay/shared/recorder.js +14 -10
  186. package/dist/esm/features/session_replay/shared/stylesheet-evaluator.js +2 -2
  187. package/dist/esm/features/session_replay/shared/utils.js +3 -2
  188. package/dist/esm/features/session_trace/aggregate/index.js +20 -37
  189. package/dist/esm/features/session_trace/aggregate/trace/storage.js +5 -3
  190. package/dist/esm/features/session_trace/instrument/index.js +5 -4
  191. package/dist/esm/features/soft_navigations/aggregate/ajax-node.js +1 -1
  192. package/dist/esm/features/soft_navigations/aggregate/index.js +21 -29
  193. package/dist/esm/features/soft_navigations/aggregate/initial-page-load-interaction.js +1 -1
  194. package/dist/esm/features/soft_navigations/aggregate/interaction.js +2 -3
  195. package/dist/esm/features/soft_navigations/instrument/index.js +11 -10
  196. package/dist/esm/features/spa/aggregate/index.js +11 -22
  197. package/dist/esm/features/spa/aggregate/interaction.js +6 -5
  198. package/dist/esm/features/spa/aggregate/serializer.js +2 -3
  199. package/dist/esm/features/spa/constants.js +2 -2
  200. package/dist/esm/features/spa/instrument/index.js +12 -11
  201. package/dist/esm/features/utils/agent-session.js +3 -1
  202. package/dist/esm/features/utils/aggregate-base.js +16 -9
  203. package/dist/esm/features/utils/event-buffer.js +126 -0
  204. package/dist/esm/features/utils/feature-gates.js +1 -1
  205. package/dist/esm/features/utils/instrument-base.js +6 -7
  206. package/dist/esm/features/utils/lazy-feature-loader.js +12 -12
  207. package/dist/esm/features/utils/nr1-debugger.js +1 -3
  208. package/dist/esm/index.js +3 -0
  209. package/dist/esm/loaders/agent-base.js +4 -12
  210. package/dist/esm/loaders/agent.js +7 -2
  211. package/dist/esm/loaders/api/api.js +18 -30
  212. package/dist/esm/loaders/api/apiAsync.js +3 -6
  213. package/dist/esm/loaders/browser-agent.js +3 -2
  214. package/dist/esm/loaders/configure/configure.js +9 -8
  215. package/dist/esm/loaders/features/enabled-features.js +1 -1
  216. package/dist/esm/loaders/features/features.js +8 -4
  217. package/dist/esm/loaders/micro-agent.js +11 -10
  218. package/dist/types/common/aggregate/aggregator.d.ts.map +1 -1
  219. package/dist/types/common/config/configurable.d.ts.map +1 -0
  220. package/dist/types/common/config/info.d.ts.map +1 -0
  221. package/dist/types/common/config/init.d.ts.map +1 -0
  222. package/dist/types/common/config/loader-config.d.ts.map +1 -0
  223. package/dist/types/common/config/runtime.d.ts.map +1 -0
  224. package/dist/types/common/constants/agent-constants.d.ts +3 -0
  225. package/dist/types/common/constants/agent-constants.d.ts.map +1 -0
  226. package/dist/types/common/constants/runtime.d.ts +0 -1
  227. package/dist/types/common/constants/runtime.d.ts.map +1 -1
  228. package/dist/types/common/harvest/harvest.d.ts +1 -7
  229. package/dist/types/common/harvest/harvest.d.ts.map +1 -1
  230. package/dist/types/common/serialize/bel-serializer.d.ts.map +1 -1
  231. package/dist/types/common/timing/time-keeper.d.ts +9 -2
  232. package/dist/types/common/timing/time-keeper.d.ts.map +1 -1
  233. package/dist/types/common/url/encode.d.ts.map +1 -1
  234. package/dist/types/common/util/console.d.ts.map +1 -1
  235. package/dist/types/common/util/obfuscate.d.ts +78 -6
  236. package/dist/types/common/util/obfuscate.d.ts.map +1 -1
  237. package/dist/types/common/util/submit-data.d.ts.map +1 -1
  238. package/dist/types/common/util/text.d.ts +2 -0
  239. package/dist/types/common/util/text.d.ts.map +1 -0
  240. package/dist/types/common/window/nreum.d.ts.map +1 -1
  241. package/dist/types/common/wrap/wrap-websocket.d.ts +4 -0
  242. package/dist/types/common/wrap/wrap-websocket.d.ts.map +1 -0
  243. package/dist/types/features/ajax/aggregate/chunk.d.ts.map +1 -1
  244. package/dist/types/features/ajax/aggregate/index.d.ts +2 -3
  245. package/dist/types/features/ajax/aggregate/index.d.ts.map +1 -1
  246. package/dist/types/features/ajax/constants.d.ts +0 -1
  247. package/dist/types/features/ajax/constants.d.ts.map +1 -1
  248. package/dist/types/features/ajax/instrument/distributed-tracing.d.ts.map +1 -1
  249. package/dist/types/features/ajax/instrument/index.d.ts +1 -0
  250. package/dist/types/features/ajax/instrument/index.d.ts.map +1 -1
  251. package/dist/types/features/{page_action → generic_events}/aggregate/index.d.ts +10 -10
  252. package/dist/types/features/generic_events/aggregate/index.d.ts.map +1 -0
  253. package/dist/types/features/generic_events/constants.d.ts +4 -0
  254. package/dist/types/features/generic_events/constants.d.ts.map +1 -0
  255. package/dist/types/features/generic_events/index.d.ts +2 -0
  256. package/dist/types/features/generic_events/index.d.ts.map +1 -0
  257. package/dist/types/features/generic_events/instrument/index.d.ts +7 -0
  258. package/dist/types/features/generic_events/instrument/index.d.ts.map +1 -0
  259. package/dist/types/features/jserrors/aggregate/index.d.ts +2 -2
  260. package/dist/types/features/jserrors/aggregate/index.d.ts.map +1 -1
  261. package/dist/types/features/jserrors/instrument/index.d.ts +1 -0
  262. package/dist/types/features/jserrors/instrument/index.d.ts.map +1 -1
  263. package/dist/types/features/logging/aggregate/index.d.ts +4 -7
  264. package/dist/types/features/logging/aggregate/index.d.ts.map +1 -1
  265. package/dist/types/features/logging/constants.d.ts +0 -1
  266. package/dist/types/features/logging/constants.d.ts.map +1 -1
  267. package/dist/types/features/logging/instrument/index.d.ts +1 -0
  268. package/dist/types/features/logging/instrument/index.d.ts.map +1 -1
  269. package/dist/types/features/metrics/aggregate/index.d.ts.map +1 -1
  270. package/dist/types/features/metrics/aggregate/websocket-detection.d.ts +12 -0
  271. package/dist/types/features/metrics/aggregate/websocket-detection.d.ts.map +1 -0
  272. package/dist/types/features/metrics/constants.d.ts +1 -0
  273. package/dist/types/features/metrics/constants.d.ts.map +1 -1
  274. package/dist/types/features/metrics/instrument/index.d.ts +1 -0
  275. package/dist/types/features/metrics/instrument/index.d.ts.map +1 -1
  276. package/dist/types/features/page_action/instrument/index.d.ts +9 -4
  277. package/dist/types/features/page_action/instrument/index.d.ts.map +1 -1
  278. package/dist/types/features/page_view_event/aggregate/index.d.ts.map +1 -1
  279. package/dist/types/features/page_view_event/instrument/index.d.ts +1 -0
  280. package/dist/types/features/page_view_event/instrument/index.d.ts.map +1 -1
  281. package/dist/types/features/page_view_timing/aggregate/index.d.ts +2 -2
  282. package/dist/types/features/page_view_timing/aggregate/index.d.ts.map +1 -1
  283. package/dist/types/features/page_view_timing/instrument/index.d.ts +1 -0
  284. package/dist/types/features/page_view_timing/instrument/index.d.ts.map +1 -1
  285. package/dist/types/features/session_replay/aggregate/index.d.ts.map +1 -1
  286. package/dist/types/features/session_replay/constants.d.ts +0 -4
  287. package/dist/types/features/session_replay/constants.d.ts.map +1 -1
  288. package/dist/types/features/session_replay/instrument/index.d.ts +1 -0
  289. package/dist/types/features/session_replay/instrument/index.d.ts.map +1 -1
  290. package/dist/types/features/session_replay/shared/recorder-events.d.ts +6 -6
  291. package/dist/types/features/session_replay/shared/recorder-events.d.ts.map +1 -1
  292. package/dist/types/features/session_replay/shared/recorder.d.ts +2 -2
  293. package/dist/types/features/session_replay/shared/recorder.d.ts.map +1 -1
  294. package/dist/types/features/session_replay/shared/utils.d.ts.map +1 -1
  295. package/dist/types/features/session_trace/aggregate/index.d.ts +2 -2
  296. package/dist/types/features/session_trace/aggregate/index.d.ts.map +1 -1
  297. package/dist/types/features/session_trace/aggregate/trace/storage.d.ts +1 -1
  298. package/dist/types/features/session_trace/aggregate/trace/storage.d.ts.map +1 -1
  299. package/dist/types/features/session_trace/instrument/index.d.ts +1 -0
  300. package/dist/types/features/session_trace/instrument/index.d.ts.map +1 -1
  301. package/dist/types/features/soft_navigations/aggregate/index.d.ts +3 -3
  302. package/dist/types/features/soft_navigations/aggregate/index.d.ts.map +1 -1
  303. package/dist/types/features/soft_navigations/instrument/index.d.ts +1 -0
  304. package/dist/types/features/soft_navigations/instrument/index.d.ts.map +1 -1
  305. package/dist/types/features/spa/aggregate/index.d.ts +2 -2
  306. package/dist/types/features/spa/aggregate/index.d.ts.map +1 -1
  307. package/dist/types/features/spa/aggregate/interaction.d.ts.map +1 -1
  308. package/dist/types/features/spa/aggregate/serializer.d.ts.map +1 -1
  309. package/dist/types/features/spa/constants.d.ts.map +1 -1
  310. package/dist/types/features/spa/instrument/index.d.ts +1 -0
  311. package/dist/types/features/spa/instrument/index.d.ts.map +1 -1
  312. package/dist/types/features/utils/agent-session.d.ts.map +1 -1
  313. package/dist/types/features/utils/aggregate-base.d.ts +1 -0
  314. package/dist/types/features/utils/aggregate-base.d.ts.map +1 -1
  315. package/dist/types/features/utils/event-buffer.d.ts +72 -0
  316. package/dist/types/features/utils/event-buffer.d.ts.map +1 -0
  317. package/dist/types/features/utils/instrument-base.d.ts +1 -0
  318. package/dist/types/features/utils/instrument-base.d.ts.map +1 -1
  319. package/dist/types/index.d.ts +3 -0
  320. package/dist/types/loaders/agent-base.d.ts +1 -2
  321. package/dist/types/loaders/agent-base.d.ts.map +1 -1
  322. package/dist/types/loaders/agent.d.ts.map +1 -1
  323. package/dist/types/loaders/api/api.d.ts.map +1 -1
  324. package/dist/types/loaders/browser-agent.d.ts.map +1 -1
  325. package/dist/types/loaders/configure/configure.d.ts.map +1 -1
  326. package/dist/types/loaders/features/features.d.ts +1 -0
  327. package/dist/types/loaders/features/features.d.ts.map +1 -1
  328. package/dist/types/loaders/micro-agent.d.ts.map +1 -1
  329. package/package.json +67 -52
  330. package/src/cdn/experimental.js +2 -4
  331. package/src/cdn/pro.js +2 -2
  332. package/src/cdn/spa.js +2 -2
  333. package/src/common/aggregate/aggregator.js +2 -3
  334. package/src/common/config/__mocks__/info.js +3 -0
  335. package/src/common/config/__mocks__/init.js +3 -0
  336. package/src/common/config/__mocks__/loader-config.js +2 -0
  337. package/src/common/config/__mocks__/runtime.js +2 -0
  338. package/src/common/config/{state/configurable.js → configurable.js} +1 -1
  339. package/src/common/config/{state/info.js → info.js} +1 -1
  340. package/src/common/config/{state/init.js → init.js} +7 -6
  341. package/src/common/config/{state/loader-config.js → loader-config.js} +1 -1
  342. package/src/common/config/{state/runtime.js → runtime.js} +19 -5
  343. package/src/common/constants/agent-constants.js +2 -0
  344. package/src/common/constants/runtime.js +0 -2
  345. package/src/common/drain/drain.js +8 -6
  346. package/src/common/event-emitter/contextual-ee.js +1 -1
  347. package/src/common/harvest/harvest.js +10 -24
  348. package/src/common/serialize/bel-serializer.js +6 -9
  349. package/src/common/session/session-entity.js +4 -4
  350. package/src/common/timing/__mocks__/time-keeper.js +6 -2
  351. package/src/common/timing/time-keeper.js +15 -5
  352. package/src/common/url/encode.js +2 -3
  353. package/src/common/util/__mocks__/console.js +1 -0
  354. package/src/common/util/__mocks__/obfuscate.js +5 -8
  355. package/src/common/util/console.js +2 -0
  356. package/src/common/util/obfuscate.js +94 -50
  357. package/src/common/util/submit-data.js +0 -1
  358. package/src/common/util/text.js +6 -0
  359. package/src/common/window/__mocks__/nreum.js +1 -1
  360. package/src/common/window/nreum.js +2 -1
  361. package/src/common/wrap/wrap-websocket.js +73 -0
  362. package/src/features/ajax/aggregate/chunk.js +3 -2
  363. package/src/features/ajax/aggregate/index.js +20 -19
  364. package/src/features/ajax/constants.js +0 -2
  365. package/src/features/ajax/instrument/distributed-tracing.js +2 -1
  366. package/src/features/ajax/instrument/index.js +9 -5
  367. package/src/features/generic_events/aggregate/index.js +139 -0
  368. package/src/features/generic_events/constants.js +5 -0
  369. package/src/features/generic_events/index.js +1 -0
  370. package/src/features/generic_events/instrument/index.js +24 -0
  371. package/src/features/jserrors/aggregate/index.js +18 -9
  372. package/src/features/jserrors/instrument/index.js +2 -0
  373. package/src/features/logging/aggregate/index.js +39 -31
  374. package/src/features/logging/constants.js +0 -2
  375. package/src/features/logging/instrument/index.js +2 -0
  376. package/src/features/logging/shared/utils.js +1 -1
  377. package/src/features/metrics/aggregate/index.js +24 -9
  378. package/src/features/metrics/aggregate/websocket-detection.js +31 -0
  379. package/src/features/metrics/constants.js +3 -0
  380. package/src/features/metrics/instrument/index.js +13 -1
  381. package/src/features/page_action/instrument/index.js +11 -6
  382. package/src/features/page_view_event/aggregate/index.js +8 -23
  383. package/src/features/page_view_event/aggregate/initialized-features.js +1 -1
  384. package/src/features/page_view_event/instrument/index.js +2 -0
  385. package/src/features/page_view_timing/aggregate/index.js +15 -18
  386. package/src/features/page_view_timing/instrument/index.js +2 -0
  387. package/src/features/session_replay/aggregate/index.js +13 -9
  388. package/src/features/session_replay/constants.js +0 -4
  389. package/src/features/session_replay/index.js +1 -7
  390. package/src/features/session_replay/instrument/index.js +3 -4
  391. package/src/features/session_replay/shared/recorder-events.js +27 -20
  392. package/src/features/session_replay/shared/recorder.js +13 -6
  393. package/src/features/session_replay/shared/stylesheet-evaluator.js +2 -2
  394. package/src/features/session_replay/shared/utils.js +3 -2
  395. package/src/features/session_trace/aggregate/index.js +16 -7
  396. package/src/features/session_trace/aggregate/trace/storage.js +6 -1
  397. package/src/features/session_trace/instrument/index.js +4 -1
  398. package/src/features/soft_navigations/aggregate/ajax-node.js +1 -1
  399. package/src/features/soft_navigations/aggregate/index.js +13 -15
  400. package/src/features/soft_navigations/aggregate/initial-page-load-interaction.js +1 -1
  401. package/src/features/soft_navigations/aggregate/interaction.js +1 -1
  402. package/src/features/soft_navigations/instrument/index.js +9 -5
  403. package/src/features/spa/aggregate/index.js +12 -20
  404. package/src/features/spa/aggregate/interaction.js +6 -5
  405. package/src/features/spa/aggregate/serializer.js +2 -3
  406. package/src/features/spa/constants.js +2 -2
  407. package/src/features/spa/instrument/index.js +9 -3
  408. package/src/features/utils/agent-session.js +3 -1
  409. package/src/features/utils/aggregate-base.js +13 -3
  410. package/src/features/utils/event-buffer.js +126 -0
  411. package/src/features/utils/feature-gates.js +1 -1
  412. package/src/features/utils/instrument-base.js +2 -1
  413. package/src/features/utils/lazy-feature-loader.js +2 -2
  414. package/src/index.js +3 -0
  415. package/src/loaders/agent-base.js +2 -6
  416. package/src/loaders/agent.js +7 -2
  417. package/src/loaders/api/api.js +3 -2
  418. package/src/loaders/api/apiAsync.js +2 -2
  419. package/src/loaders/browser-agent.js +5 -3
  420. package/src/loaders/configure/configure.js +9 -2
  421. package/src/loaders/features/enabled-features.js +1 -1
  422. package/src/loaders/features/features.js +8 -4
  423. package/src/loaders/micro-agent.js +5 -2
  424. package/dist/cjs/cdn/polyfills/lite.js +0 -16
  425. package/dist/cjs/cdn/polyfills/pro.js +0 -21
  426. package/dist/cjs/cdn/polyfills/spa.js +0 -22
  427. package/dist/cjs/cdn/polyfills.js +0 -24
  428. package/dist/cjs/common/config/config.js +0 -76
  429. package/dist/cjs/common/config/state/originals.js +0 -8
  430. package/dist/cjs/common/util/map-own.js +0 -31
  431. package/dist/cjs/common/wrap/index.js +0 -61
  432. package/dist/cjs/features/page_action/aggregate/index.js +0 -121
  433. package/dist/esm/cdn/polyfills/lite.js +0 -14
  434. package/dist/esm/cdn/polyfills/pro.js +0 -19
  435. package/dist/esm/cdn/polyfills/spa.js +0 -20
  436. package/dist/esm/cdn/polyfills.js +0 -27
  437. package/dist/esm/common/config/config.js +0 -11
  438. package/dist/esm/common/config/state/originals.js +0 -2
  439. package/dist/esm/common/util/map-own.js +0 -24
  440. package/dist/esm/common/wrap/index.js +0 -13
  441. package/dist/esm/features/page_action/aggregate/index.js +0 -114
  442. package/dist/types/cdn/polyfills/lite.d.ts +0 -2
  443. package/dist/types/cdn/polyfills/lite.d.ts.map +0 -1
  444. package/dist/types/cdn/polyfills/pro.d.ts +0 -2
  445. package/dist/types/cdn/polyfills/pro.d.ts.map +0 -1
  446. package/dist/types/cdn/polyfills/spa.d.ts +0 -2
  447. package/dist/types/cdn/polyfills/spa.d.ts.map +0 -1
  448. package/dist/types/cdn/polyfills.d.ts +0 -2
  449. package/dist/types/cdn/polyfills.d.ts.map +0 -1
  450. package/dist/types/common/config/config.d.ts +0 -13
  451. package/dist/types/common/config/config.d.ts.map +0 -1
  452. package/dist/types/common/config/state/configurable.d.ts.map +0 -1
  453. package/dist/types/common/config/state/info.d.ts.map +0 -1
  454. package/dist/types/common/config/state/init.d.ts.map +0 -1
  455. package/dist/types/common/config/state/loader-config.d.ts.map +0 -1
  456. package/dist/types/common/config/state/originals.d.ts +0 -2
  457. package/dist/types/common/config/state/originals.d.ts.map +0 -1
  458. package/dist/types/common/config/state/runtime.d.ts.map +0 -1
  459. package/dist/types/common/util/map-own.d.ts +0 -3
  460. package/dist/types/common/util/map-own.d.ts.map +0 -1
  461. package/dist/types/common/wrap/index.d.ts +0 -10
  462. package/dist/types/common/wrap/index.d.ts.map +0 -1
  463. package/dist/types/features/page_action/aggregate/index.d.ts.map +0 -1
  464. package/src/cdn/polyfills/lite.js +0 -20
  465. package/src/cdn/polyfills/pro.js +0 -30
  466. package/src/cdn/polyfills/spa.js +0 -32
  467. package/src/cdn/polyfills.js +0 -27
  468. package/src/common/config/__mocks__/config.js +0 -11
  469. package/src/common/config/config.js +0 -12
  470. package/src/common/config/state/originals.js +0 -3
  471. package/src/common/util/map-own.js +0 -22
  472. package/src/common/wrap/index.js +0 -16
  473. package/src/features/page_action/aggregate/index.js +0 -114
  474. /package/dist/types/common/config/{state/configurable.d.ts → configurable.d.ts} +0 -0
  475. /package/dist/types/common/config/{state/info.d.ts → info.d.ts} +0 -0
  476. /package/dist/types/common/config/{state/init.d.ts → init.d.ts} +0 -0
  477. /package/dist/types/common/config/{state/loader-config.d.ts → loader-config.d.ts} +0 -0
  478. /package/dist/types/common/config/{state/runtime.d.ts → runtime.d.ts} +0 -0
@@ -3,7 +3,7 @@ export const gosNREUM = jest.fn(() => ({}))
3
3
  export const gosNREUMInfo = jest.fn(() => ({}))
4
4
  export const gosNREUMLoaderConfig = jest.fn(() => ({}))
5
5
  export const gosNREUMInit = jest.fn(() => ({}))
6
- export const gosNREUMOriginals = jest.fn(() => ({}))
6
+ export const gosNREUMOriginals = jest.fn(() => ({ o: {} }))
7
7
  export const setNREUMInitializedAgent = jest.fn()
8
8
  export const getNREUMInitializedAgent = jest.fn(() => ({}))
9
9
  export const addToNREUM = jest.fn(() => ({}))
@@ -61,7 +61,8 @@ export function gosNREUMOriginals () {
61
61
  EV: globalScope.Event,
62
62
  PR: globalScope.Promise,
63
63
  MO: globalScope.MutationObserver, // this'll be undefined if not in a web window
64
- FETCH: globalScope.fetch
64
+ FETCH: globalScope.fetch,
65
+ WS: globalScope.WebSocket
65
66
  }
66
67
  }
67
68
  return nr
@@ -0,0 +1,73 @@
1
+ import { globalScope } from '../constants/runtime'
2
+ import { now } from '../timing/now'
3
+ import { checkState } from '../window/load'
4
+ import { generateRandomHexString } from '../ids/unique-id'
5
+ import { gosNREUMOriginals } from '../window/nreum'
6
+
7
+ export const WEBSOCKET_TAG = 'websocket-'
8
+ export const ADD_EVENT_LISTENER_TAG = 'addEventListener'
9
+
10
+ const wrapped = {}
11
+
12
+ export function wrapWebSocket (sharedEE) {
13
+ if (wrapped[sharedEE.debugId]++) return sharedEE
14
+ const originals = gosNREUMOriginals().o
15
+ if (!originals.WS) return sharedEE
16
+
17
+ function reporter (socketId) {
18
+ const createdAt = now()
19
+ return function (message, ...data) {
20
+ const timestamp = data[0]?.timeStamp || now()
21
+ const isLoaded = checkState()
22
+ sharedEE.emit(WEBSOCKET_TAG + message, [timestamp, timestamp - createdAt, isLoaded, socketId, ...data])
23
+ }
24
+ }
25
+
26
+ Object.defineProperty(WrappedWebSocket, 'name', {
27
+ value: 'WebSocket'
28
+ })
29
+
30
+ function WrappedWebSocket () {
31
+ const ws = new originals.WS(...arguments)
32
+ const socketId = generateRandomHexString(6)
33
+ const report = reporter(socketId)
34
+ report('new')
35
+
36
+ const events = ['message', 'error', 'open', 'close']
37
+ /** add event listeners */
38
+ events.forEach(evt => {
39
+ ws.addEventListener(evt, function (e) {
40
+ report(ADD_EVENT_LISTENER_TAG, { eventType: evt, event: e })
41
+ })
42
+ })
43
+
44
+ /** could also observe the on-events for runtime processing, but not implemented yet */
45
+
46
+ /** observe the static method send, but noteably not close, as that is currently observed with the event listener */
47
+ ;['send'].forEach(wrapStaticProperty)
48
+
49
+ function wrapStaticProperty (prop) {
50
+ const originalProp = ws[prop]
51
+ if (originalProp) {
52
+ Object.defineProperty(proxiedProp, 'name', {
53
+ value: prop
54
+ })
55
+ function proxiedProp () {
56
+ report(prop, ...arguments)
57
+ try {
58
+ return originalProp.apply(this, arguments)
59
+ } catch (err) {
60
+ report(prop + '-err', ...arguments)
61
+ // rethrow error so we don't effect execution by observing.
62
+ throw err
63
+ }
64
+ }
65
+ ws[prop] = proxiedProp
66
+ }
67
+ }
68
+
69
+ return ws
70
+ }
71
+ globalScope.WebSocket = WrappedWebSocket
72
+ return sharedEE
73
+ }
@@ -1,5 +1,6 @@
1
1
  import { nullable, numeric, getAddStringContext, addCustomAttributes } from '../../../common/serialize/bel-serializer'
2
- import { getInfo } from '../../../common/config/config'
2
+ import { getInfo } from '../../../common/config/info'
3
+ import { MAX_PAYLOAD_SIZE } from '../../../common/constants/agent-constants'
3
4
 
4
5
  export default class Chunk {
5
6
  constructor (events, aggregateInstance) {
@@ -46,6 +47,6 @@ export default class Chunk {
46
47
  this.payload += insert
47
48
  }
48
49
 
49
- this.tooBig = this.payload.length * 2 > aggregateInstance.MAX_PAYLOAD_SIZE
50
+ this.tooBig = this.payload.length * 2 > MAX_PAYLOAD_SIZE
50
51
  }
51
52
  }
@@ -5,7 +5,9 @@
5
5
  import { registerHandler } from '../../../common/event-emitter/register-handler'
6
6
  import { stringify } from '../../../common/util/stringify'
7
7
  import { handle } from '../../../common/event-emitter/handle'
8
- import { getConfiguration, getInfo, getRuntime } from '../../../common/config/config'
8
+ import { getInfo } from '../../../common/config/info'
9
+ import { getConfiguration } from '../../../common/config/init'
10
+ import { getRuntime } from '../../../common/config/runtime'
9
11
  import { HarvestScheduler } from '../../../common/harvest/harvest-scheduler'
10
12
  import { setDenyList, shouldCollectEvent } from '../../../common/deny-list/deny-list'
11
13
  import { FEATURE_NAME } from '../constants'
@@ -15,6 +17,7 @@ import { AggregateBase } from '../../utils/aggregate-base'
15
17
  import { parseGQL } from './gql'
16
18
  import { getNREUMInitializedAgent } from '../../../common/window/nreum'
17
19
  import Chunk from './chunk'
20
+ import { EventBuffer } from '../../utils/event-buffer'
18
21
 
19
22
  export class Aggregate extends AggregateBase {
20
23
  static featureName = FEATURE_NAME
@@ -30,26 +33,24 @@ export class Aggregate extends AggregateBase {
30
33
  this.#agentInit = getConfiguration(agentIdentifier)
31
34
 
32
35
  const harvestTimeSeconds = this.#agentInit.ajax.harvestTimeSeconds || 10
33
- this.MAX_PAYLOAD_SIZE = this.#agentInit.ajax.maxPayloadSize || 1000000
34
36
  setDenyList(this.#agentRuntime.denyList)
35
37
 
36
- this.ajaxEvents = []
38
+ this.ajaxEvents = new EventBuffer()
37
39
  this.spaAjaxEvents = {}
38
- this.sentAjaxEvents = []
39
40
  const classThis = this
40
41
 
41
42
  // --- v Used by old spa feature
42
43
  this.ee.on('interactionDone', (interaction, wasSaved) => {
43
- if (!this.spaAjaxEvents[interaction.id]) return
44
+ if (!this.spaAjaxEvents[interaction.id]?.hasData) return
44
45
 
45
46
  if (!wasSaved) { // if the ixn was saved, then its ajax reqs are part of the payload whereas if it was discarded, it should still be harvested in the ajax feature itself
46
- this.spaAjaxEvents[interaction.id].forEach((item) => this.ajaxEvents.push(item))
47
+ this.ajaxEvents.merge(this.spaAjaxEvents[interaction.id])
47
48
  }
48
49
  delete this.spaAjaxEvents[interaction.id]
49
50
  })
50
51
  // --- ^
51
52
  // --- v Used by new soft nav
52
- registerHandler('returnAjax', event => this.ajaxEvents.push(event), this.featureName, this.ee)
53
+ registerHandler('returnAjax', event => this.ajaxEvents.add(event), this.featureName, this.ee)
53
54
  // --- ^
54
55
  registerHandler('xhr', function () { // the EE-drain system not only switches "this" but also passes a new EventContext with info. Should consider platform refactor to another system which passes a mutable context around separately and predictably to avoid problems like this.
55
56
  classThis.storeXhr(...arguments, this) // this switches the context back to the class instance while passing the NR context as an argument -- see "ctx" in storeXhr
@@ -116,7 +117,9 @@ export class Aggregate extends AggregateBase {
116
117
  if (ctx.dt) {
117
118
  event.spanId = ctx.dt.spanId
118
119
  event.traceId = ctx.dt.traceId
119
- event.spanTimestamp = this.#agentRuntime.timeKeeper.correctAbsoluteTimestamp(ctx.dt.timestamp)
120
+ event.spanTimestamp = Math.floor(
121
+ this.#agentRuntime.timeKeeper.correctAbsoluteTimestamp(ctx.dt.timestamp)
122
+ )
120
123
  }
121
124
 
122
125
  // parsed from the AJAX body, looking for operationName param & parsing query for operationType
@@ -131,33 +134,31 @@ export class Aggregate extends AggregateBase {
131
134
  handle('ajax', [event], undefined, FEATURE_NAMES.softNav, this.ee)
132
135
  } else if (ctx.spaNode) { // For old spa (when running), if the ajax happened inside an interaction, hold it until the interaction finishes
133
136
  const interactionId = ctx.spaNode.interaction.id
134
- this.spaAjaxEvents[interactionId] = this.spaAjaxEvents[interactionId] || []
135
- this.spaAjaxEvents[interactionId].push(event)
137
+ this.spaAjaxEvents[interactionId] ??= new EventBuffer()
138
+ this.spaAjaxEvents[interactionId].add(event)
136
139
  } else {
137
- this.ajaxEvents.push(event)
140
+ this.ajaxEvents.add(event)
138
141
  }
139
142
  }
140
143
 
141
144
  prepareHarvest (options) {
142
145
  options = options || {}
143
- if (this.ajaxEvents.length === 0) return null
146
+ if (this.ajaxEvents.buffer.length === 0) return null
144
147
 
145
- const payload = this.#getPayload(this.ajaxEvents)
148
+ const payload = this.#getPayload(this.ajaxEvents.buffer)
146
149
  const payloadObjs = []
147
150
 
148
151
  for (let i = 0; i < payload.length; i++) payloadObjs.push({ body: { e: payload[i] } })
149
152
 
150
- if (options.retry) this.sentAjaxEvents = this.ajaxEvents
151
- this.ajaxEvents = []
153
+ if (options.retry) this.ajaxEvents.hold()
154
+ else this.ajaxEvents.clear()
152
155
 
153
156
  return payloadObjs
154
157
  }
155
158
 
156
159
  onEventsHarvestFinished (result) {
157
- if (result.retry && this.sentAjaxEvents.length > 0) {
158
- this.ajaxEvents.unshift(...this.sentAjaxEvents)
159
- this.sentAjaxEvents = []
160
- }
160
+ if (result.retry && this.ajaxEvents.held.hasData) this.ajaxEvents.unhold()
161
+ else this.ajaxEvents.held.clear()
161
162
  }
162
163
 
163
164
  #getPayload (events, numberOfChunks) {
@@ -1,5 +1,3 @@
1
1
  import { FEATURE_NAMES } from '../../loaders/features/features'
2
2
 
3
3
  export const FEATURE_NAME = FEATURE_NAMES.ajax
4
-
5
- export const MAX_PAYLOAD_SIZE = 1000000
@@ -2,7 +2,8 @@
2
2
  * Copyright 2020 New Relic Corporation. All rights reserved.
3
3
  * SPDX-License-Identifier: Apache-2.0
4
4
  */
5
- import { getConfiguration, getConfigurationValue, getLoaderConfig } from '../../../common/config/config'
5
+ import { getConfiguration, getConfigurationValue } from '../../../common/config/init'
6
+ import { getLoaderConfig } from '../../../common/config/loader-config'
6
7
  import { generateSpanId, generateTraceId } from '../../../common/ids/unique-id'
7
8
  import { parseUrl } from '../../../common/url/parse-url'
8
9
  import { globalScope } from '../../../common/constants/runtime'
@@ -2,13 +2,15 @@
2
2
  * Copyright 2020 New Relic Corporation. All rights reserved.
3
3
  * SPDX-License-Identifier: Apache-2.0
4
4
  */
5
- import { originals, getLoaderConfig } from '../../../common/config/config'
5
+ import { gosNREUMOriginals } from '../../../common/window/nreum'
6
+ import { getLoaderConfig } from '../../../common/config/loader-config'
6
7
  import { handle } from '../../../common/event-emitter/handle'
7
8
  import { id } from '../../../common/ids/id'
8
9
  import { ffVersion, globalScope, isBrowserScope } from '../../../common/constants/runtime'
9
10
  import { dataSize } from '../../../common/util/data-size'
10
11
  import { eventListenerOpts } from '../../../common/event-listener/event-listener-opts'
11
- import { wrapFetch, wrapXhr } from '../../../common/wrap'
12
+ import { wrapXhr } from '../../../common/wrap/wrap-xhr'
13
+ import { wrapFetch } from '../../../common/wrap/wrap-fetch'
12
14
  import { parseUrl } from '../../../common/url/parse-url'
13
15
  import { DT } from './distributed-tracing'
14
16
  import { responseSizeFromXhr } from './response-size'
@@ -22,8 +24,8 @@ import { hasUndefinedHostname } from '../../../common/deny-list/deny-list'
22
24
  var handlers = ['load', 'error', 'abort', 'timeout']
23
25
  var handlersLen = handlers.length
24
26
 
25
- var origRequest = originals.REQ
26
- var origXHR = originals.XHR
27
+ var origRequest = gosNREUMOriginals().o.REQ
28
+ var origXHR = gosNREUMOriginals().o.XHR
27
29
 
28
30
  export class Instrument extends InstrumentBase {
29
31
  static featureName = FEATURE_NAME
@@ -374,7 +376,7 @@ function subscribeToEvents (agentIdentifier, ee, handler, dt) {
374
376
  if (hasUndefinedHostname(params)) return // don't bother with XHR of url with no hostname
375
377
 
376
378
  metrics.duration = now() - this.startTime
377
- if (!this.loadCaptureCalled && xhr.readyState === 4) {
379
+ if (!this.loadCazptureCalled && xhr.readyState === 4) {
378
380
  captureXhrData(this, xhr)
379
381
  } else if (params.status == null) {
380
382
  params.status = 0
@@ -416,3 +418,5 @@ function addUrl (ctx, url) {
416
418
  ctx.parsedOrigin = parsed
417
419
  ctx.sameOrigin = parsed.sameOrigin
418
420
  }
421
+
422
+ export const Ajax = Instrument
@@ -0,0 +1,139 @@
1
+ /*
2
+ * Copyright 2020 New Relic Corporation. All rights reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+ import { stringify } from '../../../common/util/stringify'
6
+ import { HarvestScheduler } from '../../../common/harvest/harvest-scheduler'
7
+ import { cleanURL } from '../../../common/url/clean-url'
8
+ import { getInfo } from '../../../common/config/info'
9
+ import { getConfigurationValue } from '../../../common/config/init'
10
+ import { getRuntime } from '../../../common/config/runtime'
11
+ import { FEATURE_NAME } from '../constants'
12
+ import { isBrowserScope } from '../../../common/constants/runtime'
13
+ import { AggregateBase } from '../../utils/aggregate-base'
14
+ import { warn } from '../../../common/util/console'
15
+ import { now } from '../../../common/timing/now'
16
+ import { registerHandler } from '../../../common/event-emitter/register-handler'
17
+ import { deregisterDrain } from '../../../common/drain/drain'
18
+ import { SUPPORTABILITY_METRIC_CHANNEL } from '../../metrics/constants'
19
+ import { EventBuffer } from '../../utils/event-buffer'
20
+ import { applyFnToProps } from '../../../common/util/traverse'
21
+ import { IDEAL_PAYLOAD_SIZE } from '../../../common/constants/agent-constants'
22
+
23
+ export class Aggregate extends AggregateBase {
24
+ #agentRuntime
25
+ static featureName = FEATURE_NAME
26
+ constructor (agentIdentifier, aggregator) {
27
+ super(agentIdentifier, aggregator, FEATURE_NAME)
28
+
29
+ this.eventsPerHarvest = 1000
30
+ this.harvestTimeSeconds = getConfigurationValue(this.agentIdentifier, 'generic_events.harvestTimeSeconds')
31
+
32
+ this.referrerUrl = (isBrowserScope && document.referrer) ? cleanURL(document.referrer) : undefined
33
+
34
+ this.events = new EventBuffer()
35
+
36
+ this.#agentRuntime = getRuntime(this.agentIdentifier)
37
+
38
+ this.waitForFlags(['ins']).then(([ins]) => {
39
+ if (!ins) {
40
+ this.blocked = true
41
+ deregisterDrain(this.agentIdentifier, this.featureName)
42
+ return
43
+ }
44
+
45
+ if (getConfigurationValue(this.agentIdentifier, 'page_action.enabled')) {
46
+ registerHandler('api-addPageAction', (timestamp, name, attributes) => {
47
+ this.addEvent({
48
+ ...attributes,
49
+ eventType: 'PageAction',
50
+ timestamp: Math.floor(this.#agentRuntime.timeKeeper.correctAbsoluteTimestamp(
51
+ this.#agentRuntime.timeKeeper.convertRelativeTimestamp(timestamp)
52
+ )),
53
+ timeSinceLoad: timestamp / 1000,
54
+ actionName: name,
55
+ referrerUrl: this.referrerUrl,
56
+ currentUrl: cleanURL('' + location),
57
+ ...(isBrowserScope && {
58
+ browserWidth: window.document.documentElement?.clientWidth,
59
+ browserHeight: window.document.documentElement?.clientHeight
60
+ })
61
+ })
62
+ }, this.featureName, this.ee)
63
+ }
64
+
65
+ this.harvestScheduler = new HarvestScheduler('ins', { onFinished: (...args) => this.onHarvestFinished(...args) }, this)
66
+ this.harvestScheduler.harvest.on('ins', (...args) => this.onHarvestStarted(...args))
67
+ this.harvestScheduler.startTimer(this.harvestTimeSeconds, 0)
68
+
69
+ this.drain()
70
+ })
71
+ }
72
+
73
+ // WARNING: Insights times are in seconds. EXCEPT timestamp, which is in ms.
74
+ addEvent (obj = {}) {
75
+ if (!obj || !Object.keys(obj).length) return
76
+ if (!obj.eventType) {
77
+ warn(44)
78
+ return
79
+ }
80
+
81
+ for (let key in obj) {
82
+ let val = obj[key]
83
+ obj[key] = (val && typeof val === 'object' ? stringify(val) : val)
84
+ }
85
+
86
+ const defaultEventAttributes = {
87
+ /** should be overridden by the event-specific attributes, but just in case -- set it to now() */
88
+ timestamp: Math.floor(this.#agentRuntime.timeKeeper.correctAbsoluteTimestamp(
89
+ this.#agentRuntime.timeKeeper.convertRelativeTimestamp(now())
90
+ )),
91
+ /** all generic events require a pageUrl */
92
+ pageUrl: cleanURL(getRuntime(this.agentIdentifier).origin)
93
+ }
94
+
95
+ const eventAttributes = {
96
+ /** Agent-level custom attributes */
97
+ ...(getInfo(this.agentIdentifier).jsAttributes || {}),
98
+ /** Fallbacks for required properties in-case the event did not supply them, should take precedence over agent-level custom attrs */
99
+ ...defaultEventAttributes,
100
+ /** Event-specific attributes take precedence over agent-level custom attributes and fallbacks */
101
+ ...obj
102
+ }
103
+
104
+ this.events.add(eventAttributes)
105
+
106
+ this.checkEventLimits()
107
+ }
108
+
109
+ onHarvestStarted (options) {
110
+ const { userAttributes, atts } = getInfo(this.agentIdentifier)
111
+ if (!this.events.hasData) return
112
+ var payload = ({
113
+ qs: {
114
+ ua: userAttributes,
115
+ at: atts
116
+ },
117
+ body: applyFnToProps(
118
+ { ins: this.events.buffer },
119
+ this.obfuscator.obfuscateString.bind(this.obfuscator), 'string'
120
+ )
121
+ })
122
+
123
+ if (options.retry) this.events.hold()
124
+ return payload
125
+ }
126
+
127
+ onHarvestFinished (result) {
128
+ if (result && result?.sent && result?.retry && this.events.held.hasData) this.events.unhold()
129
+ else this.events.held.clear()
130
+ }
131
+
132
+ checkEventLimits () {
133
+ // check if we've reached any harvest limits...
134
+ if (this.events.bytes > IDEAL_PAYLOAD_SIZE) {
135
+ this.ee.emit(SUPPORTABILITY_METRIC_CHANNEL, ['GenericEvents/Harvest/Max/Seen'])
136
+ this.harvestScheduler.runHarvest()
137
+ }
138
+ }
139
+ }
@@ -0,0 +1,5 @@
1
+ import { FEATURE_NAMES } from '../../loaders/features/features'
2
+
3
+ export const FEATURE_NAME = FEATURE_NAMES.genericEvents
4
+ export const IDEAL_PAYLOAD_SIZE = 64000
5
+ export const MAX_PAYLOAD_SIZE = 1000000
@@ -0,0 +1 @@
1
+ export { Instrument as GenericEvents } from './instrument/index'
@@ -0,0 +1,24 @@
1
+ /* Copyright 2020 New Relic Corporation. All rights reserved.
2
+ * SPDX-License-Identifier: Apache-2.0
3
+ */
4
+
5
+ import { getConfigurationValue } from '../../../common/config/init'
6
+ import { deregisterDrain } from '../../../common/drain/drain'
7
+ import { InstrumentBase } from '../../utils/instrument-base'
8
+ import { FEATURE_NAME } from '../constants'
9
+
10
+ export class Instrument extends InstrumentBase {
11
+ static featureName = FEATURE_NAME
12
+ constructor (agentIdentifier, aggregator, auto = true) {
13
+ super(agentIdentifier, aggregator, FEATURE_NAME, auto)
14
+ const genericEventSourceConfigs = [
15
+ getConfigurationValue(this.agentIdentifier, 'page_action.enabled')
16
+ // other future generic event source configs to go here, like M&Ms, PageResouce, etc.
17
+ ]
18
+ /** If any of the sources are active, import the aggregator. otherwise deregister */
19
+ if (genericEventSourceConfigs.some(x => x)) this.importAggregator()
20
+ else deregisterDrain(this.agentIdentifier, this.featureName)
21
+ }
22
+ }
23
+
24
+ export const GenericEvents = Instrument
@@ -12,8 +12,9 @@ import { registerHandler as register } from '../../../common/event-emitter/regis
12
12
  import { HarvestScheduler } from '../../../common/harvest/harvest-scheduler'
13
13
  import { stringify } from '../../../common/util/stringify'
14
14
  import { handle } from '../../../common/event-emitter/handle'
15
- import { mapOwn } from '../../../common/util/map-own'
16
- import { getInfo, getConfigurationValue, getRuntime } from '../../../common/config/config'
15
+ import { getInfo } from '../../../common/config/info'
16
+ import { getConfigurationValue } from '../../../common/config/init'
17
+ import { getRuntime } from '../../../common/config/runtime'
17
18
  import { globalScope } from '../../../common/constants/runtime'
18
19
 
19
20
  import { FEATURE_NAME } from '../constants'
@@ -22,6 +23,7 @@ import { AggregateBase } from '../../utils/aggregate-base'
22
23
  import { getNREUMInitializedAgent } from '../../../common/window/nreum'
23
24
  import { deregisterDrain } from '../../../common/drain/drain'
24
25
  import { now } from '../../../common/timing/now'
26
+ import { applyFnToProps } from '../../../common/util/traverse'
25
27
 
26
28
  /**
27
29
  * @typedef {import('./compute-stack-trace.js').StackInfo} StackInfo
@@ -65,7 +67,10 @@ export class Aggregate extends AggregateBase {
65
67
 
66
68
  onHarvestStarted (options) {
67
69
  // this gets rid of dependency in AJAX module
68
- var body = this.aggregator.take(['err', 'ierr', 'xhr'])
70
+ var body = applyFnToProps(
71
+ this.aggregator.take(['err', 'ierr', 'xhr']),
72
+ this.obfuscator.obfuscateString.bind(this.obfuscator), 'string'
73
+ )
69
74
 
70
75
  if (options.retry) {
71
76
  this.currentBody = body
@@ -91,7 +96,7 @@ export class Aggregate extends AggregateBase {
91
96
 
92
97
  onHarvestFinished (result) {
93
98
  if (result.retry && this.currentBody) {
94
- mapOwn(this.currentBody, (key, value) => {
99
+ Object.entries(this.currentBody || {}).forEach(([key, value]) => {
95
100
  for (var i = 0; i < value.length; i++) {
96
101
  var bucket = value[i]
97
102
  var name = this.getBucketName(key, bucket.params, bucket.custom)
@@ -179,7 +184,9 @@ export class Aggregate extends AggregateBase {
179
184
  if (!this.stackReported[bucketHash]) {
180
185
  this.stackReported[bucketHash] = true
181
186
  params.stack_trace = truncateSize(stackInfo.stackString)
182
- this.observedAt[bucketHash] = agentRuntime.timeKeeper.convertRelativeTimestamp(time)
187
+ this.observedAt[bucketHash] = Math.floor(agentRuntime.timeKeeper.correctAbsoluteTimestamp(
188
+ agentRuntime.timeKeeper.convertRelativeTimestamp(time)
189
+ ))
183
190
  } else {
184
191
  params.browser_stack_hash = stringHashCode(stackInfo.stackString)
185
192
  }
@@ -196,7 +203,9 @@ export class Aggregate extends AggregateBase {
196
203
  }
197
204
 
198
205
  params.firstOccurrenceTimestamp = this.observedAt[bucketHash]
199
- params.timestamp = agentRuntime.timeKeeper.convertRelativeTimestamp(time)
206
+ params.timestamp = Math.floor(agentRuntime.timeKeeper.correctAbsoluteTimestamp(
207
+ agentRuntime.timeKeeper.convertRelativeTimestamp(time)
208
+ ))
200
209
 
201
210
  var type = internal ? 'ierr' : 'err'
202
211
  var newMetrics = { time }
@@ -264,8 +273,8 @@ export class Aggregate extends AggregateBase {
264
273
  var allCustomAttrs = {}
265
274
  const localCustomAttrs = item[4]
266
275
 
267
- mapOwn(interaction.root.attrs.custom, setCustom) // tack on custom attrs from the interaction
268
- mapOwn(localCustomAttrs, setCustom)
276
+ Object.entries(interaction.root.attrs.custom || {}).forEach(setCustom) // tack on custom attrs from the interaction
277
+ Object.entries(localCustomAttrs || {}).forEach(setCustom)
269
278
 
270
279
  var params = item[2]
271
280
  if (wasSaved) {
@@ -281,7 +290,7 @@ export class Aggregate extends AggregateBase {
281
290
 
282
291
  this.aggregator.store(item[0], aggregateHash, params, item[3], allCustomAttrs)
283
292
 
284
- function setCustom (key, val) {
293
+ function setCustom ([key, val]) {
285
294
  allCustomAttrs[key] = (val && typeof val === 'object' ? stringify(val) : val)
286
295
  }
287
296
  })
@@ -54,3 +54,5 @@ export class Instrument extends InstrumentBase {
54
54
  this.abortHandler = undefined // weakly allow this abort op to run only once
55
55
  }
56
56
  }
57
+
58
+ export const JSErrors = Instrument