@newrelic/browser-agent 1.320.1-rc.1 → 1.320.1-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.
- package/dist/cjs/common/config/runtime.js +2 -0
- package/dist/cjs/common/constants/env.cdn.js +1 -1
- package/dist/cjs/common/constants/env.npm.js +1 -1
- package/dist/cjs/common/dom/selector-path.js +1 -1
- package/dist/cjs/common/session/session-entity.js +1 -1
- package/dist/cjs/common/v2/constants.js +21 -0
- package/dist/cjs/common/v2/utils.js +25 -23
- package/dist/cjs/common/wrap/wrap-events.js +4 -3
- package/dist/cjs/common/wrap/wrap-fetch.js +2 -2
- package/dist/cjs/common/wrap/wrap-function.js +1 -1
- package/dist/cjs/common/wrap/wrap-history.js +3 -2
- package/dist/cjs/common/wrap/wrap-xhr.js +2 -2
- package/dist/cjs/features/ajax/aggregate/index.js +1 -1
- package/dist/cjs/features/generic_events/aggregate/index.js +1 -1
- package/dist/cjs/features/generic_events/instrument/index.js +1 -1
- package/dist/cjs/features/jserrors/aggregate/index.js +5 -5
- package/dist/cjs/features/logging/instrument/index.js +1 -1
- package/dist/cjs/features/session_trace/instrument/index.js +3 -3
- package/dist/cjs/features/soft_navigations/instrument/index.js +2 -2
- package/dist/cjs/loaders/api/register.js +8 -8
- package/dist/cjs/loaders/configure/configure.js +14 -0
- package/dist/esm/common/config/runtime.js +2 -0
- package/dist/esm/common/constants/env.cdn.js +1 -1
- package/dist/esm/common/constants/env.npm.js +1 -1
- package/dist/esm/common/dom/selector-path.js +1 -1
- package/dist/esm/common/session/session-entity.js +1 -1
- package/dist/esm/common/v2/constants.js +15 -0
- package/dist/esm/common/v2/utils.js +24 -22
- package/dist/esm/common/wrap/wrap-events.js +4 -3
- package/dist/esm/common/wrap/wrap-fetch.js +2 -2
- package/dist/esm/common/wrap/wrap-function.js +1 -1
- package/dist/esm/common/wrap/wrap-history.js +3 -2
- package/dist/esm/common/wrap/wrap-xhr.js +2 -2
- package/dist/esm/features/ajax/aggregate/index.js +2 -2
- package/dist/esm/features/generic_events/aggregate/index.js +1 -1
- package/dist/esm/features/generic_events/instrument/index.js +1 -1
- package/dist/esm/features/jserrors/aggregate/index.js +6 -6
- package/dist/esm/features/logging/instrument/index.js +1 -1
- package/dist/esm/features/session_trace/instrument/index.js +3 -3
- package/dist/esm/features/soft_navigations/instrument/index.js +2 -2
- package/dist/esm/loaders/api/register.js +1 -1
- package/dist/esm/loaders/configure/configure.js +14 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/common/config/runtime.d.ts.map +1 -1
- package/dist/types/common/v2/constants.d.ts +9 -0
- package/dist/types/common/v2/constants.d.ts.map +1 -0
- package/dist/types/common/v2/utils.d.ts +36 -11
- package/dist/types/common/v2/utils.d.ts.map +1 -1
- package/dist/types/common/wrap/wrap-events.d.ts +2 -1
- package/dist/types/common/wrap/wrap-events.d.ts.map +1 -1
- package/dist/types/common/wrap/wrap-history.d.ts +2 -1
- package/dist/types/common/wrap/wrap-history.d.ts.map +1 -1
- package/dist/types/features/session_trace/instrument/index.d.ts.map +1 -1
- package/dist/types/loaders/configure/configure.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/common/config/runtime.js +2 -0
- package/src/common/dom/selector-path.js +1 -1
- package/src/common/session/session-entity.js +1 -1
- package/src/common/v2/constants.js +15 -0
- package/src/common/v2/utils.js +23 -21
- package/src/common/wrap/wrap-events.js +4 -3
- package/src/common/wrap/wrap-fetch.js +2 -2
- package/src/common/wrap/wrap-function.js +1 -1
- package/src/common/wrap/wrap-history.js +3 -2
- package/src/common/wrap/wrap-xhr.js +2 -2
- package/src/features/ajax/aggregate/index.js +2 -2
- package/src/features/generic_events/aggregate/index.js +1 -1
- package/src/features/generic_events/instrument/index.js +1 -1
- package/src/features/jserrors/aggregate/index.js +6 -6
- package/src/features/logging/instrument/index.js +1 -1
- package/src/features/session_trace/instrument/index.js +3 -3
- package/src/features/soft_navigations/instrument/index.js +2 -2
- package/src/loaders/api/register.js +1 -1
- package/src/loaders/configure/configure.js +12 -0
|
@@ -46,6 +46,8 @@ const RuntimeModel = {
|
|
|
46
46
|
drainRegistry: new Map(),
|
|
47
47
|
connector: undefined,
|
|
48
48
|
harvester: undefined,
|
|
49
|
+
/** eagerly-created in configure() -- the v2 target representing the container (main) agent, see common/v2/utils#V2Target */
|
|
50
|
+
v2Target: undefined,
|
|
49
51
|
isolatedBacklog: false,
|
|
50
52
|
isRecording: false,
|
|
51
53
|
// true when actively recording, false when paused or stopped
|
|
@@ -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.320.1-rc.
|
|
20
|
+
const VERSION = exports.VERSION = "1.320.1-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.320.1-rc.
|
|
20
|
+
const VERSION = exports.VERSION = "1.320.1-rc.2";
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
23
|
* Exposes the build type of the agent
|
|
@@ -27,7 +27,7 @@ const analyzeElemPath = (elem, targetFields = [], agentRef) => {
|
|
|
27
27
|
path: undefined,
|
|
28
28
|
nearestFields: {},
|
|
29
29
|
get targets() {
|
|
30
|
-
return targets.length ? targets : [
|
|
30
|
+
return targets.length ? targets : [agentRef.runtime.v2Target];
|
|
31
31
|
},
|
|
32
32
|
hasButton: false,
|
|
33
33
|
hasLink: false
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.V2_TYPES = void 0;
|
|
7
|
+
/**
|
|
8
|
+
* Copyright 2020-2026 New Relic, Inc. All rights reserved.
|
|
9
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @enum {string}
|
|
14
|
+
* @readonly
|
|
15
|
+
*/
|
|
16
|
+
const V2_TYPES = exports.V2_TYPES = {
|
|
17
|
+
/** Micro Frontend */
|
|
18
|
+
MFE: 'MFE',
|
|
19
|
+
/** Browser Application */
|
|
20
|
+
BA: 'BA'
|
|
21
|
+
};
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.V2_TYPES = void 0;
|
|
7
6
|
exports.dedupeRegisteredEntitiesByAsset = dedupeRegisteredEntitiesByAsset;
|
|
8
7
|
exports.dedupeTargetsByInstance = dedupeTargetsByInstance;
|
|
9
8
|
exports.findTargetsFromStackTrace = findTargetsFromStackTrace;
|
|
@@ -12,23 +11,31 @@ exports.getRegisteredTargetsFromFilename = getRegisteredTargetsFromFilename;
|
|
|
12
11
|
exports.getRegisteredTargetsFromId = getRegisteredTargetsFromId;
|
|
13
12
|
exports.getVersion2Attributes = getVersion2Attributes;
|
|
14
13
|
exports.getVersion2DuplicationAttributes = getVersion2DuplicationAttributes;
|
|
14
|
+
exports.isMfeTarget = isMfeTarget;
|
|
15
15
|
exports.shouldDuplicate = shouldDuplicate;
|
|
16
16
|
var _scriptTracker = require("./script-tracker");
|
|
17
|
+
var _constants = require("./constants");
|
|
17
18
|
/**
|
|
18
19
|
* Copyright 2020-2026 New Relic, Inc. All rights reserved.
|
|
19
20
|
* SPDX-License-Identifier: Apache-2.0
|
|
20
21
|
*/
|
|
21
22
|
|
|
22
23
|
/**
|
|
23
|
-
* @
|
|
24
|
-
* @
|
|
24
|
+
* @typedef {Object} V2Target
|
|
25
|
+
* @property {'BA'} type always V2_TYPES.BA -- identifies this as the container (main) agent, not a registered MFE
|
|
26
|
+
* @property {string} instance the container agent's agentIdentifier
|
|
27
|
+
* @property {string} [id] the container agent's entity guid, once known (getter, resolved asynchronously)
|
|
28
|
+
* @property {{[key:string]: any}} attributes the V2 payload attributes for the container agent (getter)
|
|
25
29
|
*/
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Determines if a given target represents a registered MFE (as opposed to the container agent).
|
|
33
|
+
* @param {*} target the target to check
|
|
34
|
+
* @returns {boolean} true if the target is a registered MFE target
|
|
35
|
+
*/
|
|
36
|
+
function isMfeTarget(target) {
|
|
37
|
+
return target?.type === _constants.V2_TYPES.MFE;
|
|
38
|
+
}
|
|
32
39
|
|
|
33
40
|
/**
|
|
34
41
|
* Returns a single registered entity associated with a given iframe interface ID. Returns undefined if no entity is found.
|
|
@@ -124,14 +131,8 @@ function dedupeRegisteredEntitiesByAsset(entities) {
|
|
|
124
131
|
*/
|
|
125
132
|
function getVersion2Attributes(target, aggregateInstance) {
|
|
126
133
|
if (!supportsV2(aggregateInstance)) return {};
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
if (!target) {
|
|
130
|
-
return {
|
|
131
|
-
'entity.guid': containerAgentEntityGuid,
|
|
132
|
-
appId: aggregateInstance.agentRef.info.applicationID
|
|
133
|
-
};
|
|
134
|
-
}
|
|
134
|
+
/** if the target isn't a registered MFE, but we are in v2 mode, this means the data belongs to the container agent */
|
|
135
|
+
if (!isMfeTarget(target)) return aggregateInstance.agentRef.runtime.v2Target.attributes;
|
|
135
136
|
/** otherwise, the data belongs to the target (MFE) and should be attributed as such */
|
|
136
137
|
return target.attributes;
|
|
137
138
|
}
|
|
@@ -161,16 +162,17 @@ function getVersion2DuplicationAttributes(target, aggregateInstance) {
|
|
|
161
162
|
* @returns {boolean} returns true if the event should be duplicated for the target, false otherwise
|
|
162
163
|
*/
|
|
163
164
|
function shouldDuplicate(target, aggregateInstance) {
|
|
164
|
-
return
|
|
165
|
+
return isMfeTarget(target) && !!supportsV2(aggregateInstance) && aggregateInstance.agentRef.init.api.register.duplicate_data_to_container;
|
|
165
166
|
}
|
|
166
167
|
|
|
167
168
|
/**
|
|
168
169
|
* Finds the registered targets from the stack trace for a given agent reference.
|
|
169
170
|
* @param {*} agentRef The agent reference to use for finding targets.
|
|
170
|
-
* @returns {Array} An array of targets found from the stack trace. If no targets are found or allowed, returns an array
|
|
171
|
+
* @returns {Array} An array of targets found from the stack trace. If no targets are found or allowed, returns an array containing the container target.
|
|
171
172
|
*/
|
|
172
173
|
function findTargetsFromStackTrace(agentRef) {
|
|
173
|
-
if (!
|
|
174
|
+
if (!agentRef?.runtime) return [];
|
|
175
|
+
if (!isValid(true, agentRef) || !agentRef.runtime.registeredEntities?.length) return [agentRef.runtime.v2Target];
|
|
174
176
|
const targets = [];
|
|
175
177
|
try {
|
|
176
178
|
var urls = (0, _scriptTracker.extractUrlsFromStack)((0, _scriptTracker.getDeepStackTrace)());
|
|
@@ -182,15 +184,15 @@ function findTargetsFromStackTrace(agentRef) {
|
|
|
182
184
|
// Silent catch to prevent errors from propagating
|
|
183
185
|
}
|
|
184
186
|
const deduped = dedupeTargetsByInstance(targets);
|
|
185
|
-
if (!deduped.length) deduped.push(
|
|
187
|
+
if (!deduped.length) deduped.push(agentRef.runtime.v2Target); // if we can't find any targets from the stack trace, the container agent is the target
|
|
186
188
|
return deduped;
|
|
187
189
|
}
|
|
188
190
|
|
|
189
191
|
/**
|
|
190
192
|
* Removes duplicate targets from an array, keyed by `target.instance`. This guards against the same canonical
|
|
191
193
|
* target re-entering the array via multiple matched stack-frame URLs (e.g. a recursive call whose stack contains the
|
|
192
|
-
* same file at multiple depths).
|
|
193
|
-
* naturally collapse to a single entry too, which is the desired behavior.
|
|
194
|
+
* same file at multiple depths). Multiple container-target entries (whose `instance` is the container agent's stable
|
|
195
|
+
* `agentIdentifier`) naturally collapse to a single entry too, which is the desired behavior.
|
|
194
196
|
* @param {Array} targets
|
|
195
197
|
* @returns {Array} deduped list of targets, preserving relative order of first occurrence
|
|
196
198
|
*/
|
|
@@ -10,7 +10,7 @@ var _wrapFunction = require("./wrap-function");
|
|
|
10
10
|
var _getOrSet = require("../util/get-or-set");
|
|
11
11
|
var _runtime = require("../constants/runtime");
|
|
12
12
|
/**
|
|
13
|
-
* Copyright 2020-
|
|
13
|
+
* Copyright 2020-2026 New Relic, Inc. All rights reserved.
|
|
14
14
|
* SPDX-License-Identifier: Apache-2.0
|
|
15
15
|
*/
|
|
16
16
|
|
|
@@ -31,16 +31,17 @@ const flag = "nr@wrapped:".concat(_contextualEe.contextId);
|
|
|
31
31
|
* `document` (if in a browser scope). Adds custom events in context of a new emitter scoped only to these methods.
|
|
32
32
|
* @param {Object} sharedEE - The shared event emitter on which a new scoped
|
|
33
33
|
* event emitter will be based.
|
|
34
|
+
* @param {*} [agentRef] - The agent reference, used to attribute wrapped calls to the correct v2 target.
|
|
34
35
|
* @returns {Object} Scoped event emitter with a debug ID of `events`.
|
|
35
36
|
*/
|
|
36
|
-
function wrapEvents(sharedEE) {
|
|
37
|
+
function wrapEvents(sharedEE, agentRef) {
|
|
37
38
|
var ee = scopedEE(sharedEE);
|
|
38
39
|
|
|
39
40
|
// Notice if our wrapping never ran yet, the falsy NaN will not early return; but if it has,
|
|
40
41
|
// then we increment the count to track # of feats using this at runtime.
|
|
41
42
|
if (wrapped[ee.debugId]++) return ee;
|
|
42
43
|
wrapped[ee.debugId] = 1; // otherwise, first feature to wrap events
|
|
43
|
-
var wrapFn = (0, _wrapFunction.createWrapperWithEmitter)(ee, true);
|
|
44
|
+
var wrapFn = (0, _wrapFunction.createWrapperWithEmitter)(ee, true, agentRef);
|
|
44
45
|
|
|
45
46
|
// Guard against instrumenting environments w/o necessary features
|
|
46
47
|
if ('getPrototypeOf' in Object) {
|
|
@@ -52,8 +52,8 @@ function wrapFetch(sharedEE, agentRef) {
|
|
|
52
52
|
wrapPromiseMethod(_runtime.globalScope, 'fetch', prefix);
|
|
53
53
|
ee.on(prefix + 'end', function (err, res, targets) {
|
|
54
54
|
var ctx = this;
|
|
55
|
-
//
|
|
56
|
-
ctx.targets = targets || [
|
|
55
|
+
// default target reports to container
|
|
56
|
+
ctx.targets = targets || [agentRef.runtime.v2Target];
|
|
57
57
|
if (res) {
|
|
58
58
|
var size = res.headers.get('content-length');
|
|
59
59
|
if (size !== null) {
|
|
@@ -89,7 +89,7 @@ function createWrapperWithEmitter(emitter, always, agentRef) {
|
|
|
89
89
|
|
|
90
90
|
// certain wrappers can inform the function wrapper to evaluate the stack of the executed wrapped function to find targets of the execution
|
|
91
91
|
// (e.g. wrap-logger can inform this method to find try to find the MFE source of a console.log)
|
|
92
|
-
targets = evaluateStack ? (0, _utils.findTargetsFromStackTrace)(agentRef) : [
|
|
92
|
+
targets = evaluateStack ? (0, _utils.findTargetsFromStackTrace)(agentRef) : [agentRef?.runtime?.v2Target]; // default target always maps to the container agent
|
|
93
93
|
|
|
94
94
|
if (typeof getContext === 'function') {
|
|
95
95
|
ctx = getContext(args, originalThis);
|
|
@@ -25,9 +25,10 @@ const HISTORY_FNS = ['pushState', 'replaceState'];
|
|
|
25
25
|
* Wraps the `pushState` and `replaceState` methods of `window.history` and returns a corresponding event emitter
|
|
26
26
|
* scoped to the history object.
|
|
27
27
|
* @param {Object} sharedEE - The shared event emitter on which a new scoped event emitter will be based.
|
|
28
|
+
* @param {*} [agentRef] - The agent reference, used to attribute wrapped calls to the correct v2 target.
|
|
28
29
|
* @returns {Object} Scoped event emitter with a debug ID of `history`.
|
|
29
30
|
*/
|
|
30
|
-
function wrapHistory(sharedEE) {
|
|
31
|
+
function wrapHistory(sharedEE, agentRef) {
|
|
31
32
|
const ee = scopedEE(sharedEE);
|
|
32
33
|
|
|
33
34
|
// Notice if our wrapping never ran yet, the falsy NaN will not early return; but if it has,
|
|
@@ -36,7 +37,7 @@ function wrapHistory(sharedEE) {
|
|
|
36
37
|
if (!_runtime.isBrowserScope || wrapped[ee.debugId]++) return ee;
|
|
37
38
|
wrapped[ee.debugId] = 1; // otherwise, first feature to wrap history
|
|
38
39
|
|
|
39
|
-
var wrapFn = (0, _wrapFunction.createWrapperWithEmitter)(ee);
|
|
40
|
+
var wrapFn = (0, _wrapFunction.createWrapperWithEmitter)(ee, undefined, agentRef);
|
|
40
41
|
/*
|
|
41
42
|
* For objects that will be instantiated more than once, we wrap the object's prototype methods. The history object
|
|
42
43
|
* is instantiated only once, so we can wrap its methods directly--and we must wrap the history methods directly as
|
|
@@ -42,8 +42,8 @@ function wrapXhr(sharedEE, agentRef) {
|
|
|
42
42
|
if (wrapped[ee.debugId]++) return ee;
|
|
43
43
|
wrapped[ee.debugId] = 1; // otherwise, first feature to wrap XHR
|
|
44
44
|
|
|
45
|
-
(0, _wrapEvents.wrapEvents)(baseEE); // wrap-events patches XMLHttpRequest.prototype.addEventListener for us
|
|
46
|
-
var wrapFn = (0, _wrapFunction.createWrapperWithEmitter)(ee);
|
|
45
|
+
(0, _wrapEvents.wrapEvents)(baseEE, agentRef); // wrap-events patches XMLHttpRequest.prototype.addEventListener for us
|
|
46
|
+
var wrapFn = (0, _wrapFunction.createWrapperWithEmitter)(ee, undefined, agentRef);
|
|
47
47
|
var OrigXHR = _runtime.globalScope.XMLHttpRequest;
|
|
48
48
|
var MutationObserver = _runtime.globalScope.MutationObserver;
|
|
49
49
|
var Promise = _runtime.globalScope.Promise;
|
|
@@ -126,7 +126,7 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
126
126
|
if (event.gql) this.reportSupportabilityMetric('Ajax/Events/GraphQL/Bytes-Added', (0, _stringify.stringify)(event.gql).length);
|
|
127
127
|
|
|
128
128
|
/** make a copy of the event for the MFE target if it exists */
|
|
129
|
-
if (target) {
|
|
129
|
+
if ((0, _utils.isMfeTarget)(target)) {
|
|
130
130
|
this.events.add({
|
|
131
131
|
...event,
|
|
132
132
|
targetAttributes: (0, _utils.getVersion2Attributes)(target, this)
|
|
@@ -262,7 +262,7 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
262
262
|
this.addEvent(event, target);
|
|
263
263
|
}, this.featureName, this.ee);
|
|
264
264
|
if (agentRef.init.feature_flags.includes('websockets') || agentRef.init.web_sockets?.enabled) {
|
|
265
|
-
(0, _registerHandler.registerHandler)('ws-complete', (nrData, targets = [
|
|
265
|
+
(0, _registerHandler.registerHandler)('ws-complete', (nrData, targets = [agentRef.runtime.v2Target]) => {
|
|
266
266
|
targets.forEach(target => {
|
|
267
267
|
const event = {
|
|
268
268
|
...nrData,
|
|
@@ -63,7 +63,7 @@ class Instrument extends _instrumentBase.InstrumentBase {
|
|
|
63
63
|
if (_runtime.isBrowserScope) {
|
|
64
64
|
(0, _wrapFetch.wrapFetch)(this.ee, agentRef);
|
|
65
65
|
(0, _wrapXhr.wrapXhr)(this.ee, agentRef);
|
|
66
|
-
historyEE = (0, _wrapHistory.wrapHistory)(this.ee);
|
|
66
|
+
historyEE = (0, _wrapHistory.wrapHistory)(this.ee, agentRef);
|
|
67
67
|
if (agentRef.init.user_actions.enabled) {
|
|
68
68
|
_constants.OBSERVED_EVENTS.forEach(eventType => (0, _eventListenerOpts.windowAddEventListener)(eventType, evt => (0, _handle.handle)('ua', [evt], undefined, this.featureName, this.ee), true));
|
|
69
69
|
_constants.OBSERVED_WINDOW_EVENTS.forEach(eventType => {
|
|
@@ -210,7 +210,7 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
210
210
|
if (targets.length) break;
|
|
211
211
|
}
|
|
212
212
|
}
|
|
213
|
-
if (!targets.length) targets.push(
|
|
213
|
+
if (!targets.length) targets.push(this.agentRef.runtime.v2Target);
|
|
214
214
|
}
|
|
215
215
|
return targets;
|
|
216
216
|
}
|
|
@@ -254,7 +254,7 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
254
254
|
if (filterOutput?.group) params.errorGroup = filterOutput.group;
|
|
255
255
|
|
|
256
256
|
// Should only decorate "hasReplay" for the container agent, so check if the target matches the config
|
|
257
|
-
if (hasReplay && !target) params.hasReplay = hasReplay;
|
|
257
|
+
if (hasReplay && !(0, _utils.isMfeTarget)(target)) params.hasReplay = hasReplay;
|
|
258
258
|
/**
|
|
259
259
|
* The bucketHash is different from the params.stackHash because the params.stackHash is based on the canonicalized
|
|
260
260
|
* stack trace and is used downstream in NR1 to attempt to group the same errors across different browsers. However,
|
|
@@ -289,13 +289,13 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
289
289
|
|
|
290
290
|
// Trace sends the error in its payload, and both trace & replay simply listens for any error to occur.
|
|
291
291
|
const jsErrorEvent = [type, bucketHash, params, newMetrics, customAttributes];
|
|
292
|
-
if (!target) (0, _handle.handle)('trace-jserror', jsErrorEvent, undefined, _features.FEATURE_NAMES.sessionTrace, this.ee);
|
|
292
|
+
if (!(0, _utils.isMfeTarget)(target)) (0, _handle.handle)('trace-jserror', jsErrorEvent, undefined, _features.FEATURE_NAMES.sessionTrace, this.ee);
|
|
293
293
|
// still send EE events for other features such as above, but stop this one from aggregating internal data
|
|
294
294
|
if (this.blocked) return;
|
|
295
295
|
if (err.__newrelic?.socketId) {
|
|
296
296
|
customAttributes.socketId = err.__newrelic.socketId;
|
|
297
297
|
}
|
|
298
|
-
if (!target) {
|
|
298
|
+
if (!(0, _utils.isMfeTarget)(target)) {
|
|
299
299
|
const softNavInUse = Boolean(this.agentRef.features?.[_features.FEATURE_NAMES.softNav]);
|
|
300
300
|
if (softNavInUse) {
|
|
301
301
|
// pass the error to soft nav for evaluation - it will return it via 'returnJserror' when interaction is resolved
|
|
@@ -306,7 +306,7 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
306
306
|
}
|
|
307
307
|
|
|
308
308
|
// always add directly if scoped to a sub-entity, the other pathways above will be deterministic if the main agent should procede
|
|
309
|
-
if (target) this.#storeJserrorForHarvest(jsErrorEvent, {}, target);
|
|
309
|
+
if ((0, _utils.isMfeTarget)(target)) this.#storeJserrorForHarvest(jsErrorEvent, {}, target);
|
|
310
310
|
}
|
|
311
311
|
|
|
312
312
|
/**
|
|
@@ -36,7 +36,7 @@ class Instrument extends _instrumentBase.InstrumentBase {
|
|
|
36
36
|
});
|
|
37
37
|
|
|
38
38
|
/** emitted by wrap-logger function */
|
|
39
|
-
this.ee.on('wrap-logger-end', function handleLog([message], _, __, targets = []) {
|
|
39
|
+
this.ee.on('wrap-logger-end', function handleLog([message], _, __, targets = [agentRef.runtime.v2Target]) {
|
|
40
40
|
const {
|
|
41
41
|
level,
|
|
42
42
|
customAttributes,
|
|
@@ -15,7 +15,7 @@ var _now = require("../../../common/timing/now");
|
|
|
15
15
|
var _addToTrace = require("../../../loaders/api/addToTrace");
|
|
16
16
|
var _finished = require("../../../loaders/api/finished");
|
|
17
17
|
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); } /**
|
|
18
|
-
* Copyright 2020-
|
|
18
|
+
* Copyright 2020-2026 New Relic, Inc. All rights reserved.
|
|
19
19
|
* SPDX-License-Identifier: Apache-2.0
|
|
20
20
|
*/
|
|
21
21
|
const {
|
|
@@ -42,8 +42,8 @@ class Instrument extends _instrumentBase.InstrumentBase {
|
|
|
42
42
|
return;
|
|
43
43
|
}
|
|
44
44
|
const thisInstrumentEE = this.ee;
|
|
45
|
-
(0, _wrapHistory.wrapHistory)(thisInstrumentEE);
|
|
46
|
-
this.eventsEE = (0, _wrapEvents.wrapEvents)(thisInstrumentEE);
|
|
45
|
+
(0, _wrapHistory.wrapHistory)(thisInstrumentEE, agentRef);
|
|
46
|
+
this.eventsEE = (0, _wrapEvents.wrapEvents)(thisInstrumentEE, agentRef);
|
|
47
47
|
this.eventsEE.on(FN_START, function (args, target) {
|
|
48
48
|
this.bstStart = (0, _now.now)();
|
|
49
49
|
});
|
|
@@ -15,7 +15,7 @@ var _constants = require("../constants");
|
|
|
15
15
|
var _now = require("../../../common/timing/now");
|
|
16
16
|
var _interaction = require("../../../loaders/api/interaction");
|
|
17
17
|
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); } /**
|
|
18
|
-
* Copyright 2020-
|
|
18
|
+
* Copyright 2020-2026 New Relic, Inc. All rights reserved.
|
|
19
19
|
* SPDX-License-Identifier: Apache-2.0
|
|
20
20
|
*/
|
|
21
21
|
/**
|
|
@@ -34,7 +34,7 @@ class Instrument extends _instrumentBase.InstrumentBase {
|
|
|
34
34
|
(0, _interaction.setupInteractionAPI)(agentRef);
|
|
35
35
|
if (!_runtime.isBrowserScope || !(0, _nreum.gosNREUMOriginals)().o.MO) return; // soft navigations is not supported outside web env or browsers without the mutation observer API
|
|
36
36
|
|
|
37
|
-
const historyEE = (0, _wrapHistory.wrapHistory)(this.ee);
|
|
37
|
+
const historyEE = (0, _wrapHistory.wrapHistory)(this.ee, agentRef);
|
|
38
38
|
try {
|
|
39
39
|
this.removeOnAbort = new AbortController();
|
|
40
40
|
} catch (e) {}
|
|
@@ -7,12 +7,12 @@ exports.setupRegisterAPI = setupRegisterAPI;
|
|
|
7
7
|
exports.warnings = void 0;
|
|
8
8
|
var _handle = require("../../common/event-emitter/handle");
|
|
9
9
|
var _console = require("../../common/util/console");
|
|
10
|
-
var
|
|
10
|
+
var _constants = require("../../common/v2/constants");
|
|
11
11
|
var _features = require("../features/features");
|
|
12
12
|
var _now = require("../../common/timing/now");
|
|
13
|
-
var
|
|
13
|
+
var _constants2 = require("../../features/metrics/constants");
|
|
14
14
|
var _sharedHandlers = require("./sharedHandlers");
|
|
15
|
-
var
|
|
15
|
+
var _constants3 = require("./constants");
|
|
16
16
|
var _log = require("./log");
|
|
17
17
|
var _addPageAction = require("./addPageAction");
|
|
18
18
|
var _noticeError = require("./noticeError");
|
|
@@ -57,7 +57,7 @@ const warnings = exports.warnings = {
|
|
|
57
57
|
* It is not recommended for use in production environments and will not receive support for issues.
|
|
58
58
|
*/
|
|
59
59
|
function setupRegisterAPI(agent) {
|
|
60
|
-
(0, _sharedHandlers.setupAPI)(
|
|
60
|
+
(0, _sharedHandlers.setupAPI)(_constants3.REGISTER, function (target) {
|
|
61
61
|
return register(agent, target);
|
|
62
62
|
}, agent);
|
|
63
63
|
}
|
|
@@ -73,7 +73,7 @@ function register(agentRef, target) {
|
|
|
73
73
|
warnings.experimental();
|
|
74
74
|
target ||= {};
|
|
75
75
|
target.instance = (0, _uniqueId.generateRandomHexString)(8);
|
|
76
|
-
target.type =
|
|
76
|
+
target.type = _constants.V2_TYPES.MFE;
|
|
77
77
|
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.
|
|
78
78
|
target.blocked = false;
|
|
79
79
|
if (typeof target.tags !== 'object' || target.tags === null || Array.isArray(target.tags)) target.tags = {};
|
|
@@ -82,7 +82,7 @@ function register(agentRef, target) {
|
|
|
82
82
|
return agentRef.runtime.appMetadata.agents?.[0].entityGuid;
|
|
83
83
|
},
|
|
84
84
|
// getter because this is asynchronously set
|
|
85
|
-
type:
|
|
85
|
+
type: _constants.V2_TYPES.BA
|
|
86
86
|
};
|
|
87
87
|
const timings = (0, _scriptTracker.findScriptTimings)(target);
|
|
88
88
|
|
|
@@ -99,7 +99,7 @@ function register(agentRef, target) {
|
|
|
99
99
|
'source.id': target.id,
|
|
100
100
|
'source.name': target.name,
|
|
101
101
|
'source.type': target.type,
|
|
102
|
-
'parent.type': target.parent?.type ||
|
|
102
|
+
'parent.type': target.parent?.type || _constants.V2_TYPES.BA,
|
|
103
103
|
'parent.id': target.parent?.id
|
|
104
104
|
};
|
|
105
105
|
}
|
|
@@ -281,7 +281,7 @@ function register(agentRef, target) {
|
|
|
281
281
|
const timestamp = api.metadata.events.latestTimestamp ?? (0, _now.now)();
|
|
282
282
|
api.metadata.events.latestTimestamp = undefined;
|
|
283
283
|
const methodName = METHOD_NAMES.get(methodToCall) || 'unknown';
|
|
284
|
-
(0, _handle.handle)(
|
|
284
|
+
(0, _handle.handle)(_constants2.SUPPORTABILITY_METRIC_CHANNEL, ["API/register/".concat(methodName, "/called")], undefined, _features.FEATURE_NAMES.metrics, agentRef.ee);
|
|
285
285
|
try {
|
|
286
286
|
return methodToCall(...args, target, timestamp); // always report to target
|
|
287
287
|
} catch (err) {
|
|
@@ -9,6 +9,7 @@ var _nreum = require("../../common/window/nreum");
|
|
|
9
9
|
var _info = require("../../common/config/info");
|
|
10
10
|
var _init = require("../../common/config/init");
|
|
11
11
|
var _runtime = require("../../common/config/runtime");
|
|
12
|
+
var _constants = require("../../common/v2/constants");
|
|
12
13
|
var _runtime2 = require("../../common/constants/runtime");
|
|
13
14
|
var _publicPath = require("./public-path");
|
|
14
15
|
var _contextualEe = require("../../common/event-emitter/contextual-ee");
|
|
@@ -52,6 +53,19 @@ function configure(agent, opts = {}, loaderType, forceDrain) {
|
|
|
52
53
|
agent.info = (0, _info.mergeInfo)(info);
|
|
53
54
|
const updatedInit = agent.init;
|
|
54
55
|
agent.runtime ??= (0, _runtime.mergeRuntime)(runtime);
|
|
56
|
+
agent.runtime.v2Target ??= {
|
|
57
|
+
type: _constants.V2_TYPES.BA,
|
|
58
|
+
instance: agent.agentIdentifier,
|
|
59
|
+
get id() {
|
|
60
|
+
return agent.runtime.appMetadata?.agents?.[0]?.entityGuid;
|
|
61
|
+
},
|
|
62
|
+
get attributes() {
|
|
63
|
+
return {
|
|
64
|
+
'entity.guid': this.id,
|
|
65
|
+
appId: agent.info.applicationID
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
};
|
|
55
69
|
|
|
56
70
|
// Apply proxy settings whenever configure is called (supports late {init} setting)
|
|
57
71
|
if (updatedInit.proxy.assets) {
|
|
@@ -40,6 +40,8 @@ const RuntimeModel = {
|
|
|
40
40
|
drainRegistry: new Map(),
|
|
41
41
|
connector: undefined,
|
|
42
42
|
harvester: undefined,
|
|
43
|
+
/** eagerly-created in configure() -- the v2 target representing the container (main) agent, see common/v2/utils#V2Target */
|
|
44
|
+
v2Target: undefined,
|
|
43
45
|
isolatedBacklog: false,
|
|
44
46
|
isRecording: false,
|
|
45
47
|
// true when actively recording, false when paused or stopped
|
|
@@ -22,7 +22,7 @@ export const analyzeElemPath = (elem, targetFields = [], agentRef) => {
|
|
|
22
22
|
path: undefined,
|
|
23
23
|
nearestFields: {},
|
|
24
24
|
get targets() {
|
|
25
|
-
return targets.length ? targets : [
|
|
25
|
+
return targets.length ? targets : [agentRef.runtime.v2Target];
|
|
26
26
|
},
|
|
27
27
|
hasButton: false,
|
|
28
28
|
hasLink: false
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2020-2026 New Relic, Inc. All rights reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @enum {string}
|
|
8
|
+
* @readonly
|
|
9
|
+
*/
|
|
10
|
+
export const V2_TYPES = {
|
|
11
|
+
/** Micro Frontend */
|
|
12
|
+
MFE: 'MFE',
|
|
13
|
+
/** Browser Application */
|
|
14
|
+
BA: 'BA'
|
|
15
|
+
};
|
|
@@ -4,17 +4,24 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { extractUrlsFromStack, getDeepStackTrace } from './script-tracker';
|
|
7
|
+
import { V2_TYPES } from './constants';
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
|
-
* @
|
|
10
|
-
* @
|
|
10
|
+
* @typedef {Object} V2Target
|
|
11
|
+
* @property {'BA'} type always V2_TYPES.BA -- identifies this as the container (main) agent, not a registered MFE
|
|
12
|
+
* @property {string} instance the container agent's agentIdentifier
|
|
13
|
+
* @property {string} [id] the container agent's entity guid, once known (getter, resolved asynchronously)
|
|
14
|
+
* @property {{[key:string]: any}} attributes the V2 payload attributes for the container agent (getter)
|
|
11
15
|
*/
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Determines if a given target represents a registered MFE (as opposed to the container agent).
|
|
19
|
+
* @param {*} target the target to check
|
|
20
|
+
* @returns {boolean} true if the target is a registered MFE target
|
|
21
|
+
*/
|
|
22
|
+
export function isMfeTarget(target) {
|
|
23
|
+
return target?.type === V2_TYPES.MFE;
|
|
24
|
+
}
|
|
18
25
|
|
|
19
26
|
/**
|
|
20
27
|
* Returns a single registered entity associated with a given iframe interface ID. Returns undefined if no entity is found.
|
|
@@ -110,14 +117,8 @@ export function dedupeRegisteredEntitiesByAsset(entities) {
|
|
|
110
117
|
*/
|
|
111
118
|
export function getVersion2Attributes(target, aggregateInstance) {
|
|
112
119
|
if (!supportsV2(aggregateInstance)) return {};
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
if (!target) {
|
|
116
|
-
return {
|
|
117
|
-
'entity.guid': containerAgentEntityGuid,
|
|
118
|
-
appId: aggregateInstance.agentRef.info.applicationID
|
|
119
|
-
};
|
|
120
|
-
}
|
|
120
|
+
/** if the target isn't a registered MFE, but we are in v2 mode, this means the data belongs to the container agent */
|
|
121
|
+
if (!isMfeTarget(target)) return aggregateInstance.agentRef.runtime.v2Target.attributes;
|
|
121
122
|
/** otherwise, the data belongs to the target (MFE) and should be attributed as such */
|
|
122
123
|
return target.attributes;
|
|
123
124
|
}
|
|
@@ -147,16 +148,17 @@ export function getVersion2DuplicationAttributes(target, aggregateInstance) {
|
|
|
147
148
|
* @returns {boolean} returns true if the event should be duplicated for the target, false otherwise
|
|
148
149
|
*/
|
|
149
150
|
export function shouldDuplicate(target, aggregateInstance) {
|
|
150
|
-
return
|
|
151
|
+
return isMfeTarget(target) && !!supportsV2(aggregateInstance) && aggregateInstance.agentRef.init.api.register.duplicate_data_to_container;
|
|
151
152
|
}
|
|
152
153
|
|
|
153
154
|
/**
|
|
154
155
|
* Finds the registered targets from the stack trace for a given agent reference.
|
|
155
156
|
* @param {*} agentRef The agent reference to use for finding targets.
|
|
156
|
-
* @returns {Array} An array of targets found from the stack trace. If no targets are found or allowed, returns an array
|
|
157
|
+
* @returns {Array} An array of targets found from the stack trace. If no targets are found or allowed, returns an array containing the container target.
|
|
157
158
|
*/
|
|
158
159
|
export function findTargetsFromStackTrace(agentRef) {
|
|
159
|
-
if (!
|
|
160
|
+
if (!agentRef?.runtime) return [];
|
|
161
|
+
if (!isValid(true, agentRef) || !agentRef.runtime.registeredEntities?.length) return [agentRef.runtime.v2Target];
|
|
160
162
|
const targets = [];
|
|
161
163
|
try {
|
|
162
164
|
var urls = extractUrlsFromStack(getDeepStackTrace());
|
|
@@ -168,15 +170,15 @@ export function findTargetsFromStackTrace(agentRef) {
|
|
|
168
170
|
// Silent catch to prevent errors from propagating
|
|
169
171
|
}
|
|
170
172
|
const deduped = dedupeTargetsByInstance(targets);
|
|
171
|
-
if (!deduped.length) deduped.push(
|
|
173
|
+
if (!deduped.length) deduped.push(agentRef.runtime.v2Target); // if we can't find any targets from the stack trace, the container agent is the target
|
|
172
174
|
return deduped;
|
|
173
175
|
}
|
|
174
176
|
|
|
175
177
|
/**
|
|
176
178
|
* Removes duplicate targets from an array, keyed by `target.instance`. This guards against the same canonical
|
|
177
179
|
* target re-entering the array via multiple matched stack-frame URLs (e.g. a recursive call whose stack contains the
|
|
178
|
-
* same file at multiple depths).
|
|
179
|
-
* naturally collapse to a single entry too, which is the desired behavior.
|
|
180
|
+
* same file at multiple depths). Multiple container-target entries (whose `instance` is the container agent's stable
|
|
181
|
+
* `agentIdentifier`) naturally collapse to a single entry too, which is the desired behavior.
|
|
180
182
|
* @param {Array} targets
|
|
181
183
|
* @returns {Array} deduped list of targets, preserving relative order of first occurrence
|
|
182
184
|
*/
|