@newrelic/browser-agent 1.247.0 → 1.248.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/dist/cjs/common/constants/env.cdn.js +1 -1
- package/dist/cjs/common/constants/env.npm.js +1 -1
- package/dist/cjs/features/session_replay/aggregate/index.js +15 -5
- package/dist/cjs/features/session_trace/aggregate/index.js +1 -0
- package/dist/cjs/features/spa/aggregate/index.js +5 -0
- package/dist/esm/common/constants/env.cdn.js +1 -1
- package/dist/esm/common/constants/env.npm.js +1 -1
- package/dist/esm/features/session_replay/aggregate/index.js +14 -4
- package/dist/esm/features/session_trace/aggregate/index.js +1 -0
- package/dist/esm/features/spa/aggregate/index.js +5 -0
- package/dist/types/features/session_replay/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/session_trace/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/spa/aggregate/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/features/session_replay/aggregate/index.js +12 -4
- package/src/features/session_trace/aggregate/index.js +2 -0
- package/src/features/spa/aggregate/index.js +8 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,18 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [1.248.0](https://github.com/newrelic/newrelic-browser-agent/compare/v1.247.0...v1.248.0) (2023-11-16)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* Report enduser.id with Session Replay ([#815](https://github.com/newrelic/newrelic-browser-agent/issues/815)) ([8f5446d](https://github.com/newrelic/newrelic-browser-agent/commit/8f5446d1f7679f6a5ea0ba90eb082d1d4deb0d93))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
### Bug Fixes
|
|
15
|
+
|
|
16
|
+
* Fix issue with errors forcefully triggering session traces ([#819](https://github.com/newrelic/newrelic-browser-agent/issues/819)) ([3872c35](https://github.com/newrelic/newrelic-browser-agent/commit/3872c35a173f76644b663df5ca0474971451b7cf))
|
|
17
|
+
|
|
6
18
|
## [1.247.0](https://github.com/newrelic/newrelic-browser-agent/compare/v1.246.1...v1.247.0) (2023-11-14)
|
|
7
19
|
|
|
8
20
|
|
|
@@ -71,8 +71,10 @@ const MAX_PAYLOAD_SIZE = 1000000;
|
|
|
71
71
|
/** Unloading caps around 64kb */
|
|
72
72
|
exports.MAX_PAYLOAD_SIZE = MAX_PAYLOAD_SIZE;
|
|
73
73
|
const IDEAL_PAYLOAD_SIZE = 64000;
|
|
74
|
-
/**
|
|
74
|
+
/** Reserved room for query param attrs */
|
|
75
75
|
exports.IDEAL_PAYLOAD_SIZE = IDEAL_PAYLOAD_SIZE;
|
|
76
|
+
const QUERY_PARAM_PADDING = 5000;
|
|
77
|
+
/** Interval between forcing new full snapshots -- 15 seconds in error mode (x2), 5 minutes in full mode */
|
|
76
78
|
const CHECKOUT_MS = {
|
|
77
79
|
[_sessionEntity.MODE.ERROR]: 15000,
|
|
78
80
|
[_sessionEntity.MODE.FULL]: 300000,
|
|
@@ -298,6 +300,7 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
298
300
|
getHarvestContents() {
|
|
299
301
|
const agentRuntime = (0, _config.getRuntime)(this.agentIdentifier);
|
|
300
302
|
const info = (0, _config.getInfo)(this.agentIdentifier);
|
|
303
|
+
const endUserId = info.jsAttributes?.['enduser.id'];
|
|
301
304
|
if (this.backloggedEvents.length) this.events = [...this.backloggedEvents, ...this.events];
|
|
302
305
|
|
|
303
306
|
// do not let the first node be a full snapshot node, since this NEEDS to be preceded by a meta node
|
|
@@ -330,6 +333,8 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
330
333
|
app_id: info.applicationID,
|
|
331
334
|
protocol_version: '0',
|
|
332
335
|
attributes: (0, _encode.obj)({
|
|
336
|
+
// this section of attributes must be controllable and stay below the query param padding limit -- see QUERY_PARAM_PADDING
|
|
337
|
+
// if not, data could be lost to truncation at time of sending, potentially breaking parsing / API behavior in NR1
|
|
333
338
|
...(this.shouldCompress && {
|
|
334
339
|
content_encoding: 'gzip'
|
|
335
340
|
}),
|
|
@@ -347,8 +352,13 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
347
352
|
hasError: this.hasError,
|
|
348
353
|
isFirstChunk: agentRuntime.session.state.sessionReplaySentFirstChunk === false,
|
|
349
354
|
decompressedBytes: this.payloadBytesEstimation,
|
|
350
|
-
'rrweb.version': _env.RRWEB_VERSION
|
|
351
|
-
|
|
355
|
+
'rrweb.version': _env.RRWEB_VERSION,
|
|
356
|
+
// customer-defined data should go last so that if it exceeds the query param padding limit it will be truncated instead of important attrs
|
|
357
|
+
...(endUserId && {
|
|
358
|
+
'enduser.id': endUserId
|
|
359
|
+
})
|
|
360
|
+
// The Query Param is being arbitrarily limited in length here. It is also applied when estimating the size of the payload in getPayloadSize()
|
|
361
|
+
}, QUERY_PARAM_PADDING).substring(1) // remove the leading '&'
|
|
352
362
|
},
|
|
353
363
|
|
|
354
364
|
body: this.events
|
|
@@ -470,8 +480,8 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
470
480
|
/** Estimate the payload size */
|
|
471
481
|
getPayloadSize() {
|
|
472
482
|
let newBytes = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
|
|
473
|
-
// the
|
|
474
|
-
return this.estimateCompression(this.payloadBytesEstimation + newBytes) +
|
|
483
|
+
// the query param padding constant gives us some padding for the other metadata to be safely injected
|
|
484
|
+
return this.estimateCompression(this.payloadBytesEstimation + newBytes) + QUERY_PARAM_PADDING;
|
|
475
485
|
}
|
|
476
486
|
|
|
477
487
|
/**
|
|
@@ -102,6 +102,7 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
102
102
|
* "external" input in this case means errors thrown on the page or session replay itself being triggered to run in full mode by the API, which updates the session entity.
|
|
103
103
|
*/
|
|
104
104
|
const switchToFull = () => {
|
|
105
|
+
if (this.agentRuntime?.session?.state?.sessionReplayMode !== _sessionEntity.MODE.FULL) return;
|
|
105
106
|
if (mostRecentModeKnown !== _sessionEntity.MODE.FULL) {
|
|
106
107
|
const prevMode = mostRecentModeKnown;
|
|
107
108
|
mostRecentModeKnown = _sessionEntity.MODE.FULL;
|
|
@@ -23,6 +23,8 @@ var _firstContentfulPaint = require("../../../common/vitals/first-contentful-pai
|
|
|
23
23
|
var _firstPaint = require("../../../common/vitals/first-paint");
|
|
24
24
|
var _bundleId = require("../../../common/ids/bundle-id");
|
|
25
25
|
var _runtime = require("../../../common/constants/runtime");
|
|
26
|
+
var _handle = require("../../../common/event-emitter/handle");
|
|
27
|
+
var _constants2 = require("../../metrics/constants");
|
|
26
28
|
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
27
29
|
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
28
30
|
/*
|
|
@@ -672,6 +674,9 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
672
674
|
}
|
|
673
675
|
baseEE.emit('interactionSaved', [interaction]);
|
|
674
676
|
state.interactionsToHarvest.push(interaction);
|
|
677
|
+
let smCategory = 'RouteChange';
|
|
678
|
+
if (interaction.root?.attrs?.trigger === 'initialPageLoad') smCategory = 'InitialPageLoad';else if (interaction.root?.attrs?.trigger === 'api') smCategory = 'Custom';
|
|
679
|
+
(0, _handle.handle)(_constants2.SUPPORTABILITY_METRIC_CHANNEL, ["Spa/Interaction/".concat(smCategory, "/Duration/Ms"), Math.max((interaction.root?.end || 0) - (interaction.root?.start || 0), 0)], undefined, _features.FEATURE_NAMES.metrics, baseEE);
|
|
675
680
|
scheduler.scheduleHarvest(0);
|
|
676
681
|
}
|
|
677
682
|
function isEnabled() {
|
|
@@ -63,6 +63,8 @@ let recorder, gzipper, u8;
|
|
|
63
63
|
export const MAX_PAYLOAD_SIZE = 1000000;
|
|
64
64
|
/** Unloading caps around 64kb */
|
|
65
65
|
export const IDEAL_PAYLOAD_SIZE = 64000;
|
|
66
|
+
/** Reserved room for query param attrs */
|
|
67
|
+
const QUERY_PARAM_PADDING = 5000;
|
|
66
68
|
/** Interval between forcing new full snapshots -- 15 seconds in error mode (x2), 5 minutes in full mode */
|
|
67
69
|
const CHECKOUT_MS = {
|
|
68
70
|
[MODE.ERROR]: 15000,
|
|
@@ -289,6 +291,7 @@ export class Aggregate extends AggregateBase {
|
|
|
289
291
|
getHarvestContents() {
|
|
290
292
|
const agentRuntime = getRuntime(this.agentIdentifier);
|
|
291
293
|
const info = getInfo(this.agentIdentifier);
|
|
294
|
+
const endUserId = info.jsAttributes?.['enduser.id'];
|
|
292
295
|
if (this.backloggedEvents.length) this.events = [...this.backloggedEvents, ...this.events];
|
|
293
296
|
|
|
294
297
|
// do not let the first node be a full snapshot node, since this NEEDS to be preceded by a meta node
|
|
@@ -321,6 +324,8 @@ export class Aggregate extends AggregateBase {
|
|
|
321
324
|
app_id: info.applicationID,
|
|
322
325
|
protocol_version: '0',
|
|
323
326
|
attributes: encodeObj({
|
|
327
|
+
// this section of attributes must be controllable and stay below the query param padding limit -- see QUERY_PARAM_PADDING
|
|
328
|
+
// if not, data could be lost to truncation at time of sending, potentially breaking parsing / API behavior in NR1
|
|
324
329
|
...(this.shouldCompress && {
|
|
325
330
|
content_encoding: 'gzip'
|
|
326
331
|
}),
|
|
@@ -338,8 +343,13 @@ export class Aggregate extends AggregateBase {
|
|
|
338
343
|
hasError: this.hasError,
|
|
339
344
|
isFirstChunk: agentRuntime.session.state.sessionReplaySentFirstChunk === false,
|
|
340
345
|
decompressedBytes: this.payloadBytesEstimation,
|
|
341
|
-
'rrweb.version': RRWEB_VERSION
|
|
342
|
-
|
|
346
|
+
'rrweb.version': RRWEB_VERSION,
|
|
347
|
+
// customer-defined data should go last so that if it exceeds the query param padding limit it will be truncated instead of important attrs
|
|
348
|
+
...(endUserId && {
|
|
349
|
+
'enduser.id': endUserId
|
|
350
|
+
})
|
|
351
|
+
// The Query Param is being arbitrarily limited in length here. It is also applied when estimating the size of the payload in getPayloadSize()
|
|
352
|
+
}, QUERY_PARAM_PADDING).substring(1) // remove the leading '&'
|
|
343
353
|
},
|
|
344
354
|
|
|
345
355
|
body: this.events
|
|
@@ -461,8 +471,8 @@ export class Aggregate extends AggregateBase {
|
|
|
461
471
|
/** Estimate the payload size */
|
|
462
472
|
getPayloadSize() {
|
|
463
473
|
let newBytes = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
|
|
464
|
-
// the
|
|
465
|
-
return this.estimateCompression(this.payloadBytesEstimation + newBytes) +
|
|
474
|
+
// the query param padding constant gives us some padding for the other metadata to be safely injected
|
|
475
|
+
return this.estimateCompression(this.payloadBytesEstimation + newBytes) + QUERY_PARAM_PADDING;
|
|
466
476
|
}
|
|
467
477
|
|
|
468
478
|
/**
|
|
@@ -95,6 +95,7 @@ export class Aggregate extends AggregateBase {
|
|
|
95
95
|
* "external" input in this case means errors thrown on the page or session replay itself being triggered to run in full mode by the API, which updates the session entity.
|
|
96
96
|
*/
|
|
97
97
|
const switchToFull = () => {
|
|
98
|
+
if (this.agentRuntime?.session?.state?.sessionReplayMode !== MODE.FULL) return;
|
|
98
99
|
if (mostRecentModeKnown !== MODE.FULL) {
|
|
99
100
|
const prevMode = mostRecentModeKnown;
|
|
100
101
|
mostRecentModeKnown = MODE.FULL;
|
|
@@ -22,6 +22,8 @@ import { firstContentfulPaint } from '../../../common/vitals/first-contentful-pa
|
|
|
22
22
|
import { firstPaint } from '../../../common/vitals/first-paint';
|
|
23
23
|
import { bundleId } from '../../../common/ids/bundle-id';
|
|
24
24
|
import { loadedAsDeferredBrowserScript } from '../../../common/constants/runtime';
|
|
25
|
+
import { handle } from '../../../common/event-emitter/handle';
|
|
26
|
+
import { SUPPORTABILITY_METRIC_CHANNEL } from '../../metrics/constants';
|
|
25
27
|
const {
|
|
26
28
|
FEATURE_NAME,
|
|
27
29
|
INTERACTION_EVENTS,
|
|
@@ -663,6 +665,9 @@ export class Aggregate extends AggregateBase {
|
|
|
663
665
|
}
|
|
664
666
|
baseEE.emit('interactionSaved', [interaction]);
|
|
665
667
|
state.interactionsToHarvest.push(interaction);
|
|
668
|
+
let smCategory = 'RouteChange';
|
|
669
|
+
if (interaction.root?.attrs?.trigger === 'initialPageLoad') smCategory = 'InitialPageLoad';else if (interaction.root?.attrs?.trigger === 'api') smCategory = 'Custom';
|
|
670
|
+
handle(SUPPORTABILITY_METRIC_CHANNEL, ["Spa/Interaction/".concat(smCategory, "/Duration/Ms"), Math.max((interaction.root?.end || 0) - (interaction.root?.start || 0), 0)], undefined, FEATURE_NAMES.metrics, baseEE);
|
|
666
671
|
scheduler.scheduleHarvest(0);
|
|
667
672
|
}
|
|
668
673
|
function isEnabled() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/features/session_replay/aggregate/index.js"],"names":[],"mappings":"AA6BA,mCAAmC;;;;;;;;;AAoCnC,uCAAuC;AACvC,uCAAuC;AACvC,iCAAiC;AACjC,uCAAuC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/features/session_replay/aggregate/index.js"],"names":[],"mappings":"AA6BA,mCAAmC;;;;;;;;;AAoCnC,uCAAuC;AACvC,uCAAuC;AACvC,iCAAiC;AACjC,uCAAuC;AAMvC;IACE,2BAAiC;IACjC,mDAuHC;IArHC,iHAAiH;IACjH,cAAgB;IAChB,mFAAmF;IACnF,wBAA0B;IAC1B,8GAA8G;IAC9G,wBAAgH;IAChH,iFAAiF;IACjF,qBAAwB;IACxB,mEAAmE;IACnE,sBAAyB;IACzB,6GAA6G;IAC7G,aAAoB;IAGpB,iEAAiE;IACjE,mBAAsB;IACtB,gDAAgD;IAChD,wBAA0B;IAE1B;;;MAGE;IACF,qBAAwB;IACxB,4IAA4I;IAC5I,iBAAoB;IACpB,+HAA+H;IAC/H,kBAAqB;IAErB;;OAEG;IACH,oBAA+B;IAE/B,qGAAqG;IACrG,+BAA+B;IAE/B,kIAAkI;IAClI,cAAyB;IAEzB,0BAA0B;IAC1B,kBAAqB;IAOrB,uIAAuI;IACvI,0BAAyE;IA0BvE,wCAKQ;IAuCZ,qBAWC;IAED;;;;;;;OAOG;IACH,iCALW,OAAO,cACP,OAAO,iBACP,OAAO,GACL,IAAI,CAuDhB;IAED;;;;;;;;;oBAkBC;IAED;;;;;;;;;MAgEC;IAED,qCAOC;IAED,kFAAkF;IAClF,oBASC;IAED,qDAAqD;IACrD,uBA4BC;IAED,yHAAyH;IACzH,yCAsCC;IAED,0HAA0H;IAC1H,yBAGC;IAED,sBAGC;IAED,wBAEC;IAED,gCAAgC;IAChC,uCAGC;IAED;;;;OAIG;IACH,mCAKC;IAED,yDAAyD;IACzD,yBASC;IAED;;;SAGK;IACL,oCAGC;IAED,yCAGC;CACF;8BA5e6B,4BAA4B;iCALzB,2CAA2C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/features/session_trace/aggregate/index.js"],"names":[],"mappings":"AAiCA;IACE,2BAAiC;IAGjC,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/features/session_trace/aggregate/index.js"],"names":[],"mappings":"AAiCA;IACE,2BAAiC;IAGjC,iEA4IC;IA1IC,kBAA+C;IAK/C,sBAAiD;IACjD,yBAAc;IACd,sBAAe;IACf,8BAAkB;IAClB,iCAAqB;IACrB,wBAA0G;IAC1G,wBAA4G;IAC5G;;4EAEwE;IACxE,kCAAyB;IAGzB,0CAAsC;IA0HxC,sEAcC;IA6CD,oDAOC;IAGD,oCAwBC;IAGD,uEAkBC;IAED,oDAKC;IAED,wBAwBC;IAED,uCAuBC;IAGD,gDASC;IAID,qCAkBC;IAGD,qEAUC;IAGD,mEAUC;IAGD,yBAeC;IAED;;;;OAIG;IACH,2BAHW,MAAM,GACJ,MAAM,CAsBlB;IAGD;;;;;;;YAkCM;0GAC8F;;YAE9F;0FAC8E;;YAE9E,4IAA4I;;;;;;MAMjJ;IAED,mEA6BC;;CACF;8BA5gB6B,4BAA4B;6BAH7B,2BAA2B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/features/spa/aggregate/index.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/features/spa/aggregate/index.js"],"names":[],"mappings":"AA+BA;IACE,2BAAiC;IACjC,mDAssBC;IAnsBC;;;;;;;;;;;;;;;;;MAkBC;IAED,uBAAsC;CAgrBzC;8BArtB6B,4BAA4B;2BAJ/B,cAAc"}
|
package/package.json
CHANGED
|
@@ -67,6 +67,8 @@ let recorder, gzipper, u8
|
|
|
67
67
|
export const MAX_PAYLOAD_SIZE = 1000000
|
|
68
68
|
/** Unloading caps around 64kb */
|
|
69
69
|
export const IDEAL_PAYLOAD_SIZE = 64000
|
|
70
|
+
/** Reserved room for query param attrs */
|
|
71
|
+
const QUERY_PARAM_PADDING = 5000
|
|
70
72
|
/** Interval between forcing new full snapshots -- 15 seconds in error mode (x2), 5 minutes in full mode */
|
|
71
73
|
const CHECKOUT_MS = { [MODE.ERROR]: 15000, [MODE.FULL]: 300000, [MODE.OFF]: 0 }
|
|
72
74
|
|
|
@@ -292,6 +294,7 @@ export class Aggregate extends AggregateBase {
|
|
|
292
294
|
getHarvestContents () {
|
|
293
295
|
const agentRuntime = getRuntime(this.agentIdentifier)
|
|
294
296
|
const info = getInfo(this.agentIdentifier)
|
|
297
|
+
const endUserId = info.jsAttributes?.['enduser.id']
|
|
295
298
|
|
|
296
299
|
if (this.backloggedEvents.length) this.events = [...this.backloggedEvents, ...this.events]
|
|
297
300
|
|
|
@@ -327,6 +330,8 @@ export class Aggregate extends AggregateBase {
|
|
|
327
330
|
app_id: info.applicationID,
|
|
328
331
|
protocol_version: '0',
|
|
329
332
|
attributes: encodeObj({
|
|
333
|
+
// this section of attributes must be controllable and stay below the query param padding limit -- see QUERY_PARAM_PADDING
|
|
334
|
+
// if not, data could be lost to truncation at time of sending, potentially breaking parsing / API behavior in NR1
|
|
330
335
|
...(this.shouldCompress && { content_encoding: 'gzip' }),
|
|
331
336
|
'replay.firstTimestamp': firstTimestamp,
|
|
332
337
|
'replay.firstTimestampOffset': firstTimestamp - agentOffset,
|
|
@@ -342,8 +347,11 @@ export class Aggregate extends AggregateBase {
|
|
|
342
347
|
hasError: this.hasError,
|
|
343
348
|
isFirstChunk: agentRuntime.session.state.sessionReplaySentFirstChunk === false,
|
|
344
349
|
decompressedBytes: this.payloadBytesEstimation,
|
|
345
|
-
'rrweb.version': RRWEB_VERSION
|
|
346
|
-
|
|
350
|
+
'rrweb.version': RRWEB_VERSION,
|
|
351
|
+
// customer-defined data should go last so that if it exceeds the query param padding limit it will be truncated instead of important attrs
|
|
352
|
+
...(endUserId && { 'enduser.id': endUserId })
|
|
353
|
+
// The Query Param is being arbitrarily limited in length here. It is also applied when estimating the size of the payload in getPayloadSize()
|
|
354
|
+
}, QUERY_PARAM_PADDING).substring(1) // remove the leading '&'
|
|
347
355
|
},
|
|
348
356
|
body: this.events
|
|
349
357
|
}
|
|
@@ -459,8 +467,8 @@ export class Aggregate extends AggregateBase {
|
|
|
459
467
|
|
|
460
468
|
/** Estimate the payload size */
|
|
461
469
|
getPayloadSize (newBytes = 0) {
|
|
462
|
-
// the
|
|
463
|
-
return this.estimateCompression(this.payloadBytesEstimation + newBytes) +
|
|
470
|
+
// the query param padding constant gives us some padding for the other metadata to be safely injected
|
|
471
|
+
return this.estimateCompression(this.payloadBytesEstimation + newBytes) + QUERY_PARAM_PADDING
|
|
464
472
|
}
|
|
465
473
|
|
|
466
474
|
/**
|
|
@@ -89,6 +89,8 @@ export class Aggregate extends AggregateBase {
|
|
|
89
89
|
* "external" input in this case means errors thrown on the page or session replay itself being triggered to run in full mode by the API, which updates the session entity.
|
|
90
90
|
*/
|
|
91
91
|
const switchToFull = () => {
|
|
92
|
+
if (this.agentRuntime?.session?.state?.sessionReplayMode !== MODE.FULL) return
|
|
93
|
+
|
|
92
94
|
if (mostRecentModeKnown !== MODE.FULL) {
|
|
93
95
|
const prevMode = mostRecentModeKnown
|
|
94
96
|
mostRecentModeKnown = MODE.FULL
|
|
@@ -22,6 +22,8 @@ import { firstContentfulPaint } from '../../../common/vitals/first-contentful-pa
|
|
|
22
22
|
import { firstPaint } from '../../../common/vitals/first-paint'
|
|
23
23
|
import { bundleId } from '../../../common/ids/bundle-id'
|
|
24
24
|
import { loadedAsDeferredBrowserScript } from '../../../common/constants/runtime'
|
|
25
|
+
import { handle } from '../../../common/event-emitter/handle'
|
|
26
|
+
import { SUPPORTABILITY_METRIC_CHANNEL } from '../../metrics/constants'
|
|
25
27
|
|
|
26
28
|
const {
|
|
27
29
|
FEATURE_NAME, INTERACTION_EVENTS, MAX_TIMER_BUDGET, FN_START, FN_END, CB_START, INTERACTION_API, REMAINING,
|
|
@@ -724,6 +726,12 @@ export class Aggregate extends AggregateBase {
|
|
|
724
726
|
}
|
|
725
727
|
baseEE.emit('interactionSaved', [interaction])
|
|
726
728
|
state.interactionsToHarvest.push(interaction)
|
|
729
|
+
|
|
730
|
+
let smCategory = 'RouteChange'
|
|
731
|
+
if (interaction.root?.attrs?.trigger === 'initialPageLoad') smCategory = 'InitialPageLoad'
|
|
732
|
+
else if (interaction.root?.attrs?.trigger === 'api') smCategory = 'Custom'
|
|
733
|
+
handle(SUPPORTABILITY_METRIC_CHANNEL, [`Spa/Interaction/${smCategory}/Duration/Ms`, Math.max((interaction.root?.end || 0) - (interaction.root?.start || 0), 0)], undefined, FEATURE_NAMES.metrics, baseEE)
|
|
734
|
+
|
|
727
735
|
scheduler.scheduleHarvest(0)
|
|
728
736
|
}
|
|
729
737
|
|