@newrelic/browser-agent 1.263.0 → 1.264.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 (210) hide show
  1. package/CHANGELOG.md +8 -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 +3 -3
  7. package/dist/cjs/common/config/state/init.js +6 -3
  8. package/dist/cjs/common/constants/env.cdn.js +1 -1
  9. package/dist/cjs/common/constants/env.npm.js +1 -1
  10. package/dist/cjs/common/constants/runtime.js +1 -3
  11. package/dist/cjs/common/drain/drain.js +4 -4
  12. package/dist/cjs/common/harvest/harvest.js +2 -2
  13. package/dist/cjs/common/serialize/bel-serializer.js +2 -2
  14. package/dist/cjs/common/session/session-entity.js +1 -1
  15. package/dist/cjs/common/url/encode.js +3 -5
  16. package/dist/cjs/common/util/submit-data.js +0 -1
  17. package/dist/cjs/common/vitals/vital-metric.js +1 -1
  18. package/dist/cjs/features/ajax/aggregate/index.js +1 -1
  19. package/dist/cjs/features/ajax/instrument/index.js +1 -1
  20. package/dist/cjs/features/generic_events/aggregate/index.js +137 -0
  21. package/dist/cjs/features/generic_events/constants.js +8 -0
  22. package/dist/cjs/features/generic_events/index.js +12 -0
  23. package/dist/cjs/features/generic_events/instrument/index.js +27 -0
  24. package/dist/cjs/features/jserrors/aggregate/index.js +13 -12
  25. package/dist/cjs/features/jserrors/instrument/index.js +1 -1
  26. package/dist/cjs/features/logging/aggregate/index.js +1 -1
  27. package/dist/cjs/features/logging/instrument/index.js +1 -1
  28. package/dist/cjs/features/metrics/aggregate/index.js +1 -1
  29. package/dist/cjs/features/metrics/instrument/index.js +1 -1
  30. package/dist/cjs/features/page_action/instrument/index.js +6 -6
  31. package/dist/cjs/features/page_view_event/aggregate/index.js +1 -1
  32. package/dist/cjs/features/page_view_event/aggregate/initialized-features.js +1 -1
  33. package/dist/cjs/features/page_view_event/instrument/index.js +1 -1
  34. package/dist/cjs/features/page_view_timing/aggregate/index.js +3 -3
  35. package/dist/cjs/features/page_view_timing/instrument/index.js +1 -1
  36. package/dist/cjs/features/session_replay/aggregate/index.js +2 -2
  37. package/dist/cjs/features/session_replay/instrument/index.js +1 -1
  38. package/dist/cjs/features/session_replay/shared/stylesheet-evaluator.js +1 -1
  39. package/dist/cjs/features/session_trace/aggregate/index.js +1 -1
  40. package/dist/cjs/features/session_trace/aggregate/trace/storage.js +2 -2
  41. package/dist/cjs/features/session_trace/instrument/index.js +1 -1
  42. package/dist/cjs/features/soft_navigations/aggregate/bel-node.js +1 -1
  43. package/dist/cjs/features/soft_navigations/aggregate/index.js +1 -1
  44. package/dist/cjs/features/soft_navigations/aggregate/interaction.js +5 -5
  45. package/dist/cjs/features/soft_navigations/instrument/index.js +1 -1
  46. package/dist/cjs/features/spa/aggregate/index.js +2 -3
  47. package/dist/cjs/features/spa/aggregate/interaction.js +2 -2
  48. package/dist/cjs/features/spa/aggregate/serializer.js +1 -2
  49. package/dist/cjs/features/spa/instrument/index.js +1 -1
  50. package/dist/cjs/features/utils/aggregate-base.js +2 -0
  51. package/dist/cjs/features/utils/lazy-feature-loader.js +2 -2
  52. package/dist/cjs/index.js +21 -0
  53. package/dist/cjs/loaders/agent-base.js +0 -4
  54. package/dist/cjs/loaders/api/api.js +1 -1
  55. package/dist/cjs/loaders/api/apiAsync.js +1 -1
  56. package/dist/cjs/loaders/browser-agent.js +4 -3
  57. package/dist/cjs/loaders/configure/configure.js +4 -3
  58. package/dist/cjs/loaders/features/features.js +8 -4
  59. package/dist/cjs/loaders/micro-agent.js +1 -1
  60. package/dist/esm/cdn/experimental.js +2 -5
  61. package/dist/esm/cdn/pro.js +2 -2
  62. package/dist/esm/cdn/spa.js +2 -2
  63. package/dist/esm/common/aggregate/aggregator.js +3 -3
  64. package/dist/esm/common/config/state/init.js +6 -3
  65. package/dist/esm/common/constants/env.cdn.js +1 -1
  66. package/dist/esm/common/constants/env.npm.js +1 -1
  67. package/dist/esm/common/constants/runtime.js +0 -2
  68. package/dist/esm/common/drain/drain.js +4 -4
  69. package/dist/esm/common/harvest/harvest.js +3 -3
  70. package/dist/esm/common/serialize/bel-serializer.js +2 -2
  71. package/dist/esm/common/session/session-entity.js +2 -2
  72. package/dist/esm/common/url/encode.js +3 -5
  73. package/dist/esm/common/util/submit-data.js +0 -1
  74. package/dist/esm/common/vitals/vital-metric.js +1 -1
  75. package/dist/esm/features/ajax/aggregate/index.js +1 -1
  76. package/dist/esm/features/ajax/instrument/index.js +1 -1
  77. package/dist/esm/features/generic_events/aggregate/index.js +129 -0
  78. package/dist/esm/features/generic_events/constants.js +2 -0
  79. package/dist/esm/features/generic_events/index.js +1 -0
  80. package/dist/esm/features/generic_events/instrument/index.js +20 -0
  81. package/dist/esm/features/jserrors/aggregate/index.js +13 -12
  82. package/dist/esm/features/jserrors/instrument/index.js +1 -1
  83. package/dist/esm/features/logging/aggregate/index.js +1 -1
  84. package/dist/esm/features/logging/instrument/index.js +1 -1
  85. package/dist/esm/features/metrics/aggregate/index.js +1 -1
  86. package/dist/esm/features/metrics/instrument/index.js +1 -1
  87. package/dist/esm/features/page_action/instrument/index.js +7 -6
  88. package/dist/esm/features/page_view_event/aggregate/index.js +1 -1
  89. package/dist/esm/features/page_view_event/aggregate/initialized-features.js +1 -1
  90. package/dist/esm/features/page_view_event/instrument/index.js +1 -1
  91. package/dist/esm/features/page_view_timing/aggregate/index.js +3 -3
  92. package/dist/esm/features/page_view_timing/instrument/index.js +1 -1
  93. package/dist/esm/features/session_replay/aggregate/index.js +2 -2
  94. package/dist/esm/features/session_replay/instrument/index.js +1 -1
  95. package/dist/esm/features/session_replay/shared/stylesheet-evaluator.js +1 -1
  96. package/dist/esm/features/session_trace/aggregate/index.js +1 -1
  97. package/dist/esm/features/session_trace/aggregate/trace/storage.js +2 -2
  98. package/dist/esm/features/session_trace/instrument/index.js +1 -1
  99. package/dist/esm/features/soft_navigations/aggregate/bel-node.js +1 -1
  100. package/dist/esm/features/soft_navigations/aggregate/index.js +1 -1
  101. package/dist/esm/features/soft_navigations/aggregate/interaction.js +5 -5
  102. package/dist/esm/features/soft_navigations/instrument/index.js +1 -1
  103. package/dist/esm/features/spa/aggregate/index.js +2 -3
  104. package/dist/esm/features/spa/aggregate/interaction.js +2 -2
  105. package/dist/esm/features/spa/aggregate/serializer.js +1 -2
  106. package/dist/esm/features/spa/instrument/index.js +1 -1
  107. package/dist/esm/features/utils/aggregate-base.js +3 -1
  108. package/dist/esm/features/utils/lazy-feature-loader.js +2 -2
  109. package/dist/esm/index.js +3 -0
  110. package/dist/esm/loaders/agent-base.js +0 -4
  111. package/dist/esm/loaders/api/api.js +1 -1
  112. package/dist/esm/loaders/api/apiAsync.js +1 -1
  113. package/dist/esm/loaders/browser-agent.js +3 -2
  114. package/dist/esm/loaders/configure/configure.js +4 -3
  115. package/dist/esm/loaders/features/features.js +8 -4
  116. package/dist/esm/loaders/micro-agent.js +1 -1
  117. package/dist/types/common/aggregate/aggregator.d.ts.map +1 -1
  118. package/dist/types/common/config/state/init.d.ts.map +1 -1
  119. package/dist/types/common/constants/runtime.d.ts +0 -1
  120. package/dist/types/common/constants/runtime.d.ts.map +1 -1
  121. package/dist/types/common/drain/drain.d.ts.map +1 -1
  122. package/dist/types/common/serialize/bel-serializer.d.ts.map +1 -1
  123. package/dist/types/common/url/encode.d.ts.map +1 -1
  124. package/dist/types/common/util/submit-data.d.ts.map +1 -1
  125. package/dist/types/features/{page_action → generic_events}/aggregate/index.d.ts +7 -5
  126. package/dist/types/features/generic_events/aggregate/index.d.ts.map +1 -0
  127. package/dist/types/features/generic_events/constants.d.ts +2 -0
  128. package/dist/types/features/generic_events/constants.d.ts.map +1 -0
  129. package/dist/types/features/generic_events/index.d.ts +2 -0
  130. package/dist/types/features/generic_events/index.d.ts.map +1 -0
  131. package/dist/types/features/generic_events/instrument/index.d.ts +6 -0
  132. package/dist/types/features/generic_events/instrument/index.d.ts.map +1 -0
  133. package/dist/types/features/jserrors/aggregate/index.d.ts.map +1 -1
  134. package/dist/types/features/page_action/instrument/index.d.ts +5 -4
  135. package/dist/types/features/page_action/instrument/index.d.ts.map +1 -1
  136. package/dist/types/features/page_view_timing/aggregate/index.d.ts.map +1 -1
  137. package/dist/types/features/spa/aggregate/index.d.ts.map +1 -1
  138. package/dist/types/features/spa/aggregate/interaction.d.ts.map +1 -1
  139. package/dist/types/features/spa/aggregate/serializer.d.ts.map +1 -1
  140. package/dist/types/features/utils/aggregate-base.d.ts.map +1 -1
  141. package/dist/types/index.d.ts +3 -0
  142. package/dist/types/loaders/agent-base.d.ts +0 -1
  143. package/dist/types/loaders/agent-base.d.ts.map +1 -1
  144. package/dist/types/loaders/browser-agent.d.ts.map +1 -1
  145. package/dist/types/loaders/configure/configure.d.ts.map +1 -1
  146. package/dist/types/loaders/features/features.d.ts +1 -0
  147. package/dist/types/loaders/features/features.d.ts.map +1 -1
  148. package/package.json +25 -6
  149. package/src/cdn/experimental.js +2 -4
  150. package/src/cdn/pro.js +2 -2
  151. package/src/cdn/spa.js +2 -2
  152. package/src/common/aggregate/aggregator.js +2 -3
  153. package/src/common/config/state/init.js +2 -1
  154. package/src/common/constants/runtime.js +0 -2
  155. package/src/common/drain/drain.js +3 -4
  156. package/src/common/harvest/harvest.js +3 -3
  157. package/src/common/serialize/bel-serializer.js +1 -2
  158. package/src/common/session/session-entity.js +2 -2
  159. package/src/common/url/encode.js +2 -3
  160. package/src/common/util/submit-data.js +0 -1
  161. package/src/features/generic_events/aggregate/index.js +133 -0
  162. package/src/features/generic_events/constants.js +3 -0
  163. package/src/features/generic_events/index.js +1 -0
  164. package/src/features/generic_events/instrument/index.js +22 -0
  165. package/src/features/jserrors/aggregate/index.js +4 -5
  166. package/src/features/page_action/instrument/index.js +6 -6
  167. package/src/features/page_view_event/aggregate/initialized-features.js +1 -1
  168. package/src/features/page_view_timing/aggregate/index.js +1 -2
  169. package/src/features/spa/aggregate/index.js +1 -2
  170. package/src/features/spa/aggregate/interaction.js +1 -2
  171. package/src/features/spa/aggregate/serializer.js +1 -2
  172. package/src/features/utils/aggregate-base.js +3 -1
  173. package/src/features/utils/lazy-feature-loader.js +2 -2
  174. package/src/index.js +3 -0
  175. package/src/loaders/agent-base.js +0 -4
  176. package/src/loaders/api/api.js +1 -1
  177. package/src/loaders/api/apiAsync.js +1 -1
  178. package/src/loaders/browser-agent.js +5 -3
  179. package/src/loaders/configure/configure.js +5 -1
  180. package/src/loaders/features/features.js +8 -4
  181. package/src/loaders/micro-agent.js +1 -1
  182. package/dist/cjs/cdn/polyfills/lite.js +0 -16
  183. package/dist/cjs/cdn/polyfills/pro.js +0 -21
  184. package/dist/cjs/cdn/polyfills/spa.js +0 -22
  185. package/dist/cjs/cdn/polyfills.js +0 -24
  186. package/dist/cjs/common/util/map-own.js +0 -31
  187. package/dist/cjs/features/page_action/aggregate/index.js +0 -121
  188. package/dist/esm/cdn/polyfills/lite.js +0 -14
  189. package/dist/esm/cdn/polyfills/pro.js +0 -19
  190. package/dist/esm/cdn/polyfills/spa.js +0 -20
  191. package/dist/esm/cdn/polyfills.js +0 -27
  192. package/dist/esm/common/util/map-own.js +0 -24
  193. package/dist/esm/features/page_action/aggregate/index.js +0 -114
  194. package/dist/types/cdn/polyfills/lite.d.ts +0 -2
  195. package/dist/types/cdn/polyfills/lite.d.ts.map +0 -1
  196. package/dist/types/cdn/polyfills/pro.d.ts +0 -2
  197. package/dist/types/cdn/polyfills/pro.d.ts.map +0 -1
  198. package/dist/types/cdn/polyfills/spa.d.ts +0 -2
  199. package/dist/types/cdn/polyfills/spa.d.ts.map +0 -1
  200. package/dist/types/cdn/polyfills.d.ts +0 -2
  201. package/dist/types/cdn/polyfills.d.ts.map +0 -1
  202. package/dist/types/common/util/map-own.d.ts +0 -3
  203. package/dist/types/common/util/map-own.d.ts.map +0 -1
  204. package/dist/types/features/page_action/aggregate/index.d.ts.map +0 -1
  205. package/src/cdn/polyfills/lite.js +0 -20
  206. package/src/cdn/polyfills/pro.js +0 -30
  207. package/src/cdn/polyfills/spa.js +0 -32
  208. package/src/cdn/polyfills.js +0 -27
  209. package/src/common/util/map-own.js +0 -22
  210. package/src/features/page_action/aggregate/index.js +0 -114
@@ -17,9 +17,8 @@ import { Instrument as InstrumentErrors } from '../features/jserrors/instrument'
17
17
  import { Instrument as InstrumentXhr } from '../features/ajax/instrument'
18
18
  import { Instrument as InstrumentSessionTrace } from '../features/session_trace/instrument'
19
19
  import { Instrument as InstrumentSessionReplay } from '../features/session_replay/instrument'
20
- // import { Instrument as InstrumentSpa } from '../features/spa/instrument'
20
+ import { Instrument as InstrumentGenericEvents } from '../features/generic_events/instrument'
21
21
  import { Instrument as InstrumentSoftNav } from '../features/soft_navigations/instrument'
22
- import { Instrument as InstrumentPageAction } from '../features/page_action/instrument'
23
22
  import { Instrument as InstrumentLogs } from '../features/logging/instrument'
24
23
 
25
24
  new Agent({
@@ -30,10 +29,9 @@ new Agent({
30
29
  InstrumentSessionTrace,
31
30
  InstrumentSessionReplay,
32
31
  InstrumentMetrics,
33
- InstrumentPageAction,
34
32
  InstrumentErrors,
33
+ InstrumentGenericEvents,
35
34
  InstrumentLogs,
36
- // InstrumentSpa,
37
35
  InstrumentSoftNav
38
36
  ],
39
37
  loaderType: 'experimental'
package/src/cdn/pro.js CHANGED
@@ -12,7 +12,7 @@ import { Instrument as InstrumentErrors } from '../features/jserrors/instrument'
12
12
  import { Instrument as InstrumentXhr } from '../features/ajax/instrument'
13
13
  import { Instrument as InstrumentSessionTrace } from '../features/session_trace/instrument'
14
14
  import { Instrument as InstrumentSessionReplay } from '../features/session_replay/instrument'
15
- import { Instrument as InstrumentPageAction } from '../features/page_action/instrument'
15
+ import { Instrument as InstrumentGenericEvents } from '../features/generic_events/instrument'
16
16
  import { Instrument as InstrumentLogs } from '../features/logging/instrument'
17
17
 
18
18
  new Agent({
@@ -23,8 +23,8 @@ new Agent({
23
23
  InstrumentSessionReplay,
24
24
  InstrumentXhr,
25
25
  InstrumentMetrics,
26
- InstrumentPageAction,
27
26
  InstrumentErrors,
27
+ InstrumentGenericEvents,
28
28
  InstrumentLogs
29
29
  ],
30
30
  loaderType: 'pro'
package/src/cdn/spa.js CHANGED
@@ -13,7 +13,7 @@ import { Instrument as InstrumentSessionTrace } from '../features/session_trace/
13
13
  import { Instrument as InstrumentSessionReplay } from '../features/session_replay/instrument'
14
14
  import { Instrument as InstrumentSoftNav } from '../features/soft_navigations/instrument'
15
15
  import { Instrument as InstrumentSpa } from '../features/spa/instrument'
16
- import { Instrument as InstrumentPageAction } from '../features/page_action/instrument'
16
+ import { Instrument as InstrumentGenericEvents } from '../features/generic_events/instrument'
17
17
  import { Instrument as InstrumentLogs } from '../features/logging/instrument'
18
18
 
19
19
  new Agent({
@@ -24,8 +24,8 @@ new Agent({
24
24
  InstrumentSessionTrace,
25
25
  InstrumentSessionReplay,
26
26
  InstrumentMetrics,
27
- InstrumentPageAction,
28
27
  InstrumentErrors,
28
+ InstrumentGenericEvents,
29
29
  InstrumentLogs,
30
30
  InstrumentSoftNav,
31
31
  InstrumentSpa // either the softnav or the old spa will be used (not both), but we still need to pack both to avoid dynamic import for instrument files
@@ -4,7 +4,6 @@
4
4
  */
5
5
 
6
6
  import { SharedContext } from '../context/shared-context'
7
- import { mapOwn } from '../util/map-own'
8
7
 
9
8
  export class Aggregator extends SharedContext {
10
9
  constructor (parent) {
@@ -34,7 +33,7 @@ export class Aggregator extends SharedContext {
34
33
  oldMetrics.count += metrics.count
35
34
 
36
35
  // iterate through each new metric and merge
37
- mapOwn(metrics, function (key, value) {
36
+ Object.keys(metrics || {}).forEach((key) => {
38
37
  // count is a special case handled above
39
38
  if (key === 'count') return
40
39
 
@@ -94,7 +93,7 @@ export class Aggregator extends SharedContext {
94
93
  function aggregateMetrics (newMetrics, oldMetrics) {
95
94
  if (!oldMetrics) oldMetrics = { count: 0 }
96
95
  oldMetrics.count += 1
97
- mapOwn(newMetrics, function (key, value) {
96
+ Object.entries(newMetrics || {}).forEach(([key, value]) => {
98
97
  oldMetrics[key] = updateMetric(value, oldMetrics[key])
99
98
  })
100
99
  return oldMetrics
@@ -41,12 +41,13 @@ const model = () => {
41
41
  allowed_origins: undefined
42
42
  },
43
43
  feature_flags: [],
44
+ generic_events: { enabled: true, harvestTimeSeconds: 30, autoStart: true },
44
45
  harvest: { tooManyRequestsDelay: 60 },
45
46
  jserrors: { enabled: true, harvestTimeSeconds: 10, autoStart: true },
46
47
  logging: { enabled: true, harvestTimeSeconds: 10, autoStart: true, level: LOG_LEVELS.INFO },
47
48
  metrics: { enabled: true, autoStart: true },
48
49
  obfuscate: undefined,
49
- page_action: { enabled: true, harvestTimeSeconds: 30, autoStart: true },
50
+ page_action: { enabled: true },
50
51
  page_view_event: { enabled: true, autoStart: true },
51
52
  page_view_timing: { enabled: true, harvestTimeSeconds: 30, long_task: false, autoStart: true },
52
53
  privacy: { cookies_enabled: true }, // *cli - per discussion, default should be true
@@ -72,8 +72,6 @@ export const ffVersion = (() => {
72
72
  return 0
73
73
  })()
74
74
 
75
- export const isIE = Boolean(isBrowserScope && window.document.documentMode) // deprecated property that only works in IE
76
-
77
75
  export const supportsSendBeacon = !!globalScope.navigator?.sendBeacon
78
76
 
79
77
  /**
@@ -4,7 +4,6 @@
4
4
  */
5
5
 
6
6
  import { ee } from '../event-emitter/contextual-ee'
7
- import { mapOwn } from '../util/map-own'
8
7
  import { registerHandler as defaultRegister } from '../event-emitter/register-handler'
9
8
  import { featurePriority } from '../../loaders/features/features'
10
9
 
@@ -102,8 +101,8 @@ function drainGroup (agentIdentifier, group, activateGroup = true) {
102
101
  emitEvent(bufferedEventsInGroup[i], groupHandlers)
103
102
  }
104
103
 
105
- mapOwn(groupHandlers, function (eventType, handlerRegistrationList) {
106
- mapOwn(handlerRegistrationList, function (i, registration) {
104
+ Object.entries(groupHandlers).forEach(([eventType, handlerRegistrationList]) => {
105
+ Object.values(handlerRegistrationList || {}).forEach((registration) => {
107
106
  // registration is an array of: [targetEE, eventHandler]
108
107
  registration[0].on(eventType, registration[1])
109
108
  })
@@ -125,7 +124,7 @@ function drainGroup (agentIdentifier, group, activateGroup = true) {
125
124
  */
126
125
  function emitEvent (evt, groupHandlers) {
127
126
  var type = evt[1]
128
- mapOwn(groupHandlers[type], function (i, registration) {
127
+ Object.values(groupHandlers[type] || {}).forEach((registration) => {
129
128
  var sourceEE = evt[0]
130
129
  var ee = registration[0]
131
130
  if (ee === sourceEE) {
@@ -14,7 +14,7 @@ import { Obfuscator } from '../util/obfuscate'
14
14
  import { applyFnToProps } from '../util/traverse'
15
15
  import { SharedContext } from '../context/shared-context'
16
16
  import { VERSION } from '../constants/env'
17
- import { isWorkerScope, isIE } from '../constants/runtime'
17
+ import { isWorkerScope } from '../constants/runtime'
18
18
  import { warn } from '../util/console'
19
19
  import { now } from '../timing/now'
20
20
 
@@ -137,8 +137,8 @@ export class Harvest extends SharedContext {
137
137
  /* Since workers don't support sendBeacon right now, they can only use XHR method.
138
138
  Because they still do permit synch XHR, the idea is that at final harvest time (worker is closing),
139
139
  we just make a BLOCKING request--trivial impact--with the remaining data as a temp fill-in for sendBeacon.
140
- Following the removal of img-element method, IE will also use sync XHR on page dismissal to ensure final analytics are sent. */
141
- let result = submitMethod({ url: fullUrl, body, sync: opts.unload && (isWorkerScope || isIE), headers })
140
+ Following the removal of img-element method. */
141
+ let result = submitMethod({ url: fullUrl, body, sync: opts.unload && (isWorkerScope), headers })
142
142
 
143
143
  if (!opts.unload && cbFinished && submitMethod === submitData.xhr) {
144
144
  const harvestScope = this
@@ -3,7 +3,6 @@
3
3
  * SPDX-License-Identifier: Apache-2.0
4
4
  */
5
5
 
6
- import { mapOwn } from '../util/map-own'
7
6
  import { stringify } from '../util/stringify'
8
7
  import { Obfuscator } from '../util/obfuscate'
9
8
 
@@ -47,7 +46,7 @@ export function getAddStringContext (agentIdentifier) {
47
46
  export function addCustomAttributes (attrs, addString) {
48
47
  var attrParts = []
49
48
 
50
- mapOwn(attrs, function (key, val) {
49
+ Object.entries(attrs || {}).forEach(([key, val]) => {
51
50
  if (attrParts.length >= MAX_ATTRIBUTES) return
52
51
  var type = 5
53
52
  var serializedValue
@@ -3,7 +3,7 @@ import { warn } from '../util/console'
3
3
  import { stringify } from '../util/stringify'
4
4
  import { ee } from '../event-emitter/contextual-ee'
5
5
  import { Timer } from '../timer/timer'
6
- import { isBrowserScope, isIE } from '../constants/runtime'
6
+ import { isBrowserScope } from '../constants/runtime'
7
7
  import { DEFAULT_EXPIRES_MS, DEFAULT_INACTIVE_MS, MODE, PREFIX, SESSION_EVENTS, SESSION_EVENT_TYPES } from './constants'
8
8
  import { InteractionTimer } from '../timer/interaction-timer'
9
9
  import { wrapEvents } from '../wrap'
@@ -57,7 +57,7 @@ export class SessionEntity {
57
57
  * if the event was spawned on the current page or an adjacent page, and the behavior tied
58
58
  * to storage events is critical to apply only to cross-tab behavior
59
59
  * */
60
- if (isBrowserScope && !isIE) {
60
+ if (isBrowserScope) {
61
61
  windowAddEventListener('storage', (event) => {
62
62
  if (event.key === this.lookupKey) {
63
63
  const obj = typeof event.newValue === 'string' ? JSON.parse(event.newValue) : event.newValue
@@ -3,7 +3,6 @@
3
3
  * SPDX-License-Identifier: Apache-2.0
4
4
  */
5
5
 
6
- import { mapOwn } from '../util/map-own'
7
6
  import { stringify } from '../util/stringify'
8
7
 
9
8
  // Characters that are safe in a qs, but get encoded.
@@ -16,7 +15,7 @@ var charMap = {
16
15
  '%3B': ';'
17
16
  }
18
17
 
19
- var charList = mapOwn(charMap, function (k) { return k })
18
+ var charList = Object.keys(charMap)
20
19
  var safeEncoded = new RegExp(charList.join('|'), 'g')
21
20
 
22
21
  function real (c) {
@@ -43,7 +42,7 @@ export function obj (payload, maxBytes) {
43
42
  var total = 0
44
43
  var result = ''
45
44
 
46
- mapOwn(payload, function (feature, dataArray) {
45
+ Object.entries(payload || {}).forEach(([feature, dataArray]) => {
47
46
  var intermediate = []
48
47
  var next
49
48
  var i
@@ -20,7 +20,6 @@ export function getSubmitMethod ({ isFinalHarvest = false } = {}) {
20
20
  return isFinalHarvest && isBrowserScope && supportsSendBeacon
21
21
  // Use sendBeacon for final harvest
22
22
  ? beacon
23
- // Only IE does not support sendBeacon for final harvest
24
23
  // If not final harvest, or not browserScope, always use xhr post
25
24
  : xhr
26
25
  }
@@ -0,0 +1,133 @@
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 { getConfigurationValue, getInfo, getRuntime } from '../../../common/config/config'
9
+ import { FEATURE_NAME } from '../constants'
10
+ import { isBrowserScope } from '../../../common/constants/runtime'
11
+ import { AggregateBase } from '../../utils/aggregate-base'
12
+ import { warn } from '../../../common/util/console'
13
+ import { now } from '../../../common/timing/now'
14
+ import { registerHandler } from '../../../common/event-emitter/register-handler'
15
+ import { deregisterDrain } from '../../../common/drain/drain'
16
+ import { SUPPORTABILITY_METRIC_CHANNEL } from '../../metrics/constants'
17
+
18
+ export class Aggregate extends AggregateBase {
19
+ #agentRuntime
20
+ static featureName = FEATURE_NAME
21
+ constructor (agentIdentifier, aggregator) {
22
+ super(agentIdentifier, aggregator, FEATURE_NAME)
23
+
24
+ this.eventsPerHarvest = 1000
25
+ this.harvestTimeSeconds = getConfigurationValue(this.agentIdentifier, 'generic_events.harvestTimeSeconds')
26
+
27
+ this.referrerUrl = (isBrowserScope && document.referrer) ? cleanURL(document.referrer) : undefined
28
+ this.currentEvents = []
29
+
30
+ this.events = []
31
+ this.overflow = []
32
+
33
+ this.#agentRuntime = getRuntime(this.agentIdentifier)
34
+
35
+ this.waitForFlags(['ins']).then(([ins]) => {
36
+ if (!ins) {
37
+ this.blocked = true
38
+ deregisterDrain(this.agentIdentifier, this.featureName)
39
+ return
40
+ }
41
+
42
+ if (getConfigurationValue(this.agentIdentifier, 'page_action.enabled')) {
43
+ registerHandler('api-addPageAction', (timestamp, name, attributes) => {
44
+ this.addEvent({
45
+ ...attributes,
46
+ eventType: 'PageAction',
47
+ timestamp: this.#agentRuntime.timeKeeper.convertRelativeTimestamp(timestamp),
48
+ timeSinceLoad: timestamp / 1000,
49
+ actionName: name,
50
+ referrerUrl: this.referrerUrl,
51
+ currentUrl: cleanURL('' + location),
52
+ ...(isBrowserScope && {
53
+ browserWidth: window.document.documentElement?.clientWidth,
54
+ browserHeight: window.document.documentElement?.clientHeight
55
+ })
56
+ })
57
+ }, this.featureName, this.ee)
58
+ }
59
+
60
+ this.harvestScheduler = new HarvestScheduler('ins', { onFinished: (...args) => this.onHarvestFinished(...args) }, this)
61
+ this.harvestScheduler.harvest.on('ins', (...args) => this.onHarvestStarted(...args))
62
+ this.harvestScheduler.startTimer(this.harvestTimeSeconds, 0)
63
+
64
+ this.drain()
65
+ })
66
+ }
67
+
68
+ onHarvestStarted (options) {
69
+ const { userAttributes, atts } = getInfo(this.agentIdentifier)
70
+ const harvestEvents = this.overflow.length ? this.overflow.splice(0, Infinity) : this.events.splice(0, Infinity)
71
+ var payload = ({
72
+ qs: {
73
+ ua: userAttributes,
74
+ at: atts
75
+ },
76
+ body: {
77
+ ins: harvestEvents
78
+ }
79
+ })
80
+
81
+ if (options.retry) {
82
+ this.currentEvents = harvestEvents
83
+ }
84
+
85
+ return payload
86
+ }
87
+
88
+ onHarvestFinished (result) {
89
+ if (result && result.sent && result.retry && this.currentEvents.length) {
90
+ this.events = this.currentEvents.concat(this.events)
91
+ this.currentEvents = []
92
+ }
93
+ }
94
+
95
+ // WARNING: Insights times are in seconds. EXCEPT timestamp, which is in ms.
96
+ addEvent (obj = {}) {
97
+ if (!obj || !Object.keys(obj).length) return
98
+ if (!obj.eventType) {
99
+ warn(44)
100
+ return
101
+ }
102
+
103
+ for (let key in obj) {
104
+ let val = obj[key]
105
+ obj[key] = (val && typeof val === 'object' ? stringify(val) : val)
106
+ }
107
+
108
+ const defaultEventAttributes = {
109
+ /** should be overridden by the event-specific attributes, but just in case -- set it to now() */
110
+ timestamp: this.#agentRuntime.timeKeeper.convertRelativeTimestamp(now()),
111
+ /** all generic events require a pageUrl */
112
+ pageUrl: cleanURL(getRuntime(this.agentIdentifier).origin)
113
+ }
114
+
115
+ const eventAttributes = {
116
+ /** Agent-level custom attributes */
117
+ ...(getInfo(this.agentIdentifier).jsAttributes || {}),
118
+ /** Fallbacks for required properties in-case the event did not supply them, should take precedence over agent-level custom attrs */
119
+ ...defaultEventAttributes,
120
+ /** Event-specific attributes take precedence over agent-level custom attributes and fallbacks */
121
+ ...obj
122
+ }
123
+
124
+ this.events.push(eventAttributes)
125
+
126
+ // check if we've reached the harvest limit...
127
+ if (this.events.length >= this.eventsPerHarvest) {
128
+ this.ee.emit(SUPPORTABILITY_METRIC_CHANNEL, ['GenericEvents/Harvest/Max/Seen'])
129
+ this.overflow = [...this.overflow, ...this.events.splice(0, Infinity)]
130
+ this.harvestScheduler.runHarvest()
131
+ }
132
+ }
133
+ }
@@ -0,0 +1,3 @@
1
+ import { FEATURE_NAMES } from '../../loaders/features/features'
2
+
3
+ export const FEATURE_NAME = FEATURE_NAMES.genericEvents
@@ -0,0 +1 @@
1
+ export { Instrument as GenericEvents } from './instrument/index'
@@ -0,0 +1,22 @@
1
+ /* Copyright 2020 New Relic Corporation. All rights reserved.
2
+ * SPDX-License-Identifier: Apache-2.0
3
+ */
4
+
5
+ import { getConfigurationValue } from '../../../common/config/config'
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
+ }
@@ -12,7 +12,6 @@ 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
15
  import { getInfo, getConfigurationValue, getRuntime } from '../../../common/config/config'
17
16
  import { globalScope } from '../../../common/constants/runtime'
18
17
 
@@ -91,7 +90,7 @@ export class Aggregate extends AggregateBase {
91
90
 
92
91
  onHarvestFinished (result) {
93
92
  if (result.retry && this.currentBody) {
94
- mapOwn(this.currentBody, (key, value) => {
93
+ Object.entries(this.currentBody || {}).forEach(([key, value]) => {
95
94
  for (var i = 0; i < value.length; i++) {
96
95
  var bucket = value[i]
97
96
  var name = this.getBucketName(key, bucket.params, bucket.custom)
@@ -264,8 +263,8 @@ export class Aggregate extends AggregateBase {
264
263
  var allCustomAttrs = {}
265
264
  const localCustomAttrs = item[4]
266
265
 
267
- mapOwn(interaction.root.attrs.custom, setCustom) // tack on custom attrs from the interaction
268
- mapOwn(localCustomAttrs, setCustom)
266
+ Object.entries(interaction.root.attrs.custom || {}).forEach(setCustom) // tack on custom attrs from the interaction
267
+ Object.entries(localCustomAttrs || {}).forEach(setCustom)
269
268
 
270
269
  var params = item[2]
271
270
  if (wasSaved) {
@@ -281,7 +280,7 @@ export class Aggregate extends AggregateBase {
281
280
 
282
281
  this.aggregator.store(item[0], aggregateHash, params, item[3], allCustomAttrs)
283
282
 
284
- function setCustom (key, val) {
283
+ function setCustom ([key, val]) {
285
284
  allCustomAttrs[key] = (val && typeof val === 'object' ? stringify(val) : val)
286
285
  }
287
286
  })
@@ -3,13 +3,13 @@
3
3
  * SPDX-License-Identifier: Apache-2.0
4
4
  */
5
5
 
6
- import { InstrumentBase } from '../../utils/instrument-base'
7
- import { FEATURE_NAME } from '../constants'
6
+ import { GenericEvents } from '../../generic_events'
8
7
 
9
- export class Instrument extends InstrumentBase {
10
- static featureName = FEATURE_NAME
8
+ /**
9
+ * @deprecated This feature has been replaced by Generic Events. Use/Import `GenericEvents` instead. This wrapper will be removed in a future release
10
+ */
11
+ export class Instrument extends GenericEvents {
11
12
  constructor (agentIdentifier, aggregator, auto = true) {
12
- super(agentIdentifier, aggregator, FEATURE_NAME, auto)
13
- this.importAggregator()
13
+ super(agentIdentifier, aggregator, auto)
14
14
  }
15
15
  }
@@ -18,7 +18,7 @@ export function getActivatedFeaturesFlags (agentId) {
18
18
  flagArr.push('xhr'); break
19
19
  case FEATURE_NAMES.jserrors:
20
20
  flagArr.push('err'); break
21
- case FEATURE_NAMES.pageAction:
21
+ case FEATURE_NAMES.genericEvents:
22
22
  flagArr.push('ins'); break
23
23
  case FEATURE_NAMES.sessionTrace:
24
24
  flagArr.push('stn'); break
@@ -4,7 +4,6 @@
4
4
  */
5
5
 
6
6
  import { nullable, numeric, getAddStringContext, addCustomAttributes } from '../../../common/serialize/bel-serializer'
7
- import { mapOwn } from '../../../common/util/map-own'
8
7
  import { HarvestScheduler } from '../../../common/harvest/harvest-scheduler'
9
8
  import { registerHandler } from '../../../common/event-emitter/register-handler'
10
9
  import { handle } from '../../../common/event-emitter/handle'
@@ -138,7 +137,7 @@ export class Aggregate extends AggregateBase {
138
137
 
139
138
  var reservedAttributes = ['size', 'eid', 'cls', 'type', 'fid', 'elTag', 'elUrl', 'net-type',
140
139
  'net-etype', 'net-rtt', 'net-dlink']
141
- mapOwn(customAttributes, function (key, val) {
140
+ Object.entries(customAttributes || {}).forEach(([key, val]) => {
142
141
  if (reservedAttributes.indexOf(key) < 0) {
143
142
  timingAttributes[key] = val
144
143
  }
@@ -6,7 +6,6 @@
6
6
  import { registerHandler as register } from '../../../common/event-emitter/register-handler'
7
7
  import { parseUrl } from '../../../common/url/parse-url'
8
8
  import { shouldCollectEvent } from '../../../common/deny-list/deny-list'
9
- import { mapOwn } from '../../../common/util/map-own'
10
9
  import { navTimingValues as navTiming } from '../../../common/timing/nav-timing'
11
10
  import { generateUuid } from '../../../common/ids/unique-id'
12
11
  import { Interaction } from './interaction'
@@ -668,7 +667,7 @@ export class Aggregate extends AggregateBase {
668
667
 
669
668
  // make sure that newrelic[INTERACTION]() works in end handler
670
669
  state.currentNode = root
671
- mapOwn(interaction.handlers, function (i, cb) {
670
+ Object.values(interaction.handlers || {}).forEach(function (cb) {
672
671
  cb(attrs.store)
673
672
  })
674
673
  setCurrentNode(null)
@@ -4,7 +4,6 @@
4
4
  */
5
5
 
6
6
  import { getInfo, getRuntime, originals } from '../../../common/config/config'
7
- import { mapOwn } from '../../../common/util/map-own'
8
7
  import { ee } from '../../../common/event-emitter/contextual-ee'
9
8
  import { InteractionNode } from './interaction-node'
10
9
 
@@ -101,7 +100,7 @@ InteractionPrototype.finish = function finishInteraction () {
101
100
  this.onFinished(this)
102
101
  }
103
102
 
104
- mapOwn(getInfo(interaction.agentIdentifier).jsAttributes, function (attr, value) {
103
+ Object.entries(getInfo(interaction.agentIdentifier).jsAttributes || {}).forEach(([attr, value]) => {
105
104
  if (!(attr in customAttrs)) customAttrs[attr] = value
106
105
  })
107
106
 
@@ -3,7 +3,6 @@
3
3
  * SPDX-License-Identifier: Apache-2.0
4
4
  */
5
5
  import { cleanURL } from '../../../common/url/clean-url'
6
- import { mapOwn } from '../../../common/util/map-own'
7
6
  import { nullable, numeric, getAddStringContext, addCustomAttributes } from '../../../common/serialize/bel-serializer'
8
7
  import { SharedContext } from '../../../common/context/shared-context'
9
8
  import { getInfo } from '../../../common/config/config'
@@ -181,7 +180,7 @@ export class Serializer extends SharedContext {
181
180
  // get all navTiming values except navigationStart
182
181
  // (since its the same as interaction.start)
183
182
  // and limit to just the first 20 values we know about
184
- mapOwn(navTiming.slice(1, 21), function (i, v) {
183
+ Object.values(navTiming.slice(1, 21) || {}).forEach((v) => {
185
184
  if (v !== undefined) {
186
185
  navTimingNode += seperator + numeric(v - prev)
187
186
  seperator = ','
@@ -2,7 +2,7 @@ import { FeatureBase } from './feature-base'
2
2
  import { getInfo, isConfigured, getRuntime } from '../../common/config/config'
3
3
  import { configure } from '../../loaders/configure/configure'
4
4
  import { gosCDN } from '../../common/window/nreum'
5
- import { drain } from '../../common/drain/drain'
5
+ import { deregisterDrain, drain } from '../../common/drain/drain'
6
6
  import { activatedFeatures } from '../../common/util/feature-flags'
7
7
 
8
8
  export class AggregateBase extends FeatureBase {
@@ -34,6 +34,8 @@ export class AggregateBase extends FeatureBase {
34
34
  })
35
35
  return flagsPromise.catch(err => {
36
36
  this.ee.emit('internal-error', [err])
37
+ this.blocked = true
38
+ deregisterDrain(this.agentIdentifier, this.featureName)
37
39
  })
38
40
  }
39
41
 
@@ -18,12 +18,12 @@ export function lazyFeatureLoader (featureName, featurePart) {
18
18
  return import(/* webpackChunkName: "ajax-aggregate" */ '../ajax/aggregate')
19
19
  case FEATURE_NAMES.jserrors:
20
20
  return import(/* webpackChunkName: "jserrors-aggregate" */ '../jserrors/aggregate')
21
+ case FEATURE_NAMES.genericEvents:
22
+ return import(/* webpackChunkName: "generic_events-aggregate" */ '../generic_events/aggregate')
21
23
  case FEATURE_NAMES.logging:
22
24
  return import(/* webpackChunkName: "logging-aggregate" */ '../logging/aggregate')
23
25
  case FEATURE_NAMES.metrics:
24
26
  return import(/* webpackChunkName: "metrics-aggregate" */ '../metrics/aggregate')
25
- case FEATURE_NAMES.pageAction:
26
- return import(/* webpackChunkName: "page_action-aggregate" */ '../page_action/aggregate')
27
27
  case FEATURE_NAMES.pageViewEvent:
28
28
  return import(/* webpackChunkName: "page_view_event-aggregate" */ '../page_view_event/aggregate')
29
29
  case FEATURE_NAMES.pageViewTiming:
package/src/index.js CHANGED
@@ -4,9 +4,12 @@ export { MicroAgent } from './loaders/micro-agent'
4
4
 
5
5
  export { Ajax } from './features/ajax'
6
6
  export { JSErrors } from './features/jserrors'
7
+ export { GenericEvents } from './features/generic_events'
8
+ export { Logging } from './features/logging'
7
9
  export { Metrics } from './features/metrics'
8
10
  export { PageAction } from './features/page_action'
9
11
  export { PageViewEvent } from './features/page_view_event'
10
12
  export { PageViewTiming } from './features/page_view_timing'
11
13
  export { SessionTrace } from './features/session_trace'
14
+ export { SessionReplay } from './features/session_replay'
12
15
  export { Spa } from './features/spa'
@@ -3,7 +3,6 @@
3
3
  import { warn } from '../common/util/console'
4
4
  import { SR_EVENT_EMITTER_TYPES } from '../features/session_replay/constants'
5
5
  import { generateRandomHexString } from '../common/ids/unique-id'
6
- import { ee } from '../common/event-emitter/contextual-ee'
7
6
 
8
7
  /**
9
8
  * @typedef {import('./api/interaction-types').InteractionInstance} InteractionInstance
@@ -14,9 +13,6 @@ export class AgentBase {
14
13
 
15
14
  constructor (agentIdentifier = generateRandomHexString(16)) {
16
15
  this.agentIdentifier = agentIdentifier
17
-
18
- // Assign the observation context to the event emitter, so it knows how to create observation contexts
19
- this.ee = ee.get(agentIdentifier)
20
16
  }
21
17
 
22
18
  /**
@@ -69,7 +69,7 @@ export function setAPI (agentIdentifier, forceDrain, runSoftNavOverSpa = false)
69
69
  // Setup stub functions that queue calls for later processing.
70
70
  asyncApiMethods.forEach(fnName => { apiInterface[fnName] = apiCall(prefix, fnName, true, 'api') })
71
71
 
72
- apiInterface.addPageAction = apiCall(prefix, 'addPageAction', true, FEATURE_NAMES.pageAction)
72
+ apiInterface.addPageAction = apiCall(prefix, 'addPageAction', true, FEATURE_NAMES.genericEvents)
73
73
 
74
74
  apiInterface.setPageViewName = function (name, host) {
75
75
  if (typeof name !== 'string') return
@@ -27,7 +27,7 @@ export function setAPI (agentIdentifier) {
27
27
  var time = providedTime ? providedTime - originTime : t
28
28
  handle(CUSTOM_METRIC_CHANNEL, ['finished', { time }], undefined, FEATURE_NAMES.metrics, instanceEE)
29
29
  addToTrace(t, { name: 'finished', start: time + originTime, origin: 'nr' })
30
- handle('api-addPageAction', [time, 'finished'], undefined, FEATURE_NAMES.pageAction, instanceEE)
30
+ handle('api-addPageAction', [time, 'finished'], undefined, FEATURE_NAMES.genericEvents, instanceEE)
31
31
  }
32
32
 
33
33
  function addToTrace (t, evt) {