@newrelic/browser-agent 1.302.0-alpha.0 → 1.302.0-alpha.1

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 (26) 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/page_view_event/aggregate/index.js +48 -0
  5. package/dist/cjs/features/session_replay/aggregate/index.js +3 -2
  6. package/dist/cjs/features/session_replay/constants.js +2 -6
  7. package/dist/cjs/features/session_replay/instrument/index.js +3 -2
  8. package/dist/esm/common/constants/env.cdn.js +1 -1
  9. package/dist/esm/common/constants/env.npm.js +1 -1
  10. package/dist/esm/common/wrap/wrap-promise.js +10 -5
  11. package/dist/esm/features/page_view_event/aggregate/index.js +48 -0
  12. package/dist/esm/features/session_replay/aggregate/index.js +4 -3
  13. package/dist/esm/features/session_replay/constants.js +1 -5
  14. package/dist/esm/features/session_replay/instrument/index.js +4 -3
  15. package/dist/types/common/wrap/wrap-promise.d.ts.map +1 -1
  16. package/dist/types/features/page_view_event/aggregate/index.d.ts.map +1 -1
  17. package/dist/types/features/session_replay/aggregate/index.d.ts.map +1 -1
  18. package/dist/types/features/session_replay/constants.d.ts +1 -5
  19. package/dist/types/features/session_replay/constants.d.ts.map +1 -1
  20. package/dist/types/features/session_replay/instrument/index.d.ts.map +1 -1
  21. package/package.json +1 -1
  22. package/src/common/wrap/wrap-promise.js +16 -6
  23. package/src/features/page_view_event/aggregate/index.js +50 -0
  24. package/src/features/session_replay/aggregate/index.js +4 -3
  25. package/src/features/session_replay/constants.js +1 -5
  26. package/src/features/session_replay/instrument/index.js +4 -3
@@ -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-alpha.0";
20
+ const VERSION = exports.VERSION = "1.302.0-alpha.1";
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-alpha.0";
20
+ const VERSION = exports.VERSION = "1.302.0-alpha.1";
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
  });
@@ -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
  }
@@ -11,7 +11,7 @@
11
11
  /**
12
12
  * Exposes the version of the agent
13
13
  */
14
- export const VERSION = "1.302.0-alpha.0";
14
+ export const VERSION = "1.302.0-alpha.1";
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-alpha.0";
14
+ export const VERSION = "1.302.0-alpha.1";
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
  });
@@ -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
  }
@@ -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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@newrelic/browser-agent",
3
- "version": "1.302.0-alpha.0",
3
+ "version": "1.302.0-alpha.1",
4
4
  "private": false,
5
5
  "author": "New Relic Browser Agent Team <browser-agent@newrelic.com>",
6
6
  "description": "New Relic Browser Agent",
@@ -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
  })
@@ -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
  }