@newrelic/browser-agent 1.302.0-rc.7 → 1.302.0-rc.8

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.
Files changed (59) hide show
  1. package/dist/cjs/common/config/init-types.js +2 -0
  2. package/dist/cjs/common/config/init.js +3 -0
  3. package/dist/cjs/common/constants/env.cdn.js +1 -1
  4. package/dist/cjs/common/constants/env.npm.js +1 -1
  5. package/dist/cjs/common/harvest/harvester.js +1 -0
  6. package/dist/cjs/common/session/session-entity.js +4 -2
  7. package/dist/cjs/features/page_view_event/aggregate/index.js +4 -2
  8. package/dist/cjs/features/page_view_event/instrument/index.js +0 -4
  9. package/dist/cjs/features/utils/agent-session.js +13 -0
  10. package/dist/cjs/features/utils/instrument-base.js +7 -8
  11. package/dist/cjs/loaders/agent.js +2 -0
  12. package/dist/cjs/loaders/api/consent.js +24 -0
  13. package/dist/cjs/loaders/api/constants.js +3 -2
  14. package/dist/cjs/loaders/api-base.js +10 -0
  15. package/dist/esm/common/config/init-types.js +2 -0
  16. package/dist/esm/common/config/init.js +3 -0
  17. package/dist/esm/common/constants/env.cdn.js +1 -1
  18. package/dist/esm/common/constants/env.npm.js +1 -1
  19. package/dist/esm/common/harvest/harvester.js +1 -0
  20. package/dist/esm/common/session/session-entity.js +4 -2
  21. package/dist/esm/features/page_view_event/aggregate/index.js +4 -2
  22. package/dist/esm/features/page_view_event/instrument/index.js +0 -4
  23. package/dist/esm/features/utils/agent-session.js +13 -0
  24. package/dist/esm/features/utils/instrument-base.js +7 -8
  25. package/dist/esm/loaders/agent.js +2 -0
  26. package/dist/esm/loaders/api/consent.js +17 -0
  27. package/dist/esm/loaders/api/constants.js +2 -1
  28. package/dist/esm/loaders/api-base.js +11 -1
  29. package/dist/tsconfig.tsbuildinfo +1 -1
  30. package/dist/types/common/config/init-types.d.ts +6 -0
  31. package/dist/types/common/config/init.d.ts.map +1 -1
  32. package/dist/types/common/harvest/harvester.d.ts.map +1 -1
  33. package/dist/types/common/session/session-entity.d.ts.map +1 -1
  34. package/dist/types/features/page_view_event/aggregate/index.d.ts +1 -0
  35. package/dist/types/features/page_view_event/aggregate/index.d.ts.map +1 -1
  36. package/dist/types/features/page_view_event/instrument/index.d.ts.map +1 -1
  37. package/dist/types/features/utils/agent-session.d.ts.map +1 -1
  38. package/dist/types/features/utils/instrument-base.d.ts +1 -0
  39. package/dist/types/features/utils/instrument-base.d.ts.map +1 -1
  40. package/dist/types/loaders/agent.d.ts.map +1 -1
  41. package/dist/types/loaders/api/consent.d.ts +2 -0
  42. package/dist/types/loaders/api/consent.d.ts.map +1 -0
  43. package/dist/types/loaders/api/constants.d.ts +1 -0
  44. package/dist/types/loaders/api/constants.d.ts.map +1 -1
  45. package/dist/types/loaders/api-base.d.ts +7 -0
  46. package/dist/types/loaders/api-base.d.ts.map +1 -1
  47. package/package.json +1 -1
  48. package/src/common/config/init-types.js +2 -0
  49. package/src/common/config/init.js +1 -0
  50. package/src/common/harvest/harvester.js +1 -0
  51. package/src/common/session/session-entity.js +6 -2
  52. package/src/features/page_view_event/aggregate/index.js +5 -2
  53. package/src/features/page_view_event/instrument/index.js +0 -4
  54. package/src/features/utils/agent-session.js +12 -0
  55. package/src/features/utils/instrument-base.js +7 -9
  56. package/src/loaders/agent.js +2 -0
  57. package/src/loaders/api/consent.js +18 -0
  58. package/src/loaders/api/constants.js +1 -0
  59. package/src/loaders/api-base.js +11 -1
@@ -89,6 +89,8 @@ exports.default = void 0;
89
89
  * @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.
90
90
  * @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.
91
91
  * @property {boolean} [ssl] - If explicitly false, the agent will use HTTP instead of HTTPS. This setting should NOT be used.
92
+ * @property {Object} [browser_consent_mode]
93
+ * @property {boolean} [browser_consent_mode.enabled] - If true, the agent will use consent mode for whether to allow or disallow data harvest.
92
94
  * @property {Object} [user_actions]
93
95
  * @property {boolean} [user_actions.enabled] - Must be true to allow UserAction events to be captured.
94
96
  * @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.
@@ -68,6 +68,9 @@ const InitModelFn = () => {
68
68
  },
69
69
  duplicate_registered_data: false
70
70
  },
71
+ browser_consent_mode: {
72
+ enabled: false
73
+ },
71
74
  distributed_tracing: {
72
75
  enabled: undefined,
73
76
  exclude_newrelic_header: undefined,
@@ -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.302.0-rc.7";
20
+ const VERSION = exports.VERSION = "1.302.0-rc.8";
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.302.0-rc.7";
20
+ const VERSION = exports.VERSION = "1.302.0-rc.8";
21
21
 
22
22
  /**
23
23
  * Exposes the build type of the agent
@@ -69,6 +69,7 @@ class Harvester {
69
69
  endpointVersion: aggregateInst.harvestEndpointVersion || 1
70
70
  };
71
71
  if (aggregateInst.blocked) return output;
72
+ if (this.agentRef.init?.browser_consent_mode?.enabled && !this.agentRef.runtime?.session?.state?.consent) return output;
72
73
  const submitMethod = (0, _submitData.getSubmitMethod)(localOpts);
73
74
  if (!submitMethod) return output;
74
75
  const shouldRetryOnFail = !localOpts.isFinalHarvest && submitMethod === _submitData.xhr; // always retry all features harvests except for final
@@ -39,7 +39,8 @@ const model = {
39
39
  serverTimeDiff: null,
40
40
  // set by TimeKeeper; "undefined" value will not be stringified and stored but "null" will
41
41
  custom: {},
42
- numOfResets: 0
42
+ numOfResets: 0,
43
+ consent: false // set by consent() API call
43
44
  };
44
45
  class SessionEntity {
45
46
  /**
@@ -90,7 +91,8 @@ class SessionEntity {
90
91
  }) {
91
92
  /** Ensure that certain properties are preserved across a reset if already set */
92
93
  const persistentAttributes = {
93
- serverTimeDiff: this.state.serverTimeDiff || model.serverTimeDiff
94
+ serverTimeDiff: this.state.serverTimeDiff || model.serverTimeDiff,
95
+ consent: this.state.consent || model.consent
94
96
  };
95
97
  this.state = {};
96
98
  this.sync({
@@ -32,6 +32,8 @@ class Aggregate extends _aggregateBase.AggregateBase {
32
32
  static featureName = CONSTANTS.FEATURE_NAME;
33
33
  constructor(agentRef) {
34
34
  super(agentRef, CONSTANTS.FEATURE_NAME);
35
+ this.sentRum = false; // flag to facilitate calling sendRum() once externally (by the consent API in agent-session.js)
36
+
35
37
  this.timeToFirstByte = 0;
36
38
  this.firstByteToWindowLoad = 0; // our "frontend" duration
37
39
  this.firstByteToDomContent = 0; // our "dom processing" duration
@@ -125,9 +127,9 @@ class Aggregate extends _aggregateBase.AggregateBase {
125
127
  return queryParameters;
126
128
  };
127
129
  this.events.add(body);
128
- this.agentRef.runtime.harvester.triggerHarvestFor(this, {
130
+ if (this.agentRef.runtime.harvester.triggerHarvestFor(this, {
129
131
  sendEmptyBody: true
130
- });
132
+ }).ranSend) this.sentRum = true;
131
133
  }
132
134
  serializer(eventBuffer) {
133
135
  // this is necessary because PVE sends a single item rather than an array; in the case of undefined, this prevents sending [null] as body
@@ -4,7 +4,6 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.PageViewEvent = exports.Instrument = void 0;
7
- var _handle = require("../../../common/event-emitter/handle");
8
7
  var _setPageViewName = require("../../../loaders/api/setPageViewName");
9
8
  var _instrumentBase = require("../../utils/instrument-base");
10
9
  var CONSTANTS = _interopRequireWildcard(require("../constants"));
@@ -25,9 +24,6 @@ class Instrument extends _instrumentBase.InstrumentBase {
25
24
 
26
25
  /** feature specific APIs */
27
26
  (0, _setPageViewName.setupSetPageViewNameAPI)(agentRef);
28
-
29
- /** messages from the register API that can trigger a new RUM call */
30
- this.ee.on('api-send-rum', (attrs, target) => (0, _handle.handle)('send-rum', [attrs, target], undefined, this.featureName, this.ee));
31
27
  this.importAggregator(agentRef, () => Promise.resolve().then(() => _interopRequireWildcard(require(/* webpackChunkName: "page_view_event-aggregate" */'../aggregate'))));
32
28
  }
33
29
  setupInspectionEvents(agentIdentifier) {
@@ -59,6 +59,19 @@ function setupAgentSession(agentRef) {
59
59
  (0, _registerHandler.registerHandler)('api-setUserId', (time, key, value) => {
60
60
  agentRef.runtime.session.syncCustomAttribute(key, value);
61
61
  }, 'session', sharedEE);
62
+ (0, _registerHandler.registerHandler)('api-consent', accept => {
63
+ agentRef.runtime.session.write({
64
+ consent: accept === undefined ? true : accept
65
+ });
66
+
67
+ // call sendRum if it wasn't called yet
68
+ agentRef.features.page_view_event.onAggregateImported.then(loaded => {
69
+ const pveAgg = agentRef.features.page_view_event.featAggregate;
70
+ if (loaded && !pveAgg.sentRum) {
71
+ pveAgg.sendRum();
72
+ }
73
+ });
74
+ }, 'session', sharedEE);
62
75
  (0, _drain.drain)(agentRef.agentIdentifier, 'session');
63
76
  return agentRef.runtime.session;
64
77
  }
@@ -50,7 +50,10 @@ class InstrumentBase extends _featureBase.FeatureBase {
50
50
  * @type {Promise} Assigned immediately after @see importAggregator runs. Serves as a signal for when the inner async fn finishes execution. Useful for features to await
51
51
  * one another if there are inter-features dependencies.
52
52
  */
53
- this.onAggregateImported = undefined;
53
+ this.loadedSuccessfully = undefined;
54
+ this.onAggregateImported = new Promise(resolve => {
55
+ this.loadedSuccessfully = resolve;
56
+ });
54
57
 
55
58
  /**
56
59
  * used in conjunction with newrelic.start() to defer harvesting in features
@@ -82,10 +85,6 @@ class InstrumentBase extends _featureBase.FeatureBase {
82
85
  */
83
86
  importAggregator(agentRef, fetchAggregator, argsObjFromInstrument = {}) {
84
87
  if (this.featAggregate) return;
85
- let loadedSuccessfully;
86
- this.onAggregateImported = new Promise(resolve => {
87
- loadedSuccessfully = resolve;
88
- });
89
88
  const importLater = async () => {
90
89
  // wait for the deferred promise to resolve before proceeding
91
90
  // this will resolve immediately if the feature is auto-started,
@@ -113,7 +112,7 @@ class InstrumentBase extends _featureBase.FeatureBase {
113
112
  try {
114
113
  if (!this.#shouldImportAgg(this.featureName, session, agentRef.init)) {
115
114
  (0, _drain.drain)(this.agentIdentifier, this.featureName);
116
- loadedSuccessfully(false); // aggregate module isn't loaded at all
115
+ this.loadedSuccessfully(false); // aggregate module isn't loaded at all
117
116
  return;
118
117
  }
119
118
  const {
@@ -121,13 +120,13 @@ class InstrumentBase extends _featureBase.FeatureBase {
121
120
  } = await fetchAggregator();
122
121
  this.featAggregate = new Aggregate(agentRef, argsObjFromInstrument);
123
122
  agentRef.runtime.harvester.initializedAggregates.push(this.featAggregate); // "subscribe" the feature to future harvest intervals (PVE will start the timer)
124
- loadedSuccessfully(true);
123
+ this.loadedSuccessfully(true);
125
124
  } catch (e) {
126
125
  (0, _console.warn)(34, e);
127
126
  this.abortHandler?.(); // undo any important alterations made to the page
128
127
  // not supported yet but nice to do: "abort" this agent's EE for this feature specifically
129
128
  (0, _drain.drain)(this.agentIdentifier, this.featureName, true);
130
- loadedSuccessfully(false);
129
+ this.loadedSuccessfully(false);
131
130
  if (this.ee) this.ee.abort();
132
131
  }
133
132
  };
@@ -19,6 +19,7 @@ var _setCustomAttribute = require("./api/setCustomAttribute");
19
19
  var _setUserId = require("./api/setUserId");
20
20
  var _setApplicationVersion = require("./api/setApplicationVersion");
21
21
  var _start = require("./api/start");
22
+ var _consent = require("./api/consent");
22
23
  /**
23
24
  * Copyright 2020-2025 New Relic, Inc. All rights reserved.
24
25
  * SPDX-License-Identifier: Apache-2.0
@@ -77,6 +78,7 @@ class Agent extends _agentBase.AgentBase {
77
78
  (0, _setUserId.setupSetUserIdAPI)(this);
78
79
  (0, _setApplicationVersion.setupSetApplicationVersionAPI)(this);
79
80
  (0, _start.setupStartAPI)(this);
81
+ (0, _consent.setupConsentAPI)(this);
80
82
  this.run();
81
83
  }
82
84
  get config() {
@@ -0,0 +1,24 @@
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) {
18
+ if (accept !== undefined && typeof accept !== 'boolean') {
19
+ (0, _console.warn)(65, typeof accept);
20
+ return;
21
+ }
22
+ (0, _handle.handle)(_constants.prefix + _constants.CONSENT, [accept], undefined, 'session', agent.ee);
23
+ }, agent);
24
+ }
@@ -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';
@@ -230,5 +230,15 @@ class ApiBase {
230
230
  measure(name, options) {
231
231
  return this.#callMethod(_constants.MEASURE, name, options);
232
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
+ }
233
243
  }
234
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.
@@ -62,6 +62,9 @@ const InitModelFn = () => {
62
62
  },
63
63
  duplicate_registered_data: false
64
64
  },
65
+ browser_consent_mode: {
66
+ enabled: false
67
+ },
65
68
  distributed_tracing: {
66
69
  enabled: undefined,
67
70
  exclude_newrelic_header: undefined,
@@ -11,7 +11,7 @@
11
11
  /**
12
12
  * Exposes the version of the agent
13
13
  */
14
- export const VERSION = "1.302.0-rc.7";
14
+ export const VERSION = "1.302.0-rc.8";
15
15
 
16
16
  /**
17
17
  * Exposes the build type of the agent
@@ -11,7 +11,7 @@
11
11
  /**
12
12
  * Exposes the version of the agent
13
13
  */
14
- export const VERSION = "1.302.0-rc.7";
14
+ export const VERSION = "1.302.0-rc.8";
15
15
 
16
16
  /**
17
17
  * Exposes the build type of the agent
@@ -61,6 +61,7 @@ export class Harvester {
61
61
  endpointVersion: aggregateInst.harvestEndpointVersion || 1
62
62
  };
63
63
  if (aggregateInst.blocked) return output;
64
+ if (this.agentRef.init?.browser_consent_mode?.enabled && !this.agentRef.runtime?.session?.state?.consent) return output;
64
65
  const submitMethod = getSubmitMethod(localOpts);
65
66
  if (!submitMethod) return output;
66
67
  const shouldRetryOnFail = !localOpts.isFinalHarvest && submitMethod === xhrMethod; // always retry all features harvests except for final
@@ -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({
@@ -24,6 +24,8 @@ export class Aggregate extends AggregateBase {
24
24
  static featureName = CONSTANTS.FEATURE_NAME;
25
25
  constructor(agentRef) {
26
26
  super(agentRef, CONSTANTS.FEATURE_NAME);
27
+ this.sentRum = false; // flag to facilitate calling sendRum() once externally (by the consent API in agent-session.js)
28
+
27
29
  this.timeToFirstByte = 0;
28
30
  this.firstByteToWindowLoad = 0; // our "frontend" duration
29
31
  this.firstByteToDomContent = 0; // our "dom processing" duration
@@ -117,9 +119,9 @@ export class Aggregate extends AggregateBase {
117
119
  return queryParameters;
118
120
  };
119
121
  this.events.add(body);
120
- this.agentRef.runtime.harvester.triggerHarvestFor(this, {
122
+ if (this.agentRef.runtime.harvester.triggerHarvestFor(this, {
121
123
  sendEmptyBody: true
122
- });
124
+ }).ranSend) this.sentRum = true;
123
125
  }
124
126
  serializer(eventBuffer) {
125
127
  // this is necessary because PVE sends a single item rather than an array; in the case of undefined, this prevents sending [null] as body
@@ -2,7 +2,6 @@
2
2
  * Copyright 2020-2025 New Relic, Inc. All rights reserved.
3
3
  * SPDX-License-Identifier: Apache-2.0
4
4
  */
5
- import { handle } from '../../../common/event-emitter/handle';
6
5
  import { setupSetPageViewNameAPI } from '../../../loaders/api/setPageViewName';
7
6
  import { InstrumentBase } from '../../utils/instrument-base';
8
7
  import * as CONSTANTS from '../constants';
@@ -19,9 +18,6 @@ export class Instrument extends InstrumentBase {
19
18
 
20
19
  /** feature specific APIs */
21
20
  setupSetPageViewNameAPI(agentRef);
22
-
23
- /** messages from the register API that can trigger a new RUM call */
24
- this.ee.on('api-send-rum', (attrs, target) => handle('send-rum', [attrs, target], undefined, this.featureName, this.ee));
25
21
  this.importAggregator(agentRef, () => import(/* webpackChunkName: "page_view_event-aggregate" */'../aggregate'));
26
22
  }
27
23
  setupInspectionEvents(agentIdentifier) {
@@ -52,6 +52,19 @@ export function setupAgentSession(agentRef) {
52
52
  registerHandler('api-setUserId', (time, key, value) => {
53
53
  agentRef.runtime.session.syncCustomAttribute(key, value);
54
54
  }, 'session', sharedEE);
55
+ registerHandler('api-consent', accept => {
56
+ agentRef.runtime.session.write({
57
+ consent: accept === undefined ? true : accept
58
+ });
59
+
60
+ // call sendRum if it wasn't called yet
61
+ agentRef.features.page_view_event.onAggregateImported.then(loaded => {
62
+ const pveAgg = agentRef.features.page_view_event.featAggregate;
63
+ if (loaded && !pveAgg.sentRum) {
64
+ pveAgg.sendRum();
65
+ }
66
+ });
67
+ }, 'session', sharedEE);
55
68
  drain(agentRef.agentIdentifier, 'session');
56
69
  return agentRef.runtime.session;
57
70
  }
@@ -48,7 +48,10 @@ export class InstrumentBase extends FeatureBase {
48
48
  * @type {Promise} Assigned immediately after @see importAggregator runs. Serves as a signal for when the inner async fn finishes execution. Useful for features to await
49
49
  * one another if there are inter-features dependencies.
50
50
  */
51
- this.onAggregateImported = undefined;
51
+ this.loadedSuccessfully = undefined;
52
+ this.onAggregateImported = new Promise(resolve => {
53
+ this.loadedSuccessfully = resolve;
54
+ });
52
55
 
53
56
  /**
54
57
  * used in conjunction with newrelic.start() to defer harvesting in features
@@ -80,10 +83,6 @@ export class InstrumentBase extends FeatureBase {
80
83
  */
81
84
  importAggregator(agentRef, fetchAggregator, argsObjFromInstrument = {}) {
82
85
  if (this.featAggregate) return;
83
- let loadedSuccessfully;
84
- this.onAggregateImported = new Promise(resolve => {
85
- loadedSuccessfully = resolve;
86
- });
87
86
  const importLater = async () => {
88
87
  // wait for the deferred promise to resolve before proceeding
89
88
  // this will resolve immediately if the feature is auto-started,
@@ -111,7 +110,7 @@ export class InstrumentBase extends FeatureBase {
111
110
  try {
112
111
  if (!this.#shouldImportAgg(this.featureName, session, agentRef.init)) {
113
112
  drain(this.agentIdentifier, this.featureName);
114
- loadedSuccessfully(false); // aggregate module isn't loaded at all
113
+ this.loadedSuccessfully(false); // aggregate module isn't loaded at all
115
114
  return;
116
115
  }
117
116
  const {
@@ -119,13 +118,13 @@ export class InstrumentBase extends FeatureBase {
119
118
  } = await fetchAggregator();
120
119
  this.featAggregate = new Aggregate(agentRef, argsObjFromInstrument);
121
120
  agentRef.runtime.harvester.initializedAggregates.push(this.featAggregate); // "subscribe" the feature to future harvest intervals (PVE will start the timer)
122
- loadedSuccessfully(true);
121
+ this.loadedSuccessfully(true);
123
122
  } catch (e) {
124
123
  warn(34, e);
125
124
  this.abortHandler?.(); // undo any important alterations made to the page
126
125
  // not supported yet but nice to do: "abort" this agent's EE for this feature specifically
127
126
  drain(this.agentIdentifier, this.featureName, true);
128
- loadedSuccessfully(false);
127
+ this.loadedSuccessfully(false);
129
128
  if (this.ee) this.ee.abort();
130
129
  }
131
130
  };
@@ -23,6 +23,7 @@ import { setupSetCustomAttributeAPI } from './api/setCustomAttribute';
23
23
  import { setupSetUserIdAPI } from './api/setUserId';
24
24
  import { setupSetApplicationVersionAPI } from './api/setApplicationVersion';
25
25
  import { setupStartAPI } from './api/start';
26
+ import { setupConsentAPI } from './api/consent';
26
27
 
27
28
  /**
28
29
  * @typedef {Object} AgentOptions
@@ -67,6 +68,7 @@ export class Agent extends AgentBase {
67
68
  setupSetUserIdAPI(this);
68
69
  setupSetApplicationVersionAPI(this);
69
70
  setupStartAPI(this);
71
+ setupConsentAPI(this);
70
72
  this.run();
71
73
  }
72
74
  get config() {
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Copyright 2020-2025 New Relic, Inc. All rights reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+ import { prefix, CONSENT } from './constants';
6
+ import { setupAPI } from './sharedHandlers';
7
+ import { handle } from '../../common/event-emitter/handle';
8
+ import { warn } from '../../common/util/console';
9
+ export function setupConsentAPI(agent) {
10
+ setupAPI(CONSENT, function (accept) {
11
+ if (accept !== undefined && typeof accept !== 'boolean') {
12
+ warn(65, typeof accept);
13
+ return;
14
+ }
15
+ handle(prefix + CONSENT, [accept], undefined, 'session', agent.ee);
16
+ }, agent);
17
+ }
@@ -23,4 +23,5 @@ export const SET_PAGE_VIEW_NAME = 'setPageViewName';
23
23
  export const SET_USER_ID = 'setUserId';
24
24
  export const START = 'start';
25
25
  export const WRAP_LOGGER = 'wrapLogger';
26
- export const MEASURE = 'measure';
26
+ export const MEASURE = 'measure';
27
+ export const CONSENT = 'consent';
@@ -3,7 +3,7 @@
3
3
  * SPDX-License-Identifier: Apache-2.0
4
4
  */
5
5
  import { warn } from '../common/util/console';
6
- import { ADD_PAGE_ACTION, ADD_RELEASE, ADD_TO_TRACE, FINISHED, INTERACTION, LOG, NOTICE_ERROR, PAUSE_REPLAY, RECORD_CUSTOM_EVENT, RECORD_REPLAY, REGISTER, SET_APPLICATION_VERSION, SET_CURRENT_ROUTE_NAME, SET_CUSTOM_ATTRIBUTE, SET_ERROR_HANDLER, SET_PAGE_VIEW_NAME, SET_USER_ID, START, WRAP_LOGGER, MEASURE } from './api/constants';
6
+ import { ADD_PAGE_ACTION, ADD_RELEASE, ADD_TO_TRACE, CONSENT, FINISHED, INTERACTION, LOG, NOTICE_ERROR, PAUSE_REPLAY, RECORD_CUSTOM_EVENT, RECORD_REPLAY, REGISTER, SET_APPLICATION_VERSION, SET_CURRENT_ROUTE_NAME, SET_CUSTOM_ATTRIBUTE, SET_ERROR_HANDLER, SET_PAGE_VIEW_NAME, SET_USER_ID, START, WRAP_LOGGER, MEASURE } from './api/constants';
7
7
 
8
8
  /**
9
9
  * @typedef {import('./api/interaction-types').InteractionInstance} InteractionInstance
@@ -224,4 +224,14 @@ export class ApiBase {
224
224
  measure(name, options) {
225
225
  return this.#callMethod(MEASURE, name, options);
226
226
  }
227
+
228
+ /**
229
+ * Accepts or rejects consent when the agent is configured to require consent before harvesting.
230
+ * The consent state is stored in session storage inside the NRBA_SESSION object.
231
+ * {@link https://docs.newrelic.com/docs/browser/new-relic-browser/browser-apis/consent/}
232
+ * @param {boolean?} accept Whether to accept or reject consent. Defaults to true (accept) if left undefined.
233
+ */
234
+ consent(accept) {
235
+ return this.#callMethod(CONSENT, accept);
236
+ }
227
237
  }
@@ -1 +1 @@
1
- {"root":["../src/index.js","../src/cdn/experimental.js","../src/cdn/lite.js","../src/cdn/pro.js","../src/cdn/spa.js","../src/common/aggregate/aggregator.js","../src/common/aggregate/event-aggregator.js","../src/common/config/configurable.js","../src/common/config/info.js","../src/common/config/init-types.js","../src/common/config/init.js","../src/common/config/loader-config.js","../src/common/config/runtime.js","../src/common/constants/agent-constants.js","../src/common/constants/env.cdn.js","../src/common/constants/env.js","../src/common/constants/env.npm.js","../src/common/constants/runtime.js","../src/common/constants/shared-channel.js","../src/common/deny-list/deny-list.js","../src/common/dispatch/global-event.js","../src/common/dom/iframe.js","../src/common/dom/query-selector.js","../src/common/dom/selector-path.js","../src/common/drain/drain.js","../src/common/event-emitter/contextual-ee.js","../src/common/event-emitter/event-context.js","../src/common/event-emitter/handle.js","../src/common/event-emitter/register-handler.js","../src/common/event-listener/event-listener-opts.js","../src/common/harvest/harvester.js","../src/common/harvest/types.js","../src/common/ids/bundle-id.js","../src/common/ids/id.js","../src/common/ids/unique-id.js","../src/common/serialize/bel-serializer.js","../src/common/session/constants.js","../src/common/session/session-entity.js","../src/common/storage/local-storage.js","../src/common/timer/interaction-timer.js","../src/common/timer/timer.js","../src/common/timing/nav-timing.js","../src/common/timing/now.js","../src/common/timing/time-keeper.js","../src/common/unload/eol.js","../src/common/url/canonicalize-url.js","../src/common/url/clean-url.js","../src/common/url/encode.js","../src/common/url/extract-url.js","../src/common/url/location.js","../src/common/url/parse-url.js","../src/common/url/protocol.js","../src/common/util/attribute-size.js","../src/common/util/console.js","../src/common/util/data-size.js","../src/common/util/event-origin.js","../src/common/util/feature-flags.js","../src/common/util/get-or-set.js","../src/common/util/invoke.js","../src/common/util/mfe.js","../src/common/util/monkey-patched.js","../src/common/util/obfuscate.js","../src/common/util/stringify.js","../src/common/util/submit-data.js","../src/common/util/text.js","../src/common/util/traverse.js","../src/common/util/type-check.js","../src/common/vitals/constants.js","../src/common/vitals/cumulative-layout-shift.js","../src/common/vitals/first-contentful-paint.js","../src/common/vitals/first-paint.js","../src/common/vitals/interaction-to-next-paint.js","../src/common/vitals/largest-contentful-paint.js","../src/common/vitals/time-to-first-byte.js","../src/common/vitals/vital-metric.js","../src/common/window/load.js","../src/common/window/nreum.js","../src/common/window/page-visibility.js","../src/common/wrap/wrap-events.js","../src/common/wrap/wrap-fetch.js","../src/common/wrap/wrap-function.js","../src/common/wrap/wrap-history.js","../src/common/wrap/wrap-jsonp.js","../src/common/wrap/wrap-logger.js","../src/common/wrap/wrap-mutation.js","../src/common/wrap/wrap-promise.js","../src/common/wrap/wrap-timer.js","../src/common/wrap/wrap-websocket.js","../src/common/wrap/wrap-xhr.js","../src/features/ajax/constants.js","../src/features/ajax/index.js","../src/features/ajax/aggregate/gql.js","../src/features/ajax/aggregate/index.js","../src/features/ajax/instrument/distributed-tracing.js","../src/features/ajax/instrument/index.js","../src/features/ajax/instrument/response-size.js","../src/features/generic_events/constants.js","../src/features/generic_events/index.js","../src/features/generic_events/aggregate/index.js","../src/features/generic_events/aggregate/user-actions/aggregated-user-action.js","../src/features/generic_events/aggregate/user-actions/user-actions-aggregator.js","../src/features/generic_events/instrument/index.js","../src/features/jserrors/constants.js","../src/features/jserrors/index.js","../src/features/jserrors/aggregate/canonical-function-name.js","../src/features/jserrors/aggregate/cause-string.js","../src/features/jserrors/aggregate/compute-stack-trace.js","../src/features/jserrors/aggregate/format-stack-trace.js","../src/features/jserrors/aggregate/index.js","../src/features/jserrors/aggregate/internal-errors.js","../src/features/jserrors/aggregate/string-hash-code.js","../src/features/jserrors/instrument/index.js","../src/features/jserrors/shared/cast-error.js","../src/features/jserrors/shared/uncaught-error.js","../src/features/logging/constants.js","../src/features/logging/index.js","../src/features/logging/aggregate/index.js","../src/features/logging/instrument/index.js","../src/features/logging/shared/log.js","../src/features/logging/shared/utils.js","../src/features/metrics/constants.js","../src/features/metrics/index.js","../src/features/metrics/aggregate/framework-detection.js","../src/features/metrics/aggregate/harvest-metadata.js","../src/features/metrics/aggregate/index.js","../src/features/metrics/aggregate/websocket-detection.js","../src/features/metrics/instrument/index.js","../src/features/page_action/constants.js","../src/features/page_action/index.js","../src/features/page_action/instrument/index.js","../src/features/page_view_event/constants.js","../src/features/page_view_event/index.js","../src/features/page_view_event/aggregate/index.js","../src/features/page_view_event/aggregate/initialized-features.js","../src/features/page_view_event/instrument/index.js","../src/features/page_view_timing/constants.js","../src/features/page_view_timing/index.js","../src/features/page_view_timing/aggregate/index.js","../src/features/page_view_timing/instrument/index.js","../src/features/session_replay/constants.js","../src/features/session_replay/index.js","../src/features/session_replay/aggregate/index.js","../src/features/session_replay/instrument/index.js","../src/features/session_replay/shared/recorder-events.js","../src/features/session_replay/shared/recorder.js","../src/features/session_replay/shared/stylesheet-evaluator.js","../src/features/session_replay/shared/utils.js","../src/features/session_trace/constants.js","../src/features/session_trace/index.js","../src/features/session_trace/aggregate/index.js","../src/features/session_trace/aggregate/trace/node.js","../src/features/session_trace/aggregate/trace/storage.js","../src/features/session_trace/aggregate/trace/utils.js","../src/features/session_trace/instrument/index.js","../src/features/soft_navigations/constants.js","../src/features/soft_navigations/index.js","../src/features/soft_navigations/aggregate/ajax-node.js","../src/features/soft_navigations/aggregate/bel-node.js","../src/features/soft_navigations/aggregate/index.js","../src/features/soft_navigations/aggregate/initial-page-load-interaction.js","../src/features/soft_navigations/aggregate/interaction.js","../src/features/soft_navigations/instrument/index.js","../src/features/spa/constants.js","../src/features/spa/index.js","../src/features/spa/aggregate/index.js","../src/features/spa/aggregate/interaction-node.js","../src/features/spa/aggregate/interaction.js","../src/features/spa/aggregate/serializer.js","../src/features/spa/instrument/index.js","../src/features/utils/agent-session.js","../src/features/utils/aggregate-base.js","../src/features/utils/event-buffer.js","../src/features/utils/feature-base.js","../src/features/utils/feature-gates.js","../src/features/utils/instrument-base.js","../src/features/utils/nr1-debugger.js","../src/interfaces/registered-entity.js","../src/loaders/agent-base.js","../src/loaders/agent.js","../src/loaders/api-base.js","../src/loaders/browser-agent.js","../src/loaders/micro-agent-base.js","../src/loaders/micro-agent.js","../src/loaders/api/addPageAction.js","../src/loaders/api/addRelease.js","../src/loaders/api/addToTrace.js","../src/loaders/api/constants.js","../src/loaders/api/finished.js","../src/loaders/api/interaction-types.js","../src/loaders/api/interaction.js","../src/loaders/api/log.js","../src/loaders/api/measure.js","../src/loaders/api/noticeError.js","../src/loaders/api/pauseReplay.js","../src/loaders/api/recordCustomEvent.js","../src/loaders/api/recordReplay.js","../src/loaders/api/register-api-types.js","../src/loaders/api/register.js","../src/loaders/api/setApplicationVersion.js","../src/loaders/api/setCustomAttribute.js","../src/loaders/api/setErrorHandler.js","../src/loaders/api/setPageViewName.js","../src/loaders/api/setUserId.js","../src/loaders/api/sharedHandlers.js","../src/loaders/api/start.js","../src/loaders/api/topLevelCallers.js","../src/loaders/api/wrapLogger.js","../src/loaders/configure/configure.js","../src/loaders/configure/nonce.js","../src/loaders/configure/public-path.js","../src/loaders/features/enabled-features.js","../src/loaders/features/featureDependencies.js","../src/loaders/features/features.js"],"version":"5.9.3"}
1
+ {"root":["../src/index.js","../src/cdn/experimental.js","../src/cdn/lite.js","../src/cdn/pro.js","../src/cdn/spa.js","../src/common/aggregate/aggregator.js","../src/common/aggregate/event-aggregator.js","../src/common/config/configurable.js","../src/common/config/info.js","../src/common/config/init-types.js","../src/common/config/init.js","../src/common/config/loader-config.js","../src/common/config/runtime.js","../src/common/constants/agent-constants.js","../src/common/constants/env.cdn.js","../src/common/constants/env.js","../src/common/constants/env.npm.js","../src/common/constants/runtime.js","../src/common/constants/shared-channel.js","../src/common/deny-list/deny-list.js","../src/common/dispatch/global-event.js","../src/common/dom/iframe.js","../src/common/dom/query-selector.js","../src/common/dom/selector-path.js","../src/common/drain/drain.js","../src/common/event-emitter/contextual-ee.js","../src/common/event-emitter/event-context.js","../src/common/event-emitter/handle.js","../src/common/event-emitter/register-handler.js","../src/common/event-listener/event-listener-opts.js","../src/common/harvest/harvester.js","../src/common/harvest/types.js","../src/common/ids/bundle-id.js","../src/common/ids/id.js","../src/common/ids/unique-id.js","../src/common/serialize/bel-serializer.js","../src/common/session/constants.js","../src/common/session/session-entity.js","../src/common/storage/local-storage.js","../src/common/timer/interaction-timer.js","../src/common/timer/timer.js","../src/common/timing/nav-timing.js","../src/common/timing/now.js","../src/common/timing/time-keeper.js","../src/common/unload/eol.js","../src/common/url/canonicalize-url.js","../src/common/url/clean-url.js","../src/common/url/encode.js","../src/common/url/extract-url.js","../src/common/url/location.js","../src/common/url/parse-url.js","../src/common/url/protocol.js","../src/common/util/attribute-size.js","../src/common/util/console.js","../src/common/util/data-size.js","../src/common/util/event-origin.js","../src/common/util/feature-flags.js","../src/common/util/get-or-set.js","../src/common/util/invoke.js","../src/common/util/mfe.js","../src/common/util/monkey-patched.js","../src/common/util/obfuscate.js","../src/common/util/stringify.js","../src/common/util/submit-data.js","../src/common/util/text.js","../src/common/util/traverse.js","../src/common/util/type-check.js","../src/common/vitals/constants.js","../src/common/vitals/cumulative-layout-shift.js","../src/common/vitals/first-contentful-paint.js","../src/common/vitals/first-paint.js","../src/common/vitals/interaction-to-next-paint.js","../src/common/vitals/largest-contentful-paint.js","../src/common/vitals/time-to-first-byte.js","../src/common/vitals/vital-metric.js","../src/common/window/load.js","../src/common/window/nreum.js","../src/common/window/page-visibility.js","../src/common/wrap/wrap-events.js","../src/common/wrap/wrap-fetch.js","../src/common/wrap/wrap-function.js","../src/common/wrap/wrap-history.js","../src/common/wrap/wrap-jsonp.js","../src/common/wrap/wrap-logger.js","../src/common/wrap/wrap-mutation.js","../src/common/wrap/wrap-promise.js","../src/common/wrap/wrap-timer.js","../src/common/wrap/wrap-websocket.js","../src/common/wrap/wrap-xhr.js","../src/features/ajax/constants.js","../src/features/ajax/index.js","../src/features/ajax/aggregate/gql.js","../src/features/ajax/aggregate/index.js","../src/features/ajax/instrument/distributed-tracing.js","../src/features/ajax/instrument/index.js","../src/features/ajax/instrument/response-size.js","../src/features/generic_events/constants.js","../src/features/generic_events/index.js","../src/features/generic_events/aggregate/index.js","../src/features/generic_events/aggregate/user-actions/aggregated-user-action.js","../src/features/generic_events/aggregate/user-actions/user-actions-aggregator.js","../src/features/generic_events/instrument/index.js","../src/features/jserrors/constants.js","../src/features/jserrors/index.js","../src/features/jserrors/aggregate/canonical-function-name.js","../src/features/jserrors/aggregate/cause-string.js","../src/features/jserrors/aggregate/compute-stack-trace.js","../src/features/jserrors/aggregate/format-stack-trace.js","../src/features/jserrors/aggregate/index.js","../src/features/jserrors/aggregate/internal-errors.js","../src/features/jserrors/aggregate/string-hash-code.js","../src/features/jserrors/instrument/index.js","../src/features/jserrors/shared/cast-error.js","../src/features/jserrors/shared/uncaught-error.js","../src/features/logging/constants.js","../src/features/logging/index.js","../src/features/logging/aggregate/index.js","../src/features/logging/instrument/index.js","../src/features/logging/shared/log.js","../src/features/logging/shared/utils.js","../src/features/metrics/constants.js","../src/features/metrics/index.js","../src/features/metrics/aggregate/framework-detection.js","../src/features/metrics/aggregate/harvest-metadata.js","../src/features/metrics/aggregate/index.js","../src/features/metrics/aggregate/websocket-detection.js","../src/features/metrics/instrument/index.js","../src/features/page_action/constants.js","../src/features/page_action/index.js","../src/features/page_action/instrument/index.js","../src/features/page_view_event/constants.js","../src/features/page_view_event/index.js","../src/features/page_view_event/aggregate/index.js","../src/features/page_view_event/aggregate/initialized-features.js","../src/features/page_view_event/instrument/index.js","../src/features/page_view_timing/constants.js","../src/features/page_view_timing/index.js","../src/features/page_view_timing/aggregate/index.js","../src/features/page_view_timing/instrument/index.js","../src/features/session_replay/constants.js","../src/features/session_replay/index.js","../src/features/session_replay/aggregate/index.js","../src/features/session_replay/instrument/index.js","../src/features/session_replay/shared/recorder-events.js","../src/features/session_replay/shared/recorder.js","../src/features/session_replay/shared/stylesheet-evaluator.js","../src/features/session_replay/shared/utils.js","../src/features/session_trace/constants.js","../src/features/session_trace/index.js","../src/features/session_trace/aggregate/index.js","../src/features/session_trace/aggregate/trace/node.js","../src/features/session_trace/aggregate/trace/storage.js","../src/features/session_trace/aggregate/trace/utils.js","../src/features/session_trace/instrument/index.js","../src/features/soft_navigations/constants.js","../src/features/soft_navigations/index.js","../src/features/soft_navigations/aggregate/ajax-node.js","../src/features/soft_navigations/aggregate/bel-node.js","../src/features/soft_navigations/aggregate/index.js","../src/features/soft_navigations/aggregate/initial-page-load-interaction.js","../src/features/soft_navigations/aggregate/interaction.js","../src/features/soft_navigations/instrument/index.js","../src/features/spa/constants.js","../src/features/spa/index.js","../src/features/spa/aggregate/index.js","../src/features/spa/aggregate/interaction-node.js","../src/features/spa/aggregate/interaction.js","../src/features/spa/aggregate/serializer.js","../src/features/spa/instrument/index.js","../src/features/utils/agent-session.js","../src/features/utils/aggregate-base.js","../src/features/utils/event-buffer.js","../src/features/utils/feature-base.js","../src/features/utils/feature-gates.js","../src/features/utils/instrument-base.js","../src/features/utils/nr1-debugger.js","../src/interfaces/registered-entity.js","../src/loaders/agent-base.js","../src/loaders/agent.js","../src/loaders/api-base.js","../src/loaders/browser-agent.js","../src/loaders/micro-agent-base.js","../src/loaders/micro-agent.js","../src/loaders/api/addPageAction.js","../src/loaders/api/addRelease.js","../src/loaders/api/addToTrace.js","../src/loaders/api/consent.js","../src/loaders/api/constants.js","../src/loaders/api/finished.js","../src/loaders/api/interaction-types.js","../src/loaders/api/interaction.js","../src/loaders/api/log.js","../src/loaders/api/measure.js","../src/loaders/api/noticeError.js","../src/loaders/api/pauseReplay.js","../src/loaders/api/recordCustomEvent.js","../src/loaders/api/recordReplay.js","../src/loaders/api/register-api-types.js","../src/loaders/api/register.js","../src/loaders/api/setApplicationVersion.js","../src/loaders/api/setCustomAttribute.js","../src/loaders/api/setErrorHandler.js","../src/loaders/api/setPageViewName.js","../src/loaders/api/setUserId.js","../src/loaders/api/sharedHandlers.js","../src/loaders/api/start.js","../src/loaders/api/topLevelCallers.js","../src/loaders/api/wrapLogger.js","../src/loaders/configure/configure.js","../src/loaders/configure/nonce.js","../src/loaders/configure/public-path.js","../src/loaders/features/enabled-features.js","../src/loaders/features/featureDependencies.js","../src/loaders/features/features.js"],"version":"5.9.3"}
@@ -264,6 +264,12 @@ export type Init = {
264
264
  * - If explicitly false, the agent will use HTTP instead of HTTPS. This setting should NOT be used.
265
265
  */
266
266
  ssl?: boolean | undefined;
267
+ browser_consent_mode?: {
268
+ /**
269
+ * - If true, the agent will use consent mode for whether to allow or disallow data harvest.
270
+ */
271
+ enabled?: boolean | undefined;
272
+ } | undefined;
267
273
  user_actions?: {
268
274
  /**
269
275
  * - Must be true to allow UserAction events to be captured.
@@ -1 +1 @@
1
- {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../../src/common/config/init.js"],"names":[],"mappings":"AA8IO,0CAEN;mBArIY,OAAO,cAAc,EAAE,IAAI"}
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../../src/common/config/init.js"],"names":[],"mappings":"AA+IO,0CAEN;mBAtIY,OAAO,cAAc,EAAE,IAAI"}
@@ -1 +1 @@
1
- {"version":3,"file":"harvester.d.ts","sourceRoot":"","sources":["../../../../src/common/harvest/harvester.js"],"names":[],"mappings":"AA6GA;;;;IAII;AACJ;;;;;;;;;IAFc,OAAO,CAuHpB;AA9MD;IAIE,2BAUC;IAZD,6BAA0B;IAGxB,cAAwB;IAW1B,wCASC;IAED;;;;;OAKG;IACH,iCAJW,MAAM,cACN,MAAM,GACJ,OAAO,CA6CnB;;CACF;8BAGY,OAAO,YAAY,EAAE,eAAe"}
1
+ {"version":3,"file":"harvester.d.ts","sourceRoot":"","sources":["../../../../src/common/harvest/harvester.js"],"names":[],"mappings":"AA8GA;;;;IAII;AACJ;;;;;;;;;IAFc,OAAO,CAuHpB;AA/MD;IAIE,2BAUC;IAZD,6BAA0B;IAGxB,cAAwB;IAW1B,wCASC;IAED;;;;;OAKG;IACH,iCAJW,MAAM,cACN,MAAM,GACJ,OAAO,CA8CnB;;CACF;8BAGY,OAAO,YAAY,EAAE,eAAe"}
@@ -1 +1 @@
1
- {"version":3,"file":"session-entity.d.ts","sourceRoot":"","sources":["../../../../src/common/session/session-entity.js"],"names":[],"mappings":"AAqCA;IACE;;;;;OAKG;IACH,uBA+BC;IAzBC,qBAAsC;IACtC,aAAsB;IACtB,UAAe;IAGf,SAAc;IAEd,QAAiC;IAoBnC;;;;;aA6EC;IApEC,8BAA0B;IAC1B,+BAA4B;IAe1B,gCAOqC;IAUrC,4CAkBsC;IAexC,iCAAuB;IAKzB,wBAEC;IAED,sBAEC;IAED;;;OAGG;IACH,QAFa,MAAM,CA6BlB;IAED;;;;;;OAMG;IACH,YAHW,MAAM,GACJ,MAAM,CAkBlB;IAED,gBA2BC;IAED;;OAEG;IACH,gBAIC;IAED;;;OAGG;IACH,qBAHW,MAAM,GACJ,OAAO,CAInB;IAED;;;OAGG;IACH,gBAHW,MAAM,GACJ,OAAO,CAKnB;IAED,yDAUC;IAED,6DAIC;IAED;;;OAGG;IACH,6BAHW,MAAM,GACJ,MAAM,CAIlB;IAED,gDAaC;IAHG,YAAuD;CAI5D;sBAtTqB,gBAAgB;iCAGL,4BAA4B"}
1
+ {"version":3,"file":"session-entity.d.ts","sourceRoot":"","sources":["../../../../src/common/session/session-entity.js"],"names":[],"mappings":"AAsCA;IACE;;;;;OAKG;IACH,uBA+BC;IAzBC,qBAAsC;IACtC,aAAsB;IACtB,UAAe;IAGf,SAAc;IAEd,QAAiC;IAoBnC;;;;;aAgFC;IApEC,8BAA0B;IAC1B,+BAA4B;IAe1B,gCAOqC;IAUrC,4CAkBsC;IAexC,iCAAuB;IAKzB,wBAEC;IAED,sBAEC;IAED;;;OAGG;IACH,QAFa,MAAM,CA6BlB;IAED;;;;;;OAMG;IACH,YAHW,MAAM,GACJ,MAAM,CAkBlB;IAED,gBA2BC;IAED;;OAEG;IACH,gBAIC;IAED;;;OAGG;IACH,qBAHW,MAAM,GACJ,OAAO,CAInB;IAED;;;OAGG;IACH,gBAHW,MAAM,GACJ,OAAO,CAKnB;IAED,yDAUC;IAED,6DAIC;IAED;;;OAGG;IACH,6BAHW,MAAM,GACJ,MAAM,CAIlB;IAED,gDAaC;IAHG,YAAuD;CAI5D;sBA1TqB,gBAAgB;iCAGL,4BAA4B"}
@@ -1,6 +1,7 @@
1
1
  export class Aggregate extends AggregateBase {
2
2
  static featureName: string;
3
3
  constructor(agentRef: any);
4
+ sentRum: boolean;
4
5
  timeToFirstByte: number;
5
6
  firstByteToWindowLoad: number;
6
7
  firstByteToDomContent: number;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/features/page_view_event/aggregate/index.js"],"names":[],"mappings":"AAuBA;IACE,2BAA2C;IAC3C,2BA2BC;IAxBC,wBAAwB;IACxB,8BAA8B;IAC9B,8BAA8B;IAC9B,gBAAgB;IAuBlB;;;;OAIG;IACH,2BAFW,GAAC,QAoEX;IAbC;;;;;;;;;;;;;;mBAOC;IANC,iCAAyB;IAc7B,kCAEC;IAED;;;;;;aAiGC;CACF;8BAzN6B,4BAA4B"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/features/page_view_event/aggregate/index.js"],"names":[],"mappings":"AAuBA;IACE,2BAA2C;IAE3C,2BA6BC;IA1BC,iBAAoB;IAEpB,wBAAwB;IACxB,8BAA8B;IAC9B,8BAA8B;IAC9B,gBAAgB;IAuBlB;;;;OAIG;IACH,2BAFW,GAAC,QAoEX;IAbC;;;;;;;;;;;;;;mBAOC;IANC,iCAAyB;IAc7B,kCAEC;IAED;;;;;;aAiGC;CACF;8BA5N6B,4BAA4B"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/features/page_view_event/instrument/index.js"],"names":[],"mappings":"AAYA;IACE,2BAA2C;IAC3C,2BAaC;IAED,kDAiCC;CACF;AAED,8CAAuC;+BA3DR,6BAA6B"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/features/page_view_event/instrument/index.js"],"names":[],"mappings":"AAWA;IACE,2BAA2C;IAC3C,2BAUC;IAED,kDAiCC;CACF;AAED,8CAAuC;+BAxDR,6BAA6B"}
@@ -1 +1 @@
1
- {"version":3,"file":"agent-session.d.ts","sourceRoot":"","sources":["../../../../src/features/utils/agent-session.js"],"names":[],"mappings":"AAaA,sDAgDC"}
1
+ {"version":3,"file":"agent-session.d.ts","sourceRoot":"","sources":["../../../../src/features/utils/agent-session.js"],"names":[],"mappings":"AAaA,sDA4DC"}
@@ -21,6 +21,7 @@ export class InstrumentBase extends FeatureBase {
21
21
  * @type {Promise} Assigned immediately after @see importAggregator runs. Serves as a signal for when the inner async fn finishes execution. Useful for features to await
22
22
  * one another if there are inter-features dependencies.
23
23
  */
24
+ loadedSuccessfully: Promise<any>;
24
25
  onAggregateImported: Promise<any>;
25
26
  /**
26
27
  * used in conjunction with newrelic.start() to defer harvesting in features
@@ -1 +1 @@
1
- {"version":3,"file":"instrument-base.d.ts","sourceRoot":"","sources":["../../../../src/features/utils/instrument-base.js"],"names":[],"mappings":"AAuBA;;;GAGG;AACH;IACE;;;;OAIG;IACH,wCAFW,MAAM,EAyChB;IApCC,cAAwB;IAExB,8IAA8I;IAC9I,cADW,WAAW,SAAS,CACF;IAE7B;;;MAGE;IACF,eAHU,OAAO,kBAAkB,EAAE,aAAa,CAGpB;IAE9B;;;MAGE;IACF,kCAAoC;IAEpC;;;MAGE;IACF,uBAAiC;IAiBnC;;;;;;;OAOG;IACH,2BALW,MAAM,qDAEN,MAAM,QA0DhB;;CAmBF;4BAhJ2B,gBAAgB"}
1
+ {"version":3,"file":"instrument-base.d.ts","sourceRoot":"","sources":["../../../../src/features/utils/instrument-base.js"],"names":[],"mappings":"AAuBA;;;GAGG;AACH;IACE;;;;OAIG;IACH,wCAFW,MAAM,EA4ChB;IAvCC,cAAwB;IAExB,8IAA8I;IAC9I,cADW,WAAW,SAAS,CACF;IAE7B;;;MAGE;IACF,eAHU,OAAO,kBAAkB,EAAE,aAAa,CAGpB;IAE9B;;;MAGE;IACF,iCAAmC;IACnC,kCAEE;IAEF;;;MAGE;IACF,uBAAiC;IAiBnC;;;;;;;OAOG;IACH,2BALW,MAAM,qDAEN,MAAM,QAqDhB;;CAmBF;4BA9I2B,gBAAgB"}
@@ -1 +1 @@
1
- {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../../src/loaders/agent.js"],"names":[],"mappings":"AA0BA;;;;;;;;;GASG;AAEH;;;GAGG;AACH;IACE;;OAEG;IACH,qBAFW,YAAY,EA+BtB;IAnBC,yBAAkB;IAGlB,yCAAsD;IAMtD,uCAA6G;IAY/G;;;;;MAOC;IAED,gBAEC;IAED,yBAqCC;CACF;;;;;UAnGa,OAAO,uBAAuB,EAAE,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;0BAnBxB,cAAc"}
1
+ {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../../src/loaders/agent.js"],"names":[],"mappings":"AA2BA;;;;;;;;;GASG;AAEH;;;GAGG;AACH;IACE;;OAEG;IACH,qBAFW,YAAY,EAgCtB;IApBC,yBAAkB;IAGlB,yCAAsD;IAMtD,uCAA6G;IAa/G;;;;;MAOC;IAED,gBAEC;IAED,yBAqCC;CACF;;;;;UApGa,OAAO,uBAAuB,EAAE,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;0BApBxB,cAAc"}
@@ -0,0 +1,2 @@
1
+ export function setupConsentAPI(agent: any): void;
2
+ //# sourceMappingURL=consent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consent.d.ts","sourceRoot":"","sources":["../../../../src/loaders/api/consent.js"],"names":[],"mappings":"AASA,kDAQC"}
@@ -24,4 +24,5 @@ export const SET_USER_ID: "setUserId";
24
24
  export const START: "start";
25
25
  export const WRAP_LOGGER: "wrapLogger";
26
26
  export const MEASURE: "measure";
27
+ export const CONSENT: "consent";
27
28
  //# sourceMappingURL=constants.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../../src/loaders/api/constants.js"],"names":[],"mappings":"AAAA;;;GAGG;AACH,qBAAsB,MAAM,CAAA;AAC5B,+BAAwC;AAExC,8BAA+B,eAAe,CAAA;AAC9C,2BAA4B,YAAY,CAAA;AACxC,0BAA2B,YAAY,CAAA;AACvC,uBAAwB,UAAU,CAAA;AAClC,0BAA2B,aAAa,CAAA;AACxC,kBAAmB,KAAK,CAAA;AACxB,2BAA4B,aAAa,CAAA;AACzC,2BAA4B,aAAa,CAAA;AACzC,kCAAmC,mBAAmB,CAAA;AACtD,4BAA6B,cAAc,CAAA;AAC3C,uBAAwB,UAAU,CAAA;AAClC,sCAAuC,uBAAuB,CAAA;AAC9D,qCAAsC,qBAAqB,CAAA;AAC3D,mCAAoC,oBAAoB,CAAA;AACxD,gCAAiC,iBAAiB,CAAA;AAClD,iCAAkC,iBAAiB,CAAA;AACnD,0BAA2B,WAAW,CAAA;AACtC,oBAAqB,OAAO,CAAA;AAC5B,0BAA2B,YAAY,CAAA;AACvC,sBAAuB,SAAS,CAAA"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../../src/loaders/api/constants.js"],"names":[],"mappings":"AAAA;;;GAGG;AACH,qBAAsB,MAAM,CAAA;AAC5B,+BAAwC;AAExC,8BAA+B,eAAe,CAAA;AAC9C,2BAA4B,YAAY,CAAA;AACxC,0BAA2B,YAAY,CAAA;AACvC,uBAAwB,UAAU,CAAA;AAClC,0BAA2B,aAAa,CAAA;AACxC,kBAAmB,KAAK,CAAA;AACxB,2BAA4B,aAAa,CAAA;AACzC,2BAA4B,aAAa,CAAA;AACzC,kCAAmC,mBAAmB,CAAA;AACtD,4BAA6B,cAAc,CAAA;AAC3C,uBAAwB,UAAU,CAAA;AAClC,sCAAuC,uBAAuB,CAAA;AAC9D,qCAAsC,qBAAqB,CAAA;AAC3D,mCAAoC,oBAAoB,CAAA;AACxD,gCAAiC,iBAAiB,CAAA;AAClD,iCAAkC,iBAAiB,CAAA;AACnD,0BAA2B,WAAW,CAAA;AACtC,oBAAqB,OAAO,CAAA;AAC5B,0BAA2B,YAAY,CAAA;AACvC,sBAAuB,SAAS,CAAA;AAChC,sBAAuB,SAAS,CAAA"}
@@ -173,6 +173,13 @@ export class ApiBase {
173
173
  duration: number;
174
174
  customAttributes: object;
175
175
  };
176
+ /**
177
+ * Accepts or rejects consent when the agent is configured to require consent before harvesting.
178
+ * The consent state is stored in session storage inside the NRBA_SESSION object.
179
+ * {@link https://docs.newrelic.com/docs/browser/new-relic-browser/browser-apis/consent/}
180
+ * @param {boolean?} accept Whether to accept or reject consent. Defaults to true (accept) if left undefined.
181
+ */
182
+ consent(accept: boolean | null): any;
176
183
  #private;
177
184
  }
178
185
  export type InteractionInstance = import("./api/interaction-types").InteractionInstance;
@@ -1 +1 @@
1
- {"version":3,"file":"api-base.d.ts","sourceRoot":"","sources":["../../../src/loaders/api-base.js"],"names":[],"mappings":"AAOA;;GAEG;AACH;IAQE;;;;;OAKG;IACH,oBAHW,MAAM,eACN,MAAM,OAIhB;IAED;;;;;;;;OAQG;IACH,iBAHW,OAAO,0BAA0B,EAAE,sBAAsB,GAC1D,OAAO,0BAA0B,EAAE,WAAW,CAIvD;IAED;;;;;OAKG;IACH,6BAHW,MAAM,eACN,MAAM,OAIhB;IAED;;;;;OAKG;IACH,sBAHW,MAAM,SACN,MAAM,OAIhB;IAED;;;;;;OAMG;IACH,yBAJW,MAAM,SACN,MAAM,GAAC,MAAM,GAAC,OAAO,GAAC,IAAI,YAC1B,OAAO,OAIjB;IAED;;;;;OAKG;IACH,mBAHW,KAAK,GAAC,MAAM,qBACZ,MAAM,OAIhB;IAED;;;;OAIG;IACH,iBAFW,MAAM,GAAC,IAAI,OAIrB;IAED;;;;;;;OAOG;IACH,6BAJW,MAAM,GAAC,IAAI,OAMrB;IAED;;;;OAIG;IACH,0BAFW,CAAC,KAAK,EAAE,KAAK,GAAC,MAAM,KAAK,OAAO,GAAG;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,OAI9D;IAED;;;;;OAKG;IACH,iBAHW,MAAM,MACN,MAAM,OAIhB;IAED;;;;;MAKE;IACF,aAHW,MAAM,YACN;QAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,GAAC,OAAO,GAAC,OAAO,GAAC,MAAM,GAAC,MAAM,CAAA;KAAC,OAIpF;IAED;;;OAGG;IACH,aAEC;IAED;;;;OAIG;IACH,qBAFW,MAAM,OAIhB;IAED;;;;OAIG;IACH,oBAEC;IAED;;;;;OAKG;IACH,mBAEC;IAED;;;;;;;;;;OAUG;IACH,6BARW;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAC,OAUrF;IAED;;;;;OAKG;IACH,0BAHW,MAAM,OAKhB;IAED;;;;;;;;MAQE;IACF,mBALG;QAAuB,UAAU;KACjC,GAAU,mBAAmB,CAM/B;IAED;;;;;;MAME;IACF,mBAJW,MAAM,gBACN,MAAM,YACN;QAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,GAAC,OAAO,GAAC,OAAO,GAAC,MAAM,GAAC,MAAM,CAAA;KAAC,OAIpF;IAED;;;;;;OAMG;IACH,cAJW,MAAM,WACN,MAAM,OAAC,GACL;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,gBAAgB,EAAE,MAAM,CAAA;KAAC,CAIpF;;CACF;kCA3NY,OAAO,yBAAyB,EAAE,mBAAmB"}
1
+ {"version":3,"file":"api-base.d.ts","sourceRoot":"","sources":["../../../src/loaders/api-base.js"],"names":[],"mappings":"AAOA;;GAEG;AACH;IAQE;;;;;OAKG;IACH,oBAHW,MAAM,eACN,MAAM,OAIhB;IAED;;;;;;;;OAQG;IACH,iBAHW,OAAO,0BAA0B,EAAE,sBAAsB,GAC1D,OAAO,0BAA0B,EAAE,WAAW,CAIvD;IAED;;;;;OAKG;IACH,6BAHW,MAAM,eACN,MAAM,OAIhB;IAED;;;;;OAKG;IACH,sBAHW,MAAM,SACN,MAAM,OAIhB;IAED;;;;;;OAMG;IACH,yBAJW,MAAM,SACN,MAAM,GAAC,MAAM,GAAC,OAAO,GAAC,IAAI,YAC1B,OAAO,OAIjB;IAED;;;;;OAKG;IACH,mBAHW,KAAK,GAAC,MAAM,qBACZ,MAAM,OAIhB;IAED;;;;OAIG;IACH,iBAFW,MAAM,GAAC,IAAI,OAIrB;IAED;;;;;;;OAOG;IACH,6BAJW,MAAM,GAAC,IAAI,OAMrB;IAED;;;;OAIG;IACH,0BAFW,CAAC,KAAK,EAAE,KAAK,GAAC,MAAM,KAAK,OAAO,GAAG;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,OAI9D;IAED;;;;;OAKG;IACH,iBAHW,MAAM,MACN,MAAM,OAIhB;IAED;;;;;MAKE;IACF,aAHW,MAAM,YACN;QAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,GAAC,OAAO,GAAC,OAAO,GAAC,MAAM,GAAC,MAAM,CAAA;KAAC,OAIpF;IAED;;;OAGG;IACH,aAEC;IAED;;;;OAIG;IACH,qBAFW,MAAM,OAIhB;IAED;;;;OAIG;IACH,oBAEC;IAED;;;;;OAKG;IACH,mBAEC;IAED;;;;;;;;;;OAUG;IACH,6BARW;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAC,OAUrF;IAED;;;;;OAKG;IACH,0BAHW,MAAM,OAKhB;IAED;;;;;;;;MAQE;IACF,mBALG;QAAuB,UAAU;KACjC,GAAU,mBAAmB,CAM/B;IAED;;;;;;MAME;IACF,mBAJW,MAAM,gBACN,MAAM,YACN;QAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,GAAC,OAAO,GAAC,OAAO,GAAC,MAAM,GAAC,MAAM,CAAA;KAAC,OAIpF;IAED;;;;;;OAMG;IACH,cAJW,MAAM,WACN,MAAM,OAAC,GACL;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,gBAAgB,EAAE,MAAM,CAAA;KAAC,CAIpF;IAED;;;;;OAKG;IACH,gBAFW,OAAO,OAAC,OAIlB;;CACF;kCArOY,OAAO,yBAAyB,EAAE,mBAAmB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@newrelic/browser-agent",
3
- "version": "1.302.0-rc.7",
3
+ "version": "1.302.0-rc.8",
4
4
  "private": false,
5
5
  "author": "New Relic Browser Agent Team <browser-agent@newrelic.com>",
6
6
  "description": "New Relic Browser Agent",
@@ -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.
@@ -53,6 +53,7 @@ const InitModelFn = () => {
53
53
  set allow_registered_children (val) { hiddenState.experimental.allow_registered_children = val },
54
54
  duplicate_registered_data: false
55
55
  },
56
+ browser_consent_mode: { enabled: false },
56
57
  distributed_tracing: {
57
58
  enabled: undefined,
58
59
  exclude_newrelic_header: undefined,
@@ -59,6 +59,7 @@ export class Harvester {
59
59
  triggerHarvestFor (aggregateInst, localOpts = {}) {
60
60
  const output = { ranSend: false, payload: undefined, endpointVersion: aggregateInst.harvestEndpointVersion || 1 }
61
61
  if (aggregateInst.blocked) return output
62
+ if (this.agentRef.init?.browser_consent_mode?.enabled && !this.agentRef.runtime?.session?.state?.consent) return output
62
63
 
63
64
  const submitMethod = getSubmitMethod(localOpts)
64
65
  if (!submitMethod) return output
@@ -32,7 +32,8 @@ const model = {
32
32
  loggingMode: LOGGING_MODE.OFF,
33
33
  serverTimeDiff: null, // set by TimeKeeper; "undefined" value will not be stringified and stored but "null" will
34
34
  custom: {},
35
- numOfResets: 0
35
+ numOfResets: 0,
36
+ consent: false // set by consent() API call
36
37
  }
37
38
 
38
39
  export class SessionEntity {
@@ -77,7 +78,10 @@ export class SessionEntity {
77
78
 
78
79
  setup ({ value = generateRandomHexString(16), expiresMs = DEFAULT_EXPIRES_MS, inactiveMs = DEFAULT_INACTIVE_MS, numOfResets = 0 }) {
79
80
  /** Ensure that certain properties are preserved across a reset if already set */
80
- const persistentAttributes = { serverTimeDiff: this.state.serverTimeDiff || model.serverTimeDiff }
81
+ const persistentAttributes = {
82
+ serverTimeDiff: this.state.serverTimeDiff || model.serverTimeDiff,
83
+ consent: this.state.consent || model.consent
84
+ }
81
85
  this.state = {}
82
86
  this.sync({ ...model, ...persistentAttributes })
83
87
 
@@ -23,9 +23,12 @@ import { getSubmitMethod } from '../../../common/util/submit-data'
23
23
 
24
24
  export class Aggregate extends AggregateBase {
25
25
  static featureName = CONSTANTS.FEATURE_NAME
26
+
26
27
  constructor (agentRef) {
27
28
  super(agentRef, CONSTANTS.FEATURE_NAME)
28
29
 
30
+ this.sentRum = false // flag to facilitate calling sendRum() once externally (by the consent API in agent-session.js)
31
+
29
32
  this.timeToFirstByte = 0
30
33
  this.firstByteToWindowLoad = 0 // our "frontend" duration
31
34
  this.firstByteToDomContent = 0 // our "dom processing" duration
@@ -120,9 +123,9 @@ export class Aggregate extends AggregateBase {
120
123
  }
121
124
  this.events.add(body)
122
125
 
123
- this.agentRef.runtime.harvester.triggerHarvestFor(this, {
126
+ if (this.agentRef.runtime.harvester.triggerHarvestFor(this, {
124
127
  sendEmptyBody: true
125
- })
128
+ }).ranSend) this.sentRum = true
126
129
  }
127
130
 
128
131
  serializer (eventBuffer) { // this is necessary because PVE sends a single item rather than an array; in the case of undefined, this prevents sending [null] as body
@@ -2,7 +2,6 @@
2
2
  * Copyright 2020-2025 New Relic, Inc. All rights reserved.
3
3
  * SPDX-License-Identifier: Apache-2.0
4
4
  */
5
- import { handle } from '../../../common/event-emitter/handle'
6
5
  import { setupSetPageViewNameAPI } from '../../../loaders/api/setPageViewName'
7
6
  import { InstrumentBase } from '../../utils/instrument-base'
8
7
  import * as CONSTANTS from '../constants'
@@ -21,9 +20,6 @@ export class Instrument extends InstrumentBase {
21
20
  /** feature specific APIs */
22
21
  setupSetPageViewNameAPI(agentRef)
23
22
 
24
- /** messages from the register API that can trigger a new RUM call */
25
- this.ee.on('api-send-rum', (attrs, target) => handle('send-rum', [attrs, target], undefined, this.featureName, this.ee))
26
-
27
23
  this.importAggregator(agentRef, () => import(/* webpackChunkName: "page_view_event-aggregate" */ '../aggregate'))
28
24
  }
29
25
 
@@ -56,6 +56,18 @@ export function setupAgentSession (agentRef) {
56
56
  agentRef.runtime.session.syncCustomAttribute(key, value)
57
57
  }, 'session', sharedEE)
58
58
 
59
+ registerHandler('api-consent', (accept) => {
60
+ agentRef.runtime.session.write({ consent: accept === undefined ? true : accept })
61
+
62
+ // call sendRum if it wasn't called yet
63
+ agentRef.features.page_view_event.onAggregateImported.then((loaded) => {
64
+ const pveAgg = agentRef.features.page_view_event.featAggregate
65
+ if (loaded && !pveAgg.sentRum) {
66
+ pveAgg.sendRum()
67
+ }
68
+ })
69
+ }, 'session', sharedEE)
70
+
59
71
  drain(agentRef.agentIdentifier, 'session')
60
72
 
61
73
  return agentRef.runtime.session
@@ -49,7 +49,10 @@ export class InstrumentBase extends FeatureBase {
49
49
  * @type {Promise} Assigned immediately after @see importAggregator runs. Serves as a signal for when the inner async fn finishes execution. Useful for features to await
50
50
  * one another if there are inter-features dependencies.
51
51
  */
52
- this.onAggregateImported = undefined
52
+ this.loadedSuccessfully = undefined
53
+ this.onAggregateImported = new Promise(resolve => {
54
+ this.loadedSuccessfully = resolve
55
+ })
53
56
 
54
57
  /**
55
58
  * used in conjunction with newrelic.start() to defer harvesting in features
@@ -83,11 +86,6 @@ export class InstrumentBase extends FeatureBase {
83
86
  importAggregator (agentRef, fetchAggregator, argsObjFromInstrument = {}) {
84
87
  if (this.featAggregate) return
85
88
 
86
- let loadedSuccessfully
87
- this.onAggregateImported = new Promise(resolve => {
88
- loadedSuccessfully = resolve
89
- })
90
-
91
89
  const importLater = async () => {
92
90
  // wait for the deferred promise to resolve before proceeding
93
91
  // this will resolve immediately if the feature is auto-started,
@@ -113,20 +111,20 @@ export class InstrumentBase extends FeatureBase {
113
111
  try {
114
112
  if (!this.#shouldImportAgg(this.featureName, session, agentRef.init)) {
115
113
  drain(this.agentIdentifier, this.featureName)
116
- loadedSuccessfully(false) // aggregate module isn't loaded at all
114
+ this.loadedSuccessfully(false) // aggregate module isn't loaded at all
117
115
  return
118
116
  }
119
117
  const { Aggregate } = await fetchAggregator()
120
118
  this.featAggregate = new Aggregate(agentRef, argsObjFromInstrument)
121
119
 
122
120
  agentRef.runtime.harvester.initializedAggregates.push(this.featAggregate) // "subscribe" the feature to future harvest intervals (PVE will start the timer)
123
- loadedSuccessfully(true)
121
+ this.loadedSuccessfully(true)
124
122
  } catch (e) {
125
123
  warn(34, e)
126
124
  this.abortHandler?.() // undo any important alterations made to the page
127
125
  // not supported yet but nice to do: "abort" this agent's EE for this feature specifically
128
126
  drain(this.agentIdentifier, this.featureName, true)
129
- loadedSuccessfully(false)
127
+ this.loadedSuccessfully(false)
130
128
  if (this.ee) this.ee.abort()
131
129
  }
132
130
  }
@@ -23,6 +23,7 @@ import { setupSetCustomAttributeAPI } from './api/setCustomAttribute'
23
23
  import { setupSetUserIdAPI } from './api/setUserId'
24
24
  import { setupSetApplicationVersionAPI } from './api/setApplicationVersion'
25
25
  import { setupStartAPI } from './api/start'
26
+ import { setupConsentAPI } from './api/consent'
26
27
 
27
28
  /**
28
29
  * @typedef {Object} AgentOptions
@@ -70,6 +71,7 @@ export class Agent extends AgentBase {
70
71
  setupSetUserIdAPI(this)
71
72
  setupSetApplicationVersionAPI(this)
72
73
  setupStartAPI(this)
74
+ setupConsentAPI(this)
73
75
 
74
76
  this.run()
75
77
  }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Copyright 2020-2025 New Relic, Inc. All rights reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+ import { prefix, CONSENT } from './constants'
6
+ import { setupAPI } from './sharedHandlers'
7
+ import { handle } from '../../common/event-emitter/handle'
8
+ import { warn } from '../../common/util/console'
9
+
10
+ export function setupConsentAPI (agent) {
11
+ setupAPI(CONSENT, function (accept) {
12
+ if (accept !== undefined && typeof accept !== 'boolean') {
13
+ warn(65, typeof accept)
14
+ return
15
+ }
16
+ handle(prefix + CONSENT, [accept], undefined, 'session', agent.ee)
17
+ }, agent)
18
+ }
@@ -25,3 +25,4 @@ export const SET_USER_ID = 'setUserId'
25
25
  export const START = 'start'
26
26
  export const WRAP_LOGGER = 'wrapLogger'
27
27
  export const MEASURE = 'measure'
28
+ export const CONSENT = 'consent'
@@ -3,7 +3,7 @@
3
3
  * SPDX-License-Identifier: Apache-2.0
4
4
  */
5
5
  import { warn } from '../common/util/console'
6
- import { ADD_PAGE_ACTION, ADD_RELEASE, ADD_TO_TRACE, FINISHED, INTERACTION, LOG, NOTICE_ERROR, PAUSE_REPLAY, RECORD_CUSTOM_EVENT, RECORD_REPLAY, REGISTER, SET_APPLICATION_VERSION, SET_CURRENT_ROUTE_NAME, SET_CUSTOM_ATTRIBUTE, SET_ERROR_HANDLER, SET_PAGE_VIEW_NAME, SET_USER_ID, START, WRAP_LOGGER, MEASURE } from './api/constants'
6
+ import { ADD_PAGE_ACTION, ADD_RELEASE, ADD_TO_TRACE, CONSENT, FINISHED, INTERACTION, LOG, NOTICE_ERROR, PAUSE_REPLAY, RECORD_CUSTOM_EVENT, RECORD_REPLAY, REGISTER, SET_APPLICATION_VERSION, SET_CURRENT_ROUTE_NAME, SET_CUSTOM_ATTRIBUTE, SET_ERROR_HANDLER, SET_PAGE_VIEW_NAME, SET_USER_ID, START, WRAP_LOGGER, MEASURE } from './api/constants'
7
7
 
8
8
  /**
9
9
  * @typedef {import('./api/interaction-types').InteractionInstance} InteractionInstance
@@ -225,4 +225,14 @@ export class ApiBase {
225
225
  measure (name, options) {
226
226
  return this.#callMethod(MEASURE, name, options)
227
227
  }
228
+
229
+ /**
230
+ * Accepts or rejects consent when the agent is configured to require consent before harvesting.
231
+ * The consent state is stored in session storage inside the NRBA_SESSION object.
232
+ * {@link https://docs.newrelic.com/docs/browser/new-relic-browser/browser-apis/consent/}
233
+ * @param {boolean?} accept Whether to accept or reject consent. Defaults to true (accept) if left undefined.
234
+ */
235
+ consent (accept) {
236
+ return this.#callMethod(CONSENT, accept)
237
+ }
228
238
  }