@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
package/CHANGELOG.md CHANGED
@@ -3,6 +3,21 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [1.286.0](https://github.com/newrelic/newrelic-browser-agent/compare/v1.285.0...v1.286.0) (2025-04-01)
7
+
8
+
9
+ ### Features
10
+
11
+ * Erase .api property on agent instance ([#1425](https://github.com/newrelic/newrelic-browser-agent/issues/1425)) ([44786ae](https://github.com/newrelic/newrelic-browser-agent/commit/44786ae60d761b40a28f6df4b7b835c1791dda5f))
12
+ * Handle duplicate agent APIs ([#1418](https://github.com/newrelic/newrelic-browser-agent/issues/1418)) ([f808447](https://github.com/newrelic/newrelic-browser-agent/commit/f8084474ea1a567a90d0615cdfeb13a8a2c1f110))
13
+ * Reduce noise from `mousemove` events ([#1424](https://github.com/newrelic/newrelic-browser-agent/issues/1424)) ([7c02a02](https://github.com/newrelic/newrelic-browser-agent/commit/7c02a02763abdd2697e9ed1d5a89d81c251dcf67))
14
+
15
+
16
+ ### Bug Fixes
17
+
18
+ * Get string className for SVG elements ([#1423](https://github.com/newrelic/newrelic-browser-agent/issues/1423)) ([0c1ce6c](https://github.com/newrelic/newrelic-browser-agent/commit/0c1ce6ca82bce15da12fe84fd91a7d6be8b4da44))
19
+ * Patch `newrelic` event detail ([#1428](https://github.com/newrelic/newrelic-browser-agent/issues/1428)) ([8601424](https://github.com/newrelic/newrelic-browser-agent/commit/86014247ed45520adbbb053d94b6f11de48e239f))
20
+
6
21
  ## [1.285.0](https://github.com/newrelic/newrelic-browser-agent/compare/v1.284.1...v1.285.0) (2025-03-18)
7
22
 
8
23
 
package/README.md CHANGED
@@ -1,5 +1,11 @@
1
1
  <a href="https://opensource.newrelic.com/oss-category/#community-plus"><picture><source media="(prefers-color-scheme: dark)" srcset="https://github.com/newrelic/opensource-website/raw/main/src/images/categories/dark/Community_Plus.png"><source media="(prefers-color-scheme: light)" srcset="https://github.com/newrelic/opensource-website/raw/main/src/images/categories/Community_Plus.png"><img alt="New Relic Open Source community plus project banner." src="https://github.com/newrelic/opensource-website/raw/main/src/images/categories/Community_Plus.png"></picture></a>
2
2
 
3
+ ### **Deployment status:**
4
+ <img src="https://img.shields.io/endpoint?style=plastic&amp;url=https%3A%2F%2Fnewrelic.github.io%2Fnewrelic-browser-agent-release%2Fbadges%2Fcurrent-version-production.json">
5
+ <img src="https://img.shields.io/endpoint?style=plastic&amp;url=https%3A%2F%2Fnewrelic.github.io%2Fnewrelic-browser-agent-release%2Fbadges%2Fcopy-paste-version-production.json">
6
+ <img src="https://img.shields.io/endpoint?style=plastic&amp;url=https%3A%2F%2Fnewrelic.github.io%2Fnewrelic-browser-agent-release%2Fbadges%2Fgeneric-deploy-percent-production.json">
7
+
8
+
3
9
  # New Relic Browser Agent
4
10
 
5
11
  The New Relic browser agent instruments your web application or site and provides observability into performance, errors, and other behaviors.
@@ -17,7 +17,7 @@ exports.VERSION = exports.RRWEB_VERSION = exports.DIST_METHOD = exports.BUILD_EN
17
17
  /**
18
18
  * Exposes the version of the agent
19
19
  */
20
- const VERSION = exports.VERSION = "1.285.0";
20
+ const VERSION = exports.VERSION = "1.286.0";
21
21
 
22
22
  /**
23
23
  * Exposes the build type of the agent
@@ -17,7 +17,7 @@ exports.VERSION = exports.RRWEB_VERSION = exports.DIST_METHOD = exports.BUILD_EN
17
17
  /**
18
18
  * Exposes the version of the agent
19
19
  */
20
- const VERSION = exports.VERSION = "1.285.0";
20
+ const VERSION = exports.VERSION = "1.286.0";
21
21
 
22
22
  /**
23
23
  * Exposes the build type of the agent
@@ -46,7 +46,7 @@ const generateSelectorPath = (elem, targetFields = []) => {
46
46
  localName
47
47
  } = elem;
48
48
  targetFields.forEach(field => {
49
- nearestFields[nearestAttrName(field)] ||= elem[field];
49
+ nearestFields[nearestAttrName(field)] ||= elem[field]?.baseVal || elem[field];
50
50
  });
51
51
  const selector = [localName, id ? "#".concat(id) : '', pathSelector ? ">".concat(pathSelector) : ''].join('');
52
52
  pathSelector = selector;
@@ -217,7 +217,7 @@ function send(agentRef, {
217
217
  }
218
218
  (0, _globalEvent.dispatchGlobalEvent)({
219
219
  agentIdentifier: agentRef.agentIdentifier,
220
- loaded: !!_featureFlags.activatedFeatures?.[agentRef.agentIdentifier],
220
+ drained: !!_featureFlags.activatedFeatures?.[agentRef.agentIdentifier],
221
221
  type: 'data',
222
222
  name: 'harvest',
223
223
  feature: featureName,
@@ -33,10 +33,11 @@ function activateFeatures(flags, agentIdentifier) {
33
33
  activatedFeatures[agentIdentifier] = flags;
34
34
  sentIds.add(agentIdentifier);
35
35
 
36
- // let any window level subscribers know that the agent is running
36
+ // let any window level subscribers know that the agent is running, per install docs
37
37
  (0, _globalEvent.dispatchGlobalEvent)({
38
38
  agentIdentifier,
39
39
  loaded: true,
40
+ drained: true,
40
41
  type: 'lifecycle',
41
42
  name: 'load',
42
43
  feature: undefined,
@@ -16,6 +16,8 @@ var _features = require("../../../loaders/features/features");
16
16
  var _utils = require("./utils");
17
17
  var _agentConstants = require("../../../common/constants/agent-constants");
18
18
  var _aggregateBase = require("../../utils/aggregate-base");
19
+ var _console = require("../../../common/util/console");
20
+ var _invoke = require("../../../common/util/invoke");
19
21
  /**
20
22
  * Copyright 2020-2025 New Relic, Inc. All rights reserved.
21
23
  * SPDX-License-Identifier: Apache-2.0
@@ -30,6 +32,8 @@ class Recorder {
30
32
  #preloaded;
31
33
  /** flag that if true, blocks events from being "stored". Only set to true when a full snapshot has incomplete nodes (only stylesheets ATM) */
32
34
  #fixing = false;
35
+ #warnCSSOnce = (0, _invoke.single)(() => (0, _console.warn)(47)); // notifies user of potential replayer issue if fix_stylesheets is off
36
+
33
37
  constructor(parent) {
34
38
  this.#events = new _recorderEvents.RecorderEvents();
35
39
  this.#backloggedEvents = new _recorderEvents.RecorderEvents();
@@ -131,6 +135,7 @@ class Recorder {
131
135
  if (!this.shouldFix) {
132
136
  if (incompletes > 0) {
133
137
  this.currentBufferTarget.inlinedAllStylesheets = false;
138
+ this.#warnCSSOnce();
134
139
  (0, _handle.handle)(_constants3.SUPPORTABILITY_METRIC_CHANNEL, [missingInlineSMTag + 'Skipped', incompletes], undefined, _features.FEATURE_NAMES.metrics, this.parent.ee);
135
140
  }
136
141
  return this.store(event, isCheckout);
@@ -22,7 +22,8 @@ const ignoredEvents = {
22
22
  // we find that certain events make the data too noisy to be useful
23
23
  global: {
24
24
  mouseup: true,
25
- mousedown: true
25
+ mousedown: true,
26
+ mousemove: true
26
27
  },
27
28
  // certain events are present both in the window and in PVT metrics. PVT metrics are prefered so the window events should be ignored
28
29
  window: {
@@ -184,8 +185,8 @@ class TraceStorage {
184
185
  this.storeSTN(evt);
185
186
  }
186
187
  shouldIgnoreEvent(event, target) {
187
- const origin = (0, _eventOrigin.eventOrigin)(event.target, target, this.parent.ee);
188
188
  if (event.type in ignoredEvents.global) return true;
189
+ const origin = (0, _eventOrigin.eventOrigin)(event.target, target, this.parent.ee);
189
190
  if (!!ignoredEvents[origin] && ignoredEvents[origin].ignoreAll) return true;
190
191
  return !!(!!ignoredEvents[origin] && event.type in ignoredEvents[origin]);
191
192
  }
@@ -145,16 +145,14 @@ class AggregateBase extends _featureBase.FeatureBase {
145
145
  } catch (err) {
146
146
  // do nothing
147
147
  }
148
- (0, _configure.configure)({
149
- agentIdentifier: this.agentIdentifier
150
- }, {
148
+ (0, _configure.configure)(existingAgent, {
151
149
  ...cdn,
152
150
  info: {
153
151
  ...cdn.info,
154
152
  jsAttributes
155
153
  },
156
154
  runtime: existingAgent.runtime
157
- });
155
+ }, existingAgent.runtime.loaderType);
158
156
  }
159
157
  }
160
158
 
@@ -58,7 +58,7 @@ class EventStoreManager {
58
58
  add(event, target) {
59
59
  (0, _globalEvent.dispatchGlobalEvent)({
60
60
  agentIdentifier: this.agentIdentifier,
61
- loaded: !!_featureFlags.activatedFeatures?.[this.agentIdentifier],
61
+ drained: !!_featureFlags.activatedFeatures?.[this.agentIdentifier],
62
62
  type: 'data',
63
63
  name: 'buffer',
64
64
  feature: this.featureName,
@@ -13,7 +13,7 @@ var _nreum = require("../../common/window/nreum");
13
13
  const debugId = 1;
14
14
  const newrelic = (0, _nreum.gosCDN)();
15
15
  function debugNR1(agentIdentifier, location, event, otherprops = {}, debugName = 'SR') {
16
- const api = agentIdentifier ? newrelic.initializedAgents[agentIdentifier].api.addPageAction : newrelic.addPageAction;
16
+ const api = agentIdentifier ? newrelic.initializedAgents[agentIdentifier].addPageAction : newrelic.addPageAction;
17
17
  let url;
18
18
  try {
19
19
  const locURL = new URL(window.location);
@@ -25,7 +25,7 @@ class AgentBase extends _microAgentBase.MicroAgentBase {
25
25
  * @param {...any} args
26
26
  */
27
27
  #callMethod(methodName, ...args) {
28
- if (typeof this.api?.[methodName] !== 'function') (0, _console.warn)(35, methodName);else return this.api[methodName](...args);
28
+ if (this[methodName] === AgentBase.prototype[methodName] || this[methodName] === _microAgentBase.MicroAgentBase.prototype[methodName]) (0, _console.warn)(35, methodName);else return this[methodName](...args);
29
29
  }
30
30
 
31
31
  /**
@@ -76,6 +76,9 @@ class Agent extends _agentBase.AgentBase {
76
76
  runtime: this.runtime
77
77
  };
78
78
  }
79
+ get api() {
80
+ return this;
81
+ }
79
82
  run() {
80
83
  // Attempt to initialize all the requested features (sequentially in prio order & synchronously), with any failure aborting the whole process.
81
84
  try {
@@ -103,7 +106,6 @@ class Agent extends _agentBase.AgentBase {
103
106
  this.features[featName].abortHandler?.();
104
107
  }
105
108
  const newrelic = (0, _nreum.gosNREUM)();
106
- delete newrelic.initializedAgents[this.agentIdentifier]?.api; // prevent further calls to agent-specific APIs (see "configure.js")
107
109
  delete newrelic.initializedAgents[this.agentIdentifier]?.features; // GC mem used internally by features
108
110
  delete this.sharedAggregator;
109
111
  // Keep the initialized agent object with its configs for troubleshooting purposes.
@@ -7,12 +7,10 @@ exports.setAPI = setAPI;
7
7
  exports.setTopLevelCallers = setTopLevelCallers;
8
8
  var _features = require("../features/features");
9
9
  var _info = require("../../common/config/info");
10
- var _runtime = require("../../common/config/runtime");
11
10
  var _handle = require("../../common/event-emitter/handle");
12
- var _contextualEe = require("../../common/event-emitter/contextual-ee");
13
11
  var _drain = require("../../common/drain/drain");
14
12
  var _load = require("../../common/window/load");
15
- var _runtime2 = require("../../common/constants/runtime");
13
+ var _runtime = require("../../common/constants/runtime");
16
14
  var _console = require("../../common/util/console");
17
15
  var _constants = require("../../features/metrics/constants");
18
16
  var _nreum = require("../../common/window/nreum");
@@ -37,41 +35,39 @@ function setTopLevelCallers() {
37
35
  });
38
36
  function caller(fnName, ...args) {
39
37
  let returnVals = [];
40
- Object.values(nr.initializedAgents).forEach(val => {
41
- if (!val || !val.api) {
38
+ Object.values(nr.initializedAgents).forEach(agt => {
39
+ if (!agt || !agt.runtime) {
42
40
  (0, _console.warn)(38, fnName);
43
- } else if (val.exposed && val.api[fnName]) {
44
- returnVals.push(val.api[fnName](...args));
41
+ } else if (agt.exposed && agt[fnName] && agt.runtime.loaderType !== 'micro-agent') {
42
+ returnVals.push(agt[fnName](...args));
45
43
  }
46
44
  });
47
- return returnVals.length > 1 ? returnVals : returnVals[0];
45
+ return returnVals[0];
48
46
  }
49
47
  }
50
48
  const replayRunning = {};
51
- function setAPI(agentIdentifier, forceDrain, runSoftNavOverSpa = false) {
52
- if (!forceDrain) (0, _drain.registerDrain)(agentIdentifier, 'api');
53
- const apiInterface = {};
54
- var instanceEE = _contextualEe.ee.get(agentIdentifier);
55
- var tracerEE = instanceEE.get('tracer');
56
- replayRunning[agentIdentifier] = _constants3.MODE.OFF;
57
- instanceEE.on(_constants2.SR_EVENT_EMITTER_TYPES.REPLAY_RUNNING, isRunning => {
58
- replayRunning[agentIdentifier] = isRunning;
49
+ function setAPI(agent, forceDrain) {
50
+ if (!forceDrain) (0, _drain.registerDrain)(agent.agentIdentifier, 'api');
51
+ const tracerEE = agent.ee.get('tracer');
52
+ replayRunning[agent.agentIdentifier] = _constants3.MODE.OFF;
53
+ agent.ee.on(_constants2.SR_EVENT_EMITTER_TYPES.REPLAY_RUNNING, isRunning => {
54
+ replayRunning[agent.agentIdentifier] = isRunning;
59
55
  });
60
- var prefix = 'api-';
61
- var spaPrefix = prefix + 'ixn-';
62
- apiInterface.log = function (message, {
56
+ const prefix = 'api-';
57
+ const spaPrefix = prefix + 'ixn-';
58
+ agent.log = function (message, {
63
59
  customAttributes = {},
64
60
  level = _constants4.LOG_LEVELS.INFO
65
61
  } = {}) {
66
- (0, _handle.handle)(_constants.SUPPORTABILITY_METRIC_CHANNEL, ['API/log/called'], undefined, _features.FEATURE_NAMES.metrics, instanceEE);
67
- (0, _utils.bufferLog)(instanceEE, message, customAttributes, level);
62
+ (0, _handle.handle)(_constants.SUPPORTABILITY_METRIC_CHANNEL, ['API/log/called'], undefined, _features.FEATURE_NAMES.metrics, agent.ee);
63
+ (0, _utils.bufferLog)(agent.ee, message, customAttributes, level);
68
64
  };
69
- apiInterface.wrapLogger = (parent, functionName, {
65
+ agent.wrapLogger = (parent, functionName, {
70
66
  customAttributes = {},
71
67
  level = _constants4.LOG_LEVELS.INFO
72
68
  } = {}) => {
73
- (0, _handle.handle)(_constants.SUPPORTABILITY_METRIC_CHANNEL, ['API/wrapLogger/called'], undefined, _features.FEATURE_NAMES.metrics, instanceEE);
74
- (0, _wrapLogger.wrapLogger)(instanceEE, parent, functionName, {
69
+ (0, _handle.handle)(_constants.SUPPORTABILITY_METRIC_CHANNEL, ['API/wrapLogger/called'], undefined, _features.FEATURE_NAMES.metrics, agent.ee);
70
+ (0, _wrapLogger.wrapLogger)(agent.ee, parent, functionName, {
75
71
  customAttributes,
76
72
  level
77
73
  });
@@ -79,14 +75,14 @@ function setAPI(agentIdentifier, forceDrain, runSoftNavOverSpa = false) {
79
75
 
80
76
  // Setup stub functions that queue calls for later processing.
81
77
  _apiMethods.asyncApiMethods.forEach(fnName => {
82
- apiInterface[fnName] = apiCall(prefix, fnName, true, 'api');
78
+ agent[fnName] = apiCall(prefix, fnName, true, 'api');
83
79
  });
84
- apiInterface.addPageAction = apiCall(prefix, 'addPageAction', true, _features.FEATURE_NAMES.genericEvents);
85
- apiInterface.recordCustomEvent = apiCall(prefix, 'recordCustomEvent', true, _features.FEATURE_NAMES.genericEvents);
86
- apiInterface.setPageViewName = function (name, host) {
80
+ agent.addPageAction = apiCall(prefix, 'addPageAction', true, _features.FEATURE_NAMES.genericEvents);
81
+ agent.recordCustomEvent = apiCall(prefix, 'recordCustomEvent', true, _features.FEATURE_NAMES.genericEvents);
82
+ agent.setPageViewName = function (name, host) {
87
83
  if (typeof name !== 'string') return;
88
84
  if (name.charAt(0) !== '/') name = '/' + name;
89
- (0, _runtime.getRuntime)(agentIdentifier).customTransaction = (host || 'http://custom.transaction') + name;
85
+ agent.runtime.customTransaction = (host || 'http://custom.transaction') + name;
90
86
  return apiCall(prefix, 'setPageViewName', true)();
91
87
  };
92
88
 
@@ -99,11 +95,11 @@ function setAPI(agentIdentifier, forceDrain, runSoftNavOverSpa = false) {
99
95
  * @returns @see apiCall
100
96
  */
101
97
  function appendJsAttribute(key, value, apiName, addToBrowserStorage) {
102
- const currentInfo = (0, _info.getInfo)(agentIdentifier);
98
+ const currentInfo = agent.info;
103
99
  if (value === null) {
104
100
  delete currentInfo.jsAttributes[key];
105
101
  } else {
106
- (0, _info.setInfo)(agentIdentifier, {
102
+ (0, _info.setInfo)(agent.agentIdentifier, {
107
103
  ...currentInfo,
108
104
  jsAttributes: {
109
105
  ...currentInfo.jsAttributes,
@@ -113,7 +109,7 @@ function setAPI(agentIdentifier, forceDrain, runSoftNavOverSpa = false) {
113
109
  }
114
110
  return apiCall(prefix, apiName, true, !!addToBrowserStorage || value === null ? 'session' : undefined)(key, value);
115
111
  }
116
- apiInterface.setCustomAttribute = function (name, value, persistAttribute = false) {
112
+ agent.setCustomAttribute = function (name, value, persistAttribute = false) {
117
113
  if (typeof name !== 'string') {
118
114
  (0, _console.warn)(39, typeof name);
119
115
  return;
@@ -129,7 +125,7 @@ function setAPI(agentIdentifier, forceDrain, runSoftNavOverSpa = false) {
129
125
  * @param {string} value - unique user identifier; a null user id suggests none should exist
130
126
  * @returns @see apiCall
131
127
  */
132
- apiInterface.setUserId = function (value) {
128
+ agent.setUserId = function (value) {
133
129
  if (!(typeof value === 'string' || value === null)) {
134
130
  (0, _console.warn)(41, typeof value);
135
131
  return;
@@ -142,30 +138,30 @@ function setAPI(agentIdentifier, forceDrain, runSoftNavOverSpa = false) {
142
138
  * @param {string|null} value - Application version -- if null, will "unset" the value
143
139
  * @returns @see apiCall
144
140
  */
145
- apiInterface.setApplicationVersion = function (value) {
141
+ agent.setApplicationVersion = function (value) {
146
142
  if (!(typeof value === 'string' || value === null)) {
147
143
  (0, _console.warn)(42, typeof value);
148
144
  return;
149
145
  }
150
146
  return appendJsAttribute('application.version', value, 'setApplicationVersion', false);
151
147
  };
152
- apiInterface.start = () => {
148
+ agent.start = () => {
153
149
  try {
154
- (0, _handle.handle)(_constants.SUPPORTABILITY_METRIC_CHANNEL, ['API/start/called'], undefined, _features.FEATURE_NAMES.metrics, instanceEE);
155
- instanceEE.emit('manual-start-all');
150
+ (0, _handle.handle)(_constants.SUPPORTABILITY_METRIC_CHANNEL, ['API/start/called'], undefined, _features.FEATURE_NAMES.metrics, agent.ee);
151
+ agent.ee.emit('manual-start-all');
156
152
  } catch (err) {
157
153
  (0, _console.warn)(23, err);
158
154
  }
159
155
  };
160
- apiInterface[_constants2.SR_EVENT_EMITTER_TYPES.RECORD] = function () {
161
- (0, _handle.handle)(_constants.SUPPORTABILITY_METRIC_CHANNEL, ['API/recordReplay/called'], undefined, _features.FEATURE_NAMES.metrics, instanceEE);
162
- (0, _handle.handle)(_constants2.SR_EVENT_EMITTER_TYPES.RECORD, [], undefined, _features.FEATURE_NAMES.sessionReplay, instanceEE);
156
+ agent[_constants2.SR_EVENT_EMITTER_TYPES.RECORD] = function () {
157
+ (0, _handle.handle)(_constants.SUPPORTABILITY_METRIC_CHANNEL, ['API/recordReplay/called'], undefined, _features.FEATURE_NAMES.metrics, agent.ee);
158
+ (0, _handle.handle)(_constants2.SR_EVENT_EMITTER_TYPES.RECORD, [], undefined, _features.FEATURE_NAMES.sessionReplay, agent.ee);
163
159
  };
164
- apiInterface[_constants2.SR_EVENT_EMITTER_TYPES.PAUSE] = function () {
165
- (0, _handle.handle)(_constants.SUPPORTABILITY_METRIC_CHANNEL, ['API/pauseReplay/called'], undefined, _features.FEATURE_NAMES.metrics, instanceEE);
166
- (0, _handle.handle)(_constants2.SR_EVENT_EMITTER_TYPES.PAUSE, [], undefined, _features.FEATURE_NAMES.sessionReplay, instanceEE);
160
+ agent[_constants2.SR_EVENT_EMITTER_TYPES.PAUSE] = function () {
161
+ (0, _handle.handle)(_constants.SUPPORTABILITY_METRIC_CHANNEL, ['API/pauseReplay/called'], undefined, _features.FEATURE_NAMES.metrics, agent.ee);
162
+ (0, _handle.handle)(_constants2.SR_EVENT_EMITTER_TYPES.PAUSE, [], undefined, _features.FEATURE_NAMES.sessionReplay, agent.ee);
167
163
  };
168
- apiInterface.interaction = function (options) {
164
+ agent.interaction = function (options) {
169
165
  return new InteractionHandle().get(typeof options === 'object' ? options : {});
170
166
  };
171
167
  function InteractionHandle() {}
@@ -174,9 +170,9 @@ function setAPI(agentIdentifier, forceDrain, runSoftNavOverSpa = false) {
174
170
  var contextStore = {};
175
171
  var ixn = this;
176
172
  var hasCb = typeof cb === 'function';
177
- (0, _handle.handle)(_constants.SUPPORTABILITY_METRIC_CHANNEL, ['API/createTracer/called'], undefined, _features.FEATURE_NAMES.metrics, instanceEE);
173
+ (0, _handle.handle)(_constants.SUPPORTABILITY_METRIC_CHANNEL, ['API/createTracer/called'], undefined, _features.FEATURE_NAMES.metrics, agent.ee);
178
174
  // Soft navigations won't support Tracer nodes, but this fn should still work the same otherwise (e.g., run the orig cb).
179
- if (!runSoftNavOverSpa) (0, _handle.handle)(spaPrefix + 'tracer', [(0, _now.now)(), name, contextStore], ixn, _features.FEATURE_NAMES.spa, instanceEE);
175
+ if (!agent.runSoftNavOverSpa) (0, _handle.handle)(spaPrefix + 'tracer', [(0, _now.now)(), name, contextStore], ixn, _features.FEATURE_NAMES.spa, agent.ee);
180
176
  return function () {
181
177
  tracerEE.emit((hasCb ? '' : 'no-') + 'fn-start', [(0, _now.now)(), ixn, hasCb], contextStore);
182
178
  if (hasCb) {
@@ -195,15 +191,15 @@ function setAPI(agentIdentifier, forceDrain, runSoftNavOverSpa = false) {
195
191
  }
196
192
  };
197
193
  ['actionText', 'setName', 'setAttribute', 'save', 'ignore', 'onEnd', 'getContext', 'end', 'get'].forEach(name => {
198
- InteractionApiProto[name] = apiCall(spaPrefix, name, undefined, runSoftNavOverSpa ? _features.FEATURE_NAMES.softNav : _features.FEATURE_NAMES.spa);
194
+ InteractionApiProto[name] = apiCall(spaPrefix, name, undefined, agent.runSoftNavOverSpa ? _features.FEATURE_NAMES.softNav : _features.FEATURE_NAMES.spa);
199
195
  });
200
- apiInterface.setCurrentRouteName = runSoftNavOverSpa ? apiCall(spaPrefix, 'routeName', undefined, _features.FEATURE_NAMES.softNav) : apiCall(prefix, 'routeName', true, _features.FEATURE_NAMES.spa);
196
+ agent.setCurrentRouteName = agent.runSoftNavOverSpa ? apiCall(spaPrefix, 'routeName', undefined, _features.FEATURE_NAMES.softNav) : apiCall(prefix, 'routeName', true, _features.FEATURE_NAMES.spa);
201
197
  function apiCall(prefix, name, notSpa, bufferGroup) {
202
198
  return function () {
203
- (0, _handle.handle)(_constants.SUPPORTABILITY_METRIC_CHANNEL, ['API/' + name + '/called'], undefined, _features.FEATURE_NAMES.metrics, instanceEE);
199
+ (0, _handle.handle)(_constants.SUPPORTABILITY_METRIC_CHANNEL, ['API/' + name + '/called'], undefined, _features.FEATURE_NAMES.metrics, agent.ee);
204
200
  (0, _globalEvent.dispatchGlobalEvent)({
205
- agentIdentifier,
206
- loaded: !!_featureFlags.activatedFeatures?.[agentIdentifier],
201
+ agentIdentifier: agent.agentIdentifier,
202
+ drained: !!_featureFlags.activatedFeatures?.[agent.agentIdentifier],
207
203
  type: 'data',
208
204
  name: 'api',
209
205
  feature: prefix + name,
@@ -212,30 +208,30 @@ function setAPI(agentIdentifier, forceDrain, runSoftNavOverSpa = false) {
212
208
  bufferGroup
213
209
  }
214
210
  });
215
- if (bufferGroup) (0, _handle.handle)(prefix + name, [notSpa ? (0, _now.now)() : performance.now(), ...arguments], notSpa ? null : this, bufferGroup, instanceEE); // no bufferGroup means only the SM is emitted
211
+ if (bufferGroup) (0, _handle.handle)(prefix + name, [notSpa ? (0, _now.now)() : performance.now(), ...arguments], notSpa ? null : this, bufferGroup, agent.ee); // no bufferGroup means only the SM is emitted
216
212
  return notSpa ? undefined : this; // returns the InteractionHandle which allows these methods to be chained
217
213
  };
218
214
  }
219
- apiInterface.noticeError = function (err, customAttributes) {
215
+ agent.noticeError = function (err, customAttributes) {
220
216
  if (typeof err === 'string') err = new Error(err);
221
- (0, _handle.handle)(_constants.SUPPORTABILITY_METRIC_CHANNEL, ['API/noticeError/called'], undefined, _features.FEATURE_NAMES.metrics, instanceEE);
222
- (0, _handle.handle)('err', [err, (0, _now.now)(), false, customAttributes, !!replayRunning[agentIdentifier]], undefined, _features.FEATURE_NAMES.jserrors, instanceEE);
217
+ (0, _handle.handle)(_constants.SUPPORTABILITY_METRIC_CHANNEL, ['API/noticeError/called'], undefined, _features.FEATURE_NAMES.metrics, agent.ee);
218
+ (0, _handle.handle)('err', [err, (0, _now.now)(), false, customAttributes, !!replayRunning[agent.agentIdentifier]], undefined, _features.FEATURE_NAMES.jserrors, agent.ee);
223
219
  };
224
220
 
225
221
  // theres no window.load event on non-browser scopes, lazy load immediately
226
- if (!_runtime2.isBrowserScope) lazyLoad();
222
+ if (!_runtime.isBrowserScope) lazyLoad();
227
223
  // try to stay out of the way of the window.load event, lazy load once that has finished.
228
224
  else (0, _load.onWindowLoad)(() => lazyLoad(), true);
229
225
  function lazyLoad() {
230
226
  Promise.resolve().then(() => _interopRequireWildcard(require(/* webpackChunkName: "async-api" */'./apiAsync'))).then(({
231
- setAPI
227
+ setAsyncAPI
232
228
  }) => {
233
- setAPI(agentIdentifier);
234
- (0, _drain.drain)(agentIdentifier, 'api');
229
+ setAsyncAPI(agent);
230
+ (0, _drain.drain)(agent.agentIdentifier, 'api');
235
231
  }).catch(err => {
236
232
  (0, _console.warn)(27, err);
237
- instanceEE.abort();
233
+ agent.ee.abort();
238
234
  });
239
235
  }
240
- return apiInterface;
236
+ return true;
241
237
  }
@@ -3,23 +3,20 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.setAPI = setAPI;
6
+ exports.setAsyncAPI = setAsyncAPI;
7
7
  var _features = require("../features/features");
8
- var _runtime = require("../../common/config/runtime");
9
- var _contextualEe = require("../../common/event-emitter/contextual-ee");
10
8
  var _handle = require("../../common/event-emitter/handle");
11
9
  var _registerHandler = require("../../common/event-emitter/register-handler");
12
10
  var _invoke = require("../../common/util/invoke");
13
11
  var _constants = require("../../features/metrics/constants");
14
- var _runtime2 = require("../../common/constants/runtime");
12
+ var _runtime = require("../../common/constants/runtime");
15
13
  /**
16
14
  * Copyright 2020-2025 New Relic, Inc. All rights reserved.
17
15
  * SPDX-License-Identifier: Apache-2.0
18
16
  */
19
17
 
20
- function setAPI(agentIdentifier) {
21
- var instanceEE = _contextualEe.ee.get(agentIdentifier);
22
- var api = {
18
+ function setAsyncAPI(agent) {
19
+ const api = {
23
20
  finished: (0, _invoke.single)(finished),
24
21
  setErrorHandler,
25
22
  addToTrace,
@@ -27,40 +24,40 @@ function setAPI(agentIdentifier) {
27
24
  };
28
25
 
29
26
  // Hook all of the api functions up to the queues/stubs created in loader/api.js
30
- Object.entries(api).forEach(([fnName, fnCall]) => (0, _registerHandler.registerHandler)('api-' + fnName, fnCall, 'api', instanceEE));
27
+ Object.entries(api).forEach(([fnName, fnCall]) => (0, _registerHandler.registerHandler)('api-' + fnName, fnCall, 'api', agent.ee));
31
28
 
32
29
  // All API functions get passed the time they were called as their
33
30
  // first parameter. These functions can be called asynchronously.
34
31
 
35
32
  function finished(t, providedTime) {
36
- var time = providedTime ? providedTime - _runtime2.originTime : t;
33
+ const time = providedTime ? providedTime - _runtime.originTime : t;
37
34
  (0, _handle.handle)(_constants.CUSTOM_METRIC_CHANNEL, ['finished', {
38
35
  time
39
- }], undefined, _features.FEATURE_NAMES.metrics, instanceEE);
36
+ }], undefined, _features.FEATURE_NAMES.metrics, agent.ee);
40
37
  addToTrace(t, {
41
38
  name: 'finished',
42
- start: time + _runtime2.originTime,
39
+ start: time + _runtime.originTime,
43
40
  origin: 'nr'
44
41
  });
45
- (0, _handle.handle)('api-addPageAction', [time, 'finished'], undefined, _features.FEATURE_NAMES.genericEvents, instanceEE);
42
+ (0, _handle.handle)('api-addPageAction', [time, 'finished'], undefined, _features.FEATURE_NAMES.genericEvents, agent.ee);
46
43
  }
47
- function addToTrace(t, evt) {
44
+ function addToTrace(_, evt) {
48
45
  if (!(evt && typeof evt === 'object' && evt.name && evt.start)) return;
49
- var report = {
46
+ const report = {
50
47
  n: evt.name,
51
- s: evt.start - _runtime2.originTime,
52
- e: (evt.end || evt.start) - _runtime2.originTime,
48
+ s: evt.start - _runtime.originTime,
49
+ e: (evt.end || evt.start) - _runtime.originTime,
53
50
  o: evt.origin || '',
54
51
  t: 'api'
55
52
  };
56
- (0, _handle.handle)('bstApi', [report], undefined, _features.FEATURE_NAMES.sessionTrace, instanceEE);
53
+ (0, _handle.handle)('bstApi', [report], undefined, _features.FEATURE_NAMES.sessionTrace, agent.ee);
57
54
  }
58
- function setErrorHandler(t, handler) {
59
- (0, _runtime.getRuntime)(agentIdentifier).onerror = handler;
55
+ function setErrorHandler(_, handler) {
56
+ agent.runtime.onerror = handler;
60
57
  }
61
- var releaseCount = 0;
62
- function addRelease(t, name, id) {
58
+ let releaseCount = 0;
59
+ function addRelease(_, name, id) {
63
60
  if (++releaseCount > 10) return;
64
- (0, _runtime.getRuntime)(agentIdentifier).releaseIds[name.slice(-200)] = ('' + id).slice(-200);
61
+ agent.runtime.releaseIds[name.slice(-200)] = ('' + id).slice(-200);
65
62
  }
66
63
  }
@@ -20,10 +20,11 @@ var _globalEvent = require("../../common/dispatch/global-event");
20
20
  * SPDX-License-Identifier: Apache-2.0
21
21
  */
22
22
 
23
- let alreadySetOnce = false; // the configure() function can run multiple times in agent lifecycle
23
+ const alreadySetOnce = new Set(); // the configure() function can run multiple times in agent lifecycle for different agents
24
24
 
25
25
  /**
26
26
  * Sets or re-sets the agent's configuration values from global settings. This also attach those as properties to the agent instance.
27
+ * IMPORTANT: setNREUMInitializedAgent must be called on the agent prior to calling this function.
27
28
  */
28
29
  function configure(agent, opts = {}, loaderType, forceDrain) {
29
30
  // eslint-disable-next-line camelcase
@@ -51,9 +52,9 @@ function configure(agent, opts = {}, loaderType, forceDrain) {
51
52
  info.jsAttributes.isWorker = true;
52
53
  }
53
54
  (0, _info.setInfo)(agent.agentIdentifier, info);
54
- const updatedInit = (0, _init.getConfiguration)(agent.agentIdentifier);
55
+ const updatedInit = agent.init;
55
56
  const internalTrafficList = [info.beacon, info.errorBeacon];
56
- if (!alreadySetOnce) {
57
+ if (!alreadySetOnce.has(agent.agentIdentifier)) {
57
58
  if (updatedInit.proxy.assets) {
58
59
  (0, _publicPath.redefinePublicPath)(updatedInit.proxy.assets);
59
60
  internalTrafficList.push(updatedInit.proxy.assets);
@@ -68,23 +69,19 @@ function configure(agent, opts = {}, loaderType, forceDrain) {
68
69
  runtime.denyList = [...(updatedInit.ajax.deny_list || []), ...(updatedInit.ajax.block_internal ? internalTrafficList : [])];
69
70
  runtime.ptid = agent.agentIdentifier;
70
71
  (0, _runtime.setRuntime)(agent.agentIdentifier, runtime);
71
- agent.ee = _contextualEe.ee.get(agent.agentIdentifier);
72
- if (agent.api === undefined) agent.api = (0, _api.setAPI)(agent.agentIdentifier, forceDrain, agent.runSoftNavOverSpa);
73
- if (agent.exposed === undefined) agent.exposed = exposed;
74
- if (!alreadySetOnce) {
72
+ if (!alreadySetOnce.has(agent.agentIdentifier)) {
73
+ agent.ee = _contextualEe.ee.get(agent.agentIdentifier);
74
+ agent.exposed = exposed;
75
+ (0, _api.setAPI)(agent, forceDrain); // assign our API functions to the agent instance
76
+
75
77
  (0, _globalEvent.dispatchGlobalEvent)({
76
78
  agentIdentifier: agent.agentIdentifier,
77
- loaded: !!_featureFlags.activatedFeatures?.[agent.agentIdentifier],
79
+ drained: !!_featureFlags.activatedFeatures?.[agent.agentIdentifier],
78
80
  type: 'lifecycle',
79
81
  name: 'initialize',
80
82
  feature: undefined,
81
- data: {
82
- init: updatedInit,
83
- info,
84
- loader_config,
85
- runtime
86
- }
83
+ data: agent.config
87
84
  });
88
85
  }
89
- alreadySetOnce = true;
86
+ alreadySetOnce.add(agent.agentIdentifier);
90
87
  }
@@ -23,7 +23,7 @@ class MicroAgentBase {
23
23
  * @param {...any} args
24
24
  */
25
25
  #callMethod(methodName, ...args) {
26
- if (typeof this.api?.[methodName] !== 'function') (0, _console.warn)(35, methodName);else return this.api[methodName](...args);
26
+ if (this[methodName] === MicroAgentBase.prototype[methodName]) (0, _console.warn)(35, methodName);else return this[methodName](...args);
27
27
  }
28
28
 
29
29
  // MicroAgent class custom defines its own start
@@ -38,7 +38,6 @@ class MicroAgent extends _microAgentBase.MicroAgentBase {
38
38
  isolatedBacklog: true
39
39
  }
40
40
  }, options.loaderType || 'micro-agent');
41
- Object.assign(this, this.api); // the APIs should be available at the class level for micro-agent
42
41
 
43
42
  /**
44
43
  * Starts a set of agent features if not running in "autoStart" mode
@@ -91,5 +90,8 @@ class MicroAgent extends _microAgentBase.MicroAgentBase {
91
90
  runtime: this.runtime
92
91
  };
93
92
  }
93
+ get api() {
94
+ return this;
95
+ }
94
96
  }
95
97
  exports.MicroAgent = MicroAgent;
@@ -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