@newrelic/browser-agent 1.284.1 → 1.286.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.
Files changed (83) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/README.md +6 -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/dom/selector-path.js +1 -1
  6. package/dist/cjs/common/harvest/harvester.js +29 -2
  7. package/dist/cjs/common/util/feature-flags.js +8 -2
  8. package/dist/cjs/features/logging/aggregate/index.js +1 -1
  9. package/dist/cjs/features/session_replay/shared/recorder.js +8 -10
  10. package/dist/cjs/features/session_replay/shared/utils.js +12 -0
  11. package/dist/cjs/features/session_trace/aggregate/trace/storage.js +3 -2
  12. package/dist/cjs/features/utils/aggregate-base.js +4 -6
  13. package/dist/cjs/features/utils/event-store-manager.js +15 -1
  14. package/dist/cjs/features/utils/nr1-debugger.js +1 -1
  15. package/dist/cjs/loaders/agent-base.js +1 -1
  16. package/dist/cjs/loaders/agent.js +3 -1
  17. package/dist/cjs/loaders/api/api.js +68 -59
  18. package/dist/cjs/loaders/api/apiAsync.js +19 -22
  19. package/dist/cjs/loaders/configure/configure.js +20 -7
  20. package/dist/cjs/loaders/features/features.js +4 -3
  21. package/dist/cjs/loaders/micro-agent-base.js +1 -1
  22. package/dist/cjs/loaders/micro-agent.js +3 -1
  23. package/dist/esm/common/constants/env.cdn.js +1 -1
  24. package/dist/esm/common/constants/env.npm.js +1 -1
  25. package/dist/esm/common/dom/selector-path.js +1 -1
  26. package/dist/esm/common/harvest/harvester.js +30 -3
  27. package/dist/esm/common/util/feature-flags.js +8 -2
  28. package/dist/esm/features/logging/aggregate/index.js +1 -1
  29. package/dist/esm/features/session_replay/shared/recorder.js +7 -9
  30. package/dist/esm/features/session_replay/shared/utils.js +11 -0
  31. package/dist/esm/features/session_trace/aggregate/trace/storage.js +3 -2
  32. package/dist/esm/features/utils/aggregate-base.js +4 -6
  33. package/dist/esm/features/utils/event-store-manager.js +15 -1
  34. package/dist/esm/features/utils/nr1-debugger.js +1 -1
  35. package/dist/esm/loaders/agent-base.js +1 -1
  36. package/dist/esm/loaders/agent.js +3 -1
  37. package/dist/esm/loaders/api/api.js +67 -58
  38. package/dist/esm/loaders/api/apiAsync.js +14 -17
  39. package/dist/esm/loaders/configure/configure.js +21 -8
  40. package/dist/esm/loaders/features/features.js +3 -2
  41. package/dist/esm/loaders/micro-agent-base.js +1 -1
  42. package/dist/esm/loaders/micro-agent.js +3 -1
  43. package/dist/types/common/dom/selector-path.d.ts.map +1 -1
  44. package/dist/types/common/harvest/harvester.d.ts.map +1 -1
  45. package/dist/types/common/util/feature-flags.d.ts.map +1 -1
  46. package/dist/types/features/logging/aggregate/index.d.ts +0 -1
  47. package/dist/types/features/logging/aggregate/index.d.ts.map +1 -1
  48. package/dist/types/features/session_replay/shared/recorder.d.ts.map +1 -1
  49. package/dist/types/features/session_replay/shared/utils.d.ts +1 -0
  50. package/dist/types/features/session_replay/shared/utils.d.ts.map +1 -1
  51. package/dist/types/features/utils/event-store-manager.d.ts +5 -1
  52. package/dist/types/features/utils/event-store-manager.d.ts.map +1 -1
  53. package/dist/types/loaders/agent.d.ts +1 -0
  54. package/dist/types/loaders/agent.d.ts.map +1 -1
  55. package/dist/types/loaders/api/api.d.ts +1 -20
  56. package/dist/types/loaders/api/api.d.ts.map +1 -1
  57. package/dist/types/loaders/api/apiAsync.d.ts +1 -1
  58. package/dist/types/loaders/api/apiAsync.d.ts.map +1 -1
  59. package/dist/types/loaders/configure/configure.d.ts +1 -0
  60. package/dist/types/loaders/configure/configure.d.ts.map +1 -1
  61. package/dist/types/loaders/features/features.d.ts +2 -0
  62. package/dist/types/loaders/features/features.d.ts.map +1 -1
  63. package/dist/types/loaders/micro-agent.d.ts +1 -0
  64. package/dist/types/loaders/micro-agent.d.ts.map +1 -1
  65. package/package.json +1 -1
  66. package/src/common/dom/selector-path.js +1 -3
  67. package/src/common/harvest/harvester.js +33 -3
  68. package/src/common/util/feature-flags.js +10 -2
  69. package/src/features/logging/aggregate/index.js +2 -2
  70. package/src/features/session_replay/shared/recorder.js +7 -9
  71. package/src/features/session_replay/shared/utils.js +12 -0
  72. package/src/features/session_trace/aggregate/trace/storage.js +2 -2
  73. package/src/features/utils/aggregate-base.js +4 -4
  74. package/src/features/utils/event-store-manager.js +15 -1
  75. package/src/features/utils/nr1-debugger.js +1 -1
  76. package/src/loaders/agent-base.js +2 -2
  77. package/src/loaders/agent.js +4 -1
  78. package/src/loaders/api/api.js +64 -58
  79. package/src/loaders/api/apiAsync.js +14 -18
  80. package/src/loaders/configure/configure.js +21 -8
  81. package/src/loaders/features/features.js +3 -2
  82. package/src/loaders/micro-agent-base.js +2 -2
  83. package/src/loaders/micro-agent.js +4 -1
@@ -26,4 +26,15 @@ export function buildNRMetaNode(timestamp, timeKeeper) {
26
26
  correctedOriginTime: timeKeeper.correctedOriginTime,
27
27
  originTimeDiff: Math.floor(originTime - timeKeeper.correctedOriginTime)
28
28
  };
29
+ }
30
+ export function customMasker(text, element) {
31
+ try {
32
+ if (typeof element?.type === 'string') {
33
+ if (element.type.toLowerCase() === 'password') return '*'.repeat(text?.length || 0);
34
+ if (element?.dataset?.nrUnmask !== undefined || element?.classList?.contains('nr-unmask')) return text;
35
+ }
36
+ } catch (err) {
37
+ // likely an element was passed to this handler that was invalid and was missing attributes or methods
38
+ }
39
+ return typeof text === 'string' ? text.replace(/[\S]/g, '*') : '*'.repeat(text?.length || 0);
29
40
  }
@@ -15,7 +15,8 @@ const ignoredEvents = {
15
15
  // we find that certain events make the data too noisy to be useful
16
16
  global: {
17
17
  mouseup: true,
18
- mousedown: true
18
+ mousedown: true,
19
+ mousemove: true
19
20
  },
20
21
  // certain events are present both in the window and in PVT metrics. PVT metrics are prefered so the window events should be ignored
21
22
  window: {
@@ -177,8 +178,8 @@ export class TraceStorage {
177
178
  this.storeSTN(evt);
178
179
  }
179
180
  shouldIgnoreEvent(event, target) {
180
- const origin = eventOrigin(event.target, target, this.parent.ee);
181
181
  if (event.type in ignoredEvents.global) return true;
182
+ const origin = eventOrigin(event.target, target, this.parent.ee);
182
183
  if (!!ignoredEvents[origin] && ignoredEvents[origin].ignoreAll) return true;
183
184
  return !!(!!ignoredEvents[origin] && event.type in ignoredEvents[origin]);
184
185
  }
@@ -36,7 +36,7 @@ export class AggregateBase extends FeatureBase {
36
36
  This was necessary to prevent race cond. issues where the event buffer was checked before the feature could "block" itself.
37
37
  Its easier to just keep an empty event buffer in place. */
38
38
  default:
39
- this.events = new EventStoreManager(agentRef.mainAppKey, 1);
39
+ this.events = new EventStoreManager(agentRef.mainAppKey, 1, agentRef.agentIdentifier, this.featureName);
40
40
  break;
41
41
  }
42
42
  this.harvestOpts = {}; // features aggregate classes can define custom opts for when their harvest is called
@@ -138,16 +138,14 @@ export class AggregateBase extends FeatureBase {
138
138
  } catch (err) {
139
139
  // do nothing
140
140
  }
141
- configure({
142
- agentIdentifier: this.agentIdentifier
143
- }, {
141
+ configure(existingAgent, {
144
142
  ...cdn,
145
143
  info: {
146
144
  ...cdn.info,
147
145
  jsAttributes
148
146
  },
149
147
  runtime: existingAgent.runtime
150
- });
148
+ }, existingAgent.runtime.loaderType);
151
149
  }
152
150
  }
153
151
 
@@ -163,7 +161,7 @@ export class AggregateBase extends FeatureBase {
163
161
  appId: agentRef.info.applicationID
164
162
  };
165
163
  // Create a single Aggregator for this agent if DNE yet; to be used by jserror endpoint features.
166
- if (!agentRef.sharedAggregator) agentRef.sharedAggregator = new EventStoreManager(agentRef.mainAppKey, 2);
164
+ if (!agentRef.sharedAggregator) agentRef.sharedAggregator = new EventStoreManager(agentRef.mainAppKey, 2, agentRef.agentIdentifier, 'shared_aggregator');
167
165
  if (!agentRef.runtime.harvester) agentRef.runtime.harvester = new Harvester(agentRef);
168
166
  }
169
167
 
@@ -3,6 +3,8 @@
3
3
  * SPDX-License-Identifier: Apache-2.0
4
4
  */
5
5
  import { EventAggregator } from '../../common/aggregate/event-aggregator';
6
+ import { dispatchGlobalEvent } from '../../common/dispatch/global-event';
7
+ import { activatedFeatures } from '../../common/util/feature-flags';
6
8
  import { EventBuffer } from './event-buffer';
7
9
 
8
10
  /**
@@ -13,12 +15,16 @@ export class EventStoreManager {
13
15
  /**
14
16
  * @param {object} defaultTarget - should contain licenseKey and appId of the main app from NREUM.info at startup
15
17
  * @param {1|2} storageChoice - the type of storage to use in this manager; 'EventBuffer' (1), 'EventAggregator' (2)
18
+ * @param {string} agentIdentifier - agent identifier used in inspection events
19
+ * @param {string} featureName - feature name used in inspection events for non-shared aggregators
16
20
  */
17
- constructor(defaultTarget, storageChoice) {
21
+ constructor(defaultTarget, storageChoice, agentIdentifier, featureName) {
18
22
  this.mainApp = defaultTarget;
19
23
  this.StorageClass = storageChoice === 1 ? EventBuffer : EventAggregator;
20
24
  this.appStorageMap = new Map();
21
25
  this.appStorageMap.set(defaultTarget, new this.StorageClass());
26
+ this.agentIdentifier = agentIdentifier;
27
+ this.featureName = featureName;
22
28
  }
23
29
 
24
30
  // This class must contain an union of all methods from all supported storage classes and conceptualize away the target app argument.
@@ -44,6 +50,14 @@ export class EventStoreManager {
44
50
  * @returns {boolean} True if the event was successfully added
45
51
  */
46
52
  add(event, target) {
53
+ dispatchGlobalEvent({
54
+ agentIdentifier: this.agentIdentifier,
55
+ drained: !!activatedFeatures?.[this.agentIdentifier],
56
+ type: 'data',
57
+ name: 'buffer',
58
+ feature: this.featureName,
59
+ data: event
60
+ });
47
61
  if (target && !this.appStorageMap.has(target)) this.appStorageMap.set(target, new this.StorageClass());
48
62
  return this.appStorageMap.get(target || this.mainApp).add(event);
49
63
  }
@@ -6,7 +6,7 @@ import { gosCDN } from '../../common/window/nreum';
6
6
  const debugId = 1;
7
7
  const newrelic = gosCDN();
8
8
  export function debugNR1(agentIdentifier, location, event, otherprops = {}, debugName = 'SR') {
9
- const api = agentIdentifier ? newrelic.initializedAgents[agentIdentifier].api.addPageAction : newrelic.addPageAction;
9
+ const api = agentIdentifier ? newrelic.initializedAgents[agentIdentifier].addPageAction : newrelic.addPageAction;
10
10
  let url;
11
11
  try {
12
12
  const locURL = new URL(window.location);
@@ -20,7 +20,7 @@ export class AgentBase extends MicroAgentBase {
20
20
  * @param {...any} args
21
21
  */
22
22
  #callMethod(methodName, ...args) {
23
- if (typeof this.api?.[methodName] !== 'function') warn(35, methodName);else return this.api[methodName](...args);
23
+ if (this[methodName] === AgentBase.prototype[methodName] || this[methodName] === MicroAgentBase.prototype[methodName]) warn(35, methodName);else return this[methodName](...args);
24
24
  }
25
25
 
26
26
  /**
@@ -67,6 +67,9 @@ export class Agent extends AgentBase {
67
67
  runtime: this.runtime
68
68
  };
69
69
  }
70
+ get api() {
71
+ return this;
72
+ }
70
73
  run() {
71
74
  // Attempt to initialize all the requested features (sequentially in prio order & synchronously), with any failure aborting the whole process.
72
75
  try {
@@ -94,7 +97,6 @@ export class Agent extends AgentBase {
94
97
  this.features[featName].abortHandler?.();
95
98
  }
96
99
  const newrelic = gosNREUM();
97
- delete newrelic.initializedAgents[this.agentIdentifier]?.api; // prevent further calls to agent-specific APIs (see "configure.js")
98
100
  delete newrelic.initializedAgents[this.agentIdentifier]?.features; // GC mem used internally by features
99
101
  delete this.sharedAggregator;
100
102
  // Keep the initialized agent object with its configs for troubleshooting purposes.
@@ -3,10 +3,8 @@
3
3
  * SPDX-License-Identifier: Apache-2.0
4
4
  */
5
5
  import { FEATURE_NAMES } from '../features/features';
6
- import { getInfo, setInfo } from '../../common/config/info';
7
- import { getRuntime } from '../../common/config/runtime';
6
+ import { setInfo } from '../../common/config/info';
8
7
  import { handle } from '../../common/event-emitter/handle';
9
- import { ee } from '../../common/event-emitter/contextual-ee';
10
8
  import { drain, registerDrain } from '../../common/drain/drain';
11
9
  import { onWindowLoad } from '../../common/window/load';
12
10
  import { isBrowserScope } from '../../common/constants/runtime';
@@ -20,6 +18,8 @@ import { MODE } from '../../common/session/constants';
20
18
  import { LOG_LEVELS } from '../../features/logging/constants';
21
19
  import { bufferLog } from '../../features/logging/shared/utils';
22
20
  import { wrapLogger } from '../../common/wrap/wrap-logger';
21
+ import { dispatchGlobalEvent } from '../../common/dispatch/global-event';
22
+ import { activatedFeatures } from '../../common/util/feature-flags';
23
23
  export function setTopLevelCallers() {
24
24
  const nr = gosCDN();
25
25
  apiMethods.forEach(f => {
@@ -27,41 +27,39 @@ export function setTopLevelCallers() {
27
27
  });
28
28
  function caller(fnName, ...args) {
29
29
  let returnVals = [];
30
- Object.values(nr.initializedAgents).forEach(val => {
31
- if (!val || !val.api) {
30
+ Object.values(nr.initializedAgents).forEach(agt => {
31
+ if (!agt || !agt.runtime) {
32
32
  warn(38, fnName);
33
- } else if (val.exposed && val.api[fnName]) {
34
- returnVals.push(val.api[fnName](...args));
33
+ } else if (agt.exposed && agt[fnName] && agt.runtime.loaderType !== 'micro-agent') {
34
+ returnVals.push(agt[fnName](...args));
35
35
  }
36
36
  });
37
- return returnVals.length > 1 ? returnVals : returnVals[0];
37
+ return returnVals[0];
38
38
  }
39
39
  }
40
40
  const replayRunning = {};
41
- export function setAPI(agentIdentifier, forceDrain, runSoftNavOverSpa = false) {
42
- if (!forceDrain) registerDrain(agentIdentifier, 'api');
43
- const apiInterface = {};
44
- var instanceEE = ee.get(agentIdentifier);
45
- var tracerEE = instanceEE.get('tracer');
46
- replayRunning[agentIdentifier] = MODE.OFF;
47
- instanceEE.on(SR_EVENT_EMITTER_TYPES.REPLAY_RUNNING, isRunning => {
48
- replayRunning[agentIdentifier] = isRunning;
41
+ export function setAPI(agent, forceDrain) {
42
+ if (!forceDrain) registerDrain(agent.agentIdentifier, 'api');
43
+ const tracerEE = agent.ee.get('tracer');
44
+ replayRunning[agent.agentIdentifier] = MODE.OFF;
45
+ agent.ee.on(SR_EVENT_EMITTER_TYPES.REPLAY_RUNNING, isRunning => {
46
+ replayRunning[agent.agentIdentifier] = isRunning;
49
47
  });
50
- var prefix = 'api-';
51
- var spaPrefix = prefix + 'ixn-';
52
- apiInterface.log = function (message, {
48
+ const prefix = 'api-';
49
+ const spaPrefix = prefix + 'ixn-';
50
+ agent.log = function (message, {
53
51
  customAttributes = {},
54
52
  level = LOG_LEVELS.INFO
55
53
  } = {}) {
56
- handle(SUPPORTABILITY_METRIC_CHANNEL, ['API/log/called'], undefined, FEATURE_NAMES.metrics, instanceEE);
57
- bufferLog(instanceEE, message, customAttributes, level);
54
+ handle(SUPPORTABILITY_METRIC_CHANNEL, ['API/log/called'], undefined, FEATURE_NAMES.metrics, agent.ee);
55
+ bufferLog(agent.ee, message, customAttributes, level);
58
56
  };
59
- apiInterface.wrapLogger = (parent, functionName, {
57
+ agent.wrapLogger = (parent, functionName, {
60
58
  customAttributes = {},
61
59
  level = LOG_LEVELS.INFO
62
60
  } = {}) => {
63
- handle(SUPPORTABILITY_METRIC_CHANNEL, ['API/wrapLogger/called'], undefined, FEATURE_NAMES.metrics, instanceEE);
64
- wrapLogger(instanceEE, parent, functionName, {
61
+ handle(SUPPORTABILITY_METRIC_CHANNEL, ['API/wrapLogger/called'], undefined, FEATURE_NAMES.metrics, agent.ee);
62
+ wrapLogger(agent.ee, parent, functionName, {
65
63
  customAttributes,
66
64
  level
67
65
  });
@@ -69,14 +67,14 @@ export function setAPI(agentIdentifier, forceDrain, runSoftNavOverSpa = false) {
69
67
 
70
68
  // Setup stub functions that queue calls for later processing.
71
69
  asyncApiMethods.forEach(fnName => {
72
- apiInterface[fnName] = apiCall(prefix, fnName, true, 'api');
70
+ agent[fnName] = apiCall(prefix, fnName, true, 'api');
73
71
  });
74
- apiInterface.addPageAction = apiCall(prefix, 'addPageAction', true, FEATURE_NAMES.genericEvents);
75
- apiInterface.recordCustomEvent = apiCall(prefix, 'recordCustomEvent', true, FEATURE_NAMES.genericEvents);
76
- apiInterface.setPageViewName = function (name, host) {
72
+ agent.addPageAction = apiCall(prefix, 'addPageAction', true, FEATURE_NAMES.genericEvents);
73
+ agent.recordCustomEvent = apiCall(prefix, 'recordCustomEvent', true, FEATURE_NAMES.genericEvents);
74
+ agent.setPageViewName = function (name, host) {
77
75
  if (typeof name !== 'string') return;
78
76
  if (name.charAt(0) !== '/') name = '/' + name;
79
- getRuntime(agentIdentifier).customTransaction = (host || 'http://custom.transaction') + name;
77
+ agent.runtime.customTransaction = (host || 'http://custom.transaction') + name;
80
78
  return apiCall(prefix, 'setPageViewName', true)();
81
79
  };
82
80
 
@@ -89,11 +87,11 @@ export function setAPI(agentIdentifier, forceDrain, runSoftNavOverSpa = false) {
89
87
  * @returns @see apiCall
90
88
  */
91
89
  function appendJsAttribute(key, value, apiName, addToBrowserStorage) {
92
- const currentInfo = getInfo(agentIdentifier);
90
+ const currentInfo = agent.info;
93
91
  if (value === null) {
94
92
  delete currentInfo.jsAttributes[key];
95
93
  } else {
96
- setInfo(agentIdentifier, {
94
+ setInfo(agent.agentIdentifier, {
97
95
  ...currentInfo,
98
96
  jsAttributes: {
99
97
  ...currentInfo.jsAttributes,
@@ -103,7 +101,7 @@ export function setAPI(agentIdentifier, forceDrain, runSoftNavOverSpa = false) {
103
101
  }
104
102
  return apiCall(prefix, apiName, true, !!addToBrowserStorage || value === null ? 'session' : undefined)(key, value);
105
103
  }
106
- apiInterface.setCustomAttribute = function (name, value, persistAttribute = false) {
104
+ agent.setCustomAttribute = function (name, value, persistAttribute = false) {
107
105
  if (typeof name !== 'string') {
108
106
  warn(39, typeof name);
109
107
  return;
@@ -119,7 +117,7 @@ export function setAPI(agentIdentifier, forceDrain, runSoftNavOverSpa = false) {
119
117
  * @param {string} value - unique user identifier; a null user id suggests none should exist
120
118
  * @returns @see apiCall
121
119
  */
122
- apiInterface.setUserId = function (value) {
120
+ agent.setUserId = function (value) {
123
121
  if (!(typeof value === 'string' || value === null)) {
124
122
  warn(41, typeof value);
125
123
  return;
@@ -132,30 +130,30 @@ export function setAPI(agentIdentifier, forceDrain, runSoftNavOverSpa = false) {
132
130
  * @param {string|null} value - Application version -- if null, will "unset" the value
133
131
  * @returns @see apiCall
134
132
  */
135
- apiInterface.setApplicationVersion = function (value) {
133
+ agent.setApplicationVersion = function (value) {
136
134
  if (!(typeof value === 'string' || value === null)) {
137
135
  warn(42, typeof value);
138
136
  return;
139
137
  }
140
138
  return appendJsAttribute('application.version', value, 'setApplicationVersion', false);
141
139
  };
142
- apiInterface.start = () => {
140
+ agent.start = () => {
143
141
  try {
144
- handle(SUPPORTABILITY_METRIC_CHANNEL, ['API/start/called'], undefined, FEATURE_NAMES.metrics, instanceEE);
145
- instanceEE.emit('manual-start-all');
142
+ handle(SUPPORTABILITY_METRIC_CHANNEL, ['API/start/called'], undefined, FEATURE_NAMES.metrics, agent.ee);
143
+ agent.ee.emit('manual-start-all');
146
144
  } catch (err) {
147
145
  warn(23, err);
148
146
  }
149
147
  };
150
- apiInterface[SR_EVENT_EMITTER_TYPES.RECORD] = function () {
151
- handle(SUPPORTABILITY_METRIC_CHANNEL, ['API/recordReplay/called'], undefined, FEATURE_NAMES.metrics, instanceEE);
152
- handle(SR_EVENT_EMITTER_TYPES.RECORD, [], undefined, FEATURE_NAMES.sessionReplay, instanceEE);
148
+ agent[SR_EVENT_EMITTER_TYPES.RECORD] = function () {
149
+ handle(SUPPORTABILITY_METRIC_CHANNEL, ['API/recordReplay/called'], undefined, FEATURE_NAMES.metrics, agent.ee);
150
+ handle(SR_EVENT_EMITTER_TYPES.RECORD, [], undefined, FEATURE_NAMES.sessionReplay, agent.ee);
153
151
  };
154
- apiInterface[SR_EVENT_EMITTER_TYPES.PAUSE] = function () {
155
- handle(SUPPORTABILITY_METRIC_CHANNEL, ['API/pauseReplay/called'], undefined, FEATURE_NAMES.metrics, instanceEE);
156
- handle(SR_EVENT_EMITTER_TYPES.PAUSE, [], undefined, FEATURE_NAMES.sessionReplay, instanceEE);
152
+ agent[SR_EVENT_EMITTER_TYPES.PAUSE] = function () {
153
+ handle(SUPPORTABILITY_METRIC_CHANNEL, ['API/pauseReplay/called'], undefined, FEATURE_NAMES.metrics, agent.ee);
154
+ handle(SR_EVENT_EMITTER_TYPES.PAUSE, [], undefined, FEATURE_NAMES.sessionReplay, agent.ee);
157
155
  };
158
- apiInterface.interaction = function (options) {
156
+ agent.interaction = function (options) {
159
157
  return new InteractionHandle().get(typeof options === 'object' ? options : {});
160
158
  };
161
159
  function InteractionHandle() {}
@@ -164,9 +162,9 @@ export function setAPI(agentIdentifier, forceDrain, runSoftNavOverSpa = false) {
164
162
  var contextStore = {};
165
163
  var ixn = this;
166
164
  var hasCb = typeof cb === 'function';
167
- handle(SUPPORTABILITY_METRIC_CHANNEL, ['API/createTracer/called'], undefined, FEATURE_NAMES.metrics, instanceEE);
165
+ handle(SUPPORTABILITY_METRIC_CHANNEL, ['API/createTracer/called'], undefined, FEATURE_NAMES.metrics, agent.ee);
168
166
  // Soft navigations won't support Tracer nodes, but this fn should still work the same otherwise (e.g., run the orig cb).
169
- if (!runSoftNavOverSpa) handle(spaPrefix + 'tracer', [now(), name, contextStore], ixn, FEATURE_NAMES.spa, instanceEE);
167
+ if (!agent.runSoftNavOverSpa) handle(spaPrefix + 'tracer', [now(), name, contextStore], ixn, FEATURE_NAMES.spa, agent.ee);
170
168
  return function () {
171
169
  tracerEE.emit((hasCb ? '' : 'no-') + 'fn-start', [now(), ixn, hasCb], contextStore);
172
170
  if (hasCb) {
@@ -185,20 +183,31 @@ export function setAPI(agentIdentifier, forceDrain, runSoftNavOverSpa = false) {
185
183
  }
186
184
  };
187
185
  ['actionText', 'setName', 'setAttribute', 'save', 'ignore', 'onEnd', 'getContext', 'end', 'get'].forEach(name => {
188
- InteractionApiProto[name] = apiCall(spaPrefix, name, undefined, runSoftNavOverSpa ? FEATURE_NAMES.softNav : FEATURE_NAMES.spa);
186
+ InteractionApiProto[name] = apiCall(spaPrefix, name, undefined, agent.runSoftNavOverSpa ? FEATURE_NAMES.softNav : FEATURE_NAMES.spa);
189
187
  });
190
- apiInterface.setCurrentRouteName = runSoftNavOverSpa ? apiCall(spaPrefix, 'routeName', undefined, FEATURE_NAMES.softNav) : apiCall(prefix, 'routeName', true, FEATURE_NAMES.spa);
188
+ agent.setCurrentRouteName = agent.runSoftNavOverSpa ? apiCall(spaPrefix, 'routeName', undefined, FEATURE_NAMES.softNav) : apiCall(prefix, 'routeName', true, FEATURE_NAMES.spa);
191
189
  function apiCall(prefix, name, notSpa, bufferGroup) {
192
190
  return function () {
193
- handle(SUPPORTABILITY_METRIC_CHANNEL, ['API/' + name + '/called'], undefined, FEATURE_NAMES.metrics, instanceEE);
194
- if (bufferGroup) handle(prefix + name, [notSpa ? now() : performance.now(), ...arguments], notSpa ? null : this, bufferGroup, instanceEE); // no bufferGroup means only the SM is emitted
191
+ handle(SUPPORTABILITY_METRIC_CHANNEL, ['API/' + name + '/called'], undefined, FEATURE_NAMES.metrics, agent.ee);
192
+ dispatchGlobalEvent({
193
+ agentIdentifier: agent.agentIdentifier,
194
+ drained: !!activatedFeatures?.[agent.agentIdentifier],
195
+ type: 'data',
196
+ name: 'api',
197
+ feature: prefix + name,
198
+ data: {
199
+ notSpa,
200
+ bufferGroup
201
+ }
202
+ });
203
+ if (bufferGroup) handle(prefix + name, [notSpa ? now() : performance.now(), ...arguments], notSpa ? null : this, bufferGroup, agent.ee); // no bufferGroup means only the SM is emitted
195
204
  return notSpa ? undefined : this; // returns the InteractionHandle which allows these methods to be chained
196
205
  };
197
206
  }
198
- apiInterface.noticeError = function (err, customAttributes) {
207
+ agent.noticeError = function (err, customAttributes) {
199
208
  if (typeof err === 'string') err = new Error(err);
200
- handle(SUPPORTABILITY_METRIC_CHANNEL, ['API/noticeError/called'], undefined, FEATURE_NAMES.metrics, instanceEE);
201
- handle('err', [err, now(), false, customAttributes, !!replayRunning[agentIdentifier]], undefined, FEATURE_NAMES.jserrors, instanceEE);
209
+ handle(SUPPORTABILITY_METRIC_CHANNEL, ['API/noticeError/called'], undefined, FEATURE_NAMES.metrics, agent.ee);
210
+ handle('err', [err, now(), false, customAttributes, !!replayRunning[agent.agentIdentifier]], undefined, FEATURE_NAMES.jserrors, agent.ee);
202
211
  };
203
212
 
204
213
  // theres no window.load event on non-browser scopes, lazy load immediately
@@ -207,14 +216,14 @@ export function setAPI(agentIdentifier, forceDrain, runSoftNavOverSpa = false) {
207
216
  else onWindowLoad(() => lazyLoad(), true);
208
217
  function lazyLoad() {
209
218
  import(/* webpackChunkName: "async-api" */'./apiAsync').then(({
210
- setAPI
219
+ setAsyncAPI
211
220
  }) => {
212
- setAPI(agentIdentifier);
213
- drain(agentIdentifier, 'api');
221
+ setAsyncAPI(agent);
222
+ drain(agent.agentIdentifier, 'api');
214
223
  }).catch(err => {
215
224
  warn(27, err);
216
- instanceEE.abort();
225
+ agent.ee.abort();
217
226
  });
218
227
  }
219
- return apiInterface;
228
+ return true;
220
229
  }
@@ -3,16 +3,13 @@
3
3
  * SPDX-License-Identifier: Apache-2.0
4
4
  */
5
5
  import { FEATURE_NAMES } from '../features/features';
6
- import { getRuntime } from '../../common/config/runtime';
7
- import { ee } from '../../common/event-emitter/contextual-ee';
8
6
  import { handle } from '../../common/event-emitter/handle';
9
7
  import { registerHandler } from '../../common/event-emitter/register-handler';
10
8
  import { single } from '../../common/util/invoke';
11
9
  import { CUSTOM_METRIC_CHANNEL } from '../../features/metrics/constants';
12
10
  import { originTime } from '../../common/constants/runtime';
13
- export function setAPI(agentIdentifier) {
14
- var instanceEE = ee.get(agentIdentifier);
15
- var api = {
11
+ export function setAsyncAPI(agent) {
12
+ const api = {
16
13
  finished: single(finished),
17
14
  setErrorHandler,
18
15
  addToTrace,
@@ -20,40 +17,40 @@ export function setAPI(agentIdentifier) {
20
17
  };
21
18
 
22
19
  // Hook all of the api functions up to the queues/stubs created in loader/api.js
23
- Object.entries(api).forEach(([fnName, fnCall]) => registerHandler('api-' + fnName, fnCall, 'api', instanceEE));
20
+ Object.entries(api).forEach(([fnName, fnCall]) => registerHandler('api-' + fnName, fnCall, 'api', agent.ee));
24
21
 
25
22
  // All API functions get passed the time they were called as their
26
23
  // first parameter. These functions can be called asynchronously.
27
24
 
28
25
  function finished(t, providedTime) {
29
- var time = providedTime ? providedTime - originTime : t;
26
+ const time = providedTime ? providedTime - originTime : t;
30
27
  handle(CUSTOM_METRIC_CHANNEL, ['finished', {
31
28
  time
32
- }], undefined, FEATURE_NAMES.metrics, instanceEE);
29
+ }], undefined, FEATURE_NAMES.metrics, agent.ee);
33
30
  addToTrace(t, {
34
31
  name: 'finished',
35
32
  start: time + originTime,
36
33
  origin: 'nr'
37
34
  });
38
- handle('api-addPageAction', [time, 'finished'], undefined, FEATURE_NAMES.genericEvents, instanceEE);
35
+ handle('api-addPageAction', [time, 'finished'], undefined, FEATURE_NAMES.genericEvents, agent.ee);
39
36
  }
40
- function addToTrace(t, evt) {
37
+ function addToTrace(_, evt) {
41
38
  if (!(evt && typeof evt === 'object' && evt.name && evt.start)) return;
42
- var report = {
39
+ const report = {
43
40
  n: evt.name,
44
41
  s: evt.start - originTime,
45
42
  e: (evt.end || evt.start) - originTime,
46
43
  o: evt.origin || '',
47
44
  t: 'api'
48
45
  };
49
- handle('bstApi', [report], undefined, FEATURE_NAMES.sessionTrace, instanceEE);
46
+ handle('bstApi', [report], undefined, FEATURE_NAMES.sessionTrace, agent.ee);
50
47
  }
51
- function setErrorHandler(t, handler) {
52
- getRuntime(agentIdentifier).onerror = handler;
48
+ function setErrorHandler(_, handler) {
49
+ agent.runtime.onerror = handler;
53
50
  }
54
- var releaseCount = 0;
55
- function addRelease(t, name, id) {
51
+ let releaseCount = 0;
52
+ function addRelease(_, name, id) {
56
53
  if (++releaseCount > 10) return;
57
- getRuntime(agentIdentifier).releaseIds[name.slice(-200)] = ('' + id).slice(-200);
54
+ agent.runtime.releaseIds[name.slice(-200)] = ('' + id).slice(-200);
58
55
  }
59
56
  }
@@ -5,17 +5,19 @@
5
5
  import { setAPI, setTopLevelCallers } from '../api/api';
6
6
  import { addToNREUM, gosCDN } from '../../common/window/nreum';
7
7
  import { setInfo } from '../../common/config/info';
8
- import { getConfiguration, setConfiguration } from '../../common/config/init';
8
+ import { setConfiguration } from '../../common/config/init';
9
9
  import { setLoaderConfig } from '../../common/config/loader-config';
10
10
  import { setRuntime } from '../../common/config/runtime';
11
11
  import { activatedFeatures } from '../../common/util/feature-flags';
12
12
  import { isWorkerScope } from '../../common/constants/runtime';
13
13
  import { redefinePublicPath } from './public-path';
14
14
  import { ee } from '../../common/event-emitter/contextual-ee';
15
- let alreadySetOnce = false; // the configure() function can run multiple times in agent lifecycle
15
+ import { dispatchGlobalEvent } from '../../common/dispatch/global-event';
16
+ const alreadySetOnce = new Set(); // the configure() function can run multiple times in agent lifecycle for different agents
16
17
 
17
18
  /**
18
19
  * Sets or re-sets the agent's configuration values from global settings. This also attach those as properties to the agent instance.
20
+ * IMPORTANT: setNREUMInitializedAgent must be called on the agent prior to calling this function.
19
21
  */
20
22
  export function configure(agent, opts = {}, loaderType, forceDrain) {
21
23
  // eslint-disable-next-line camelcase
@@ -43,9 +45,9 @@ export function configure(agent, opts = {}, loaderType, forceDrain) {
43
45
  info.jsAttributes.isWorker = true;
44
46
  }
45
47
  setInfo(agent.agentIdentifier, info);
46
- const updatedInit = getConfiguration(agent.agentIdentifier);
48
+ const updatedInit = agent.init;
47
49
  const internalTrafficList = [info.beacon, info.errorBeacon];
48
- if (!alreadySetOnce) {
50
+ if (!alreadySetOnce.has(agent.agentIdentifier)) {
49
51
  if (updatedInit.proxy.assets) {
50
52
  redefinePublicPath(updatedInit.proxy.assets);
51
53
  internalTrafficList.push(updatedInit.proxy.assets);
@@ -60,8 +62,19 @@ export function configure(agent, opts = {}, loaderType, forceDrain) {
60
62
  runtime.denyList = [...(updatedInit.ajax.deny_list || []), ...(updatedInit.ajax.block_internal ? internalTrafficList : [])];
61
63
  runtime.ptid = agent.agentIdentifier;
62
64
  setRuntime(agent.agentIdentifier, runtime);
63
- agent.ee = ee.get(agent.agentIdentifier);
64
- if (agent.api === undefined) agent.api = setAPI(agent.agentIdentifier, forceDrain, agent.runSoftNavOverSpa);
65
- if (agent.exposed === undefined) agent.exposed = exposed;
66
- alreadySetOnce = true;
65
+ if (!alreadySetOnce.has(agent.agentIdentifier)) {
66
+ agent.ee = ee.get(agent.agentIdentifier);
67
+ agent.exposed = exposed;
68
+ setAPI(agent, forceDrain); // assign our API functions to the agent instance
69
+
70
+ dispatchGlobalEvent({
71
+ agentIdentifier: agent.agentIdentifier,
72
+ drained: !!activatedFeatures?.[agent.agentIdentifier],
73
+ type: 'lifecycle',
74
+ name: 'initialize',
75
+ feature: undefined,
76
+ data: agent.config
77
+ });
78
+ }
79
+ alreadySetOnce.add(agent.agentIdentifier);
67
80
  }
@@ -6,8 +6,9 @@
6
6
  // To reduce build size a bit:
7
7
  export const EVENTS = 'events';
8
8
  export const JSERRORS = 'jserrors';
9
- const BLOBS = 'browser/blobs';
9
+ export const BLOBS = 'browser/blobs';
10
10
  export const RUM = 'rum';
11
+ export const LOGS = 'browser/logs';
11
12
  export const FEATURE_NAMES = {
12
13
  ajax: 'ajax',
13
14
  genericEvents: 'generic_events',
@@ -53,6 +54,6 @@ export const FEATURE_TO_ENDPOINT = {
53
54
  [FEATURE_NAMES.jserrors]: JSERRORS,
54
55
  [FEATURE_NAMES.sessionTrace]: BLOBS,
55
56
  [FEATURE_NAMES.sessionReplay]: BLOBS,
56
- [FEATURE_NAMES.logging]: 'browser/logs',
57
+ [FEATURE_NAMES.logging]: LOGS,
57
58
  [FEATURE_NAMES.genericEvents]: 'ins'
58
59
  };
@@ -16,7 +16,7 @@ export class MicroAgentBase {
16
16
  * @param {...any} args
17
17
  */
18
18
  #callMethod(methodName, ...args) {
19
- if (typeof this.api?.[methodName] !== 'function') warn(35, methodName);else return this.api[methodName](...args);
19
+ if (this[methodName] === MicroAgentBase.prototype[methodName]) warn(35, methodName);else return this[methodName](...args);
20
20
  }
21
21
 
22
22
  // MicroAgent class custom defines its own start
@@ -33,7 +33,6 @@ export class MicroAgent extends MicroAgentBase {
33
33
  isolatedBacklog: true
34
34
  }
35
35
  }, options.loaderType || 'micro-agent');
36
- Object.assign(this, this.api); // the APIs should be available at the class level for micro-agent
37
36
 
38
37
  /**
39
38
  * Starts a set of agent features if not running in "autoStart" mode
@@ -86,4 +85,7 @@ export class MicroAgent extends MicroAgentBase {
86
85
  runtime: this.runtime
87
86
  };
88
87
  }
88
+ get api() {
89
+ return this;
90
+ }
89
91
  }
@@ -1 +1 @@
1
- {"version":3,"file":"selector-path.d.ts","sourceRoot":"","sources":["../../../../src/common/dom/selector-path.js"],"names":[],"mappings":"AAYO,2CALI,WAAW,yBAGT,MAAM,GAAC,SAAS,CAmD5B"}
1
+ {"version":3,"file":"selector-path.d.ts","sourceRoot":"","sources":["../../../../src/common/dom/selector-path.js"],"names":[],"mappings":"AAYO,2CALI,WAAW,yBAGT,MAAM,GAAC,SAAS,CAiD5B"}
@@ -1 +1 @@
1
- {"version":3,"file":"harvester.d.ts","sourceRoot":"","sources":["../../../../src/common/harvest/harvester.js"],"names":[],"mappings":"AAsBA;IAIE,2BAcC;IAhBD,6BAA0B;IAGxB,cAAwB;IAe1B,wCASC;IAED;;;;;OAKG;IACH,iCAJW,MAAM,cACN,MAAM,GACJ,OAAO,CA8CnB;;CACF;8BAGY,OAAO,YAAY,EAAE,eAAe"}
1
+ {"version":3,"file":"harvester.d.ts","sourceRoot":"","sources":["../../../../src/common/harvest/harvester.js"],"names":[],"mappings":"AAwBA;IAIE,2BAcC;IAhBD,6BAA0B;IAGxB,cAAwB;IAe1B,wCASC;IAED;;;;;OAKG;IACH,iCAJW,MAAM,cACN,MAAM,GACJ,OAAO,CA+CnB;;CACF;8BAGY,OAAO,YAAY,EAAE,eAAe"}
@@ -1 +1 @@
1
- {"version":3,"file":"feature-flags.d.ts","sourceRoot":"","sources":["../../../../src/common/util/feature-flags.js"],"names":[],"mappings":"AAYA;;;;;;GAMG;AACH,wCAJW;IAAC,CAAC,GAAG,EAAC,MAAM,GAAE,MAAM,CAAA;CAAC,mBACrB,MAAM,GACJ,IAAI,CAehB;AAvBD,gGAAgG;AAChG,mCAAmC"}
1
+ {"version":3,"file":"feature-flags.d.ts","sourceRoot":"","sources":["../../../../src/common/util/feature-flags.js"],"names":[],"mappings":"AAYA;;;;;;GAMG;AACH,wCAJW;IAAC,CAAC,GAAG,EAAC,MAAM,GAAE,MAAM,CAAA;CAAC,mBACrB,MAAM,GACJ,IAAI,CAuBhB;AA/BD,gGAAgG;AAChG,mCAAmC"}
@@ -2,7 +2,6 @@ export class Aggregate extends AggregateBase {
2
2
  static featureName: string;
3
3
  constructor(agentRef: any);
4
4
  isSessionTrackingEnabled: any;
5
- mode: any;
6
5
  loggingMode: any;
7
6
  updateLoggingMode(loggingMode: any): void;
8
7
  handleLog(timestamp: any, message: any, attributes?: {}, level?: string): void;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/features/logging/aggregate/index.js"],"names":[],"mappings":"AAiBA;IACE,2BAAiC;IACjC,2BAmCC;IAjCC,8BAA+G;IAUxG,UAA4B;IAc/B,iBAA4C;IAWlD,0CAKC;IAED,+EAuDC;IAED;;YAIM,0FAA0F;;;QAoB5F,0DAA0D;;QAM7D;IAED;;MAEC;IAED,yDAAyD;IACzD,yBAOC;IAED,yCAIC;CACF;8BApK6B,4BAA4B"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/features/logging/aggregate/index.js"],"names":[],"mappings":"AAiBA;IACE,2BAAiC;IACjC,2BAmCC;IAjCC,8BAA+G;IAUxG,iBAAmC;IAyB5C,0CAKC;IAED,+EAuDC;IAED;;YAIM,0FAA0F;;;QAoB5F,0DAA0D;;QAM7D;IAED;;MAEC;IAED,yDAAyD;IACzD,yBAOC;IAED,yCAIC;CACF;8BApK6B,4BAA4B"}
@@ -1 +1 @@
1
- {"version":3,"file":"recorder.d.ts","sourceRoot":"","sources":["../../../../../src/features/session_replay/shared/recorder.js"],"names":[],"mappings":"AAiBA;IAUE,yBAkBC;IAdC,iEAAiE;IACjE,mBAAsB;IACtB,6DAA6D;IAC7D,oCAAuC;IACvC,+IAA+I;IAC/I,yBAA4B;IAC5B,kIAAkI;IAClI,kBAAqB;IACrB,sDAAsD;IACtD,YAAoB;IACpB,0FAA0F;IAC1F,eAAyE;IACzE,uIAAuI;IACvI,0BAAyE;IAG3E;;;;;;;;;MAmBC;IAED,mFAAmF;IACnF,oBAKC;IAED,qDAAqD;IACrD,uBAoCC;IAED;;;;;OAKG;IACH,aAHW,GAAC,cACD,GAAC,QAgCX;IAED,0HAA0H;IAC1H,yCAoDC;IA1CG,8BAAoB;IA4CxB,0HAA0H;IAC1H,yBAOC;IAED,wBAEC;IAED,gCAAgC;IAChC,uCAGC;IAED;;;SAGK;IACL,oCAGC;;CACF;+BArO8B,mBAAmB"}
1
+ {"version":3,"file":"recorder.d.ts","sourceRoot":"","sources":["../../../../../src/features/session_replay/shared/recorder.js"],"names":[],"mappings":"AAmBA;IAYE,yBAkBC;IAdC,iEAAiE;IACjE,mBAAsB;IACtB,6DAA6D;IAC7D,oCAAuC;IACvC,+IAA+I;IAC/I,yBAA4B;IAC5B,kIAAkI;IAClI,kBAAqB;IACrB,sDAAsD;IACtD,YAAoB;IACpB,0FAA0F;IAC1F,eAAyE;IACzE,uIAAuI;IACvI,0BAAyE;IAG3E;;;;;;;;;MAmBC;IAED,mFAAmF;IACnF,oBAKC;IAED,qDAAqD;IACrD,uBA6BC;IAED;;;;;OAKG;IACH,aAHW,GAAC,cACD,GAAC,QAiCX;IAED,0HAA0H;IAC1H,yCAoDC;IA1CG,8BAAoB;IA4CxB,0HAA0H;IAC1H,yBAOC;IAED,wBAEC;IAED,gCAAgC;IAChC,uCAGC;IAED;;;SAGK;IACL,oCAGC;;CACF;+BAnO8B,mBAAmB"}
@@ -8,4 +8,5 @@ export function buildNRMetaNode(timestamp: any, timeKeeper: any): {
8
8
  correctedOriginTime: any;
9
9
  originTimeDiff: number;
10
10
  };
11
+ export function customMasker(text: any, element: any): any;
11
12
  //# sourceMappingURL=utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../../../src/features/session_replay/shared/utils.js"],"names":[],"mappings":"AASA,6DAIC;AAED,wDAEC;AAED;;;;;;;EAUC"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../../../src/features/session_replay/shared/utils.js"],"names":[],"mappings":"AASA,6DAIC;AAED,wDAEC;AAED;;;;;;;EAUC;AAED,2DAUC"}