@newrelic/browser-agent 1.302.0 → 1.303.0-rc.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 +20 -0
- package/dist/cjs/common/config/init-types.js +2 -0
- package/dist/cjs/common/config/init.js +3 -0
- package/dist/cjs/common/config/runtime.js +9 -0
- package/dist/cjs/common/constants/env.cdn.js +1 -1
- package/dist/cjs/common/constants/env.npm.js +1 -1
- package/dist/cjs/common/harvest/harvester.js +13 -9
- package/dist/cjs/common/harvest/types.js +0 -1
- package/dist/cjs/common/session/session-entity.js +4 -2
- package/dist/cjs/common/util/mfe.js +8 -5
- package/dist/cjs/common/wrap/wrap-promise.js +10 -5
- package/dist/cjs/features/generic_events/aggregate/index.js +4 -4
- package/dist/cjs/features/logging/aggregate/index.js +1 -2
- package/dist/cjs/features/page_view_event/aggregate/index.js +84 -22
- package/dist/cjs/features/page_view_event/instrument/index.js +0 -4
- package/dist/cjs/features/session_replay/aggregate/index.js +3 -2
- package/dist/cjs/features/session_replay/constants.js +2 -6
- package/dist/cjs/features/session_replay/instrument/index.js +3 -2
- package/dist/cjs/features/utils/agent-session.js +5 -0
- package/dist/cjs/features/utils/instrument-base.js +7 -8
- package/dist/cjs/interfaces/registered-entity.js +21 -0
- package/dist/cjs/loaders/agent.js +2 -0
- package/dist/cjs/loaders/api/consent.js +37 -0
- package/dist/cjs/loaders/api/constants.js +3 -2
- package/dist/cjs/loaders/api/measure.js +36 -35
- package/dist/cjs/loaders/api/recordCustomEvent.js +5 -3
- package/dist/cjs/loaders/api/register-api-types.js +14 -10
- package/dist/cjs/loaders/api/register.js +25 -10
- package/dist/cjs/loaders/api-base.js +14 -7
- package/dist/esm/common/config/init-types.js +2 -0
- package/dist/esm/common/config/init.js +3 -0
- package/dist/esm/common/config/runtime.js +9 -0
- package/dist/esm/common/constants/env.cdn.js +1 -1
- package/dist/esm/common/constants/env.npm.js +1 -1
- package/dist/esm/common/harvest/harvester.js +13 -9
- package/dist/esm/common/harvest/types.js +0 -1
- package/dist/esm/common/session/session-entity.js +4 -2
- package/dist/esm/common/util/mfe.js +7 -5
- package/dist/esm/common/wrap/wrap-promise.js +10 -5
- package/dist/esm/features/generic_events/aggregate/index.js +4 -4
- package/dist/esm/features/logging/aggregate/index.js +1 -2
- package/dist/esm/features/page_view_event/aggregate/index.js +84 -22
- package/dist/esm/features/page_view_event/instrument/index.js +0 -4
- package/dist/esm/features/session_replay/aggregate/index.js +4 -3
- package/dist/esm/features/session_replay/constants.js +1 -5
- package/dist/esm/features/session_replay/instrument/index.js +4 -3
- package/dist/esm/features/utils/agent-session.js +5 -0
- package/dist/esm/features/utils/instrument-base.js +7 -8
- package/dist/esm/interfaces/registered-entity.js +21 -0
- package/dist/esm/loaders/agent.js +2 -0
- package/dist/esm/loaders/api/consent.js +30 -0
- package/dist/esm/loaders/api/constants.js +2 -1
- package/dist/esm/loaders/api/measure.js +35 -35
- package/dist/esm/loaders/api/recordCustomEvent.js +4 -3
- package/dist/esm/loaders/api/register-api-types.js +14 -10
- package/dist/esm/loaders/api/register.js +26 -10
- package/dist/esm/loaders/api-base.js +15 -8
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/common/config/init-types.d.ts +6 -0
- package/dist/types/common/config/init.d.ts.map +1 -1
- package/dist/types/common/config/runtime.d.ts.map +1 -1
- package/dist/types/common/harvest/harvester.d.ts.map +1 -1
- package/dist/types/common/harvest/types.d.ts +0 -2
- package/dist/types/common/harvest/types.d.ts.map +1 -1
- package/dist/types/common/session/session-entity.d.ts.map +1 -1
- package/dist/types/common/util/mfe.d.ts +3 -0
- package/dist/types/common/util/mfe.d.ts.map +1 -1
- package/dist/types/common/wrap/wrap-promise.d.ts.map +1 -1
- package/dist/types/features/page_view_event/aggregate/index.d.ts +22 -3
- package/dist/types/features/page_view_event/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/page_view_event/instrument/index.d.ts.map +1 -1
- package/dist/types/features/session_replay/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/session_replay/constants.d.ts +1 -5
- package/dist/types/features/session_replay/constants.d.ts.map +1 -1
- package/dist/types/features/session_replay/instrument/index.d.ts.map +1 -1
- package/dist/types/features/utils/agent-session.d.ts.map +1 -1
- package/dist/types/features/utils/instrument-base.d.ts +1 -0
- package/dist/types/features/utils/instrument-base.d.ts.map +1 -1
- package/dist/types/interfaces/registered-entity.d.ts +25 -0
- package/dist/types/interfaces/registered-entity.d.ts.map +1 -1
- package/dist/types/loaders/agent.d.ts.map +1 -1
- package/dist/types/loaders/api/consent.d.ts +2 -0
- package/dist/types/loaders/api/consent.d.ts.map +1 -0
- package/dist/types/loaders/api/constants.d.ts +1 -0
- package/dist/types/loaders/api/constants.d.ts.map +1 -1
- package/dist/types/loaders/api/measure.d.ts +3 -0
- package/dist/types/loaders/api/measure.d.ts.map +1 -1
- package/dist/types/loaders/api/recordCustomEvent.d.ts +1 -0
- package/dist/types/loaders/api/recordCustomEvent.d.ts.map +1 -1
- package/dist/types/loaders/api/register-api-types.d.ts +43 -12
- package/dist/types/loaders/api/register-api-types.d.ts.map +1 -1
- package/dist/types/loaders/api/register.d.ts +0 -16
- package/dist/types/loaders/api/register.d.ts.map +1 -1
- package/dist/types/loaders/api-base.d.ts +20 -15
- package/dist/types/loaders/api-base.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/common/config/init-types.js +2 -0
- package/src/common/config/init.js +1 -0
- package/src/common/config/runtime.js +10 -0
- package/src/common/harvest/harvester.js +11 -8
- package/src/common/harvest/types.js +0 -1
- package/src/common/session/session-entity.js +6 -2
- package/src/common/util/mfe.js +10 -4
- package/src/common/wrap/wrap-promise.js +16 -6
- package/src/features/generic_events/aggregate/index.js +4 -4
- package/src/features/logging/aggregate/index.js +1 -1
- package/src/features/page_view_event/aggregate/index.js +79 -15
- package/src/features/page_view_event/instrument/index.js +0 -4
- package/src/features/session_replay/aggregate/index.js +4 -3
- package/src/features/session_replay/constants.js +1 -5
- package/src/features/session_replay/instrument/index.js +4 -3
- package/src/features/utils/agent-session.js +4 -0
- package/src/features/utils/instrument-base.js +7 -9
- package/src/interfaces/registered-entity.js +21 -0
- package/src/loaders/agent.js +2 -0
- package/src/loaders/api/consent.js +31 -0
- package/src/loaders/api/constants.js +1 -0
- package/src/loaders/api/measure.js +34 -33
- package/src/loaders/api/recordCustomEvent.js +5 -3
- package/src/loaders/api/register-api-types.js +14 -10
- package/src/loaders/api/register.js +17 -10
- package/src/loaders/api-base.js +15 -8
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.setupConsentAPI = setupConsentAPI;
|
|
7
|
+
var _constants = require("./constants");
|
|
8
|
+
var _sharedHandlers = require("./sharedHandlers");
|
|
9
|
+
var _handle = require("../../common/event-emitter/handle");
|
|
10
|
+
var _console = require("../../common/util/console");
|
|
11
|
+
/**
|
|
12
|
+
* Copyright 2020-2025 New Relic, Inc. All rights reserved.
|
|
13
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
function setupConsentAPI(agent) {
|
|
17
|
+
(0, _sharedHandlers.setupAPI)(_constants.CONSENT, function (accept = true) {
|
|
18
|
+
if (typeof accept !== 'boolean') {
|
|
19
|
+
(0, _console.warn)(65, typeof accept);
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
/** harvester, by way of "consented" getter, checks session state first, and falls back on runtime state if not available. Set both here */
|
|
23
|
+
(0, _handle.handle)(_constants.prefix + _constants.CONSENT, [accept], undefined, 'session', agent.ee); // sets session state (if available)
|
|
24
|
+
agent.runtime.consented = accept; // sets runtime state
|
|
25
|
+
|
|
26
|
+
/** if consent is granted, attempt to make a PageView event harvest if one has not already been made */
|
|
27
|
+
if (accept) {
|
|
28
|
+
const pveInst = agent.features.page_view_event;
|
|
29
|
+
pveInst.onAggregateImported.then(loaded => {
|
|
30
|
+
const pveAgg = pveInst.featAggregate;
|
|
31
|
+
if (loaded && !pveAgg.sentRum) {
|
|
32
|
+
pveAgg.sendRum();
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
}, agent);
|
|
37
|
+
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.spaPrefix = exports.prefix = exports.WRAP_LOGGER = exports.START = exports.SET_USER_ID = exports.SET_PAGE_VIEW_NAME = exports.SET_ERROR_HANDLER = exports.SET_CUSTOM_ATTRIBUTE = exports.SET_CURRENT_ROUTE_NAME = exports.SET_APPLICATION_VERSION = exports.REGISTER = exports.RECORD_REPLAY = exports.RECORD_CUSTOM_EVENT = exports.PAUSE_REPLAY = exports.NOTICE_ERROR = exports.MEASURE = exports.LOG = exports.INTERACTION = exports.FINISHED = exports.ADD_TO_TRACE = exports.ADD_RELEASE = exports.ADD_PAGE_ACTION = void 0;
|
|
6
|
+
exports.spaPrefix = exports.prefix = exports.WRAP_LOGGER = exports.START = exports.SET_USER_ID = exports.SET_PAGE_VIEW_NAME = exports.SET_ERROR_HANDLER = exports.SET_CUSTOM_ATTRIBUTE = exports.SET_CURRENT_ROUTE_NAME = exports.SET_APPLICATION_VERSION = exports.REGISTER = exports.RECORD_REPLAY = exports.RECORD_CUSTOM_EVENT = exports.PAUSE_REPLAY = exports.NOTICE_ERROR = exports.MEASURE = exports.LOG = exports.INTERACTION = exports.FINISHED = exports.CONSENT = exports.ADD_TO_TRACE = exports.ADD_RELEASE = exports.ADD_PAGE_ACTION = void 0;
|
|
7
7
|
/**
|
|
8
8
|
* Copyright 2020-2025 New Relic, Inc. All rights reserved.
|
|
9
9
|
* SPDX-License-Identifier: Apache-2.0
|
|
@@ -29,4 +29,5 @@ const SET_PAGE_VIEW_NAME = exports.SET_PAGE_VIEW_NAME = 'setPageViewName';
|
|
|
29
29
|
const SET_USER_ID = exports.SET_USER_ID = 'setUserId';
|
|
30
30
|
const START = exports.START = 'start';
|
|
31
31
|
const WRAP_LOGGER = exports.WRAP_LOGGER = 'wrapLogger';
|
|
32
|
-
const MEASURE = exports.MEASURE = 'measure';
|
|
32
|
+
const MEASURE = exports.MEASURE = 'measure';
|
|
33
|
+
const CONSENT = exports.CONSENT = 'consent';
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
+
exports.measure = measure;
|
|
6
7
|
exports.setupMeasureAPI = setupMeasureAPI;
|
|
7
8
|
var _handle = require("../../common/event-emitter/handle");
|
|
8
9
|
var _now = require("../../common/timing/now");
|
|
@@ -16,45 +17,45 @@ var _sharedHandlers = require("./sharedHandlers");
|
|
|
16
17
|
*/
|
|
17
18
|
|
|
18
19
|
function setupMeasureAPI(agent) {
|
|
19
|
-
(0, _sharedHandlers.setupAPI)(_constants.MEASURE,
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
20
|
+
(0, _sharedHandlers.setupAPI)(_constants.MEASURE, (name, options) => measure(name, options, agent), agent);
|
|
21
|
+
}
|
|
22
|
+
function measure(name, options, agentRef, target, timestamp = (0, _now.now)()) {
|
|
23
|
+
const {
|
|
24
|
+
start,
|
|
25
|
+
end,
|
|
26
|
+
customAttributes
|
|
27
|
+
} = options || {};
|
|
28
|
+
const returnObj = {
|
|
29
|
+
customAttributes: customAttributes || {}
|
|
30
|
+
};
|
|
31
|
+
if (typeof returnObj.customAttributes !== 'object' || typeof name !== 'string' || name.length === 0) {
|
|
32
|
+
(0, _console.warn)(57);
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
33
35
|
|
|
34
|
-
|
|
36
|
+
/**
|
|
35
37
|
* getValueFromTiming - Helper function to extract a numeric value from a supplied option.
|
|
36
38
|
* @param {Number|PerformanceMark} [timing] The timing value
|
|
37
39
|
* @param {Number} [d] The default value to return if timing is invalid
|
|
38
40
|
* @returns {Number} The timing value or the default value
|
|
39
41
|
*/
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
}, agent);
|
|
42
|
+
const getValueFromTiming = (timing, d) => {
|
|
43
|
+
if (timing == null) return d;
|
|
44
|
+
if (typeof timing === 'number') return timing;
|
|
45
|
+
if (timing instanceof PerformanceMark) return timing.startTime;
|
|
46
|
+
return Number.NaN;
|
|
47
|
+
};
|
|
48
|
+
returnObj.start = getValueFromTiming(start, 0);
|
|
49
|
+
returnObj.end = getValueFromTiming(end, timestamp);
|
|
50
|
+
if (Number.isNaN(returnObj.start) || Number.isNaN(returnObj.end)) {
|
|
51
|
+
(0, _console.warn)(57);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
returnObj.duration = returnObj.end - returnObj.start;
|
|
55
|
+
if (returnObj.duration < 0) {
|
|
56
|
+
(0, _console.warn)(58);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
(0, _handle.handle)(_constants.prefix + _constants.MEASURE, [returnObj, name, target], undefined, _features.FEATURE_NAMES.genericEvents, agentRef.ee);
|
|
60
|
+
return returnObj;
|
|
60
61
|
}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
+
exports.recordCustomEvent = recordCustomEvent;
|
|
6
7
|
exports.setupRecordCustomEventAPI = setupRecordCustomEventAPI;
|
|
7
8
|
var _handle = require("../../common/event-emitter/handle");
|
|
8
9
|
var _now = require("../../common/timing/now");
|
|
@@ -15,7 +16,8 @@ var _sharedHandlers = require("./sharedHandlers");
|
|
|
15
16
|
*/
|
|
16
17
|
|
|
17
18
|
function setupRecordCustomEventAPI(agent) {
|
|
18
|
-
(0, _sharedHandlers.setupAPI)(_constants.RECORD_CUSTOM_EVENT,
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
(0, _sharedHandlers.setupAPI)(_constants.RECORD_CUSTOM_EVENT, (eventType, attributes) => recordCustomEvent(eventType, attributes, agent), agent);
|
|
20
|
+
}
|
|
21
|
+
function recordCustomEvent(eventType, attributes = {}, agentRef, target, timestamp = (0, _now.now)()) {
|
|
22
|
+
(0, _handle.handle)(_constants.prefix + _constants.RECORD_CUSTOM_EVENT, [timestamp, eventType, attributes, target], undefined, _features.FEATURE_NAMES.genericEvents, agentRef.ee);
|
|
21
23
|
}
|
|
@@ -10,26 +10,30 @@ exports.default = void 0;
|
|
|
10
10
|
*/
|
|
11
11
|
/**
|
|
12
12
|
* @typedef {Object} RegisterAPI
|
|
13
|
-
* @property {
|
|
14
|
-
* @property {
|
|
15
|
-
* @property {
|
|
16
|
-
* @property {
|
|
17
|
-
* @property {
|
|
18
|
-
* @property {
|
|
13
|
+
* @property {(name: string, attributes?: object) => void} addPageAction - Add a page action for the registered entity.
|
|
14
|
+
* @property {(message: string, options?: { customAttributes?: object, level?: 'ERROR' | 'TRACE' | 'DEBUG' | 'INFO' | 'WARN'}) => void} log - Capture a log for the registered entity.
|
|
15
|
+
* @property {(error: Error | string, customAttributes?: object) => void} noticeError - Notice an error for the registered entity.
|
|
16
|
+
* @property {(target: RegisterAPIConstructor) => RegisterAPI} register - Record a custom event for the registered entity.
|
|
17
|
+
* @property {(eventType: string, attributes?: Object) => void} recordCustomEvent - Record a custom event for the registered entity.
|
|
18
|
+
* @property {(eventType: string, options?: {start: number, end: number, duration: number, customAttributes: object}) => ({start: number, end: number, duration: number, customAttributes: object})} measure - Measures a task that is recorded as a BrowserPerformance event.
|
|
19
|
+
* @property {(value: string | null) => void} setApplicationVersion - Add an application.version attribute to all outgoing data for the registered entity.
|
|
20
|
+
* @property {(name: string, value: string | number | boolean | null, persist?: boolean) => void} setCustomAttribute - Add a custom attribute to outgoing data for the registered entity.
|
|
21
|
+
* @property {(value: string | null) => void} setUserId - Add an enduser.id attribute to all outgoing API data for the registered entity.
|
|
19
22
|
* @property {RegisterAPIMetadata} metadata - The metadata object containing the custom attributes and target information for the registered entity.
|
|
20
23
|
*/
|
|
21
24
|
/**
|
|
22
25
|
* @typedef {Object} RegisterAPIConstructor
|
|
23
|
-
* @property {
|
|
24
|
-
* @property {string}
|
|
25
|
-
* @property {string}
|
|
26
|
+
* @property {string|number} id - The unique id for the registered entity. This will be assigned to any synthesized entities.
|
|
27
|
+
* @property {string} name - The readable name for the registered entity. This will be assigned to any synthesized entities.
|
|
28
|
+
* @property {string} [parentId] - The parentId for the registered entity. If none was supplied, it will assume the entity guid from the main agent.
|
|
26
29
|
*/
|
|
27
30
|
/**
|
|
28
31
|
* @typedef {Object} RegisterAPIMetadata
|
|
29
32
|
* @property {Object} customAttributes - The custom attributes for the registered entity.
|
|
30
33
|
* @property {Object} target - The options for the registered entity.
|
|
31
|
-
* @property {string} target.licenseKey - The license key for the registered entity. If none was supplied, it will assume the license key from the main agent.
|
|
34
|
+
* @property {string} [target.licenseKey] - The license key for the registered entity. If none was supplied, it will assume the license key from the main agent.
|
|
32
35
|
* @property {string} target.id - The ID for the registered entity.
|
|
33
36
|
* @property {string} target.name - The name returned for the registered entity.
|
|
37
|
+
* @property {string} [target.parentId] - The parentId for the registered entity. If none was supplied, it will assume the entity guid from the main agent.
|
|
34
38
|
*/
|
|
35
39
|
var _default = exports.default = {};
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.buildRegisterApi = buildRegisterApi;
|
|
7
6
|
exports.setupRegisterAPI = setupRegisterAPI;
|
|
8
7
|
var _handle = require("../../common/event-emitter/handle");
|
|
9
8
|
var _console = require("../../common/util/console");
|
|
@@ -17,6 +16,8 @@ var _log = require("./log");
|
|
|
17
16
|
var _addPageAction = require("./addPageAction");
|
|
18
17
|
var _noticeError = require("./noticeError");
|
|
19
18
|
var _invoke = require("../../common/util/invoke");
|
|
19
|
+
var _measure = require("./measure");
|
|
20
|
+
var _recordCustomEvent = require("./recordCustomEvent");
|
|
20
21
|
/**
|
|
21
22
|
* Copyright 2020-2025 New Relic, Inc. All rights reserved.
|
|
22
23
|
* SPDX-License-Identifier: Apache-2.0
|
|
@@ -33,7 +34,7 @@ var _invoke = require("../../common/util/invoke");
|
|
|
33
34
|
*/
|
|
34
35
|
function setupRegisterAPI(agent) {
|
|
35
36
|
(0, _sharedHandlers.setupAPI)(_constants2.REGISTER, function (target) {
|
|
36
|
-
return
|
|
37
|
+
return register(agent, target);
|
|
37
38
|
}, agent);
|
|
38
39
|
}
|
|
39
40
|
|
|
@@ -41,19 +42,18 @@ function setupRegisterAPI(agent) {
|
|
|
41
42
|
* Builds the api object that will be returned from the register api method.
|
|
42
43
|
* Also conducts certain side-effects, such as harvesting a PageView event when triggered and gathering metadata for the registered entity.
|
|
43
44
|
* @param {Object} agentRef the reference to the base agent instance
|
|
44
|
-
* @param {
|
|
45
|
-
* @param {
|
|
46
|
-
* @param {string} [target.licenseKey] the license key of the target to report data to
|
|
47
|
-
* @param {string} target.id the entity ID of the target to report data to
|
|
48
|
-
* @param {string} target.name the entity name of the target to report data to
|
|
45
|
+
* @param {import('./register-api-types').RegisterAPIConstructor} target
|
|
46
|
+
* @param {import('./register-api-types').RegisterAPIConstructor} [parent]
|
|
49
47
|
* @returns {RegisterAPI} the api object to be returned from the register api method
|
|
50
48
|
*/
|
|
51
|
-
function
|
|
49
|
+
function register(agentRef, target, parent) {
|
|
52
50
|
const attrs = {};
|
|
53
51
|
(0, _console.warn)(54, 'newrelic.register');
|
|
54
52
|
target ||= {};
|
|
53
|
+
target.eventSource = 'MicroFrontendBrowserAgent';
|
|
55
54
|
target.licenseKey ||= agentRef.info.licenseKey; // will inherit the license key from the container agent if not provided for brevity. A future state may dictate that we need different license keys to do different things.
|
|
56
55
|
target.blocked = false;
|
|
56
|
+
target.parent = parent || {};
|
|
57
57
|
|
|
58
58
|
/** @type {Function} a function that is set and reports when APIs are triggered -- warns the customer of the invalid state */
|
|
59
59
|
let invalidApiResponse = () => {};
|
|
@@ -86,6 +86,9 @@ function buildRegisterApi(agentRef, target) {
|
|
|
86
86
|
/** primary cases that can block the register API from working at init time */
|
|
87
87
|
if (!agentRef.init.api.allow_registered_children) block((0, _invoke.single)(() => (0, _console.warn)(55)));
|
|
88
88
|
if (!(0, _mfe.isValidMFETarget)(target)) block((0, _invoke.single)(() => (0, _console.warn)(48, target)));
|
|
89
|
+
if (!(0, _mfe.hasValidValue)(target.id) || !(0, _mfe.hasValidValue)(target.name)) {
|
|
90
|
+
block((0, _invoke.single)(() => (0, _console.warn)(48, target)));
|
|
91
|
+
}
|
|
89
92
|
|
|
90
93
|
/** @type {RegisterAPI} */
|
|
91
94
|
const api = {
|
|
@@ -100,10 +103,22 @@ function buildRegisterApi(agentRef, target) {
|
|
|
100
103
|
...(options.customAttributes || {})
|
|
101
104
|
}
|
|
102
105
|
}, agentRef], target),
|
|
106
|
+
measure: (name, options = {}) => report(_measure.measure, [name, {
|
|
107
|
+
...options,
|
|
108
|
+
customAttributes: {
|
|
109
|
+
...attrs,
|
|
110
|
+
...(options.customAttributes || {})
|
|
111
|
+
}
|
|
112
|
+
}, agentRef], target),
|
|
103
113
|
noticeError: (error, attributes = {}) => report(_noticeError.noticeError, [error, {
|
|
104
114
|
...attrs,
|
|
105
115
|
...attributes
|
|
106
116
|
}, agentRef], target),
|
|
117
|
+
register: (target = {}) => report(register, [agentRef, target], api.metadata.target),
|
|
118
|
+
recordCustomEvent: (eventType, attributes = {}) => report(_recordCustomEvent.recordCustomEvent, [eventType, {
|
|
119
|
+
...attrs,
|
|
120
|
+
...attributes
|
|
121
|
+
}, agentRef], target),
|
|
107
122
|
setApplicationVersion: value => setLocalValue('application.version', value),
|
|
108
123
|
setCustomAttribute: (key, value) => setLocalValue(key, value),
|
|
109
124
|
setUserId: value => setLocalValue('enduser.id', value),
|
|
@@ -151,8 +166,8 @@ function buildRegisterApi(agentRef, target) {
|
|
|
151
166
|
const timestamp = (0, _now.now)();
|
|
152
167
|
(0, _handle.handle)(_constants.SUPPORTABILITY_METRIC_CHANNEL, ["API/register/".concat(methodToCall.name, "/called")], undefined, _features.FEATURE_NAMES.metrics, agentRef.ee);
|
|
153
168
|
try {
|
|
154
|
-
const shouldDuplicate = agentRef.init.api.duplicate_registered_data;
|
|
155
|
-
if (shouldDuplicate
|
|
169
|
+
const shouldDuplicate = agentRef.init.api.duplicate_registered_data && methodToCall.name !== 'register';
|
|
170
|
+
if (shouldDuplicate) {
|
|
156
171
|
// also report to container by providing undefined target
|
|
157
172
|
methodToCall(...args, undefined, timestamp);
|
|
158
173
|
}
|
|
@@ -37,11 +37,8 @@ class ApiBase {
|
|
|
37
37
|
* It is not recommended for use in production environments and will not receive support for issues.
|
|
38
38
|
*
|
|
39
39
|
* Registers an external caller to report through the base agent to a different target than the base agent.
|
|
40
|
-
* @param {
|
|
41
|
-
|
|
42
|
-
* @param {string} target.applicationID The applicationID to report data to
|
|
43
|
-
* @param {string=} target.entityGuid The entityGuid to report data to
|
|
44
|
-
* @returns {object} Returns an object that contains the available API methods and configurations to use with the external caller. See loaders/api/api.js for more information.
|
|
40
|
+
* @param {import('./api/register-api-types').RegisterAPIConstructor} target the target object to report data to
|
|
41
|
+
@returns {import('./api/register-api-types').RegisterAPI} Returns an object that contains the available API methods and configurations to use with the external caller. See loaders/api/api.js for more information.
|
|
45
42
|
*/
|
|
46
43
|
register(target) {
|
|
47
44
|
return this.#callMethod(_constants.REGISTER, target);
|
|
@@ -51,7 +48,7 @@ class ApiBase {
|
|
|
51
48
|
* Records a custom event with a specified eventType and attributes.
|
|
52
49
|
* {@link https://docs.newrelic.com/docs/browser/new-relic-browser/browser-apis/recordCustomEvent/}
|
|
53
50
|
* @param {string} eventType The eventType to store the event as.
|
|
54
|
-
* @param {
|
|
51
|
+
* @param {Object} [attributes] JSON object with one or more key/value pairs. For example: {key:"value"}.
|
|
55
52
|
*/
|
|
56
53
|
recordCustomEvent(eventType, attributes) {
|
|
57
54
|
return this.#callMethod(_constants.RECORD_CUSTOM_EVENT, eventType, attributes);
|
|
@@ -227,11 +224,21 @@ class ApiBase {
|
|
|
227
224
|
* Measures a task that is recorded as a BrowserPerformance event.
|
|
228
225
|
* {@link https://docs.newrelic.com/docs/browser/new-relic-browser/browser-apis/measure/}
|
|
229
226
|
* @param {string} name The name of the task
|
|
230
|
-
* @param {object
|
|
227
|
+
* @param {{start: number, end: number, duration: number, customAttributes: object}} [options] An object used to control the way the measure API operates
|
|
231
228
|
* @returns {{start: number, end: number, duration: number, customAttributes: object}} Measurement details
|
|
232
229
|
*/
|
|
233
230
|
measure(name, options) {
|
|
234
231
|
return this.#callMethod(_constants.MEASURE, name, options);
|
|
235
232
|
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Accepts or rejects consent when the agent is configured to require consent before harvesting.
|
|
236
|
+
* The consent state is stored in session storage inside the NRBA_SESSION object.
|
|
237
|
+
* {@link https://docs.newrelic.com/docs/browser/new-relic-browser/browser-apis/consent/}
|
|
238
|
+
* @param {boolean?} accept Whether to accept or reject consent. Defaults to true (accept) if left undefined.
|
|
239
|
+
*/
|
|
240
|
+
consent(accept) {
|
|
241
|
+
return this.#callMethod(_constants.CONSENT, accept);
|
|
242
|
+
}
|
|
236
243
|
}
|
|
237
244
|
exports.ApiBase = ApiBase;
|
|
@@ -84,6 +84,8 @@
|
|
|
84
84
|
* @property {boolean} [spa.enabled] - Turn on/off the single page application feature (on by default). NOTE: the SPA feature is deprecated and under removal procedure.
|
|
85
85
|
* @property {boolean} [spa.autoStart] - If true, the agent will automatically start the single page application feature. Otherwise, it will be in a deferred state until the `start` API method is called.
|
|
86
86
|
* @property {boolean} [ssl] - If explicitly false, the agent will use HTTP instead of HTTPS. This setting should NOT be used.
|
|
87
|
+
* @property {Object} [browser_consent_mode]
|
|
88
|
+
* @property {boolean} [browser_consent_mode.enabled] - If true, the agent will use consent mode for whether to allow or disallow data harvest.
|
|
87
89
|
* @property {Object} [user_actions]
|
|
88
90
|
* @property {boolean} [user_actions.enabled] - Must be true to allow UserAction events to be captured.
|
|
89
91
|
* @property {Array<string>} [user_actions.elementAttributes] - List of HTML Element properties to be captured with UserAction events' target elements. This may help to identify the source element being interacted with in the UI.
|
|
@@ -17,9 +17,18 @@ const ReadOnly = {
|
|
|
17
17
|
version: VERSION,
|
|
18
18
|
originTime
|
|
19
19
|
};
|
|
20
|
+
const hiddenState = {
|
|
21
|
+
consented: false
|
|
22
|
+
};
|
|
20
23
|
const RuntimeModel = {
|
|
21
24
|
/** Agent-specific metadata found in the RUM call response. ex. entityGuid */
|
|
22
25
|
appMetadata: {},
|
|
26
|
+
get consented() {
|
|
27
|
+
return this.session?.state?.consent || hiddenState.consented;
|
|
28
|
+
},
|
|
29
|
+
set consented(value) {
|
|
30
|
+
hiddenState.consented = value;
|
|
31
|
+
},
|
|
23
32
|
customTransaction: undefined,
|
|
24
33
|
denyList: undefined,
|
|
25
34
|
disabled: false,
|
|
@@ -17,8 +17,10 @@ import { stringify } from '../util/stringify';
|
|
|
17
17
|
import { getSubmitMethod, xhr as xhrMethod, xhrFetch as fetchMethod } from '../util/submit-data';
|
|
18
18
|
import { activatedFeatures } from '../util/feature-flags';
|
|
19
19
|
import { dispatchGlobalEvent } from '../dispatch/global-event';
|
|
20
|
-
const
|
|
21
|
-
const
|
|
20
|
+
const RETRY = 'Harvester/Retry/';
|
|
21
|
+
const RETRY_ATTEMPTED = RETRY + 'Attempted/';
|
|
22
|
+
const RETRY_FAILED = RETRY + 'Failed/';
|
|
23
|
+
const RETRY_SUCCEEDED = RETRY + 'Succeeded/';
|
|
22
24
|
export class Harvester {
|
|
23
25
|
#started = false;
|
|
24
26
|
initializedAggregates = [];
|
|
@@ -59,11 +61,11 @@ export class Harvester {
|
|
|
59
61
|
endpointVersion: aggregateInst.harvestEndpointVersion || 1
|
|
60
62
|
};
|
|
61
63
|
if (aggregateInst.blocked) return output;
|
|
64
|
+
if (this.agentRef.init?.browser_consent_mode?.enabled && !this.agentRef.runtime.consented) return output;
|
|
62
65
|
const submitMethod = getSubmitMethod(localOpts);
|
|
63
66
|
if (!submitMethod) return output;
|
|
64
67
|
const shouldRetryOnFail = !localOpts.isFinalHarvest && submitMethod === xhrMethod; // always retry all features harvests except for final
|
|
65
|
-
output.payload =
|
|
66
|
-
|
|
68
|
+
output.payload = aggregateInst.makeHarvestPayload(shouldRetryOnFail, localOpts);
|
|
67
69
|
if (!output.payload) return output;
|
|
68
70
|
send(this.agentRef, {
|
|
69
71
|
endpoint: FEATURE_TO_ENDPOINT[aggregateInst.featureName],
|
|
@@ -85,7 +87,9 @@ export class Harvester {
|
|
|
85
87
|
function cbFinished(result) {
|
|
86
88
|
if (aggregateInst.harvestOpts.prevAttemptCode) {
|
|
87
89
|
// this means we just retried a harvest that last failed
|
|
88
|
-
handle(SUPPORTABILITY_METRIC_CHANNEL, [
|
|
90
|
+
const reportSM = message => handle(SUPPORTABILITY_METRIC_CHANNEL, [message], undefined, FEATURE_NAMES.metrics, aggregateInst.ee);
|
|
91
|
+
reportSM(RETRY_ATTEMPTED + aggregateInst.featureName);
|
|
92
|
+
reportSM((result.retry ? RETRY_FAILED : RETRY_SUCCEEDED) + aggregateInst.harvestOpts.prevAttemptCode);
|
|
89
93
|
delete aggregateInst.harvestOpts.prevAttemptCode; // always reset last observation so we don't falsely report again next harvest
|
|
90
94
|
// In case this re-attempt failed again, that'll be handled (re-marked again) next.
|
|
91
95
|
}
|
|
@@ -175,9 +179,9 @@ export function send(agentRef, {
|
|
|
175
179
|
status: this.status,
|
|
176
180
|
retry: shouldRetry(this.status),
|
|
177
181
|
fullUrl,
|
|
178
|
-
xhr: this
|
|
182
|
+
xhr: this,
|
|
183
|
+
responseText: this.responseText
|
|
179
184
|
};
|
|
180
|
-
if (localOpts.needResponse) cbResult.responseText = this.responseText;
|
|
181
185
|
cbFinished(cbResult);
|
|
182
186
|
|
|
183
187
|
/** temporary audit of consistency of harvest metadata flags */
|
|
@@ -191,9 +195,9 @@ export function send(agentRef, {
|
|
|
191
195
|
status,
|
|
192
196
|
retry: shouldRetry(status),
|
|
193
197
|
fullUrl,
|
|
194
|
-
fetchResponse: response
|
|
198
|
+
fetchResponse: response,
|
|
199
|
+
responseText: await response.text()
|
|
195
200
|
};
|
|
196
|
-
if (localOpts.needResponse) cbResult.responseText = await response.text();
|
|
197
201
|
cbFinished(cbResult);
|
|
198
202
|
/** temporary audit of consistency of harvest metadata flags */
|
|
199
203
|
if (!shouldRetry(status)) trackHarvestMetadata();
|
|
@@ -24,7 +24,6 @@
|
|
|
24
24
|
* @property {HarvestEndpointIdentifier} endpoint The endpoint to use (jserrors, events, resources etc.)
|
|
25
25
|
* @property {HarvestPayload} payload Object representing payload.
|
|
26
26
|
* @property {object} localOpts Additional options for sending data
|
|
27
|
-
* @property {boolean} localOpts.needResponse Specify whether the caller expects a response data.
|
|
28
27
|
* @property {boolean} localOpts.isFinalHarvest Specify whether the call is a final harvest during page unload.
|
|
29
28
|
* @property {boolean} localOpts.sendEmptyBody Specify whether the call should be made even if the body is empty. Useful for rum calls.
|
|
30
29
|
* @property {boolean} localOpts.forceNoRetry Don't save the buffered data in the case of a need to retry the transmission.
|
|
@@ -33,7 +33,8 @@ const model = {
|
|
|
33
33
|
serverTimeDiff: null,
|
|
34
34
|
// set by TimeKeeper; "undefined" value will not be stringified and stored but "null" will
|
|
35
35
|
custom: {},
|
|
36
|
-
numOfResets: 0
|
|
36
|
+
numOfResets: 0,
|
|
37
|
+
consent: false // set by consent() API call
|
|
37
38
|
};
|
|
38
39
|
export class SessionEntity {
|
|
39
40
|
/**
|
|
@@ -84,7 +85,8 @@ export class SessionEntity {
|
|
|
84
85
|
}) {
|
|
85
86
|
/** Ensure that certain properties are preserved across a reset if already set */
|
|
86
87
|
const persistentAttributes = {
|
|
87
|
-
serverTimeDiff: this.state.serverTimeDiff || model.serverTimeDiff
|
|
88
|
+
serverTimeDiff: this.state.serverTimeDiff || model.serverTimeDiff,
|
|
89
|
+
consent: this.state.consent || model.consent
|
|
88
90
|
};
|
|
89
91
|
this.state = {};
|
|
90
92
|
this.sync({
|
|
@@ -10,9 +10,14 @@
|
|
|
10
10
|
export function isValidMFETarget(target = {}) {
|
|
11
11
|
return !!(target.id && target.name);
|
|
12
12
|
}
|
|
13
|
+
export function hasValidValue(val) {
|
|
14
|
+
return typeof val === 'string' && val.trim().length < 501 || typeof val === 'number';
|
|
15
|
+
}
|
|
13
16
|
|
|
14
17
|
/**
|
|
15
18
|
* When given a valid target, returns an object with the MFE payload attributes. Returns an empty object otherwise.
|
|
19
|
+
* @note Field names may change as the schema is finalized
|
|
20
|
+
*
|
|
16
21
|
* @param {Object} [target] the registered target
|
|
17
22
|
* @param {AggregateInstance} [aggregateInstance] the aggregate instance calling the method
|
|
18
23
|
* @returns {{'mfe.id': *, 'mfe.name': String}|{}} returns an empty object if args are not supplied or the aggregate instance is not supporting version 2
|
|
@@ -28,11 +33,8 @@ export function getVersion2Attributes(target, aggregateInstance) {
|
|
|
28
33
|
}
|
|
29
34
|
return {
|
|
30
35
|
'mfe.id': target.id,
|
|
31
|
-
// these field names may change as the schema is finalized
|
|
32
36
|
'mfe.name': target.name,
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
// these field names may change as the schema is finalized
|
|
36
|
-
'parent.id': containerAgentEntityGuid
|
|
37
|
+
eventSource: target.eventSource,
|
|
38
|
+
'parent.id': target.parent?.id || containerAgentEntityGuid
|
|
37
39
|
};
|
|
38
40
|
}
|
|
@@ -129,12 +129,17 @@ export function wrapPromise(sharedEE) {
|
|
|
129
129
|
});
|
|
130
130
|
promiseEE.on('propagate', function (val, overwrite, trigger) {
|
|
131
131
|
if (!this.getCtx || overwrite) {
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
132
|
+
const selfStore = this;
|
|
133
|
+
const parentStore = val instanceof Promise ? promiseEE.context(val) : null;
|
|
134
|
+
let cachedCtx;
|
|
135
|
+
this.getCtx = function getCtx() {
|
|
136
|
+
if (cachedCtx) return cachedCtx;
|
|
137
|
+
if (parentStore && parentStore !== selfStore) {
|
|
138
|
+
cachedCtx = typeof parentStore.getCtx === 'function' ? parentStore.getCtx() : parentStore;
|
|
139
|
+
} else {
|
|
140
|
+
cachedCtx = selfStore;
|
|
136
141
|
}
|
|
137
|
-
return
|
|
142
|
+
return cachedCtx;
|
|
138
143
|
};
|
|
139
144
|
}
|
|
140
145
|
});
|
|
@@ -28,13 +28,13 @@ export class Aggregate extends AggregateBase {
|
|
|
28
28
|
return;
|
|
29
29
|
}
|
|
30
30
|
this.#trackSupportabilityMetrics();
|
|
31
|
-
registerHandler('api-recordCustomEvent', (timestamp, eventType, attributes) => {
|
|
31
|
+
registerHandler('api-recordCustomEvent', (timestamp, eventType, attributes, target) => {
|
|
32
32
|
if (RESERVED_EVENT_TYPES.includes(eventType)) return warn(46);
|
|
33
33
|
this.addEvent({
|
|
34
34
|
eventType,
|
|
35
35
|
timestamp: this.toEpoch(timestamp),
|
|
36
36
|
...attributes
|
|
37
|
-
});
|
|
37
|
+
}, target);
|
|
38
38
|
}, this.featureName, this.ee);
|
|
39
39
|
if (agentRef.init.page_action.enabled) {
|
|
40
40
|
registerHandler('api-addPageAction', (timestamp, name, attributes, target) => {
|
|
@@ -231,7 +231,7 @@ export class Aggregate extends AggregateBase {
|
|
|
231
231
|
}
|
|
232
232
|
}, this.featureName, this.ee);
|
|
233
233
|
}
|
|
234
|
-
registerHandler('api-measure', (args, n) => {
|
|
234
|
+
registerHandler('api-measure', (args, n, target) => {
|
|
235
235
|
const {
|
|
236
236
|
start,
|
|
237
237
|
duration,
|
|
@@ -245,7 +245,7 @@ export class Aggregate extends AggregateBase {
|
|
|
245
245
|
entryDuration: duration,
|
|
246
246
|
entryType: 'measure'
|
|
247
247
|
};
|
|
248
|
-
this.addEvent(event);
|
|
248
|
+
this.addEvent(event, target);
|
|
249
249
|
}, this.featureName, this.ee);
|
|
250
250
|
this.drain();
|
|
251
251
|
});
|
|
@@ -97,8 +97,7 @@ export class Aggregate extends AggregateBase {
|
|
|
97
97
|
common: {
|
|
98
98
|
/** Attributes in the `common` section are added to `all` logs generated in the payload */
|
|
99
99
|
attributes: {
|
|
100
|
-
...this.agentRef.info.jsAttributes,
|
|
101
|
-
// user-provided custom attributes
|
|
100
|
+
...applyFnToProps(this.agentRef.info.jsAttributes, this.obfuscator.obfuscateString.bind(this.obfuscator), 'string'),
|
|
102
101
|
...(this.harvestEndpointVersion === 1 && {
|
|
103
102
|
'entity.guid': this.agentRef.runtime.appMetadata.agents[0].entityGuid,
|
|
104
103
|
appId: this.agentRef.info.applicationID
|