@newrelic/browser-agent 1.301.0 → 1.302.0-alpha.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 (142) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/cjs/common/config/init-types.js +1 -1
  3. package/dist/cjs/common/config/init.js +7 -1
  4. package/dist/cjs/common/config/runtime.js +1 -1
  5. package/dist/cjs/common/constants/agent-constants.js +11 -2
  6. package/dist/cjs/common/constants/env.cdn.js +1 -1
  7. package/dist/cjs/common/constants/env.npm.js +1 -1
  8. package/dist/cjs/common/drain/drain.js +1 -1
  9. package/dist/cjs/common/harvest/harvester.js +30 -39
  10. package/dist/cjs/common/util/mfe.js +45 -0
  11. package/dist/cjs/features/ajax/aggregate/index.js +5 -1
  12. package/dist/cjs/features/generic_events/aggregate/index.js +9 -8
  13. package/dist/cjs/features/generic_events/constants.js +3 -1
  14. package/dist/cjs/features/generic_events/instrument/index.js +38 -32
  15. package/dist/cjs/features/jserrors/aggregate/index.js +18 -17
  16. package/dist/cjs/features/logging/aggregate/index.js +19 -15
  17. package/dist/cjs/features/logging/shared/utils.js +3 -3
  18. package/dist/cjs/features/page_view_event/aggregate/index.js +3 -33
  19. package/dist/cjs/features/session_replay/aggregate/index.js +13 -13
  20. package/dist/cjs/features/session_replay/shared/recorder.js +3 -2
  21. package/dist/cjs/features/session_trace/aggregate/index.js +0 -2
  22. package/dist/cjs/features/soft_navigations/aggregate/index.js +1 -2
  23. package/dist/cjs/features/utils/aggregate-base.js +45 -47
  24. package/dist/cjs/loaders/api/addPageAction.js +2 -2
  25. package/dist/cjs/loaders/api/log.js +2 -2
  26. package/dist/cjs/loaders/api/noticeError.js +2 -2
  27. package/dist/cjs/loaders/api/register-api-types.js +5 -5
  28. package/dist/cjs/loaders/api/register.js +80 -97
  29. package/dist/esm/common/config/init-types.js +1 -1
  30. package/dist/esm/common/config/init.js +7 -1
  31. package/dist/esm/common/config/runtime.js +1 -1
  32. package/dist/esm/common/constants/agent-constants.js +9 -1
  33. package/dist/esm/common/constants/env.cdn.js +1 -1
  34. package/dist/esm/common/constants/env.npm.js +1 -1
  35. package/dist/esm/common/drain/drain.js +1 -1
  36. package/dist/esm/common/harvest/harvester.js +30 -39
  37. package/dist/esm/common/util/mfe.js +38 -0
  38. package/dist/esm/features/ajax/aggregate/index.js +5 -1
  39. package/dist/esm/features/generic_events/aggregate/index.js +9 -8
  40. package/dist/esm/features/generic_events/constants.js +3 -1
  41. package/dist/esm/features/generic_events/instrument/index.js +38 -32
  42. package/dist/esm/features/jserrors/aggregate/index.js +18 -17
  43. package/dist/esm/features/logging/aggregate/index.js +19 -15
  44. package/dist/esm/features/logging/shared/utils.js +3 -3
  45. package/dist/esm/features/page_view_event/aggregate/index.js +3 -33
  46. package/dist/esm/features/session_replay/aggregate/index.js +13 -13
  47. package/dist/esm/features/session_replay/shared/recorder.js +3 -2
  48. package/dist/esm/features/session_trace/aggregate/index.js +0 -2
  49. package/dist/esm/features/soft_navigations/aggregate/index.js +1 -2
  50. package/dist/esm/features/utils/aggregate-base.js +46 -48
  51. package/dist/esm/loaders/api/addPageAction.js +2 -2
  52. package/dist/esm/loaders/api/log.js +2 -2
  53. package/dist/esm/loaders/api/noticeError.js +2 -2
  54. package/dist/esm/loaders/api/register-api-types.js +5 -5
  55. package/dist/esm/loaders/api/register.js +80 -97
  56. package/dist/tsconfig.tsbuildinfo +1 -1
  57. package/dist/types/common/config/init-types.d.ts +4 -1
  58. package/dist/types/common/config/init-types.d.ts.map +1 -1
  59. package/dist/types/common/config/init.d.ts.map +1 -1
  60. package/dist/types/common/constants/agent-constants.d.ts +7 -4
  61. package/dist/types/common/constants/agent-constants.d.ts.map +1 -1
  62. package/dist/types/common/harvest/harvester.d.ts +2 -2
  63. package/dist/types/common/harvest/harvester.d.ts.map +1 -1
  64. package/dist/types/common/util/mfe.d.ts +20 -0
  65. package/dist/types/common/util/mfe.d.ts.map +1 -0
  66. package/dist/types/features/ajax/aggregate/index.d.ts.map +1 -1
  67. package/dist/types/features/generic_events/aggregate/index.d.ts +2 -2
  68. package/dist/types/features/generic_events/aggregate/index.d.ts.map +1 -1
  69. package/dist/types/features/generic_events/constants.d.ts +1 -0
  70. package/dist/types/features/generic_events/instrument/index.d.ts.map +1 -1
  71. package/dist/types/features/jserrors/aggregate/index.d.ts +3 -3
  72. package/dist/types/features/jserrors/aggregate/index.d.ts.map +1 -1
  73. package/dist/types/features/logging/aggregate/index.d.ts +3 -3
  74. package/dist/types/features/logging/aggregate/index.d.ts.map +1 -1
  75. package/dist/types/features/logging/shared/utils.d.ts +2 -2
  76. package/dist/types/features/logging/shared/utils.d.ts.map +1 -1
  77. package/dist/types/features/page_view_event/aggregate/index.d.ts +2 -4
  78. package/dist/types/features/page_view_event/aggregate/index.d.ts.map +1 -1
  79. package/dist/types/features/session_replay/aggregate/index.d.ts +13 -4
  80. package/dist/types/features/session_replay/aggregate/index.d.ts.map +1 -1
  81. package/dist/types/features/session_replay/shared/recorder.d.ts +1 -0
  82. package/dist/types/features/session_replay/shared/recorder.d.ts.map +1 -1
  83. package/dist/types/features/session_trace/aggregate/index.d.ts.map +1 -1
  84. package/dist/types/features/soft_navigations/aggregate/index.d.ts.map +1 -1
  85. package/dist/types/features/utils/aggregate-base.d.ts +13 -5
  86. package/dist/types/features/utils/aggregate-base.d.ts.map +1 -1
  87. package/dist/types/loaders/api/addPageAction.d.ts +1 -1
  88. package/dist/types/loaders/api/addPageAction.d.ts.map +1 -1
  89. package/dist/types/loaders/api/log.d.ts +1 -1
  90. package/dist/types/loaders/api/log.d.ts.map +1 -1
  91. package/dist/types/loaders/api/noticeError.d.ts +1 -1
  92. package/dist/types/loaders/api/noticeError.d.ts.map +1 -1
  93. package/dist/types/loaders/api/register-api-types.d.ts +4 -4
  94. package/dist/types/loaders/api/register-api-types.d.ts.map +1 -1
  95. package/dist/types/loaders/api/register.d.ts +8 -1
  96. package/dist/types/loaders/api/register.d.ts.map +1 -1
  97. package/package.json +3 -3
  98. package/src/common/config/init-types.js +1 -1
  99. package/src/common/config/init.js +3 -1
  100. package/src/common/config/runtime.js +1 -1
  101. package/src/common/constants/agent-constants.js +10 -0
  102. package/src/common/drain/drain.js +1 -1
  103. package/src/common/harvest/harvester.js +27 -32
  104. package/src/common/util/mfe.js +35 -0
  105. package/src/features/ajax/aggregate/index.js +7 -1
  106. package/src/features/generic_events/aggregate/index.js +9 -8
  107. package/src/features/generic_events/constants.js +3 -1
  108. package/src/features/generic_events/instrument/index.js +44 -35
  109. package/src/features/jserrors/aggregate/index.js +17 -17
  110. package/src/features/logging/aggregate/index.js +20 -13
  111. package/src/features/logging/shared/utils.js +3 -3
  112. package/src/features/page_view_event/aggregate/index.js +3 -28
  113. package/src/features/session_replay/aggregate/index.js +12 -10
  114. package/src/features/session_replay/shared/recorder.js +3 -2
  115. package/src/features/session_trace/aggregate/index.js +0 -2
  116. package/src/features/soft_navigations/aggregate/index.js +1 -2
  117. package/src/features/utils/aggregate-base.js +47 -42
  118. package/src/loaders/api/addPageAction.js +2 -2
  119. package/src/loaders/api/log.js +2 -2
  120. package/src/loaders/api/noticeError.js +2 -2
  121. package/src/loaders/api/register-api-types.js +5 -5
  122. package/src/loaders/api/register.js +62 -89
  123. package/dist/cjs/common/util/target.js +0 -34
  124. package/dist/cjs/features/utils/entity-manager.js +0 -46
  125. package/dist/cjs/features/utils/event-store-manager.js +0 -174
  126. package/dist/cjs/loaders/api/register-api.js +0 -165
  127. package/dist/esm/common/util/target.js +0 -27
  128. package/dist/esm/features/utils/entity-manager.js +0 -39
  129. package/dist/esm/features/utils/event-store-manager.js +0 -166
  130. package/dist/esm/loaders/api/register-api.js +0 -159
  131. package/dist/types/common/util/target.d.ts +0 -18
  132. package/dist/types/common/util/target.d.ts.map +0 -1
  133. package/dist/types/features/utils/entity-manager.d.ts +0 -11
  134. package/dist/types/features/utils/entity-manager.d.ts.map +0 -1
  135. package/dist/types/features/utils/event-store-manager.d.ts +0 -85
  136. package/dist/types/features/utils/event-store-manager.d.ts.map +0 -1
  137. package/dist/types/loaders/api/register-api.d.ts +0 -14
  138. package/dist/types/loaders/api/register-api.d.ts.map +0 -1
  139. package/src/common/util/target.js +0 -27
  140. package/src/features/utils/entity-manager.js +0 -45
  141. package/src/features/utils/event-store-manager.js +0 -165
  142. package/src/loaders/api/register-api.js +0 -152
@@ -12,10 +12,10 @@ var _constants = require("../constants");
12
12
  var _log = require("../shared/log");
13
13
  var _utils = require("../shared/utils");
14
14
  var _traverse = require("../../../common/util/traverse");
15
- var _target = require("../../../common/util/target");
16
15
  var _constants2 = require("../../../common/session/constants");
17
16
  var _constants3 = require("../../session_replay/constants");
18
17
  var _featureGates = require("../../utils/feature-gates");
18
+ var _mfe = require("../../../common/util/mfe");
19
19
  /**
20
20
  * Copyright 2020-2025 New Relic, Inc. All rights reserved.
21
21
  * SPDX-License-Identifier: Apache-2.0
@@ -26,6 +26,9 @@ class Aggregate extends _aggregateBase.AggregateBase {
26
26
  constructor(agentRef) {
27
27
  super(agentRef, _constants.FEATURE_NAME);
28
28
  this.isSessionTrackingEnabled = (0, _featureGates.canEnableSessionTracking)(agentRef.init) && agentRef.runtime.session;
29
+
30
+ /** set up agg-level behaviors specific to this feature */
31
+ this.harvestOpts.raw = true;
29
32
  super.customAttributesAreSeparate = true;
30
33
 
31
34
  // The SessionEntity class can emit a message indicating the session was cleared and reset (expiry, inactivity). This feature must abort and never resume if that occurs.
@@ -36,7 +39,6 @@ class Aggregate extends _aggregateBase.AggregateBase {
36
39
  if (this.blocked || type !== _constants2.SESSION_EVENT_TYPES.CROSS_TAB) return;
37
40
  if (this.loggingMode !== _constants.LOGGING_MODE.OFF && data.loggingMode === _constants.LOGGING_MODE.OFF) this.abort(_constants3.ABORT_REASONS.CROSS_TAB);else this.loggingMode = data.loggingMode;
38
41
  });
39
- this.harvestOpts.raw = true;
40
42
  this.waitForFlags(['log']).then(([loggingMode]) => {
41
43
  const session = this.agentRef.runtime.session ?? {};
42
44
  if (this.loggingMode === _constants.LOGGING_MODE.OFF || session.isNew && loggingMode === _constants.LOGGING_MODE.OFF) {
@@ -63,10 +65,14 @@ class Aggregate extends _aggregateBase.AggregateBase {
63
65
  loggingMode: this.loggingMode
64
66
  });
65
67
  }
66
- handleLog(timestamp, message, attributes = {}, level = _constants.LOG_LEVELS.INFO, targetEntityGuid) {
67
- if (!this.agentRef.runtime.entityManager.get(targetEntityGuid)) return (0, _console.warn)(56, this.featureName);
68
+ handleLog(timestamp, message, attributes = {}, level = _constants.LOG_LEVELS.INFO, target) {
68
69
  if (this.blocked || !this.loggingMode) return;
69
70
  if (!attributes || typeof attributes !== 'object') attributes = {};
71
+ attributes = {
72
+ ...attributes,
73
+ /** Specific attributes only supplied if harvesting to endpoint version 2 */
74
+ ...(0, _mfe.getVersion2Attributes)(target, this)
75
+ };
70
76
  if (typeof level === 'string') level = level.toUpperCase();
71
77
  if (!(0, _utils.isValidLogLevel)(level)) return (0, _console.warn)(30, level);
72
78
  if (this.loggingMode < (_constants.LOGGING_MODE[level] || Infinity)) {
@@ -90,10 +96,9 @@ class Aggregate extends _aggregateBase.AggregateBase {
90
96
  }
91
97
  if (typeof message !== 'string' || !message) return (0, _console.warn)(32);
92
98
  const log = new _log.Log(Math.floor(this.agentRef.runtime.timeKeeper.correctRelativeTimestamp(timestamp)), message, attributes, level);
93
- this.events.add(log, targetEntityGuid);
99
+ this.events.add(log);
94
100
  }
95
- serializer(eventBuffer, targetEntityGuid) {
96
- const target = this.agentRef.runtime.entityManager.get(targetEntityGuid);
101
+ serializer(eventBuffer) {
97
102
  const sessionEntity = this.agentRef.runtime.session;
98
103
  return [{
99
104
  common: {
@@ -101,19 +106,19 @@ class Aggregate extends _aggregateBase.AggregateBase {
101
106
  attributes: {
102
107
  ...this.agentRef.info.jsAttributes,
103
108
  // user-provided custom attributes
104
- 'entity.guid': target.entityGuid,
105
- // browser entity guid as provided API target OR the default from RUM response if not supplied
109
+ ...(this.harvestEndpointVersion === 1 && {
110
+ 'entity.guid': this.agentRef.runtime.appMetadata.agents[0].entityGuid,
111
+ appId: this.agentRef.info.applicationID
112
+ }),
106
113
  ...(sessionEntity && {
107
114
  session: sessionEntity.state.value || '0',
108
115
  // The session ID that we generate and keep across page loads
109
- hasReplay: sessionEntity.state.sessionReplayMode === 1 && (0, _target.isContainerAgentTarget)(target, this.agentRef),
116
+ hasReplay: sessionEntity.state.sessionReplayMode === 1,
110
117
  // True if a session replay recording is running
111
118
  hasTrace: sessionEntity.state.sessionTraceMode === 1 // True if a session trace recording is running
112
119
  }),
113
120
  ptid: this.agentRef.runtime.ptid,
114
121
  // page trace id
115
- appId: target.applicationID || this.agentRef.info.applicationID,
116
- // Application ID from info object,
117
122
  standalone: Boolean(this.agentRef.info.sa),
118
123
  // copy paste (true) vs APM (false)
119
124
  agentVersion: this.agentRef.runtime.version,
@@ -128,10 +133,9 @@ class Aggregate extends _aggregateBase.AggregateBase {
128
133
  logs: (0, _traverse.applyFnToProps)(eventBuffer, this.obfuscator.obfuscateString.bind(this.obfuscator), 'string')
129
134
  }];
130
135
  }
131
- queryStringsBuilder(_, targetEntityGuid) {
132
- const target = this.agentRef.runtime.entityManager.get(targetEntityGuid);
136
+ queryStringsBuilder() {
133
137
  return {
134
- browser_monitoring_key: target.licenseKey
138
+ browser_monitoring_key: this.agentRef.info.licenseKey
135
139
  };
136
140
  }
137
141
 
@@ -20,11 +20,11 @@ var _constants2 = require("../constants");
20
20
  * @param {string} message - the log message string
21
21
  * @param {{[key: string]: *}} customAttributes - The log's custom attributes if any
22
22
  * @param {enum} level - the log level enum
23
- * @param {object=} targetEntityGuid - the optional target entity guid provided by an api call
23
+ * @param {object=} target - the optional target provided by an api call
24
24
  */
25
- function bufferLog(ee, message, customAttributes = {}, level = _constants2.LOG_LEVELS.INFO, targetEntityGuid, timestamp = (0, _now.now)()) {
25
+ function bufferLog(ee, message, customAttributes = {}, level = _constants2.LOG_LEVELS.INFO, target, timestamp = (0, _now.now)()) {
26
26
  (0, _handle.handle)(_constants.SUPPORTABILITY_METRIC_CHANNEL, ["API/logging/".concat(level.toLowerCase(), "/called")], undefined, _features.FEATURE_NAMES.metrics, ee);
27
- (0, _handle.handle)(_constants2.LOGGING_EVENT_EMITTER_CHANNEL, [timestamp, message, customAttributes, level, targetEntityGuid], undefined, _features.FEATURE_NAMES.logging, ee);
27
+ (0, _handle.handle)(_constants2.LOGGING_EVENT_EMITTER_CHANNEL, [timestamp, message, customAttributes, level, target], undefined, _features.FEATURE_NAMES.logging, ee);
28
28
  }
29
29
 
30
30
  /**
@@ -19,8 +19,6 @@ var _timeToFirstByte = require("../../../common/vitals/time-to-first-byte");
19
19
  var _now = require("../../../common/timing/now");
20
20
  var _timeKeeper = require("../../../common/timing/time-keeper");
21
21
  var _traverse = require("../../../common/util/traverse");
22
- var _registerHandler = require("../../../common/event-emitter/register-handler");
23
- var _target = require("../../../common/util/target");
24
22
  function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
25
23
  /**
26
24
  * Copyright 2020-2025 New Relic, Inc. All rights reserved.
@@ -35,9 +33,6 @@ class Aggregate extends _aggregateBase.AggregateBase {
35
33
  this.firstByteToWindowLoad = 0; // our "frontend" duration
36
34
  this.firstByteToDomContent = 0; // our "dom processing" duration
37
35
 
38
- (0, _registerHandler.registerHandler)('send-rum', (customAttibutes, target) => {
39
- this.sendRum(customAttibutes, target);
40
- }, this.featureName, this.ee);
41
36
  if (!(0, _info.isValid)(agentRef.info)) {
42
37
  this.ee.abort();
43
38
  return (0, _console.warn)(43);
@@ -65,7 +60,7 @@ class Aggregate extends _aggregateBase.AggregateBase {
65
60
  *
66
61
  * @param {Function} cb A function to run once the RUM call has finished - Defaults to activateFeatures
67
62
  * @param {*} customAttributes custom attributes to attach to the RUM call - Defaults to info.js
68
- * @param {*} target The target to harvest to - Since we will not know the entityGuid before harvesting, this must be an object directly supplied from the info object or API, not an entityGuid string for lookup with the entityManager - Defaults to { licenseKey: this.agentRef.info.licenseKey, applicationID: this.agentRef.info.applicationID }
63
+ * @param {*} target The target to harvest to
69
64
  */
70
65
  sendRum(customAttributes = this.agentRef.info.jsAttributes, target = {
71
66
  licenseKey: this.agentRef.info.licenseKey,
@@ -128,7 +123,7 @@ class Aggregate extends _aggregateBase.AggregateBase {
128
123
  this.rumStartTime = (0, _now.now)();
129
124
  this.agentRef.runtime.harvester.triggerHarvestFor(this, {
130
125
  directSend: {
131
- targetApp: target,
126
+ target,
132
127
  payload: {
133
128
  qs: queryParameters,
134
129
  body
@@ -141,8 +136,7 @@ class Aggregate extends _aggregateBase.AggregateBase {
141
136
  postHarvestCleanup({
142
137
  status,
143
138
  responseText,
144
- xhr,
145
- targetApp
139
+ xhr
146
140
  }) {
147
141
  const rumEndTime = (0, _now.now)();
148
142
  let app, flags;
@@ -151,14 +145,10 @@ class Aggregate extends _aggregateBase.AggregateBase {
151
145
  app,
152
146
  ...flags
153
147
  } = JSON.parse(responseText));
154
- this.processEntities(app.agents, targetApp);
155
148
  } catch (error) {
156
149
  // wont set entity stuff here, if main agent will later abort, if registered agent, nothing will happen
157
150
  (0, _console.warn)(53, error);
158
151
  }
159
-
160
- /** Only run agent-wide side-effects if the harvest was for the main agent */
161
- if (!(0, _target.isContainerAgentTarget)(targetApp, this.agentRef)) return;
162
152
  if (status >= 400 || status === 0) {
163
153
  (0, _console.warn)(18, status);
164
154
  // Adding retry logic for the rum call will be a separate change; this.blocked will need to be changed since that prevents another triggerHarvestFor()
@@ -189,25 +179,5 @@ class Aggregate extends _aggregateBase.AggregateBase {
189
179
  this.agentRef.runtime.harvester.startTimer();
190
180
  (0, _featureFlags.activateFeatures)(flags, this.agentRef);
191
181
  }
192
- processEntities(entities, targetApp) {
193
- if (!entities || !targetApp) return;
194
- entities.forEach(agent => {
195
- const entityManager = this.agentRef.runtime.entityManager;
196
- const entityGuid = agent.entityGuid;
197
- const entity = entityManager.get(entityGuid);
198
- if (entity) return; // already processed
199
-
200
- if ((0, _target.isContainerAgentTarget)(targetApp, this.agentRef)) {
201
- entityManager.setDefaultEntity({
202
- ...targetApp,
203
- entityGuid
204
- });
205
- }
206
- entityManager.set(agent.entityGuid, {
207
- ...targetApp,
208
- entityGuid
209
- });
210
- });
211
- }
212
182
  }
213
183
  exports.Aggregate = Aggregate;
@@ -40,6 +40,8 @@ class Aggregate extends _aggregateBase.AggregateBase {
40
40
  this.gzipper = undefined;
41
41
  /** populated with the u8 string lib async */
42
42
  this.u8 = undefined;
43
+ /** flips to false if the compressor libraries cannot import */
44
+ this.shouldCompress = true;
43
45
 
44
46
  /** set by BCS response */
45
47
  this.entitled = false;
@@ -211,23 +213,22 @@ class Aggregate extends _aggregateBase.AggregateBase {
211
213
  this.gzipper = gzipSync;
212
214
  this.u8 = strToU8;
213
215
  } catch (err) {
214
- // compressor failed to load, but we can still record without compression as a last ditch effort
216
+ this.shouldCompress = false;
217
+ // compressor failed to load, but we can still try to record without compression as a last ditch effort
215
218
  }
216
219
  }
217
- makeHarvestPayload(shouldRetryOnFail) {
218
- const payloadOutput = {
219
- targetApp: undefined,
220
- payload: undefined
221
- };
222
- if (this.mode !== _constants2.MODE.FULL || this.blocked) return;
223
- if (!this.recorder || !this.timeKeeper?.ready || !this.recorder.hasSeenSnapshot) return;
220
+ makeHarvestPayload() {
221
+ if (this.mode !== _constants2.MODE.FULL || this.blocked) return; // harvests should only be made in FULL mode, and not if the feature is blocked
222
+ if (this.shouldCompress && !this.gzipper) return; // if compression is enabled, but the libraries have not loaded, wait for them to load
223
+ if (!this.recorder || !this.timeKeeper?.ready || !(this.recorder.hasSeenSnapshot && this.recorder.hasSeenMeta)) return; // if the recorder or the timekeeper is not ready, or the recorder has not yet seen a snapshot, do not harvest
224
+
224
225
  const recorderEvents = this.recorder.getEvents();
225
226
  // get the event type and use that to trigger another harvest if needed
226
227
  if (!recorderEvents.events.length) return;
227
228
  const payload = this.getHarvestContents(recorderEvents);
228
229
  if (!payload.body.length) {
229
230
  this.recorder.clearBuffer();
230
- return [payloadOutput];
231
+ return;
231
232
  }
232
233
  this.reportSupportabilityMetric('SessionReplay/Harvest/Attempts');
233
234
  let len = 0;
@@ -242,19 +243,18 @@ class Aggregate extends _aggregateBase.AggregateBase {
242
243
  }
243
244
  if (len > _agentConstants.MAX_PAYLOAD_SIZE) {
244
245
  this.abort(_constants.ABORT_REASONS.TOO_BIG, len);
245
- return [payloadOutput];
246
+ return;
246
247
  }
248
+
247
249
  // TODO -- Gracefully handle the buffer for retries.
248
250
  if (!this.agentRef.runtime.session.state.sessionReplaySentFirstChunk) this.syncWithSessionManager({
249
251
  sessionReplaySentFirstChunk: true
250
252
  });
251
253
  this.recorder.clearBuffer();
252
- if (recorderEvents.type === 'preloaded') this.agentRef.runtime.harvester.triggerHarvestFor(this);
253
- payloadOutput.payload = payload;
254
254
  if (!this.agentRef.runtime.session.state.traceHarvestStarted) {
255
255
  (0, _console.warn)(59, JSON.stringify(this.agentRef.runtime.session.state));
256
256
  }
257
- return [payloadOutput];
257
+ return payload;
258
258
  }
259
259
 
260
260
  /**
@@ -49,6 +49,7 @@ class Recorder {
49
49
  this.backloggedEvents = new _recorderEvents.RecorderEvents(this.shouldFix);
50
50
  /** Only set to true once a snapshot node has been processed. Used to block harvests from sending before we know we have a snapshot */
51
51
  this.hasSeenSnapshot = false;
52
+ this.hasSeenMeta = false;
52
53
  /** Hold on to the last meta node, so that it can be re-inserted if the meta and snapshot nodes are broken up due to harvesting */
53
54
  this.lastMeta = false;
54
55
  /** The method to stop recording. This defaults to a noop, but is overwritten once the recording library is imported and initialized */
@@ -203,9 +204,9 @@ class Recorder {
203
204
  }
204
205
 
205
206
  // meta event
206
- this.events.hasMeta ||= event.type === _constants.RRWEB_EVENT_TYPES.Meta;
207
+ this.hasSeenMeta ||= this.events.hasMeta ||= event.type === _constants.RRWEB_EVENT_TYPES.Meta;
207
208
  // snapshot event
208
- this.events.hasSnapshot ||= this.hasSeenSnapshot ||= event.type === _constants.RRWEB_EVENT_TYPES.FullSnapshot;
209
+ this.hasSeenSnapshot ||= this.events.hasSnapshot ||= event.type === _constants.RRWEB_EVENT_TYPES.FullSnapshot;
209
210
 
210
211
  //* dont let the EventBuffer class double evaluate the event data size, it's a performance burden and we have special reasons to do it outside the event buffer */
211
212
  this.events.add(event, eventBytes);
@@ -98,8 +98,6 @@ class Aggregate extends _aggregateBase.AggregateBase {
98
98
  sessionTraceMode: this.mode
99
99
  });
100
100
  this.drain();
101
- /** try to harvest immediately. This will not send if the trace is not running in FULL mode due to the pre-harvest checks. */
102
- this.agentRef.runtime.harvester.triggerHarvestFor(this);
103
101
  }
104
102
  preHarvestChecks() {
105
103
  if (this.blocked || this.mode !== _constants2.MODE.FULL) return; // only allow harvest if running in full mode
@@ -53,7 +53,6 @@ class Aggregate extends _aggregateBase.AggregateBase {
53
53
  this.waitForFlags(['spa']).then(([spaOn]) => {
54
54
  if (spaOn) {
55
55
  this.drain();
56
- setTimeout(() => agentRef.runtime.harvester.triggerHarvestFor(this), 0); // send the IPL ixn on next tick, giving some time for any ajax to finish; we may want to just remove this?
57
56
  } else {
58
57
  this.blocked = true; // if rum response determines that customer lacks entitlements for spa endpoint, this feature shouldn't harvest
59
58
  this.deregisterDrain();
@@ -148,7 +147,7 @@ class Aggregate extends _aggregateBase.AggregateBase {
148
147
  */
149
148
  if (this.interactionInProgress?.isActiveDuring(timestamp)) return this.interactionInProgress;
150
149
  let saveIxn;
151
- const interactionsBuffer = this.interactionsToHarvest.get()?.[0]?.data;
150
+ const interactionsBuffer = this.interactionsToHarvest.get();
152
151
  if (!interactionsBuffer) return undefined; // no interactions have been staged yet, so nothing to search through)
153
152
  for (let idx = interactionsBuffer.length - 1; idx >= 0; idx--) {
154
153
  // reverse search for the latest completed interaction for efficiency
@@ -12,10 +12,7 @@ var _drain = require("../../common/drain/drain");
12
12
  var _featureFlags = require("../../common/util/feature-flags");
13
13
  var _obfuscate = require("../../common/util/obfuscate");
14
14
  var _features = require("../../loaders/features/features");
15
- var _eventStoreManager = require("./event-store-manager");
16
15
  var _harvester = require("../../common/harvest/harvester");
17
- var _console = require("../../common/util/console");
18
- var _entityManager = require("./entity-manager");
19
16
  var _eventBuffer = require("./event-buffer");
20
17
  var _handle = require("../../common/event-emitter/handle");
21
18
  var _constants = require("../metrics/constants");
@@ -46,16 +43,8 @@ class AggregateBase extends _featureBase.FeatureBase {
46
43
  this.isRetrying = false;
47
44
  this.harvestOpts = {}; // features aggregate classes can define custom opts for when their harvest is called
48
45
 
49
- const agentEntityGuid = this.agentRef?.runtime?.appMetadata?.agents?.[0]?.entityGuid;
50
- this.#setupEventStore(agentEntityGuid);
51
- if (!agentEntityGuid) {
52
- /** wait for the entity guid from the rum response and use to it to further configure things to set the default entity to share an indexed entity with entityGuid */
53
- this.ee.on('entity-added', entity => {
54
- // not all event managers have this fn, like ST and SR
55
- // this allows the lookup to work for the default and an entityGuid without creating two separate buffers
56
- this.events?.setEventStore?.(entity.entityGuid);
57
- });
58
- }
46
+ this.#setupEventStore();
47
+ this.waitForDrain();
59
48
  }
60
49
 
61
50
  /**
@@ -63,7 +52,7 @@ class AggregateBase extends _featureBase.FeatureBase {
63
52
  * @param {string} entityGuid
64
53
  * @returns {void}
65
54
  */
66
- #setupEventStore(entityGuid) {
55
+ #setupEventStore() {
67
56
  if (this.events) return;
68
57
  switch (this.featureName) {
69
58
  // SessionReplay has its own storage mechanisms.
@@ -72,19 +61,39 @@ class AggregateBase extends _featureBase.FeatureBase {
72
61
  // Jserror and Metric features uses a singleton EventAggregator instead of a regular EventBuffer.
73
62
  case _features.FEATURE_NAMES.jserrors:
74
63
  case _features.FEATURE_NAMES.metrics:
75
- this.events = this.agentRef.sharedAggregator ??= new _eventStoreManager.EventStoreManager(this.agentRef, _eventAggregator.EventAggregator, entityGuid, {
76
- featureName: 'shared_aggregator'
77
- });
64
+ this.events = this.agentRef.sharedAggregator ??= new _eventAggregator.EventAggregator();
78
65
  break;
79
- /** All other features get EventBuffer in the ESM by default. Note: PVE is included here, but event buffer will always be empty so future harvests will still not happen by interval or EOL.
66
+ /** All other features get EventBuffer by default. Note: PVE is included here, but event buffer will always be empty so future harvests will still not happen by interval or EOL.
80
67
  This was necessary to prevent race cond. issues where the event buffer was checked before the feature could "block" itself.
81
68
  Its easier to just keep an empty event buffer in place. */
82
69
  default:
83
- this.events = new _eventStoreManager.EventStoreManager(this.agentRef, _eventBuffer.EventBuffer, entityGuid, this);
70
+ this.events = new _eventBuffer.EventBuffer(_agentConstants.MAX_PAYLOAD_SIZE, this);
84
71
  break;
85
72
  }
86
73
  }
87
74
 
75
+ /** @type {Boolean} indicates if the feature supports registered entities and the harvest requirements therein. Also read by getter "harvestEndpointVersion". Controlled by feature flag in pre-release phase. */
76
+ get supportsRegisteredEntities() {
77
+ return this.featureName in _agentConstants.SUPPORTS_REGISTERED_ENTITIES && (_agentConstants.SUPPORTS_REGISTERED_ENTITIES[this.featureName] || this.agentRef.init.feature_flags.includes('register.' + this.featureName));
78
+ }
79
+
80
+ /**
81
+ * the endpoint version the feature uses during harvests
82
+ * @type {number}
83
+ * @returns {boolean}
84
+ */
85
+ get harvestEndpointVersion() {
86
+ return this.supportsRegisteredEntities && !!this.agentRef.runtime.registeredEntities.length ? 2 : 1;
87
+ }
88
+ waitForDrain() {
89
+ /** emitted when the feature successfully drains */
90
+ this.ee.on('drain-' + this.featureName, () => {
91
+ /** make an immediate harvest for all the features to help with harvestability for pre-load dervied data on short lived pages */
92
+ if (!this.drained) setTimeout(() => this.agentRef.runtime.harvester.triggerHarvestFor(this), 1);
93
+ this.drained = true;
94
+ });
95
+ }
96
+
88
97
  /**
89
98
  * Evaluates whether a harvest should be made early by estimating the size of the current payload. Currently, this only happens if the event storage is EventBuffer, since that triggers this method directly.
90
99
  * If conditions are met, a new harvest will be triggered immediately.
@@ -132,7 +141,6 @@ class AggregateBase extends _featureBase.FeatureBase {
132
141
  */
133
142
  drain() {
134
143
  (0, _drain.drain)(this.agentIdentifier, this.featureName);
135
- this.drained = true;
136
144
  }
137
145
  preHarvestChecks(opts) {
138
146
  return !this.blocked;
@@ -142,47 +150,38 @@ class AggregateBase extends _featureBase.FeatureBase {
142
150
  * Return harvest payload. A "serializer" function can be defined on a derived class to format the payload.
143
151
  * @param {Boolean} shouldRetryOnFail - harvester flag to backup payload for retry later if harvest request fails; this should be moved to harvester logic
144
152
  * @param {object|undefined} opts - opts passed from the harvester to help form the payload
145
- * @param {string} opts.targetEntityGuid - the entity guid of the target app
153
+ * @param {string} opts.target - the target app metadata
146
154
  * @returns {Array} Final payload tagged with their targeting browser app. The value of `payload` can be undefined if there are no pending events for an app. This should be a minimum length of 1.
147
155
  */
148
156
  makeHarvestPayload(shouldRetryOnFail = false, opts = {}) {
149
- if (!this.events || this.events.isEmpty(this.harvestOpts, opts.targetEntityGuid)) return;
157
+ if (!this.events || this.events.isEmpty(this.harvestOpts)) return;
150
158
  // Other conditions and things to do when preparing harvest that is required.
151
159
  if (this.preHarvestChecks && !this.preHarvestChecks(opts)) return;
152
- if (shouldRetryOnFail) this.events.save(this.harvestOpts, opts.targetEntityGuid);
153
- const returnedDataArr = this.events.get(this.harvestOpts, opts.targetEntityGuid);
154
- if (!returnedDataArr.length) return (0, _console.warn)(52);
155
- this.events.clear(this.harvestOpts, opts.targetEntityGuid);
156
- return returnedDataArr.map(({
157
- targetApp,
158
- data
159
- }) => {
160
- // A serializer or formatter assists in creating the payload `body` from stored events on harvest when defined by derived feature class.
161
- const body = this.serializer ? this.serializer(data, targetApp?.entityGuid) : data;
162
- const payload = {
163
- body
164
- };
165
- // Constructs the payload `qs` for relevant features on harvest.
166
- if (this.queryStringsBuilder) payload.qs = this.queryStringsBuilder(data, targetApp?.entityGuid);
167
- return {
168
- targetApp,
169
- payload
170
- };
171
- });
160
+ if (shouldRetryOnFail) this.events.save(this.harvestOpts);
161
+ const data = this.events.get(this.harvestOpts);
162
+ if (!data) return;
163
+ this.events.clear(this.harvestOpts);
164
+
165
+ // A serializer or formatter assists in creating the payload `body` from stored events on harvest when defined by derived feature class.
166
+ const body = this.serializer ? this.serializer(data) : data;
167
+ const payload = {
168
+ body
169
+ };
170
+ // Constructs the payload `qs` for relevant features on harvest.
171
+ if (this.queryStringsBuilder) payload.qs = this.queryStringsBuilder(data);
172
+ return payload;
172
173
  }
173
174
 
174
175
  /**
175
176
  * Cleanup task after a harvest.
176
177
  * @param {object} result - the cbResult object from the harvester's send method
177
- * @param {object=} result.targetApp - the target app object that was used to point the harvest to the correct app
178
- * @param {string=} result.targetApp.entityGuid - the entity guid of the target app
179
178
  * @param {boolean=} result.sent - whether the harvest was sent successfully
180
179
  * @param {boolean=} result.retry - whether the harvest should be retried
181
180
  */
182
181
  postHarvestCleanup(result = {}) {
183
182
  this.isRetrying = result.sent && result.retry;
184
- if (this.isRetrying) this.events.reloadSave(this.harvestOpts, result.targetApp?.entityGuid);
185
- this.events.clearSave(this.harvestOpts, result.targetApp?.entityGuid);
183
+ if (this.isRetrying) this.events.reloadSave(this.harvestOpts);
184
+ this.events.clearSave(this.harvestOpts);
186
185
  }
187
186
 
188
187
  /**
@@ -222,7 +221,6 @@ class AggregateBase extends _featureBase.FeatureBase {
222
221
  doOnceForAllAggregate(agentRef) {
223
222
  if (!agentRef.runtime.obfuscator) agentRef.runtime.obfuscator = new _obfuscate.Obfuscator(agentRef);
224
223
  this.obfuscator = agentRef.runtime.obfuscator;
225
- if (!agentRef.runtime.entityManager) agentRef.runtime.entityManager = new _entityManager.EntityManager(this.agentRef);
226
224
  if (!agentRef.runtime.harvester) agentRef.runtime.harvester = new _harvester.Harvester(agentRef);
227
225
  }
228
226
 
@@ -18,6 +18,6 @@ var _sharedHandlers = require("./sharedHandlers");
18
18
  function setupAddPageActionAPI(agent) {
19
19
  (0, _sharedHandlers.setupAPI)(_constants.ADD_PAGE_ACTION, (name, attributes) => addPageAction(name, attributes, agent), agent);
20
20
  }
21
- function addPageAction(name, attributes, agentRef, targetEntityGuid, timestamp = (0, _now.now)()) {
22
- (0, _handle.handle)(_constants.prefix + _constants.ADD_PAGE_ACTION, [timestamp, name, attributes, targetEntityGuid], undefined, _features.FEATURE_NAMES.genericEvents, agentRef.ee);
21
+ function addPageAction(name, attributes, agentRef, target, timestamp = (0, _now.now)()) {
22
+ (0, _handle.handle)(_constants.prefix + _constants.ADD_PAGE_ACTION, [timestamp, name, attributes, target], undefined, _features.FEATURE_NAMES.genericEvents, agentRef.ee);
23
23
  }
@@ -21,6 +21,6 @@ function setupLogAPI(agent) {
21
21
  function log(message, {
22
22
  customAttributes = {},
23
23
  level = _constants.LOG_LEVELS.INFO
24
- } = {}, agentRef, targetEntityGuid, timestamp = (0, _now.now)()) {
25
- (0, _utils.bufferLog)(agentRef.ee, message, customAttributes, level, targetEntityGuid, timestamp);
24
+ } = {}, agentRef, target, timestamp = (0, _now.now)()) {
25
+ (0, _utils.bufferLog)(agentRef.ee, message, customAttributes, level, target, timestamp);
26
26
  }
@@ -18,8 +18,8 @@ var _sharedHandlers = require("./sharedHandlers");
18
18
  function setupNoticeErrorAPI(agent) {
19
19
  (0, _sharedHandlers.setupAPI)(_constants.NOTICE_ERROR, (err, customAttributes) => noticeError(err, customAttributes, agent), agent);
20
20
  }
21
- function noticeError(err, customAttributes, agentRef, targetEntityGuid, timestamp = (0, _now.now)()) {
21
+ function noticeError(err, customAttributes, agentRef, target, timestamp = (0, _now.now)()) {
22
22
  if (typeof err === 'string') err = new Error(err);
23
- (0, _handle.handle)('err', [err, timestamp, false, customAttributes, agentRef.runtime.isRecording, undefined, targetEntityGuid], undefined, _features.FEATURE_NAMES.jserrors, agentRef.ee);
23
+ (0, _handle.handle)('err', [err, timestamp, false, customAttributes, agentRef.runtime.isRecording, undefined, target], undefined, _features.FEATURE_NAMES.jserrors, agentRef.ee);
24
24
  (0, _handle.handle)('uaErr', [], undefined, _features.FEATURE_NAMES.genericEvents, agentRef.ee);
25
25
  }
@@ -21,15 +21,15 @@ exports.default = void 0;
21
21
  /**
22
22
  * @typedef {Object} RegisterAPIConstructor
23
23
  * @property {Object} opts - The options for the registered entity.
24
- * @property {string} opts.licenseKey - The license key for the registered entity.
25
- * @property {string} opts.applicationID - The application ID for the registered entity.
24
+ * @property {string} opts.id - The unique id for the registered entity. This will be assigned to any synthesized entities.
25
+ * @property {string} opts.name - The readable name for the registered entity. This will be assigned to any synthesized entities.
26
26
  */
27
27
  /**
28
28
  * @typedef {Object} RegisterAPIMetadata
29
29
  * @property {Object} customAttributes - The custom attributes for the registered entity.
30
30
  * @property {Object} target - The options for the registered entity.
31
- * @property {string} target.licenseKey - The license key for the registered entity.
32
- * @property {string} target.applicationID - The application ID for the registered entity.
33
- * @property {string} target.entityGuid - The entity guid returned for the registered entity.
31
+ * @property {string} target.licenseKey - The license key for the registered entity. If none was supplied, it will assume the license key from the main agent.
32
+ * @property {string} target.id - The ID for the registered entity.
33
+ * @property {string} target.name - The name returned for the registered entity.
34
34
  */
35
35
  var _default = exports.default = {};