@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,6 +1,3 @@
1
- import { getInfo } from '../../../common/config/info';
2
- import { getConfigurationValue } from '../../../common/config/init';
3
- import { getRuntime } from '../../../common/config/runtime';
4
1
  import { handle } from '../../../common/event-emitter/handle';
5
2
  import { registerHandler } from '../../../common/event-emitter/register-handler';
6
3
  import { HarvestScheduler } from '../../../common/harvest/harvest-scheduler';
@@ -16,16 +13,12 @@ import { MAX_PAYLOAD_SIZE } from '../../../common/constants/agent-constants';
16
13
  import { EventBuffer } from '../../utils/event-buffer';
17
14
  export class Aggregate extends AggregateBase {
18
15
  static featureName = FEATURE_NAME;
19
- #agentRuntime;
20
- #agentInfo;
21
- constructor(agentIdentifier, aggregator) {
22
- super(agentIdentifier, aggregator, FEATURE_NAME);
16
+ constructor(agentRef) {
17
+ super(agentRef, FEATURE_NAME);
23
18
 
24
19
  /** held logs before sending */
25
20
  this.bufferedLogs = new EventBuffer();
26
- this.#agentRuntime = getRuntime(this.agentIdentifier);
27
- this.#agentInfo = getInfo(this.agentIdentifier);
28
- this.harvestTimeSeconds = getConfigurationValue(this.agentIdentifier, 'logging.harvestTimeSeconds');
21
+ this.harvestTimeSeconds = agentRef.init.logging.harvestTimeSeconds;
29
22
  this.waitForFlags([]).then(() => {
30
23
  this.scheduler = new HarvestScheduler('browser/logs', {
31
24
  onFinished: this.onHarvestFinished.bind(this),
@@ -60,7 +53,7 @@ export class Aggregate extends AggregateBase {
60
53
  return;
61
54
  }
62
55
  if (typeof message !== 'string' || !message) return warn(32);
63
- const log = new Log(Math.floor(this.#agentRuntime.timeKeeper.correctRelativeTimestamp(timestamp)), message, attributes, level);
56
+ const log = new Log(Math.floor(this.agentRef.runtime.timeKeeper.correctRelativeTimestamp(timestamp)), message, attributes, level);
64
57
  const logBytes = log.message.length + stringify(log.attributes).length + log.level.length + 10; // timestamp == 10 chars
65
58
 
66
59
  if (!this.bufferedLogs.canMerge(logBytes)) {
@@ -81,34 +74,34 @@ export class Aggregate extends AggregateBase {
81
74
  /** These attributes are evaluated and dropped at ingest processing time and do not get stored on NRDB */
82
75
  const unbilledAttributes = {
83
76
  'instrumentation.provider': 'browser',
84
- 'instrumentation.version': this.#agentRuntime.version,
85
- 'instrumentation.name': this.#agentRuntime.loaderType
77
+ 'instrumentation.version': this.agentRef.runtime.version,
78
+ 'instrumentation.name': this.agentRef.runtime.loaderType
86
79
  };
87
80
  /** see https://source.datanerd.us/agents/rum-specs/blob/main/browser/Log for logging spec */
88
81
  const payload = {
89
82
  qs: {
90
- browser_monitoring_key: this.#agentInfo.licenseKey
83
+ browser_monitoring_key: this.agentRef.info.licenseKey
91
84
  },
92
85
  body: [{
93
86
  common: {
94
87
  /** Attributes in the `common` section are added to `all` logs generated in the payload */
95
88
  attributes: {
96
- 'entity.guid': this.#agentRuntime.appMetadata?.agents?.[0]?.entityGuid,
89
+ 'entity.guid': this.agentRef.runtime.appMetadata?.agents?.[0]?.entityGuid,
97
90
  // browser entity guid as provided from RUM response
98
- session: this.#agentRuntime?.session?.state.value || '0',
91
+ session: this.agentRef.runtime.session?.state.value || '0',
99
92
  // The session ID that we generate and keep across page loads
100
- hasReplay: this.#agentRuntime?.session?.state.sessionReplayMode === 1,
93
+ hasReplay: this.agentRef.runtime.session?.state.sessionReplayMode === 1,
101
94
  // True if a session replay recording is running
102
- hasTrace: this.#agentRuntime?.session?.state.sessionTraceMode === 1,
95
+ hasTrace: this.agentRef.runtime.session?.state.sessionTraceMode === 1,
103
96
  // True if a session trace recording is running
104
- ptid: this.#agentRuntime.ptid,
97
+ ptid: this.agentRef.runtime.ptid,
105
98
  // page trace id
106
- appId: this.#agentInfo.applicationID,
99
+ appId: this.agentRef.info.applicationID,
107
100
  // Application ID from info object,
108
- standalone: Boolean(this.#agentInfo.sa),
101
+ standalone: Boolean(this.agentRef.info.sa),
109
102
  // copy paste (true) vs APM (false)
110
- agentVersion: this.#agentRuntime.version,
111
- // browser agent version,
103
+ agentVersion: this.agentRef.runtime.version,
104
+ // browser agent version
112
105
  ...unbilledAttributes
113
106
  }
114
107
  },
@@ -3,8 +3,8 @@ import { FEATURE_NAME } from '../constants';
3
3
  import { bufferLog } from '../shared/utils';
4
4
  export class Instrument extends InstrumentBase {
5
5
  static featureName = FEATURE_NAME;
6
- constructor(agentIdentifier, aggregator, auto = true) {
7
- super(agentIdentifier, aggregator, FEATURE_NAME, auto);
6
+ constructor(agentRef, auto = true) {
7
+ super(agentRef, FEATURE_NAME, auto);
8
8
  const instanceEE = this.ee;
9
9
  /** emitted by wrap-logger function */
10
10
  this.ee.on('wrap-logger-end', function handleLog([message]) {
@@ -14,7 +14,7 @@ export class Instrument extends InstrumentBase {
14
14
  } = this;
15
15
  bufferLog(instanceEE, message, customAttributes, level);
16
16
  });
17
- this.importAggregator();
17
+ this.importAggregator(agentRef);
18
18
  }
19
19
  }
20
20
  export const Logging = Instrument;
@@ -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
  });