@newrelic/browser-agent 1.301.0-rc.1 → 1.301.0-rc.2

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 (133) hide show
  1. package/dist/cjs/common/config/init-types.js +1 -1
  2. package/dist/cjs/common/config/init.js +7 -1
  3. package/dist/cjs/common/config/runtime.js +1 -1
  4. package/dist/cjs/common/constants/agent-constants.js +11 -2
  5. package/dist/cjs/common/constants/env.cdn.js +1 -1
  6. package/dist/cjs/common/constants/env.npm.js +1 -1
  7. package/dist/cjs/common/drain/drain.js +1 -1
  8. package/dist/cjs/common/harvest/harvester.js +30 -39
  9. package/dist/cjs/common/util/mfe.js +45 -0
  10. package/dist/cjs/features/generic_events/aggregate/index.js +9 -8
  11. package/dist/cjs/features/generic_events/constants.js +3 -1
  12. package/dist/cjs/features/jserrors/aggregate/index.js +18 -17
  13. package/dist/cjs/features/logging/aggregate/index.js +19 -15
  14. package/dist/cjs/features/logging/shared/utils.js +3 -3
  15. package/dist/cjs/features/page_view_event/aggregate/index.js +3 -33
  16. package/dist/cjs/features/session_replay/aggregate/index.js +13 -13
  17. package/dist/cjs/features/session_replay/shared/recorder.js +3 -2
  18. package/dist/cjs/features/session_trace/aggregate/index.js +0 -2
  19. package/dist/cjs/features/soft_navigations/aggregate/index.js +1 -2
  20. package/dist/cjs/features/utils/aggregate-base.js +45 -47
  21. package/dist/cjs/loaders/api/addPageAction.js +2 -2
  22. package/dist/cjs/loaders/api/log.js +2 -2
  23. package/dist/cjs/loaders/api/noticeError.js +2 -2
  24. package/dist/cjs/loaders/api/register-api-types.js +5 -5
  25. package/dist/cjs/loaders/api/register.js +80 -97
  26. package/dist/esm/common/config/init-types.js +1 -1
  27. package/dist/esm/common/config/init.js +7 -1
  28. package/dist/esm/common/config/runtime.js +1 -1
  29. package/dist/esm/common/constants/agent-constants.js +9 -1
  30. package/dist/esm/common/constants/env.cdn.js +1 -1
  31. package/dist/esm/common/constants/env.npm.js +1 -1
  32. package/dist/esm/common/drain/drain.js +1 -1
  33. package/dist/esm/common/harvest/harvester.js +30 -39
  34. package/dist/esm/common/util/mfe.js +38 -0
  35. package/dist/esm/features/generic_events/aggregate/index.js +9 -8
  36. package/dist/esm/features/generic_events/constants.js +3 -1
  37. package/dist/esm/features/jserrors/aggregate/index.js +18 -17
  38. package/dist/esm/features/logging/aggregate/index.js +19 -15
  39. package/dist/esm/features/logging/shared/utils.js +3 -3
  40. package/dist/esm/features/page_view_event/aggregate/index.js +3 -33
  41. package/dist/esm/features/session_replay/aggregate/index.js +13 -13
  42. package/dist/esm/features/session_replay/shared/recorder.js +3 -2
  43. package/dist/esm/features/session_trace/aggregate/index.js +0 -2
  44. package/dist/esm/features/soft_navigations/aggregate/index.js +1 -2
  45. package/dist/esm/features/utils/aggregate-base.js +46 -48
  46. package/dist/esm/loaders/api/addPageAction.js +2 -2
  47. package/dist/esm/loaders/api/log.js +2 -2
  48. package/dist/esm/loaders/api/noticeError.js +2 -2
  49. package/dist/esm/loaders/api/register-api-types.js +5 -5
  50. package/dist/esm/loaders/api/register.js +80 -97
  51. package/dist/tsconfig.tsbuildinfo +1 -1
  52. package/dist/types/common/config/init-types.d.ts +4 -1
  53. package/dist/types/common/config/init-types.d.ts.map +1 -1
  54. package/dist/types/common/config/init.d.ts.map +1 -1
  55. package/dist/types/common/constants/agent-constants.d.ts +7 -4
  56. package/dist/types/common/constants/agent-constants.d.ts.map +1 -1
  57. package/dist/types/common/harvest/harvester.d.ts +2 -2
  58. package/dist/types/common/harvest/harvester.d.ts.map +1 -1
  59. package/dist/types/common/util/mfe.d.ts +20 -0
  60. package/dist/types/common/util/mfe.d.ts.map +1 -0
  61. package/dist/types/features/generic_events/aggregate/index.d.ts +2 -2
  62. package/dist/types/features/generic_events/aggregate/index.d.ts.map +1 -1
  63. package/dist/types/features/generic_events/constants.d.ts +1 -0
  64. package/dist/types/features/jserrors/aggregate/index.d.ts +3 -3
  65. package/dist/types/features/jserrors/aggregate/index.d.ts.map +1 -1
  66. package/dist/types/features/logging/aggregate/index.d.ts +3 -3
  67. package/dist/types/features/logging/aggregate/index.d.ts.map +1 -1
  68. package/dist/types/features/logging/shared/utils.d.ts +2 -2
  69. package/dist/types/features/logging/shared/utils.d.ts.map +1 -1
  70. package/dist/types/features/page_view_event/aggregate/index.d.ts +2 -4
  71. package/dist/types/features/page_view_event/aggregate/index.d.ts.map +1 -1
  72. package/dist/types/features/session_replay/aggregate/index.d.ts +13 -4
  73. package/dist/types/features/session_replay/aggregate/index.d.ts.map +1 -1
  74. package/dist/types/features/session_replay/shared/recorder.d.ts +1 -0
  75. package/dist/types/features/session_replay/shared/recorder.d.ts.map +1 -1
  76. package/dist/types/features/session_trace/aggregate/index.d.ts.map +1 -1
  77. package/dist/types/features/soft_navigations/aggregate/index.d.ts.map +1 -1
  78. package/dist/types/features/utils/aggregate-base.d.ts +13 -5
  79. package/dist/types/features/utils/aggregate-base.d.ts.map +1 -1
  80. package/dist/types/loaders/api/addPageAction.d.ts +1 -1
  81. package/dist/types/loaders/api/addPageAction.d.ts.map +1 -1
  82. package/dist/types/loaders/api/log.d.ts +1 -1
  83. package/dist/types/loaders/api/log.d.ts.map +1 -1
  84. package/dist/types/loaders/api/noticeError.d.ts +1 -1
  85. package/dist/types/loaders/api/noticeError.d.ts.map +1 -1
  86. package/dist/types/loaders/api/register-api-types.d.ts +4 -4
  87. package/dist/types/loaders/api/register-api-types.d.ts.map +1 -1
  88. package/dist/types/loaders/api/register.d.ts +8 -1
  89. package/dist/types/loaders/api/register.d.ts.map +1 -1
  90. package/package.json +1 -1
  91. package/src/common/config/init-types.js +1 -1
  92. package/src/common/config/init.js +3 -1
  93. package/src/common/config/runtime.js +1 -1
  94. package/src/common/constants/agent-constants.js +10 -0
  95. package/src/common/drain/drain.js +1 -1
  96. package/src/common/harvest/harvester.js +27 -32
  97. package/src/common/util/mfe.js +35 -0
  98. package/src/features/generic_events/aggregate/index.js +9 -8
  99. package/src/features/generic_events/constants.js +3 -1
  100. package/src/features/jserrors/aggregate/index.js +17 -17
  101. package/src/features/logging/aggregate/index.js +20 -13
  102. package/src/features/logging/shared/utils.js +3 -3
  103. package/src/features/page_view_event/aggregate/index.js +3 -28
  104. package/src/features/session_replay/aggregate/index.js +12 -10
  105. package/src/features/session_replay/shared/recorder.js +3 -2
  106. package/src/features/session_trace/aggregate/index.js +0 -2
  107. package/src/features/soft_navigations/aggregate/index.js +1 -2
  108. package/src/features/utils/aggregate-base.js +47 -42
  109. package/src/loaders/api/addPageAction.js +2 -2
  110. package/src/loaders/api/log.js +2 -2
  111. package/src/loaders/api/noticeError.js +2 -2
  112. package/src/loaders/api/register-api-types.js +5 -5
  113. package/src/loaders/api/register.js +62 -89
  114. package/dist/cjs/common/util/target.js +0 -34
  115. package/dist/cjs/features/utils/entity-manager.js +0 -46
  116. package/dist/cjs/features/utils/event-store-manager.js +0 -174
  117. package/dist/cjs/loaders/api/register-api.js +0 -165
  118. package/dist/esm/common/util/target.js +0 -27
  119. package/dist/esm/features/utils/entity-manager.js +0 -39
  120. package/dist/esm/features/utils/event-store-manager.js +0 -166
  121. package/dist/esm/loaders/api/register-api.js +0 -159
  122. package/dist/types/common/util/target.d.ts +0 -18
  123. package/dist/types/common/util/target.d.ts.map +0 -1
  124. package/dist/types/features/utils/entity-manager.d.ts +0 -11
  125. package/dist/types/features/utils/entity-manager.d.ts.map +0 -1
  126. package/dist/types/features/utils/event-store-manager.d.ts +0 -85
  127. package/dist/types/features/utils/event-store-manager.d.ts.map +0 -1
  128. package/dist/types/loaders/api/register-api.d.ts +0 -14
  129. package/dist/types/loaders/api/register-api.d.ts.map +0 -1
  130. package/src/common/util/target.js +0 -27
  131. package/src/features/utils/entity-manager.js +0 -45
  132. package/src/features/utils/event-store-manager.js +0 -165
  133. package/src/loaders/api/register-api.js +0 -152
@@ -40,7 +40,7 @@ exports.default = void 0;
40
40
  * @property {Object} [metrics]
41
41
  * @property {boolean} [metrics.enabled] - Turn on/off the metrics feature (on by default).
42
42
  * @property {boolean} [metrics.autoStart] - If true, the agent will automatically start the metrics feature. Otherwise, it will be in a deferred state until the `start` API method is called.
43
- * @property {Array<Object>} [obfuscate] - Array of regexp and corresponding replacement patterns for obfuscating data.
43
+ * @property {{regex: RegExp | string, replacement: string}[]} [obfuscate] - Array of regexp and corresponding replacement patterns for obfuscating data.
44
44
  * @property {Object} [page_action]
45
45
  * @property {boolean} [page_action.enabled] - Must be true to allow PageAction events to be captured.
46
46
  * @property {Object} [page_view_event]
@@ -27,6 +27,7 @@ const InitModelFn = () => {
27
27
  const hiddenState = {
28
28
  feature_flags: [],
29
29
  experimental: {
30
+ allow_registered_children: false,
30
31
  resources: false
31
32
  },
32
33
  mask_selector: '*',
@@ -59,7 +60,12 @@ const InitModelFn = () => {
59
60
  autoStart: true
60
61
  },
61
62
  api: {
62
- allow_registered_children: true,
63
+ get allow_registered_children() {
64
+ return hiddenState.feature_flags.includes(_constants.FEATURE_FLAGS.REGISTER) || hiddenState.experimental.allow_registered_children;
65
+ },
66
+ set allow_registered_children(val) {
67
+ hiddenState.experimental.allow_registered_children = val;
68
+ },
63
69
  duplicate_registered_data: false
64
70
  },
65
71
  distributed_tracing: {
@@ -29,7 +29,6 @@ const RuntimeModel = {
29
29
  customTransaction: undefined,
30
30
  denyList: undefined,
31
31
  disabled: false,
32
- entityManager: undefined,
33
32
  harvester: undefined,
34
33
  isolatedBacklog: false,
35
34
  isRecording: false,
@@ -42,6 +41,7 @@ const RuntimeModel = {
42
41
  releaseIds: {},
43
42
  session: undefined,
44
43
  timeKeeper: undefined,
44
+ registeredEntities: [],
45
45
  /** a proxy is set in agent-session to track jsAttributes changes for harvesting mechanics */
46
46
  jsAttributesMetadata: {
47
47
  bytes: 0
@@ -3,12 +3,21 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.SESSION_ERROR = exports.MAX_PAYLOAD_SIZE = exports.IDEAL_PAYLOAD_SIZE = exports.DEFAULT_KEY = void 0;
6
+ exports.SUPPORTS_REGISTERED_ENTITIES = exports.SESSION_ERROR = exports.MAX_PAYLOAD_SIZE = exports.IDEAL_PAYLOAD_SIZE = exports.DEFAULT_KEY = void 0;
7
+ var _features = require("../../loaders/features/features");
7
8
  /**
8
9
  * Copyright 2020-2025 New Relic, Inc. All rights reserved.
9
10
  * SPDX-License-Identifier: Apache-2.0
10
11
  */
12
+
11
13
  const IDEAL_PAYLOAD_SIZE = exports.IDEAL_PAYLOAD_SIZE = 16000;
12
14
  const MAX_PAYLOAD_SIZE = exports.MAX_PAYLOAD_SIZE = 1000000;
13
15
  const DEFAULT_KEY = exports.DEFAULT_KEY = 'NR_CONTAINER_AGENT';
14
- const SESSION_ERROR = exports.SESSION_ERROR = 'SESSION_ERROR';
16
+ const SESSION_ERROR = exports.SESSION_ERROR = 'SESSION_ERROR';
17
+ const SUPPORTS_REGISTERED_ENTITIES = exports.SUPPORTS_REGISTERED_ENTITIES = {
18
+ [_features.FEATURE_NAMES.logging]: true,
19
+ // flip other features here when they are supported by DEM consumers
20
+ [_features.FEATURE_NAMES.genericEvents]: false,
21
+ [_features.FEATURE_NAMES.jserrors]: false,
22
+ [_features.FEATURE_NAMES.ajax]: false
23
+ };
@@ -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.301.0-rc.1";
20
+ const VERSION = exports.VERSION = "1.301.0-rc.2";
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.301.0-rc.1";
20
+ const VERSION = exports.VERSION = "1.301.0-rc.2";
21
21
 
22
22
  /**
23
23
  * Exposes the build type of the agent
@@ -130,7 +130,7 @@ function drainGroup(agentIdentifier, group, activateGroup = true) {
130
130
  }
131
131
  if (!baseEE.isolatedBacklog) delete handlers[group];
132
132
  baseEE.backlog[group] = null;
133
- baseEE.emit('drain-' + group, []); // TODO: Code exists purely for a unit test and needs to be refined
133
+ baseEE.emit('drain-' + group, []); // Informs the feature that it has drained its backlog of events, this kicks off an immediate harvest to capture any load-driven events that were buffered.
134
134
  }
135
135
 
136
136
  /**
@@ -61,35 +61,30 @@ class Harvester {
61
61
  * @returns {boolean} True if 1+ network call was made. Note that this does not mean or guarantee that it was successful (or that all were in the case of more than 1).
62
62
  */
63
63
  triggerHarvestFor(aggregateInst, localOpts = {}) {
64
- if (aggregateInst.blocked) return false;
64
+ const output = {
65
+ ranSend: false,
66
+ payload: undefined,
67
+ endpointVersion: aggregateInst.harvestEndpointVersion || 1
68
+ };
69
+ if (aggregateInst.blocked) return output;
65
70
  const submitMethod = (0, _submitData.getSubmitMethod)(localOpts);
66
- if (!submitMethod) return false;
71
+ if (!submitMethod) return output;
67
72
  const shouldRetryOnFail = !localOpts.isFinalHarvest && submitMethod === _submitData.xhr; // always retry all features harvests except for final
68
- let dataToSendArr;
69
- let ranSend = false;
70
- if (!localOpts.directSend) {
71
- // primarily used by rum call to bypass makeHarvestPayload by providing payload directly
72
- dataToSendArr = aggregateInst.makeHarvestPayload(shouldRetryOnFail, localOpts); // be sure the 'this' of makeHarvestPayload is the aggregate w/ access to its harvestOpts
73
- if (!dataToSendArr) return false; // can be undefined if storage is empty or preharvest checks failed
74
- } else dataToSendArr = [localOpts.directSend];
75
- dataToSendArr.forEach(({
76
- targetApp,
77
- payload
78
- }) => {
79
- if (!payload) return;
80
- send(this.agentRef, {
81
- endpoint: _features.FEATURE_TO_ENDPOINT[aggregateInst.featureName],
82
- targetApp,
83
- payload,
84
- localOpts,
85
- submitMethod,
86
- cbFinished,
87
- raw: aggregateInst.harvestOpts.raw,
88
- featureName: aggregateInst.featureName
89
- });
90
- ranSend = true;
73
+ output.payload = !localOpts.directSend ? aggregateInst.makeHarvestPayload(shouldRetryOnFail, localOpts) : localOpts.directSend?.payload; // features like PVE can define the payload directly, bypassing the makeHarvestPayload logic
74
+
75
+ if (!output.payload) return output;
76
+ send(this.agentRef, {
77
+ endpoint: _features.FEATURE_TO_ENDPOINT[aggregateInst.featureName],
78
+ payload: output.payload,
79
+ localOpts,
80
+ submitMethod,
81
+ cbFinished,
82
+ raw: aggregateInst.harvestOpts.raw,
83
+ featureName: aggregateInst.featureName,
84
+ endpointVersion: output.endpointVersion
91
85
  });
92
- return ranSend;
86
+ output.ranSend = true;
87
+ return output;
93
88
 
94
89
  /**
95
90
  * This is executed immediately after harvest sends the data via XHR, or if there's nothing to send. Note that this excludes on unloading / sendBeacon.
@@ -122,13 +117,13 @@ const warnings = {};
122
117
  */
123
118
  function send(agentRef, {
124
119
  endpoint,
125
- targetApp,
126
120
  payload,
127
121
  localOpts = {},
128
122
  submitMethod,
129
123
  cbFinished,
130
124
  raw,
131
- featureName
125
+ featureName,
126
+ endpointVersion = 1
132
127
  }) {
133
128
  if (!agentRef.info.errorBeacon) return false;
134
129
  let {
@@ -138,15 +133,14 @@ function send(agentRef, {
138
133
  if (Object.keys(body).length === 0 && !localOpts.sendEmptyBody) {
139
134
  // if there's no body to send, just run onfinish stuff and return
140
135
  if (cbFinished) cbFinished({
141
- sent: false,
142
- targetApp
136
+ sent: false
143
137
  });
144
138
  return false;
145
139
  }
146
140
  const protocol = agentRef.init.ssl === false ? 'http' : 'https';
147
141
  const perceivedBeacon = agentRef.init.proxy.beacon || agentRef.info.errorBeacon;
148
- const url = raw ? "".concat(protocol, "://").concat(perceivedBeacon, "/").concat(endpoint) : "".concat(protocol, "://").concat(perceivedBeacon).concat(endpoint !== _features.RUM ? '/' + endpoint : '', "/1/").concat(targetApp.licenseKey);
149
- const baseParams = !raw ? baseQueryString(agentRef, qs, endpoint, targetApp.applicationID) : '';
142
+ const url = raw ? "".concat(protocol, "://").concat(perceivedBeacon, "/").concat(endpoint) : "".concat(protocol, "://").concat(perceivedBeacon).concat(endpoint !== _features.RUM ? '/' + endpoint : '', "/").concat(endpointVersion, "/").concat(agentRef.info.licenseKey);
143
+ const baseParams = !raw ? baseQueryString(agentRef, qs, endpoint) : '';
150
144
  let payloadParams = (0, _encode.obj)(qs, agentRef.runtime.maxBytes);
151
145
  if (baseParams === '' && payloadParams.startsWith('&')) {
152
146
  payloadParams = payloadParams.substring(1);
@@ -189,8 +183,7 @@ function send(agentRef, {
189
183
  status: this.status,
190
184
  retry: shouldRetry(this.status),
191
185
  fullUrl,
192
- xhr: this,
193
- targetApp
186
+ xhr: this
194
187
  };
195
188
  if (localOpts.needResponse) cbResult.responseText = this.responseText;
196
189
  cbFinished(cbResult);
@@ -206,8 +199,7 @@ function send(agentRef, {
206
199
  status,
207
200
  retry: shouldRetry(status),
208
201
  fullUrl,
209
- fetchResponse: response,
210
- targetApp
202
+ fetchResponse: response
211
203
  };
212
204
  if (localOpts.needResponse) cbResult.responseText = await response.text();
213
205
  cbFinished(cbResult);
@@ -248,7 +240,6 @@ function send(agentRef, {
248
240
  data: {
249
241
  endpoint,
250
242
  headers,
251
- targetApp,
252
243
  payload,
253
244
  submitMethod: getSubmitMethodName(),
254
245
  raw,
@@ -298,12 +289,12 @@ function cleanPayload(payload = {}) {
298
289
  }
299
290
 
300
291
  // The stuff that gets sent every time.
301
- function baseQueryString(agentRef, qs, endpoint, applicationID) {
292
+ function baseQueryString(agentRef, qs, endpoint) {
302
293
  const ref = agentRef.runtime.obfuscator.obfuscateString((0, _cleanUrl.cleanURL)('' + _runtime.globalScope.location));
303
294
  const session = agentRef.runtime.session;
304
295
  const hr = !!session?.state.sessionReplaySentFirstChunk && session?.state.sessionReplayMode === 1 && endpoint !== _features.JSERRORS;
305
296
  const ht = !!session?.state.traceHarvestStarted && session?.state.sessionTraceMode === 1 && ![_features.LOGS, _features.BLOBS].includes(endpoint);
306
- const qps = ['a=' + applicationID, (0, _encode.param)('sa', agentRef.info.sa ? '' + agentRef.info.sa : ''), (0, _encode.param)('v', _env.VERSION), transactionNameParam(), (0, _encode.param)('ct', agentRef.runtime.customTransaction), '&rst=' + (0, _now.now)(), '&ck=0',
297
+ const qps = ['a=' + agentRef.info.applicationID, (0, _encode.param)('sa', agentRef.info.sa ? '' + agentRef.info.sa : ''), (0, _encode.param)('v', _env.VERSION), transactionNameParam(), (0, _encode.param)('ct', agentRef.runtime.customTransaction), '&rst=' + (0, _now.now)(), '&ck=0',
307
298
  // ck param DEPRECATED - still expected by backend
308
299
  '&s=' + (session?.state.value || '0'),
309
300
  // the 0 id encaps all untrackable and default traffic
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.getVersion2Attributes = getVersion2Attributes;
7
+ exports.isValidMFETarget = isValidMFETarget;
8
+ /**
9
+ * Copyright 2020-2025 New Relic, Inc. All rights reserved.
10
+ * SPDX-License-Identifier: Apache-2.0
11
+ */
12
+
13
+ /**
14
+ * @param {Object} [target] - the target to be validated
15
+ * @returns {boolean}
16
+ */
17
+ function isValidMFETarget(target = {}) {
18
+ return !!(target.id && target.name);
19
+ }
20
+
21
+ /**
22
+ * When given a valid target, returns an object with the MFE payload attributes. Returns an empty object otherwise.
23
+ * @param {Object} [target] the registered target
24
+ * @param {AggregateInstance} [aggregateInstance] the aggregate instance calling the method
25
+ * @returns {{'mfe.id': *, 'mfe.name': String}|{}} returns an empty object if args are not supplied or the aggregate instance is not supporting version 2
26
+ */
27
+ function getVersion2Attributes(target, aggregateInstance) {
28
+ if (aggregateInstance?.harvestEndpointVersion !== 2) return {};
29
+ const containerAgentEntityGuid = aggregateInstance.agentRef.runtime.appMetadata.agents[0].entityGuid;
30
+ if (!isValidMFETarget(target)) {
31
+ return {
32
+ 'entity.guid': containerAgentEntityGuid,
33
+ appId: aggregateInstance.agentRef.info.applicationID
34
+ };
35
+ }
36
+ return {
37
+ 'mfe.id': target.id,
38
+ // these field names may change as the schema is finalized
39
+ 'mfe.name': target.name,
40
+ // these field names may change as the schema is finalized
41
+ eventSource: 'MicroFrontendBrowserAgent',
42
+ // these field names may change as the schema is finalized
43
+ 'parent.id': containerAgentEntityGuid
44
+ };
45
+ }
@@ -16,6 +16,7 @@ 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
20
  /**
20
21
  * Copyright 2020-2025 New Relic, Inc. All rights reserved.
21
22
  * SPDX-License-Identifier: Apache-2.0
@@ -43,8 +44,7 @@ class Aggregate extends _aggregateBase.AggregateBase {
43
44
  });
44
45
  }, this.featureName, this.ee);
45
46
  if (agentRef.init.page_action.enabled) {
46
- (0, _registerHandler.registerHandler)('api-addPageAction', (timestamp, name, attributes, targetEntityGuid) => {
47
- if (!this.agentRef.runtime.entityManager.get(targetEntityGuid)) return (0, _console.warn)(56, this.featureName);
47
+ (0, _registerHandler.registerHandler)('api-addPageAction', (timestamp, name, attributes, target) => {
48
48
  this.addEvent({
49
49
  ...attributes,
50
50
  eventType: 'PageAction',
@@ -56,7 +56,7 @@ class Aggregate extends _aggregateBase.AggregateBase {
56
56
  browserWidth: window.document.documentElement?.clientWidth,
57
57
  browserHeight: window.document.documentElement?.clientHeight
58
58
  })
59
- }, targetEntityGuid);
59
+ }, target);
60
60
  }, this.featureName, this.ee);
61
61
  }
62
62
  let addUserAction = () => {/** no-op */};
@@ -254,7 +254,6 @@ class Aggregate extends _aggregateBase.AggregateBase {
254
254
  };
255
255
  this.addEvent(event);
256
256
  }, this.featureName, this.ee);
257
- agentRef.runtime.harvester.triggerHarvestFor(this);
258
257
  this.drain();
259
258
  });
260
259
  }
@@ -270,10 +269,10 @@ class Aggregate extends _aggregateBase.AggregateBase {
270
269
  * * sessionTraceId: set by the `ptid=` query param
271
270
  * * userAgent*: set by the userAgent header
272
271
  * @param {object=} obj the event object for storing in the event buffer
273
- * @param {string=} targetEntityGuid the target entity guid for the event to scope buffering and harvesting. Defaults to agent config if undefined
272
+ * @param {string=} target the target metadata for the event to scope buffering and harvesting. Defaults to container agent config if undefined
274
273
  * @returns void
275
274
  */
276
- addEvent(obj = {}, targetEntityGuid) {
275
+ addEvent(obj = {}, target) {
277
276
  if (!obj || !Object.keys(obj).length) return;
278
277
  if (!obj.eventType) {
279
278
  (0, _console.warn)(44);
@@ -288,7 +287,9 @@ class Aggregate extends _aggregateBase.AggregateBase {
288
287
  timestamp: Math.floor(this.agentRef.runtime.timeKeeper.correctRelativeTimestamp((0, _now.now)())),
289
288
  /** all generic events require pageUrl(s) */
290
289
  pageUrl: (0, _cleanUrl.cleanURL)('' + _runtime.initialLocation),
291
- currentUrl: (0, _cleanUrl.cleanURL)('' + location)
290
+ currentUrl: (0, _cleanUrl.cleanURL)('' + location),
291
+ /** Specific attributes only supplied if harvesting to endpoint version 2 */
292
+ ...(0, _mfe.getVersion2Attributes)(target, this)
292
293
  };
293
294
  const eventAttributes = {
294
295
  /** Agent-level custom attributes */
@@ -298,7 +299,7 @@ class Aggregate extends _aggregateBase.AggregateBase {
298
299
  /** Event-specific attributes take precedence over agent-level custom attributes and fallbacks */
299
300
  ...obj
300
301
  };
301
- this.events.add(eventAttributes, targetEntityGuid);
302
+ this.events.add(eventAttributes);
302
303
  }
303
304
  serializer(eventBuffer) {
304
305
  return (0, _traverse.applyFnToProps)({
@@ -18,5 +18,7 @@ const RAGE_CLICK_THRESHOLD_MS = exports.RAGE_CLICK_THRESHOLD_MS = 1000;
18
18
  const FRUSTRATION_TIMEOUT_MS = exports.FRUSTRATION_TIMEOUT_MS = 2000;
19
19
  const RESERVED_EVENT_TYPES = exports.RESERVED_EVENT_TYPES = ['PageAction', 'UserAction', 'BrowserPerformance'];
20
20
  const FEATURE_FLAGS = exports.FEATURE_FLAGS = {
21
- RESOURCES: 'experimental.resources'
21
+ RESOURCES: 'experimental.resources',
22
+ REGISTER: 'register'
23
+ // register.jserrors and register.generic_events are also used, but not referenced directly so no need to represent here
22
24
  };
@@ -18,8 +18,7 @@ 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 _target = require("../../../common/util/target");
22
- var _console = require("../../../common/util/console");
21
+ var _mfe = require("../../../common/util/mfe");
23
22
  var _causeString = require("./cause-string");
24
23
  /**
25
24
  * Copyright 2020-2025 New Relic, Inc. All rights reserved.
@@ -34,6 +33,9 @@ class Aggregate extends _aggregateBase.AggregateBase {
34
33
  static featureName = _constants.FEATURE_NAME;
35
34
  constructor(agentRef) {
36
35
  super(agentRef, _constants.FEATURE_NAME);
36
+
37
+ /** set up agg-level behaviors specific to this feature */
38
+ this.harvestOpts.aggregatorTypes = ['err', 'ierr', 'xhr']; // the types in EventAggregator this feature cares about
37
39
  this.stackReported = {};
38
40
  this.observedAt = {};
39
41
  this.pageviewReported = {};
@@ -46,8 +48,6 @@ class Aggregate extends _aggregateBase.AggregateBase {
46
48
  (0, _registerHandler.registerHandler)('ierr', (...args) => this.storeError(...args), this.featureName, this.ee);
47
49
  (0, _registerHandler.registerHandler)('softNavFlush', (interactionId, wasFinished, softNavAttrs, interactionEndTime) => this.onSoftNavNotification(interactionId, wasFinished, softNavAttrs, interactionEndTime), this.featureName, this.ee); // when an ixn is done or cancelled
48
50
 
49
- this.harvestOpts.aggregatorTypes = ['err', 'ierr', 'xhr']; // the types in EventAggregator this feature cares about
50
-
51
51
  // 0 == off, 1 == on
52
52
  this.waitForFlags(['err']).then(([errFlag]) => {
53
53
  if (errFlag) {
@@ -107,10 +107,8 @@ class Aggregate extends _aggregateBase.AggregateBase {
107
107
  * @param {object=} target the target to buffer and harvest to, if undefined the default configuration target is used
108
108
  * @returns
109
109
  */
110
- storeError(err, time, internal, customAttributes, hasReplay, swallowReason, targetEntityGuid) {
110
+ storeError(err, time, internal, customAttributes, hasReplay, swallowReason, target) {
111
111
  if (!err) return;
112
- const target = this.agentRef.runtime.entityManager.get(targetEntityGuid);
113
- if (!target) return (0, _console.warn)(56, this.featureName);
114
112
  // are we in an interaction
115
113
  time = time || (0, _now.now)();
116
114
  let filterOutput;
@@ -148,7 +146,7 @@ class Aggregate extends _aggregateBase.AggregateBase {
148
146
  if (filterOutput?.group) params.errorGroup = filterOutput.group;
149
147
 
150
148
  // Should only decorate "hasReplay" for the container agent, so check if the target matches the config
151
- if (hasReplay && (0, _target.isContainerAgentTarget)(target, this.agentRef)) params.hasReplay = hasReplay;
149
+ if (hasReplay && !target) params.hasReplay = hasReplay;
152
150
  /**
153
151
  * The bucketHash is different from the params.stackHash because the params.stackHash is based on the canonicalized
154
152
  * stack trace and is used downstream in NR1 to attempt to group the same errors across different browsers. However,
@@ -183,14 +181,14 @@ class Aggregate extends _aggregateBase.AggregateBase {
183
181
 
184
182
  // Trace sends the error in its payload, and both trace & replay simply listens for any error to occur.
185
183
  const jsErrorEvent = [type, bucketHash, params, newMetrics, customAttributes];
186
- if (this.shouldAllowMainAgentToCapture(targetEntityGuid)) (0, _handle.handle)('trace-jserror', jsErrorEvent, undefined, _features.FEATURE_NAMES.sessionTrace, this.ee);
184
+ if (this.shouldAllowMainAgentToCapture(target)) (0, _handle.handle)('trace-jserror', jsErrorEvent, undefined, _features.FEATURE_NAMES.sessionTrace, this.ee);
187
185
  // still send EE events for other features such as above, but stop this one from aggregating internal data
188
186
  if (this.blocked) return;
189
187
  if (err?.__newrelic?.[this.agentIdentifier]) {
190
188
  params._interactionId = err.__newrelic[this.agentIdentifier].interactionId;
191
189
  params._interactionNodeId = err.__newrelic[this.agentIdentifier].interactionNodeId;
192
190
  }
193
- if (this.shouldAllowMainAgentToCapture(targetEntityGuid)) {
191
+ if (this.shouldAllowMainAgentToCapture(target)) {
194
192
  const softNavInUse = Boolean(this.agentRef.features?.[_features.FEATURE_NAMES.softNav]);
195
193
  // Note: the following are subject to potential race cond wherein if the other feature aren't fully initialized, it'll be treated as there being no associated interaction.
196
194
  // They each will also tack on their respective properties to the params object as part of the decision flow.
@@ -211,11 +209,14 @@ class Aggregate extends _aggregateBase.AggregateBase {
211
209
  }
212
210
 
213
211
  // always add directly if scoped to a sub-entity, the other pathways above will be deterministic if the main agent should procede
214
- if (targetEntityGuid) this.#storeJserrorForHarvest([...jsErrorEvent, targetEntityGuid], false, params._softNavAttributes);
212
+ if (target) this.#storeJserrorForHarvest([...jsErrorEvent, target], false, params._softNavAttributes);
215
213
  }
216
214
  #storeJserrorForHarvest(errorInfoArr, softNavOccurredFinished, softNavCustomAttrs = {}) {
217
- let [type, bucketHash, params, newMetrics, localAttrs, targetEntityGuid] = errorInfoArr;
218
- const allCustomAttrs = {};
215
+ let [type, bucketHash, params, newMetrics, localAttrs, target] = errorInfoArr;
216
+ const allCustomAttrs = {
217
+ /** MFE specific attributes if in "multiple" mode (ie consumer version 2) */
218
+ ...(0, _mfe.getVersion2Attributes)(target, this)
219
+ };
219
220
  if (softNavOccurredFinished) {
220
221
  Object.entries(softNavCustomAttrs).forEach(([k, v]) => setCustom(k, v)); // when an ixn finishes, it'll include stuff in jsAttributes + attrs specific to the ixn
221
222
  bucketHash += params.browserInteractionId;
@@ -230,7 +231,7 @@ class Aggregate extends _aggregateBase.AggregateBase {
230
231
 
231
232
  const jsAttributesHash = (0, _stringHashCode.stringHashCode)((0, _stringify.stringify)(allCustomAttrs));
232
233
  const aggregateHash = bucketHash + ':' + jsAttributesHash;
233
- this.events.add([type, aggregateHash, params, newMetrics, allCustomAttrs], targetEntityGuid);
234
+ this.events.add([type, aggregateHash, params, newMetrics, allCustomAttrs]);
234
235
  function setCustom(key, val) {
235
236
  allCustomAttrs[key] = val && typeof val === 'object' ? (0, _stringify.stringify)(val) : val;
236
237
  }
@@ -239,11 +240,11 @@ class Aggregate extends _aggregateBase.AggregateBase {
239
240
  /**
240
241
  * 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
241
242
  * the main agent should not capture events unless it is configured to do so.
242
- * @param {string} entityGuid - the context object for the event
243
+ * @param {string} target - the context object for the event
243
244
  * @returns {boolean} - whether the main agent should capture the event to its internal target
244
245
  */
245
- shouldAllowMainAgentToCapture(entityGuid) {
246
- return !entityGuid || this.agentRef.init.api.duplicate_registered_data;
246
+ shouldAllowMainAgentToCapture(target) {
247
+ return !target || this.agentRef.init.api.duplicate_registered_data;
247
248
  }
248
249
 
249
250
  // TO-DO: Remove this function when old spa is taken out. #storeJserrorForHarvest handles the work with the softnav feature.
@@ -12,10 +12,10 @@ var _constants = require("../constants");
12
12
  var _log = require("../shared/log");
13
13
  var _utils = require("../shared/utils");
14
14
  var _traverse = require("../../../common/util/traverse");
15
- var _target = require("../../../common/util/target");
16
15
  var _constants2 = require("../../../common/session/constants");
17
16
  var _constants3 = require("../../session_replay/constants");
18
17
  var _featureGates = require("../../utils/feature-gates");
18
+ var _mfe = require("../../../common/util/mfe");
19
19
  /**
20
20
  * Copyright 2020-2025 New Relic, Inc. All rights reserved.
21
21
  * SPDX-License-Identifier: Apache-2.0
@@ -26,6 +26,9 @@ class Aggregate extends _aggregateBase.AggregateBase {
26
26
  constructor(agentRef) {
27
27
  super(agentRef, _constants.FEATURE_NAME);
28
28
  this.isSessionTrackingEnabled = (0, _featureGates.canEnableSessionTracking)(agentRef.init) && agentRef.runtime.session;
29
+
30
+ /** set up agg-level behaviors specific to this feature */
31
+ this.harvestOpts.raw = true;
29
32
  super.customAttributesAreSeparate = true;
30
33
 
31
34
  // The SessionEntity class can emit a message indicating the session was cleared and reset (expiry, inactivity). This feature must abort and never resume if that occurs.
@@ -36,7 +39,6 @@ class Aggregate extends _aggregateBase.AggregateBase {
36
39
  if (this.blocked || type !== _constants2.SESSION_EVENT_TYPES.CROSS_TAB) return;
37
40
  if (this.loggingMode !== _constants.LOGGING_MODE.OFF && data.loggingMode === _constants.LOGGING_MODE.OFF) this.abort(_constants3.ABORT_REASONS.CROSS_TAB);else this.loggingMode = data.loggingMode;
38
41
  });
39
- this.harvestOpts.raw = true;
40
42
  this.waitForFlags(['log']).then(([loggingMode]) => {
41
43
  const session = this.agentRef.runtime.session ?? {};
42
44
  if (this.loggingMode === _constants.LOGGING_MODE.OFF || session.isNew && loggingMode === _constants.LOGGING_MODE.OFF) {
@@ -63,10 +65,14 @@ class Aggregate extends _aggregateBase.AggregateBase {
63
65
  loggingMode: this.loggingMode
64
66
  });
65
67
  }
66
- handleLog(timestamp, message, attributes = {}, level = _constants.LOG_LEVELS.INFO, targetEntityGuid) {
67
- if (!this.agentRef.runtime.entityManager.get(targetEntityGuid)) return (0, _console.warn)(56, this.featureName);
68
+ handleLog(timestamp, message, attributes = {}, level = _constants.LOG_LEVELS.INFO, target) {
68
69
  if (this.blocked || !this.loggingMode) return;
69
70
  if (!attributes || typeof attributes !== 'object') attributes = {};
71
+ attributes = {
72
+ ...attributes,
73
+ /** Specific attributes only supplied if harvesting to endpoint version 2 */
74
+ ...(0, _mfe.getVersion2Attributes)(target, this)
75
+ };
70
76
  if (typeof level === 'string') level = level.toUpperCase();
71
77
  if (!(0, _utils.isValidLogLevel)(level)) return (0, _console.warn)(30, level);
72
78
  if (this.loggingMode < (_constants.LOGGING_MODE[level] || Infinity)) {
@@ -90,10 +96,9 @@ class Aggregate extends _aggregateBase.AggregateBase {
90
96
  }
91
97
  if (typeof message !== 'string' || !message) return (0, _console.warn)(32);
92
98
  const log = new _log.Log(Math.floor(this.agentRef.runtime.timeKeeper.correctRelativeTimestamp(timestamp)), message, attributes, level);
93
- this.events.add(log, targetEntityGuid);
99
+ this.events.add(log);
94
100
  }
95
- serializer(eventBuffer, targetEntityGuid) {
96
- const target = this.agentRef.runtime.entityManager.get(targetEntityGuid);
101
+ serializer(eventBuffer) {
97
102
  const sessionEntity = this.agentRef.runtime.session;
98
103
  return [{
99
104
  common: {
@@ -101,19 +106,19 @@ class Aggregate extends _aggregateBase.AggregateBase {
101
106
  attributes: {
102
107
  ...this.agentRef.info.jsAttributes,
103
108
  // user-provided custom attributes
104
- 'entity.guid': target.entityGuid,
105
- // browser entity guid as provided API target OR the default from RUM response if not supplied
109
+ ...(this.harvestEndpointVersion === 1 && {
110
+ 'entity.guid': this.agentRef.runtime.appMetadata.agents[0].entityGuid,
111
+ appId: this.agentRef.info.applicationID
112
+ }),
106
113
  ...(sessionEntity && {
107
114
  session: sessionEntity.state.value || '0',
108
115
  // The session ID that we generate and keep across page loads
109
- hasReplay: sessionEntity.state.sessionReplayMode === 1 && (0, _target.isContainerAgentTarget)(target, this.agentRef),
116
+ hasReplay: sessionEntity.state.sessionReplayMode === 1,
110
117
  // True if a session replay recording is running
111
118
  hasTrace: sessionEntity.state.sessionTraceMode === 1 // True if a session trace recording is running
112
119
  }),
113
120
  ptid: this.agentRef.runtime.ptid,
114
121
  // page trace id
115
- appId: target.applicationID || this.agentRef.info.applicationID,
116
- // Application ID from info object,
117
122
  standalone: Boolean(this.agentRef.info.sa),
118
123
  // copy paste (true) vs APM (false)
119
124
  agentVersion: this.agentRef.runtime.version,
@@ -128,10 +133,9 @@ class Aggregate extends _aggregateBase.AggregateBase {
128
133
  logs: (0, _traverse.applyFnToProps)(eventBuffer, this.obfuscator.obfuscateString.bind(this.obfuscator), 'string')
129
134
  }];
130
135
  }
131
- queryStringsBuilder(_, targetEntityGuid) {
132
- const target = this.agentRef.runtime.entityManager.get(targetEntityGuid);
136
+ queryStringsBuilder() {
133
137
  return {
134
- browser_monitoring_key: target.licenseKey
138
+ browser_monitoring_key: this.agentRef.info.licenseKey
135
139
  };
136
140
  }
137
141
 
@@ -20,11 +20,11 @@ var _constants2 = require("../constants");
20
20
  * @param {string} message - the log message string
21
21
  * @param {{[key: string]: *}} customAttributes - The log's custom attributes if any
22
22
  * @param {enum} level - the log level enum
23
- * @param {object=} targetEntityGuid - the optional target entity guid provided by an api call
23
+ * @param {object=} target - the optional target provided by an api call
24
24
  */
25
- function bufferLog(ee, message, customAttributes = {}, level = _constants2.LOG_LEVELS.INFO, targetEntityGuid, timestamp = (0, _now.now)()) {
25
+ function bufferLog(ee, message, customAttributes = {}, level = _constants2.LOG_LEVELS.INFO, target, timestamp = (0, _now.now)()) {
26
26
  (0, _handle.handle)(_constants.SUPPORTABILITY_METRIC_CHANNEL, ["API/logging/".concat(level.toLowerCase(), "/called")], undefined, _features.FEATURE_NAMES.metrics, ee);
27
- (0, _handle.handle)(_constants2.LOGGING_EVENT_EMITTER_CHANNEL, [timestamp, message, customAttributes, level, targetEntityGuid], undefined, _features.FEATURE_NAMES.logging, ee);
27
+ (0, _handle.handle)(_constants2.LOGGING_EVENT_EMITTER_CHANNEL, [timestamp, message, customAttributes, level, target], undefined, _features.FEATURE_NAMES.logging, ee);
28
28
  }
29
29
 
30
30
  /**