@newrelic/browser-agent 1.310.1 → 1.311.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +1 -1
- 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
|
@@ -11,7 +11,7 @@ var _constants2 = require("../../../common/session/constants");
|
|
|
11
11
|
var _globalEvent = require("../../../common/dispatch/global-event");
|
|
12
12
|
var _load = require("../../../common/window/load");
|
|
13
13
|
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); } /**
|
|
14
|
-
* Copyright 2020-
|
|
14
|
+
* Copyright 2020-2026 New Relic, Inc. All rights reserved.
|
|
15
15
|
* SPDX-License-Identifier: Apache-2.0
|
|
16
16
|
*/
|
|
17
17
|
class Instrument extends _instrumentBase.InstrumentBase {
|
|
@@ -20,17 +20,16 @@ class Instrument extends _instrumentBase.InstrumentBase {
|
|
|
20
20
|
super(agentRef, CONSTANTS.FEATURE_NAME);
|
|
21
21
|
|
|
22
22
|
/** setup inspection events for window lifecycle */
|
|
23
|
-
this.setupInspectionEvents(
|
|
23
|
+
this.setupInspectionEvents();
|
|
24
24
|
|
|
25
25
|
/** feature specific APIs */
|
|
26
26
|
(0, _setPageViewName.setupSetPageViewNameAPI)(agentRef);
|
|
27
27
|
this.importAggregator(agentRef, () => Promise.resolve().then(() => _interopRequireWildcard(require(/* webpackChunkName: "page_view_event-aggregate" */'../aggregate'))));
|
|
28
28
|
}
|
|
29
|
-
setupInspectionEvents(
|
|
29
|
+
setupInspectionEvents() {
|
|
30
30
|
const dispatch = (evt, name) => {
|
|
31
31
|
if (!evt) return;
|
|
32
32
|
(0, _globalEvent.dispatchGlobalEvent)({
|
|
33
|
-
agentIdentifier,
|
|
34
33
|
timeStamp: evt.timeStamp,
|
|
35
34
|
loaded: evt.target.readyState === 'complete',
|
|
36
35
|
type: 'window',
|
|
@@ -49,7 +48,6 @@ class Instrument extends _instrumentBase.InstrumentBase {
|
|
|
49
48
|
});
|
|
50
49
|
this.ee.on(_constants2.SESSION_EVENTS.UPDATE, (_, data) => {
|
|
51
50
|
(0, _globalEvent.dispatchGlobalEvent)({
|
|
52
|
-
agentIdentifier,
|
|
53
51
|
type: 'lifecycle',
|
|
54
52
|
name: 'session',
|
|
55
53
|
data
|
|
@@ -21,6 +21,7 @@ var _runtime = require("../../../common/constants/runtime");
|
|
|
21
21
|
var _eventOrigin = require("../../../common/util/event-origin");
|
|
22
22
|
var _loadTime = require("../../../common/vitals/load-time");
|
|
23
23
|
var _webdriverDetection = require("../../../common/util/webdriver-detection");
|
|
24
|
+
var _cleanUrl = require("../../../common/url/clean-url");
|
|
24
25
|
/**
|
|
25
26
|
* Copyright 2020-2026 New Relic, Inc. All rights reserved.
|
|
26
27
|
* SPDX-License-Identifier: Apache-2.0
|
|
@@ -84,6 +85,7 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
84
85
|
}
|
|
85
86
|
addTiming(name, value, attrs) {
|
|
86
87
|
attrs = attrs || {};
|
|
88
|
+
attrs.pageUrl = (0, _cleanUrl.cleanURL)((0, _runtime.getNavigationEntry)()?.name || _runtime.initialLocation);
|
|
87
89
|
addConnectionAttributes(attrs); // network conditions may differ from the actual for VitalMetrics when they were captured
|
|
88
90
|
|
|
89
91
|
// If cls was set to another value by `onCLS`, then it's supported and is attached onto any timing but is omitted until such time.
|
|
@@ -15,7 +15,7 @@ var _traverse = require("../../../common/util/traverse");
|
|
|
15
15
|
var _cleanUrl = require("../../../common/url/clean-url");
|
|
16
16
|
var _console = require("../../../common/util/console");
|
|
17
17
|
/**
|
|
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
|
|
|
@@ -64,8 +64,9 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
64
64
|
// if another page's session entity has expired, or another page has transitioned to off and this one hasn't... we can just abort straight away here
|
|
65
65
|
if (this.sessionId !== sessionState.value || eventType === 'cross-tab' && sessionState.sessionTraceMode === _constants2.MODE.OFF) this.abort(2);
|
|
66
66
|
});
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
const navEntry = (0, _runtime.getNavigationEntry)();
|
|
68
|
+
if (navEntry) {
|
|
69
|
+
this.traceStorage.storeTiming(navEntry);
|
|
69
70
|
} else {
|
|
70
71
|
this.traceStorage.storeTiming(_runtime.globalScope.performance?.timing, true);
|
|
71
72
|
}
|
|
@@ -5,7 +5,6 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.setupAgentSession = setupAgentSession;
|
|
7
7
|
var _drain = require("../../common/drain/drain");
|
|
8
|
-
var _contextualEe = require("../../common/event-emitter/contextual-ee");
|
|
9
8
|
var _registerHandler = require("../../common/event-emitter/register-handler");
|
|
10
9
|
var _sessionEntity = require("../../common/session/session-entity");
|
|
11
10
|
var _localStorage = require("../../common/storage/local-storage.js");
|
|
@@ -27,7 +26,7 @@ function setupAgentSession(agentRef) {
|
|
|
27
26
|
|
|
28
27
|
const sessionInit = agentRef.init.session;
|
|
29
28
|
agentRef.runtime.session = new _sessionEntity.SessionEntity({
|
|
30
|
-
|
|
29
|
+
agentRef,
|
|
31
30
|
key: _constants.DEFAULT_KEY,
|
|
32
31
|
storage: new _localStorage.LocalStorage(),
|
|
33
32
|
expiresMs: sessionInit?.expiresMs,
|
|
@@ -49,7 +48,7 @@ function setupAgentSession(agentRef) {
|
|
|
49
48
|
|
|
50
49
|
/** track changes to the jsAttributes field over time for aiding with harvest mechanics */
|
|
51
50
|
agentRef.runtime.jsAttributesMetadata = (0, _attributeSize.trackObjectAttributeSize)(agentRef.info, 'jsAttributes');
|
|
52
|
-
const sharedEE =
|
|
51
|
+
const sharedEE = agentRef.ee;
|
|
53
52
|
|
|
54
53
|
// any calls to newrelic.setCustomAttribute(<persisted>) will need to be added to:
|
|
55
54
|
// local info.jsAttributes {}
|
|
@@ -74,6 +73,6 @@ function setupAgentSession(agentRef) {
|
|
|
74
73
|
consent: accept === undefined ? true : accept
|
|
75
74
|
});
|
|
76
75
|
}, 'session', sharedEE);
|
|
77
|
-
(0, _drain.drain)(agentRef
|
|
76
|
+
(0, _drain.drain)(agentRef, 'session');
|
|
78
77
|
return agentRef.runtime.session;
|
|
79
78
|
}
|
|
@@ -9,7 +9,6 @@ var _info = require("../../common/config/info");
|
|
|
9
9
|
var _configure = require("../../loaders/configure/configure");
|
|
10
10
|
var _nreum = require("../../common/window/nreum");
|
|
11
11
|
var _drain = require("../../common/drain/drain");
|
|
12
|
-
var _featureFlags = require("../../common/util/feature-flags");
|
|
13
12
|
var _obfuscate = require("../../common/util/obfuscate");
|
|
14
13
|
var _features = require("../../loaders/features/features");
|
|
15
14
|
var _harvester = require("../../common/harvest/harvester");
|
|
@@ -30,8 +29,7 @@ class AggregateBase extends _featureBase.FeatureBase {
|
|
|
30
29
|
* @param {string} featureName The name of the feature creating the instance.
|
|
31
30
|
*/
|
|
32
31
|
constructor(agentRef, featureName) {
|
|
33
|
-
super(agentRef
|
|
34
|
-
this.agentRef = agentRef;
|
|
32
|
+
super(agentRef, featureName);
|
|
35
33
|
this.checkConfiguration(agentRef);
|
|
36
34
|
this.doOnceForAllAggregate(agentRef);
|
|
37
35
|
|
|
@@ -115,8 +113,8 @@ class AggregateBase extends _featureBase.FeatureBase {
|
|
|
115
113
|
*/
|
|
116
114
|
waitForFlags(flagNames = []) {
|
|
117
115
|
const flagsPromise = new Promise((resolve, reject) => {
|
|
118
|
-
if (
|
|
119
|
-
resolve(buildOutput(
|
|
116
|
+
if (this.agentRef.runtime?.activatedFeatures) {
|
|
117
|
+
resolve(buildOutput(this.agentRef.runtime.activatedFeatures));
|
|
120
118
|
} else {
|
|
121
119
|
this.ee.on('rumresp', (resp = {}) => {
|
|
122
120
|
resolve(buildOutput(resp));
|
|
@@ -140,7 +138,7 @@ class AggregateBase extends _featureBase.FeatureBase {
|
|
|
140
138
|
* Stages the feature to be drained
|
|
141
139
|
*/
|
|
142
140
|
drain() {
|
|
143
|
-
(0, _drain.drain)(this.
|
|
141
|
+
(0, _drain.drain)(this.agentRef, this.featureName);
|
|
144
142
|
}
|
|
145
143
|
preHarvestChecks(opts) {
|
|
146
144
|
return !this.blocked && !this.ee.aborted;
|
|
@@ -4,19 +4,18 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.FeatureBase = void 0;
|
|
7
|
-
var _contextualEe = require("../../common/event-emitter/contextual-ee");
|
|
8
7
|
var _drain = require("../../common/drain/drain");
|
|
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
13
|
class FeatureBase {
|
|
15
|
-
constructor(
|
|
16
|
-
/** @type {
|
|
17
|
-
this.
|
|
14
|
+
constructor(agentRef, featureName) {
|
|
15
|
+
/** @type {Object} */
|
|
16
|
+
this.agentRef = agentRef;
|
|
18
17
|
/** @type {import('../../common/event-emitter/contextual-ee').ee} */
|
|
19
|
-
this.ee =
|
|
18
|
+
this.ee = agentRef?.ee;
|
|
20
19
|
/** @type {string} */
|
|
21
20
|
this.featureName = featureName;
|
|
22
21
|
/**
|
|
@@ -27,7 +26,7 @@ class FeatureBase {
|
|
|
27
26
|
this.blocked = false;
|
|
28
27
|
}
|
|
29
28
|
deregisterDrain() {
|
|
30
|
-
(0, _drain.deregisterDrain)(this.
|
|
29
|
+
(0, _drain.deregisterDrain)(this.agentRef, this.featureName);
|
|
31
30
|
}
|
|
32
31
|
}
|
|
33
32
|
exports.FeatureBase = FeatureBase;
|
|
@@ -16,7 +16,7 @@ var _invoke = require("../../common/util/invoke");
|
|
|
16
16
|
var _agentConstants = require("../../common/constants/agent-constants");
|
|
17
17
|
var _handle = require("../../common/event-emitter/handle");
|
|
18
18
|
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); } /**
|
|
19
|
-
* Copyright 2020-
|
|
19
|
+
* Copyright 2020-2026 New Relic, Inc. All rights reserved.
|
|
20
20
|
* SPDX-License-Identifier: Apache-2.0
|
|
21
21
|
*/ /**
|
|
22
22
|
* @file Defines `InstrumentBase` to be used as the super of the Instrument classes implemented by each feature.
|
|
@@ -30,12 +30,11 @@ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r
|
|
|
30
30
|
class InstrumentBase extends _featureBase.FeatureBase {
|
|
31
31
|
/**
|
|
32
32
|
* Instantiate InstrumentBase.
|
|
33
|
-
* @param {
|
|
33
|
+
* @param {Object} agentRef - The agent reference object.
|
|
34
34
|
* @param {string} featureName - The name of the feature module (used to construct file path).
|
|
35
35
|
*/
|
|
36
36
|
constructor(agentRef, featureName) {
|
|
37
|
-
super(agentRef
|
|
38
|
-
this.agentRef = agentRef;
|
|
37
|
+
super(agentRef, featureName);
|
|
39
38
|
|
|
40
39
|
/** @type {Function | undefined} This should be set by any derived Instrument class if it has things to do when feature fails or is killed. */
|
|
41
40
|
this.abortHandler = undefined;
|
|
@@ -65,13 +64,13 @@ class InstrumentBase extends _featureBase.FeatureBase {
|
|
|
65
64
|
this.ee.on('manual-start-all', (0, _invoke.single)(() => {
|
|
66
65
|
// register the feature to drain only once the API has been called, it will drain when importAggregator finishes for all the features
|
|
67
66
|
// called by the api in that cycle
|
|
68
|
-
(0, _drain.registerDrain)(agentRef
|
|
67
|
+
(0, _drain.registerDrain)(agentRef, this.featureName);
|
|
69
68
|
resolve();
|
|
70
69
|
}));
|
|
71
70
|
});
|
|
72
71
|
} else {
|
|
73
72
|
/** if the feature requires opt-in (!auto-start), it will get registered once the api has been called */
|
|
74
|
-
(0, _drain.registerDrain)(agentRef
|
|
73
|
+
(0, _drain.registerDrain)(agentRef, featureName);
|
|
75
74
|
}
|
|
76
75
|
}
|
|
77
76
|
|
|
@@ -111,7 +110,7 @@ class InstrumentBase extends _featureBase.FeatureBase {
|
|
|
111
110
|
*/
|
|
112
111
|
try {
|
|
113
112
|
if (!this.#shouldImportAgg(this.featureName, session, agentRef.init)) {
|
|
114
|
-
(0, _drain.drain)(this.
|
|
113
|
+
(0, _drain.drain)(this.agentRef, this.featureName);
|
|
115
114
|
this.loadedSuccessfully(false); // aggregate module isn't loaded at all
|
|
116
115
|
return;
|
|
117
116
|
}
|
|
@@ -125,7 +124,7 @@ class InstrumentBase extends _featureBase.FeatureBase {
|
|
|
125
124
|
(0, _console.warn)(34, e);
|
|
126
125
|
this.abortHandler?.(); // undo any important alterations made to the page
|
|
127
126
|
// not supported yet but nice to do: "abort" this agent's EE for this feature specifically
|
|
128
|
-
(0, _drain.drain)(this.
|
|
127
|
+
(0, _drain.drain)(this.agentRef, this.featureName, true);
|
|
129
128
|
this.loadedSuccessfully(false);
|
|
130
129
|
if (this.ee) this.ee.abort();
|
|
131
130
|
}
|
|
@@ -24,7 +24,7 @@ exports.default = void 0;
|
|
|
24
24
|
*/
|
|
25
25
|
/**
|
|
26
26
|
* @typedef {Object} RegisterAPIConstructor
|
|
27
|
-
* @property {string
|
|
27
|
+
* @property {string} id - The unique id for the registered entity. This will be assigned to any synthesized entities.
|
|
28
28
|
* @property {string} name - The readable name for the registered entity. This will be assigned to any synthesized entities.
|
|
29
29
|
* @property {{[key: string]: any}} [tags] - The tags for the registered entity as key-value pairs. This will be assigned to any synthesized entities. Tags are converted to source.* attributes (e.g., {environment: 'production'} becomes source.environment: 'production').
|
|
30
30
|
* @property {boolean} [isolated] - When true, each registration creates an isolated instance. When false, multiple registrations with the same id and isolated: false will share a single instance, including all custom attributes, ids, names, and metadata. Calling deregister on a shared instance will deregister it for all entities using the instance. Defaults to true.
|
|
@@ -94,7 +94,7 @@ function register(agentRef, target, parent) {
|
|
|
94
94
|
invalidApiResponse = warning;
|
|
95
95
|
};
|
|
96
96
|
function hasValidValue(val) {
|
|
97
|
-
return typeof val === 'string' && !!val.trim() && val.trim().length < 501
|
|
97
|
+
return typeof val === 'string' && !!val.trim() && val.trim().length < 501;
|
|
98
98
|
}
|
|
99
99
|
|
|
100
100
|
/** primary cases that can block the register API from working at init time */
|
|
@@ -9,13 +9,12 @@ var _globalEvent = require("../../common/dispatch/global-event");
|
|
|
9
9
|
var _handle = require("../../common/event-emitter/handle");
|
|
10
10
|
var _now = require("../../common/timing/now");
|
|
11
11
|
var _console = require("../../common/util/console");
|
|
12
|
-
var _featureFlags = require("../../common/util/feature-flags");
|
|
13
12
|
var _constants = require("../../features/metrics/constants");
|
|
14
13
|
var _agentBase = require("../agent-base");
|
|
15
14
|
var _features = require("../features/features");
|
|
16
15
|
var _constants2 = require("./constants");
|
|
17
16
|
/**
|
|
18
|
-
* Copyright 2020-
|
|
17
|
+
* Copyright 2020-2026 New Relic, Inc. All rights reserved.
|
|
19
18
|
* SPDX-License-Identifier: Apache-2.0
|
|
20
19
|
*/
|
|
21
20
|
|
|
@@ -35,8 +34,7 @@ function setupAPI(name, fn, agent, obj) {
|
|
|
35
34
|
api[name] = function () {
|
|
36
35
|
(0, _handle.handle)(_constants.SUPPORTABILITY_METRIC_CHANNEL, ['API/' + name + '/called'], undefined, _features.FEATURE_NAMES.metrics, agent.ee);
|
|
37
36
|
(0, _globalEvent.dispatchGlobalEvent)({
|
|
38
|
-
|
|
39
|
-
drained: !!_featureFlags.activatedFeatures?.[agent.agentIdentifier],
|
|
37
|
+
drained: !!agent.runtime?.activatedFeatures,
|
|
40
38
|
type: 'data',
|
|
41
39
|
name: 'api',
|
|
42
40
|
feature: _constants2.prefix + name,
|
|
@@ -9,7 +9,6 @@ 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 _featureFlags = require("../../common/util/feature-flags");
|
|
13
12
|
var _runtime2 = require("../../common/constants/runtime");
|
|
14
13
|
var _publicPath = require("./public-path");
|
|
15
14
|
var _contextualEe = require("../../common/event-emitter/contextual-ee");
|
|
@@ -20,8 +19,6 @@ var _loaderConfig = require("../../common/config/loader-config");
|
|
|
20
19
|
* SPDX-License-Identifier: Apache-2.0
|
|
21
20
|
*/
|
|
22
21
|
|
|
23
|
-
const alreadySetOnce = new Set(); // the configure() function can run multiple times in agent lifecycle for different agents
|
|
24
|
-
|
|
25
22
|
/**
|
|
26
23
|
* Sets or re-sets the agent's configuration values from global settings. This also attach those as properties to the agent instance.
|
|
27
24
|
* IMPORTANT: setNREUMInitializedAgent must be called on the agent prior to calling this function.
|
|
@@ -52,32 +49,37 @@ function configure(agent, opts = {}, loaderType, forceDrain) {
|
|
|
52
49
|
}
|
|
53
50
|
agent.info = (0, _info.mergeInfo)(info);
|
|
54
51
|
const updatedInit = agent.init;
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
}
|
|
61
|
-
if (updatedInit.proxy.beacon) internalTrafficList.push(updatedInit.proxy.beacon);
|
|
62
|
-
agent.beacons = [...internalTrafficList];
|
|
63
|
-
(0, _topLevelCallers.setTopLevelCallers)(agent); // no need to set global APIs on newrelic obj more than once
|
|
64
|
-
(0, _nreum.addToNREUM)('activatedFeatures', _featureFlags.activatedFeatures);
|
|
52
|
+
agent.runtime ??= (0, _runtime.mergeRuntime)(runtime);
|
|
53
|
+
|
|
54
|
+
// Apply proxy settings whenever configure is called (supports late {init} setting)
|
|
55
|
+
if (updatedInit.proxy.assets) {
|
|
56
|
+
(0, _publicPath.redefinePublicPath)(updatedInit.proxy.assets);
|
|
65
57
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
58
|
+
if (!agent.runtime.configured) {
|
|
59
|
+
Object.defineProperty(agent, 'beacons', {
|
|
60
|
+
get() {
|
|
61
|
+
return [agent.info.beacon, agent.info.errorBeacon, agent.init.proxy.assets, agent.init.proxy.beacon].filter(Boolean);
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
Object.defineProperty(agent.runtime, 'denyList', {
|
|
65
|
+
get() {
|
|
66
|
+
// Compute the internal traffic list fresh each time to ensure beacons array is current
|
|
67
|
+
return [...(agent.init.ajax.deny_list || []), ...(agent.init.ajax.block_internal ? agent.beacons : [])];
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
agent.runtime.ptid = agent.agentIdentifier;
|
|
71
|
+
(0, _topLevelCallers.setTopLevelCallers)(agent); // no need to set global APIs on newrelic obj more than once
|
|
72
|
+
|
|
73
|
+
agent.runtime.loaderType = loaderType;
|
|
71
74
|
agent.ee = _contextualEe.ee.get(agent.agentIdentifier);
|
|
72
75
|
agent.exposed = exposed;
|
|
73
76
|
(0, _globalEvent.dispatchGlobalEvent)({
|
|
74
|
-
|
|
75
|
-
drained: !!_featureFlags.activatedFeatures?.[agent.agentIdentifier],
|
|
77
|
+
drained: !!agent.runtime.activatedFeatures,
|
|
76
78
|
type: 'lifecycle',
|
|
77
79
|
name: 'initialize',
|
|
78
80
|
feature: undefined,
|
|
79
81
|
data: agent.config
|
|
80
82
|
});
|
|
83
|
+
agent.runtime.configured = true;
|
|
81
84
|
}
|
|
82
|
-
alreadySetOnce.add(agent.agentIdentifier);
|
|
83
85
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Copyright 2020-
|
|
2
|
+
* Copyright 2020-2026 New Relic, Inc. All rights reserved.
|
|
3
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
*/
|
|
5
5
|
import { warn } from '../util/console';
|
|
@@ -17,7 +17,7 @@ export function getModeledObject(obj, model) {
|
|
|
17
17
|
output[key] = null;
|
|
18
18
|
continue;
|
|
19
19
|
}
|
|
20
|
-
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];
|
|
20
|
+
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];
|
|
21
21
|
} catch (e) {
|
|
22
22
|
if (!output[key]) warn(1, e);
|
|
23
23
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Copyright 2020-
|
|
2
|
+
* Copyright 2020-2026 New Relic, Inc. All rights reserved.
|
|
3
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
*/
|
|
5
5
|
import { getModeledObject } from './configurable';
|
|
@@ -21,8 +21,12 @@ const hiddenState = {
|
|
|
21
21
|
consented: false
|
|
22
22
|
};
|
|
23
23
|
const RuntimeModel = {
|
|
24
|
+
/** @type {{[key: string]: number} | undefined} */
|
|
25
|
+
activatedFeatures: undefined,
|
|
24
26
|
/** Agent-specific metadata found in the RUM call response. ex. entityGuid */
|
|
25
27
|
appMetadata: {},
|
|
28
|
+
/** @type {boolean} */
|
|
29
|
+
configured: false,
|
|
26
30
|
get consented() {
|
|
27
31
|
return this.session?.state?.consent || hiddenState.consented;
|
|
28
32
|
},
|
|
@@ -30,8 +34,10 @@ const RuntimeModel = {
|
|
|
30
34
|
hiddenState.consented = value;
|
|
31
35
|
},
|
|
32
36
|
customTransaction: undefined,
|
|
33
|
-
denyList:
|
|
37
|
+
denyList: [],
|
|
34
38
|
disabled: false,
|
|
39
|
+
/** @type {Map<string, {staged: boolean, priority: number}>} */
|
|
40
|
+
drainRegistry: new Map(),
|
|
35
41
|
harvester: undefined,
|
|
36
42
|
isolatedBacklog: false,
|
|
37
43
|
isRecording: false,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Copyright 2020-
|
|
2
|
+
* Copyright 2020-2026 New Relic, Inc. All rights reserved.
|
|
3
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
*/
|
|
5
5
|
|
|
@@ -49,4 +49,17 @@ export const ffVersion = (() => {
|
|
|
49
49
|
* @type {number}
|
|
50
50
|
*/
|
|
51
51
|
export const originTime = Date.now() - now();
|
|
52
|
-
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Gets the first navigation entry from the Performance Timeline API.
|
|
55
|
+
* Returns undefined if the entry is not available or invalid.
|
|
56
|
+
* Matches web-vitals validation: checks that responseStart exists, is positive, and is not larger than current time.
|
|
57
|
+
* See: https://github.com/GoogleChrome/web-vitals/issues/137
|
|
58
|
+
* @returns {PerformanceNavigationTiming | undefined}
|
|
59
|
+
*/
|
|
60
|
+
export const getNavigationEntry = () => {
|
|
61
|
+
const navigationEntry = globalScope?.performance?.getEntriesByType?.('navigation')?.[0];
|
|
62
|
+
if (navigationEntry && navigationEntry.responseStart > 0 && navigationEntry.responseStart < globalScope.performance.now()) {
|
|
63
|
+
return navigationEntry;
|
|
64
|
+
}
|
|
65
|
+
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Copyright 2020-
|
|
2
|
+
* Copyright 2020-2026 New Relic, Inc. All rights reserved.
|
|
3
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
*/
|
|
5
5
|
|
|
@@ -84,5 +84,5 @@ export function setDenyList(denyListConfig) {
|
|
|
84
84
|
function convertToRegularExpression(filter, isPathname = false) {
|
|
85
85
|
const newFilter = filter.replace(/[.+?^${}()|[\]\\]/g, m => '\\' + m) // use a replacer function to not break apm injection
|
|
86
86
|
.replace(/\*/g, '.*?'); // use lazy matching instead of greedy
|
|
87
|
-
return new RegExp((isPathname ? '^' : '') + newFilter + '
|
|
87
|
+
return new RegExp((isPathname ? '^' : '') + newFilter + '\x24'); // x24 == $, but using a literal $ causes webpack to to break when building unminified
|
|
88
88
|
}
|
|
@@ -4,82 +4,73 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { dispatchGlobalEvent } from '../../common/dispatch/global-event';
|
|
7
|
-
import { ee } from '../event-emitter/contextual-ee';
|
|
8
7
|
import { registerHandler as defaultRegister } from '../event-emitter/register-handler';
|
|
9
8
|
import { featurePriority } from '../../loaders/features/features';
|
|
10
9
|
import { EventContext } from '../event-emitter/event-context';
|
|
11
|
-
const registry = {};
|
|
12
10
|
|
|
13
11
|
/**
|
|
14
12
|
* Adds an entry to the centralized drain registry specifying that a particular agent has events of a particular named
|
|
15
13
|
* event-group "bucket" that should be drained at the time the agent drains all its buffered events. Buffered events
|
|
16
14
|
* accumulate because instrumentation begins as soon as possible, before the agent has finished lazy-loading the code
|
|
17
15
|
* responsible for aggregating and reporting captured data.
|
|
18
|
-
* @param {
|
|
16
|
+
* @param {Object} agentRef - The agent reference object.
|
|
19
17
|
* @param {string} group - The named "bucket" for the events this feature will be bucketing for later collection.
|
|
20
18
|
*/
|
|
21
|
-
export function registerDrain(
|
|
19
|
+
export function registerDrain(agentRef, group) {
|
|
20
|
+
if (!agentRef) return;
|
|
22
21
|
// Here `item` captures the registered properties of a feature-group: whether it is ready for its buffered events
|
|
23
22
|
// to be drained (`staged`) and the `priority` order in which it should be drained relative to other feature groups.
|
|
24
23
|
const item = {
|
|
25
24
|
staged: false,
|
|
26
25
|
priority: featurePriority[group] || 0
|
|
27
26
|
};
|
|
28
|
-
|
|
29
|
-
if (!registry[agentIdentifier].get(group)) registry[agentIdentifier].set(group, item);
|
|
27
|
+
if (!agentRef.runtime.drainRegistry.get(group)) agentRef.runtime.drainRegistry.set(group, item);
|
|
30
28
|
}
|
|
31
29
|
|
|
32
30
|
/**
|
|
33
31
|
* Removes an item from the registry and immediately re-checks if the registry is ready to "drain all"
|
|
34
|
-
* @param {
|
|
32
|
+
* @param {Object} agentRef - The agent reference object.
|
|
35
33
|
* @param {*} group - The named "bucket" to be removed from the registry
|
|
36
34
|
*/
|
|
37
|
-
export function deregisterDrain(
|
|
38
|
-
if (!
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
if (
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Registers the specified agent with the centralized event buffer registry if it is not already registered.
|
|
46
|
-
* Agents without an identifier (as in the case of some tests) will be excluded from the registry.
|
|
47
|
-
* @param {string} agentIdentifier - A 16 character string uniquely identifying an agent.
|
|
48
|
-
*/
|
|
49
|
-
function curateRegistry(agentIdentifier) {
|
|
50
|
-
if (!agentIdentifier) throw new Error('agentIdentifier required');
|
|
51
|
-
if (!registry[agentIdentifier]) registry[agentIdentifier] = new Map();
|
|
35
|
+
export function deregisterDrain(agentRef, group) {
|
|
36
|
+
if (!agentRef) return;
|
|
37
|
+
const drainRegistry = agentRef.runtime.drainRegistry;
|
|
38
|
+
if (!drainRegistry) return;
|
|
39
|
+
if (drainRegistry.get(group)) drainRegistry.delete(group);
|
|
40
|
+
drainGroup(agentRef, group, false);
|
|
41
|
+
if (drainRegistry.size) checkCanDrainAll(agentRef);
|
|
52
42
|
}
|
|
53
43
|
|
|
54
44
|
/**
|
|
55
45
|
* Drain buffered events out of the event emitter. Each feature should have its events bucketed by "group" and drain
|
|
56
46
|
* its own named group explicitly, when ready.
|
|
57
|
-
* @param {
|
|
47
|
+
* @param {Object} agentRef - The agent reference object.
|
|
58
48
|
* @param {string} featureName - A named group into which the feature's buffered events are bucketed.
|
|
59
49
|
* @param {boolean} force - Whether to force the drain to occur immediately, bypassing the registry and staging logic.
|
|
60
50
|
*/
|
|
61
|
-
export function drain(
|
|
62
|
-
|
|
51
|
+
export function drain(agentRef, featureName = 'feature', force = false) {
|
|
52
|
+
if (!agentRef) return;
|
|
63
53
|
// If the feature for the specified agent is not in the registry, that means the instrument file was bypassed.
|
|
64
54
|
// This could happen in tests, or loaders that directly import the aggregator. In these cases it is safe to
|
|
65
55
|
// drain the feature group immediately rather than waiting to drain all at once.
|
|
66
|
-
if (!
|
|
56
|
+
if (!agentRef.runtime.drainRegistry.get(featureName) || force) return drainGroup(agentRef, featureName);
|
|
67
57
|
|
|
68
58
|
// When `drain` is called, this feature is ready to drain (staged).
|
|
69
|
-
|
|
70
|
-
checkCanDrainAll(
|
|
59
|
+
agentRef.runtime.drainRegistry.get(featureName).staged = true;
|
|
60
|
+
checkCanDrainAll(agentRef);
|
|
71
61
|
}
|
|
72
62
|
|
|
73
63
|
/** 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 */
|
|
74
|
-
function checkCanDrainAll(
|
|
64
|
+
function checkCanDrainAll(agentRef) {
|
|
65
|
+
if (!agentRef) return;
|
|
75
66
|
// Only when the event-groups for all features are ready to drain (staged) do we execute the drain. This has the effect
|
|
76
67
|
// that the last feature to call drain triggers drain for all features.
|
|
77
|
-
const items = Array.from(
|
|
68
|
+
const items = Array.from(agentRef.runtime.drainRegistry);
|
|
78
69
|
if (items.every(([key, values]) => values.staged)) {
|
|
79
70
|
items.sort((a, b) => a[1].priority - b[1].priority);
|
|
80
71
|
items.forEach(([group]) => {
|
|
81
|
-
|
|
82
|
-
drainGroup(
|
|
72
|
+
agentRef.runtime.drainRegistry.delete(group);
|
|
73
|
+
drainGroup(agentRef, group);
|
|
83
74
|
});
|
|
84
75
|
}
|
|
85
76
|
}
|
|
@@ -89,12 +80,12 @@ function checkCanDrainAll(agentIdentifier) {
|
|
|
89
80
|
* the subscribed handlers for the group.
|
|
90
81
|
* @param {*} group - The name of a particular feature's event "bucket".
|
|
91
82
|
*/
|
|
92
|
-
function drainGroup(
|
|
93
|
-
|
|
83
|
+
function drainGroup(agentRef, group, activateGroup = true) {
|
|
84
|
+
if (!agentRef) return;
|
|
85
|
+
const baseEE = agentRef.ee;
|
|
94
86
|
const handlers = defaultRegister.handlers; // other storage in registerHandler
|
|
95
|
-
if (baseEE.aborted || !baseEE.backlog || !handlers) return;
|
|
87
|
+
if (!baseEE || baseEE.aborted || !baseEE.backlog || !handlers) return;
|
|
96
88
|
dispatchGlobalEvent({
|
|
97
|
-
agentIdentifier,
|
|
98
89
|
type: 'lifecycle',
|
|
99
90
|
name: 'drain',
|
|
100
91
|
feature: group
|
|
@@ -15,7 +15,6 @@ import { obj, param } from '../url/encode';
|
|
|
15
15
|
import { warn } from '../util/console';
|
|
16
16
|
import { stringify } from '../util/stringify';
|
|
17
17
|
import { getSubmitMethod, xhr as xhrMethod, xhrFetch as fetchMethod } from '../util/submit-data';
|
|
18
|
-
import { activatedFeatures } from '../util/feature-flags';
|
|
19
18
|
import { dispatchGlobalEvent } from '../dispatch/global-event';
|
|
20
19
|
const RETRY = 'Harvester/Retry/';
|
|
21
20
|
const RETRY_ATTEMPTED = RETRY + 'Attempted/';
|
|
@@ -229,8 +228,7 @@ export function send(agentRef, {
|
|
|
229
228
|
}
|
|
230
229
|
}
|
|
231
230
|
dispatchGlobalEvent({
|
|
232
|
-
|
|
233
|
-
drained: !!activatedFeatures?.[agentRef.agentIdentifier],
|
|
231
|
+
drained: !!agentRef.runtime?.activatedFeatures,
|
|
234
232
|
type: 'data',
|
|
235
233
|
name: 'harvest',
|
|
236
234
|
feature: featureName,
|