@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
@@ -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'
@@ -30,16 +28,17 @@ export class Aggregate extends AggregateBase {
30
28
  this.addTiming(name, value, attrs)
31
29
  }
32
30
 
33
- constructor (agentIdentifier, aggregator) {
34
- super(agentIdentifier, aggregator, FEATURE_NAME)
31
+ constructor (agentRef) {
32
+ super(agentRef, FEATURE_NAME)
35
33
 
36
34
  this.timings = new EventBuffer()
37
35
  this.curSessEndRecorded = false
38
36
 
39
37
  registerHandler('docHidden', msTimestamp => this.endCurrentSession(msTimestamp), this.featureName, this.ee)
40
- registerHandler('winPagehide', msTimestamp => this.recordPageUnload(msTimestamp), this.featureName, this.ee)
38
+ // Add the time of _window pagehide event_ firing to the next PVT harvest == NRDB windowUnload attr:
39
+ registerHandler('winPagehide', msTimestamp => this.addTiming('unload', msTimestamp, null), this.featureName, this.ee)
41
40
 
42
- const harvestTimeSeconds = getConfigurationValue(this.agentIdentifier, 'page_view_timing.harvestTimeSeconds') || 30
41
+ const harvestTimeSeconds = agentRef.init.page_view_timing.harvestTimeSeconds || 30
43
42
 
44
43
  this.waitForFlags(([])).then(() => {
45
44
  /* It's important that CWV api, like "onLCP", is called before the **scheduler** is initialized. The reason is because they listen to the same
@@ -82,21 +81,6 @@ export class Aggregate extends AggregateBase {
82
81
  }
83
82
  }
84
83
 
85
- /**
86
- * Add the time of _window pagehide event_ firing to the next PVT harvest == NRDB windowUnload attr.
87
- */
88
- recordPageUnload (timestamp) {
89
- this.addTiming('unload', timestamp, null)
90
- /*
91
- 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.
92
- Affected: Safari < v14.1/.5 ; versions that don't support 'visiilitychange' event
93
- 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.
94
- Mitigation: NR 'unload' and 'pageHide' are both recorded when window pageHide fires, rather than only recording 'unload'.
95
- Future: When EoL can become the singular subscribeToVisibilityChange, it's likely endCurrentSession isn't needed here as 'unload'-'pageHide' can be untangled.
96
- */
97
- this.endCurrentSession(timestamp)
98
- }
99
-
100
84
  addTiming (name, value, attrs) {
101
85
  attrs = attrs || {}
102
86
  addConnectionAttributes(attrs) // network conditions may differ from the actual for VitalMetrics when they were captured
@@ -129,11 +113,10 @@ export class Aggregate extends AggregateBase {
129
113
 
130
114
  appendGlobalCustomAttributes (timing) {
131
115
  var timingAttributes = timing.attrs || {}
132
- var customAttributes = getInfo(this.agentIdentifier).jsAttributes || {}
133
116
 
134
117
  var reservedAttributes = ['size', 'eid', 'cls', 'type', 'fid', 'elTag', 'elUrl', 'net-type',
135
118
  'net-etype', 'net-rtt', 'net-dlink']
136
- Object.entries(customAttributes || {}).forEach(([key, val]) => {
119
+ Object.entries(this.agentRef.info.jsAttributes || {}).forEach(([key, val]) => {
137
120
  if (reservedAttributes.indexOf(key) < 0) {
138
121
  timingAttributes[key] = val
139
122
  }
@@ -12,8 +12,8 @@ import { now } from '../../../common/timing/now'
12
12
 
13
13
  export class Instrument extends InstrumentBase {
14
14
  static featureName = FEATURE_NAME
15
- constructor (agentIdentifier, aggregator, auto = true) {
16
- super(agentIdentifier, aggregator, FEATURE_NAME, auto)
15
+ constructor (agentRef, auto = true) {
16
+ super(agentRef, FEATURE_NAME, auto)
17
17
  if (!isBrowserScope) return // CWV is irrelevant outside web context
18
18
 
19
19
  // 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.
@@ -22,7 +22,7 @@ export class Instrument extends InstrumentBase {
22
22
  // 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(?)
23
23
  windowAddEventListener('pagehide', () => handle('winPagehide', [now()], undefined, FEATURE_NAME, this.ee))
24
24
 
25
- this.importAggregator()
25
+ this.importAggregator(agentRef)
26
26
  }
27
27
  }
28
28
 
@@ -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'
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'
@@ -35,10 +31,10 @@ export class Aggregate extends AggregateBase {
35
31
  mode = MODE.OFF
36
32
 
37
33
  // pass the recorder into the aggregator
38
- constructor (agentIdentifier, aggregator, args) {
39
- super(agentIdentifier, aggregator, FEATURE_NAME)
34
+ constructor (agentRef, args) {
35
+ super(agentRef, FEATURE_NAME)
40
36
  /** The interval to harvest at. This gets overridden if the size of the payload exceeds certain thresholds */
41
- this.harvestTimeSeconds = getConfigurationValue(this.agentIdentifier, 'session_replay.harvestTimeSeconds') || 60
37
+ this.harvestTimeSeconds = agentRef.init.session_replay.harvestTimeSeconds || 60
42
38
  /** Set once the recorder has fully initialized after flag checks and sampling */
43
39
  this.initialized = false
44
40
  /** Set once the feature has been "aborted" to prevent other side-effects from continuing */
@@ -77,8 +73,7 @@ export class Aggregate extends AggregateBase {
77
73
  this.ee.on(SESSION_EVENTS.RESUME, () => {
78
74
  if (!this.recorder) return
79
75
  // if the mode changed on a different tab, it needs to update this instance to match
80
- const { session } = getRuntime(this.agentIdentifier)
81
- this.mode = session.state.sessionReplayMode
76
+ this.mode = agentRef.runtime.session.state.sessionReplayMode
82
77
  if (!this.initialized || this.mode === MODE.OFF) return
83
78
  this.recorder?.startRecording()
84
79
  })
@@ -105,12 +100,12 @@ export class Aggregate extends AggregateBase {
105
100
  this.handleError(e)
106
101
  }, this.featureName, this.ee)
107
102
 
108
- const { error_sampling_rate, sampling_rate, autoStart, block_selector, mask_text_selector, mask_all_inputs, inline_images, collect_fonts } = getConfigurationValue(this.agentIdentifier, 'session_replay')
103
+ const { error_sampling_rate, sampling_rate, autoStart, block_selector, mask_text_selector, mask_all_inputs, inline_images, collect_fonts } = agentRef.init.session_replay
109
104
 
110
105
  this.waitForFlags(['srs', 'sr']).then(([srMode, entitled]) => {
111
106
  this.entitled = !!entitled
112
107
  if (!this.entitled) {
113
- deregisterDrain(this.agentIdentifier, this.featureName)
108
+ this.deregisterDrain()
114
109
  if (this.recorder?.recording) {
115
110
  this.abort(ABORT_REASONS.ENTITLEMENTS)
116
111
  handle(SUPPORTABILITY_METRIC_CHANNEL, ['SessionReplay/EnabledNotEntitled/Detected'], undefined, FEATURE_NAMES.metrics, this.ee)
@@ -178,7 +173,7 @@ export class Aggregate extends AggregateBase {
178
173
  // we are not actively recording SR... DO NOT import or run the recording library
179
174
  // session replay samples can only be decided on the first load of a session
180
175
  // session replays can continue if already in progress
181
- const { session, timeKeeper } = getRuntime(this.agentIdentifier)
176
+ const { session, timeKeeper } = this.agentRef.runtime
182
177
  this.timeKeeper = timeKeeper
183
178
  if (this.recorder?.parent.trigger === TRIGGERS.API && this.recorder?.recording) {
184
179
  this.mode = MODE.FULL
@@ -285,8 +280,7 @@ export class Aggregate extends AggregateBase {
285
280
  return
286
281
  }
287
282
  // TODO -- Gracefully handle the buffer for retries.
288
- const { session } = getRuntime(this.agentIdentifier)
289
- if (!session.state.sessionReplaySentFirstChunk) this.syncWithSessionManager({ sessionReplaySentFirstChunk: true })
283
+ if (!this.agentRef.runtime.session.state.sessionReplaySentFirstChunk) this.syncWithSessionManager({ sessionReplaySentFirstChunk: true })
290
284
  this.recorder.clearBuffer()
291
285
  if (recorderEvents.type === 'preloaded') this.scheduler.runHarvest(opts)
292
286
  return [payload]
@@ -301,9 +295,8 @@ export class Aggregate extends AggregateBase {
301
295
  getHarvestContents (recorderEvents) {
302
296
  recorderEvents ??= this.recorder.getEvents()
303
297
  let events = recorderEvents.events
304
- const agentRuntime = getRuntime(this.agentIdentifier)
305
- const info = getInfo(this.agentIdentifier)
306
- const endUserId = info.jsAttributes?.['enduser.id']
298
+ const agentRuntime = this.agentRef.runtime
299
+ const endUserId = this.agentRef.info.jsAttributes?.['enduser.id']
307
300
 
308
301
  // do not let the first node be a full snapshot node, since this NEEDS to be preceded by a meta node
309
302
  // we will manually inject it if this happens
@@ -335,9 +328,9 @@ export class Aggregate extends AggregateBase {
335
328
 
336
329
  return {
337
330
  qs: {
338
- browser_monitoring_key: info.licenseKey,
331
+ browser_monitoring_key: this.agentRef.info.licenseKey,
339
332
  type: 'SessionReplay',
340
- app_id: info.applicationID,
333
+ app_id: this.agentRef.info.applicationID,
341
334
  protocol_version: '0',
342
335
  timestamp: firstTimestamp,
343
336
  attributes: encodeObj({
@@ -407,7 +400,6 @@ export class Aggregate extends AggregateBase {
407
400
  }
408
401
 
409
402
  syncWithSessionManager (state = {}) {
410
- const { session } = getRuntime(this.agentIdentifier)
411
- session.write(state)
403
+ this.agentRef.runtime.session.write(state)
412
404
  }
413
405
  }
@@ -16,15 +16,17 @@ export class Instrument extends InstrumentBase {
16
16
  static featureName = FEATURE_NAME
17
17
 
18
18
  #mode
19
- constructor (agentIdentifier, aggregator, auto = true) {
20
- super(agentIdentifier, aggregator, FEATURE_NAME, auto)
19
+ #agentRef
20
+ constructor (agentRef, auto = true) {
21
+ super(agentRef, FEATURE_NAME, auto)
21
22
  let session
22
23
  this.replayRunning = false
24
+ this.#agentRef = agentRef
23
25
  try {
24
26
  session = JSON.parse(localStorage.getItem(`${PREFIX}_${DEFAULT_KEY}`))
25
27
  } catch (err) { }
26
28
 
27
- if (hasReplayPrerequisite(agentIdentifier)) {
29
+ if (hasReplayPrerequisite(agentRef.agentIdentifier)) {
28
30
  this.ee.on(SR_EVENT_EMITTER_TYPES.RECORD, () => this.#apiStartOrRestartReplay())
29
31
  }
30
32
 
@@ -32,7 +34,7 @@ export class Instrument extends InstrumentBase {
32
34
  this.#mode = session?.sessionReplayMode
33
35
  this.#preloadStartRecording()
34
36
  } else {
35
- this.importAggregator()
37
+ this.importAggregator(agentRef)
36
38
  }
37
39
 
38
40
  /** If the recorder is running, we can pass error events on to the agg to help it switch to full mode later */
@@ -79,7 +81,7 @@ export class Instrument extends InstrumentBase {
79
81
  this.recorder.startRecording()
80
82
  this.abortHandler = this.recorder.stopRecording
81
83
  } catch (e) {}
82
- this.importAggregator({ recorder: this.recorder, errorNoticed: this.errorNoticed })
84
+ this.importAggregator(this.#agentRef, { recorder: this.recorder, errorNoticed: this.errorNoticed })
83
85
  }
84
86
 
85
87
  /**
@@ -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'
@@ -19,14 +15,12 @@ const QUERY_PARAM_PADDING = 5000
19
15
  export class Aggregate extends AggregateBase {
20
16
  static featureName = FEATURE_NAME
21
17
 
22
- constructor (agentIdentifier, aggregator) {
23
- super(agentIdentifier, aggregator, FEATURE_NAME)
24
- this.agentRuntime = getRuntime(agentIdentifier)
25
- this.agentInfo = getInfo(agentIdentifier)
18
+ constructor (agentRef) {
19
+ super(agentRef, FEATURE_NAME)
26
20
 
27
21
  /** A buffer to hold on to harvested traces in the case that a retry must be made later */
28
22
  this.sentTrace = null
29
- this.harvestTimeSeconds = getConfigurationValue(agentIdentifier, 'session_trace.harvestTimeSeconds') || 30
23
+ this.harvestTimeSeconds = agentRef.init.session_trace.harvestTimeSeconds || 30
30
24
  /** Tied to the entitlement flag response from BCS. Will short circuit operations of the agg if false */
31
25
  this.entitled = undefined
32
26
  /** A flag used to decide if the 30 node threshold should be ignored on the first harvest to ensure sending on the first payload */
@@ -43,13 +37,13 @@ export class Aggregate extends AggregateBase {
43
37
  /** 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 */
44
38
  initialize (stMode, stEntitled, ignoreSession) {
45
39
  this.entitled ??= stEntitled
46
- if (this.blocked || !this.entitled) return deregisterDrain(this.agentIdentifier, this.featureName)
40
+ if (this.blocked || !this.entitled) return this.deregisterDrain()
47
41
 
48
42
  if (!this.initialized) {
49
43
  this.initialized = true
50
44
  /** Store session identifiers at initialization time to be cross-checked later at harvest time for session changes that are subject to race conditions */
51
- this.ptid = this.agentRuntime.ptid
52
- this.sessionId = this.agentRuntime.session?.state.value
45
+ this.ptid = this.agentRef.runtime.ptid
46
+ this.sessionId = this.agentRef.runtime.session?.state.value
53
47
  // 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.
54
48
  this.ee.on(SESSION_EVENTS.RESET, () => {
55
49
  if (this.blocked) return
@@ -74,14 +68,14 @@ export class Aggregate extends AggregateBase {
74
68
 
75
69
  /** ST/SR sampling flow in BCS - https://drive.google.com/file/d/19hwt2oft-8Hh4RrjpLqEXfpP_9wYBLcq/view?usp=sharing */
76
70
  /** 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 */
77
- if (!this.agentRuntime.session.isNew && !ignoreSession) this.mode = this.agentRuntime.session.state.sessionTraceMode
71
+ if (!this.agentRef.runtime.session.isNew && !ignoreSession) this.mode = this.agentRef.runtime.session.state.sessionTraceMode
78
72
  else this.mode = stMode
79
73
 
80
74
  /** If the mode is off, we do not want to hold up draining for other features, so we deregister the feature for now.
81
75
  * If it drains later (due to a mode change), data and handlers will instantly drain instead of waiting for the registry. */
82
- if (this.mode === MODE.OFF) return deregisterDrain(this.agentIdentifier, this.featureName)
76
+ if (this.mode === MODE.OFF) return this.deregisterDrain()
83
77
 
84
- this.timeKeeper ??= this.agentRuntime.timeKeeper
78
+ this.timeKeeper ??= this.agentRef.runtime.timeKeeper
85
79
 
86
80
  this.scheduler = new HarvestScheduler('browser/blobs', {
87
81
  onFinished: this.onHarvestFinished.bind(this),
@@ -107,7 +101,7 @@ export class Aggregate extends AggregateBase {
107
101
  if (this.mode === MODE.ERROR) this.switchToFull()
108
102
  }, this.featureName, this.ee)
109
103
  }
110
- this.agentRuntime.session.write({ sessionTraceMode: this.mode })
104
+ this.agentRef.runtime.session.write({ sessionTraceMode: this.mode })
111
105
  this.drain()
112
106
  }
113
107
 
@@ -123,7 +117,7 @@ export class Aggregate extends AggregateBase {
123
117
  this.traceStorage.prevStoredEvents.clear() // release references to past events for GC
124
118
  if (!this.timeKeeper?.ready) return // this should likely never happen, but just to be safe, we should never harvest if we cant correct time
125
119
  if (this.blocked || this.mode !== MODE.FULL || this.traceStorage.nodeCount === 0) return
126
- 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
120
+ 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
127
121
  /** Get the ST nodes from the traceStorage buffer. This also returns helpful metadata about the payload. */
128
122
  const { stns, earliestTimeStamp, latestTimeStamp } = this.traceStorage.takeSTNs()
129
123
  if (!stns) return // there are no trace nodes
@@ -131,11 +125,11 @@ export class Aggregate extends AggregateBase {
131
125
  this.sentTrace = stns
132
126
  }
133
127
 
134
- const firstSessionHarvest = !this.agentRuntime.session.state.traceHarvestStarted
135
- if (firstSessionHarvest) this.agentRuntime.session.write({ traceHarvestStarted: true })
128
+ const firstSessionHarvest = !this.agentRef.runtime.session.state.traceHarvestStarted
129
+ if (firstSessionHarvest) this.agentRef.runtime.session.write({ traceHarvestStarted: true })
136
130
 
137
- const hasReplay = this.agentRuntime.session?.state.sessionReplayMode === 1
138
- const endUserId = this.agentInfo?.jsAttributes?.['enduser.id']
131
+ const hasReplay = this.agentRef.runtime.session?.state.sessionReplayMode === 1
132
+ const endUserId = this.agentRef.info?.jsAttributes?.['enduser.id']
139
133
 
140
134
  this.everHarvested = true
141
135
 
@@ -148,17 +142,17 @@ export class Aggregate extends AggregateBase {
148
142
  *
149
143
  * For data that does not fit the schema of the above, it should be url-encoded and placed into `attributes`
150
144
  */
151
- const agentMetadata = this.agentRuntime.appMetadata?.agents?.[0] || {}
145
+ const agentMetadata = this.agentRef.runtime.appMetadata?.agents?.[0] || {}
152
146
  return {
153
147
  qs: {
154
- browser_monitoring_key: this.agentInfo.licenseKey,
148
+ browser_monitoring_key: this.agentRef.info.licenseKey,
155
149
  type: 'BrowserSessionChunk',
156
- app_id: this.agentInfo.applicationID,
150
+ app_id: this.agentRef.info.applicationID,
157
151
  protocol_version: '0',
158
152
  timestamp: Math.floor(this.timeKeeper.correctRelativeTimestamp(earliestTimeStamp)),
159
153
  attributes: encodeObj({
160
154
  ...(agentMetadata.entityGuid && { entityGuid: agentMetadata.entityGuid }),
161
- harvestId: `${this.agentRuntime.session?.state.value}_${this.agentRuntime.ptid}_${this.agentRuntime.harvestCount}`,
155
+ harvestId: `${this.agentRef.runtime.session?.state.value}_${this.agentRef.runtime.ptid}_${this.agentRef.runtime.harvestCount}`,
162
156
  // this section of attributes must be controllable and stay below the query param padding limit -- see QUERY_PARAM_PADDING
163
157
  // if not, data could be lost to truncation at time of sending, potentially breaking parsing / API behavior in NR1
164
158
  // trace payload metadata
@@ -167,7 +161,7 @@ export class Aggregate extends AggregateBase {
167
161
  'trace.nodes': stns.length,
168
162
  'trace.originTimestamp': this.timeKeeper.correctedOriginTime,
169
163
  // other payload metadata
170
- agentVersion: this.agentRuntime.version,
164
+ agentVersion: this.agentRef.runtime.version,
171
165
  ...(firstSessionHarvest && { firstSessionHarvest }),
172
166
  ...(hasReplay && { hasReplay }),
173
167
  ptid: `${this.ptid}`,
@@ -197,7 +191,7 @@ export class Aggregate extends AggregateBase {
197
191
  if (this.mode === MODE.FULL || !this.entitled || this.blocked) return
198
192
  const prevMode = this.mode
199
193
  this.mode = MODE.FULL
200
- this.agentRuntime.session.write({ sessionTraceMode: this.mode })
194
+ this.agentRef.runtime.session.write({ sessionTraceMode: this.mode })
201
195
  if (prevMode === MODE.OFF || !this.initialized) return this.initialize(this.mode, this.entitled)
202
196
  if (this.initialized) {
203
197
  this.traceStorage.trimSTNs(ERROR_MODE_SECONDS_WINDOW) // up until now, Trace would've been just buffering nodes up to max, which needs to be trimmed to last X seconds
@@ -209,7 +203,7 @@ export class Aggregate extends AggregateBase {
209
203
  abort (reason) {
210
204
  this.blocked = true
211
205
  this.mode = MODE.OFF
212
- this.agentRuntime.session.write({ sessionTraceMode: this.mode })
206
+ this.agentRef.runtime.session.write({ sessionTraceMode: this.mode })
213
207
  this.scheduler?.stopTimer()
214
208
  }
215
209
  }
@@ -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
 
@@ -18,11 +17,11 @@ const {
18
17
 
19
18
  export class Instrument extends InstrumentBase {
20
19
  static featureName = FEATURE_NAME
21
- constructor (agentIdentifier, aggregator, auto = true) {
22
- super(agentIdentifier, aggregator, FEATURE_NAME, auto)
20
+ constructor (agentRef, auto = true) {
21
+ super(agentRef, FEATURE_NAME, auto)
23
22
  const canTrackSession = canEnableSessionTracking(this.agentIdentifier)
24
23
  if (!canTrackSession) {
25
- deregisterDrain(this.agentIdentifier, this.featureName)
24
+ this.deregisterDrain()
26
25
  return
27
26
  }
28
27
 
@@ -59,7 +58,7 @@ export class Instrument extends InstrumentBase {
59
58
  // Per NEWRELIC-8525, we don't have a fallback for capturing resources for older versions that don't support PO at this time.
60
59
  }
61
60
 
62
- this.importAggregator({ resourceObserver: observer })
61
+ this.importAggregator(agentRef, { resourceObserver: observer })
63
62
  }
64
63
  }
65
64
 
@@ -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'
@@ -16,14 +14,14 @@ import { Interaction } from './interaction'
16
14
 
17
15
  export class Aggregate extends AggregateBase {
18
16
  static featureName = FEATURE_NAME
19
- constructor (agentIdentifier, aggregator, { domObserver }) {
20
- super(agentIdentifier, aggregator, FEATURE_NAME)
17
+ constructor (agentRef, { domObserver }) {
18
+ super(agentRef, FEATURE_NAME)
21
19
 
22
- const harvestTimeSeconds = getConfigurationValue(agentIdentifier, 'soft_navigations.harvestTimeSeconds') || 10
20
+ const harvestTimeSeconds = agentRef.init.soft_navigations.harvestTimeSeconds || 10
23
21
  this.interactionsToHarvest = new EventBuffer()
24
22
  this.domObserver = domObserver
25
23
 
26
- this.initialPageLoadInteraction = new InitialPageLoadInteraction(agentIdentifier)
24
+ this.initialPageLoadInteraction = new InitialPageLoadInteraction(agentRef.agentIdentifier)
27
25
  timeToFirstByte.subscribe(({ attrs }) => {
28
26
  const loadEventTime = attrs.navigationEntry.loadEventEnd
29
27
  this.initialPageLoadInteraction.forceSave = true
@@ -45,12 +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
- }, { agentIdentifier, ee: this.ee })
46
+ }, this)
49
47
  scheduler.harvest.on('events', this.onHarvestStarted.bind(this))
50
48
  scheduler.startTimer(harvestTimeSeconds, 0)
51
49
  } else {
52
50
  this.blocked = true // if rum response determines that customer lacks entitlements for spa endpoint, this feature shouldn't harvest
53
- deregisterDrain(this.agentIdentifier, this.featureName)
51
+ this.deregisterDrain()
54
52
  }
55
53
  })
56
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)
@@ -58,7 +58,7 @@ export class Instrument extends InstrumentBase {
58
58
  for (let eventType of INTERACTION_TRIGGERS) document.addEventListener(eventType, () => { /* no-op, this ensures the UI events are monitored by our callback above */ })
59
59
 
60
60
  this.abortHandler = abort
61
- this.importAggregator({ domObserver })
61
+ this.importAggregator(agentRef, { domObserver })
62
62
 
63
63
  function abort () {
64
64
  this.removeOnAbort?.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
 
@@ -34,13 +31,12 @@ const {
34
31
  } = CONSTANTS
35
32
  export class Aggregate extends AggregateBase {
36
33
  static featureName = FEATURE_NAME
37
- constructor (agentIdentifier, aggregator) {
38
- super(agentIdentifier, aggregator, FEATURE_NAME)
34
+ constructor (agentRef) {
35
+ super(agentRef, FEATURE_NAME)
39
36
 
40
- const agentRuntime = getRuntime(agentIdentifier)
41
37
  this.state = {
42
- initialPageURL: agentRuntime.origin,
43
- lastSeenUrl: agentRuntime.origin,
38
+ initialPageURL: agentRef.runtime.origin,
39
+ lastSeenUrl: agentRef.runtime.origin,
44
40
  lastSeenRouteName: null,
45
41
  timerMap: {},
46
42
  timerBudget: MAX_TIMER_BUDGET,
@@ -51,10 +47,10 @@ export class Aggregate extends AggregateBase {
51
47
  pageLoaded: false,
52
48
  childTime: 0,
53
49
  depth: 0,
54
- harvestTimeSeconds: getConfigurationValue(agentIdentifier, 'spa.harvestTimeSeconds') || 10,
50
+ harvestTimeSeconds: agentRef.init.spa.harvestTimeSeconds || 10,
55
51
  interactionsToHarvest: new EventBuffer(),
56
52
  // The below feature flag is used to disable the SPA ajax fix for specific customers, see https://new-relic.atlassian.net/browse/NR-172169
57
- disableSpaFix: (getConfigurationValue(agentIdentifier, 'feature_flags') || []).indexOf('disable-spa-fix') > -1
53
+ disableSpaFix: (agentRef.init.feature_flags || []).indexOf('disable-spa-fix') > -1
58
54
  }
59
55
 
60
56
  let scheduler
@@ -62,7 +58,7 @@ export class Aggregate extends AggregateBase {
62
58
 
63
59
  const { state, serializer } = this
64
60
 
65
- const baseEE = ee.get(agentIdentifier) // <-- parent baseEE
61
+ const baseEE = ee.get(agentRef.agentIdentifier) // <-- parent baseEE
66
62
  const mutationEE = baseEE.get('mutation')
67
63
  const promiseEE = baseEE.get('promise')
68
64
  const historyEE = baseEE.get('history')
@@ -110,18 +106,18 @@ export class Aggregate extends AggregateBase {
110
106
  scheduler = new HarvestScheduler('events', {
111
107
  onFinished: onHarvestFinished,
112
108
  retryDelay: state.harvestTimeSeconds
113
- }, { agentIdentifier, ee: baseEE })
109
+ }, this)
114
110
  scheduler.harvest.on('events', onHarvestStarted)
115
111
  this.drain()
116
112
  } else {
117
113
  this.blocked = true
118
- deregisterDrain(this.agentIdentifier, this.featureName)
114
+ this.deregisterDrain()
119
115
  }
120
116
  })
121
117
 
122
- if (!isEnabled()) return
118
+ if (agentRef.init.spa.enabled !== true) return
123
119
 
124
- state.initialPageLoad = new Interaction('initialPageLoad', 0, state.lastSeenUrl, state.lastSeenRouteName, onInteractionFinished, agentIdentifier)
120
+ state.initialPageLoad = new Interaction('initialPageLoad', 0, state.lastSeenUrl, state.lastSeenRouteName, onInteractionFinished, agentRef.agentIdentifier)
125
121
  state.initialPageLoad.save = true
126
122
  state.prevInteraction = state.initialPageLoad
127
123
  state.currentNode = state.initialPageLoad.root // hint
@@ -212,7 +208,7 @@ export class Aggregate extends AggregateBase {
212
208
  // Otherwise, if no interaction is currently active, create a new node ID,
213
209
  // and let the aggregator know that we entered a new event handler callback
214
210
  // so that it has a chance to possibly start an interaction.
215
- 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)
216
212
 
217
213
  // Store the interaction as prevInteraction in case it is prematurely discarded
218
214
  state.prevInteraction = ixn
@@ -310,7 +306,7 @@ export class Aggregate extends AggregateBase {
310
306
  this.sent = true
311
307
  node.dt = this.dt
312
308
  if (node.dt?.timestamp) {
313
- node.dt.timestamp = agentRuntime.timeKeeper.correctAbsoluteTimestamp(node.dt.timestamp)
309
+ node.dt.timestamp = agentRef.runtime.timeKeeper.correctAbsoluteTimestamp(node.dt.timestamp)
314
310
  }
315
311
  node.jsEnd = node.start = this.startTime
316
312
  node[INTERACTION][REMAINING]++
@@ -410,7 +406,7 @@ export class Aggregate extends AggregateBase {
410
406
  if (dtPayload && this[SPA_NODE]) {
411
407
  this[SPA_NODE].dt = dtPayload
412
408
  if (this[SPA_NODE].dt?.timestamp) {
413
- this[SPA_NODE].dt.timestamp = agentRuntime.timeKeeper.correctAbsoluteTimestamp(this[SPA_NODE].dt.timestamp)
409
+ this[SPA_NODE].dt.timestamp = agentRef.runtime.timeKeeper.correctAbsoluteTimestamp(this[SPA_NODE].dt.timestamp)
414
410
  }
415
411
  }
416
412
  }
@@ -548,7 +544,7 @@ export class Aggregate extends AggregateBase {
548
544
  var interaction
549
545
  if (state?.currentNode?.[INTERACTION]) interaction = this.ixn = state.currentNode[INTERACTION]
550
546
  else if (state?.prevNode?.end === null && state?.prevNode?.[INTERACTION]?.root?.[INTERACTION]?.eventName !== 'initialPageLoad') interaction = this.ixn = state.prevNode[INTERACTION]
551
- else interaction = this.ixn = new Interaction('api', t, state.lastSeenUrl, state.lastSeenRouteName, onInteractionFinished, agentIdentifier)
547
+ else interaction = this.ixn = new Interaction('api', t, state.lastSeenUrl, state.lastSeenRouteName, onInteractionFinished, agentRef.agentIdentifier)
552
548
  if (!state.currentNode) {
553
549
  interaction.checkFinish()
554
550
  if (state.depth) setCurrentNode(interaction.root)
@@ -702,9 +698,9 @@ export class Aggregate extends AggregateBase {
702
698
  register('function-err', function (args, obj, error) {
703
699
  if (!state.currentNode) return
704
700
  error.__newrelic ??= {}
705
- error.__newrelic[agentIdentifier] = { interactionId: state.currentNode.interaction.id }
701
+ error.__newrelic[agentRef.agentIdentifier] = { interactionId: state.currentNode.interaction.id }
706
702
  if (state.currentNode.type && state.currentNode.type !== 'interaction') {
707
- error.__newrelic[agentIdentifier].interactionNodeId = state.currentNode.id
703
+ error.__newrelic[agentRef.agentIdentifier].interactionNodeId = state.currentNode.id
708
704
  }
709
705
  }, this.featureName, baseEE)
710
706
 
@@ -751,10 +747,5 @@ export class Aggregate extends AggregateBase {
751
747
  scheduler?.scheduleHarvest(0)
752
748
  if (!scheduler) warn(19)
753
749
  }
754
-
755
- function isEnabled () {
756
- var enabled = getConfigurationValue(agentIdentifier, 'spa.enabled')
757
- return enabled !== false
758
- }
759
750
  }
760
751
  }
@@ -25,8 +25,8 @@ const {
25
25
  */
26
26
  export class Instrument extends InstrumentBase {
27
27
  static featureName = FEATURE_NAME
28
- constructor (agentIdentifier, aggregator, auto = true) {
29
- super(agentIdentifier, aggregator, FEATURE_NAME, auto)
28
+ constructor (agentRef, auto = true) {
29
+ super(agentRef, FEATURE_NAME, auto)
30
30
  if (!isBrowserScope) return // SPA not supported outside web env
31
31
 
32
32
  try {
@@ -54,7 +54,7 @@ export class Instrument extends InstrumentBase {
54
54
  promiseEE.on(CB_END, endTimestamp)
55
55
  jsonpEE.on(CB_END, endTimestamp)
56
56
 
57
- this.ee.on('fn-err', (...args) => { if (!args[2]?.__newrelic?.[agentIdentifier]) handle('function-err', [...args], undefined, this.featureName, this.ee) })
57
+ this.ee.on('fn-err', (...args) => { if (!args[2]?.__newrelic?.[agentRef.agentIdentifier]) handle('function-err', [...args], undefined, this.featureName, this.ee) })
58
58
 
59
59
  this.ee.buffer([FN_START, FN_END, 'xhr-resolved'], this.featureName)
60
60
  eventsEE.buffer([FN_START], this.featureName)
@@ -110,7 +110,7 @@ export class Instrument extends InstrumentBase {
110
110
  }
111
111
 
112
112
  this.abortHandler = this.#abort
113
- this.importAggregator()
113
+ this.importAggregator(agentRef)
114
114
  }
115
115
 
116
116
  /** Restoration and resource release tasks to be done if SPA loader is being aborted. Unwind changes to globals and subscription to DOM events. */