@newrelic/browser-agent 1.269.0 → 1.270.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 (162) hide show
  1. package/CHANGELOG.md +11 -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/instrument/index.js +4 -5
  26. package/dist/cjs/features/soft_navigations/aggregate/index.js +6 -11
  27. package/dist/cjs/features/soft_navigations/instrument/index.js +3 -3
  28. package/dist/cjs/features/spa/aggregate/index.js +19 -30
  29. package/dist/cjs/features/spa/instrument/index.js +4 -4
  30. package/dist/cjs/features/utils/aggregate-base.js +11 -12
  31. package/dist/cjs/features/utils/feature-base.js +5 -3
  32. package/dist/cjs/features/utils/instrument-base.js +18 -10
  33. package/dist/cjs/loaders/agent.js +1 -5
  34. package/dist/cjs/loaders/micro-agent.js +6 -9
  35. package/dist/esm/common/constants/env.cdn.js +1 -1
  36. package/dist/esm/common/constants/env.npm.js +1 -1
  37. package/dist/esm/common/constants/runtime.js +0 -1
  38. package/dist/esm/common/harvest/harvest-scheduler.js +3 -4
  39. package/dist/esm/common/unload/eol.js +2 -5
  40. package/dist/esm/common/util/submit-data.js +2 -2
  41. package/dist/esm/features/ajax/aggregate/index.js +8 -17
  42. package/dist/esm/features/ajax/instrument/index.js +8 -10
  43. package/dist/esm/features/generic_events/aggregate/index.js +11 -18
  44. package/dist/esm/features/generic_events/instrument/index.js +5 -8
  45. package/dist/esm/features/jserrors/aggregate/index.js +15 -20
  46. package/dist/esm/features/jserrors/instrument/index.js +3 -3
  47. package/dist/esm/features/logging/aggregate/index.js +16 -23
  48. package/dist/esm/features/logging/instrument/index.js +3 -3
  49. package/dist/esm/features/metrics/aggregate/index.js +8 -11
  50. package/dist/esm/features/metrics/instrument/index.js +3 -3
  51. package/dist/esm/features/page_view_event/aggregate/index.js +16 -30
  52. package/dist/esm/features/page_view_event/instrument/index.js +3 -3
  53. package/dist/esm/features/page_view_timing/aggregate/index.js +6 -23
  54. package/dist/esm/features/page_view_timing/instrument/index.js +3 -3
  55. package/dist/esm/features/session_replay/aggregate/index.js +13 -27
  56. package/dist/esm/features/session_replay/instrument/index.js +7 -5
  57. package/dist/esm/features/session_trace/aggregate/index.js +22 -28
  58. package/dist/esm/features/session_trace/instrument/index.js +4 -5
  59. package/dist/esm/features/soft_navigations/aggregate/index.js +6 -11
  60. package/dist/esm/features/soft_navigations/instrument/index.js +3 -3
  61. package/dist/esm/features/spa/aggregate/index.js +17 -28
  62. package/dist/esm/features/spa/instrument/index.js +4 -4
  63. package/dist/esm/features/utils/aggregate-base.js +13 -14
  64. package/dist/esm/features/utils/feature-base.js +5 -3
  65. package/dist/esm/features/utils/instrument-base.js +18 -10
  66. package/dist/esm/loaders/agent.js +1 -5
  67. package/dist/esm/loaders/micro-agent.js +6 -9
  68. package/dist/types/common/constants/runtime.d.ts +0 -1
  69. package/dist/types/common/constants/runtime.d.ts.map +1 -1
  70. package/dist/types/common/harvest/harvest-scheduler.d.ts.map +1 -1
  71. package/dist/types/common/unload/eol.d.ts +1 -1
  72. package/dist/types/common/unload/eol.d.ts.map +1 -1
  73. package/dist/types/features/ajax/aggregate/index.d.ts +1 -1
  74. package/dist/types/features/ajax/aggregate/index.d.ts.map +1 -1
  75. package/dist/types/features/ajax/instrument/index.d.ts +1 -1
  76. package/dist/types/features/ajax/instrument/index.d.ts.map +1 -1
  77. package/dist/types/features/generic_events/aggregate/index.d.ts +1 -2
  78. package/dist/types/features/generic_events/aggregate/index.d.ts.map +1 -1
  79. package/dist/types/features/generic_events/instrument/index.d.ts +1 -1
  80. package/dist/types/features/generic_events/instrument/index.d.ts.map +1 -1
  81. package/dist/types/features/jserrors/aggregate/index.d.ts +1 -1
  82. package/dist/types/features/jserrors/aggregate/index.d.ts.map +1 -1
  83. package/dist/types/features/jserrors/instrument/index.d.ts +1 -1
  84. package/dist/types/features/jserrors/instrument/index.d.ts.map +1 -1
  85. package/dist/types/features/logging/aggregate/index.d.ts +1 -2
  86. package/dist/types/features/logging/aggregate/index.d.ts.map +1 -1
  87. package/dist/types/features/logging/instrument/index.d.ts +1 -1
  88. package/dist/types/features/logging/instrument/index.d.ts.map +1 -1
  89. package/dist/types/features/metrics/aggregate/index.d.ts +1 -1
  90. package/dist/types/features/metrics/aggregate/index.d.ts.map +1 -1
  91. package/dist/types/features/metrics/instrument/index.d.ts +1 -1
  92. package/dist/types/features/metrics/instrument/index.d.ts.map +1 -1
  93. package/dist/types/features/page_action/instrument/index.d.ts +1 -0
  94. package/dist/types/features/page_action/instrument/index.d.ts.map +1 -1
  95. package/dist/types/features/page_view_event/aggregate/index.d.ts +1 -1
  96. package/dist/types/features/page_view_event/aggregate/index.d.ts.map +1 -1
  97. package/dist/types/features/page_view_event/instrument/index.d.ts +1 -1
  98. package/dist/types/features/page_view_event/instrument/index.d.ts.map +1 -1
  99. package/dist/types/features/page_view_timing/aggregate/index.d.ts +1 -5
  100. package/dist/types/features/page_view_timing/aggregate/index.d.ts.map +1 -1
  101. package/dist/types/features/page_view_timing/instrument/index.d.ts +1 -1
  102. package/dist/types/features/page_view_timing/instrument/index.d.ts.map +1 -1
  103. package/dist/types/features/session_replay/aggregate/index.d.ts +0 -1
  104. package/dist/types/features/session_replay/aggregate/index.d.ts.map +1 -1
  105. package/dist/types/features/session_replay/instrument/index.d.ts +1 -1
  106. package/dist/types/features/session_replay/instrument/index.d.ts.map +1 -1
  107. package/dist/types/features/session_trace/aggregate/index.d.ts +1 -3
  108. package/dist/types/features/session_trace/aggregate/index.d.ts.map +1 -1
  109. package/dist/types/features/session_trace/instrument/index.d.ts +1 -1
  110. package/dist/types/features/session_trace/instrument/index.d.ts.map +1 -1
  111. package/dist/types/features/soft_navigations/aggregate/index.d.ts +1 -1
  112. package/dist/types/features/soft_navigations/aggregate/index.d.ts.map +1 -1
  113. package/dist/types/features/soft_navigations/instrument/index.d.ts +1 -1
  114. package/dist/types/features/soft_navigations/instrument/index.d.ts.map +1 -1
  115. package/dist/types/features/spa/aggregate/index.d.ts +1 -1
  116. package/dist/types/features/spa/aggregate/index.d.ts.map +1 -1
  117. package/dist/types/features/spa/instrument/index.d.ts +1 -1
  118. package/dist/types/features/spa/instrument/index.d.ts.map +1 -1
  119. package/dist/types/features/utils/aggregate-base.d.ts +2 -2
  120. package/dist/types/features/utils/aggregate-base.d.ts.map +1 -1
  121. package/dist/types/features/utils/feature-base.d.ts +2 -3
  122. package/dist/types/features/utils/feature-base.d.ts.map +1 -1
  123. package/dist/types/features/utils/instrument-base.d.ts +3 -3
  124. package/dist/types/features/utils/instrument-base.d.ts.map +1 -1
  125. package/dist/types/loaders/agent.d.ts +0 -2
  126. package/dist/types/loaders/agent.d.ts.map +1 -1
  127. package/dist/types/loaders/micro-agent.d.ts +0 -2
  128. package/dist/types/loaders/micro-agent.d.ts.map +1 -1
  129. package/package.json +1 -1
  130. package/src/common/constants/__mocks__/runtime.js +0 -1
  131. package/src/common/constants/runtime.js +0 -2
  132. package/src/common/harvest/harvest-scheduler.js +3 -4
  133. package/src/common/unload/eol.js +2 -5
  134. package/src/common/util/submit-data.js +2 -2
  135. package/src/features/ajax/aggregate/index.js +8 -18
  136. package/src/features/ajax/instrument/index.js +8 -10
  137. package/src/features/generic_events/aggregate/index.js +11 -20
  138. package/src/features/generic_events/instrument/index.js +7 -10
  139. package/src/features/jserrors/aggregate/index.js +15 -20
  140. package/src/features/jserrors/instrument/index.js +3 -4
  141. package/src/features/logging/aggregate/index.js +15 -23
  142. package/src/features/logging/instrument/index.js +3 -3
  143. package/src/features/metrics/aggregate/index.js +8 -11
  144. package/src/features/metrics/instrument/index.js +3 -3
  145. package/src/features/page_view_event/aggregate/index.js +16 -22
  146. package/src/features/page_view_event/instrument/index.js +3 -3
  147. package/src/features/page_view_timing/aggregate/index.js +6 -23
  148. package/src/features/page_view_timing/instrument/index.js +3 -3
  149. package/src/features/session_replay/aggregate/index.js +13 -21
  150. package/src/features/session_replay/instrument/index.js +7 -5
  151. package/src/features/session_trace/aggregate/index.js +22 -28
  152. package/src/features/session_trace/instrument/index.js +4 -5
  153. package/src/features/soft_navigations/aggregate/index.js +6 -8
  154. package/src/features/soft_navigations/instrument/index.js +3 -3
  155. package/src/features/spa/aggregate/index.js +17 -26
  156. package/src/features/spa/instrument/index.js +4 -4
  157. package/src/features/utils/__mocks__/feature-base.js +1 -2
  158. package/src/features/utils/aggregate-base.js +13 -14
  159. package/src/features/utils/feature-base.js +6 -3
  160. package/src/features/utils/instrument-base.js +16 -10
  161. package/src/loaders/agent.js +1 -3
  162. package/src/loaders/micro-agent.js +7 -9
@@ -1,5 +1,3 @@
1
- import { getConfiguration } from '../../../common/config/init';
2
- import { getRuntime } from '../../../common/config/runtime';
3
1
  import { registerHandler } from '../../../common/event-emitter/register-handler';
4
2
  import { HarvestScheduler } from '../../../common/harvest/harvest-scheduler';
5
3
  import { FEATURE_NAME, SUPPORTABILITY_METRIC, CUSTOM_METRIC, SUPPORTABILITY_METRIC_CHANNEL, CUSTOM_METRIC_CHANNEL /*, WATCHABLE_WEB_SOCKET_EVENTS */ } from '../constants';
@@ -9,15 +7,14 @@ import { onDOMContentLoaded } from '../../../common/window/load';
9
7
  import { windowAddEventListener } from '../../../common/event-listener/event-listener-opts';
10
8
  import { isBrowserScope, isWorkerScope } from '../../../common/constants/runtime';
11
9
  import { AggregateBase } from '../../utils/aggregate-base';
12
- import { deregisterDrain } from '../../../common/drain/drain';
13
10
  import { isIFrameWindow } from '../../../common/dom/iframe';
14
11
  // import { WEBSOCKET_TAG } from '../../../common/wrap/wrap-websocket'
15
12
  // import { handleWebsocketEvents } from './websocket-detection'
16
13
 
17
14
  export class Aggregate extends AggregateBase {
18
15
  static featureName = FEATURE_NAME;
19
- constructor(agentIdentifier, aggregator) {
20
- super(agentIdentifier, aggregator, FEATURE_NAME);
16
+ constructor(agentRef) {
17
+ super(agentRef, FEATURE_NAME);
21
18
  this.waitForFlags(['err']).then(([errFlag]) => {
22
19
  if (errFlag) {
23
20
  // *cli, Mar 23 - Per NR-94597, this feature should only harvest ONCE at the (potential) EoL time of the page.
@@ -26,12 +23,12 @@ export class Aggregate extends AggregateBase {
26
23
  }, this);
27
24
  // this is needed to ensure EoL is "on" and sent
28
25
  scheduler.harvest.on('jserrors', () => ({
29
- body: this.aggregator.take(['cm', 'sm'])
26
+ body: this.agentRef.sharedAggregator.take(['cm', 'sm'])
30
27
  }));
31
28
  this.drain();
32
29
  } else {
33
30
  this.blocked = true; // if rum response determines that customer lacks entitlements for spa endpoint, this feature shouldn't harvest
34
- deregisterDrain(this.agentIdentifier, this.featureName);
31
+ this.deregisterDrain();
35
32
  }
36
33
  });
37
34
 
@@ -47,7 +44,7 @@ export class Aggregate extends AggregateBase {
47
44
  const params = {
48
45
  name
49
46
  };
50
- this.aggregator.storeMetric(type, name, params, value);
47
+ this.agentRef.sharedAggregator.storeMetric(type, name, params, value);
51
48
  }
52
49
  storeEventMetrics(name, metrics) {
53
50
  if (this.blocked) return;
@@ -55,18 +52,18 @@ export class Aggregate extends AggregateBase {
55
52
  const params = {
56
53
  name
57
54
  };
58
- this.aggregator.store(type, name, params, metrics);
55
+ this.agentRef.sharedAggregator.store(type, name, params, metrics);
59
56
  }
60
57
  singleChecks() {
61
58
  // report loaderType
62
59
  const {
63
60
  distMethod,
64
61
  loaderType
65
- } = getRuntime(this.agentIdentifier);
62
+ } = this.agentRef.runtime;
66
63
  const {
67
64
  proxy,
68
65
  privacy
69
- } = getConfiguration(this.agentIdentifier);
66
+ } = this.agentRef.init;
70
67
  if (loaderType) this.storeSupportabilityMetrics("Generic/LoaderType/".concat(loaderType, "/Detected"));
71
68
  if (distMethod) this.storeSupportabilityMetrics("Generic/DistMethod/".concat(distMethod, "/Detected"));
72
69
  if (isBrowserScope) {
@@ -4,8 +4,8 @@ import { InstrumentBase } from '../../utils/instrument-base';
4
4
  import { FEATURE_NAME /*, WATCHABLE_WEB_SOCKET_EVENTS */ } from '../constants';
5
5
  export class Instrument extends InstrumentBase {
6
6
  static featureName = FEATURE_NAME;
7
- constructor(agentIdentifier, aggregator, auto = true) {
8
- super(agentIdentifier, aggregator, FEATURE_NAME, auto);
7
+ constructor(agentRef, auto = true) {
8
+ super(agentRef, FEATURE_NAME, auto);
9
9
  // wrapWebSocket(this.ee)
10
10
 
11
11
  // WATCHABLE_WEB_SOCKET_EVENTS.forEach((suffix) => {
@@ -14,7 +14,7 @@ export class Instrument extends InstrumentBase {
14
14
  // })
15
15
  // })
16
16
 
17
- this.importAggregator();
17
+ this.importAggregator(agentRef);
18
18
  }
19
19
  }
20
20
  export const Metrics = Instrument;
@@ -1,8 +1,7 @@
1
1
  import { globalScope, isBrowserScope, originTime } from '../../../common/constants/runtime';
2
2
  import { addPT, addPN } from '../../../common/timing/nav-timing';
3
3
  import { stringify } from '../../../common/util/stringify';
4
- import { getInfo, isValid } from '../../../common/config/info';
5
- import { getRuntime } from '../../../common/config/runtime';
4
+ import { isValid } from '../../../common/config/info';
6
5
  import { Harvest } from '../../../common/harvest/harvest';
7
6
  import * as CONSTANTS from '../constants';
8
7
  import { getActivatedFeaturesFlags } from './initialized-features';
@@ -17,13 +16,13 @@ import { TimeKeeper } from '../../../common/timing/time-keeper';
17
16
  import { applyFnToProps } from '../../../common/util/traverse';
18
17
  export class Aggregate extends AggregateBase {
19
18
  static featureName = CONSTANTS.FEATURE_NAME;
20
- constructor(agentIdentifier, aggregator) {
21
- super(agentIdentifier, aggregator, CONSTANTS.FEATURE_NAME);
19
+ constructor(agentRef) {
20
+ super(agentRef, CONSTANTS.FEATURE_NAME);
22
21
  this.timeToFirstByte = 0;
23
22
  this.firstByteToWindowLoad = 0; // our "frontend" duration
24
23
  this.firstByteToDomContent = 0; // our "dom processing" duration
25
- this.timeKeeper = new TimeKeeper(this.agentIdentifier);
26
- if (!isValid(agentIdentifier)) {
24
+ this.timeKeeper = new TimeKeeper(agentRef.agentIdentifier);
25
+ if (!isValid(agentRef.agentIdentifier)) {
27
26
  this.ee.abort();
28
27
  return warn(43);
29
28
  }
@@ -45,43 +44,30 @@ export class Aggregate extends AggregateBase {
45
44
  }
46
45
  }
47
46
  sendRum() {
48
- const info = getInfo(this.agentIdentifier);
49
- const agentRuntime = getRuntime(this.agentIdentifier);
47
+ const info = this.agentRef.info;
50
48
  const harvester = new Harvest(this);
51
- if (info.queueTime) this.aggregator.store('measures', 'qt', {
52
- value: info.queueTime
53
- });
54
- if (info.applicationTime) this.aggregator.store('measures', 'ap', {
55
- value: info.applicationTime
56
- });
49
+ const measures = {};
50
+ if (info.queueTime) measures.qt = info.queueTime;
51
+ if (info.applicationTime) measures.ap = info.applicationTime;
57
52
 
58
53
  // These 3 values should've been recorded after load and before this func runs. They are part of the minimum required for PageView events to be created.
59
54
  // Following PR #428, which demands that all agents send RUM call, these need to be sent even outside of the main window context where PerformanceTiming
60
55
  // or PerformanceNavigationTiming do not exists. Hence, they'll be filled in by 0s instead in, for example, worker threads that still init the PVE module.
61
- this.aggregator.store('measures', 'be', {
62
- value: this.timeToFirstByte
63
- });
64
- this.aggregator.store('measures', 'fe', {
65
- value: this.firstByteToWindowLoad
66
- });
67
- this.aggregator.store('measures', 'dc', {
68
- value: this.firstByteToDomContent
69
- });
56
+ measures.be = this.timeToFirstByte;
57
+ measures.fe = this.firstByteToWindowLoad;
58
+ measures.dc = this.firstByteToDomContent;
70
59
  const queryParameters = {
71
60
  tt: info.ttGuid,
72
61
  us: info.user,
73
62
  ac: info.account,
74
63
  pr: info.product,
75
64
  af: getActivatedFeaturesFlags(this.agentIdentifier).join(','),
76
- ...Object.entries(this.aggregator.get('measures') || {}).reduce((aggregator, [metricName, measure]) => {
77
- aggregator[metricName] = measure.params?.value;
78
- return aggregator;
79
- }, {}),
65
+ ...measures,
80
66
  xx: info.extra,
81
67
  ua: info.userAttributes,
82
68
  at: info.atts
83
69
  };
84
- if (agentRuntime.session) queryParameters.fsh = Number(agentRuntime.session.isNew); // "first session harvest" aka RUM request or PageView event of a session
70
+ if (this.agentRef.runtime.session) queryParameters.fsh = Number(this.agentRef.runtime.session.isNew); // "first session harvest" aka RUM request or PageView event of a session
85
71
 
86
72
  let body;
87
73
  if (typeof info.jsAttributes === 'object' && Object.keys(info.jsAttributes).length > 0) {
@@ -142,13 +128,13 @@ export class Aggregate extends AggregateBase {
142
128
  try {
143
129
  this.timeKeeper.processRumRequest(xhr, rumStartTime, rumEndTime, app.nrServerTime);
144
130
  if (!this.timeKeeper.ready) throw new Error('TimeKeeper not ready');
145
- agentRuntime.timeKeeper = this.timeKeeper;
131
+ this.agentRef.runtime.timeKeeper = this.timeKeeper;
146
132
  } catch (error) {
147
133
  this.ee.abort();
148
134
  warn(17, error);
149
135
  return;
150
136
  }
151
- agentRuntime.appMetadata = app;
137
+ this.agentRef.runtime.appMetadata = app;
152
138
  activateFeatures(flags, this.agentIdentifier);
153
139
  this.drain();
154
140
  } catch (err) {
@@ -2,9 +2,9 @@ import { InstrumentBase } from '../../utils/instrument-base';
2
2
  import * as CONSTANTS from '../constants';
3
3
  export class Instrument extends InstrumentBase {
4
4
  static featureName = CONSTANTS.FEATURE_NAME;
5
- constructor(agentIdentifier, aggregator, auto = true) {
6
- super(agentIdentifier, aggregator, CONSTANTS.FEATURE_NAME, auto);
7
- this.importAggregator();
5
+ constructor(agentRef, auto = true) {
6
+ super(agentRef, CONSTANTS.FEATURE_NAME, auto);
7
+ this.importAggregator(agentRef);
8
8
  }
9
9
  }
10
10
  export const PageViewEvent = Instrument;
@@ -7,8 +7,6 @@ import { nullable, numeric, getAddStringContext, addCustomAttributes } from '../
7
7
  import { HarvestScheduler } from '../../../common/harvest/harvest-scheduler';
8
8
  import { registerHandler } from '../../../common/event-emitter/register-handler';
9
9
  import { handle } from '../../../common/event-emitter/handle';
10
- import { getInfo } from '../../../common/config/info';
11
- import { getConfigurationValue } from '../../../common/config/init';
12
10
  import { FEATURE_NAME } from '../constants';
13
11
  import { FEATURE_NAMES } from '../../../loaders/features/features';
14
12
  import { AggregateBase } from '../../utils/aggregate-base';
@@ -31,13 +29,14 @@ export class Aggregate extends AggregateBase {
31
29
  }) => {
32
30
  this.addTiming(name, value, attrs);
33
31
  };
34
- constructor(agentIdentifier, aggregator) {
35
- super(agentIdentifier, aggregator, FEATURE_NAME);
32
+ constructor(agentRef) {
33
+ super(agentRef, FEATURE_NAME);
36
34
  this.timings = new EventBuffer();
37
35
  this.curSessEndRecorded = false;
38
36
  registerHandler('docHidden', msTimestamp => this.endCurrentSession(msTimestamp), this.featureName, this.ee);
39
- registerHandler('winPagehide', msTimestamp => this.recordPageUnload(msTimestamp), this.featureName, this.ee);
40
- const harvestTimeSeconds = getConfigurationValue(this.agentIdentifier, 'page_view_timing.harvestTimeSeconds') || 30;
37
+ // Add the time of _window pagehide event_ firing to the next PVT harvest == NRDB windowUnload attr:
38
+ registerHandler('winPagehide', msTimestamp => this.addTiming('unload', msTimestamp, null), this.featureName, this.ee);
39
+ const harvestTimeSeconds = agentRef.init.page_view_timing.harvestTimeSeconds || 30;
41
40
  this.waitForFlags([]).then(() => {
42
41
  /* It's important that CWV api, like "onLCP", is called before the **scheduler** is initialized. The reason is because they listen to the same
43
42
  on vis change or pagehide events, and we'd want ex. onLCP to record the timing (win the race) before we try to send "final harvest". */
@@ -84,21 +83,6 @@ export class Aggregate extends AggregateBase {
84
83
  this.curSessEndRecorded = true;
85
84
  }
86
85
  }
87
-
88
- /**
89
- * Add the time of _window pagehide event_ firing to the next PVT harvest == NRDB windowUnload attr.
90
- */
91
- recordPageUnload(timestamp) {
92
- this.addTiming('unload', timestamp, null);
93
- /*
94
- Issue: Because window's pageHide commonly fires BEFORE vis change and "final" harvest would happen at the former in this case, we also have to add our vis-change event now or it may not be sent.
95
- Affected: Safari < v14.1/.5 ; versions that don't support 'visiilitychange' event
96
- Impact: For affected w/o this, NR 'pageHide' attribute may not be sent. For other browsers w/o this, NR 'pageHide' gets fragmented into its own harvest call on page unloading because of dual EoL logic.
97
- Mitigation: NR 'unload' and 'pageHide' are both recorded when window pageHide fires, rather than only recording 'unload'.
98
- Future: When EoL can become the singular subscribeToVisibilityChange, it's likely endCurrentSession isn't needed here as 'unload'-'pageHide' can be untangled.
99
- */
100
- this.endCurrentSession(timestamp);
101
- }
102
86
  addTiming(name, value, attrs) {
103
87
  attrs = attrs || {};
104
88
  addConnectionAttributes(attrs); // network conditions may differ from the actual for VitalMetrics when they were captured
@@ -126,9 +110,8 @@ export class Aggregate extends AggregateBase {
126
110
  }
127
111
  appendGlobalCustomAttributes(timing) {
128
112
  var timingAttributes = timing.attrs || {};
129
- var customAttributes = getInfo(this.agentIdentifier).jsAttributes || {};
130
113
  var reservedAttributes = ['size', 'eid', 'cls', 'type', 'fid', 'elTag', 'elUrl', 'net-type', 'net-etype', 'net-rtt', 'net-dlink'];
131
- Object.entries(customAttributes || {}).forEach(([key, val]) => {
114
+ Object.entries(this.agentRef.info.jsAttributes || {}).forEach(([key, val]) => {
132
115
  if (reservedAttributes.indexOf(key) < 0) {
133
116
  timingAttributes[key] = val;
134
117
  }
@@ -11,8 +11,8 @@ import { isBrowserScope } from '../../../common/constants/runtime';
11
11
  import { now } from '../../../common/timing/now';
12
12
  export class Instrument extends InstrumentBase {
13
13
  static featureName = FEATURE_NAME;
14
- constructor(agentIdentifier, aggregator, auto = true) {
15
- super(agentIdentifier, aggregator, FEATURE_NAME, auto);
14
+ constructor(agentRef, auto = true) {
15
+ super(agentRef, FEATURE_NAME, auto);
16
16
  if (!isBrowserScope) return; // CWV is irrelevant outside web context
17
17
 
18
18
  // While we try to replicate web-vital's visibilitywatcher logic in an effort to defer that library to post-pageload, this isn't perfect and doesn't consider prerendering.
@@ -20,7 +20,7 @@ export class Instrument extends InstrumentBase {
20
20
 
21
21
  // Window fires its pagehide event (typically on navigation--this occurrence is a *subset* of vis change); don't defer this unless it's guarantee it cannot happen before load(?)
22
22
  windowAddEventListener('pagehide', () => handle('winPagehide', [now()], undefined, FEATURE_NAME, this.ee));
23
- this.importAggregator();
23
+ this.importAggregator(agentRef);
24
24
  }
25
25
  }
26
26
  export const PageViewTiming = Instrument;
@@ -9,9 +9,6 @@
9
9
  import { registerHandler } from '../../../common/event-emitter/register-handler';
10
10
  import { HarvestScheduler } from '../../../common/harvest/harvest-scheduler';
11
11
  import { ABORT_REASONS, FEATURE_NAME, QUERY_PARAM_PADDING, RRWEB_EVENT_TYPES, SR_EVENT_EMITTER_TYPES, TRIGGERS } from '../constants';
12
- import { getInfo } from '../../../common/config/info';
13
- import { getConfigurationValue } from '../../../common/config/init';
14
- import { getRuntime } from '../../../common/config/runtime';
15
12
  import { AggregateBase } from '../../utils/aggregate-base';
16
13
  import { sharedChannel } from '../../../common/constants/shared-channel';
17
14
  import { obj as encodeObj } from '../../../common/url/encode';
@@ -24,7 +21,6 @@ import { RRWEB_VERSION } from "../../../common/constants/env.npm";
24
21
  import { MODE, SESSION_EVENTS, SESSION_EVENT_TYPES } from '../../../common/session/constants';
25
22
  import { stringify } from '../../../common/util/stringify';
26
23
  import { stylesheetEvaluator } from '../shared/stylesheet-evaluator';
27
- import { deregisterDrain } from '../../../common/drain/drain';
28
24
  import { now } from '../../../common/timing/now';
29
25
  import { buildNRMetaNode } from '../shared/utils';
30
26
  import { MAX_PAYLOAD_SIZE } from '../../../common/constants/agent-constants';
@@ -34,10 +30,10 @@ export class Aggregate extends AggregateBase {
34
30
  mode = MODE.OFF;
35
31
 
36
32
  // pass the recorder into the aggregator
37
- constructor(agentIdentifier, aggregator, args) {
38
- super(agentIdentifier, aggregator, FEATURE_NAME);
33
+ constructor(agentRef, args) {
34
+ super(agentRef, FEATURE_NAME);
39
35
  /** The interval to harvest at. This gets overridden if the size of the payload exceeds certain thresholds */
40
- this.harvestTimeSeconds = getConfigurationValue(this.agentIdentifier, 'session_replay.harvestTimeSeconds') || 60;
36
+ this.harvestTimeSeconds = agentRef.init.session_replay.harvestTimeSeconds || 60;
41
37
  /** Set once the recorder has fully initialized after flag checks and sampling */
42
38
  this.initialized = false;
43
39
  /** Set once the feature has been "aborted" to prevent other side-effects from continuing */
@@ -71,10 +67,7 @@ export class Aggregate extends AggregateBase {
71
67
  this.ee.on(SESSION_EVENTS.RESUME, () => {
72
68
  if (!this.recorder) return;
73
69
  // if the mode changed on a different tab, it needs to update this instance to match
74
- const {
75
- session
76
- } = getRuntime(this.agentIdentifier);
77
- this.mode = session.state.sessionReplayMode;
70
+ this.mode = agentRef.runtime.session.state.sessionReplayMode;
78
71
  if (!this.initialized || this.mode === MODE.OFF) return;
79
72
  this.recorder?.startRecording();
80
73
  });
@@ -106,11 +99,11 @@ export class Aggregate extends AggregateBase {
106
99
  mask_all_inputs,
107
100
  inline_images,
108
101
  collect_fonts
109
- } = getConfigurationValue(this.agentIdentifier, 'session_replay');
102
+ } = agentRef.init.session_replay;
110
103
  this.waitForFlags(['srs', 'sr']).then(([srMode, entitled]) => {
111
104
  this.entitled = !!entitled;
112
105
  if (!this.entitled) {
113
- deregisterDrain(this.agentIdentifier, this.featureName);
106
+ this.deregisterDrain();
114
107
  if (this.recorder?.recording) {
115
108
  this.abort(ABORT_REASONS.ENTITLEMENTS);
116
109
  handle(SUPPORTABILITY_METRIC_CHANNEL, ['SessionReplay/EnabledNotEntitled/Detected'], undefined, FEATURE_NAMES.metrics, this.ee);
@@ -180,7 +173,7 @@ export class Aggregate extends AggregateBase {
180
173
  const {
181
174
  session,
182
175
  timeKeeper
183
- } = getRuntime(this.agentIdentifier);
176
+ } = this.agentRef.runtime;
184
177
  this.timeKeeper = timeKeeper;
185
178
  if (this.recorder?.parent.trigger === TRIGGERS.API && this.recorder?.recording) {
186
179
  this.mode = MODE.FULL;
@@ -296,10 +289,7 @@ export class Aggregate extends AggregateBase {
296
289
  return;
297
290
  }
298
291
  // TODO -- Gracefully handle the buffer for retries.
299
- const {
300
- session
301
- } = getRuntime(this.agentIdentifier);
302
- if (!session.state.sessionReplaySentFirstChunk) this.syncWithSessionManager({
292
+ if (!this.agentRef.runtime.session.state.sessionReplaySentFirstChunk) this.syncWithSessionManager({
303
293
  sessionReplaySentFirstChunk: true
304
294
  });
305
295
  this.recorder.clearBuffer();
@@ -314,9 +304,8 @@ export class Aggregate extends AggregateBase {
314
304
  getHarvestContents(recorderEvents) {
315
305
  recorderEvents ??= this.recorder.getEvents();
316
306
  let events = recorderEvents.events;
317
- const agentRuntime = getRuntime(this.agentIdentifier);
318
- const info = getInfo(this.agentIdentifier);
319
- const endUserId = info.jsAttributes?.['enduser.id'];
307
+ const agentRuntime = this.agentRef.runtime;
308
+ const endUserId = this.agentRef.info.jsAttributes?.['enduser.id'];
320
309
 
321
310
  // do not let the first node be a full snapshot node, since this NEEDS to be preceded by a meta node
322
311
  // we will manually inject it if this happens
@@ -344,9 +333,9 @@ export class Aggregate extends AggregateBase {
344
333
  const agentMetadata = agentRuntime.appMetadata?.agents?.[0] || {};
345
334
  return {
346
335
  qs: {
347
- browser_monitoring_key: info.licenseKey,
336
+ browser_monitoring_key: this.agentRef.info.licenseKey,
348
337
  type: 'SessionReplay',
349
- app_id: info.applicationID,
338
+ app_id: this.agentRef.info.applicationID,
350
339
  protocol_version: '0',
351
340
  timestamp: firstTimestamp,
352
341
  attributes: encodeObj({
@@ -423,9 +412,6 @@ export class Aggregate extends AggregateBase {
423
412
  while (this.recorder?.getEvents().events.length) this.recorder?.clearBuffer?.();
424
413
  }
425
414
  syncWithSessionManager(state = {}) {
426
- const {
427
- session
428
- } = getRuntime(this.agentIdentifier);
429
- session.write(state);
415
+ this.agentRef.runtime.session.write(state);
430
416
  }
431
417
  }
@@ -14,21 +14,23 @@ import { FEATURE_NAME, SR_EVENT_EMITTER_TYPES, TRIGGERS } from '../constants';
14
14
  export class Instrument extends InstrumentBase {
15
15
  static featureName = FEATURE_NAME;
16
16
  #mode;
17
- constructor(agentIdentifier, aggregator, auto = true) {
18
- super(agentIdentifier, aggregator, FEATURE_NAME, auto);
17
+ #agentRef;
18
+ constructor(agentRef, auto = true) {
19
+ super(agentRef, FEATURE_NAME, auto);
19
20
  let session;
20
21
  this.replayRunning = false;
22
+ this.#agentRef = agentRef;
21
23
  try {
22
24
  session = JSON.parse(localStorage.getItem("".concat(PREFIX, "_").concat(DEFAULT_KEY)));
23
25
  } catch (err) {}
24
- if (hasReplayPrerequisite(agentIdentifier)) {
26
+ if (hasReplayPrerequisite(agentRef.agentIdentifier)) {
25
27
  this.ee.on(SR_EVENT_EMITTER_TYPES.RECORD, () => this.#apiStartOrRestartReplay());
26
28
  }
27
29
  if (this.#canPreloadRecorder(session)) {
28
30
  this.#mode = session?.sessionReplayMode;
29
31
  this.#preloadStartRecording();
30
32
  } else {
31
- this.importAggregator();
33
+ this.importAggregator(agentRef);
32
34
  }
33
35
 
34
36
  /** If the recorder is running, we can pass error events on to the agg to help it switch to full mode later */
@@ -82,7 +84,7 @@ export class Instrument extends InstrumentBase {
82
84
  this.recorder.startRecording();
83
85
  this.abortHandler = this.recorder.stopRecording;
84
86
  } catch (e) {}
85
- this.importAggregator({
87
+ this.importAggregator(this.#agentRef, {
86
88
  recorder: this.recorder,
87
89
  errorNoticed: this.errorNoticed
88
90
  });
@@ -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();
@@ -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
  }