@newrelic/browser-agent 1.285.0 → 1.286.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 (65) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/README.md +6 -0
  3. package/dist/cjs/common/constants/env.cdn.js +1 -1
  4. package/dist/cjs/common/constants/env.npm.js +1 -1
  5. package/dist/cjs/common/dom/selector-path.js +1 -1
  6. package/dist/cjs/common/harvest/harvester.js +1 -1
  7. package/dist/cjs/common/util/feature-flags.js +2 -1
  8. package/dist/cjs/features/session_replay/shared/recorder.js +5 -0
  9. package/dist/cjs/features/session_trace/aggregate/trace/storage.js +3 -2
  10. package/dist/cjs/features/utils/aggregate-base.js +2 -4
  11. package/dist/cjs/features/utils/event-store-manager.js +1 -1
  12. package/dist/cjs/features/utils/nr1-debugger.js +1 -1
  13. package/dist/cjs/loaders/agent-base.js +1 -1
  14. package/dist/cjs/loaders/agent.js +3 -1
  15. package/dist/cjs/loaders/api/api.js +57 -61
  16. package/dist/cjs/loaders/api/apiAsync.js +19 -22
  17. package/dist/cjs/loaders/configure/configure.js +12 -15
  18. package/dist/cjs/loaders/micro-agent-base.js +1 -1
  19. package/dist/cjs/loaders/micro-agent.js +3 -1
  20. package/dist/esm/common/constants/env.cdn.js +1 -1
  21. package/dist/esm/common/constants/env.npm.js +1 -1
  22. package/dist/esm/common/dom/selector-path.js +1 -1
  23. package/dist/esm/common/harvest/harvester.js +1 -1
  24. package/dist/esm/common/util/feature-flags.js +2 -1
  25. package/dist/esm/features/session_replay/shared/recorder.js +5 -0
  26. package/dist/esm/features/session_trace/aggregate/trace/storage.js +3 -2
  27. package/dist/esm/features/utils/aggregate-base.js +2 -4
  28. package/dist/esm/features/utils/event-store-manager.js +1 -1
  29. package/dist/esm/features/utils/nr1-debugger.js +1 -1
  30. package/dist/esm/loaders/agent-base.js +1 -1
  31. package/dist/esm/loaders/agent.js +3 -1
  32. package/dist/esm/loaders/api/api.js +56 -60
  33. package/dist/esm/loaders/api/apiAsync.js +14 -17
  34. package/dist/esm/loaders/configure/configure.js +13 -16
  35. package/dist/esm/loaders/micro-agent-base.js +1 -1
  36. package/dist/esm/loaders/micro-agent.js +3 -1
  37. package/dist/types/common/dom/selector-path.d.ts.map +1 -1
  38. package/dist/types/common/util/feature-flags.d.ts.map +1 -1
  39. package/dist/types/features/session_replay/shared/recorder.d.ts.map +1 -1
  40. package/dist/types/loaders/agent.d.ts +1 -0
  41. package/dist/types/loaders/agent.d.ts.map +1 -1
  42. package/dist/types/loaders/api/api.d.ts +1 -20
  43. package/dist/types/loaders/api/api.d.ts.map +1 -1
  44. package/dist/types/loaders/api/apiAsync.d.ts +1 -1
  45. package/dist/types/loaders/api/apiAsync.d.ts.map +1 -1
  46. package/dist/types/loaders/configure/configure.d.ts +1 -0
  47. package/dist/types/loaders/configure/configure.d.ts.map +1 -1
  48. package/dist/types/loaders/micro-agent.d.ts +1 -0
  49. package/dist/types/loaders/micro-agent.d.ts.map +1 -1
  50. package/package.json +1 -1
  51. package/src/common/dom/selector-path.js +1 -3
  52. package/src/common/harvest/harvester.js +1 -1
  53. package/src/common/util/feature-flags.js +2 -1
  54. package/src/features/session_replay/shared/recorder.js +5 -0
  55. package/src/features/session_trace/aggregate/trace/storage.js +2 -2
  56. package/src/features/utils/aggregate-base.js +2 -2
  57. package/src/features/utils/event-store-manager.js +1 -1
  58. package/src/features/utils/nr1-debugger.js +1 -1
  59. package/src/loaders/agent-base.js +2 -2
  60. package/src/loaders/agent.js +4 -1
  61. package/src/loaders/api/api.js +56 -60
  62. package/src/loaders/api/apiAsync.js +14 -18
  63. package/src/loaders/configure/configure.js +12 -12
  64. package/src/loaders/micro-agent-base.js +2 -2
  65. package/src/loaders/micro-agent.js +4 -1
@@ -11,7 +11,7 @@
11
11
  /**
12
12
  * Exposes the version of the agent
13
13
  */
14
- export const VERSION = "1.285.0";
14
+ export const VERSION = "1.286.0";
15
15
 
16
16
  /**
17
17
  * Exposes the build type of the agent
@@ -40,7 +40,7 @@ export const generateSelectorPath = (elem, targetFields = []) => {
40
40
  localName
41
41
  } = elem;
42
42
  targetFields.forEach(field => {
43
- nearestFields[nearestAttrName(field)] ||= elem[field];
43
+ nearestFields[nearestAttrName(field)] ||= elem[field]?.baseVal || elem[field];
44
44
  });
45
45
  const selector = [localName, id ? "#".concat(id) : '', pathSelector ? ">".concat(pathSelector) : ''].join('');
46
46
  pathSelector = selector;
@@ -210,7 +210,7 @@ function send(agentRef, {
210
210
  }
211
211
  dispatchGlobalEvent({
212
212
  agentIdentifier: agentRef.agentIdentifier,
213
- loaded: !!activatedFeatures?.[agentRef.agentIdentifier],
213
+ drained: !!activatedFeatures?.[agentRef.agentIdentifier],
214
214
  type: 'data',
215
215
  name: 'harvest',
216
216
  feature: featureName,
@@ -25,10 +25,11 @@ export function activateFeatures(flags, agentIdentifier) {
25
25
  activatedFeatures[agentIdentifier] = flags;
26
26
  sentIds.add(agentIdentifier);
27
27
 
28
- // let any window level subscribers know that the agent is running
28
+ // let any window level subscribers know that the agent is running, per install docs
29
29
  dispatchGlobalEvent({
30
30
  agentIdentifier,
31
31
  loaded: true,
32
+ drained: true,
32
33
  type: 'lifecycle',
33
34
  name: 'load',
34
35
  feature: undefined,
@@ -14,6 +14,8 @@ import { FEATURE_NAMES } from '../../../loaders/features/features';
14
14
  import { buildNRMetaNode, customMasker } from './utils';
15
15
  import { IDEAL_PAYLOAD_SIZE } from '../../../common/constants/agent-constants';
16
16
  import { AggregateBase } from '../../utils/aggregate-base';
17
+ import { warn } from '../../../common/util/console';
18
+ import { single } from '../../../common/util/invoke';
17
19
  export class Recorder {
18
20
  /** Each page mutation or event will be stored (raw) in this array. This array will be cleared on each harvest */
19
21
  #events;
@@ -23,6 +25,8 @@ export class Recorder {
23
25
  #preloaded;
24
26
  /** flag that if true, blocks events from being "stored". Only set to true when a full snapshot has incomplete nodes (only stylesheets ATM) */
25
27
  #fixing = false;
28
+ #warnCSSOnce = single(() => warn(47)); // notifies user of potential replayer issue if fix_stylesheets is off
29
+
26
30
  constructor(parent) {
27
31
  this.#events = new RecorderEvents();
28
32
  this.#backloggedEvents = new RecorderEvents();
@@ -124,6 +128,7 @@ export class Recorder {
124
128
  if (!this.shouldFix) {
125
129
  if (incompletes > 0) {
126
130
  this.currentBufferTarget.inlinedAllStylesheets = false;
131
+ this.#warnCSSOnce();
127
132
  handle(SUPPORTABILITY_METRIC_CHANNEL, [missingInlineSMTag + 'Skipped', incompletes], undefined, FEATURE_NAMES.metrics, this.parent.ee);
128
133
  }
129
134
  return this.store(event, isCheckout);
@@ -15,7 +15,8 @@ const ignoredEvents = {
15
15
  // we find that certain events make the data too noisy to be useful
16
16
  global: {
17
17
  mouseup: true,
18
- mousedown: true
18
+ mousedown: true,
19
+ mousemove: true
19
20
  },
20
21
  // certain events are present both in the window and in PVT metrics. PVT metrics are prefered so the window events should be ignored
21
22
  window: {
@@ -177,8 +178,8 @@ export class TraceStorage {
177
178
  this.storeSTN(evt);
178
179
  }
179
180
  shouldIgnoreEvent(event, target) {
180
- const origin = eventOrigin(event.target, target, this.parent.ee);
181
181
  if (event.type in ignoredEvents.global) return true;
182
+ const origin = eventOrigin(event.target, target, this.parent.ee);
182
183
  if (!!ignoredEvents[origin] && ignoredEvents[origin].ignoreAll) return true;
183
184
  return !!(!!ignoredEvents[origin] && event.type in ignoredEvents[origin]);
184
185
  }
@@ -138,16 +138,14 @@ export class AggregateBase extends FeatureBase {
138
138
  } catch (err) {
139
139
  // do nothing
140
140
  }
141
- configure({
142
- agentIdentifier: this.agentIdentifier
143
- }, {
141
+ configure(existingAgent, {
144
142
  ...cdn,
145
143
  info: {
146
144
  ...cdn.info,
147
145
  jsAttributes
148
146
  },
149
147
  runtime: existingAgent.runtime
150
- });
148
+ }, existingAgent.runtime.loaderType);
151
149
  }
152
150
  }
153
151
 
@@ -52,7 +52,7 @@ export class EventStoreManager {
52
52
  add(event, target) {
53
53
  dispatchGlobalEvent({
54
54
  agentIdentifier: this.agentIdentifier,
55
- loaded: !!activatedFeatures?.[this.agentIdentifier],
55
+ drained: !!activatedFeatures?.[this.agentIdentifier],
56
56
  type: 'data',
57
57
  name: 'buffer',
58
58
  feature: this.featureName,
@@ -6,7 +6,7 @@ import { gosCDN } from '../../common/window/nreum';
6
6
  const debugId = 1;
7
7
  const newrelic = gosCDN();
8
8
  export function debugNR1(agentIdentifier, location, event, otherprops = {}, debugName = 'SR') {
9
- const api = agentIdentifier ? newrelic.initializedAgents[agentIdentifier].api.addPageAction : newrelic.addPageAction;
9
+ const api = agentIdentifier ? newrelic.initializedAgents[agentIdentifier].addPageAction : newrelic.addPageAction;
10
10
  let url;
11
11
  try {
12
12
  const locURL = new URL(window.location);
@@ -20,7 +20,7 @@ export class AgentBase extends MicroAgentBase {
20
20
  * @param {...any} args
21
21
  */
22
22
  #callMethod(methodName, ...args) {
23
- if (typeof this.api?.[methodName] !== 'function') warn(35, methodName);else return this.api[methodName](...args);
23
+ if (this[methodName] === AgentBase.prototype[methodName] || this[methodName] === MicroAgentBase.prototype[methodName]) warn(35, methodName);else return this[methodName](...args);
24
24
  }
25
25
 
26
26
  /**
@@ -67,6 +67,9 @@ export class Agent extends AgentBase {
67
67
  runtime: this.runtime
68
68
  };
69
69
  }
70
+ get api() {
71
+ return this;
72
+ }
70
73
  run() {
71
74
  // Attempt to initialize all the requested features (sequentially in prio order & synchronously), with any failure aborting the whole process.
72
75
  try {
@@ -94,7 +97,6 @@ export class Agent extends AgentBase {
94
97
  this.features[featName].abortHandler?.();
95
98
  }
96
99
  const newrelic = gosNREUM();
97
- delete newrelic.initializedAgents[this.agentIdentifier]?.api; // prevent further calls to agent-specific APIs (see "configure.js")
98
100
  delete newrelic.initializedAgents[this.agentIdentifier]?.features; // GC mem used internally by features
99
101
  delete this.sharedAggregator;
100
102
  // Keep the initialized agent object with its configs for troubleshooting purposes.
@@ -3,10 +3,8 @@
3
3
  * SPDX-License-Identifier: Apache-2.0
4
4
  */
5
5
  import { FEATURE_NAMES } from '../features/features';
6
- import { getInfo, setInfo } from '../../common/config/info';
7
- import { getRuntime } from '../../common/config/runtime';
6
+ import { setInfo } from '../../common/config/info';
8
7
  import { handle } from '../../common/event-emitter/handle';
9
- import { ee } from '../../common/event-emitter/contextual-ee';
10
8
  import { drain, registerDrain } from '../../common/drain/drain';
11
9
  import { onWindowLoad } from '../../common/window/load';
12
10
  import { isBrowserScope } from '../../common/constants/runtime';
@@ -29,41 +27,39 @@ export function setTopLevelCallers() {
29
27
  });
30
28
  function caller(fnName, ...args) {
31
29
  let returnVals = [];
32
- Object.values(nr.initializedAgents).forEach(val => {
33
- if (!val || !val.api) {
30
+ Object.values(nr.initializedAgents).forEach(agt => {
31
+ if (!agt || !agt.runtime) {
34
32
  warn(38, fnName);
35
- } else if (val.exposed && val.api[fnName]) {
36
- returnVals.push(val.api[fnName](...args));
33
+ } else if (agt.exposed && agt[fnName] && agt.runtime.loaderType !== 'micro-agent') {
34
+ returnVals.push(agt[fnName](...args));
37
35
  }
38
36
  });
39
- return returnVals.length > 1 ? returnVals : returnVals[0];
37
+ return returnVals[0];
40
38
  }
41
39
  }
42
40
  const replayRunning = {};
43
- export function setAPI(agentIdentifier, forceDrain, runSoftNavOverSpa = false) {
44
- if (!forceDrain) registerDrain(agentIdentifier, 'api');
45
- const apiInterface = {};
46
- var instanceEE = ee.get(agentIdentifier);
47
- var tracerEE = instanceEE.get('tracer');
48
- replayRunning[agentIdentifier] = MODE.OFF;
49
- instanceEE.on(SR_EVENT_EMITTER_TYPES.REPLAY_RUNNING, isRunning => {
50
- replayRunning[agentIdentifier] = isRunning;
41
+ export function setAPI(agent, forceDrain) {
42
+ if (!forceDrain) registerDrain(agent.agentIdentifier, 'api');
43
+ const tracerEE = agent.ee.get('tracer');
44
+ replayRunning[agent.agentIdentifier] = MODE.OFF;
45
+ agent.ee.on(SR_EVENT_EMITTER_TYPES.REPLAY_RUNNING, isRunning => {
46
+ replayRunning[agent.agentIdentifier] = isRunning;
51
47
  });
52
- var prefix = 'api-';
53
- var spaPrefix = prefix + 'ixn-';
54
- apiInterface.log = function (message, {
48
+ const prefix = 'api-';
49
+ const spaPrefix = prefix + 'ixn-';
50
+ agent.log = function (message, {
55
51
  customAttributes = {},
56
52
  level = LOG_LEVELS.INFO
57
53
  } = {}) {
58
- handle(SUPPORTABILITY_METRIC_CHANNEL, ['API/log/called'], undefined, FEATURE_NAMES.metrics, instanceEE);
59
- bufferLog(instanceEE, message, customAttributes, level);
54
+ handle(SUPPORTABILITY_METRIC_CHANNEL, ['API/log/called'], undefined, FEATURE_NAMES.metrics, agent.ee);
55
+ bufferLog(agent.ee, message, customAttributes, level);
60
56
  };
61
- apiInterface.wrapLogger = (parent, functionName, {
57
+ agent.wrapLogger = (parent, functionName, {
62
58
  customAttributes = {},
63
59
  level = LOG_LEVELS.INFO
64
60
  } = {}) => {
65
- handle(SUPPORTABILITY_METRIC_CHANNEL, ['API/wrapLogger/called'], undefined, FEATURE_NAMES.metrics, instanceEE);
66
- wrapLogger(instanceEE, parent, functionName, {
61
+ handle(SUPPORTABILITY_METRIC_CHANNEL, ['API/wrapLogger/called'], undefined, FEATURE_NAMES.metrics, agent.ee);
62
+ wrapLogger(agent.ee, parent, functionName, {
67
63
  customAttributes,
68
64
  level
69
65
  });
@@ -71,14 +67,14 @@ export function setAPI(agentIdentifier, forceDrain, runSoftNavOverSpa = false) {
71
67
 
72
68
  // Setup stub functions that queue calls for later processing.
73
69
  asyncApiMethods.forEach(fnName => {
74
- apiInterface[fnName] = apiCall(prefix, fnName, true, 'api');
70
+ agent[fnName] = apiCall(prefix, fnName, true, 'api');
75
71
  });
76
- apiInterface.addPageAction = apiCall(prefix, 'addPageAction', true, FEATURE_NAMES.genericEvents);
77
- apiInterface.recordCustomEvent = apiCall(prefix, 'recordCustomEvent', true, FEATURE_NAMES.genericEvents);
78
- apiInterface.setPageViewName = function (name, host) {
72
+ agent.addPageAction = apiCall(prefix, 'addPageAction', true, FEATURE_NAMES.genericEvents);
73
+ agent.recordCustomEvent = apiCall(prefix, 'recordCustomEvent', true, FEATURE_NAMES.genericEvents);
74
+ agent.setPageViewName = function (name, host) {
79
75
  if (typeof name !== 'string') return;
80
76
  if (name.charAt(0) !== '/') name = '/' + name;
81
- getRuntime(agentIdentifier).customTransaction = (host || 'http://custom.transaction') + name;
77
+ agent.runtime.customTransaction = (host || 'http://custom.transaction') + name;
82
78
  return apiCall(prefix, 'setPageViewName', true)();
83
79
  };
84
80
 
@@ -91,11 +87,11 @@ export function setAPI(agentIdentifier, forceDrain, runSoftNavOverSpa = false) {
91
87
  * @returns @see apiCall
92
88
  */
93
89
  function appendJsAttribute(key, value, apiName, addToBrowserStorage) {
94
- const currentInfo = getInfo(agentIdentifier);
90
+ const currentInfo = agent.info;
95
91
  if (value === null) {
96
92
  delete currentInfo.jsAttributes[key];
97
93
  } else {
98
- setInfo(agentIdentifier, {
94
+ setInfo(agent.agentIdentifier, {
99
95
  ...currentInfo,
100
96
  jsAttributes: {
101
97
  ...currentInfo.jsAttributes,
@@ -105,7 +101,7 @@ export function setAPI(agentIdentifier, forceDrain, runSoftNavOverSpa = false) {
105
101
  }
106
102
  return apiCall(prefix, apiName, true, !!addToBrowserStorage || value === null ? 'session' : undefined)(key, value);
107
103
  }
108
- apiInterface.setCustomAttribute = function (name, value, persistAttribute = false) {
104
+ agent.setCustomAttribute = function (name, value, persistAttribute = false) {
109
105
  if (typeof name !== 'string') {
110
106
  warn(39, typeof name);
111
107
  return;
@@ -121,7 +117,7 @@ export function setAPI(agentIdentifier, forceDrain, runSoftNavOverSpa = false) {
121
117
  * @param {string} value - unique user identifier; a null user id suggests none should exist
122
118
  * @returns @see apiCall
123
119
  */
124
- apiInterface.setUserId = function (value) {
120
+ agent.setUserId = function (value) {
125
121
  if (!(typeof value === 'string' || value === null)) {
126
122
  warn(41, typeof value);
127
123
  return;
@@ -134,30 +130,30 @@ export function setAPI(agentIdentifier, forceDrain, runSoftNavOverSpa = false) {
134
130
  * @param {string|null} value - Application version -- if null, will "unset" the value
135
131
  * @returns @see apiCall
136
132
  */
137
- apiInterface.setApplicationVersion = function (value) {
133
+ agent.setApplicationVersion = function (value) {
138
134
  if (!(typeof value === 'string' || value === null)) {
139
135
  warn(42, typeof value);
140
136
  return;
141
137
  }
142
138
  return appendJsAttribute('application.version', value, 'setApplicationVersion', false);
143
139
  };
144
- apiInterface.start = () => {
140
+ agent.start = () => {
145
141
  try {
146
- handle(SUPPORTABILITY_METRIC_CHANNEL, ['API/start/called'], undefined, FEATURE_NAMES.metrics, instanceEE);
147
- instanceEE.emit('manual-start-all');
142
+ handle(SUPPORTABILITY_METRIC_CHANNEL, ['API/start/called'], undefined, FEATURE_NAMES.metrics, agent.ee);
143
+ agent.ee.emit('manual-start-all');
148
144
  } catch (err) {
149
145
  warn(23, err);
150
146
  }
151
147
  };
152
- apiInterface[SR_EVENT_EMITTER_TYPES.RECORD] = function () {
153
- handle(SUPPORTABILITY_METRIC_CHANNEL, ['API/recordReplay/called'], undefined, FEATURE_NAMES.metrics, instanceEE);
154
- handle(SR_EVENT_EMITTER_TYPES.RECORD, [], undefined, FEATURE_NAMES.sessionReplay, instanceEE);
148
+ agent[SR_EVENT_EMITTER_TYPES.RECORD] = function () {
149
+ handle(SUPPORTABILITY_METRIC_CHANNEL, ['API/recordReplay/called'], undefined, FEATURE_NAMES.metrics, agent.ee);
150
+ handle(SR_EVENT_EMITTER_TYPES.RECORD, [], undefined, FEATURE_NAMES.sessionReplay, agent.ee);
155
151
  };
156
- apiInterface[SR_EVENT_EMITTER_TYPES.PAUSE] = function () {
157
- handle(SUPPORTABILITY_METRIC_CHANNEL, ['API/pauseReplay/called'], undefined, FEATURE_NAMES.metrics, instanceEE);
158
- handle(SR_EVENT_EMITTER_TYPES.PAUSE, [], undefined, FEATURE_NAMES.sessionReplay, instanceEE);
152
+ agent[SR_EVENT_EMITTER_TYPES.PAUSE] = function () {
153
+ handle(SUPPORTABILITY_METRIC_CHANNEL, ['API/pauseReplay/called'], undefined, FEATURE_NAMES.metrics, agent.ee);
154
+ handle(SR_EVENT_EMITTER_TYPES.PAUSE, [], undefined, FEATURE_NAMES.sessionReplay, agent.ee);
159
155
  };
160
- apiInterface.interaction = function (options) {
156
+ agent.interaction = function (options) {
161
157
  return new InteractionHandle().get(typeof options === 'object' ? options : {});
162
158
  };
163
159
  function InteractionHandle() {}
@@ -166,9 +162,9 @@ export function setAPI(agentIdentifier, forceDrain, runSoftNavOverSpa = false) {
166
162
  var contextStore = {};
167
163
  var ixn = this;
168
164
  var hasCb = typeof cb === 'function';
169
- handle(SUPPORTABILITY_METRIC_CHANNEL, ['API/createTracer/called'], undefined, FEATURE_NAMES.metrics, instanceEE);
165
+ handle(SUPPORTABILITY_METRIC_CHANNEL, ['API/createTracer/called'], undefined, FEATURE_NAMES.metrics, agent.ee);
170
166
  // Soft navigations won't support Tracer nodes, but this fn should still work the same otherwise (e.g., run the orig cb).
171
- if (!runSoftNavOverSpa) handle(spaPrefix + 'tracer', [now(), name, contextStore], ixn, FEATURE_NAMES.spa, instanceEE);
167
+ if (!agent.runSoftNavOverSpa) handle(spaPrefix + 'tracer', [now(), name, contextStore], ixn, FEATURE_NAMES.spa, agent.ee);
172
168
  return function () {
173
169
  tracerEE.emit((hasCb ? '' : 'no-') + 'fn-start', [now(), ixn, hasCb], contextStore);
174
170
  if (hasCb) {
@@ -187,15 +183,15 @@ export function setAPI(agentIdentifier, forceDrain, runSoftNavOverSpa = false) {
187
183
  }
188
184
  };
189
185
  ['actionText', 'setName', 'setAttribute', 'save', 'ignore', 'onEnd', 'getContext', 'end', 'get'].forEach(name => {
190
- InteractionApiProto[name] = apiCall(spaPrefix, name, undefined, runSoftNavOverSpa ? FEATURE_NAMES.softNav : FEATURE_NAMES.spa);
186
+ InteractionApiProto[name] = apiCall(spaPrefix, name, undefined, agent.runSoftNavOverSpa ? FEATURE_NAMES.softNav : FEATURE_NAMES.spa);
191
187
  });
192
- apiInterface.setCurrentRouteName = runSoftNavOverSpa ? apiCall(spaPrefix, 'routeName', undefined, FEATURE_NAMES.softNav) : apiCall(prefix, 'routeName', true, FEATURE_NAMES.spa);
188
+ agent.setCurrentRouteName = agent.runSoftNavOverSpa ? apiCall(spaPrefix, 'routeName', undefined, FEATURE_NAMES.softNav) : apiCall(prefix, 'routeName', true, FEATURE_NAMES.spa);
193
189
  function apiCall(prefix, name, notSpa, bufferGroup) {
194
190
  return function () {
195
- handle(SUPPORTABILITY_METRIC_CHANNEL, ['API/' + name + '/called'], undefined, FEATURE_NAMES.metrics, instanceEE);
191
+ handle(SUPPORTABILITY_METRIC_CHANNEL, ['API/' + name + '/called'], undefined, FEATURE_NAMES.metrics, agent.ee);
196
192
  dispatchGlobalEvent({
197
- agentIdentifier,
198
- loaded: !!activatedFeatures?.[agentIdentifier],
193
+ agentIdentifier: agent.agentIdentifier,
194
+ drained: !!activatedFeatures?.[agent.agentIdentifier],
199
195
  type: 'data',
200
196
  name: 'api',
201
197
  feature: prefix + name,
@@ -204,14 +200,14 @@ export function setAPI(agentIdentifier, forceDrain, runSoftNavOverSpa = false) {
204
200
  bufferGroup
205
201
  }
206
202
  });
207
- if (bufferGroup) handle(prefix + name, [notSpa ? now() : performance.now(), ...arguments], notSpa ? null : this, bufferGroup, instanceEE); // no bufferGroup means only the SM is emitted
203
+ if (bufferGroup) handle(prefix + name, [notSpa ? now() : performance.now(), ...arguments], notSpa ? null : this, bufferGroup, agent.ee); // no bufferGroup means only the SM is emitted
208
204
  return notSpa ? undefined : this; // returns the InteractionHandle which allows these methods to be chained
209
205
  };
210
206
  }
211
- apiInterface.noticeError = function (err, customAttributes) {
207
+ agent.noticeError = function (err, customAttributes) {
212
208
  if (typeof err === 'string') err = new Error(err);
213
- handle(SUPPORTABILITY_METRIC_CHANNEL, ['API/noticeError/called'], undefined, FEATURE_NAMES.metrics, instanceEE);
214
- handle('err', [err, now(), false, customAttributes, !!replayRunning[agentIdentifier]], undefined, FEATURE_NAMES.jserrors, instanceEE);
209
+ handle(SUPPORTABILITY_METRIC_CHANNEL, ['API/noticeError/called'], undefined, FEATURE_NAMES.metrics, agent.ee);
210
+ handle('err', [err, now(), false, customAttributes, !!replayRunning[agent.agentIdentifier]], undefined, FEATURE_NAMES.jserrors, agent.ee);
215
211
  };
216
212
 
217
213
  // theres no window.load event on non-browser scopes, lazy load immediately
@@ -220,14 +216,14 @@ export function setAPI(agentIdentifier, forceDrain, runSoftNavOverSpa = false) {
220
216
  else onWindowLoad(() => lazyLoad(), true);
221
217
  function lazyLoad() {
222
218
  import(/* webpackChunkName: "async-api" */'./apiAsync').then(({
223
- setAPI
219
+ setAsyncAPI
224
220
  }) => {
225
- setAPI(agentIdentifier);
226
- drain(agentIdentifier, 'api');
221
+ setAsyncAPI(agent);
222
+ drain(agent.agentIdentifier, 'api');
227
223
  }).catch(err => {
228
224
  warn(27, err);
229
- instanceEE.abort();
225
+ agent.ee.abort();
230
226
  });
231
227
  }
232
- return apiInterface;
228
+ return true;
233
229
  }
@@ -3,16 +3,13 @@
3
3
  * SPDX-License-Identifier: Apache-2.0
4
4
  */
5
5
  import { FEATURE_NAMES } from '../features/features';
6
- import { getRuntime } from '../../common/config/runtime';
7
- import { ee } from '../../common/event-emitter/contextual-ee';
8
6
  import { handle } from '../../common/event-emitter/handle';
9
7
  import { registerHandler } from '../../common/event-emitter/register-handler';
10
8
  import { single } from '../../common/util/invoke';
11
9
  import { CUSTOM_METRIC_CHANNEL } from '../../features/metrics/constants';
12
10
  import { originTime } from '../../common/constants/runtime';
13
- export function setAPI(agentIdentifier) {
14
- var instanceEE = ee.get(agentIdentifier);
15
- var api = {
11
+ export function setAsyncAPI(agent) {
12
+ const api = {
16
13
  finished: single(finished),
17
14
  setErrorHandler,
18
15
  addToTrace,
@@ -20,40 +17,40 @@ export function setAPI(agentIdentifier) {
20
17
  };
21
18
 
22
19
  // Hook all of the api functions up to the queues/stubs created in loader/api.js
23
- Object.entries(api).forEach(([fnName, fnCall]) => registerHandler('api-' + fnName, fnCall, 'api', instanceEE));
20
+ Object.entries(api).forEach(([fnName, fnCall]) => registerHandler('api-' + fnName, fnCall, 'api', agent.ee));
24
21
 
25
22
  // All API functions get passed the time they were called as their
26
23
  // first parameter. These functions can be called asynchronously.
27
24
 
28
25
  function finished(t, providedTime) {
29
- var time = providedTime ? providedTime - originTime : t;
26
+ const time = providedTime ? providedTime - originTime : t;
30
27
  handle(CUSTOM_METRIC_CHANNEL, ['finished', {
31
28
  time
32
- }], undefined, FEATURE_NAMES.metrics, instanceEE);
29
+ }], undefined, FEATURE_NAMES.metrics, agent.ee);
33
30
  addToTrace(t, {
34
31
  name: 'finished',
35
32
  start: time + originTime,
36
33
  origin: 'nr'
37
34
  });
38
- handle('api-addPageAction', [time, 'finished'], undefined, FEATURE_NAMES.genericEvents, instanceEE);
35
+ handle('api-addPageAction', [time, 'finished'], undefined, FEATURE_NAMES.genericEvents, agent.ee);
39
36
  }
40
- function addToTrace(t, evt) {
37
+ function addToTrace(_, evt) {
41
38
  if (!(evt && typeof evt === 'object' && evt.name && evt.start)) return;
42
- var report = {
39
+ const report = {
43
40
  n: evt.name,
44
41
  s: evt.start - originTime,
45
42
  e: (evt.end || evt.start) - originTime,
46
43
  o: evt.origin || '',
47
44
  t: 'api'
48
45
  };
49
- handle('bstApi', [report], undefined, FEATURE_NAMES.sessionTrace, instanceEE);
46
+ handle('bstApi', [report], undefined, FEATURE_NAMES.sessionTrace, agent.ee);
50
47
  }
51
- function setErrorHandler(t, handler) {
52
- getRuntime(agentIdentifier).onerror = handler;
48
+ function setErrorHandler(_, handler) {
49
+ agent.runtime.onerror = handler;
53
50
  }
54
- var releaseCount = 0;
55
- function addRelease(t, name, id) {
51
+ let releaseCount = 0;
52
+ function addRelease(_, name, id) {
56
53
  if (++releaseCount > 10) return;
57
- getRuntime(agentIdentifier).releaseIds[name.slice(-200)] = ('' + id).slice(-200);
54
+ agent.runtime.releaseIds[name.slice(-200)] = ('' + id).slice(-200);
58
55
  }
59
56
  }
@@ -5,7 +5,7 @@
5
5
  import { setAPI, setTopLevelCallers } from '../api/api';
6
6
  import { addToNREUM, gosCDN } from '../../common/window/nreum';
7
7
  import { setInfo } from '../../common/config/info';
8
- import { getConfiguration, setConfiguration } from '../../common/config/init';
8
+ import { setConfiguration } from '../../common/config/init';
9
9
  import { setLoaderConfig } from '../../common/config/loader-config';
10
10
  import { setRuntime } from '../../common/config/runtime';
11
11
  import { activatedFeatures } from '../../common/util/feature-flags';
@@ -13,10 +13,11 @@ import { isWorkerScope } from '../../common/constants/runtime';
13
13
  import { redefinePublicPath } from './public-path';
14
14
  import { ee } from '../../common/event-emitter/contextual-ee';
15
15
  import { dispatchGlobalEvent } from '../../common/dispatch/global-event';
16
- let alreadySetOnce = false; // the configure() function can run multiple times in agent lifecycle
16
+ const alreadySetOnce = new Set(); // the configure() function can run multiple times in agent lifecycle for different agents
17
17
 
18
18
  /**
19
19
  * Sets or re-sets the agent's configuration values from global settings. This also attach those as properties to the agent instance.
20
+ * IMPORTANT: setNREUMInitializedAgent must be called on the agent prior to calling this function.
20
21
  */
21
22
  export function configure(agent, opts = {}, loaderType, forceDrain) {
22
23
  // eslint-disable-next-line camelcase
@@ -44,9 +45,9 @@ export function configure(agent, opts = {}, loaderType, forceDrain) {
44
45
  info.jsAttributes.isWorker = true;
45
46
  }
46
47
  setInfo(agent.agentIdentifier, info);
47
- const updatedInit = getConfiguration(agent.agentIdentifier);
48
+ const updatedInit = agent.init;
48
49
  const internalTrafficList = [info.beacon, info.errorBeacon];
49
- if (!alreadySetOnce) {
50
+ if (!alreadySetOnce.has(agent.agentIdentifier)) {
50
51
  if (updatedInit.proxy.assets) {
51
52
  redefinePublicPath(updatedInit.proxy.assets);
52
53
  internalTrafficList.push(updatedInit.proxy.assets);
@@ -61,23 +62,19 @@ export function configure(agent, opts = {}, loaderType, forceDrain) {
61
62
  runtime.denyList = [...(updatedInit.ajax.deny_list || []), ...(updatedInit.ajax.block_internal ? internalTrafficList : [])];
62
63
  runtime.ptid = agent.agentIdentifier;
63
64
  setRuntime(agent.agentIdentifier, runtime);
64
- agent.ee = ee.get(agent.agentIdentifier);
65
- if (agent.api === undefined) agent.api = setAPI(agent.agentIdentifier, forceDrain, agent.runSoftNavOverSpa);
66
- if (agent.exposed === undefined) agent.exposed = exposed;
67
- if (!alreadySetOnce) {
65
+ if (!alreadySetOnce.has(agent.agentIdentifier)) {
66
+ agent.ee = ee.get(agent.agentIdentifier);
67
+ agent.exposed = exposed;
68
+ setAPI(agent, forceDrain); // assign our API functions to the agent instance
69
+
68
70
  dispatchGlobalEvent({
69
71
  agentIdentifier: agent.agentIdentifier,
70
- loaded: !!activatedFeatures?.[agent.agentIdentifier],
72
+ drained: !!activatedFeatures?.[agent.agentIdentifier],
71
73
  type: 'lifecycle',
72
74
  name: 'initialize',
73
75
  feature: undefined,
74
- data: {
75
- init: updatedInit,
76
- info,
77
- loader_config,
78
- runtime
79
- }
76
+ data: agent.config
80
77
  });
81
78
  }
82
- alreadySetOnce = true;
79
+ alreadySetOnce.add(agent.agentIdentifier);
83
80
  }
@@ -16,7 +16,7 @@ export class MicroAgentBase {
16
16
  * @param {...any} args
17
17
  */
18
18
  #callMethod(methodName, ...args) {
19
- if (typeof this.api?.[methodName] !== 'function') warn(35, methodName);else return this.api[methodName](...args);
19
+ if (this[methodName] === MicroAgentBase.prototype[methodName]) warn(35, methodName);else return this[methodName](...args);
20
20
  }
21
21
 
22
22
  // MicroAgent class custom defines its own start
@@ -33,7 +33,6 @@ export class MicroAgent extends MicroAgentBase {
33
33
  isolatedBacklog: true
34
34
  }
35
35
  }, options.loaderType || 'micro-agent');
36
- Object.assign(this, this.api); // the APIs should be available at the class level for micro-agent
37
36
 
38
37
  /**
39
38
  * Starts a set of agent features if not running in "autoStart" mode
@@ -86,4 +85,7 @@ export class MicroAgent extends MicroAgentBase {
86
85
  runtime: this.runtime
87
86
  };
88
87
  }
88
+ get api() {
89
+ return this;
90
+ }
89
91
  }
@@ -1 +1 @@
1
- {"version":3,"file":"selector-path.d.ts","sourceRoot":"","sources":["../../../../src/common/dom/selector-path.js"],"names":[],"mappings":"AAYO,2CALI,WAAW,yBAGT,MAAM,GAAC,SAAS,CAmD5B"}
1
+ {"version":3,"file":"selector-path.d.ts","sourceRoot":"","sources":["../../../../src/common/dom/selector-path.js"],"names":[],"mappings":"AAYO,2CALI,WAAW,yBAGT,MAAM,GAAC,SAAS,CAiD5B"}
@@ -1 +1 @@
1
- {"version":3,"file":"feature-flags.d.ts","sourceRoot":"","sources":["../../../../src/common/util/feature-flags.js"],"names":[],"mappings":"AAYA;;;;;;GAMG;AACH,wCAJW;IAAC,CAAC,GAAG,EAAC,MAAM,GAAE,MAAM,CAAA;CAAC,mBACrB,MAAM,GACJ,IAAI,CAsBhB;AA9BD,gGAAgG;AAChG,mCAAmC"}
1
+ {"version":3,"file":"feature-flags.d.ts","sourceRoot":"","sources":["../../../../src/common/util/feature-flags.js"],"names":[],"mappings":"AAYA;;;;;;GAMG;AACH,wCAJW;IAAC,CAAC,GAAG,EAAC,MAAM,GAAE,MAAM,CAAA;CAAC,mBACrB,MAAM,GACJ,IAAI,CAuBhB;AA/BD,gGAAgG;AAChG,mCAAmC"}
@@ -1 +1 @@
1
- {"version":3,"file":"recorder.d.ts","sourceRoot":"","sources":["../../../../../src/features/session_replay/shared/recorder.js"],"names":[],"mappings":"AAiBA;IAUE,yBAkBC;IAdC,iEAAiE;IACjE,mBAAsB;IACtB,6DAA6D;IAC7D,oCAAuC;IACvC,+IAA+I;IAC/I,yBAA4B;IAC5B,kIAAkI;IAClI,kBAAqB;IACrB,sDAAsD;IACtD,YAAoB;IACpB,0FAA0F;IAC1F,eAAyE;IACzE,uIAAuI;IACvI,0BAAyE;IAG3E;;;;;;;;;MAmBC;IAED,mFAAmF;IACnF,oBAKC;IAED,qDAAqD;IACrD,uBA6BC;IAED;;;;;OAKG;IACH,aAHW,GAAC,cACD,GAAC,QAgCX;IAED,0HAA0H;IAC1H,yCAoDC;IA1CG,8BAAoB;IA4CxB,0HAA0H;IAC1H,yBAOC;IAED,wBAEC;IAED,gCAAgC;IAChC,uCAGC;IAED;;;SAGK;IACL,oCAGC;;CACF;+BA9N8B,mBAAmB"}
1
+ {"version":3,"file":"recorder.d.ts","sourceRoot":"","sources":["../../../../../src/features/session_replay/shared/recorder.js"],"names":[],"mappings":"AAmBA;IAYE,yBAkBC;IAdC,iEAAiE;IACjE,mBAAsB;IACtB,6DAA6D;IAC7D,oCAAuC;IACvC,+IAA+I;IAC/I,yBAA4B;IAC5B,kIAAkI;IAClI,kBAAqB;IACrB,sDAAsD;IACtD,YAAoB;IACpB,0FAA0F;IAC1F,eAAyE;IACzE,uIAAuI;IACvI,0BAAyE;IAG3E;;;;;;;;;MAmBC;IAED,mFAAmF;IACnF,oBAKC;IAED,qDAAqD;IACrD,uBA6BC;IAED;;;;;OAKG;IACH,aAHW,GAAC,cACD,GAAC,QAiCX;IAED,0HAA0H;IAC1H,yCAoDC;IA1CG,8BAAoB;IA4CxB,0HAA0H;IAC1H,yBAOC;IAED,wBAEC;IAED,gCAAgC;IAChC,uCAGC;IAED;;;SAGK;IACL,oCAGC;;CACF;+BAnO8B,mBAAmB"}
@@ -26,6 +26,7 @@ export class Agent extends AgentBase {
26
26
  loader_config: any;
27
27
  runtime: any;
28
28
  };
29
+ get api(): this;
29
30
  run(): false | undefined;
30
31
  }
31
32
  export type AgentOptions = {
@@ -1 +1 @@
1
- {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../../src/loaders/agent.js"],"names":[],"mappings":"AAqBA;;;;;;;;;GASG;AAEH;;;GAGG;AACH;IACE;;OAEG;IACH,qBAFW,YAAY,EAyBtB;IAbC,yBAAkB;IAGlB,yCAAsD;IAMtD,uCAA6G;IAM/G;;;;;MAOC;IAED,yBAsCC;CACF;;;;;UA1Fa,OAAO,uBAAuB,EAAE,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;0BAdxB,cAAc"}
1
+ {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../../src/loaders/agent.js"],"names":[],"mappings":"AAqBA;;;;;;;;;GASG;AAEH;;;GAGG;AACH;IACE;;OAEG;IACH,qBAFW,YAAY,EAyBtB;IAbC,yBAAkB;IAGlB,yCAAsD;IAMtD,uCAA6G;IAM/G;;;;;MAOC;IAED,gBAEC;IAED,yBAqCC;CACF;;;;;UA7Fa,OAAO,uBAAuB,EAAE,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;0BAdxB,cAAc"}
@@ -1,22 +1,3 @@
1
1
  export function setTopLevelCallers(): void;
2
- export function setAPI(agentIdentifier: any, forceDrain: any, runSoftNavOverSpa?: boolean): {
3
- log(message: any, { customAttributes, level }?: {
4
- customAttributes?: {} | undefined;
5
- level?: string | undefined;
6
- }): void;
7
- wrapLogger(parent: any, functionName: any, { customAttributes, level }?: {
8
- customAttributes?: {} | undefined;
9
- level?: string | undefined;
10
- }): void;
11
- addPageAction: (...args: any[]) => any;
12
- recordCustomEvent: (...args: any[]) => any;
13
- setPageViewName(name: any, host: any): any;
14
- setCustomAttribute(name: any, value: any, persistAttribute?: boolean): any;
15
- setUserId(value: string): any;
16
- setApplicationVersion(value: string | null): any;
17
- start(): void;
18
- interaction(options: any): any;
19
- setCurrentRouteName: (...args: any[]) => any;
20
- noticeError(err: any, customAttributes: any): void;
21
- };
2
+ export function setAPI(agent: any, forceDrain: any): boolean;
22
3
  //# sourceMappingURL=api.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../../../src/loaders/api/api.js"],"names":[],"mappings":"AAyBA,2CAiBC;AAID;;;;;;;;;;;;;qBAqEa,MAAM;iCAaN,MAAM,GAAC,IAAI;;;;;EAyGvB"}
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../../../src/loaders/api/api.js"],"names":[],"mappings":"AAuBA,2CAiBC;AAID,6DAyLC"}
@@ -1,2 +1,2 @@
1
- export function setAPI(agentIdentifier: any): void;
1
+ export function setAsyncAPI(agent: any): void;
2
2
  //# sourceMappingURL=apiAsync.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"apiAsync.d.ts","sourceRoot":"","sources":["../../../../src/loaders/api/apiAsync.js"],"names":[],"mappings":"AAaA,mDA8CC"}
1
+ {"version":3,"file":"apiAsync.d.ts","sourceRoot":"","sources":["../../../../src/loaders/api/apiAsync.js"],"names":[],"mappings":"AAWA,8CA4CC"}