@newrelic/browser-agent 1.307.0 → 1.308.0-rc.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 (68) hide show
  1. package/CHANGELOG.md +17 -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/harvest/harvester.js +1 -1
  5. package/dist/cjs/common/util/{mfe.js → v2.js} +16 -14
  6. package/dist/cjs/common/wrap/wrap-websocket.js +34 -33
  7. package/dist/cjs/features/ajax/aggregate/index.js +1 -1
  8. package/dist/cjs/features/generic_events/aggregate/index.js +3 -3
  9. package/dist/cjs/features/jserrors/aggregate/index.js +6 -16
  10. package/dist/cjs/features/logging/aggregate/index.js +3 -3
  11. package/dist/cjs/features/soft_navigations/aggregate/index.js +1 -1
  12. package/dist/cjs/features/utils/agent-session.js +1 -1
  13. package/dist/cjs/features/utils/aggregate-base.js +1 -1
  14. package/dist/cjs/interfaces/registered-entity.js +26 -1
  15. package/dist/cjs/loaders/api/interaction.js +1 -1
  16. package/dist/cjs/loaders/api/register-api-types.js +4 -1
  17. package/dist/cjs/loaders/api/register.js +44 -22
  18. package/dist/cjs/loaders/api/setUserId.js +1 -1
  19. package/dist/cjs/loaders/api-base.js +1 -1
  20. package/dist/cjs/loaders/configure/configure.js +1 -1
  21. package/dist/esm/common/constants/env.cdn.js +1 -1
  22. package/dist/esm/common/constants/env.npm.js +1 -1
  23. package/dist/esm/common/harvest/harvester.js +1 -1
  24. package/dist/esm/common/util/{mfe.js → v2.js} +15 -12
  25. package/dist/esm/common/wrap/wrap-websocket.js +34 -33
  26. package/dist/esm/features/ajax/aggregate/index.js +1 -1
  27. package/dist/esm/features/generic_events/aggregate/index.js +2 -2
  28. package/dist/esm/features/jserrors/aggregate/index.js +5 -15
  29. package/dist/esm/features/logging/aggregate/index.js +2 -2
  30. package/dist/esm/features/soft_navigations/aggregate/index.js +1 -1
  31. package/dist/esm/features/utils/agent-session.js +1 -1
  32. package/dist/esm/features/utils/aggregate-base.js +1 -1
  33. package/dist/esm/interfaces/registered-entity.js +26 -1
  34. package/dist/esm/loaders/api/interaction.js +1 -1
  35. package/dist/esm/loaders/api/register-api-types.js +4 -1
  36. package/dist/esm/loaders/api/register.js +44 -22
  37. package/dist/esm/loaders/api/setUserId.js +1 -1
  38. package/dist/esm/loaders/api-base.js +1 -1
  39. package/dist/esm/loaders/configure/configure.js +1 -1
  40. package/dist/tsconfig.tsbuildinfo +1 -1
  41. package/dist/types/common/util/{mfe.d.ts → v2.d.ts} +10 -12
  42. package/dist/types/common/util/v2.d.ts.map +1 -0
  43. package/dist/types/common/wrap/wrap-websocket.d.ts.map +1 -1
  44. package/dist/types/features/jserrors/aggregate/index.d.ts +0 -7
  45. package/dist/types/features/jserrors/aggregate/index.d.ts.map +1 -1
  46. package/dist/types/interfaces/registered-entity.d.ts +19 -0
  47. package/dist/types/interfaces/registered-entity.d.ts.map +1 -1
  48. package/dist/types/loaders/api/register-api-types.d.ts +9 -0
  49. package/dist/types/loaders/api/register-api-types.d.ts.map +1 -1
  50. package/package.json +2 -2
  51. package/src/common/harvest/harvester.js +1 -1
  52. package/src/common/util/{mfe.js → v2.js} +14 -12
  53. package/src/common/wrap/wrap-websocket.js +34 -33
  54. package/src/features/ajax/aggregate/index.js +1 -1
  55. package/src/features/generic_events/aggregate/index.js +2 -2
  56. package/src/features/jserrors/aggregate/index.js +5 -15
  57. package/src/features/logging/aggregate/index.js +2 -2
  58. package/src/features/soft_navigations/aggregate/index.js +1 -1
  59. package/src/features/utils/agent-session.js +1 -1
  60. package/src/features/utils/aggregate-base.js +1 -1
  61. package/src/interfaces/registered-entity.js +26 -1
  62. package/src/loaders/api/interaction.js +1 -1
  63. package/src/loaders/api/register-api-types.js +4 -1
  64. package/src/loaders/api/register.js +28 -15
  65. package/src/loaders/api/setUserId.js +1 -1
  66. package/src/loaders/api-base.js +1 -1
  67. package/src/loaders/configure/configure.js +1 -1
  68. package/dist/types/common/util/mfe.d.ts.map +0 -1
package/CHANGELOG.md CHANGED
@@ -3,6 +3,23 @@
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.308.0](https://github.com/newrelic/newrelic-browser-agent/compare/v1.307.0...v1.308.0) (2026-01-08)
7
+
8
+
9
+ ### Features
10
+
11
+ * Add "deregister" API ([#1632](https://github.com/newrelic/newrelic-browser-agent/issues/1632)) ([6338f04](https://github.com/newrelic/newrelic-browser-agent/commit/6338f04a2ec09ce0cbfa34e5878e14bfa5637a02))
12
+ * add child.id attribute to facilitate MFE cross-linking ([#1662](https://github.com/newrelic/newrelic-browser-agent/issues/1662)) ([71fb23f](https://github.com/newrelic/newrelic-browser-agent/commit/71fb23f75f903f32ab07c09622692dab757ce274))
13
+ * Add default close reason ([#1665](https://github.com/newrelic/newrelic-browser-agent/issues/1665)) ([6ff6d39](https://github.com/newrelic/newrelic-browser-agent/commit/6ff6d39cf2b3584de7b6b9a75fbceffd7bce00de))
14
+ * add parent.type attribute to facilitate relationship synthesis ([#1661](https://github.com/newrelic/newrelic-browser-agent/issues/1661)) ([b2d3965](https://github.com/newrelic/newrelic-browser-agent/commit/b2d39659a17e1472e5b60baed04fbd0390267d95))
15
+ * add support for mfe tags with the register API ([#1660](https://github.com/newrelic/newrelic-browser-agent/issues/1660)) ([8a835b3](https://github.com/newrelic/newrelic-browser-agent/commit/8a835b39ea62389d5922d4fedb3b55b4479dd523))
16
+
17
+
18
+ ### Bug Fixes
19
+
20
+ * Clean WebSocket URLs ([#1663](https://github.com/newrelic/newrelic-browser-agent/issues/1663)) ([a381a16](https://github.com/newrelic/newrelic-browser-agent/commit/a381a16cc6d1eabb5998188f69bb744525db3464))
21
+ * enforce non-null values on the numeric fields ([#1664](https://github.com/newrelic/newrelic-browser-agent/issues/1664)) ([78da14b](https://github.com/newrelic/newrelic-browser-agent/commit/78da14b5b5a5fcc54edfbca5284d57a3c816dd9c))
22
+
6
23
  ## [1.307.0](https://github.com/newrelic/newrelic-browser-agent/compare/v1.306.0...v1.307.0) (2026-01-06)
7
24
 
8
25
 
@@ -17,7 +17,7 @@ exports.VERSION = exports.RRWEB_VERSION = exports.RRWEB_PACKAGE_NAME = exports.D
17
17
  /**
18
18
  * Exposes the version of the agent
19
19
  */
20
- const VERSION = exports.VERSION = "1.307.0";
20
+ const VERSION = exports.VERSION = "1.308.0-rc.0";
21
21
 
22
22
  /**
23
23
  * Exposes the build type of the agent
@@ -17,7 +17,7 @@ exports.VERSION = exports.RRWEB_VERSION = exports.RRWEB_PACKAGE_NAME = exports.D
17
17
  /**
18
18
  * Exposes the version of the agent
19
19
  */
20
- const VERSION = exports.VERSION = "1.307.0";
20
+ const VERSION = exports.VERSION = "1.308.0-rc.0";
21
21
 
22
22
  /**
23
23
  * Exposes the build type of the agent
@@ -21,7 +21,7 @@ var _submitData = require("../util/submit-data");
21
21
  var _featureFlags = require("../util/feature-flags");
22
22
  var _globalEvent = require("../dispatch/global-event");
23
23
  /**
24
- * Copyright 2020-2025 New Relic, Inc. All rights reserved.
24
+ * Copyright 2020-2026 New Relic, Inc. All rights reserved.
25
25
  * SPDX-License-Identifier: Apache-2.0
26
26
  */
27
27
 
@@ -3,27 +3,26 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
+ exports.V2_TYPES = void 0;
6
7
  exports.getVersion2Attributes = getVersion2Attributes;
7
- exports.hasValidValue = hasValidValue;
8
- exports.isValidMFETarget = isValidMFETarget;
9
8
  /**
10
- * Copyright 2020-2025 New Relic, Inc. All rights reserved.
9
+ * Copyright 2020-2026 New Relic, Inc. All rights reserved.
11
10
  * SPDX-License-Identifier: Apache-2.0
12
11
  */
13
12
 
14
13
  /**
15
- * @param {Object} [target] - the target to be validated
16
- * @returns {boolean}
14
+ * @enum {string}
15
+ * @readonly
17
16
  */
18
- function isValidMFETarget(target = {}) {
19
- return !!(target.id && target.name);
20
- }
21
- function hasValidValue(val) {
22
- return typeof val === 'string' && val.trim().length < 501 || typeof val === 'number';
23
- }
17
+ const V2_TYPES = exports.V2_TYPES = {
18
+ /** Micro Frontend */
19
+ MFE: 'MFE',
20
+ /** Browser Application */
21
+ BA: 'BA'
22
+ };
24
23
 
25
24
  /**
26
- * When given a valid target, returns an object with the MFE payload attributes. Returns an empty object otherwise.
25
+ * When given a valid target, returns an object with the V2 payload attributes. Returns an empty object otherwise.
27
26
  * @note Field names may change as the schema is finalized
28
27
  *
29
28
  * @param {Object} [target] the registered target
@@ -33,16 +32,19 @@ function hasValidValue(val) {
33
32
  function getVersion2Attributes(target, aggregateInstance) {
34
33
  if (aggregateInstance?.harvestEndpointVersion !== 2) return {};
35
34
  const containerAgentEntityGuid = aggregateInstance.agentRef.runtime.appMetadata.agents[0].entityGuid;
36
- if (!isValidMFETarget(target)) {
35
+ /** if there's no target, but we are in v2 mode, this means the data belongs to the container agent */
36
+ if (!target) {
37
37
  return {
38
38
  'entity.guid': containerAgentEntityGuid,
39
39
  appId: aggregateInstance.agentRef.info.applicationID
40
40
  };
41
41
  }
42
+ /** otherwise, the data belongs to the target (MFE) and should be attributed as such */
42
43
  return {
43
44
  'source.id': target.id,
44
45
  'source.name': target.name,
45
46
  'source.type': target.type,
46
- 'parent.id': target.parent?.id || containerAgentEntityGuid
47
+ 'parent.id': target.parent?.id || containerAgentEntityGuid,
48
+ 'parent.type': target.parent?.type || V2_TYPES.BA
47
49
  };
48
50
  }
@@ -7,10 +7,11 @@ exports.wrapWebSocket = wrapWebSocket;
7
7
  var _runtime = require("../constants/runtime");
8
8
  var _uniqueId = require("../ids/unique-id");
9
9
  var _now = require("../timing/now");
10
+ var _cleanUrl = require("../url/clean-url");
10
11
  var _nreum = require("../window/nreum");
11
12
  var _pageVisibility = require("../window/page-visibility");
12
13
  /**
13
- * Copyright 2020-2025 New Relic, Inc. All rights reserved.
14
+ * Copyright 2020-2026 New Relic, Inc. All rights reserved.
14
15
  * SPDX-License-Identifier: Apache-2.0
15
16
  */
16
17
 
@@ -75,11 +76,11 @@ function wrapWebSocket(sharedEE) {
75
76
  type,
76
77
  size
77
78
  } = getDataInfo(event.data);
78
- this.nrData.messageOrigin ??= event.origin; // the origin of messages thru WS lifetime cannot be changed, so set once is sufficient
79
- this.nrData.messageCount = (this.nrData.messageCount ?? 0) + 1;
80
- this.nrData.messageBytes = (this.nrData.messageBytes ?? 0) + size;
81
- this.nrData.messageBytesMin = Math.min(this.nrData.messageBytesMin ?? Infinity, size);
82
- this.nrData.messageBytesMax = Math.max(this.nrData.messageBytesMax ?? 0, size);
79
+ this.nrData.messageOrigin ??= (0, _cleanUrl.cleanURL)(event.origin); // the origin of messages thru WS lifetime cannot be changed, so set once is sufficient
80
+ this.nrData.messageCount++;
81
+ this.nrData.messageBytes += size;
82
+ this.nrData.messageBytesMin = Math.min(this.nrData.messageBytesMin || Infinity, size);
83
+ this.nrData.messageBytesMax = Math.max(this.nrData.messageBytesMax, size);
83
84
  if (!(this.nrData.messageTypes ?? '').includes(type)) {
84
85
  this.nrData.messageTypes = this.nrData.messageTypes ? "".concat(this.nrData.messageTypes, ",").concat(type) : type;
85
86
  }
@@ -87,7 +88,7 @@ function wrapWebSocket(sharedEE) {
87
88
  this.addEventListener('close', event => {
88
89
  this.nrData.closedAt = (0, _now.now)();
89
90
  this.nrData.closeCode = event.code;
90
- this.nrData.closeReason = event.reason;
91
+ if (event.reason) this.nrData.closeReason = event.reason;
91
92
  this.nrData.closeWasClean = event.wasClean;
92
93
  this.nrData.connectedDuration = this.nrData.closedAt - this.nrData.openedAt;
93
94
  openWebSockets.delete(this); // remove from tracking set since it's now closed
@@ -123,10 +124,10 @@ function wrapWebSocket(sharedEE) {
123
124
  type,
124
125
  size
125
126
  } = getDataInfo(data);
126
- this.nrData.sendCount = (this.nrData.sendCount ?? 0) + 1;
127
- this.nrData.sendBytes = (this.nrData.sendBytes ?? 0) + size;
128
- this.nrData.sendBytesMin = Math.min(this.nrData.sendBytesMin ?? Infinity, size);
129
- this.nrData.sendBytesMax = Math.max(this.nrData.sendBytesMax ?? 0, size);
127
+ this.nrData.sendCount++;
128
+ this.nrData.sendBytes += size;
129
+ this.nrData.sendBytesMin = Math.min(this.nrData.sendBytesMin || Infinity, size);
130
+ this.nrData.sendBytesMax = Math.max(this.nrData.sendBytesMax, size);
130
131
  if (!(this.nrData.sendTypes ?? '').includes(type)) {
131
132
  this.nrData.sendTypes = this.nrData.sendTypes ? "".concat(this.nrData.sendTypes, ",").concat(type) : type;
132
133
  }
@@ -206,7 +207,7 @@ class WebSocketData {
206
207
  this.timestamp = (0, _now.now)();
207
208
 
208
209
  /** @type {string} Most current URL when WebSocket was created; relevant for SPA */
209
- this.currentUrl = window.location.href;
210
+ this.currentUrl = (0, _cleanUrl.cleanURL)(window.location.href);
210
211
 
211
212
  /*
212
213
  * pageUrl will be set by addEvent later; unlike timestamp and currentUrl, it's not sensitive to *when* it is set.
@@ -217,7 +218,7 @@ class WebSocketData {
217
218
  this.socketId = (0, _uniqueId.generateRandomHexString)(8);
218
219
 
219
220
  /** @type {string} The URL requested for the WebSocket connection */
220
- this.requestedUrl = requestedUrl;
221
+ this.requestedUrl = (0, _cleanUrl.cleanURL)(requestedUrl);
221
222
 
222
223
  /** @type {string} Comma-separated list of requested protocols */
223
224
  this.requestedProtocols = Array.isArray(requestedProtocols) ? requestedProtocols.join(',') : requestedProtocols || '';
@@ -239,33 +240,33 @@ class WebSocketData {
239
240
  /** @type {string} [messageOrigin] Origin of messages (set once) */
240
241
  this.messageOrigin = undefined;
241
242
 
242
- /** @type {number} [messageCount] Total number of messages received */
243
- this.messageCount = undefined;
243
+ /** @type {number} Total number of messages received */
244
+ this.messageCount = 0;
244
245
 
245
- /** @type {number} [messageBytes] Total bytes received */
246
- this.messageBytes = undefined;
246
+ /** @type {number} Total bytes received */
247
+ this.messageBytes = 0;
247
248
 
248
- /** @type {number} [messageBytesMin] Minimum message size received */
249
- this.messageBytesMin = undefined;
249
+ /** @type {number} Minimum message size received */
250
+ this.messageBytesMin = 0;
250
251
 
251
- /** @type {number} [messageBytesMax] Maximum message size received */
252
- this.messageBytesMax = undefined;
252
+ /** @type {number} Maximum message size received */
253
+ this.messageBytesMax = 0;
253
254
 
254
255
  /** @type {string} [messageTypes] Comma-separated list of message types received */
255
256
  this.messageTypes = undefined;
256
257
 
257
258
  // Send metrics
258
- /** @type {number} [sendCount] Total number of messages sent */
259
- this.sendCount = undefined;
259
+ /** @type {number} Total number of messages sent */
260
+ this.sendCount = 0;
260
261
 
261
- /** @type {number} [sendBytes] Total bytes sent */
262
- this.sendBytes = undefined;
262
+ /** @type {number} Total bytes sent */
263
+ this.sendBytes = 0;
263
264
 
264
- /** @type {number} [sendBytesMin] Minimum message size sent */
265
- this.sendBytesMin = undefined;
265
+ /** @type {number} Minimum message size sent */
266
+ this.sendBytesMin = 0;
266
267
 
267
- /** @type {number} [sendBytesMax] Maximum message size sent */
268
- this.sendBytesMax = undefined;
268
+ /** @type {number} Maximum message size sent */
269
+ this.sendBytesMax = 0;
269
270
 
270
271
  /** @type {string} [sendTypes] Comma-separated list of message types sent */
271
272
  this.sendTypes = undefined;
@@ -277,14 +278,14 @@ class WebSocketData {
277
278
  /** @type {number} [closeCode] WebSocket close code */
278
279
  this.closeCode = undefined;
279
280
 
280
- /** @type {string} [closeReason] WebSocket close reason */
281
- this.closeReason = undefined;
281
+ /** @type {string} WebSocket close reason */
282
+ this.closeReason = 'unknown';
282
283
 
283
284
  /** @type {boolean} [closeWasClean] Whether the connection closed cleanly */
284
285
  this.closeWasClean = undefined;
285
286
 
286
- /** @type {number} [connectedDuration] Duration of the connection in milliseconds */
287
- this.connectedDuration = undefined;
287
+ /** @type {number} Duration of the connection in milliseconds */
288
+ this.connectedDuration = 0;
288
289
 
289
290
  // Error tracking
290
291
  /** @type {boolean} [hasErrors] Whether any errors occurred */
@@ -15,7 +15,7 @@ var _gql = require("./gql");
15
15
  var _belSerializer = require("../../../common/serialize/bel-serializer");
16
16
  var _nreum = require("../../../common/window/nreum");
17
17
  /**
18
- * Copyright 2020-2025 New Relic, Inc. All rights reserved.
18
+ * Copyright 2020-2026 New Relic, Inc. All rights reserved.
19
19
  * SPDX-License-Identifier: Apache-2.0
20
20
  */
21
21
 
@@ -16,9 +16,9 @@ var _traverse = require("../../../common/util/traverse");
16
16
  var _userActionsAggregator = require("./user-actions/user-actions-aggregator");
17
17
  var _iframe = require("../../../common/dom/iframe");
18
18
  var _typeCheck = require("../../../common/util/type-check");
19
- var _mfe = require("../../../common/util/mfe");
19
+ var _v = require("../../../common/util/v2");
20
20
  /**
21
- * Copyright 2020-2025 New Relic, Inc. All rights reserved.
21
+ * Copyright 2020-2026 New Relic, Inc. All rights reserved.
22
22
  * SPDX-License-Identifier: Apache-2.0
23
23
  */
24
24
 
@@ -305,7 +305,7 @@ class Aggregate extends _aggregateBase.AggregateBase {
305
305
  pageUrl: (0, _cleanUrl.cleanURL)('' + _runtime.initialLocation),
306
306
  currentUrl: (0, _cleanUrl.cleanURL)('' + location),
307
307
  /** Specific attributes only supplied if harvesting to endpoint version 2 */
308
- ...(0, _mfe.getVersion2Attributes)(target, this)
308
+ ...(0, _v.getVersion2Attributes)(target, this)
309
309
  };
310
310
  const eventAttributes = {
311
311
  /** Agent-level custom attributes */
@@ -18,10 +18,10 @@ var _aggregateBase = require("../../utils/aggregate-base");
18
18
  var _now = require("../../../common/timing/now");
19
19
  var _traverse = require("../../../common/util/traverse");
20
20
  var _internalErrors = require("./internal-errors");
21
- var _mfe = require("../../../common/util/mfe");
21
+ var _v = require("../../../common/util/v2");
22
22
  var _causeString = require("./cause-string");
23
23
  /**
24
- * Copyright 2020-2025 New Relic, Inc. All rights reserved.
24
+ * Copyright 2020-2026 New Relic, Inc. All rights reserved.
25
25
  * SPDX-License-Identifier: Apache-2.0
26
26
  */
27
27
 
@@ -149,7 +149,7 @@ class Aggregate extends _aggregateBase.AggregateBase {
149
149
  * the canonical stack trace excludes items like the column number increasing the hit-rate of different errors potentially
150
150
  * bucketing and ultimately resulting in the loss of data in NR1.
151
151
  */
152
- var bucketHash = (0, _stringHashCode.stringHashCode)("".concat(stackInfo.name, "_").concat(stackInfo.message, "_").concat(stackInfo.stackString, "_").concat(params.hasReplay ? 1 : 0));
152
+ var bucketHash = (0, _stringHashCode.stringHashCode)("".concat(stackInfo.name, "_").concat(stackInfo.message, "_").concat(stackInfo.stackString, "_").concat(params.hasReplay ? 1 : 0, "_").concat(target?.id || 'container'));
153
153
  if (!this.stackReported[bucketHash]) {
154
154
  this.stackReported[bucketHash] = true;
155
155
  params.stack_trace = (0, _formatStackTrace.truncateSize)(stackInfo.stackString);
@@ -177,7 +177,7 @@ class Aggregate extends _aggregateBase.AggregateBase {
177
177
 
178
178
  // Trace sends the error in its payload, and both trace & replay simply listens for any error to occur.
179
179
  const jsErrorEvent = [type, bucketHash, params, newMetrics, customAttributes];
180
- if (this.shouldAllowMainAgentToCapture(target)) (0, _handle.handle)('trace-jserror', jsErrorEvent, undefined, _features.FEATURE_NAMES.sessionTrace, this.ee);
180
+ if (!target) (0, _handle.handle)('trace-jserror', jsErrorEvent, undefined, _features.FEATURE_NAMES.sessionTrace, this.ee);
181
181
  // still send EE events for other features such as above, but stop this one from aggregating internal data
182
182
  if (this.blocked) return;
183
183
  if (err.__newrelic?.[this.agentIdentifier]) {
@@ -187,7 +187,7 @@ class Aggregate extends _aggregateBase.AggregateBase {
187
187
  if (err.__newrelic?.socketId) {
188
188
  customAttributes.socketId = err.__newrelic.socketId;
189
189
  }
190
- if (this.shouldAllowMainAgentToCapture(target)) {
190
+ if (!target) {
191
191
  const softNavInUse = Boolean(this.agentRef.features?.[_features.FEATURE_NAMES.softNav]);
192
192
  if (softNavInUse) {
193
193
  // pass the error to soft nav for evaluation - it will return it via 'returnJserror' when interaction is resolved
@@ -204,7 +204,7 @@ class Aggregate extends _aggregateBase.AggregateBase {
204
204
  let [type, bucketHash, params, newMetrics, localAttrs, target] = errorInfoArr;
205
205
  const allCustomAttrs = {
206
206
  /** MFE specific attributes if in "multiple" mode (ie consumer version 2) */
207
- ...(0, _mfe.getVersion2Attributes)(target, this)
207
+ ...(0, _v.getVersion2Attributes)(target, this)
208
208
  };
209
209
  Object.entries(this.agentRef.info.jsAttributes).forEach(([k, v]) => setCustom(k, v));
210
210
  Object.entries(softNavCustomAttrs).forEach(([k, v]) => setCustom(k, v)); // when an ixn finishes, it'll pass attrs specific to the ixn; if no associated ixn, this defaults to empty
@@ -218,15 +218,5 @@ class Aggregate extends _aggregateBase.AggregateBase {
218
218
  allCustomAttrs[key] = val && typeof val === 'object' ? (0, _stringify.stringify)(val) : val;
219
219
  }
220
220
  }
221
-
222
- /**
223
- * If the event lacks an entityGuid (the default behavior), the main agent should capture the data. If the data is assigned to a sub-entity target
224
- * the main agent should not capture events unless it is configured to do so.
225
- * @param {string} target - the context object for the event
226
- * @returns {boolean} - whether the main agent should capture the event to its internal target
227
- */
228
- shouldAllowMainAgentToCapture(target) {
229
- return !target || this.agentRef.init.api.duplicate_registered_data;
230
- }
231
221
  }
232
222
  exports.Aggregate = Aggregate;
@@ -15,9 +15,9 @@ var _traverse = require("../../../common/util/traverse");
15
15
  var _constants2 = require("../../../common/session/constants");
16
16
  var _constants3 = require("../../session_replay/constants");
17
17
  var _featureGates = require("../../utils/feature-gates");
18
- var _mfe = require("../../../common/util/mfe");
18
+ var _v = require("../../../common/util/v2");
19
19
  /**
20
- * Copyright 2020-2025 New Relic, Inc. All rights reserved.
20
+ * Copyright 2020-2026 New Relic, Inc. All rights reserved.
21
21
  * SPDX-License-Identifier: Apache-2.0
22
22
  */
23
23
 
@@ -81,7 +81,7 @@ class Aggregate extends _aggregateBase.AggregateBase {
81
81
  attributes = {
82
82
  ...attributes,
83
83
  /** Specific attributes only supplied if harvesting to endpoint version 2 */
84
- ...(0, _mfe.getVersion2Attributes)(target, this)
84
+ ...(0, _v.getVersion2Attributes)(target, this)
85
85
  };
86
86
  if (typeof level === 'string') level = level.toUpperCase();
87
87
  if (!(0, _utils.isValidLogLevel)(level)) return (0, _console.warn)(30, level);
@@ -14,7 +14,7 @@ var _ajaxNode = require("./ajax-node");
14
14
  var _initialPageLoadInteraction = require("./initial-page-load-interaction");
15
15
  var _interaction = require("./interaction");
16
16
  /**
17
- * Copyright 2020-2025 New Relic, Inc. All rights reserved.
17
+ * Copyright 2020-2026 New Relic, Inc. All rights reserved.
18
18
  * SPDX-License-Identifier: Apache-2.0
19
19
  */
20
20
 
@@ -18,7 +18,7 @@ var _constants3 = require("../metrics/constants");
18
18
  var _features = require("../../loaders/features/features");
19
19
  var _sharedHandlers = require("../../loaders/api/sharedHandlers");
20
20
  /**
21
- * Copyright 2020-2025 New Relic, Inc. All rights reserved.
21
+ * Copyright 2020-2026 New Relic, Inc. All rights reserved.
22
22
  * SPDX-License-Identifier: Apache-2.0
23
23
  */
24
24
 
@@ -19,7 +19,7 @@ var _constants = require("../metrics/constants");
19
19
  var _eventAggregator = require("../../common/aggregate/event-aggregator");
20
20
  var _agentConstants = require("../../common/constants/agent-constants");
21
21
  /**
22
- * Copyright 2020-2025 New Relic, Inc. All rights reserved.
22
+ * Copyright 2020-2026 New Relic, Inc. All rights reserved.
23
23
  * SPDX-License-Identifier: Apache-2.0
24
24
  */
25
25
 
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.RegisteredEntity = void 0;
7
7
  var _console = require("../common/util/console");
8
8
  /**
9
- * Copyright 2020-2025 New Relic, Inc. All rights reserved.
9
+ * Copyright 2020-2026 New Relic, Inc. All rights reserved.
10
10
  * SPDX-License-Identifier: Apache-2.0
11
11
  */
12
12
 
@@ -54,6 +54,31 @@ class RegisteredEntity {
54
54
  (0, _console.warn)(35, 'addPageAction');
55
55
  }
56
56
 
57
+ /**
58
+ * @experimental
59
+ * IMPORTANT: This feature is being developed for use internally and is not in a public-facing production-ready state.
60
+ * It is not recommended for use in production environments and will not receive support for issues.
61
+ *
62
+ * Registers an external caller to report through the base agent to a different target than the base agent. Will be related to this registered entity when called through this access point.
63
+ * @param {import('../loaders/api/register-api-types').RegisterAPIConstructor} target the target object to report data to
64
+ @returns {import('../loaders/api/register-api-types').RegisterAPI} Returns an object that contains the available API methods and configurations to use with the external caller. See loaders/api/api.js for more information.
65
+ */
66
+ register(target) {
67
+ (0, _console.warn)(35, 'register');
68
+ }
69
+
70
+ /**
71
+ * @experimental
72
+ * IMPORTANT: This feature is being developed for use internally and is not in a public-facing production-ready state.
73
+ * It is not recommended for use in production environments and will not receive support for issues.
74
+ *
75
+ * Deregister the registered entity (this), which blocks its use and captures end of life timings.
76
+ * @returns {void}
77
+ */
78
+ deregister() {
79
+ (0, _console.warn)(35, 'deregister');
80
+ }
81
+
57
82
  /**
58
83
  * Records a custom event with a specified eventType and attributes.
59
84
  * {@link https://docs.newrelic.com/docs/browser/new-relic-browser/browser-apis/recordCustomEvent/}
@@ -11,7 +11,7 @@ var _features = require("../features/features");
11
11
  var _constants2 = require("./constants");
12
12
  var _sharedHandlers = require("./sharedHandlers");
13
13
  /**
14
- * Copyright 2020-2025 New Relic, Inc. All rights reserved.
14
+ * Copyright 2020-2026 New Relic, Inc. All rights reserved.
15
15
  * SPDX-License-Identifier: Apache-2.0
16
16
  */
17
17
 
@@ -5,7 +5,7 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.default = void 0;
7
7
  /**
8
- * Copyright 2020-2025 New Relic, Inc. All rights reserved.
8
+ * Copyright 2020-2026 New Relic, Inc. All rights reserved.
9
9
  * SPDX-License-Identifier: Apache-2.0
10
10
  */
11
11
  /**
@@ -14,6 +14,7 @@ exports.default = void 0;
14
14
  * @property {(message: string, options?: { customAttributes?: object, level?: 'ERROR' | 'TRACE' | 'DEBUG' | 'INFO' | 'WARN'}) => void} log - Capture a log for the registered entity.
15
15
  * @property {(error: Error | string, customAttributes?: object) => void} noticeError - Notice an error for the registered entity.
16
16
  * @property {(target: RegisterAPIConstructor) => RegisterAPI} register - Record a custom event for the registered entity.
17
+ * @property {() => void} deregister - Deregister the registered entity, which blocks its use and captures end of life timings.
17
18
  * @property {(eventType: string, attributes?: Object) => void} recordCustomEvent - Record a custom event for the registered entity.
18
19
  * @property {(eventType: string, options?: {start: number, end: number, duration: number, customAttributes: object}) => ({start: number, end: number, duration: number, customAttributes: object})} measure - Measures a task that is recorded as a BrowserPerformance event.
19
20
  * @property {(value: string | null) => void} setApplicationVersion - Add an application.version attribute to all outgoing data for the registered entity.
@@ -25,6 +26,7 @@ exports.default = void 0;
25
26
  * @typedef {Object} RegisterAPIConstructor
26
27
  * @property {string|number} id - The unique id for the registered entity. This will be assigned to any synthesized entities.
27
28
  * @property {string} name - The readable name for the registered entity. This will be assigned to any synthesized entities.
29
+ * @property {boolean} [isolated] - When true, each registration creates an isolated instance. When false, multiple registrations with the same id and isolated: false will share a single instance, including all custom attributes, ids, names, and metadata. Calling deregister on a shared instance will deregister it for all entities using the instance. Defaults to true.
28
30
  * @property {string} [parentId] - The parentId for the registered entity. If none was supplied, it will assume the entity guid from the main agent.
29
31
  */
30
32
  /**
@@ -35,5 +37,6 @@ exports.default = void 0;
35
37
  * @property {string} target.id - The ID for the registered entity.
36
38
  * @property {string} target.name - The name returned for the registered entity.
37
39
  * @property {string} [target.parentId] - The parentId for the registered entity. If none was supplied, it will assume the entity guid from the main agent.
40
+ * @property {boolean} [target.isolated] - When true, each registration creates an isolated instance. When false, multiple registrations with the same id and isolated: false will share a single instance, including all custom attributes, ids, names, and metadata. Calling deregister on a shared instance will deregister it for all entities using the instance. Defaults to true.
38
41
  */
39
42
  var _default = exports.default = {};
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.setupRegisterAPI = setupRegisterAPI;
7
7
  var _handle = require("../../common/event-emitter/handle");
8
8
  var _console = require("../../common/util/console");
9
- var _mfe = require("../../common/util/mfe");
9
+ var _v = require("../../common/util/v2");
10
10
  var _features = require("../features/features");
11
11
  var _now = require("../../common/timing/now");
12
12
  var _constants = require("../../features/metrics/constants");
@@ -19,7 +19,7 @@ var _invoke = require("../../common/util/invoke");
19
19
  var _measure = require("./measure");
20
20
  var _recordCustomEvent = require("./recordCustomEvent");
21
21
  /**
22
- * Copyright 2020-2025 New Relic, Inc. All rights reserved.
22
+ * Copyright 2020-2026 New Relic, Inc. All rights reserved.
23
23
  * SPDX-License-Identifier: Apache-2.0
24
24
  */
25
25
 
@@ -47,31 +47,33 @@ function setupRegisterAPI(agent) {
47
47
  * @returns {RegisterAPI} the api object to be returned from the register api method
48
48
  */
49
49
  function register(agentRef, target, parent) {
50
- const attrs = {};
51
50
  (0, _console.warn)(54, 'newrelic.register');
52
51
  target ||= {};
53
- target.type = 'MFE';
52
+ target.type = _v.V2_TYPES.MFE;
54
53
  target.licenseKey ||= agentRef.info.licenseKey; // will inherit the license key from the container agent if not provided for brevity. A future state may dictate that we need different license keys to do different things.
55
54
  target.blocked = false;
56
55
  target.parent = parent || {};
56
+ if (!Array.isArray(target.tags)) target.tags = [];
57
+ const attrs = {};
58
+ target.tags.forEach(tag => {
59
+ if (tag !== 'name' && tag !== 'id') attrs["source.".concat(tag)] = true;
60
+ });
61
+ target.isolated ??= true;
57
62
 
58
63
  /** @type {Function} a function that is set and reports when APIs are triggered -- warns the customer of the invalid state */
59
64
  let invalidApiResponse = () => {};
60
65
  /** @type {Array} the array of registered target APIs */
61
66
  const registeredEntities = agentRef.runtime.registeredEntities;
62
-
63
- /** if we have already registered this target, go ahead and re-use it */
64
- const preregisteredEntity = registeredEntities.find(({
65
- metadata: {
66
- target: {
67
- id,
68
- name
67
+ if (!target.isolated) {
68
+ /** if we have already registered this non-isolated target, go ahead and re-use it */
69
+ const sharedEntity = registeredEntities.find(({
70
+ metadata: {
71
+ target: {
72
+ id
73
+ }
69
74
  }
70
- }
71
- }) => id === target.id);
72
- if (preregisteredEntity) {
73
- if (preregisteredEntity.metadata.target.name !== target.name) preregisteredEntity.metadata.target.name = target.name;
74
- return preregisteredEntity;
75
+ }) => id === target.id && !target.isolated);
76
+ if (sharedEntity) return sharedEntity;
75
77
  }
76
78
 
77
79
  /**
@@ -82,13 +84,13 @@ function register(agentRef, target, parent) {
82
84
  target.blocked = true;
83
85
  invalidApiResponse = warning;
84
86
  };
87
+ function hasValidValue(val) {
88
+ return typeof val === 'string' && !!val.trim() && val.trim().length < 501 || typeof val === 'number';
89
+ }
85
90
 
86
91
  /** primary cases that can block the register API from working at init time */
87
92
  if (!agentRef.init.api.allow_registered_children) block((0, _invoke.single)(() => (0, _console.warn)(55)));
88
- if (!(0, _mfe.isValidMFETarget)(target)) block((0, _invoke.single)(() => (0, _console.warn)(48, target)));
89
- if (!(0, _mfe.hasValidValue)(target.id) || !(0, _mfe.hasValidValue)(target.name)) {
90
- block((0, _invoke.single)(() => (0, _console.warn)(48, target)));
91
- }
93
+ if (!hasValidValue(target.id) || !hasValidValue(target.name)) block((0, _invoke.single)(() => (0, _console.warn)(48, target)));
92
94
 
93
95
  /** @type {RegisterAPI} */
94
96
  const api = {
@@ -96,6 +98,10 @@ function register(agentRef, target, parent) {
96
98
  ...attrs,
97
99
  ...attributes
98
100
  }, agentRef], target),
101
+ deregister: () => {
102
+ /** note: blocking this instance will disable access for all entities sharing the instance, and will invalidate it from the v2 checks */
103
+ block((0, _invoke.single)(() => (0, _console.warn)(68)));
104
+ },
99
105
  log: (message, options = {}) => report(_log.log, [message, {
100
106
  ...options,
101
107
  customAttributes: {
@@ -168,8 +174,24 @@ function register(agentRef, target, parent) {
168
174
  try {
169
175
  const shouldDuplicate = agentRef.init.api.duplicate_registered_data && methodToCall.name !== 'register';
170
176
  if (shouldDuplicate) {
171
- // also report to container by providing undefined target
172
- methodToCall(...args, undefined, timestamp);
177
+ let duplicatedArgs = args;
178
+ if (args[1] instanceof Object) {
179
+ const childAttrs = {
180
+ 'child.id': target.id,
181
+ 'child.type': target.type
182
+ };
183
+ if ('customAttributes' in args[1]) duplicatedArgs = [args[0], {
184
+ ...args[1],
185
+ customAttributes: {
186
+ ...args[1].customAttributes,
187
+ ...childAttrs
188
+ }
189
+ }, ...args.slice(2)];else duplicatedArgs = [args[0], {
190
+ ...args[1],
191
+ ...childAttrs
192
+ }, ...args.slice(2)];
193
+ }
194
+ methodToCall(...duplicatedArgs, undefined, timestamp);
173
195
  }
174
196
  return methodToCall(...args, target, timestamp); // always report to target
175
197
  } catch (err) {
@@ -9,7 +9,7 @@ var _constants = require("./constants");
9
9
  var _sharedHandlers = require("./sharedHandlers");
10
10
  var _handle = require("../../common/event-emitter/handle");
11
11
  /**
12
- * Copyright 2020-2025 New Relic, Inc. All rights reserved.
12
+ * Copyright 2020-2026 New Relic, Inc. All rights reserved.
13
13
  * SPDX-License-Identifier: Apache-2.0
14
14
  */
15
15
 
@@ -7,7 +7,7 @@ exports.ApiBase = void 0;
7
7
  var _console = require("../common/util/console");
8
8
  var _constants = require("./api/constants");
9
9
  /**
10
- * Copyright 2020-2025 New Relic, Inc. All rights reserved.
10
+ * Copyright 2020-2026 New Relic, Inc. All rights reserved.
11
11
  * SPDX-License-Identifier: Apache-2.0
12
12
  */
13
13
 
@@ -16,7 +16,7 @@ var _contextualEe = require("../../common/event-emitter/contextual-ee");
16
16
  var _globalEvent = require("../../common/dispatch/global-event");
17
17
  var _loaderConfig = require("../../common/config/loader-config");
18
18
  /**
19
- * Copyright 2020-2025 New Relic, Inc. All rights reserved.
19
+ * Copyright 2020-2026 New Relic, Inc. All rights reserved.
20
20
  * SPDX-License-Identifier: Apache-2.0
21
21
  */
22
22