@newrelic/browser-agent 1.302.0-rc.2 → 1.302.0-rc.4

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 (53) hide show
  1. package/dist/cjs/common/constants/env.cdn.js +1 -1
  2. package/dist/cjs/common/constants/env.npm.js +1 -1
  3. package/dist/cjs/common/wrap/wrap-promise.js +10 -5
  4. package/dist/cjs/features/generic_events/aggregate/index.js +2 -2
  5. package/dist/cjs/features/page_view_event/aggregate/index.js +48 -0
  6. package/dist/cjs/features/session_replay/aggregate/index.js +3 -2
  7. package/dist/cjs/features/session_replay/constants.js +2 -6
  8. package/dist/cjs/features/session_replay/instrument/index.js +3 -2
  9. package/dist/cjs/interfaces/registered-entity.js +10 -0
  10. package/dist/cjs/loaders/api/recordCustomEvent.js +5 -3
  11. package/dist/cjs/loaders/api/register-api-types.js +9 -9
  12. package/dist/cjs/loaders/api/register.js +5 -0
  13. package/dist/cjs/loaders/api-base.js +3 -6
  14. package/dist/esm/common/constants/env.cdn.js +1 -1
  15. package/dist/esm/common/constants/env.npm.js +1 -1
  16. package/dist/esm/common/wrap/wrap-promise.js +10 -5
  17. package/dist/esm/features/generic_events/aggregate/index.js +2 -2
  18. package/dist/esm/features/page_view_event/aggregate/index.js +48 -0
  19. package/dist/esm/features/session_replay/aggregate/index.js +4 -3
  20. package/dist/esm/features/session_replay/constants.js +1 -5
  21. package/dist/esm/features/session_replay/instrument/index.js +4 -3
  22. package/dist/esm/interfaces/registered-entity.js +10 -0
  23. package/dist/esm/loaders/api/recordCustomEvent.js +4 -3
  24. package/dist/esm/loaders/api/register-api-types.js +9 -9
  25. package/dist/esm/loaders/api/register.js +5 -0
  26. package/dist/esm/loaders/api-base.js +3 -6
  27. package/dist/types/common/wrap/wrap-promise.d.ts.map +1 -1
  28. package/dist/types/features/page_view_event/aggregate/index.d.ts.map +1 -1
  29. package/dist/types/features/session_replay/aggregate/index.d.ts.map +1 -1
  30. package/dist/types/features/session_replay/constants.d.ts +1 -5
  31. package/dist/types/features/session_replay/constants.d.ts.map +1 -1
  32. package/dist/types/features/session_replay/instrument/index.d.ts.map +1 -1
  33. package/dist/types/interfaces/registered-entity.d.ts +7 -0
  34. package/dist/types/interfaces/registered-entity.d.ts.map +1 -1
  35. package/dist/types/loaders/api/recordCustomEvent.d.ts +1 -0
  36. package/dist/types/loaders/api/recordCustomEvent.d.ts.map +1 -1
  37. package/dist/types/loaders/api/register-api-types.d.ts +19 -11
  38. package/dist/types/loaders/api/register-api-types.d.ts.map +1 -1
  39. package/dist/types/loaders/api/register.d.ts.map +1 -1
  40. package/dist/types/loaders/api-base.d.ts +6 -13
  41. package/dist/types/loaders/api-base.d.ts.map +1 -1
  42. package/package.json +2 -2
  43. package/src/common/wrap/wrap-promise.js +16 -6
  44. package/src/features/generic_events/aggregate/index.js +2 -2
  45. package/src/features/page_view_event/aggregate/index.js +50 -0
  46. package/src/features/session_replay/aggregate/index.js +4 -3
  47. package/src/features/session_replay/constants.js +1 -5
  48. package/src/features/session_replay/instrument/index.js +4 -3
  49. package/src/interfaces/registered-entity.js +10 -0
  50. package/src/loaders/api/recordCustomEvent.js +5 -3
  51. package/src/loaders/api/register-api-types.js +9 -9
  52. package/src/loaders/api/register.js +2 -0
  53. package/src/loaders/api-base.js +3 -6
@@ -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.2";
20
+ const VERSION = exports.VERSION = "1.302.0-rc.4";
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.2";
20
+ const VERSION = exports.VERSION = "1.302.0-rc.4";
21
21
 
22
22
  /**
23
23
  * Exposes the build type of the agent
@@ -136,12 +136,17 @@ function wrapPromise(sharedEE) {
136
136
  });
137
137
  promiseEE.on('propagate', function (val, overwrite, trigger) {
138
138
  if (!this.getCtx || overwrite) {
139
- this.getCtx = function () {
140
- // eslint-disable-next-line
141
- if (val instanceof Promise) {
142
- var store = promiseEE.context(val);
139
+ const selfStore = this;
140
+ const parentStore = val instanceof Promise ? promiseEE.context(val) : null;
141
+ let cachedCtx;
142
+ this.getCtx = function getCtx() {
143
+ if (cachedCtx) return cachedCtx;
144
+ if (parentStore && parentStore !== selfStore) {
145
+ cachedCtx = typeof parentStore.getCtx === 'function' ? parentStore.getCtx() : parentStore;
146
+ } else {
147
+ cachedCtx = selfStore;
143
148
  }
144
- return store && store.getCtx ? store.getCtx() : this;
149
+ return cachedCtx;
145
150
  };
146
151
  }
147
152
  });
@@ -35,13 +35,13 @@ class Aggregate extends _aggregateBase.AggregateBase {
35
35
  return;
36
36
  }
37
37
  this.#trackSupportabilityMetrics();
38
- (0, _registerHandler.registerHandler)('api-recordCustomEvent', (timestamp, eventType, attributes) => {
38
+ (0, _registerHandler.registerHandler)('api-recordCustomEvent', (timestamp, eventType, attributes, target) => {
39
39
  if (_constants.RESERVED_EVENT_TYPES.includes(eventType)) return (0, _console.warn)(46);
40
40
  this.addEvent({
41
41
  eventType,
42
42
  timestamp: this.toEpoch(timestamp),
43
43
  ...attributes
44
- });
44
+ }, target);
45
45
  }, this.featureName, this.ee);
46
46
  if (agentRef.init.page_action.enabled) {
47
47
  (0, _registerHandler.registerHandler)('api-addPageAction', (timestamp, name, attributes, target) => {
@@ -19,6 +19,9 @@ 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 _harvester = require("../../../common/harvest/harvester");
23
+ var _features = require("../../../loaders/features/features");
24
+ var _submitData = require("../../../common/util/submit-data");
22
25
  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); }
23
26
  /**
24
27
  * Copyright 2020-2025 New Relic, Inc. All rights reserved.
@@ -151,6 +154,51 @@ class Aggregate extends _aggregateBase.AggregateBase {
151
154
  }
152
155
  if (status >= 400 || status === 0) {
153
156
  (0, _console.warn)(18, status);
157
+
158
+ // Get estimated payload size of our backlog
159
+ const textEncoder = new TextEncoder();
160
+ const payloadSize = Object.values(newrelic.ee.backlog).reduce((acc, value) => {
161
+ if (!value) return acc;
162
+ const encoded = textEncoder.encode(value);
163
+ return acc + encoded.byteLength;
164
+ }, 0);
165
+
166
+ // Send SMs about failed RUM request
167
+ const body = {
168
+ sm: [{
169
+ params: {
170
+ name: "Browser/Supportability/BCS/Error/".concat(status)
171
+ },
172
+ stats: {
173
+ c: 1
174
+ }
175
+ }, {
176
+ params: {
177
+ name: 'Browser/Supportability/BCS/Error/Dropped/Bytes'
178
+ },
179
+ stats: {
180
+ c: 1,
181
+ t: payloadSize
182
+ }
183
+ }, {
184
+ params: {
185
+ name: 'Browser/Supportability/BCS/Error/Duration/Ms'
186
+ },
187
+ stats: {
188
+ c: 1,
189
+ t: rumEndTime - this.rumStartTime
190
+ }
191
+ }]
192
+ };
193
+ (0, _harvester.send)(this.agentRef, {
194
+ endpoint: _features.FEATURE_TO_ENDPOINT[_features.FEATURE_NAMES.metrics],
195
+ payload: {
196
+ body
197
+ },
198
+ submitMethod: (0, _submitData.getSubmitMethod)(),
199
+ featureName: _features.FEATURE_NAMES.metrics
200
+ });
201
+
154
202
  // Adding retry logic for the rum call will be a separate change; this.blocked will need to be changed since that prevents another triggerHarvestFor()
155
203
  this.ee.abort();
156
204
  return;
@@ -19,6 +19,7 @@ var _now = require("../../../common/timing/now");
19
19
  var _agentConstants = require("../../../common/constants/agent-constants");
20
20
  var _cleanUrl = require("../../../common/url/clean-url");
21
21
  var _featureGates = require("../../utils/feature-gates");
22
+ var _constants3 = require("../../../loaders/api/constants");
22
23
  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); } /**
23
24
  * Copyright 2020-2025 New Relic, Inc. All rights reserved.
24
25
  * SPDX-License-Identifier: Apache-2.0
@@ -76,10 +77,10 @@ class Aggregate extends _aggregateBase.AggregateBase {
76
77
  if (this.mode !== _constants2.MODE.OFF && data.sessionReplayMode === _constants2.MODE.OFF) this.abort(_constants.ABORT_REASONS.CROSS_TAB);
77
78
  this.mode = data.sessionReplayMode;
78
79
  });
79
- (0, _registerHandler.registerHandler)(_constants.SR_EVENT_EMITTER_TYPES.PAUSE, () => {
80
+ (0, _registerHandler.registerHandler)(_constants3.PAUSE_REPLAY, () => {
80
81
  this.forceStop(this.mode === _constants2.MODE.FULL);
81
82
  }, this.featureName, this.ee);
82
- (0, _registerHandler.registerHandler)(_constants.SR_EVENT_EMITTER_TYPES.ERROR_DURING_REPLAY, e => {
83
+ (0, _registerHandler.registerHandler)(_constants.ERROR_DURING_REPLAY, e => {
83
84
  this.handleError(e);
84
85
  }, this.featureName, this.ee);
85
86
  const {
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.TRIGGERS = exports.SR_EVENT_EMITTER_TYPES = exports.RRWEB_EVENT_TYPES = exports.QUERY_PARAM_PADDING = exports.FEATURE_NAME = exports.CHECKOUT_MS = exports.AVG_COMPRESSION = exports.ABORT_REASONS = void 0;
6
+ exports.TRIGGERS = exports.RRWEB_EVENT_TYPES = exports.QUERY_PARAM_PADDING = exports.FEATURE_NAME = exports.ERROR_DURING_REPLAY = exports.CHECKOUT_MS = exports.AVG_COMPRESSION = exports.ABORT_REASONS = void 0;
7
7
  var _constants = require("../../common/session/constants");
8
8
  var _features = require("../../loaders/features/features");
9
9
  /**
@@ -12,11 +12,7 @@ var _features = require("../../loaders/features/features");
12
12
  */
13
13
 
14
14
  const FEATURE_NAME = exports.FEATURE_NAME = _features.FEATURE_NAMES.sessionReplay;
15
- const SR_EVENT_EMITTER_TYPES = exports.SR_EVENT_EMITTER_TYPES = {
16
- RECORD: 'recordReplay',
17
- PAUSE: 'pauseReplay',
18
- ERROR_DURING_REPLAY: 'errorDuringReplay'
19
- };
15
+ const ERROR_DURING_REPLAY = exports.ERROR_DURING_REPLAY = 'errorDuringReplay';
20
16
  const AVG_COMPRESSION = exports.AVG_COMPRESSION = 0.12;
21
17
  const RRWEB_EVENT_TYPES = exports.RRWEB_EVENT_TYPES = {
22
18
  DomContentLoaded: 0,
@@ -11,6 +11,7 @@ var _utils = require("../shared/utils");
11
11
  var _constants2 = require("../constants");
12
12
  var _recordReplay = require("../../../loaders/api/recordReplay");
13
13
  var _pauseReplay = require("../../../loaders/api/pauseReplay");
14
+ var _constants3 = require("../../../loaders/api/constants");
14
15
  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); } /**
15
16
  * Copyright 2020-2025 New Relic, Inc. All rights reserved.
16
17
  * SPDX-License-Identifier: Apache-2.0
@@ -34,7 +35,7 @@ class Instrument extends _instrumentBase.InstrumentBase {
34
35
  session = JSON.parse(localStorage.getItem("".concat(_constants.PREFIX, "_").concat(_constants.DEFAULT_KEY)));
35
36
  } catch (err) {}
36
37
  if ((0, _utils.hasReplayPrerequisite)(agentRef.init)) {
37
- this.ee.on(_constants2.SR_EVENT_EMITTER_TYPES.RECORD, () => this.#apiStartOrRestartReplay());
38
+ this.ee.on(_constants3.RECORD_REPLAY, () => this.#apiStartOrRestartReplay());
38
39
  }
39
40
  if (this.#canPreloadRecorder(session)) {
40
41
  this.importRecorder().then(recorder => {
@@ -48,7 +49,7 @@ class Instrument extends _instrumentBase.InstrumentBase {
48
49
  if (this.blocked) return;
49
50
  if (this.agentRef.runtime.isRecording) {
50
51
  this.errorNoticed = true;
51
- (0, _handle.handle)(_constants2.SR_EVENT_EMITTER_TYPES.ERROR_DURING_REPLAY, [e], undefined, this.featureName, this.ee);
52
+ (0, _handle.handle)(_constants2.ERROR_DURING_REPLAY, [e], undefined, this.featureName, this.ee);
52
53
  }
53
54
  });
54
55
  }
@@ -54,6 +54,16 @@ class RegisteredEntity {
54
54
  (0, _console.warn)(35, 'addPageAction');
55
55
  }
56
56
 
57
+ /**
58
+ * Records a custom event with a specified eventType and attributes.
59
+ * {@link https://docs.newrelic.com/docs/browser/new-relic-browser/browser-apis/recordCustomEvent/}
60
+ * @param {string} eventType The eventType to store the event as.
61
+ * @param {Object} [attributes] JSON object with one or more key/value pairs. For example: {key:"value"}.
62
+ */
63
+ recordCustomEvent(eventType, attributes) {
64
+ (0, _console.warn)(35, 'recordCustomEvent');
65
+ }
66
+
57
67
  /**
58
68
  * Adds a user-defined attribute name and value to subsequent events on the page for the registered target. Note -- the persist flag does not work with the register API.
59
69
  * {@link https://docs.newrelic.com/docs/browser/new-relic-browser/browser-apis/setcustomattribute/}
@@ -3,6 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
+ exports.recordCustomEvent = recordCustomEvent;
6
7
  exports.setupRecordCustomEventAPI = setupRecordCustomEventAPI;
7
8
  var _handle = require("../../common/event-emitter/handle");
8
9
  var _now = require("../../common/timing/now");
@@ -15,7 +16,8 @@ var _sharedHandlers = require("./sharedHandlers");
15
16
  */
16
17
 
17
18
  function setupRecordCustomEventAPI(agent) {
18
- (0, _sharedHandlers.setupAPI)(_constants.RECORD_CUSTOM_EVENT, function () {
19
- (0, _handle.handle)(_constants.prefix + _constants.RECORD_CUSTOM_EVENT, [(0, _now.now)(), ...arguments], undefined, _features.FEATURE_NAMES.genericEvents, agent.ee);
20
- }, agent);
19
+ (0, _sharedHandlers.setupAPI)(_constants.RECORD_CUSTOM_EVENT, (eventType, attributes) => recordCustomEvent(eventType, attributes, agent), agent);
20
+ }
21
+ function recordCustomEvent(eventType, attributes = {}, agentRef, target, timestamp = (0, _now.now)()) {
22
+ (0, _handle.handle)(_constants.prefix + _constants.RECORD_CUSTOM_EVENT, [timestamp, eventType, attributes, target], undefined, _features.FEATURE_NAMES.genericEvents, agentRef.ee);
21
23
  }
@@ -10,19 +10,19 @@ exports.default = void 0;
10
10
  */
11
11
  /**
12
12
  * @typedef {Object} RegisterAPI
13
- * @property {Function} addPageAction - Add a page action for the registered entity.
14
- * @property {Function} log - Capture a log for the registered entity.
15
- * @property {Function} noticeError - Notice an error for the registered entity.
16
- * @property {Function} setApplicationVersion - Add an application.version attribute to all outgoing data for the registered entity.
17
- * @property {Function} setCustomAttribute - Add a custom attribute to outgoing data for the registered entity.
18
- * @property {Function} setUserId - Add an enduser.id attribute to all outgoing API data for the registered entity.
13
+ * @property {(name: string, attributes?: object) => void} addPageAction - Add a page action for the registered entity.
14
+ * @property {(message: string, options?: { customAttributes?: object, level?: 'ERROR' | 'TRACE' | 'DEBUG' | 'INFO' | 'WARN'}) => void} log - Capture a log for the registered entity.
15
+ * @property {(error: Error | string, customAttributes?: object) => void} noticeError - Notice an error for the registered entity.
16
+ * @property {(eventType: string, attributes?: Object) => void} recordCustomEvent - Record a custom event for the registered entity.
17
+ * @property {(value: string | null) => void} setApplicationVersion - Add an application.version attribute to all outgoing data for the registered entity.
18
+ * @property {(name: string, value: string | number | boolean | null, persist?: boolean) => void} setCustomAttribute - Add a custom attribute to outgoing data for the registered entity.
19
+ * @property {(value: string | null) => void} setUserId - Add an enduser.id attribute to all outgoing API data for the registered entity.
19
20
  * @property {RegisterAPIMetadata} metadata - The metadata object containing the custom attributes and target information for the registered entity.
20
21
  */
21
22
  /**
22
23
  * @typedef {Object} RegisterAPIConstructor
23
- * @property {Object} opts - The options 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.
24
+ * @property {string|number} id - The unique id for the registered entity. This will be assigned to any synthesized entities.
25
+ * @property {string} 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
@@ -17,6 +17,7 @@ var _log = require("./log");
17
17
  var _addPageAction = require("./addPageAction");
18
18
  var _noticeError = require("./noticeError");
19
19
  var _invoke = require("../../common/util/invoke");
20
+ var _recordCustomEvent = require("./recordCustomEvent");
20
21
  /**
21
22
  * Copyright 2020-2025 New Relic, Inc. All rights reserved.
22
23
  * SPDX-License-Identifier: Apache-2.0
@@ -104,6 +105,10 @@ function buildRegisterApi(agentRef, target) {
104
105
  ...attrs,
105
106
  ...attributes
106
107
  }, agentRef], target),
108
+ recordCustomEvent: (eventType, attributes = {}) => report(_recordCustomEvent.recordCustomEvent, [eventType, {
109
+ ...attrs,
110
+ ...attributes
111
+ }, agentRef], target),
107
112
  setApplicationVersion: value => setLocalValue('application.version', value),
108
113
  setCustomAttribute: (key, value) => setLocalValue(key, value),
109
114
  setUserId: value => setLocalValue('enduser.id', value),
@@ -37,11 +37,8 @@ class ApiBase {
37
37
  * It is not recommended for use in production environments and will not receive support for issues.
38
38
  *
39
39
  * Registers an external caller to report through the base agent to a different target than the base agent.
40
- * @param {object} target the target object to report data to
41
- * @param {string} target.licenseKey The licenseKey to report data to
42
- * @param {string} target.applicationID The applicationID to report data to
43
- * @param {string=} target.entityGuid The entityGuid to report data to
44
- * @returns {object} Returns an object that contains the available API methods and configurations to use with the external caller. See loaders/api/api.js for more information.
40
+ * @param {import('./api/register-api-types').RegisterAPIConstructor} target the target object to report data to
41
+ @returns {import('./api/register-api-types').RegisterAPI} Returns an object that contains the available API methods and configurations to use with the external caller. See loaders/api/api.js for more information.
45
42
  */
46
43
  register(target) {
47
44
  return this.#callMethod(_constants.REGISTER, target);
@@ -51,7 +48,7 @@ class ApiBase {
51
48
  * Records a custom event with a specified eventType and attributes.
52
49
  * {@link https://docs.newrelic.com/docs/browser/new-relic-browser/browser-apis/recordCustomEvent/}
53
50
  * @param {string} eventType The eventType to store the event as.
54
- * @param {object} [attributes] JSON object with one or more key/value pairs. For example: {key:"value"}.
51
+ * @param {Object} [attributes] JSON object with one or more key/value pairs. For example: {key:"value"}.
55
52
  */
56
53
  recordCustomEvent(eventType, attributes) {
57
54
  return this.#callMethod(_constants.RECORD_CUSTOM_EVENT, eventType, attributes);
@@ -11,7 +11,7 @@
11
11
  /**
12
12
  * Exposes the version of the agent
13
13
  */
14
- export const VERSION = "1.302.0-rc.2";
14
+ export const VERSION = "1.302.0-rc.4";
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.2";
14
+ export const VERSION = "1.302.0-rc.4";
15
15
 
16
16
  /**
17
17
  * Exposes the build type of the agent
@@ -129,12 +129,17 @@ export function wrapPromise(sharedEE) {
129
129
  });
130
130
  promiseEE.on('propagate', function (val, overwrite, trigger) {
131
131
  if (!this.getCtx || overwrite) {
132
- this.getCtx = function () {
133
- // eslint-disable-next-line
134
- if (val instanceof Promise) {
135
- var store = promiseEE.context(val);
132
+ const selfStore = this;
133
+ const parentStore = val instanceof Promise ? promiseEE.context(val) : null;
134
+ let cachedCtx;
135
+ this.getCtx = function getCtx() {
136
+ if (cachedCtx) return cachedCtx;
137
+ if (parentStore && parentStore !== selfStore) {
138
+ cachedCtx = typeof parentStore.getCtx === 'function' ? parentStore.getCtx() : parentStore;
139
+ } else {
140
+ cachedCtx = selfStore;
136
141
  }
137
- return store && store.getCtx ? store.getCtx() : this;
142
+ return cachedCtx;
138
143
  };
139
144
  }
140
145
  });
@@ -28,13 +28,13 @@ export class Aggregate extends AggregateBase {
28
28
  return;
29
29
  }
30
30
  this.#trackSupportabilityMetrics();
31
- registerHandler('api-recordCustomEvent', (timestamp, eventType, attributes) => {
31
+ registerHandler('api-recordCustomEvent', (timestamp, eventType, attributes, target) => {
32
32
  if (RESERVED_EVENT_TYPES.includes(eventType)) return warn(46);
33
33
  this.addEvent({
34
34
  eventType,
35
35
  timestamp: this.toEpoch(timestamp),
36
36
  ...attributes
37
- });
37
+ }, target);
38
38
  }, this.featureName, this.ee);
39
39
  if (agentRef.init.page_action.enabled) {
40
40
  registerHandler('api-addPageAction', (timestamp, name, attributes, target) => {
@@ -17,6 +17,9 @@ import { timeToFirstByte } from '../../../common/vitals/time-to-first-byte';
17
17
  import { now } from '../../../common/timing/now';
18
18
  import { TimeKeeper } from '../../../common/timing/time-keeper';
19
19
  import { applyFnToProps } from '../../../common/util/traverse';
20
+ import { send } from '../../../common/harvest/harvester';
21
+ import { FEATURE_NAMES, FEATURE_TO_ENDPOINT } from '../../../loaders/features/features';
22
+ import { getSubmitMethod } from '../../../common/util/submit-data';
20
23
  export class Aggregate extends AggregateBase {
21
24
  static featureName = CONSTANTS.FEATURE_NAME;
22
25
  constructor(agentRef) {
@@ -143,6 +146,51 @@ export class Aggregate extends AggregateBase {
143
146
  }
144
147
  if (status >= 400 || status === 0) {
145
148
  warn(18, status);
149
+
150
+ // Get estimated payload size of our backlog
151
+ const textEncoder = new TextEncoder();
152
+ const payloadSize = Object.values(newrelic.ee.backlog).reduce((acc, value) => {
153
+ if (!value) return acc;
154
+ const encoded = textEncoder.encode(value);
155
+ return acc + encoded.byteLength;
156
+ }, 0);
157
+
158
+ // Send SMs about failed RUM request
159
+ const body = {
160
+ sm: [{
161
+ params: {
162
+ name: "Browser/Supportability/BCS/Error/".concat(status)
163
+ },
164
+ stats: {
165
+ c: 1
166
+ }
167
+ }, {
168
+ params: {
169
+ name: 'Browser/Supportability/BCS/Error/Dropped/Bytes'
170
+ },
171
+ stats: {
172
+ c: 1,
173
+ t: payloadSize
174
+ }
175
+ }, {
176
+ params: {
177
+ name: 'Browser/Supportability/BCS/Error/Duration/Ms'
178
+ },
179
+ stats: {
180
+ c: 1,
181
+ t: rumEndTime - this.rumStartTime
182
+ }
183
+ }]
184
+ };
185
+ send(this.agentRef, {
186
+ endpoint: FEATURE_TO_ENDPOINT[FEATURE_NAMES.metrics],
187
+ payload: {
188
+ body
189
+ },
190
+ submitMethod: getSubmitMethod(),
191
+ featureName: FEATURE_NAMES.metrics
192
+ });
193
+
146
194
  // Adding retry logic for the rum call will be a separate change; this.blocked will need to be changed since that prevents another triggerHarvestFor()
147
195
  this.ee.abort();
148
196
  return;
@@ -7,7 +7,7 @@
7
7
  */
8
8
 
9
9
  import { registerHandler } from '../../../common/event-emitter/register-handler';
10
- import { ABORT_REASONS, FEATURE_NAME, QUERY_PARAM_PADDING, RRWEB_EVENT_TYPES, SR_EVENT_EMITTER_TYPES, TRIGGERS } from '../constants';
10
+ import { ABORT_REASONS, ERROR_DURING_REPLAY, FEATURE_NAME, QUERY_PARAM_PADDING, RRWEB_EVENT_TYPES, TRIGGERS } from '../constants';
11
11
  import { AggregateBase } from '../../utils/aggregate-base';
12
12
  import { sharedChannel } from '../../../common/constants/shared-channel';
13
13
  import { obj as encodeObj } from '../../../common/url/encode';
@@ -21,6 +21,7 @@ import { now } from '../../../common/timing/now';
21
21
  import { MAX_PAYLOAD_SIZE } from '../../../common/constants/agent-constants';
22
22
  import { cleanURL } from '../../../common/url/clean-url';
23
23
  import { canEnableSessionTracking } from '../../utils/feature-gates';
24
+ import { PAUSE_REPLAY } from '../../../loaders/api/constants';
24
25
  export class Aggregate extends AggregateBase {
25
26
  static featureName = FEATURE_NAME;
26
27
  mode = MODE.OFF;
@@ -72,10 +73,10 @@ export class Aggregate extends AggregateBase {
72
73
  if (this.mode !== MODE.OFF && data.sessionReplayMode === MODE.OFF) this.abort(ABORT_REASONS.CROSS_TAB);
73
74
  this.mode = data.sessionReplayMode;
74
75
  });
75
- registerHandler(SR_EVENT_EMITTER_TYPES.PAUSE, () => {
76
+ registerHandler(PAUSE_REPLAY, () => {
76
77
  this.forceStop(this.mode === MODE.FULL);
77
78
  }, this.featureName, this.ee);
78
- registerHandler(SR_EVENT_EMITTER_TYPES.ERROR_DURING_REPLAY, e => {
79
+ registerHandler(ERROR_DURING_REPLAY, e => {
79
80
  this.handleError(e);
80
81
  }, this.featureName, this.ee);
81
82
  const {
@@ -5,11 +5,7 @@
5
5
  import { MODE } from '../../common/session/constants';
6
6
  import { FEATURE_NAMES } from '../../loaders/features/features';
7
7
  export const FEATURE_NAME = FEATURE_NAMES.sessionReplay;
8
- export const SR_EVENT_EMITTER_TYPES = {
9
- RECORD: 'recordReplay',
10
- PAUSE: 'pauseReplay',
11
- ERROR_DURING_REPLAY: 'errorDuringReplay'
12
- };
8
+ export const ERROR_DURING_REPLAY = 'errorDuringReplay';
13
9
  export const AVG_COMPRESSION = 0.12;
14
10
  export const RRWEB_EVENT_TYPES = {
15
11
  DomContentLoaded: 0,
@@ -10,9 +10,10 @@ import { handle } from '../../../common/event-emitter/handle';
10
10
  import { DEFAULT_KEY, MODE, PREFIX } from '../../../common/session/constants';
11
11
  import { InstrumentBase } from '../../utils/instrument-base';
12
12
  import { hasReplayPrerequisite, isPreloadAllowed } from '../shared/utils';
13
- import { FEATURE_NAME, SR_EVENT_EMITTER_TYPES, TRIGGERS } from '../constants';
13
+ import { ERROR_DURING_REPLAY, FEATURE_NAME, TRIGGERS } from '../constants';
14
14
  import { setupRecordReplayAPI } from '../../../loaders/api/recordReplay';
15
15
  import { setupPauseReplayAPI } from '../../../loaders/api/pauseReplay';
16
+ import { RECORD_REPLAY } from '../../../loaders/api/constants';
16
17
  export class Instrument extends InstrumentBase {
17
18
  static featureName = FEATURE_NAME;
18
19
  /** @type {Promise|undefined} A promise that resolves when the recorder module is imported and added to the class. Undefined if the recorder has never been staged to import with `importRecorder`. */
@@ -30,7 +31,7 @@ export class Instrument extends InstrumentBase {
30
31
  session = JSON.parse(localStorage.getItem("".concat(PREFIX, "_").concat(DEFAULT_KEY)));
31
32
  } catch (err) {}
32
33
  if (hasReplayPrerequisite(agentRef.init)) {
33
- this.ee.on(SR_EVENT_EMITTER_TYPES.RECORD, () => this.#apiStartOrRestartReplay());
34
+ this.ee.on(RECORD_REPLAY, () => this.#apiStartOrRestartReplay());
34
35
  }
35
36
  if (this.#canPreloadRecorder(session)) {
36
37
  this.importRecorder().then(recorder => {
@@ -44,7 +45,7 @@ export class Instrument extends InstrumentBase {
44
45
  if (this.blocked) return;
45
46
  if (this.agentRef.runtime.isRecording) {
46
47
  this.errorNoticed = true;
47
- handle(SR_EVENT_EMITTER_TYPES.ERROR_DURING_REPLAY, [e], undefined, this.featureName, this.ee);
48
+ handle(ERROR_DURING_REPLAY, [e], undefined, this.featureName, this.ee);
48
49
  }
49
50
  });
50
51
  }
@@ -48,6 +48,16 @@ export class RegisteredEntity {
48
48
  warn(35, 'addPageAction');
49
49
  }
50
50
 
51
+ /**
52
+ * Records a custom event with a specified eventType and attributes.
53
+ * {@link https://docs.newrelic.com/docs/browser/new-relic-browser/browser-apis/recordCustomEvent/}
54
+ * @param {string} eventType The eventType to store the event as.
55
+ * @param {Object} [attributes] JSON object with one or more key/value pairs. For example: {key:"value"}.
56
+ */
57
+ recordCustomEvent(eventType, attributes) {
58
+ warn(35, 'recordCustomEvent');
59
+ }
60
+
51
61
  /**
52
62
  * Adds a user-defined attribute name and value to subsequent events on the page for the registered target. Note -- the persist flag does not work with the register API.
53
63
  * {@link https://docs.newrelic.com/docs/browser/new-relic-browser/browser-apis/setcustomattribute/}
@@ -8,7 +8,8 @@ import { FEATURE_NAMES } from '../features/features';
8
8
  import { prefix, RECORD_CUSTOM_EVENT } from './constants';
9
9
  import { setupAPI } from './sharedHandlers';
10
10
  export function setupRecordCustomEventAPI(agent) {
11
- setupAPI(RECORD_CUSTOM_EVENT, function () {
12
- handle(prefix + RECORD_CUSTOM_EVENT, [now(), ...arguments], undefined, FEATURE_NAMES.genericEvents, agent.ee);
13
- }, agent);
11
+ setupAPI(RECORD_CUSTOM_EVENT, (eventType, attributes) => recordCustomEvent(eventType, attributes, agent), agent);
12
+ }
13
+ export function recordCustomEvent(eventType, attributes = {}, agentRef, target, timestamp = now()) {
14
+ handle(prefix + RECORD_CUSTOM_EVENT, [timestamp, eventType, attributes, target], undefined, FEATURE_NAMES.genericEvents, agentRef.ee);
14
15
  }
@@ -5,20 +5,20 @@
5
5
 
6
6
  /**
7
7
  * @typedef {Object} RegisterAPI
8
- * @property {Function} addPageAction - Add a page action for the registered entity.
9
- * @property {Function} log - Capture a log for the registered entity.
10
- * @property {Function} noticeError - Notice an error for the registered entity.
11
- * @property {Function} setApplicationVersion - Add an application.version attribute to all outgoing data for the registered entity.
12
- * @property {Function} setCustomAttribute - Add a custom attribute to outgoing data for the registered entity.
13
- * @property {Function} setUserId - Add an enduser.id attribute to all outgoing API data for the registered entity.
8
+ * @property {(name: string, attributes?: object) => void} addPageAction - Add a page action for the registered entity.
9
+ * @property {(message: string, options?: { customAttributes?: object, level?: 'ERROR' | 'TRACE' | 'DEBUG' | 'INFO' | 'WARN'}) => void} log - Capture a log for the registered entity.
10
+ * @property {(error: Error | string, customAttributes?: object) => void} noticeError - Notice an error for the registered entity.
11
+ * @property {(eventType: string, attributes?: Object) => void} recordCustomEvent - Record a custom event for the registered entity.
12
+ * @property {(value: string | null) => void} setApplicationVersion - Add an application.version attribute to all outgoing data for the registered entity.
13
+ * @property {(name: string, value: string | number | boolean | null, persist?: boolean) => void} setCustomAttribute - Add a custom attribute to outgoing data for the registered entity.
14
+ * @property {(value: string | null) => void} setUserId - Add an enduser.id attribute to all outgoing API data for the registered entity.
14
15
  * @property {RegisterAPIMetadata} metadata - The metadata object containing the custom attributes and target information for the registered entity.
15
16
  */
16
17
 
17
18
  /**
18
19
  * @typedef {Object} RegisterAPIConstructor
19
- * @property {Object} opts - The options for the registered entity.
20
- * @property {string} opts.id - The unique id for the registered entity. This will be assigned to any synthesized entities.
21
- * @property {string} opts.name - The readable name for the registered entity. This will be assigned to any synthesized entities.
20
+ * @property {string|number} id - The unique id for the registered entity. This will be assigned to any synthesized entities.
21
+ * @property {string} name - The readable name for the registered entity. This will be assigned to any synthesized entities.
22
22
  */
23
23
 
24
24
  /**
@@ -14,6 +14,7 @@ import { log } from './log';
14
14
  import { addPageAction } from './addPageAction';
15
15
  import { noticeError } from './noticeError';
16
16
  import { single } from '../../common/util/invoke';
17
+ import { recordCustomEvent } from './recordCustomEvent';
17
18
 
18
19
  /**
19
20
  * @typedef {import('./register-api-types').RegisterAPI} RegisterAPI
@@ -97,6 +98,10 @@ export function buildRegisterApi(agentRef, target) {
97
98
  ...attrs,
98
99
  ...attributes
99
100
  }, agentRef], target),
101
+ recordCustomEvent: (eventType, attributes = {}) => report(recordCustomEvent, [eventType, {
102
+ ...attrs,
103
+ ...attributes
104
+ }, agentRef], target),
100
105
  setApplicationVersion: value => setLocalValue('application.version', value),
101
106
  setCustomAttribute: (key, value) => setLocalValue(key, value),
102
107
  setUserId: value => setLocalValue('enduser.id', value),
@@ -31,11 +31,8 @@ export class ApiBase {
31
31
  * It is not recommended for use in production environments and will not receive support for issues.
32
32
  *
33
33
  * Registers an external caller to report through the base agent to a different target than the base agent.
34
- * @param {object} target the target object to report data to
35
- * @param {string} target.licenseKey The licenseKey to report data to
36
- * @param {string} target.applicationID The applicationID to report data to
37
- * @param {string=} target.entityGuid The entityGuid to report data to
38
- * @returns {object} Returns an object that contains the available API methods and configurations to use with the external caller. See loaders/api/api.js for more information.
34
+ * @param {import('./api/register-api-types').RegisterAPIConstructor} target the target object to report data to
35
+ @returns {import('./api/register-api-types').RegisterAPI} Returns an object that contains the available API methods and configurations to use with the external caller. See loaders/api/api.js for more information.
39
36
  */
40
37
  register(target) {
41
38
  return this.#callMethod(REGISTER, target);
@@ -45,7 +42,7 @@ export class ApiBase {
45
42
  * Records a custom event with a specified eventType and attributes.
46
43
  * {@link https://docs.newrelic.com/docs/browser/new-relic-browser/browser-apis/recordCustomEvent/}
47
44
  * @param {string} eventType The eventType to store the event as.
48
- * @param {object} [attributes] JSON object with one or more key/value pairs. For example: {key:"value"}.
45
+ * @param {Object} [attributes] JSON object with one or more key/value pairs. For example: {key:"value"}.
49
46
  */
50
47
  recordCustomEvent(eventType, attributes) {
51
48
  return this.#callMethod(RECORD_CUSTOM_EVENT, eventType, attributes);
@@ -1 +1 @@
1
- {"version":3,"file":"wrap-promise.d.ts","sourceRoot":"","sources":["../../../../src/common/wrap/wrap-promise.js"],"names":[],"mappings":"AAgBA;;;;;;GAMG;AACH,sCAHW,MAAM,GACJ,MAAM,CAqIlB;AAED;;;;;;GAMG;AACH,mCAJW,MAAM,GAEJ,MAAM,CAIlB"}
1
+ {"version":3,"file":"wrap-promise.d.ts","sourceRoot":"","sources":["../../../../src/common/wrap/wrap-promise.js"],"names":[],"mappings":"AAgBA;;;;;;GAMG;AACH,sCAHW,MAAM,GACJ,MAAM,CA+IlB;AAED;;;;;;GAMG;AACH,mCAJW,MAAM,GAEJ,MAAM,CAIlB"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/features/page_view_event/aggregate/index.js"],"names":[],"mappings":"AAoBA;IACE,2BAA2C;IAC3C,2BA0BC;IAvBC,wBAAwB;IACxB,8BAA8B;IAC9B,8BAA8B;IAuBhC;;;;;OAKG;IACH,2BAHW,GAAC,WACD,GAAC,QAsEX;IAVC,iCAAyB;IAY3B;;;;aAyCC;CACF;8BA5J6B,4BAA4B"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/features/page_view_event/aggregate/index.js"],"names":[],"mappings":"AAuBA;IACE,2BAA2C;IAC3C,2BA0BC;IAvBC,wBAAwB;IACxB,8BAA8B;IAC9B,8BAA8B;IAuBhC;;;;;OAKG;IACH,2BAHW,GAAC,WACD,GAAC,QAsEX;IAVC,iCAAyB;IAY3B;;;;aAwFC;CACF;8BA9M6B,4BAA4B"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/features/session_replay/aggregate/index.js"],"names":[],"mappings":"AAwBA;IACE,2BAAiC;IAIjC,sCAyFC;IA5FD,aAAe;IAKb,iFAAiF;IACjF,qBAAwB;IAGxB,2CAA2C;IAC3C,sDAAwB;IACxB,6CAA6C;IAC7C,gDAAmB;IACnB,+DAA+D;IAC/D,wBAA0B;IAE1B,0BAA0B;IAC1B,kBAAqB;IACrB,6CAA6C;IAC7C,gBAA2B;IAE3B,qBAA2B;IAE3B,cAA8C;IAI9C,kCAAqG;IAmEvG,0BAEC;IAED,0BAMC;IAED,qBAUC;IAED;;;;;;OAMG;IACH,4BALW,OAAO,iBACP,OAAO;;;;;;QAEL,IAAI,CA8ChB;IAED,2BAUC;IAED;;;;;;;;;;kBAwCC;IAED;;;;OAIG;IACH,6BAHW,MAAM,EAAE,GACN;QAAE,UAAU,EAAE,MAAM,GAAC,SAAS,CAAC;QAAC,SAAS,EAAE,MAAM,GAAC,SAAS,CAAA;KAAE,CAUzE;IAED;;;;;;;;;;MAsEC;IAED,sCAKC;IAED;;;;OAIG;IACH,mCAKC;IAED,yDAAyD;IACzD,+CASC;IAED,yCAIC;CACF;8BA5W6B,4BAA4B"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/features/session_replay/aggregate/index.js"],"names":[],"mappings":"AAyBA;IACE,2BAAiC;IAIjC,sCAyFC;IA5FD,aAAe;IAKb,iFAAiF;IACjF,qBAAwB;IAGxB,2CAA2C;IAC3C,sDAAwB;IACxB,6CAA6C;IAC7C,gDAAmB;IACnB,+DAA+D;IAC/D,wBAA0B;IAE1B,0BAA0B;IAC1B,kBAAqB;IACrB,6CAA6C;IAC7C,gBAA2B;IAE3B,qBAA2B;IAE3B,cAA8C;IAI9C,kCAAqG;IAmEvG,0BAEC;IAED,0BAMC;IAED,qBAUC;IAED;;;;;;OAMG;IACH,4BALW,OAAO,iBACP,OAAO;;;;;;QAEL,IAAI,CA8ChB;IAED,2BAUC;IAED;;;;;;;;;;kBAwCC;IAED;;;;OAIG;IACH,6BAHW,MAAM,EAAE,GACN;QAAE,UAAU,EAAE,MAAM,GAAC,SAAS,CAAC;QAAC,SAAS,EAAE,MAAM,GAAC,SAAS,CAAA;KAAE,CAUzE;IAED;;;;;;;;;;MAsEC;IAED,sCAKC;IAED;;;;OAIG;IACH,mCAKC;IAED,yDAAyD;IACzD,+CASC;IAED,yCAIC;CACF;8BA7W6B,4BAA4B"}
@@ -1,9 +1,5 @@
1
1
  export const FEATURE_NAME: string;
2
- export namespace SR_EVENT_EMITTER_TYPES {
3
- let RECORD: string;
4
- let PAUSE: string;
5
- let ERROR_DURING_REPLAY: string;
6
- }
2
+ export const ERROR_DURING_REPLAY: "errorDuringReplay";
7
3
  export const AVG_COMPRESSION: 0.12;
8
4
  export namespace RRWEB_EVENT_TYPES {
9
5
  let DomContentLoaded: number;
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../../src/features/session_replay/constants.js"],"names":[],"mappings":"AAOA,kCAAuD;;;;;;AAQvD,8BAA+B,IAAI,CAAA;;;;;;;;;AASnC,2GAA2G;AAC3G;IAA6B,CAAC,IAAI,CAAC,KAAK,CAAC,SAAO;IAAE,CAAC,IAAI,CAAC,IAAI,CAAC,SAAQ;IAAE,CAAC,IAAI,CAAC,GAAG,CAAC,SAAG;EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BtF,0CAA0C;AAC1C,kCAAmC,IAAI,CAAA;;;;;;;;qBAjDlB,gCAAgC"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../../src/features/session_replay/constants.js"],"names":[],"mappings":"AAOA,kCAAuD;AAEvD,kCAAmC,mBAAmB,CAAA;AAEtD,8BAA+B,IAAI,CAAA;;;;;;;;;AASnC,2GAA2G;AAC3G;IAA6B,CAAC,IAAI,CAAC,KAAK,CAAC,SAAO;IAAE,CAAC,IAAI,CAAC,IAAI,CAAC,SAAQ;IAAE,CAAC,IAAI,CAAC,GAAG,CAAC,SAAG;EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BtF,0CAA0C;AAC1C,kCAAmC,IAAI,CAAA;;;;;;;;qBA7ClB,gCAAgC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/features/session_replay/instrument/index.js"],"names":[],"mappings":"AAgBA;IACE,2BAAiC;IAMjC,2BAgCC;IAnCD,+CAA+C;IAC/C,cAAQ;IA8BF,sBAAwB;IAmB9B;;;OAGG;IACH,+BAkBC;;CAgBF;AAED,8CAAuC;+BApGR,6BAA6B"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/features/session_replay/instrument/index.js"],"names":[],"mappings":"AAiBA;IACE,2BAAiC;IAMjC,2BAgCC;IAnCD,+CAA+C;IAC/C,cAAQ;IA8BF,sBAAwB;IAmB9B;;;OAGG;IACH,+BAkBC;;CAgBF;AAED,8CAAuC;+BArGR,6BAA6B"}
@@ -25,6 +25,13 @@ export class RegisteredEntity {
25
25
  * @param {object} [attributes] JSON object with one or more key/value pairs. For example: {key:"value"}. The key is reported as its own PageAction attribute with the specified values.
26
26
  */
27
27
  addPageAction(name: string, attributes?: object): void;
28
+ /**
29
+ * Records a custom event with a specified eventType and attributes.
30
+ * {@link https://docs.newrelic.com/docs/browser/new-relic-browser/browser-apis/recordCustomEvent/}
31
+ * @param {string} eventType The eventType to store the event as.
32
+ * @param {Object} [attributes] JSON object with one or more key/value pairs. For example: {key:"value"}.
33
+ */
34
+ recordCustomEvent(eventType: string, attributes?: Object): void;
28
35
  /**
29
36
  * Adds a user-defined attribute name and value to subsequent events on the page for the registered target. Note -- the persist flag does not work with the register API.
30
37
  * {@link https://docs.newrelic.com/docs/browser/new-relic-browser/browser-apis/setcustomattribute/}
@@ -1 +1 @@
1
- {"version":3,"file":"registered-entity.d.ts","sourceRoot":"","sources":["../../../src/interfaces/registered-entity.js"],"names":[],"mappings":"AAMA;;;;GAIG;AAEH;;;;;;GAMG;AACH;IAOE;;;OAGG;IACH,kBAFW,sBAAsB,EAShC;IAjBD,kCAAkC;IAClC,UADW,mBAAmB,CAI7B;IAeD;;;;;OAKG;IACH,oBAHW,MAAM,eACN,MAAM,QAKhB;IAED;;;;;;OAMG;IACH,yBAJW,MAAM,SACN,MAAM,GAAC,MAAM,GAAC,OAAO,GAAC,IAAI,YAC1B,OAAO,QAKjB;IAED;;;;;OAKG;IACH,mBAHW,KAAK,GAAC,MAAM,qBACZ,MAAM,QAKhB;IAED;;;;OAIG;IACH,iBAFW,MAAM,GAAC,IAAI,QAKrB;IAED;;;;;;;OAOG;IACH,6BAJW,MAAM,GAAC,IAAI,QAOrB;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,QAKpF;CACF;0BAnGY,OAAO,mCAAmC,EAAE,WAAW;kCACvD,OAAO,mCAAmC,EAAE,mBAAmB;qCAC/D,OAAO,mCAAmC,EAAE,sBAAsB"}
1
+ {"version":3,"file":"registered-entity.d.ts","sourceRoot":"","sources":["../../../src/interfaces/registered-entity.js"],"names":[],"mappings":"AAMA;;;;GAIG;AAEH;;;;;;GAMG;AACH;IAOE;;;OAGG;IACH,kBAFW,sBAAsB,EAShC;IAjBD,kCAAkC;IAClC,UADW,mBAAmB,CAI7B;IAeD;;;;;OAKG;IACH,oBAHW,MAAM,eACN,MAAM,QAKhB;IAED;;;;;SAKK;IACL,6BAHa,MAAM,eACN,MAAM,QAIlB;IAED;;;;;;OAMG;IACH,yBAJW,MAAM,SACN,MAAM,GAAC,MAAM,GAAC,OAAO,GAAC,IAAI,YAC1B,OAAO,QAKjB;IAED;;;;;OAKG;IACH,mBAHW,KAAK,GAAC,MAAM,qBACZ,MAAM,QAKhB;IAED;;;;OAIG;IACH,iBAFW,MAAM,GAAC,IAAI,QAKrB;IAED;;;;;;;OAOG;IACH,6BAJW,MAAM,GAAC,IAAI,QAOrB;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,QAKpF;CACF;0BA7GY,OAAO,mCAAmC,EAAE,WAAW;kCACvD,OAAO,mCAAmC,EAAE,mBAAmB;qCAC/D,OAAO,mCAAmC,EAAE,sBAAsB"}
@@ -1,2 +1,3 @@
1
1
  export function setupRecordCustomEventAPI(agent: any): void;
2
+ export function recordCustomEvent(eventType: any, attributes: {} | undefined, agentRef: any, target: any, timestamp?: number): void;
2
3
  //# sourceMappingURL=recordCustomEvent.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"recordCustomEvent.d.ts","sourceRoot":"","sources":["../../../../src/loaders/api/recordCustomEvent.js"],"names":[],"mappings":"AAUA,4DAIC"}
1
+ {"version":3,"file":"recordCustomEvent.d.ts","sourceRoot":"","sources":["../../../../src/loaders/api/recordCustomEvent.js"],"names":[],"mappings":"AAUA,4DAEC;AAED,oIAEC"}
@@ -4,27 +4,34 @@ export type RegisterAPI = {
4
4
  /**
5
5
  * - Add a page action for the registered entity.
6
6
  */
7
- addPageAction: Function;
7
+ addPageAction: (name: string, attributes?: object) => void;
8
8
  /**
9
9
  * - Capture a log for the registered entity.
10
10
  */
11
- log: Function;
11
+ log: (message: string, options?: {
12
+ customAttributes?: object;
13
+ level?: "ERROR" | "TRACE" | "DEBUG" | "INFO" | "WARN";
14
+ }) => void;
12
15
  /**
13
16
  * - Notice an error for the registered entity.
14
17
  */
15
- noticeError: Function;
18
+ noticeError: (error: Error | string, customAttributes?: object) => void;
19
+ /**
20
+ * - Record a custom event for the registered entity.
21
+ */
22
+ recordCustomEvent: (eventType: string, attributes?: Object) => void;
16
23
  /**
17
24
  * - Add an application.version attribute to all outgoing data for the registered entity.
18
25
  */
19
- setApplicationVersion: Function;
26
+ setApplicationVersion: (value: string | null) => void;
20
27
  /**
21
28
  * - Add a custom attribute to outgoing data for the registered entity.
22
29
  */
23
- setCustomAttribute: Function;
30
+ setCustomAttribute: (name: string, value: string | number | boolean | null, persist?: boolean) => void;
24
31
  /**
25
32
  * - Add an enduser.id attribute to all outgoing API data for the registered entity.
26
33
  */
27
- setUserId: Function;
34
+ setUserId: (value: string | null) => void;
28
35
  /**
29
36
  * - The metadata object containing the custom attributes and target information for the registered entity.
30
37
  */
@@ -32,12 +39,13 @@ export type RegisterAPI = {
32
39
  };
33
40
  export type RegisterAPIConstructor = {
34
41
  /**
35
- * - The options for the registered entity.
42
+ * - The unique id for the registered entity. This will be assigned to any synthesized entities.
36
43
  */
37
- opts: {
38
- id: string;
39
- name: string;
40
- };
44
+ id: string | number;
45
+ /**
46
+ * - The readable name for the registered entity. This will be assigned to any synthesized entities.
47
+ */
48
+ name: string;
41
49
  };
42
50
  export type RegisterAPIMetadata = {
43
51
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"register-api-types.d.ts","sourceRoot":"","sources":["../../../../src/loaders/api/register-api-types.js"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAac,mBAAmB;;;;;;UAM9B;QAAwB,EAAE,EAAf,MAAM;QACO,IAAI,EAAjB,MAAM;KACnB;;;;;;sBAIa,MAAM;;;;YAEjB;QAA0B,UAAU,EAAzB,MAAM;QACS,EAAE,EAAjB,MAAM;QACS,IAAI,EAAnB,MAAM;KACnB"}
1
+ {"version":3,"file":"register-api-types.d.ts","sourceRoot":"","sources":["../../../../src/loaders/api/register-api-types.js"],"names":[],"mappings":";;;;;;mBAOc,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,KAAK,IAAI;;;;SAC3C,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,CAAA;KAAC,KAAK,IAAI;;;;iBACxH,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,EAAE,gBAAgB,CAAC,EAAE,MAAM,KAAK,IAAI;;;;uBAC1D,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,KAAK,IAAI;;;;2BAChD,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI;;;;wBAC9B,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,EAAE,OAAO,CAAC,EAAE,OAAO,KAAK,IAAI;;;;eAClF,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI;;;;cAC9B,mBAAmB;;;;;;QAKnB,MAAM,GAAC,MAAM;;;;UACb,MAAM;;;;;;sBAKN,MAAM;;;;YAEjB;QAA0B,UAAU,EAAzB,MAAM;QACS,EAAE,EAAjB,MAAM;QACS,IAAI,EAAnB,MAAM;KACnB"}
@@ -1 +1 @@
1
- {"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../../../../src/loaders/api/register.js"],"names":[],"mappings":"AAiBA;;GAEG;AAEH;;;;GAIG;AACH,mDAIC;AAED;;;;;;;;;;GAUG;AACH,2CARW,MAAM,UAGd;IAAwB,UAAU;IACX,EAAE,EAAjB,MAAM;IACS,IAAI,EAAnB,MAAM;CACd,GAAU,WAAW,CAmGvB;0BA1HY,OAAO,sBAAsB,EAAE,WAAW"}
1
+ {"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../../../../src/loaders/api/register.js"],"names":[],"mappings":"AAkBA;;GAEG;AAEH;;;;GAIG;AACH,mDAIC;AAED;;;;;;;;;;GAUG;AACH,2CARW,MAAM,UAGd;IAAwB,UAAU;IACX,EAAE,EAAjB,MAAM;IACS,IAAI,EAAnB,MAAM;CACd,GAAU,WAAW,CAoGvB;0BA3HY,OAAO,sBAAsB,EAAE,WAAW"}
@@ -15,24 +15,17 @@ export class ApiBase {
15
15
  * It is not recommended for use in production environments and will not receive support for issues.
16
16
  *
17
17
  * Registers an external caller to report through the base agent to a different target than the base agent.
18
- * @param {object} target the target object to report data to
19
- * @param {string} target.licenseKey The licenseKey to report data to
20
- * @param {string} target.applicationID The applicationID to report data to
21
- * @param {string=} target.entityGuid The entityGuid to report data to
22
- * @returns {object} Returns an object that contains the available API methods and configurations to use with the external caller. See loaders/api/api.js for more information.
23
- */
24
- register(target: {
25
- licenseKey: string;
26
- applicationID: string;
27
- entityGuid?: string | undefined;
28
- }): object;
18
+ * @param {import('./api/register-api-types').RegisterAPIConstructor} target the target object to report data to
19
+ @returns {import('./api/register-api-types').RegisterAPI} Returns an object that contains the available API methods and configurations to use with the external caller. See loaders/api/api.js for more information.
20
+ */
21
+ register(target: import("./api/register-api-types").RegisterAPIConstructor): import("./api/register-api-types").RegisterAPI;
29
22
  /**
30
23
  * Records a custom event with a specified eventType and attributes.
31
24
  * {@link https://docs.newrelic.com/docs/browser/new-relic-browser/browser-apis/recordCustomEvent/}
32
25
  * @param {string} eventType The eventType to store the event as.
33
- * @param {object} [attributes] JSON object with one or more key/value pairs. For example: {key:"value"}.
26
+ * @param {Object} [attributes] JSON object with one or more key/value pairs. For example: {key:"value"}.
34
27
  */
35
- recordCustomEvent(eventType: string, attributes?: object): any;
28
+ recordCustomEvent(eventType: string, attributes?: Object): any;
36
29
  /**
37
30
  * Groups page views to help URL structure or to capture the URL's routing information.
38
31
  * {@link https://docs.newrelic.com/docs/browser/new-relic-browser/browser-apis/setpageviewname/}
@@ -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;;;;;;;;;;;OAWG;IACH,iBALG;QAAuB,UAAU,EAAzB,MAAM;QACS,aAAa,EAA5B,MAAM;QACU,UAAU,GAA1B,MAAM,YAAC;KACf,GAAU,MAAM,CAIlB;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;kCA9NY,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;;CACF;kCA3NY,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.2",
3
+ "version": "1.302.0-rc.4",
4
4
  "private": false,
5
5
  "author": "New Relic Browser Agent Team <browser-agent@newrelic.com>",
6
6
  "description": "New Relic Browser Agent",
@@ -170,7 +170,7 @@
170
170
  "runtime": {
171
171
  "name": "node",
172
172
  "onFail": "error",
173
- "version": "22.11.0"
173
+ "version": ">=22.11.0"
174
174
  },
175
175
  "packageManager": {
176
176
  "name": "npm",
@@ -140,13 +140,23 @@ export function wrapPromise (sharedEE) {
140
140
 
141
141
  promiseEE.on('propagate', function (val, overwrite, trigger) {
142
142
  if (!this.getCtx || overwrite) {
143
- this.getCtx = function () {
144
- // eslint-disable-next-line
145
- if (val instanceof Promise) {
146
- var store = promiseEE.context(val)
143
+ const selfStore = this
144
+ const parentStore =
145
+ val instanceof Promise ? promiseEE.context(val) : null
146
+ let cachedCtx
147
+
148
+ this.getCtx = function getCtx () {
149
+ if (cachedCtx) return cachedCtx
150
+
151
+ if (parentStore && parentStore !== selfStore) {
152
+ cachedCtx =
153
+ typeof parentStore.getCtx === 'function'
154
+ ? parentStore.getCtx()
155
+ : parentStore
156
+ } else {
157
+ cachedCtx = selfStore
147
158
  }
148
-
149
- return store && store.getCtx ? store.getCtx() : this
159
+ return cachedCtx
150
160
  }
151
161
  }
152
162
  })
@@ -33,13 +33,13 @@ export class Aggregate extends AggregateBase {
33
33
 
34
34
  this.#trackSupportabilityMetrics()
35
35
 
36
- registerHandler('api-recordCustomEvent', (timestamp, eventType, attributes) => {
36
+ registerHandler('api-recordCustomEvent', (timestamp, eventType, attributes, target) => {
37
37
  if (RESERVED_EVENT_TYPES.includes(eventType)) return warn(46)
38
38
  this.addEvent({
39
39
  eventType,
40
40
  timestamp: this.toEpoch(timestamp),
41
41
  ...attributes
42
- })
42
+ }, target)
43
43
  }, this.featureName, this.ee)
44
44
 
45
45
  if (agentRef.init.page_action.enabled) {
@@ -17,6 +17,9 @@ import { timeToFirstByte } from '../../../common/vitals/time-to-first-byte'
17
17
  import { now } from '../../../common/timing/now'
18
18
  import { TimeKeeper } from '../../../common/timing/time-keeper'
19
19
  import { applyFnToProps } from '../../../common/util/traverse'
20
+ import { send } from '../../../common/harvest/harvester'
21
+ import { FEATURE_NAMES, FEATURE_TO_ENDPOINT } from '../../../loaders/features/features'
22
+ import { getSubmitMethod } from '../../../common/util/submit-data'
20
23
 
21
24
  export class Aggregate extends AggregateBase {
22
25
  static featureName = CONSTANTS.FEATURE_NAME
@@ -136,6 +139,53 @@ export class Aggregate extends AggregateBase {
136
139
 
137
140
  if (status >= 400 || status === 0) {
138
141
  warn(18, status)
142
+
143
+ // Get estimated payload size of our backlog
144
+ const textEncoder = new TextEncoder()
145
+ const payloadSize = Object.values(newrelic.ee.backlog).reduce((acc, value) => {
146
+ if (!value) return acc
147
+
148
+ const encoded = textEncoder.encode(value)
149
+ return acc + encoded.byteLength
150
+ }, 0)
151
+
152
+ // Send SMs about failed RUM request
153
+ const body = {
154
+ sm: [{
155
+ params: {
156
+ name: `Browser/Supportability/BCS/Error/${status}`
157
+ },
158
+ stats: {
159
+ c: 1
160
+ }
161
+ },
162
+ {
163
+ params: {
164
+ name: 'Browser/Supportability/BCS/Error/Dropped/Bytes'
165
+ },
166
+ stats: {
167
+ c: 1,
168
+ t: payloadSize
169
+ }
170
+ },
171
+ {
172
+ params: {
173
+ name: 'Browser/Supportability/BCS/Error/Duration/Ms'
174
+ },
175
+ stats: {
176
+ c: 1,
177
+ t: rumEndTime - this.rumStartTime
178
+ }
179
+ }]
180
+ }
181
+
182
+ send(this.agentRef, {
183
+ endpoint: FEATURE_TO_ENDPOINT[FEATURE_NAMES.metrics],
184
+ payload: { body },
185
+ submitMethod: getSubmitMethod(),
186
+ featureName: FEATURE_NAMES.metrics
187
+ })
188
+
139
189
  // Adding retry logic for the rum call will be a separate change; this.blocked will need to be changed since that prevents another triggerHarvestFor()
140
190
  this.ee.abort()
141
191
  return
@@ -7,7 +7,7 @@
7
7
  */
8
8
 
9
9
  import { registerHandler } from '../../../common/event-emitter/register-handler'
10
- import { ABORT_REASONS, FEATURE_NAME, QUERY_PARAM_PADDING, RRWEB_EVENT_TYPES, SR_EVENT_EMITTER_TYPES, TRIGGERS } from '../constants'
10
+ import { ABORT_REASONS, ERROR_DURING_REPLAY, FEATURE_NAME, QUERY_PARAM_PADDING, RRWEB_EVENT_TYPES, TRIGGERS } from '../constants'
11
11
  import { AggregateBase } from '../../utils/aggregate-base'
12
12
  import { sharedChannel } from '../../../common/constants/shared-channel'
13
13
  import { obj as encodeObj } from '../../../common/url/encode'
@@ -21,6 +21,7 @@ import { now } from '../../../common/timing/now'
21
21
  import { MAX_PAYLOAD_SIZE } from '../../../common/constants/agent-constants'
22
22
  import { cleanURL } from '../../../common/url/clean-url'
23
23
  import { canEnableSessionTracking } from '../../utils/feature-gates'
24
+ import { PAUSE_REPLAY } from '../../../loaders/api/constants'
24
25
 
25
26
  export class Aggregate extends AggregateBase {
26
27
  static featureName = FEATURE_NAME
@@ -77,11 +78,11 @@ export class Aggregate extends AggregateBase {
77
78
  this.mode = data.sessionReplayMode
78
79
  })
79
80
 
80
- registerHandler(SR_EVENT_EMITTER_TYPES.PAUSE, () => {
81
+ registerHandler(PAUSE_REPLAY, () => {
81
82
  this.forceStop(this.mode === MODE.FULL)
82
83
  }, this.featureName, this.ee)
83
84
 
84
- registerHandler(SR_EVENT_EMITTER_TYPES.ERROR_DURING_REPLAY, e => {
85
+ registerHandler(ERROR_DURING_REPLAY, e => {
85
86
  this.handleError(e)
86
87
  }, this.featureName, this.ee)
87
88
 
@@ -7,11 +7,7 @@ import { FEATURE_NAMES } from '../../loaders/features/features'
7
7
 
8
8
  export const FEATURE_NAME = FEATURE_NAMES.sessionReplay
9
9
 
10
- export const SR_EVENT_EMITTER_TYPES = {
11
- RECORD: 'recordReplay',
12
- PAUSE: 'pauseReplay',
13
- ERROR_DURING_REPLAY: 'errorDuringReplay'
14
- }
10
+ export const ERROR_DURING_REPLAY = 'errorDuringReplay'
15
11
 
16
12
  export const AVG_COMPRESSION = 0.12
17
13
  export const RRWEB_EVENT_TYPES = {
@@ -10,9 +10,10 @@ import { handle } from '../../../common/event-emitter/handle'
10
10
  import { DEFAULT_KEY, MODE, PREFIX } from '../../../common/session/constants'
11
11
  import { InstrumentBase } from '../../utils/instrument-base'
12
12
  import { hasReplayPrerequisite, isPreloadAllowed } from '../shared/utils'
13
- import { FEATURE_NAME, SR_EVENT_EMITTER_TYPES, TRIGGERS } from '../constants'
13
+ import { ERROR_DURING_REPLAY, FEATURE_NAME, TRIGGERS } from '../constants'
14
14
  import { setupRecordReplayAPI } from '../../../loaders/api/recordReplay'
15
15
  import { setupPauseReplayAPI } from '../../../loaders/api/pauseReplay'
16
+ import { RECORD_REPLAY } from '../../../loaders/api/constants'
16
17
 
17
18
  export class Instrument extends InstrumentBase {
18
19
  static featureName = FEATURE_NAME
@@ -34,7 +35,7 @@ export class Instrument extends InstrumentBase {
34
35
  } catch (err) { }
35
36
 
36
37
  if (hasReplayPrerequisite(agentRef.init)) {
37
- this.ee.on(SR_EVENT_EMITTER_TYPES.RECORD, () => this.#apiStartOrRestartReplay())
38
+ this.ee.on(RECORD_REPLAY, () => this.#apiStartOrRestartReplay())
38
39
  }
39
40
 
40
41
  if (this.#canPreloadRecorder(session)) {
@@ -50,7 +51,7 @@ export class Instrument extends InstrumentBase {
50
51
  if (this.blocked) return
51
52
  if (this.agentRef.runtime.isRecording) {
52
53
  this.errorNoticed = true
53
- handle(SR_EVENT_EMITTER_TYPES.ERROR_DURING_REPLAY, [e], undefined, this.featureName, this.ee)
54
+ handle(ERROR_DURING_REPLAY, [e], undefined, this.featureName, this.ee)
54
55
  }
55
56
  })
56
57
  }
@@ -48,6 +48,16 @@ export class RegisteredEntity {
48
48
  warn(35, 'addPageAction')
49
49
  }
50
50
 
51
+ /**
52
+ * Records a custom event with a specified eventType and attributes.
53
+ * {@link https://docs.newrelic.com/docs/browser/new-relic-browser/browser-apis/recordCustomEvent/}
54
+ * @param {string} eventType The eventType to store the event as.
55
+ * @param {Object} [attributes] JSON object with one or more key/value pairs. For example: {key:"value"}.
56
+ */
57
+ recordCustomEvent (eventType, attributes) {
58
+ warn(35, 'recordCustomEvent')
59
+ }
60
+
51
61
  /**
52
62
  * Adds a user-defined attribute name and value to subsequent events on the page for the registered target. Note -- the persist flag does not work with the register API.
53
63
  * {@link https://docs.newrelic.com/docs/browser/new-relic-browser/browser-apis/setcustomattribute/}
@@ -9,7 +9,9 @@ import { prefix, RECORD_CUSTOM_EVENT } from './constants'
9
9
  import { setupAPI } from './sharedHandlers'
10
10
 
11
11
  export function setupRecordCustomEventAPI (agent) {
12
- setupAPI(RECORD_CUSTOM_EVENT, function () {
13
- handle(prefix + RECORD_CUSTOM_EVENT, [now(), ...arguments], undefined, FEATURE_NAMES.genericEvents, agent.ee)
14
- }, agent)
12
+ setupAPI(RECORD_CUSTOM_EVENT, (eventType, attributes) => recordCustomEvent(eventType, attributes, agent), agent)
13
+ }
14
+
15
+ export function recordCustomEvent (eventType, attributes = {}, agentRef, target, timestamp = now()) {
16
+ handle(prefix + RECORD_CUSTOM_EVENT, [timestamp, eventType, attributes, target], undefined, FEATURE_NAMES.genericEvents, agentRef.ee)
15
17
  }
@@ -5,20 +5,20 @@
5
5
 
6
6
  /**
7
7
  * @typedef {Object} RegisterAPI
8
- * @property {Function} addPageAction - Add a page action for the registered entity.
9
- * @property {Function} log - Capture a log for the registered entity.
10
- * @property {Function} noticeError - Notice an error for the registered entity.
11
- * @property {Function} setApplicationVersion - Add an application.version attribute to all outgoing data for the registered entity.
12
- * @property {Function} setCustomAttribute - Add a custom attribute to outgoing data for the registered entity.
13
- * @property {Function} setUserId - Add an enduser.id attribute to all outgoing API data for the registered entity.
8
+ * @property {(name: string, attributes?: object) => void} addPageAction - Add a page action for the registered entity.
9
+ * @property {(message: string, options?: { customAttributes?: object, level?: 'ERROR' | 'TRACE' | 'DEBUG' | 'INFO' | 'WARN'}) => void} log - Capture a log for the registered entity.
10
+ * @property {(error: Error | string, customAttributes?: object) => void} noticeError - Notice an error for the registered entity.
11
+ * @property {(eventType: string, attributes?: Object) => void} recordCustomEvent - Record a custom event for the registered entity.
12
+ * @property {(value: string | null) => void} setApplicationVersion - Add an application.version attribute to all outgoing data for the registered entity.
13
+ * @property {(name: string, value: string | number | boolean | null, persist?: boolean) => void} setCustomAttribute - Add a custom attribute to outgoing data for the registered entity.
14
+ * @property {(value: string | null) => void} setUserId - Add an enduser.id attribute to all outgoing API data for the registered entity.
14
15
  * @property {RegisterAPIMetadata} metadata - The metadata object containing the custom attributes and target information for the registered entity.
15
16
  */
16
17
 
17
18
  /**
18
19
  * @typedef {Object} RegisterAPIConstructor
19
- * @property {Object} opts - The options for the registered entity.
20
- * @property {string} opts.id - The unique id for the registered entity. This will be assigned to any synthesized entities.
21
- * @property {string} opts.name - The readable name for the registered entity. This will be assigned to any synthesized entities.
20
+ * @property {string|number} id - The unique id for the registered entity. This will be assigned to any synthesized entities.
21
+ * @property {string} name - The readable name for the registered entity. This will be assigned to any synthesized entities.
22
22
  */
23
23
 
24
24
  /**
@@ -14,6 +14,7 @@ import { log } from './log'
14
14
  import { addPageAction } from './addPageAction'
15
15
  import { noticeError } from './noticeError'
16
16
  import { single } from '../../common/util/invoke'
17
+ import { recordCustomEvent } from './recordCustomEvent'
17
18
 
18
19
  /**
19
20
  * @typedef {import('./register-api-types').RegisterAPI} RegisterAPI
@@ -79,6 +80,7 @@ export function buildRegisterApi (agentRef, target) {
79
80
  addPageAction: (name, attributes = {}) => report(addPageAction, [name, { ...attrs, ...attributes }, agentRef], target),
80
81
  log: (message, options = {}) => report(log, [message, { ...options, customAttributes: { ...attrs, ...(options.customAttributes || {}) } }, agentRef], target),
81
82
  noticeError: (error, attributes = {}) => report(noticeError, [error, { ...attrs, ...attributes }, agentRef], target),
83
+ recordCustomEvent: (eventType, attributes = {}) => report(recordCustomEvent, [eventType, { ...attrs, ...attributes }, agentRef], target),
82
84
  setApplicationVersion: (value) => setLocalValue('application.version', value),
83
85
  setCustomAttribute: (key, value) => setLocalValue(key, value),
84
86
  setUserId: (value) => setLocalValue('enduser.id', value),
@@ -32,11 +32,8 @@ export class ApiBase {
32
32
  * It is not recommended for use in production environments and will not receive support for issues.
33
33
  *
34
34
  * Registers an external caller to report through the base agent to a different target than the base agent.
35
- * @param {object} target the target object to report data to
36
- * @param {string} target.licenseKey The licenseKey to report data to
37
- * @param {string} target.applicationID The applicationID to report data to
38
- * @param {string=} target.entityGuid The entityGuid to report data to
39
- * @returns {object} Returns an object that contains the available API methods and configurations to use with the external caller. See loaders/api/api.js for more information.
35
+ * @param {import('./api/register-api-types').RegisterAPIConstructor} target the target object to report data to
36
+ @returns {import('./api/register-api-types').RegisterAPI} Returns an object that contains the available API methods and configurations to use with the external caller. See loaders/api/api.js for more information.
40
37
  */
41
38
  register (target) {
42
39
  return this.#callMethod(REGISTER, target)
@@ -46,7 +43,7 @@ export class ApiBase {
46
43
  * Records a custom event with a specified eventType and attributes.
47
44
  * {@link https://docs.newrelic.com/docs/browser/new-relic-browser/browser-apis/recordCustomEvent/}
48
45
  * @param {string} eventType The eventType to store the event as.
49
- * @param {object} [attributes] JSON object with one or more key/value pairs. For example: {key:"value"}.
46
+ * @param {Object} [attributes] JSON object with one or more key/value pairs. For example: {key:"value"}.
50
47
  */
51
48
  recordCustomEvent (eventType, attributes) {
52
49
  return this.#callMethod(RECORD_CUSTOM_EVENT, eventType, attributes)