@newrelic/browser-agent 1.310.1 → 1.311.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 +16 -0
- package/dist/cjs/common/config/configurable.js +2 -2
- package/dist/cjs/common/config/runtime.js +8 -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/constants/runtime.js +17 -4
- package/dist/cjs/common/deny-list/deny-list.js +2 -2
- package/dist/cjs/common/drain/drain.js +27 -37
- package/dist/cjs/common/harvest/harvester.js +1 -3
- package/dist/cjs/common/session/session-entity.js +7 -8
- package/dist/cjs/common/util/console.js +1 -2
- package/dist/cjs/common/util/feature-flags.js +5 -16
- package/dist/cjs/common/util/script-tracker.js +22 -4
- package/dist/cjs/common/util/stringify.js +22 -7
- package/dist/cjs/common/vitals/largest-contentful-paint.js +0 -1
- package/dist/cjs/common/vitals/load-time.js +3 -2
- package/dist/cjs/common/vitals/time-to-first-byte.js +2 -2
- package/dist/cjs/features/jserrors/aggregate/index.js +0 -4
- package/dist/cjs/features/page_view_event/aggregate/index.js +3 -3
- package/dist/cjs/features/page_view_event/aggregate/initialized-features.js +3 -5
- package/dist/cjs/features/page_view_event/instrument/index.js +3 -5
- package/dist/cjs/features/page_view_timing/aggregate/index.js +2 -0
- package/dist/cjs/features/session_trace/aggregate/index.js +4 -3
- package/dist/cjs/features/utils/agent-session.js +3 -4
- package/dist/cjs/features/utils/aggregate-base.js +4 -6
- package/dist/cjs/features/utils/feature-base.js +6 -7
- package/dist/cjs/features/utils/instrument-base.js +7 -8
- package/dist/cjs/loaders/api/register-api-types.js +1 -1
- package/dist/cjs/loaders/api/register.js +1 -1
- package/dist/cjs/loaders/api/sharedHandlers.js +2 -4
- package/dist/cjs/loaders/configure/configure.js +23 -21
- package/dist/esm/common/config/configurable.js +2 -2
- package/dist/esm/common/config/runtime.js +8 -2
- package/dist/esm/common/constants/env.cdn.js +1 -1
- package/dist/esm/common/constants/env.npm.js +1 -1
- package/dist/esm/common/constants/runtime.js +15 -2
- package/dist/esm/common/deny-list/deny-list.js +2 -2
- package/dist/esm/common/drain/drain.js +27 -36
- package/dist/esm/common/harvest/harvester.js +1 -3
- package/dist/esm/common/session/session-entity.js +7 -8
- package/dist/esm/common/util/console.js +1 -2
- package/dist/esm/common/util/feature-flags.js +5 -14
- package/dist/esm/common/util/script-tracker.js +22 -5
- package/dist/esm/common/util/stringify.js +22 -7
- package/dist/esm/common/vitals/largest-contentful-paint.js +0 -1
- package/dist/esm/common/vitals/load-time.js +4 -3
- package/dist/esm/common/vitals/time-to-first-byte.js +3 -3
- package/dist/esm/features/jserrors/aggregate/index.js +0 -4
- package/dist/esm/features/page_view_event/aggregate/index.js +4 -4
- package/dist/esm/features/page_view_event/aggregate/initialized-features.js +3 -5
- package/dist/esm/features/page_view_event/instrument/index.js +3 -5
- package/dist/esm/features/page_view_timing/aggregate/index.js +3 -1
- package/dist/esm/features/session_trace/aggregate/index.js +5 -4
- package/dist/esm/features/utils/agent-session.js +3 -4
- package/dist/esm/features/utils/aggregate-base.js +4 -6
- package/dist/esm/features/utils/feature-base.js +6 -7
- package/dist/esm/features/utils/instrument-base.js +7 -8
- package/dist/esm/loaders/api/register-api-types.js +1 -1
- package/dist/esm/loaders/api/register.js +1 -1
- package/dist/esm/loaders/api/sharedHandlers.js +2 -4
- package/dist/esm/loaders/configure/configure.js +24 -21
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/common/config/configurable.d.ts.map +1 -1
- package/dist/types/common/config/runtime.d.ts.map +1 -1
- package/dist/types/common/constants/runtime.d.ts +1 -1
- package/dist/types/common/constants/runtime.d.ts.map +1 -1
- package/dist/types/common/drain/drain.d.ts +6 -6
- package/dist/types/common/drain/drain.d.ts.map +1 -1
- package/dist/types/common/harvest/harvester.d.ts.map +1 -1
- package/dist/types/common/session/session-entity.d.ts +2 -2
- package/dist/types/common/session/session-entity.d.ts.map +1 -1
- package/dist/types/common/util/console.d.ts.map +1 -1
- package/dist/types/common/util/feature-flags.d.ts +3 -5
- package/dist/types/common/util/feature-flags.d.ts.map +1 -1
- package/dist/types/common/util/script-tracker.d.ts +5 -0
- package/dist/types/common/util/script-tracker.d.ts.map +1 -1
- package/dist/types/common/util/stringify.d.ts.map +1 -1
- package/dist/types/features/jserrors/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/page_view_event/aggregate/initialized-features.d.ts +2 -2
- package/dist/types/features/page_view_event/aggregate/initialized-features.d.ts.map +1 -1
- package/dist/types/features/page_view_event/instrument/index.d.ts +1 -1
- package/dist/types/features/page_view_event/instrument/index.d.ts.map +1 -1
- package/dist/types/features/page_view_timing/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/session_trace/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/utils/agent-session.d.ts.map +1 -1
- package/dist/types/features/utils/aggregate-base.d.ts +0 -1
- package/dist/types/features/utils/aggregate-base.d.ts.map +1 -1
- package/dist/types/features/utils/feature-base.d.ts +3 -3
- package/dist/types/features/utils/feature-base.d.ts.map +1 -1
- package/dist/types/features/utils/instrument-base.d.ts +2 -3
- package/dist/types/features/utils/instrument-base.d.ts.map +1 -1
- package/dist/types/loaders/api/register-api-types.d.ts +1 -1
- package/dist/types/loaders/api/register-api-types.d.ts.map +1 -1
- package/dist/types/loaders/api/sharedHandlers.d.ts.map +1 -1
- package/dist/types/loaders/configure/configure.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/common/config/configurable.js +2 -1
- package/src/common/config/runtime.js +8 -2
- package/src/common/constants/runtime.js +16 -2
- package/src/common/deny-list/deny-list.js +2 -2
- package/src/common/drain/__mocks__/drain.js +2 -1
- package/src/common/drain/drain.js +27 -37
- package/src/common/harvest/harvester.js +1 -3
- package/src/common/session/session-entity.js +7 -8
- package/src/common/util/console.js +1 -2
- package/src/common/util/feature-flags.js +5 -17
- package/src/common/util/script-tracker.js +23 -5
- package/src/common/util/stringify.js +24 -7
- package/src/common/vitals/largest-contentful-paint.js +0 -1
- package/src/common/vitals/load-time.js +4 -3
- package/src/common/vitals/time-to-first-byte.js +3 -3
- package/src/features/jserrors/aggregate/index.js +0 -4
- package/src/features/page_view_event/aggregate/index.js +4 -4
- package/src/features/page_view_event/aggregate/initialized-features.js +3 -5
- package/src/features/page_view_event/instrument/index.js +3 -5
- package/src/features/page_view_timing/aggregate/index.js +4 -1
- package/src/features/session_trace/aggregate/index.js +5 -4
- package/src/features/utils/__mocks__/feature-base.js +3 -3
- package/src/features/utils/agent-session.js +3 -4
- package/src/features/utils/aggregate-base.js +4 -6
- package/src/features/utils/feature-base.js +6 -7
- package/src/features/utils/instrument-base.js +7 -9
- package/src/loaders/api/register-api-types.js +1 -1
- package/src/loaders/api/register.js +1 -1
- package/src/loaders/api/sharedHandlers.js +2 -4
- package/src/loaders/configure/configure.js +30 -26
- package/dist/cjs/features/utils/nr1-debugger.js +0 -30
- package/dist/esm/features/utils/nr1-debugger.js +0 -23
- package/dist/types/features/utils/nr1-debugger.d.ts +0 -2
- package/dist/types/features/utils/nr1-debugger.d.ts.map +0 -1
- package/src/features/utils/nr1-debugger.js +0 -26
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,22 @@
|
|
|
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.311.0](https://github.com/newrelic/newrelic-browser-agent/compare/v1.310.1...v1.311.0) (2026-03-20)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* agentIdentifier removal ([#1712](https://github.com/newrelic/newrelic-browser-agent/issues/1712)) ([d9f6711](https://github.com/newrelic/newrelic-browser-agent/commit/d9f6711e4f1073b1e7713fe7966721fd6b31b864))
|
|
12
|
+
* Attribute original page URL to all PageViewTiming nodes ([#1716](https://github.com/newrelic/newrelic-browser-agent/issues/1716)) ([847b6a7](https://github.com/newrelic/newrelic-browser-agent/commit/847b6a72650a113fdf2f074a6a057ac601aafb02))
|
|
13
|
+
* improve MFE timing logic ([#1714](https://github.com/newrelic/newrelic-browser-agent/issues/1714)) ([9a3ef06](https://github.com/newrelic/newrelic-browser-agent/commit/9a3ef06652a36a05b950f9154969a767fa3b731e))
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
### Bug Fixes
|
|
17
|
+
|
|
18
|
+
* Circular replacer removed reused objects from harvests ([#1718](https://github.com/newrelic/newrelic-browser-agent/issues/1718)) ([76024d0](https://github.com/newrelic/newrelic-browser-agent/commit/76024d0f3465db42ddaa297d0f87a9e21f2f9b03))
|
|
19
|
+
* Enforce string IDs for new MFE registrations ([#1725](https://github.com/newrelic/newrelic-browser-agent/issues/1725)) ([38fae07](https://github.com/newrelic/newrelic-browser-agent/commit/38fae0758645c5f0cd26f7067be973f7ee807819))
|
|
20
|
+
* Update RegExp to prevent un-minimized webpack build issue ([#1711](https://github.com/newrelic/newrelic-browser-agent/issues/1711)) ([1a2408f](https://github.com/newrelic/newrelic-browser-agent/commit/1a2408f15c8ae96396cf3597058a5d18fa5cb4fd))
|
|
21
|
+
|
|
6
22
|
## [1.310.1](https://github.com/newrelic/newrelic-browser-agent/compare/v1.310.0...v1.310.1) (2026-02-19)
|
|
7
23
|
|
|
8
24
|
|
|
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.getModeledObject = getModeledObject;
|
|
7
7
|
var _console = require("../util/console");
|
|
8
8
|
/**
|
|
9
|
-
* Copyright 2020-
|
|
9
|
+
* Copyright 2020-2026 New Relic, Inc. All rights reserved.
|
|
10
10
|
* SPDX-License-Identifier: Apache-2.0
|
|
11
11
|
*/
|
|
12
12
|
|
|
@@ -24,7 +24,7 @@ function getModeledObject(obj, model) {
|
|
|
24
24
|
output[key] = null;
|
|
25
25
|
continue;
|
|
26
26
|
}
|
|
27
|
-
if (Array.isArray(obj[key]) && Array.isArray(model[key])) output[key] = Array.from(new Set([...obj[key], ...model[key]]));else if (typeof obj[key] === 'object' && typeof model[key] === 'object') output[key] = getModeledObject(obj[key], model[key]);else output[key] = obj[key];
|
|
27
|
+
if (Array.isArray(obj[key]) && Array.isArray(model[key])) output[key] = Array.from(new Set([...obj[key], ...model[key]]));else if (obj[key] instanceof Map || obj[key] instanceof Set || obj[key] instanceof Date || obj[key] instanceof RegExp) output[key] = obj[key];else if (typeof obj[key] === 'object' && typeof model[key] === 'object') output[key] = getModeledObject(obj[key], model[key]);else output[key] = obj[key];
|
|
28
28
|
} catch (e) {
|
|
29
29
|
if (!output[key]) (0, _console.warn)(1, e);
|
|
30
30
|
}
|
|
@@ -8,7 +8,7 @@ var _configurable = require("./configurable");
|
|
|
8
8
|
var _runtime = require("../constants/runtime");
|
|
9
9
|
var _env = require("../constants/env.npm");
|
|
10
10
|
/**
|
|
11
|
-
* Copyright 2020-
|
|
11
|
+
* Copyright 2020-2026 New Relic, Inc. All rights reserved.
|
|
12
12
|
* SPDX-License-Identifier: Apache-2.0
|
|
13
13
|
*/
|
|
14
14
|
|
|
@@ -27,8 +27,12 @@ const hiddenState = {
|
|
|
27
27
|
consented: false
|
|
28
28
|
};
|
|
29
29
|
const RuntimeModel = {
|
|
30
|
+
/** @type {{[key: string]: number} | undefined} */
|
|
31
|
+
activatedFeatures: undefined,
|
|
30
32
|
/** Agent-specific metadata found in the RUM call response. ex. entityGuid */
|
|
31
33
|
appMetadata: {},
|
|
34
|
+
/** @type {boolean} */
|
|
35
|
+
configured: false,
|
|
32
36
|
get consented() {
|
|
33
37
|
return this.session?.state?.consent || hiddenState.consented;
|
|
34
38
|
},
|
|
@@ -36,8 +40,10 @@ const RuntimeModel = {
|
|
|
36
40
|
hiddenState.consented = value;
|
|
37
41
|
},
|
|
38
42
|
customTransaction: undefined,
|
|
39
|
-
denyList:
|
|
43
|
+
denyList: [],
|
|
40
44
|
disabled: false,
|
|
45
|
+
/** @type {Map<string, {staged: boolean, priority: number}>} */
|
|
46
|
+
drainRegistry: new Map(),
|
|
41
47
|
harvester: undefined,
|
|
42
48
|
isolatedBacklog: false,
|
|
43
49
|
isRecording: false,
|
|
@@ -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.311.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.311.0-rc.1";
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
23
|
* Exposes the build type of the agent
|
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.
|
|
6
|
+
exports.originTime = exports.loadedAsDeferredBrowserScript = exports.isiOS = exports.isWorkerScope = exports.isBrowserScope = exports.initiallyHidden = exports.initialLocation = exports.iOSBelow16 = exports.globalScope = exports.getNavigationEntry = exports.ffVersion = void 0;
|
|
7
7
|
var _now = require("../timing/now");
|
|
8
8
|
/**
|
|
9
|
-
* Copyright 2020-
|
|
9
|
+
* Copyright 2020-2026 New Relic, Inc. All rights reserved.
|
|
10
10
|
* SPDX-License-Identifier: Apache-2.0
|
|
11
11
|
*/
|
|
12
12
|
|
|
@@ -54,5 +54,18 @@ const ffVersion = exports.ffVersion = (() => {
|
|
|
54
54
|
* @type {number}
|
|
55
55
|
*/
|
|
56
56
|
const originTime = exports.originTime = Date.now() - (0, _now.now)();
|
|
57
|
-
|
|
58
|
-
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Gets the first navigation entry from the Performance Timeline API.
|
|
60
|
+
* Returns undefined if the entry is not available or invalid.
|
|
61
|
+
* Matches web-vitals validation: checks that responseStart exists, is positive, and is not larger than current time.
|
|
62
|
+
* See: https://github.com/GoogleChrome/web-vitals/issues/137
|
|
63
|
+
* @returns {PerformanceNavigationTiming | undefined}
|
|
64
|
+
*/
|
|
65
|
+
const getNavigationEntry = () => {
|
|
66
|
+
const navigationEntry = globalScope?.performance?.getEntriesByType?.('navigation')?.[0];
|
|
67
|
+
if (navigationEntry && navigationEntry.responseStart > 0 && navigationEntry.responseStart < globalScope.performance.now()) {
|
|
68
|
+
return navigationEntry;
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
exports.getNavigationEntry = getNavigationEntry;
|
|
@@ -7,7 +7,7 @@ exports.hasUndefinedHostname = hasUndefinedHostname;
|
|
|
7
7
|
exports.setDenyList = setDenyList;
|
|
8
8
|
exports.shouldCollectEvent = shouldCollectEvent;
|
|
9
9
|
/**
|
|
10
|
-
* Copyright 2020-
|
|
10
|
+
* Copyright 2020-2026 New Relic, Inc. All rights reserved.
|
|
11
11
|
* SPDX-License-Identifier: Apache-2.0
|
|
12
12
|
*/
|
|
13
13
|
|
|
@@ -92,5 +92,5 @@ function setDenyList(denyListConfig) {
|
|
|
92
92
|
function convertToRegularExpression(filter, isPathname = false) {
|
|
93
93
|
const newFilter = filter.replace(/[.+?^${}()|[\]\\]/g, m => '\\' + m) // use a replacer function to not break apm injection
|
|
94
94
|
.replace(/\*/g, '.*?'); // use lazy matching instead of greedy
|
|
95
|
-
return new RegExp((isPathname ? '^' : '') + newFilter + '
|
|
95
|
+
return new RegExp((isPathname ? '^' : '') + newFilter + '\x24'); // x24 == $, but using a literal $ causes webpack to to break when building unminified
|
|
96
96
|
}
|
|
@@ -7,7 +7,6 @@ exports.deregisterDrain = deregisterDrain;
|
|
|
7
7
|
exports.drain = drain;
|
|
8
8
|
exports.registerDrain = registerDrain;
|
|
9
9
|
var _globalEvent = require("../../common/dispatch/global-event");
|
|
10
|
-
var _contextualEe = require("../event-emitter/contextual-ee");
|
|
11
10
|
var _registerHandler = require("../event-emitter/register-handler");
|
|
12
11
|
var _features = require("../../loaders/features/features");
|
|
13
12
|
var _eventContext = require("../event-emitter/event-context");
|
|
@@ -16,78 +15,69 @@ var _eventContext = require("../event-emitter/event-context");
|
|
|
16
15
|
* SPDX-License-Identifier: Apache-2.0
|
|
17
16
|
*/
|
|
18
17
|
|
|
19
|
-
const registry = {};
|
|
20
|
-
|
|
21
18
|
/**
|
|
22
19
|
* Adds an entry to the centralized drain registry specifying that a particular agent has events of a particular named
|
|
23
20
|
* event-group "bucket" that should be drained at the time the agent drains all its buffered events. Buffered events
|
|
24
21
|
* accumulate because instrumentation begins as soon as possible, before the agent has finished lazy-loading the code
|
|
25
22
|
* responsible for aggregating and reporting captured data.
|
|
26
|
-
* @param {
|
|
23
|
+
* @param {Object} agentRef - The agent reference object.
|
|
27
24
|
* @param {string} group - The named "bucket" for the events this feature will be bucketing for later collection.
|
|
28
25
|
*/
|
|
29
|
-
function registerDrain(
|
|
26
|
+
function registerDrain(agentRef, group) {
|
|
27
|
+
if (!agentRef) return;
|
|
30
28
|
// Here `item` captures the registered properties of a feature-group: whether it is ready for its buffered events
|
|
31
29
|
// to be drained (`staged`) and the `priority` order in which it should be drained relative to other feature groups.
|
|
32
30
|
const item = {
|
|
33
31
|
staged: false,
|
|
34
32
|
priority: _features.featurePriority[group] || 0
|
|
35
33
|
};
|
|
36
|
-
|
|
37
|
-
if (!registry[agentIdentifier].get(group)) registry[agentIdentifier].set(group, item);
|
|
34
|
+
if (!agentRef.runtime.drainRegistry.get(group)) agentRef.runtime.drainRegistry.set(group, item);
|
|
38
35
|
}
|
|
39
36
|
|
|
40
37
|
/**
|
|
41
38
|
* Removes an item from the registry and immediately re-checks if the registry is ready to "drain all"
|
|
42
|
-
* @param {
|
|
39
|
+
* @param {Object} agentRef - The agent reference object.
|
|
43
40
|
* @param {*} group - The named "bucket" to be removed from the registry
|
|
44
41
|
*/
|
|
45
|
-
function deregisterDrain(
|
|
46
|
-
if (!
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
if (
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Registers the specified agent with the centralized event buffer registry if it is not already registered.
|
|
54
|
-
* Agents without an identifier (as in the case of some tests) will be excluded from the registry.
|
|
55
|
-
* @param {string} agentIdentifier - A 16 character string uniquely identifying an agent.
|
|
56
|
-
*/
|
|
57
|
-
function curateRegistry(agentIdentifier) {
|
|
58
|
-
if (!agentIdentifier) throw new Error('agentIdentifier required');
|
|
59
|
-
if (!registry[agentIdentifier]) registry[agentIdentifier] = new Map();
|
|
42
|
+
function deregisterDrain(agentRef, group) {
|
|
43
|
+
if (!agentRef) return;
|
|
44
|
+
const drainRegistry = agentRef.runtime.drainRegistry;
|
|
45
|
+
if (!drainRegistry) return;
|
|
46
|
+
if (drainRegistry.get(group)) drainRegistry.delete(group);
|
|
47
|
+
drainGroup(agentRef, group, false);
|
|
48
|
+
if (drainRegistry.size) checkCanDrainAll(agentRef);
|
|
60
49
|
}
|
|
61
50
|
|
|
62
51
|
/**
|
|
63
52
|
* Drain buffered events out of the event emitter. Each feature should have its events bucketed by "group" and drain
|
|
64
53
|
* its own named group explicitly, when ready.
|
|
65
|
-
* @param {
|
|
54
|
+
* @param {Object} agentRef - The agent reference object.
|
|
66
55
|
* @param {string} featureName - A named group into which the feature's buffered events are bucketed.
|
|
67
56
|
* @param {boolean} force - Whether to force the drain to occur immediately, bypassing the registry and staging logic.
|
|
68
57
|
*/
|
|
69
|
-
function drain(
|
|
70
|
-
|
|
58
|
+
function drain(agentRef, featureName = 'feature', force = false) {
|
|
59
|
+
if (!agentRef) return;
|
|
71
60
|
// If the feature for the specified agent is not in the registry, that means the instrument file was bypassed.
|
|
72
61
|
// This could happen in tests, or loaders that directly import the aggregator. In these cases it is safe to
|
|
73
62
|
// drain the feature group immediately rather than waiting to drain all at once.
|
|
74
|
-
if (!
|
|
63
|
+
if (!agentRef.runtime.drainRegistry.get(featureName) || force) return drainGroup(agentRef, featureName);
|
|
75
64
|
|
|
76
65
|
// When `drain` is called, this feature is ready to drain (staged).
|
|
77
|
-
|
|
78
|
-
checkCanDrainAll(
|
|
66
|
+
agentRef.runtime.drainRegistry.get(featureName).staged = true;
|
|
67
|
+
checkCanDrainAll(agentRef);
|
|
79
68
|
}
|
|
80
69
|
|
|
81
70
|
/** Checks all items in the registry to see if they have been "staged". If ALL items are staged, it will drain all registry items (drainGroup). It not, nothing will happen */
|
|
82
|
-
function checkCanDrainAll(
|
|
71
|
+
function checkCanDrainAll(agentRef) {
|
|
72
|
+
if (!agentRef) return;
|
|
83
73
|
// Only when the event-groups for all features are ready to drain (staged) do we execute the drain. This has the effect
|
|
84
74
|
// that the last feature to call drain triggers drain for all features.
|
|
85
|
-
const items = Array.from(
|
|
75
|
+
const items = Array.from(agentRef.runtime.drainRegistry);
|
|
86
76
|
if (items.every(([key, values]) => values.staged)) {
|
|
87
77
|
items.sort((a, b) => a[1].priority - b[1].priority);
|
|
88
78
|
items.forEach(([group]) => {
|
|
89
|
-
|
|
90
|
-
drainGroup(
|
|
79
|
+
agentRef.runtime.drainRegistry.delete(group);
|
|
80
|
+
drainGroup(agentRef, group);
|
|
91
81
|
});
|
|
92
82
|
}
|
|
93
83
|
}
|
|
@@ -97,12 +87,12 @@ function checkCanDrainAll(agentIdentifier) {
|
|
|
97
87
|
* the subscribed handlers for the group.
|
|
98
88
|
* @param {*} group - The name of a particular feature's event "bucket".
|
|
99
89
|
*/
|
|
100
|
-
function drainGroup(
|
|
101
|
-
|
|
90
|
+
function drainGroup(agentRef, group, activateGroup = true) {
|
|
91
|
+
if (!agentRef) return;
|
|
92
|
+
const baseEE = agentRef.ee;
|
|
102
93
|
const handlers = _registerHandler.registerHandler.handlers; // other storage in registerHandler
|
|
103
|
-
if (baseEE.aborted || !baseEE.backlog || !handlers) return;
|
|
94
|
+
if (!baseEE || baseEE.aborted || !baseEE.backlog || !handlers) return;
|
|
104
95
|
(0, _globalEvent.dispatchGlobalEvent)({
|
|
105
|
-
agentIdentifier,
|
|
106
96
|
type: 'lifecycle',
|
|
107
97
|
name: 'drain',
|
|
108
98
|
feature: group
|
|
@@ -18,7 +18,6 @@ var _encode = require("../url/encode");
|
|
|
18
18
|
var _console = require("../util/console");
|
|
19
19
|
var _stringify = require("../util/stringify");
|
|
20
20
|
var _submitData = require("../util/submit-data");
|
|
21
|
-
var _featureFlags = require("../util/feature-flags");
|
|
22
21
|
var _globalEvent = require("../dispatch/global-event");
|
|
23
22
|
/**
|
|
24
23
|
* Copyright 2020-2026 New Relic, Inc. All rights reserved.
|
|
@@ -237,8 +236,7 @@ function send(agentRef, {
|
|
|
237
236
|
}
|
|
238
237
|
}
|
|
239
238
|
(0, _globalEvent.dispatchGlobalEvent)({
|
|
240
|
-
|
|
241
|
-
drained: !!_featureFlags.activatedFeatures?.[agentRef.agentIdentifier],
|
|
239
|
+
drained: !!agentRef.runtime?.activatedFeatures,
|
|
242
240
|
type: 'data',
|
|
243
241
|
name: 'harvest',
|
|
244
242
|
feature: featureName,
|
|
@@ -7,7 +7,6 @@ exports.SessionEntity = void 0;
|
|
|
7
7
|
var _uniqueId = require("../ids/unique-id");
|
|
8
8
|
var _console = require("../util/console");
|
|
9
9
|
var _stringify = require("../util/stringify");
|
|
10
|
-
var _contextualEe = require("../event-emitter/contextual-ee");
|
|
11
10
|
var _timer = require("../timer/timer");
|
|
12
11
|
var _runtime = require("../constants/runtime");
|
|
13
12
|
var _constants = require("./constants");
|
|
@@ -45,27 +44,27 @@ const model = {
|
|
|
45
44
|
};
|
|
46
45
|
class SessionEntity {
|
|
47
46
|
/**
|
|
48
|
-
* Create a self-managing Session Entity. This entity is scoped to the agent
|
|
47
|
+
* Create a self-managing Session Entity. This entity is scoped to the agent which triggered it, allowing for multiple simultaneous session objects to exist.
|
|
49
48
|
* There is one "namespace" an agent can store data in LS -- NRBA_{key}. If there are two agents on one page, and they both use the same key, they could overwrite each other since they would both use the same namespace in LS by default.
|
|
50
49
|
* The value can be overridden in the constructor, but will default to a unique 16 character hex string
|
|
51
50
|
* expiresMs and inactiveMs are used to "expire" the session, but can be overridden in the constructor. Pass 0 to disable expiration timers.
|
|
52
51
|
*/
|
|
53
52
|
constructor(opts) {
|
|
54
53
|
const {
|
|
55
|
-
|
|
54
|
+
agentRef,
|
|
56
55
|
key,
|
|
57
56
|
storage
|
|
58
57
|
} = opts;
|
|
59
|
-
if (!
|
|
60
|
-
throw new Error("Missing required field(s):".concat(!
|
|
58
|
+
if (!agentRef || !key || !storage) {
|
|
59
|
+
throw new Error("Missing required field(s):".concat(!agentRef ? ' agentRef' : '').concat(!key ? ' key' : '').concat(!storage ? ' storage' : ''));
|
|
61
60
|
}
|
|
62
|
-
this.
|
|
61
|
+
this.agentRef = agentRef;
|
|
63
62
|
this.storage = storage;
|
|
64
63
|
this.state = {};
|
|
65
64
|
|
|
66
65
|
// key is intended to act as the k=v pair
|
|
67
66
|
this.key = key;
|
|
68
|
-
this.ee =
|
|
67
|
+
this.ee = agentRef.ee;
|
|
69
68
|
(0, _wrapEvents.wrapEvents)(this.ee);
|
|
70
69
|
this.setup(opts);
|
|
71
70
|
|
|
@@ -253,7 +252,7 @@ class SessionEntity {
|
|
|
253
252
|
this.expiresTimer?.clear?.();
|
|
254
253
|
delete this.isNew;
|
|
255
254
|
this.setup({
|
|
256
|
-
|
|
255
|
+
agentRef: this.agentRef,
|
|
257
256
|
key: this.key,
|
|
258
257
|
storage: this.storage,
|
|
259
258
|
expiresMs: this.expiresMs,
|
|
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.warn = warn;
|
|
7
7
|
var _globalEvent = require("../dispatch/global-event");
|
|
8
8
|
/**
|
|
9
|
-
* Copyright 2020-
|
|
9
|
+
* Copyright 2020-2026 New Relic, Inc. All rights reserved.
|
|
10
10
|
* SPDX-License-Identifier: Apache-2.0
|
|
11
11
|
*/
|
|
12
12
|
|
|
@@ -22,7 +22,6 @@ function warn(code, secondary) {
|
|
|
22
22
|
if (typeof console.debug !== 'function') return;
|
|
23
23
|
console.debug("New Relic Warning: https://github.com/newrelic/newrelic-browser-agent/blob/main/docs/warning-codes.md#".concat(code), secondary);
|
|
24
24
|
(0, _globalEvent.dispatchGlobalEvent)({
|
|
25
|
-
agentIdentifier: null,
|
|
26
25
|
drained: null,
|
|
27
26
|
type: 'data',
|
|
28
27
|
name: 'warn',
|
|
@@ -4,37 +4,26 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.activateFeatures = activateFeatures;
|
|
7
|
-
exports.activatedFeatures = void 0;
|
|
8
7
|
var _globalEvent = require("../dispatch/global-event");
|
|
9
8
|
/**
|
|
10
|
-
* Copyright 2020-
|
|
9
|
+
* Copyright 2020-2026 New Relic, Inc. All rights reserved.
|
|
11
10
|
* SPDX-License-Identifier: Apache-2.0
|
|
12
11
|
*/
|
|
13
12
|
|
|
14
|
-
const sentIds = new Set();
|
|
15
|
-
|
|
16
|
-
/** A map of feature flags and their values as provided by the rum call -- scoped by agent ID */
|
|
17
|
-
const activatedFeatures = exports.activatedFeatures = {};
|
|
18
|
-
|
|
19
13
|
/**
|
|
20
|
-
* Sets the activatedFeatures
|
|
14
|
+
* Sets the activatedFeatures on the agentRef, dispatches the global loaded event,
|
|
21
15
|
* and emits the rumresp flag to features
|
|
22
16
|
* @param {{[key:string]:number}} flags key-val pair of flag names and numeric
|
|
23
|
-
* @param {
|
|
17
|
+
* @param {Object} agentRef agent reference
|
|
24
18
|
* @returns {void}
|
|
25
19
|
*/
|
|
26
20
|
function activateFeatures(flags, agentRef) {
|
|
27
|
-
|
|
28
|
-
activatedFeatures[agentIdentifier] ??= {};
|
|
29
|
-
if (!flags || typeof flags !== 'object') return;
|
|
30
|
-
if (sentIds.has(agentIdentifier)) return;
|
|
21
|
+
if (!flags || typeof flags !== 'object' || !!agentRef.runtime.activatedFeatures) return;
|
|
31
22
|
agentRef.ee.emit('rumresp', [flags]);
|
|
32
|
-
activatedFeatures
|
|
33
|
-
sentIds.add(agentIdentifier);
|
|
23
|
+
agentRef.runtime.activatedFeatures = flags;
|
|
34
24
|
|
|
35
25
|
// let any window level subscribers know that the agent is running, per install docs
|
|
36
26
|
(0, _globalEvent.dispatchGlobalEvent)({
|
|
37
|
-
agentIdentifier,
|
|
38
27
|
loaded: true,
|
|
39
28
|
drained: true,
|
|
40
29
|
type: 'lifecycle',
|
|
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.findScriptTimings = findScriptTimings;
|
|
7
|
+
exports.thisFile = void 0;
|
|
7
8
|
var _runtime = require("../constants/runtime");
|
|
8
9
|
var _now = require("../timing/now");
|
|
9
10
|
var _cleanUrl = require("../url/clean-url");
|
|
@@ -17,8 +18,16 @@ var _browserStackMatchers = require("./browser-stack-matchers");
|
|
|
17
18
|
* @typedef {import('./register-api-types').RegisterAPITimings} RegisterAPITimings
|
|
18
19
|
*/
|
|
19
20
|
|
|
21
|
+
/** export for testing purposes */
|
|
22
|
+
let thisFile = exports.thisFile = void 0;
|
|
23
|
+
try {
|
|
24
|
+
exports.thisFile = thisFile = extractUrlsFromStack(getDeepStackTrace()).at(0);
|
|
25
|
+
} catch (err) {
|
|
26
|
+
exports.thisFile = thisFile = extractUrlsFromStack(err).at(0);
|
|
27
|
+
}
|
|
28
|
+
|
|
20
29
|
/** @type {(entry: PerformanceEntry) => boolean} - A shared function to determine if a performance entry is a valid script or link resource for evaluation */
|
|
21
|
-
const validEntryCriteria = entry => entry.initiatorType === 'script' || entry.initiatorType
|
|
30
|
+
const validEntryCriteria = entry => entry.initiatorType === 'script' || ['link', 'fetch'].includes(entry.initiatorType) && entry.name.endsWith('.js');
|
|
22
31
|
|
|
23
32
|
/** @type {Set<PerformanceResourceTiming>} - A set of resource timing objects that are "valid" -- see "validEntryCriteria" */
|
|
24
33
|
const scripts = new Set();
|
|
@@ -62,9 +71,15 @@ function extractUrlsFromStack(stack) {
|
|
|
62
71
|
const lines = stack.split('\n');
|
|
63
72
|
for (const line of lines) {
|
|
64
73
|
// Try gecko format first, then chrome
|
|
65
|
-
const parts = line.match(_browserStackMatchers.gecko) || line.match(_browserStackMatchers.chrome);
|
|
74
|
+
const parts = line.match(_browserStackMatchers.gecko) || line.match(_browserStackMatchers.chrome) || line.match(_browserStackMatchers.chromeEval);
|
|
66
75
|
if (parts && parts[2]) {
|
|
67
76
|
urls.add((0, _cleanUrl.cleanURL)(parts[2]));
|
|
77
|
+
} else {
|
|
78
|
+
// Fallback: match URLs using a generic .js pattern (non-greedy to handle ports and query params)
|
|
79
|
+
const fallbackMatch = line.match(/\(([^)]+\.js):\d+:\d+\)/) || line.match(/^\s+at\s+([^\s(]+\.js):\d+:\d+/);
|
|
80
|
+
if (fallbackMatch && fallbackMatch[1]) {
|
|
81
|
+
urls.add((0, _cleanUrl.cleanURL)(fallbackMatch[1]));
|
|
82
|
+
}
|
|
68
83
|
}
|
|
69
84
|
}
|
|
70
85
|
return [...urls];
|
|
@@ -121,9 +136,11 @@ function findScriptTimings() {
|
|
|
121
136
|
};
|
|
122
137
|
const stack = getDeepStackTrace();
|
|
123
138
|
if (!stack) return timings;
|
|
124
|
-
const navUrl = _runtime.globalScope.performance?.getEntriesByType('navigation')?.
|
|
139
|
+
const navUrl = _runtime.globalScope.performance?.getEntriesByType('navigation')?.[0]?.name || '';
|
|
125
140
|
try {
|
|
126
|
-
const
|
|
141
|
+
const urls = extractUrlsFromStack(stack);
|
|
142
|
+
/** if there is exactly one url, this means the MFE script is running in the same file as the agent. Otherwise, lets strip away the known agent file from any other file lines */
|
|
143
|
+
const mfeScriptUrl = (urls.length > 1 ? urls.filter(line => !thisFile.endsWith(line) && !line.endsWith(thisFile)) : urls).at(0);
|
|
127
144
|
if (!mfeScriptUrl) return timings;
|
|
128
145
|
if (navUrl.includes(mfeScriptUrl)) {
|
|
129
146
|
// this means the stack is indicating that the registration came from an inline script or eval, so we won't find a matching script resource - return early with just the URL
|
|
@@ -143,6 +160,7 @@ function findScriptTimings() {
|
|
|
143
160
|
if (wasPreloaded(mfeScriptUrl)) {
|
|
144
161
|
timings.asset = mfeScriptUrl;
|
|
145
162
|
timings.type = 'preload';
|
|
163
|
+
|
|
146
164
|
// wait for a late PO callback... The timings object can be mutated after the fact since we return a pointer and not a cloned object
|
|
147
165
|
poSubscribers.push({
|
|
148
166
|
addedAt: (0, _now.now)(),
|
|
@@ -6,23 +6,38 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.stringify = stringify;
|
|
7
7
|
var _contextualEe = require("../event-emitter/contextual-ee");
|
|
8
8
|
/**
|
|
9
|
-
* Copyright 2020-
|
|
9
|
+
* Copyright 2020-2026 New Relic, Inc. All rights reserved.
|
|
10
10
|
* SPDX-License-Identifier: Apache-2.0
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* Returns a function for use as a replacer parameter in JSON.stringify() to handle circular references.
|
|
15
|
+
* Uses an array to track the current ancestor chain, allowing the same object to appear
|
|
16
|
+
* multiple times in the structure as long as it's not a circular reference.
|
|
15
17
|
* @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Cyclic_object_value MDN - Cyclical object value}
|
|
16
|
-
* @returns {Function} A function that filters out
|
|
18
|
+
* @returns {Function} A function that filters out circular references while allowing duplicate references.
|
|
17
19
|
*/
|
|
18
20
|
const getCircularReplacer = () => {
|
|
19
|
-
const
|
|
20
|
-
return (key, value)
|
|
21
|
-
if (
|
|
22
|
-
|
|
21
|
+
const stack = [];
|
|
22
|
+
return function (key, value) {
|
|
23
|
+
if (stack.length > 0) {
|
|
24
|
+
// Find where we are in the stack
|
|
25
|
+
const thisPos = stack.indexOf(this);
|
|
26
|
+
if (~thisPos) {
|
|
27
|
+
// We're still in the stack, trim it
|
|
28
|
+
stack.splice(thisPos + 1);
|
|
29
|
+
} else {
|
|
30
|
+
// We're not in the stack, add ourselves
|
|
31
|
+
stack.push(this);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Check if value is in the current ancestor chain
|
|
35
|
+
if (~stack.indexOf(value)) {
|
|
23
36
|
return;
|
|
24
37
|
}
|
|
25
|
-
|
|
38
|
+
} else {
|
|
39
|
+
// First call, initialize with root
|
|
40
|
+
stack.push(value);
|
|
26
41
|
}
|
|
27
42
|
return value;
|
|
28
43
|
};
|
|
@@ -37,7 +37,6 @@ if (_runtime.isBrowserScope) {
|
|
|
37
37
|
if (lcpEntry.element?.tagName) attrs.elTag = lcpEntry.element.tagName;
|
|
38
38
|
}
|
|
39
39
|
if (attribution.element) attrs.element = attribution.element;
|
|
40
|
-
if (attribution.navigationEntry) attrs.pageUrl = (0, _cleanUrl.cleanURL)(attribution.navigationEntry.name); // used to ensure the LCP gets the correct URL at harvest time if a soft nav has occurred before page load
|
|
41
40
|
if (attribution.url) attrs.elUrl = (0, _cleanUrl.cleanURL)(attribution.url);
|
|
42
41
|
largestContentfulPaint.update({
|
|
43
42
|
value,
|
|
@@ -9,7 +9,7 @@ var _load = require("../window/load");
|
|
|
9
9
|
var _constants = require("./constants");
|
|
10
10
|
var _vitalMetric = require("./vital-metric");
|
|
11
11
|
/**
|
|
12
|
-
* Copyright 2020-
|
|
12
|
+
* Copyright 2020-2026 New Relic, Inc. All rights reserved.
|
|
13
13
|
* SPDX-License-Identifier: Apache-2.0
|
|
14
14
|
*/
|
|
15
15
|
|
|
@@ -18,8 +18,9 @@ if (_runtime.isBrowserScope) {
|
|
|
18
18
|
const perf = _runtime.globalScope.performance;
|
|
19
19
|
const handler = () => {
|
|
20
20
|
if (!loadTime.isValid && perf) {
|
|
21
|
+
const navEntry = (0, _runtime.getNavigationEntry)();
|
|
21
22
|
loadTime.update({
|
|
22
|
-
value:
|
|
23
|
+
value: navEntry ? navEntry.loadEventEnd : perf.timing?.loadEventEnd - _runtime.originTime
|
|
23
24
|
});
|
|
24
25
|
}
|
|
25
26
|
};
|
|
@@ -9,7 +9,7 @@ var _constants = require("./constants");
|
|
|
9
9
|
var _vitalMetric = require("./vital-metric");
|
|
10
10
|
var _attribution = require("web-vitals/attribution");
|
|
11
11
|
/**
|
|
12
|
-
* Copyright 2020-
|
|
12
|
+
* Copyright 2020-2026 New Relic, Inc. All rights reserved.
|
|
13
13
|
* SPDX-License-Identifier: Apache-2.0
|
|
14
14
|
*/
|
|
15
15
|
|
|
@@ -23,7 +23,7 @@ const timeToFirstByte = exports.timeToFirstByte = new _vitalMetric.VitalMetric(_
|
|
|
23
23
|
* - cross-origin iframes specifically in firefox and safari
|
|
24
24
|
* - onTTFB relies on a truthy `responseStart` value, should ensure that exists before relying on it (seen to be falsy in certain Electron.js cases for instance)
|
|
25
25
|
*/
|
|
26
|
-
if (_runtime.isBrowserScope && (0, _runtime.
|
|
26
|
+
if (_runtime.isBrowserScope && (0, _runtime.getNavigationEntry)() && !_runtime.isiOS && window === window.parent) {
|
|
27
27
|
(0, _attribution.onTTFB)(({
|
|
28
28
|
value,
|
|
29
29
|
attribution
|
|
@@ -180,10 +180,6 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
180
180
|
if (!target) (0, _handle.handle)('trace-jserror', jsErrorEvent, undefined, _features.FEATURE_NAMES.sessionTrace, this.ee);
|
|
181
181
|
// still send EE events for other features such as above, but stop this one from aggregating internal data
|
|
182
182
|
if (this.blocked) return;
|
|
183
|
-
if (err.__newrelic?.[this.agentIdentifier]) {
|
|
184
|
-
params._interactionId = err.__newrelic[this.agentIdentifier].interactionId;
|
|
185
|
-
params._interactionNodeId = err.__newrelic[this.agentIdentifier].interactionNodeId;
|
|
186
|
-
}
|
|
187
183
|
if (err.__newrelic?.socketId) {
|
|
188
184
|
customAttributes.socketId = err.__newrelic.socketId;
|
|
189
185
|
}
|
|
@@ -83,7 +83,7 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
83
83
|
us: info.user,
|
|
84
84
|
ac: info.account,
|
|
85
85
|
pr: info.product,
|
|
86
|
-
af: (0, _initializedFeatures.getActivatedFeaturesFlags)(this.
|
|
86
|
+
af: (0, _initializedFeatures.getActivatedFeaturesFlags)(this.agentRef).join(','),
|
|
87
87
|
...measures,
|
|
88
88
|
xx: info.extra,
|
|
89
89
|
ua: info.userAttributes,
|
|
@@ -98,9 +98,9 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
98
98
|
}
|
|
99
99
|
}, this.obfuscator.obfuscateString.bind(this.obfuscator), 'string');
|
|
100
100
|
if (_runtime.globalScope.performance) {
|
|
101
|
-
|
|
101
|
+
const navTimingEntry = (0, _runtime.getNavigationEntry)();
|
|
102
|
+
if (navTimingEntry) {
|
|
102
103
|
// Navigation Timing level 2 API that replaced PerformanceTiming & PerformanceNavigation
|
|
103
|
-
const navTimingEntry = _runtime.globalScope?.performance?.getEntriesByType('navigation')?.[0];
|
|
104
104
|
const perf = {
|
|
105
105
|
timing: (0, _navTiming.addPT)(_runtime.originTime, navTimingEntry, {}),
|
|
106
106
|
navigation: (0, _navTiming.addPN)(navTimingEntry, {})
|
|
@@ -5,7 +5,6 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.getActivatedFeaturesFlags = getActivatedFeaturesFlags;
|
|
7
7
|
var _features = require("../../../loaders/features/features");
|
|
8
|
-
var _nreum = require("../../../common/window/nreum");
|
|
9
8
|
/**
|
|
10
9
|
* Copyright 2020-2026 New Relic, Inc. All rights reserved.
|
|
11
10
|
* SPDX-License-Identifier: Apache-2.0
|
|
@@ -14,14 +13,13 @@ var _nreum = require("../../../common/window/nreum");
|
|
|
14
13
|
/**
|
|
15
14
|
* Get an array of flags required by downstream (NR UI) based on the features initialized in this agent
|
|
16
15
|
* (aka what is running on the page).
|
|
17
|
-
* @param {
|
|
16
|
+
* @param {Object} agentRef - the agent reference object
|
|
18
17
|
* @returns {String[]} Up to 5 short strings corresponding to ingest mapping of features.
|
|
19
18
|
*/
|
|
20
|
-
function getActivatedFeaturesFlags(
|
|
19
|
+
function getActivatedFeaturesFlags(agentRef) {
|
|
21
20
|
const flagArr = [];
|
|
22
|
-
const newrelic = (0, _nreum.gosNREUM)();
|
|
23
21
|
try {
|
|
24
|
-
Object.keys(
|
|
22
|
+
Object.keys(agentRef.features || {}).forEach(featName => {
|
|
25
23
|
switch (featName) {
|
|
26
24
|
case _features.FEATURE_NAMES.ajax:
|
|
27
25
|
flagArr.push('xhr');
|