@newrelic/browser-agent 1.269.0 → 1.270.1

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 (165) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/cjs/common/constants/env.cdn.js +1 -1
  3. package/dist/cjs/common/constants/env.npm.js +1 -1
  4. package/dist/cjs/common/constants/runtime.js +1 -2
  5. package/dist/cjs/common/harvest/harvest-scheduler.js +3 -4
  6. package/dist/cjs/common/unload/eol.js +2 -5
  7. package/dist/cjs/common/util/submit-data.js +1 -1
  8. package/dist/cjs/features/ajax/aggregate/index.js +8 -17
  9. package/dist/cjs/features/ajax/instrument/index.js +8 -10
  10. package/dist/cjs/features/generic_events/aggregate/index.js +15 -22
  11. package/dist/cjs/features/generic_events/instrument/index.js +5 -8
  12. package/dist/cjs/features/jserrors/aggregate/index.js +17 -22
  13. package/dist/cjs/features/jserrors/instrument/index.js +3 -3
  14. package/dist/cjs/features/logging/aggregate/index.js +16 -23
  15. package/dist/cjs/features/logging/instrument/index.js +3 -3
  16. package/dist/cjs/features/metrics/aggregate/index.js +13 -16
  17. package/dist/cjs/features/metrics/instrument/index.js +3 -3
  18. package/dist/cjs/features/page_view_event/aggregate/index.js +15 -29
  19. package/dist/cjs/features/page_view_event/instrument/index.js +3 -3
  20. package/dist/cjs/features/page_view_timing/aggregate/index.js +6 -23
  21. package/dist/cjs/features/page_view_timing/instrument/index.js +3 -3
  22. package/dist/cjs/features/session_replay/aggregate/index.js +15 -29
  23. package/dist/cjs/features/session_replay/instrument/index.js +7 -5
  24. package/dist/cjs/features/session_trace/aggregate/index.js +25 -31
  25. package/dist/cjs/features/session_trace/aggregate/trace/storage.js +1 -1
  26. package/dist/cjs/features/session_trace/instrument/index.js +4 -5
  27. package/dist/cjs/features/soft_navigations/aggregate/index.js +6 -11
  28. package/dist/cjs/features/soft_navigations/instrument/index.js +3 -3
  29. package/dist/cjs/features/spa/aggregate/index.js +19 -30
  30. package/dist/cjs/features/spa/instrument/index.js +4 -4
  31. package/dist/cjs/features/utils/aggregate-base.js +11 -12
  32. package/dist/cjs/features/utils/feature-base.js +5 -3
  33. package/dist/cjs/features/utils/instrument-base.js +18 -10
  34. package/dist/cjs/loaders/agent.js +1 -5
  35. package/dist/cjs/loaders/micro-agent.js +6 -9
  36. package/dist/esm/common/constants/env.cdn.js +1 -1
  37. package/dist/esm/common/constants/env.npm.js +1 -1
  38. package/dist/esm/common/constants/runtime.js +0 -1
  39. package/dist/esm/common/harvest/harvest-scheduler.js +3 -4
  40. package/dist/esm/common/unload/eol.js +2 -5
  41. package/dist/esm/common/util/submit-data.js +2 -2
  42. package/dist/esm/features/ajax/aggregate/index.js +8 -17
  43. package/dist/esm/features/ajax/instrument/index.js +8 -10
  44. package/dist/esm/features/generic_events/aggregate/index.js +11 -18
  45. package/dist/esm/features/generic_events/instrument/index.js +5 -8
  46. package/dist/esm/features/jserrors/aggregate/index.js +15 -20
  47. package/dist/esm/features/jserrors/instrument/index.js +3 -3
  48. package/dist/esm/features/logging/aggregate/index.js +16 -23
  49. package/dist/esm/features/logging/instrument/index.js +3 -3
  50. package/dist/esm/features/metrics/aggregate/index.js +8 -11
  51. package/dist/esm/features/metrics/instrument/index.js +3 -3
  52. package/dist/esm/features/page_view_event/aggregate/index.js +16 -30
  53. package/dist/esm/features/page_view_event/instrument/index.js +3 -3
  54. package/dist/esm/features/page_view_timing/aggregate/index.js +6 -23
  55. package/dist/esm/features/page_view_timing/instrument/index.js +3 -3
  56. package/dist/esm/features/session_replay/aggregate/index.js +13 -27
  57. package/dist/esm/features/session_replay/instrument/index.js +7 -5
  58. package/dist/esm/features/session_trace/aggregate/index.js +22 -28
  59. package/dist/esm/features/session_trace/aggregate/trace/storage.js +1 -1
  60. package/dist/esm/features/session_trace/instrument/index.js +4 -5
  61. package/dist/esm/features/soft_navigations/aggregate/index.js +6 -11
  62. package/dist/esm/features/soft_navigations/instrument/index.js +3 -3
  63. package/dist/esm/features/spa/aggregate/index.js +17 -28
  64. package/dist/esm/features/spa/instrument/index.js +4 -4
  65. package/dist/esm/features/utils/aggregate-base.js +13 -14
  66. package/dist/esm/features/utils/feature-base.js +5 -3
  67. package/dist/esm/features/utils/instrument-base.js +18 -10
  68. package/dist/esm/loaders/agent.js +1 -5
  69. package/dist/esm/loaders/micro-agent.js +6 -9
  70. package/dist/types/common/constants/runtime.d.ts +0 -1
  71. package/dist/types/common/constants/runtime.d.ts.map +1 -1
  72. package/dist/types/common/harvest/harvest-scheduler.d.ts.map +1 -1
  73. package/dist/types/common/unload/eol.d.ts +1 -1
  74. package/dist/types/common/unload/eol.d.ts.map +1 -1
  75. package/dist/types/features/ajax/aggregate/index.d.ts +1 -1
  76. package/dist/types/features/ajax/aggregate/index.d.ts.map +1 -1
  77. package/dist/types/features/ajax/instrument/index.d.ts +1 -1
  78. package/dist/types/features/ajax/instrument/index.d.ts.map +1 -1
  79. package/dist/types/features/generic_events/aggregate/index.d.ts +1 -2
  80. package/dist/types/features/generic_events/aggregate/index.d.ts.map +1 -1
  81. package/dist/types/features/generic_events/instrument/index.d.ts +1 -1
  82. package/dist/types/features/generic_events/instrument/index.d.ts.map +1 -1
  83. package/dist/types/features/jserrors/aggregate/index.d.ts +1 -1
  84. package/dist/types/features/jserrors/aggregate/index.d.ts.map +1 -1
  85. package/dist/types/features/jserrors/instrument/index.d.ts +1 -1
  86. package/dist/types/features/jserrors/instrument/index.d.ts.map +1 -1
  87. package/dist/types/features/logging/aggregate/index.d.ts +1 -2
  88. package/dist/types/features/logging/aggregate/index.d.ts.map +1 -1
  89. package/dist/types/features/logging/instrument/index.d.ts +1 -1
  90. package/dist/types/features/logging/instrument/index.d.ts.map +1 -1
  91. package/dist/types/features/metrics/aggregate/index.d.ts +1 -1
  92. package/dist/types/features/metrics/aggregate/index.d.ts.map +1 -1
  93. package/dist/types/features/metrics/instrument/index.d.ts +1 -1
  94. package/dist/types/features/metrics/instrument/index.d.ts.map +1 -1
  95. package/dist/types/features/page_action/instrument/index.d.ts +1 -0
  96. package/dist/types/features/page_action/instrument/index.d.ts.map +1 -1
  97. package/dist/types/features/page_view_event/aggregate/index.d.ts +1 -1
  98. package/dist/types/features/page_view_event/aggregate/index.d.ts.map +1 -1
  99. package/dist/types/features/page_view_event/instrument/index.d.ts +1 -1
  100. package/dist/types/features/page_view_event/instrument/index.d.ts.map +1 -1
  101. package/dist/types/features/page_view_timing/aggregate/index.d.ts +1 -5
  102. package/dist/types/features/page_view_timing/aggregate/index.d.ts.map +1 -1
  103. package/dist/types/features/page_view_timing/instrument/index.d.ts +1 -1
  104. package/dist/types/features/page_view_timing/instrument/index.d.ts.map +1 -1
  105. package/dist/types/features/session_replay/aggregate/index.d.ts +0 -1
  106. package/dist/types/features/session_replay/aggregate/index.d.ts.map +1 -1
  107. package/dist/types/features/session_replay/instrument/index.d.ts +1 -1
  108. package/dist/types/features/session_replay/instrument/index.d.ts.map +1 -1
  109. package/dist/types/features/session_trace/aggregate/index.d.ts +1 -3
  110. package/dist/types/features/session_trace/aggregate/index.d.ts.map +1 -1
  111. package/dist/types/features/session_trace/instrument/index.d.ts +1 -1
  112. package/dist/types/features/session_trace/instrument/index.d.ts.map +1 -1
  113. package/dist/types/features/soft_navigations/aggregate/index.d.ts +1 -1
  114. package/dist/types/features/soft_navigations/aggregate/index.d.ts.map +1 -1
  115. package/dist/types/features/soft_navigations/instrument/index.d.ts +1 -1
  116. package/dist/types/features/soft_navigations/instrument/index.d.ts.map +1 -1
  117. package/dist/types/features/spa/aggregate/index.d.ts +1 -1
  118. package/dist/types/features/spa/aggregate/index.d.ts.map +1 -1
  119. package/dist/types/features/spa/instrument/index.d.ts +1 -1
  120. package/dist/types/features/spa/instrument/index.d.ts.map +1 -1
  121. package/dist/types/features/utils/aggregate-base.d.ts +2 -2
  122. package/dist/types/features/utils/aggregate-base.d.ts.map +1 -1
  123. package/dist/types/features/utils/feature-base.d.ts +2 -3
  124. package/dist/types/features/utils/feature-base.d.ts.map +1 -1
  125. package/dist/types/features/utils/instrument-base.d.ts +3 -3
  126. package/dist/types/features/utils/instrument-base.d.ts.map +1 -1
  127. package/dist/types/loaders/agent.d.ts +0 -2
  128. package/dist/types/loaders/agent.d.ts.map +1 -1
  129. package/dist/types/loaders/micro-agent.d.ts +0 -2
  130. package/dist/types/loaders/micro-agent.d.ts.map +1 -1
  131. package/package.json +1 -1
  132. package/src/common/constants/__mocks__/runtime.js +0 -1
  133. package/src/common/constants/runtime.js +0 -2
  134. package/src/common/harvest/harvest-scheduler.js +3 -4
  135. package/src/common/unload/eol.js +2 -5
  136. package/src/common/util/submit-data.js +2 -2
  137. package/src/features/ajax/aggregate/index.js +8 -18
  138. package/src/features/ajax/instrument/index.js +8 -10
  139. package/src/features/generic_events/aggregate/index.js +11 -20
  140. package/src/features/generic_events/instrument/index.js +7 -10
  141. package/src/features/jserrors/aggregate/index.js +15 -20
  142. package/src/features/jserrors/instrument/index.js +3 -4
  143. package/src/features/logging/aggregate/index.js +15 -23
  144. package/src/features/logging/instrument/index.js +3 -3
  145. package/src/features/metrics/aggregate/index.js +8 -11
  146. package/src/features/metrics/instrument/index.js +3 -3
  147. package/src/features/page_view_event/aggregate/index.js +16 -22
  148. package/src/features/page_view_event/instrument/index.js +3 -3
  149. package/src/features/page_view_timing/aggregate/index.js +6 -23
  150. package/src/features/page_view_timing/instrument/index.js +3 -3
  151. package/src/features/session_replay/aggregate/index.js +13 -21
  152. package/src/features/session_replay/instrument/index.js +7 -5
  153. package/src/features/session_trace/aggregate/index.js +22 -28
  154. package/src/features/session_trace/aggregate/trace/storage.js +1 -1
  155. package/src/features/session_trace/instrument/index.js +4 -5
  156. package/src/features/soft_navigations/aggregate/index.js +6 -8
  157. package/src/features/soft_navigations/instrument/index.js +3 -3
  158. package/src/features/spa/aggregate/index.js +17 -26
  159. package/src/features/spa/instrument/index.js +4 -4
  160. package/src/features/utils/__mocks__/feature-base.js +1 -2
  161. package/src/features/utils/aggregate-base.js +13 -14
  162. package/src/features/utils/feature-base.js +6 -3
  163. package/src/features/utils/instrument-base.js +16 -10
  164. package/src/loaders/agent.js +1 -3
  165. package/src/loaders/micro-agent.js +7 -9
@@ -1,13 +1,9 @@
1
1
  import { registerHandler } from '../../../common/event-emitter/register-handler';
2
2
  import { HarvestScheduler } from '../../../common/harvest/harvest-scheduler';
3
- import { getInfo } from '../../../common/config/info';
4
- import { getConfigurationValue } from '../../../common/config/init';
5
- import { getRuntime } from '../../../common/config/runtime';
6
3
  import { FEATURE_NAME } from '../constants';
7
4
  import { AggregateBase } from '../../utils/aggregate-base';
8
5
  import { TraceStorage } from './trace/storage';
9
6
  import { obj as encodeObj } from '../../../common/url/encode';
10
- import { deregisterDrain } from '../../../common/drain/drain';
11
7
  import { globalScope } from '../../../common/constants/runtime';
12
8
  import { MODE, SESSION_EVENTS } from '../../../common/session/constants';
13
9
  import { applyFnToProps } from '../../../common/util/traverse';
@@ -17,14 +13,12 @@ const ERROR_MODE_SECONDS_WINDOW = 30 * 1000; // sliding window of nodes to track
17
13
  const QUERY_PARAM_PADDING = 5000;
18
14
  export class Aggregate extends AggregateBase {
19
15
  static featureName = FEATURE_NAME;
20
- constructor(agentIdentifier, aggregator) {
21
- super(agentIdentifier, aggregator, FEATURE_NAME);
22
- this.agentRuntime = getRuntime(agentIdentifier);
23
- this.agentInfo = getInfo(agentIdentifier);
16
+ constructor(agentRef) {
17
+ super(agentRef, FEATURE_NAME);
24
18
 
25
19
  /** A buffer to hold on to harvested traces in the case that a retry must be made later */
26
20
  this.sentTrace = null;
27
- this.harvestTimeSeconds = getConfigurationValue(agentIdentifier, 'session_trace.harvestTimeSeconds') || 30;
21
+ this.harvestTimeSeconds = agentRef.init.session_trace.harvestTimeSeconds || 30;
28
22
  /** Tied to the entitlement flag response from BCS. Will short circuit operations of the agg if false */
29
23
  this.entitled = undefined;
30
24
  /** A flag used to decide if the 30 node threshold should be ignored on the first harvest to ensure sending on the first payload */
@@ -40,12 +34,12 @@ export class Aggregate extends AggregateBase {
40
34
  /** Sets up event listeners, and initializes this module to run in the correct "mode". Can be triggered from a few places, but makes an effort to only set up listeners once */
41
35
  initialize(stMode, stEntitled, ignoreSession) {
42
36
  this.entitled ??= stEntitled;
43
- if (this.blocked || !this.entitled) return deregisterDrain(this.agentIdentifier, this.featureName);
37
+ if (this.blocked || !this.entitled) return this.deregisterDrain();
44
38
  if (!this.initialized) {
45
39
  this.initialized = true;
46
40
  /** Store session identifiers at initialization time to be cross-checked later at harvest time for session changes that are subject to race conditions */
47
- this.ptid = this.agentRuntime.ptid;
48
- this.sessionId = this.agentRuntime.session?.state.value;
41
+ this.ptid = this.agentRef.runtime.ptid;
42
+ this.sessionId = this.agentRef.runtime.session?.state.value;
49
43
  // The SessionEntity class can emit a message indicating the session was cleared and reset (expiry, inactivity). This feature must abort and never resume if that occurs.
50
44
  this.ee.on(SESSION_EVENTS.RESET, () => {
51
45
  if (this.blocked) return;
@@ -69,12 +63,12 @@ export class Aggregate extends AggregateBase {
69
63
 
70
64
  /** ST/SR sampling flow in BCS - https://drive.google.com/file/d/19hwt2oft-8Hh4RrjpLqEXfpP_9wYBLcq/view?usp=sharing */
71
65
  /** ST will run in the mode provided by BCS if the session IS NEW. If not... it will use the state of the session entity to determine what mode to run in */
72
- if (!this.agentRuntime.session.isNew && !ignoreSession) this.mode = this.agentRuntime.session.state.sessionTraceMode;else this.mode = stMode;
66
+ if (!this.agentRef.runtime.session.isNew && !ignoreSession) this.mode = this.agentRef.runtime.session.state.sessionTraceMode;else this.mode = stMode;
73
67
 
74
68
  /** If the mode is off, we do not want to hold up draining for other features, so we deregister the feature for now.
75
69
  * If it drains later (due to a mode change), data and handlers will instantly drain instead of waiting for the registry. */
76
- if (this.mode === MODE.OFF) return deregisterDrain(this.agentIdentifier, this.featureName);
77
- this.timeKeeper ??= this.agentRuntime.timeKeeper;
70
+ if (this.mode === MODE.OFF) return this.deregisterDrain();
71
+ this.timeKeeper ??= this.agentRef.runtime.timeKeeper;
78
72
  this.scheduler = new HarvestScheduler('browser/blobs', {
79
73
  onFinished: this.onHarvestFinished.bind(this),
80
74
  retryDelay: this.harvestTimeSeconds,
@@ -98,7 +92,7 @@ export class Aggregate extends AggregateBase {
98
92
  if (this.mode === MODE.ERROR) this.switchToFull();
99
93
  }, this.featureName, this.ee);
100
94
  }
101
- this.agentRuntime.session.write({
95
+ this.agentRef.runtime.session.write({
102
96
  sessionTraceMode: this.mode
103
97
  });
104
98
  this.drain();
@@ -116,7 +110,7 @@ export class Aggregate extends AggregateBase {
116
110
  this.traceStorage.prevStoredEvents.clear(); // release references to past events for GC
117
111
  if (!this.timeKeeper?.ready) return; // this should likely never happen, but just to be safe, we should never harvest if we cant correct time
118
112
  if (this.blocked || this.mode !== MODE.FULL || this.traceStorage.nodeCount === 0) return;
119
- if (this.sessionId !== this.agentRuntime.session?.state.value || this.ptid !== this.agentRuntime.ptid) return this.abort(3); // if something unexpected happened and we somehow still got to the point of harvesting after a session identifier changed, we should force-exit instead of harvesting
113
+ if (this.sessionId !== this.agentRef.runtime.session?.state.value || this.ptid !== this.agentRef.runtime.ptid) return this.abort(3); // if something unexpected happened and we somehow still got to the point of harvesting after a session identifier changed, we should force-exit instead of harvesting
120
114
  /** Get the ST nodes from the traceStorage buffer. This also returns helpful metadata about the payload. */
121
115
  const {
122
116
  stns,
@@ -127,12 +121,12 @@ export class Aggregate extends AggregateBase {
127
121
  if (options.retry) {
128
122
  this.sentTrace = stns;
129
123
  }
130
- const firstSessionHarvest = !this.agentRuntime.session.state.traceHarvestStarted;
131
- if (firstSessionHarvest) this.agentRuntime.session.write({
124
+ const firstSessionHarvest = !this.agentRef.runtime.session.state.traceHarvestStarted;
125
+ if (firstSessionHarvest) this.agentRef.runtime.session.write({
132
126
  traceHarvestStarted: true
133
127
  });
134
- const hasReplay = this.agentRuntime.session?.state.sessionReplayMode === 1;
135
- const endUserId = this.agentInfo?.jsAttributes?.['enduser.id'];
128
+ const hasReplay = this.agentRef.runtime.session?.state.sessionReplayMode === 1;
129
+ const endUserId = this.agentRef.info?.jsAttributes?.['enduser.id'];
136
130
  this.everHarvested = true;
137
131
 
138
132
  /** The blob consumer expects the following and will reject if not supplied:
@@ -144,19 +138,19 @@ export class Aggregate extends AggregateBase {
144
138
  *
145
139
  * For data that does not fit the schema of the above, it should be url-encoded and placed into `attributes`
146
140
  */
147
- const agentMetadata = this.agentRuntime.appMetadata?.agents?.[0] || {};
141
+ const agentMetadata = this.agentRef.runtime.appMetadata?.agents?.[0] || {};
148
142
  return {
149
143
  qs: {
150
- browser_monitoring_key: this.agentInfo.licenseKey,
144
+ browser_monitoring_key: this.agentRef.info.licenseKey,
151
145
  type: 'BrowserSessionChunk',
152
- app_id: this.agentInfo.applicationID,
146
+ app_id: this.agentRef.info.applicationID,
153
147
  protocol_version: '0',
154
148
  timestamp: Math.floor(this.timeKeeper.correctRelativeTimestamp(earliestTimeStamp)),
155
149
  attributes: encodeObj({
156
150
  ...(agentMetadata.entityGuid && {
157
151
  entityGuid: agentMetadata.entityGuid
158
152
  }),
159
- harvestId: "".concat(this.agentRuntime.session?.state.value, "_").concat(this.agentRuntime.ptid, "_").concat(this.agentRuntime.harvestCount),
153
+ harvestId: "".concat(this.agentRef.runtime.session?.state.value, "_").concat(this.agentRef.runtime.ptid, "_").concat(this.agentRef.runtime.harvestCount),
160
154
  // this section of attributes must be controllable and stay below the query param padding limit -- see QUERY_PARAM_PADDING
161
155
  // if not, data could be lost to truncation at time of sending, potentially breaking parsing / API behavior in NR1
162
156
  // trace payload metadata
@@ -165,7 +159,7 @@ export class Aggregate extends AggregateBase {
165
159
  'trace.nodes': stns.length,
166
160
  'trace.originTimestamp': this.timeKeeper.correctedOriginTime,
167
161
  // other payload metadata
168
- agentVersion: this.agentRuntime.version,
162
+ agentVersion: this.agentRef.runtime.version,
169
163
  ...(firstSessionHarvest && {
170
164
  firstSessionHarvest
171
165
  }),
@@ -204,7 +198,7 @@ export class Aggregate extends AggregateBase {
204
198
  if (this.mode === MODE.FULL || !this.entitled || this.blocked) return;
205
199
  const prevMode = this.mode;
206
200
  this.mode = MODE.FULL;
207
- this.agentRuntime.session.write({
201
+ this.agentRef.runtime.session.write({
208
202
  sessionTraceMode: this.mode
209
203
  });
210
204
  if (prevMode === MODE.OFF || !this.initialized) return this.initialize(this.mode, this.entitled);
@@ -218,7 +212,7 @@ export class Aggregate extends AggregateBase {
218
212
  abort(reason) {
219
213
  this.blocked = true;
220
214
  this.mode = MODE.OFF;
221
- this.agentRuntime.session.write({
215
+ this.agentRef.runtime.session.write({
222
216
  sessionTraceMode: this.mode
223
217
  });
224
218
  this.scheduler?.stopTimer();
@@ -46,7 +46,7 @@ export class TraceStorage {
46
46
  if (this.parent.blocked) return;
47
47
  if (this.nodeCount >= MAX_NODES_PER_HARVEST) {
48
48
  // limit the amount of pending data awaiting next harvest
49
- if (this.parent.agentRuntime.session.state.sessionTraceMode !== MODE.ERROR) return;
49
+ if (this.parent.mode !== MODE.ERROR) return;
50
50
  const openedSpace = this.trimSTNs(ERROR_MODE_SECONDS_WINDOW); // but maybe we could make some space by discarding irrelevant nodes if we're in sessioned Error mode
51
51
  if (openedSpace === 0) return;
52
52
  }
@@ -8,7 +8,6 @@ import { wrapEvents } from '../../../common/wrap/wrap-events';
8
8
  import { InstrumentBase } from '../../utils/instrument-base';
9
9
  import * as CONSTANTS from '../constants';
10
10
  import { FEATURE_NAMES } from '../../../loaders/features/features';
11
- import { deregisterDrain } from '../../../common/drain/drain';
12
11
  import { canEnableSessionTracking } from '../../utils/feature-gates';
13
12
  import { now } from '../../../common/timing/now';
14
13
  const {
@@ -23,11 +22,11 @@ const {
23
22
  } = CONSTANTS;
24
23
  export class Instrument extends InstrumentBase {
25
24
  static featureName = FEATURE_NAME;
26
- constructor(agentIdentifier, aggregator, auto = true) {
27
- super(agentIdentifier, aggregator, FEATURE_NAME, auto);
25
+ constructor(agentRef, auto = true) {
26
+ super(agentRef, FEATURE_NAME, auto);
28
27
  const canTrackSession = canEnableSessionTracking(this.agentIdentifier);
29
28
  if (!canTrackSession) {
30
- deregisterDrain(this.agentIdentifier, this.featureName);
29
+ this.deregisterDrain();
31
30
  return;
32
31
  }
33
32
  const thisInstrumentEE = this.ee;
@@ -63,7 +62,7 @@ export class Instrument extends InstrumentBase {
63
62
  } catch (e) {
64
63
  // Per NEWRELIC-8525, we don't have a fallback for capturing resources for older versions that don't support PO at this time.
65
64
  }
66
- this.importAggregator({
65
+ this.importAggregator(agentRef, {
67
66
  resourceObserver: observer
68
67
  });
69
68
  }
@@ -1,5 +1,3 @@
1
- import { getConfigurationValue } from '../../../common/config/init';
2
- import { deregisterDrain } from '../../../common/drain/drain';
3
1
  import { handle } from '../../../common/event-emitter/handle';
4
2
  import { registerHandler } from '../../../common/event-emitter/register-handler';
5
3
  import { HarvestScheduler } from '../../../common/harvest/harvest-scheduler';
@@ -15,14 +13,14 @@ import { InitialPageLoadInteraction } from './initial-page-load-interaction';
15
13
  import { Interaction } from './interaction';
16
14
  export class Aggregate extends AggregateBase {
17
15
  static featureName = FEATURE_NAME;
18
- constructor(agentIdentifier, aggregator, {
16
+ constructor(agentRef, {
19
17
  domObserver
20
18
  }) {
21
- super(agentIdentifier, aggregator, FEATURE_NAME);
22
- const harvestTimeSeconds = getConfigurationValue(agentIdentifier, 'soft_navigations.harvestTimeSeconds') || 10;
19
+ super(agentRef, FEATURE_NAME);
20
+ const harvestTimeSeconds = agentRef.init.soft_navigations.harvestTimeSeconds || 10;
23
21
  this.interactionsToHarvest = new EventBuffer();
24
22
  this.domObserver = domObserver;
25
- this.initialPageLoadInteraction = new InitialPageLoadInteraction(agentIdentifier);
23
+ this.initialPageLoadInteraction = new InitialPageLoadInteraction(agentRef.agentIdentifier);
26
24
  timeToFirstByte.subscribe(({
27
25
  attrs
28
26
  }) => {
@@ -45,15 +43,12 @@ export class Aggregate extends AggregateBase {
45
43
  onFinished: this.onHarvestFinished.bind(this),
46
44
  retryDelay: harvestTimeSeconds,
47
45
  onUnload: () => this.interactionInProgress?.done() // return any held ajax or jserr events so they can be sent with EoL harvest
48
- }, {
49
- agentIdentifier,
50
- ee: this.ee
51
- });
46
+ }, this);
52
47
  scheduler.harvest.on('events', this.onHarvestStarted.bind(this));
53
48
  scheduler.startTimer(harvestTimeSeconds, 0);
54
49
  } else {
55
50
  this.blocked = true; // if rum response determines that customer lacks entitlements for spa endpoint, this feature shouldn't harvest
56
- deregisterDrain(this.agentIdentifier, this.featureName);
51
+ this.deregisterDrain();
57
52
  }
58
53
  });
59
54
 
@@ -18,8 +18,8 @@ const UI_WAIT_INTERVAL = 1 / 10 * 1000; // assume 10 fps
18
18
 
19
19
  export class Instrument extends InstrumentBase {
20
20
  static featureName = FEATURE_NAME;
21
- constructor(agentIdentifier, aggregator, auto = true) {
22
- super(agentIdentifier, aggregator, FEATURE_NAME, auto);
21
+ constructor(agentRef, auto = true) {
22
+ super(agentRef, FEATURE_NAME, auto);
23
23
  if (!isBrowserScope || !gosNREUMOriginals().o.MO) return; // soft navigations is not supported outside web env or browsers without the mutation observer API
24
24
 
25
25
  const historyEE = wrapHistory(this.ee);
@@ -61,7 +61,7 @@ export class Instrument extends InstrumentBase {
61
61
  });
62
62
  for (let eventType of INTERACTION_TRIGGERS) document.addEventListener(eventType, () => {/* no-op, this ensures the UI events are monitored by our callback above */});
63
63
  this.abortHandler = abort;
64
- this.importAggregator({
64
+ this.importAggregator(agentRef, {
65
65
  domObserver
66
66
  });
67
67
  function abort() {
@@ -9,8 +9,6 @@ import { shouldCollectEvent } from '../../../common/deny-list/deny-list';
9
9
  import { navTimingValues as navTiming } from '../../../common/timing/nav-timing';
10
10
  import { generateUuid } from '../../../common/ids/unique-id';
11
11
  import { Interaction } from './interaction';
12
- import { getConfigurationValue } from '../../../common/config/init';
13
- import { getRuntime } from '../../../common/config/runtime';
14
12
  import { eventListenerOpts } from '../../../common/event-listener/event-listener-opts';
15
13
  import { HarvestScheduler } from '../../../common/harvest/harvest-scheduler';
16
14
  import { Serializer } from './serializer';
@@ -24,7 +22,6 @@ import { bundleId } from '../../../common/ids/bundle-id';
24
22
  import { loadedAsDeferredBrowserScript } from '../../../common/constants/runtime';
25
23
  import { handle } from '../../../common/event-emitter/handle';
26
24
  import { SUPPORTABILITY_METRIC_CHANNEL } from '../../metrics/constants';
27
- import { deregisterDrain } from '../../../common/drain/drain';
28
25
  import { warn } from '../../../common/util/console';
29
26
  import { EventBuffer } from '../../utils/event-buffer';
30
27
  const {
@@ -47,12 +44,11 @@ const {
47
44
  } = CONSTANTS;
48
45
  export class Aggregate extends AggregateBase {
49
46
  static featureName = FEATURE_NAME;
50
- constructor(agentIdentifier, aggregator) {
51
- super(agentIdentifier, aggregator, FEATURE_NAME);
52
- const agentRuntime = getRuntime(agentIdentifier);
47
+ constructor(agentRef) {
48
+ super(agentRef, FEATURE_NAME);
53
49
  this.state = {
54
- initialPageURL: agentRuntime.origin,
55
- lastSeenUrl: agentRuntime.origin,
50
+ initialPageURL: agentRef.runtime.origin,
51
+ lastSeenUrl: agentRef.runtime.origin,
56
52
  lastSeenRouteName: null,
57
53
  timerMap: {},
58
54
  timerBudget: MAX_TIMER_BUDGET,
@@ -63,10 +59,10 @@ export class Aggregate extends AggregateBase {
63
59
  pageLoaded: false,
64
60
  childTime: 0,
65
61
  depth: 0,
66
- harvestTimeSeconds: getConfigurationValue(agentIdentifier, 'spa.harvestTimeSeconds') || 10,
62
+ harvestTimeSeconds: agentRef.init.spa.harvestTimeSeconds || 10,
67
63
  interactionsToHarvest: new EventBuffer(),
68
64
  // The below feature flag is used to disable the SPA ajax fix for specific customers, see https://new-relic.atlassian.net/browse/NR-172169
69
- disableSpaFix: (getConfigurationValue(agentIdentifier, 'feature_flags') || []).indexOf('disable-spa-fix') > -1
65
+ disableSpaFix: (agentRef.init.feature_flags || []).indexOf('disable-spa-fix') > -1
70
66
  };
71
67
  let scheduler;
72
68
  this.serializer = new Serializer(this);
@@ -74,7 +70,7 @@ export class Aggregate extends AggregateBase {
74
70
  state,
75
71
  serializer
76
72
  } = this;
77
- const baseEE = ee.get(agentIdentifier); // <-- parent baseEE
73
+ const baseEE = ee.get(agentRef.agentIdentifier); // <-- parent baseEE
78
74
  const mutationEE = baseEE.get('mutation');
79
75
  const promiseEE = baseEE.get('promise');
80
76
  const historyEE = baseEE.get('history');
@@ -122,19 +118,16 @@ export class Aggregate extends AggregateBase {
122
118
  scheduler = new HarvestScheduler('events', {
123
119
  onFinished: onHarvestFinished,
124
120
  retryDelay: state.harvestTimeSeconds
125
- }, {
126
- agentIdentifier,
127
- ee: baseEE
128
- });
121
+ }, this);
129
122
  scheduler.harvest.on('events', onHarvestStarted);
130
123
  this.drain();
131
124
  } else {
132
125
  this.blocked = true;
133
- deregisterDrain(this.agentIdentifier, this.featureName);
126
+ this.deregisterDrain();
134
127
  }
135
128
  });
136
- if (!isEnabled()) return;
137
- state.initialPageLoad = new Interaction('initialPageLoad', 0, state.lastSeenUrl, state.lastSeenRouteName, onInteractionFinished, agentIdentifier);
129
+ if (agentRef.init.spa.enabled !== true) return;
130
+ state.initialPageLoad = new Interaction('initialPageLoad', 0, state.lastSeenUrl, state.lastSeenRouteName, onInteractionFinished, agentRef.agentIdentifier);
138
131
  state.initialPageLoad.save = true;
139
132
  state.prevInteraction = state.initialPageLoad;
140
133
  state.currentNode = state.initialPageLoad.root; // hint
@@ -215,7 +208,7 @@ export class Aggregate extends AggregateBase {
215
208
  // Otherwise, if no interaction is currently active, create a new node ID,
216
209
  // and let the aggregator know that we entered a new event handler callback
217
210
  // so that it has a chance to possibly start an interaction.
218
- var ixn = new Interaction(evName, this[FN_START], state.lastSeenUrl, state.lastSeenRouteName, onInteractionFinished, agentIdentifier);
211
+ var ixn = new Interaction(evName, this[FN_START], state.lastSeenUrl, state.lastSeenRouteName, onInteractionFinished, agentRef.agentIdentifier);
219
212
 
220
213
  // Store the interaction as prevInteraction in case it is prematurely discarded
221
214
  state.prevInteraction = ixn;
@@ -306,7 +299,7 @@ export class Aggregate extends AggregateBase {
306
299
  this.sent = true;
307
300
  node.dt = this.dt;
308
301
  if (node.dt?.timestamp) {
309
- node.dt.timestamp = agentRuntime.timeKeeper.correctAbsoluteTimestamp(node.dt.timestamp);
302
+ node.dt.timestamp = agentRef.runtime.timeKeeper.correctAbsoluteTimestamp(node.dt.timestamp);
310
303
  }
311
304
  node.jsEnd = node.start = this.startTime;
312
305
  node[INTERACTION][REMAINING]++;
@@ -395,7 +388,7 @@ export class Aggregate extends AggregateBase {
395
388
  if (dtPayload && this[SPA_NODE]) {
396
389
  this[SPA_NODE].dt = dtPayload;
397
390
  if (this[SPA_NODE].dt?.timestamp) {
398
- this[SPA_NODE].dt.timestamp = agentRuntime.timeKeeper.correctAbsoluteTimestamp(this[SPA_NODE].dt.timestamp);
391
+ this[SPA_NODE].dt.timestamp = agentRef.runtime.timeKeeper.correctAbsoluteTimestamp(this[SPA_NODE].dt.timestamp);
399
392
  }
400
393
  }
401
394
  }
@@ -513,7 +506,7 @@ export class Aggregate extends AggregateBase {
513
506
  }, this.featureName, promiseEE);
514
507
  register(INTERACTION_API + 'get', function (t) {
515
508
  var interaction;
516
- if (state?.currentNode?.[INTERACTION]) interaction = this.ixn = state.currentNode[INTERACTION];else if (state?.prevNode?.end === null && state?.prevNode?.[INTERACTION]?.root?.[INTERACTION]?.eventName !== 'initialPageLoad') interaction = this.ixn = state.prevNode[INTERACTION];else interaction = this.ixn = new Interaction('api', t, state.lastSeenUrl, state.lastSeenRouteName, onInteractionFinished, agentIdentifier);
509
+ if (state?.currentNode?.[INTERACTION]) interaction = this.ixn = state.currentNode[INTERACTION];else if (state?.prevNode?.end === null && state?.prevNode?.[INTERACTION]?.root?.[INTERACTION]?.eventName !== 'initialPageLoad') interaction = this.ixn = state.prevNode[INTERACTION];else interaction = this.ixn = new Interaction('api', t, state.lastSeenUrl, state.lastSeenRouteName, onInteractionFinished, agentRef.agentIdentifier);
517
510
  if (!state.currentNode) {
518
511
  interaction.checkFinish();
519
512
  if (state.depth) setCurrentNode(interaction.root);
@@ -642,11 +635,11 @@ export class Aggregate extends AggregateBase {
642
635
  register('function-err', function (args, obj, error) {
643
636
  if (!state.currentNode) return;
644
637
  error.__newrelic ??= {};
645
- error.__newrelic[agentIdentifier] = {
638
+ error.__newrelic[agentRef.agentIdentifier] = {
646
639
  interactionId: state.currentNode.interaction.id
647
640
  };
648
641
  if (state.currentNode.type && state.currentNode.type !== 'interaction') {
649
- error.__newrelic[agentIdentifier].interactionNodeId = state.currentNode.id;
642
+ error.__newrelic[agentRef.agentIdentifier].interactionNodeId = state.currentNode.id;
650
643
  }
651
644
  }, this.featureName, baseEE);
652
645
  baseEE.on('interaction', saveInteraction);
@@ -684,9 +677,5 @@ export class Aggregate extends AggregateBase {
684
677
  scheduler?.scheduleHarvest(0);
685
678
  if (!scheduler) warn(19);
686
679
  }
687
- function isEnabled() {
688
- var enabled = getConfigurationValue(agentIdentifier, 'spa.enabled');
689
- return enabled !== false;
690
- }
691
680
  }
692
681
  }
@@ -33,8 +33,8 @@ const {
33
33
  */
34
34
  export class Instrument extends InstrumentBase {
35
35
  static featureName = FEATURE_NAME;
36
- constructor(agentIdentifier, aggregator, auto = true) {
37
- super(agentIdentifier, aggregator, FEATURE_NAME, auto);
36
+ constructor(agentRef, auto = true) {
37
+ super(agentRef, FEATURE_NAME, auto);
38
38
  if (!isBrowserScope) return; // SPA not supported outside web env
39
39
 
40
40
  try {
@@ -58,7 +58,7 @@ export class Instrument extends InstrumentBase {
58
58
  promiseEE.on(CB_END, endTimestamp);
59
59
  jsonpEE.on(CB_END, endTimestamp);
60
60
  this.ee.on('fn-err', (...args) => {
61
- if (!args[2]?.__newrelic?.[agentIdentifier]) handle('function-err', [...args], undefined, this.featureName, this.ee);
61
+ if (!args[2]?.__newrelic?.[agentRef.agentIdentifier]) handle('function-err', [...args], undefined, this.featureName, this.ee);
62
62
  });
63
63
  this.ee.buffer([FN_START, FN_END, 'xhr-resolved'], this.featureName);
64
64
  eventsEE.buffer([FN_START], this.featureName);
@@ -105,7 +105,7 @@ export class Instrument extends InstrumentBase {
105
105
  });
106
106
  }
107
107
  this.abortHandler = this.#abort;
108
- this.importAggregator();
108
+ this.importAggregator(agentRef);
109
109
  }
110
110
 
111
111
  /** Restoration and resource release tasks to be done if SPA loader is being aborted. Unwind changes to globals and subscription to DOM events. */
@@ -1,16 +1,16 @@
1
1
  import { FeatureBase } from './feature-base';
2
- import { getInfo, isValid } from '../../common/config/info';
3
- import { getRuntime } from '../../common/config/runtime';
2
+ import { isValid } from '../../common/config/info';
4
3
  import { configure } from '../../loaders/configure/configure';
5
4
  import { gosCDN } from '../../common/window/nreum';
6
- import { deregisterDrain, drain } from '../../common/drain/drain';
5
+ import { drain } from '../../common/drain/drain';
7
6
  import { activatedFeatures } from '../../common/util/feature-flags';
8
7
  import { Obfuscator } from '../../common/util/obfuscate';
9
8
  export class AggregateBase extends FeatureBase {
10
- constructor(...args) {
11
- super(...args);
12
- this.checkConfiguration();
13
- this.obfuscator = getRuntime(this.agentIdentifier).obfuscator;
9
+ constructor(agentRef, featureName) {
10
+ super(agentRef.agentIdentifier, featureName);
11
+ this.agentRef = agentRef;
12
+ this.checkConfiguration(agentRef);
13
+ this.obfuscator = agentRef.runtime.obfuscator;
14
14
  }
15
15
 
16
16
  /**
@@ -37,7 +37,7 @@ export class AggregateBase extends FeatureBase {
37
37
  return flagsPromise.catch(err => {
38
38
  this.ee.emit('internal-error', [err]);
39
39
  this.blocked = true;
40
- deregisterDrain(this.agentIdentifier, this.featureName);
40
+ this.deregisterDrain();
41
41
  });
42
42
  }
43
43
  drain() {
@@ -49,7 +49,7 @@ export class AggregateBase extends FeatureBase {
49
49
  * Checks for additional `jsAttributes` items to support backward compatibility with implementations of the agent where
50
50
  * loader configurations may appear after the loader code is executed.
51
51
  */
52
- checkConfiguration() {
52
+ checkConfiguration(existingAgent) {
53
53
  // NOTE: This check has to happen at aggregator load time
54
54
  if (!isValid(this.agentIdentifier)) {
55
55
  const cdn = gosCDN();
@@ -59,7 +59,7 @@ export class AggregateBase extends FeatureBase {
59
59
  try {
60
60
  jsAttributes = {
61
61
  ...jsAttributes,
62
- ...getInfo(this.agentIdentifier)?.jsAttributes
62
+ ...existingAgent.info?.jsAttributes
63
63
  };
64
64
  } catch (err) {
65
65
  // do nothing
@@ -72,12 +72,11 @@ export class AggregateBase extends FeatureBase {
72
72
  ...cdn.info,
73
73
  jsAttributes
74
74
  },
75
- runtime: getRuntime(this.agentIdentifier)
75
+ runtime: existingAgent.runtime
76
76
  });
77
77
  }
78
- const runtime = getRuntime(this.agentIdentifier);
79
- if (!runtime.obfuscator) {
80
- runtime.obfuscator = new Obfuscator(this.agentIdentifier);
78
+ if (!existingAgent.runtime.obfuscator) {
79
+ existingAgent.runtime.obfuscator = new Obfuscator(this.agentIdentifier);
81
80
  }
82
81
  }
83
82
  }
@@ -1,10 +1,9 @@
1
1
  import { ee } from '../../common/event-emitter/contextual-ee';
2
+ import { deregisterDrain } from '../../common/drain/drain';
2
3
  export class FeatureBase {
3
- constructor(agentIdentifier, aggregator, featureName) {
4
+ constructor(agentIdentifier, featureName) {
4
5
  /** @type {string} */
5
6
  this.agentIdentifier = agentIdentifier;
6
- /** @type {import('../../common/aggregate/aggregator').Aggregator} */
7
- this.aggregator = aggregator;
8
7
  /** @type {import('../../common/event-emitter/contextual-ee').ee} */
9
8
  this.ee = ee.get(agentIdentifier);
10
9
  /** @type {string} */
@@ -16,4 +15,7 @@ export class FeatureBase {
16
15
  */
17
16
  this.blocked = false;
18
17
  }
18
+ deregisterDrain() {
19
+ deregisterDrain(this.agentIdentifier, this.featureName);
20
+ }
19
21
  }
@@ -10,7 +10,6 @@ import { onWindowLoad } from '../../common/window/load';
10
10
  import { isBrowserScope } from '../../common/constants/runtime';
11
11
  import { warn } from '../../common/util/console';
12
12
  import { FEATURE_NAMES } from '../../loaders/features/features';
13
- import { getConfigurationValue } from '../../common/config/init';
14
13
  import { hasReplayPrerequisite } from '../session_replay/shared/utils';
15
14
  import { canEnableSessionTracking } from './feature-gates';
16
15
  import { single } from '../../common/util/invoke';
@@ -23,14 +22,13 @@ export class InstrumentBase extends FeatureBase {
23
22
  /**
24
23
  * Instantiate InstrumentBase.
25
24
  * @param {string} agentIdentifier - The unique ID of the instantiated agent (relative to global scope).
26
- * @param {import('../../common/aggregate/aggregator').Aggregator} aggregator - The shared Aggregator that will handle batching and reporting of data.
27
25
  * @param {string} featureName - The name of the feature module (used to construct file path).
28
26
  * @param {boolean} [auto=true] - Determines whether the feature should automatically register to have the draining
29
27
  * of its pooled instrumentation data handled by the agent's centralized drain functionality, rather than draining
30
28
  * immediately. Primarily useful for fine-grained control in tests.
31
29
  */
32
- constructor(agentIdentifier, aggregator, featureName, auto = true) {
33
- super(agentIdentifier, aggregator, featureName);
30
+ constructor(agentRef, featureName, auto = true) {
31
+ super(agentRef.agentIdentifier, featureName);
34
32
  this.auto = auto;
35
33
 
36
34
  /** @type {Function | undefined} This should be set by any derived Instrument class if it has things to do when feature fails or is killed. */
@@ -50,15 +48,15 @@ export class InstrumentBase extends FeatureBase {
50
48
  this.onAggregateImported = undefined;
51
49
 
52
50
  /** used in conjunction with newrelic.start() to defer harvesting in features */
53
- if (getConfigurationValue(this.agentIdentifier, "".concat(this.featureName, ".autoStart")) === false) this.auto = false;
51
+ if (agentRef.init[this.featureName].autoStart === false) this.auto = false;
54
52
  /** if the feature requires opt-in (!auto-start), it will get registered once the api has been called */
55
- if (this.auto) registerDrain(agentIdentifier, featureName);else {
53
+ if (this.auto) registerDrain(agentRef.agentIdentifier, featureName);else {
56
54
  this.ee.on('manual-start-all', single(() => {
57
55
  // register the feature to drain only once the API has been called, it will drain when importAggregator finishes for all the features
58
56
  // called by the api in that cycle
59
- registerDrain(this.agentIdentifier, this.featureName);
57
+ registerDrain(agentRef.agentIdentifier, this.featureName);
60
58
  this.auto = true;
61
- this.importAggregator();
59
+ this.importAggregator(agentRef);
62
60
  }));
63
61
  }
64
62
  }
@@ -66,10 +64,11 @@ export class InstrumentBase extends FeatureBase {
66
64
  /**
67
65
  * Lazy-load the latter part of the feature: its aggregator. This method is called by the first part of the feature
68
66
  * (the instrumentation) when instrumentation is complete.
67
+ * @param agentRef - reference to the base agent ancestor that this feature belongs to
69
68
  * @param {Object} [argsObjFromInstrument] - any values or references to pass down to aggregate
70
69
  * @returns void
71
70
  */
72
- importAggregator(argsObjFromInstrument = {}) {
71
+ importAggregator(agentRef, argsObjFromInstrument = {}) {
73
72
  if (this.featAggregate || !this.auto) return;
74
73
  let loadedSuccessfully;
75
74
  this.onAggregateImported = new Promise(resolve => {
@@ -91,6 +90,15 @@ export class InstrumentBase extends FeatureBase {
91
90
  if (this.featureName === FEATURE_NAMES.sessionReplay) this.abortHandler?.(); // SR should stop recording if session DNE
92
91
  }
93
92
 
93
+ // Create a single Aggregator for this agent if DNE yet; to be used by jserror endpoint features.
94
+ if (!agentRef.sharedAggregator) {
95
+ agentRef.sharedAggregator = import(/* webpackChunkName: "shared-aggregator" */'../../common/aggregate/aggregator');
96
+ const {
97
+ Aggregator
98
+ } = await agentRef.sharedAggregator;
99
+ agentRef.sharedAggregator = new Aggregator();
100
+ } else await agentRef.sharedAggregator; // if another feature is already importing the aggregator, wait for it to finish
101
+
94
102
  /**
95
103
  * Note this try-catch differs from the one in Agent.run() in that it's placed later in a page's lifecycle and
96
104
  * it's only responsible for aborting its one specific feature, rather than all.
@@ -107,7 +115,7 @@ export class InstrumentBase extends FeatureBase {
107
115
  const {
108
116
  Aggregate
109
117
  } = await lazyFeatureLoader(this.featureName, 'aggregate');
110
- this.featAggregate = new Aggregate(this.agentIdentifier, this.aggregator, argsObjFromInstrument);
118
+ this.featAggregate = new Aggregate(agentRef, argsObjFromInstrument);
111
119
  loadedSuccessfully(true);
112
120
  } catch (e) {
113
121
  warn(34, e);
@@ -10,7 +10,6 @@ import { featurePriority, FEATURE_NAMES } from './features/features';
10
10
  // required features
11
11
  import { Instrument as PageViewEvent } from '../features/page_view_event/instrument';
12
12
  // common files
13
- import { Aggregator } from '../common/aggregate/aggregator';
14
13
  import { gosNREUM, setNREUMInitializedAgent } from '../common/window/nreum';
15
14
  import { warn } from '../common/util/console';
16
15
  import { globalScope } from '../common/constants/runtime';
@@ -32,9 +31,6 @@ export class Agent extends AgentBase {
32
31
  warn(21);
33
32
  return;
34
33
  }
35
- this.sharedAggregator = new Aggregator({
36
- agentIdentifier: this.agentIdentifier
37
- });
38
34
  this.features = {};
39
35
  setNREUMInitializedAgent(this.agentIdentifier, this); // append this agent onto the global NREUM.initializedAgents
40
36
 
@@ -74,7 +70,7 @@ export class Agent extends AgentBase {
74
70
  missingDependencies
75
71
  });
76
72
  }
77
- this.features[InstrumentCtor.featureName] = new InstrumentCtor(this.agentIdentifier, this.sharedAggregator);
73
+ this.features[InstrumentCtor.featureName] = new InstrumentCtor(this);
78
74
  });
79
75
  } catch (err) {
80
76
  warn(22, err);