@newrelic/browser-agent 1.301.0 → 1.302.0-rc.1
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/CHANGELOG.md +13 -0
- package/dist/cjs/common/config/init-types.js +1 -1
- package/dist/cjs/common/config/init.js +7 -1
- package/dist/cjs/common/config/runtime.js +1 -1
- package/dist/cjs/common/constants/agent-constants.js +11 -2
- package/dist/cjs/common/constants/env.cdn.js +1 -1
- package/dist/cjs/common/constants/env.npm.js +1 -1
- package/dist/cjs/common/drain/drain.js +1 -1
- package/dist/cjs/common/harvest/harvester.js +30 -39
- package/dist/cjs/common/util/mfe.js +45 -0
- package/dist/cjs/features/ajax/aggregate/index.js +5 -1
- package/dist/cjs/features/generic_events/aggregate/index.js +9 -8
- package/dist/cjs/features/generic_events/constants.js +3 -1
- package/dist/cjs/features/generic_events/instrument/index.js +38 -32
- package/dist/cjs/features/jserrors/aggregate/index.js +18 -17
- package/dist/cjs/features/logging/aggregate/index.js +19 -15
- package/dist/cjs/features/logging/shared/utils.js +3 -3
- package/dist/cjs/features/page_view_event/aggregate/index.js +3 -33
- package/dist/cjs/features/session_replay/aggregate/index.js +13 -13
- package/dist/cjs/features/session_replay/shared/recorder.js +3 -2
- package/dist/cjs/features/session_trace/aggregate/index.js +0 -2
- package/dist/cjs/features/soft_navigations/aggregate/index.js +1 -2
- package/dist/cjs/features/utils/aggregate-base.js +45 -47
- package/dist/cjs/loaders/api/addPageAction.js +2 -2
- package/dist/cjs/loaders/api/log.js +2 -2
- package/dist/cjs/loaders/api/noticeError.js +2 -2
- package/dist/cjs/loaders/api/register-api-types.js +5 -5
- package/dist/cjs/loaders/api/register.js +80 -97
- package/dist/esm/common/config/init-types.js +1 -1
- package/dist/esm/common/config/init.js +7 -1
- package/dist/esm/common/config/runtime.js +1 -1
- package/dist/esm/common/constants/agent-constants.js +9 -1
- package/dist/esm/common/constants/env.cdn.js +1 -1
- package/dist/esm/common/constants/env.npm.js +1 -1
- package/dist/esm/common/drain/drain.js +1 -1
- package/dist/esm/common/harvest/harvester.js +30 -39
- package/dist/esm/common/util/mfe.js +38 -0
- package/dist/esm/features/ajax/aggregate/index.js +5 -1
- package/dist/esm/features/generic_events/aggregate/index.js +9 -8
- package/dist/esm/features/generic_events/constants.js +3 -1
- package/dist/esm/features/generic_events/instrument/index.js +38 -32
- package/dist/esm/features/jserrors/aggregate/index.js +18 -17
- package/dist/esm/features/logging/aggregate/index.js +19 -15
- package/dist/esm/features/logging/shared/utils.js +3 -3
- package/dist/esm/features/page_view_event/aggregate/index.js +3 -33
- package/dist/esm/features/session_replay/aggregate/index.js +13 -13
- package/dist/esm/features/session_replay/shared/recorder.js +3 -2
- package/dist/esm/features/session_trace/aggregate/index.js +0 -2
- package/dist/esm/features/soft_navigations/aggregate/index.js +1 -2
- package/dist/esm/features/utils/aggregate-base.js +46 -48
- package/dist/esm/loaders/api/addPageAction.js +2 -2
- package/dist/esm/loaders/api/log.js +2 -2
- package/dist/esm/loaders/api/noticeError.js +2 -2
- package/dist/esm/loaders/api/register-api-types.js +5 -5
- package/dist/esm/loaders/api/register.js +80 -97
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/common/config/init-types.d.ts +4 -1
- package/dist/types/common/config/init-types.d.ts.map +1 -1
- package/dist/types/common/config/init.d.ts.map +1 -1
- package/dist/types/common/constants/agent-constants.d.ts +7 -4
- package/dist/types/common/constants/agent-constants.d.ts.map +1 -1
- package/dist/types/common/harvest/harvester.d.ts +2 -2
- package/dist/types/common/harvest/harvester.d.ts.map +1 -1
- package/dist/types/common/util/mfe.d.ts +20 -0
- package/dist/types/common/util/mfe.d.ts.map +1 -0
- package/dist/types/features/ajax/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/generic_events/aggregate/index.d.ts +2 -2
- package/dist/types/features/generic_events/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/generic_events/constants.d.ts +1 -0
- package/dist/types/features/generic_events/instrument/index.d.ts.map +1 -1
- package/dist/types/features/jserrors/aggregate/index.d.ts +3 -3
- package/dist/types/features/jserrors/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/logging/aggregate/index.d.ts +3 -3
- package/dist/types/features/logging/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/logging/shared/utils.d.ts +2 -2
- package/dist/types/features/logging/shared/utils.d.ts.map +1 -1
- package/dist/types/features/page_view_event/aggregate/index.d.ts +2 -4
- package/dist/types/features/page_view_event/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/session_replay/aggregate/index.d.ts +13 -4
- package/dist/types/features/session_replay/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/session_replay/shared/recorder.d.ts +1 -0
- package/dist/types/features/session_replay/shared/recorder.d.ts.map +1 -1
- package/dist/types/features/session_trace/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/soft_navigations/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/utils/aggregate-base.d.ts +13 -5
- package/dist/types/features/utils/aggregate-base.d.ts.map +1 -1
- package/dist/types/loaders/api/addPageAction.d.ts +1 -1
- package/dist/types/loaders/api/addPageAction.d.ts.map +1 -1
- package/dist/types/loaders/api/log.d.ts +1 -1
- package/dist/types/loaders/api/log.d.ts.map +1 -1
- package/dist/types/loaders/api/noticeError.d.ts +1 -1
- package/dist/types/loaders/api/noticeError.d.ts.map +1 -1
- package/dist/types/loaders/api/register-api-types.d.ts +4 -4
- package/dist/types/loaders/api/register-api-types.d.ts.map +1 -1
- package/dist/types/loaders/api/register.d.ts +8 -1
- package/dist/types/loaders/api/register.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/common/config/init-types.js +1 -1
- package/src/common/config/init.js +3 -1
- package/src/common/config/runtime.js +1 -1
- package/src/common/constants/agent-constants.js +10 -0
- package/src/common/drain/drain.js +1 -1
- package/src/common/harvest/harvester.js +27 -32
- package/src/common/util/mfe.js +35 -0
- package/src/features/ajax/aggregate/index.js +7 -1
- package/src/features/generic_events/aggregate/index.js +9 -8
- package/src/features/generic_events/constants.js +3 -1
- package/src/features/generic_events/instrument/index.js +44 -35
- package/src/features/jserrors/aggregate/index.js +17 -17
- package/src/features/logging/aggregate/index.js +20 -13
- package/src/features/logging/shared/utils.js +3 -3
- package/src/features/page_view_event/aggregate/index.js +3 -28
- package/src/features/session_replay/aggregate/index.js +12 -10
- package/src/features/session_replay/shared/recorder.js +3 -2
- package/src/features/session_trace/aggregate/index.js +0 -2
- package/src/features/soft_navigations/aggregate/index.js +1 -2
- package/src/features/utils/aggregate-base.js +47 -42
- package/src/loaders/api/addPageAction.js +2 -2
- package/src/loaders/api/log.js +2 -2
- package/src/loaders/api/noticeError.js +2 -2
- package/src/loaders/api/register-api-types.js +5 -5
- package/src/loaders/api/register.js +62 -89
- package/dist/cjs/common/util/target.js +0 -34
- package/dist/cjs/features/utils/entity-manager.js +0 -46
- package/dist/cjs/features/utils/event-store-manager.js +0 -174
- package/dist/cjs/loaders/api/register-api.js +0 -165
- package/dist/esm/common/util/target.js +0 -27
- package/dist/esm/features/utils/entity-manager.js +0 -39
- package/dist/esm/features/utils/event-store-manager.js +0 -166
- package/dist/esm/loaders/api/register-api.js +0 -159
- package/dist/types/common/util/target.d.ts +0 -18
- package/dist/types/common/util/target.d.ts.map +0 -1
- package/dist/types/features/utils/entity-manager.d.ts +0 -11
- package/dist/types/features/utils/entity-manager.d.ts.map +0 -1
- package/dist/types/features/utils/event-store-manager.d.ts +0 -85
- package/dist/types/features/utils/event-store-manager.d.ts.map +0 -1
- package/dist/types/loaders/api/register-api.d.ts +0 -14
- package/dist/types/loaders/api/register-api.d.ts.map +0 -1
- package/src/common/util/target.js +0 -27
- package/src/features/utils/entity-manager.js +0 -45
- package/src/features/utils/event-store-manager.js +0 -165
- package/src/loaders/api/register-api.js +0 -152
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,19 @@
|
|
|
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.302.0](https://github.com/newrelic/newrelic-browser-agent/compare/v1.301.0...v1.302.0) (2025-10-24)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* Prepare agent to utilize v2 harvests for MFE registrations ([#1495](https://github.com/newrelic/newrelic-browser-agent/issues/1495)) ([a7ac827](https://github.com/newrelic/newrelic-browser-agent/commit/a7ac82751dd8dade8294a66a7894c1295679265b))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
### Bug Fixes
|
|
15
|
+
|
|
16
|
+
* Improve accuracy in standalone AjaxRequest event start times ([#1598](https://github.com/newrelic/newrelic-browser-agent/issues/1598)) ([b41de5c](https://github.com/newrelic/newrelic-browser-agent/commit/b41de5cbcd9d75fa8bd3c67ad1270fde4f788733))
|
|
17
|
+
* User frustrations logic should be gated ([#1600](https://github.com/newrelic/newrelic-browser-agent/issues/1600)) ([984b05e](https://github.com/newrelic/newrelic-browser-agent/commit/984b05e8920be79d7c3d1c3d7d56c75fa2cfe253))
|
|
18
|
+
|
|
6
19
|
## [1.301.0](https://github.com/newrelic/newrelic-browser-agent/compare/v1.300.0...v1.301.0) (2025-10-21)
|
|
7
20
|
|
|
8
21
|
|
|
@@ -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 {
|
|
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
|
|
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.
|
|
20
|
+
const VERSION = exports.VERSION = "1.302.0-rc.1";
|
|
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.
|
|
20
|
+
const VERSION = exports.VERSION = "1.302.0-rc.1";
|
|
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, []); //
|
|
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
|
-
|
|
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
|
|
71
|
+
if (!submitMethod) return output;
|
|
67
72
|
const shouldRetryOnFail = !localOpts.isFinalHarvest && submitMethod === _submitData.xhr; // always retry all features harvests except for final
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
if (!
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
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
|
-
|
|
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 : '', "/
|
|
149
|
-
const baseParams = !raw ? baseQueryString(agentRef, qs, endpoint
|
|
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
|
|
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
|
+
}
|
|
@@ -131,9 +131,13 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
131
131
|
if (!eventBuffer.length) return;
|
|
132
132
|
const addString = (0, _belSerializer.getAddStringContext)(this.agentRef.runtime.obfuscator);
|
|
133
133
|
let payload = 'bel.7;';
|
|
134
|
+
let firstTimestamp = 0;
|
|
134
135
|
for (let i = 0; i < eventBuffer.length; i++) {
|
|
135
136
|
const event = eventBuffer[i];
|
|
136
|
-
|
|
137
|
+
// ajax nodes are relative to the first node (or page origin if no previous node), so we need to calculate the relative start time
|
|
138
|
+
const relativeStartTime = event.startTime - firstTimestamp;
|
|
139
|
+
if (i === 0) firstTimestamp = event.startTime;
|
|
140
|
+
const fields = [(0, _belSerializer.numeric)(relativeStartTime), (0, _belSerializer.numeric)(event.endTime - event.startTime), (0, _belSerializer.numeric)(0),
|
|
137
141
|
// callbackEnd
|
|
138
142
|
(0, _belSerializer.numeric)(0),
|
|
139
143
|
// no callbackDuration for non-SPA events
|
|
@@ -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,
|
|
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
|
-
},
|
|
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=}
|
|
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 = {},
|
|
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
|
|
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
|
};
|
|
@@ -38,6 +38,13 @@ class Instrument extends _instrumentBase.InstrumentBase {
|
|
|
38
38
|
(0, _finished.setupFinishedAPI)(agentRef);
|
|
39
39
|
(0, _register.setupRegisterAPI)(agentRef);
|
|
40
40
|
(0, _measure.setupMeasureAPI)(agentRef);
|
|
41
|
+
const ufEnabled = agentRef.init.feature_flags.includes('user_frustrations');
|
|
42
|
+
let historyEE;
|
|
43
|
+
if (_runtime.isBrowserScope && ufEnabled) {
|
|
44
|
+
(0, _wrapFetch.wrapFetch)(this.ee);
|
|
45
|
+
(0, _wrapXhr.wrapXhr)(this.ee);
|
|
46
|
+
historyEE = (0, _wrapHistory.wrapHistory)(this.ee);
|
|
47
|
+
}
|
|
41
48
|
if (_runtime.isBrowserScope) {
|
|
42
49
|
if (agentRef.init.user_actions.enabled) {
|
|
43
50
|
_constants.OBSERVED_EVENTS.forEach(eventType => (0, _eventListenerOpts.windowAddEventListener)(eventType, evt => (0, _handle.handle)('ua', [evt], undefined, this.featureName, this.ee), true));
|
|
@@ -51,6 +58,37 @@ class Instrument extends _instrumentBase.InstrumentBase {
|
|
|
51
58
|
}
|
|
52
59
|
// Capture is not used here so that we don't get element focus/blur events, only the window's as they do not bubble. They are also not cancellable, so no worries about being front of line.
|
|
53
60
|
);
|
|
61
|
+
if (ufEnabled) {
|
|
62
|
+
_runtime.globalScope.addEventListener('error', () => {
|
|
63
|
+
(0, _handle.handle)('uaErr', [], undefined, _features.FEATURE_NAMES.genericEvents, this.ee);
|
|
64
|
+
}, (0, _eventListenerOpts.eventListenerOpts)(false, this.removeOnAbort?.signal));
|
|
65
|
+
this.ee.on('open-xhr-start', (args, xhr) => {
|
|
66
|
+
if (!isInternalTraffic(args[1])) {
|
|
67
|
+
xhr.addEventListener('readystatechange', () => {
|
|
68
|
+
if (xhr.readyState === 2) {
|
|
69
|
+
// HEADERS_RECEIVED
|
|
70
|
+
(0, _handle.handle)('uaXhr', [], undefined, _features.FEATURE_NAMES.genericEvents, this.ee);
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
this.ee.on('fetch-start', fetchArguments => {
|
|
76
|
+
if (fetchArguments.length >= 1 && !isInternalTraffic((0, _extractUrl.extractUrl)(fetchArguments[0]))) {
|
|
77
|
+
(0, _handle.handle)('uaXhr', [], undefined, _features.FEATURE_NAMES.genericEvents, this.ee);
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
function isInternalTraffic(url) {
|
|
81
|
+
const parsedUrl = (0, _parseUrl.parseUrl)(url);
|
|
82
|
+
return agentRef.beacons.includes(parsedUrl.hostname + ':' + parsedUrl.port);
|
|
83
|
+
}
|
|
84
|
+
historyEE.on('pushState-end', navigationChange);
|
|
85
|
+
historyEE.on('replaceState-end', navigationChange);
|
|
86
|
+
window.addEventListener('hashchange', navigationChange, (0, _eventListenerOpts.eventListenerOpts)(true, this.removeOnAbort?.signal));
|
|
87
|
+
window.addEventListener('popstate', navigationChange, (0, _eventListenerOpts.eventListenerOpts)(true, this.removeOnAbort?.signal));
|
|
88
|
+
function navigationChange() {
|
|
89
|
+
historyEE.emit('navChange');
|
|
90
|
+
}
|
|
91
|
+
}
|
|
54
92
|
}
|
|
55
93
|
if (agentRef.init.performance.resources.enabled && _runtime.globalScope.PerformanceObserver?.supportedEntryTypes.includes('resource')) {
|
|
56
94
|
const observer = new PerformanceObserver(list => {
|
|
@@ -63,14 +101,6 @@ class Instrument extends _instrumentBase.InstrumentBase {
|
|
|
63
101
|
buffered: true
|
|
64
102
|
});
|
|
65
103
|
}
|
|
66
|
-
const historyEE = (0, _wrapHistory.wrapHistory)(this.ee);
|
|
67
|
-
historyEE.on('pushState-end', navigationChange);
|
|
68
|
-
historyEE.on('replaceState-end', navigationChange);
|
|
69
|
-
window.addEventListener('hashchange', navigationChange, (0, _eventListenerOpts.eventListenerOpts)(true, this.removeOnAbort?.signal));
|
|
70
|
-
window.addEventListener('popstate', navigationChange, (0, _eventListenerOpts.eventListenerOpts)(true, this.removeOnAbort?.signal));
|
|
71
|
-
function navigationChange() {
|
|
72
|
-
historyEE.emit('navChange');
|
|
73
|
-
}
|
|
74
104
|
}
|
|
75
105
|
try {
|
|
76
106
|
this.removeOnAbort = new AbortController();
|
|
@@ -79,30 +109,6 @@ class Instrument extends _instrumentBase.InstrumentBase {
|
|
|
79
109
|
this.removeOnAbort?.abort();
|
|
80
110
|
this.abortHandler = undefined; // weakly allow this abort op to run only once
|
|
81
111
|
};
|
|
82
|
-
_runtime.globalScope.addEventListener('error', () => {
|
|
83
|
-
(0, _handle.handle)('uaErr', [], undefined, _features.FEATURE_NAMES.genericEvents, this.ee);
|
|
84
|
-
}, (0, _eventListenerOpts.eventListenerOpts)(false, this.removeOnAbort?.signal));
|
|
85
|
-
(0, _wrapFetch.wrapFetch)(this.ee);
|
|
86
|
-
(0, _wrapXhr.wrapXhr)(this.ee);
|
|
87
|
-
this.ee.on('open-xhr-start', (args, xhr) => {
|
|
88
|
-
if (!isInternalTraffic(args[1])) {
|
|
89
|
-
xhr.addEventListener('readystatechange', () => {
|
|
90
|
-
if (xhr.readyState === 2) {
|
|
91
|
-
// HEADERS_RECEIVED
|
|
92
|
-
(0, _handle.handle)('uaXhr', [], undefined, _features.FEATURE_NAMES.genericEvents, this.ee);
|
|
93
|
-
}
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
});
|
|
97
|
-
this.ee.on('fetch-start', fetchArguments => {
|
|
98
|
-
if (fetchArguments.length >= 1 && !isInternalTraffic((0, _extractUrl.extractUrl)(fetchArguments[0]))) {
|
|
99
|
-
(0, _handle.handle)('uaXhr', [], undefined, _features.FEATURE_NAMES.genericEvents, this.ee);
|
|
100
|
-
}
|
|
101
|
-
});
|
|
102
|
-
function isInternalTraffic(url) {
|
|
103
|
-
const parsedUrl = (0, _parseUrl.parseUrl)(url);
|
|
104
|
-
return agentRef.beacons.includes(parsedUrl.hostname + ':' + parsedUrl.port);
|
|
105
|
-
}
|
|
106
112
|
|
|
107
113
|
/** If any of the sources are active, import the aggregator. otherwise deregister */
|
|
108
114
|
if (genericEventSourceConfigs.some(x => x)) this.importAggregator(agentRef, () => Promise.resolve().then(() => _interopRequireWildcard(require(/* webpackChunkName: "generic_events-aggregate" */'../aggregate'))));else this.deregisterDrain();
|
|
@@ -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
|
|
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,
|
|
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 &&
|
|
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(
|
|
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(
|
|
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 (
|
|
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,
|
|
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]
|
|
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}
|
|
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(
|
|
246
|
-
return !
|
|
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.
|