@newrelic/browser-agent 1.239.1 → 1.241.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/README.md +4 -0
- package/dist/cjs/cdn/pro.js +3 -2
- package/dist/cjs/cdn/spa.js +4 -3
- package/dist/cjs/common/config/state/init.js +25 -17
- package/dist/cjs/common/constants/env.cdn.js +1 -1
- package/dist/cjs/common/constants/env.npm.js +1 -1
- package/dist/cjs/common/constants/runtime.js +9 -5
- package/dist/cjs/common/harvest/harvest.js +5 -3
- package/dist/cjs/common/vitals/constants.js +17 -0
- package/dist/cjs/common/vitals/cumulative-layout-shift.js +27 -0
- package/dist/cjs/common/vitals/first-contentful-paint.js +49 -0
- package/dist/cjs/common/vitals/first-input-delay.js +32 -0
- package/dist/{esm/features/page_view_timing → cjs/common/vitals}/first-paint.js +19 -17
- package/dist/cjs/common/vitals/interaction-to-next-paint.js +29 -0
- package/dist/cjs/common/vitals/largest-contentful-paint.js +41 -0
- package/dist/cjs/common/vitals/long-task.js +64 -0
- package/dist/cjs/common/vitals/time-to-first-byte.js +36 -0
- package/dist/cjs/common/vitals/vital-metric.js +71 -0
- package/dist/cjs/features/ajax/aggregate/index.js +4 -1
- package/dist/cjs/features/metrics/aggregate/index.js +17 -7
- package/dist/cjs/features/page_view_event/aggregate/index.js +18 -40
- package/dist/cjs/features/page_view_event/constants.js +2 -8
- package/dist/cjs/features/page_view_event/instrument/index.js +0 -22
- package/dist/cjs/features/page_view_timing/aggregate/index.js +36 -147
- package/dist/cjs/features/page_view_timing/instrument/index.js +0 -3
- package/dist/cjs/features/session_replay/aggregate/index.js +81 -35
- package/dist/cjs/features/session_trace/aggregate/index.js +13 -1
- package/dist/cjs/features/spa/aggregate/index.js +4 -3
- package/dist/cjs/loaders/agent.js +3 -0
- package/dist/cjs/loaders/api/api.js +2 -0
- package/dist/cjs/loaders/api/apiAsync.js +4 -2
- package/dist/cjs/loaders/browser-agent.js +2 -1
- package/dist/cjs/loaders/configure/configure.js +13 -1
- package/dist/cjs/loaders/configure/public-path.js +13 -0
- package/dist/cjs/loaders/configure/public-path.npm.js +10 -0
- package/dist/esm/cdn/pro.js +2 -1
- package/dist/esm/cdn/spa.js +2 -1
- package/dist/esm/common/config/state/init.js +25 -17
- package/dist/esm/common/constants/env.cdn.js +1 -1
- package/dist/esm/common/constants/env.npm.js +1 -1
- package/dist/esm/common/constants/runtime.js +5 -3
- package/dist/esm/common/harvest/harvest.js +6 -4
- package/dist/esm/common/vitals/constants.js +10 -0
- package/dist/esm/common/vitals/cumulative-layout-shift.js +20 -0
- package/dist/esm/common/vitals/first-contentful-paint.js +41 -0
- package/dist/esm/common/vitals/first-input-delay.js +25 -0
- package/dist/{cjs/features/page_view_timing → esm/common/vitals}/first-paint.js +12 -24
- package/dist/esm/common/vitals/interaction-to-next-paint.js +22 -0
- package/dist/esm/common/vitals/largest-contentful-paint.js +34 -0
- package/dist/esm/common/vitals/long-task.js +57 -0
- package/dist/esm/common/vitals/time-to-first-byte.js +29 -0
- package/dist/esm/common/vitals/vital-metric.js +64 -0
- package/dist/esm/features/ajax/aggregate/index.js +4 -1
- package/dist/esm/features/metrics/aggregate/index.js +18 -8
- package/dist/esm/features/page_view_event/aggregate/index.js +20 -42
- package/dist/esm/features/page_view_event/constants.js +1 -4
- package/dist/esm/features/page_view_event/instrument/index.js +0 -22
- package/dist/esm/features/page_view_timing/aggregate/index.js +37 -148
- package/dist/esm/features/page_view_timing/instrument/index.js +0 -3
- package/dist/esm/features/session_replay/aggregate/index.js +81 -35
- package/dist/esm/features/session_trace/aggregate/index.js +13 -1
- package/dist/esm/features/spa/aggregate/index.js +4 -3
- package/dist/esm/loaders/agent.js +2 -0
- package/dist/esm/loaders/api/api.js +2 -0
- package/dist/esm/loaders/api/apiAsync.js +5 -3
- package/dist/esm/loaders/browser-agent.js +2 -1
- package/dist/esm/loaders/configure/configure.js +13 -1
- package/dist/esm/loaders/configure/public-path.js +6 -0
- package/dist/esm/loaders/configure/public-path.npm.js +3 -0
- package/dist/types/common/config/state/init.d.ts.map +1 -1
- package/dist/types/common/constants/runtime.d.ts +3 -1
- package/dist/types/common/constants/runtime.d.ts.map +1 -1
- package/dist/types/common/harvest/harvest.d.ts +0 -1
- package/dist/types/common/harvest/harvest.d.ts.map +1 -1
- package/dist/types/common/vitals/constants.d.ts +11 -0
- package/dist/types/common/vitals/constants.d.ts.map +1 -0
- package/dist/types/common/vitals/cumulative-layout-shift.d.ts +3 -0
- package/dist/types/common/vitals/cumulative-layout-shift.d.ts.map +1 -0
- package/dist/types/common/vitals/first-contentful-paint.d.ts +3 -0
- package/dist/types/common/vitals/first-contentful-paint.d.ts.map +1 -0
- package/dist/types/common/vitals/first-input-delay.d.ts +3 -0
- package/dist/types/common/vitals/first-input-delay.d.ts.map +1 -0
- package/dist/types/common/vitals/first-paint.d.ts +3 -0
- package/dist/types/common/vitals/first-paint.d.ts.map +1 -0
- package/dist/types/common/vitals/interaction-to-next-paint.d.ts +3 -0
- package/dist/types/common/vitals/interaction-to-next-paint.d.ts.map +1 -0
- package/dist/types/common/vitals/largest-contentful-paint.d.ts +3 -0
- package/dist/types/common/vitals/largest-contentful-paint.d.ts.map +1 -0
- package/dist/types/common/vitals/long-task.d.ts +3 -0
- package/dist/types/common/vitals/long-task.d.ts.map +1 -0
- package/dist/types/common/vitals/time-to-first-byte.d.ts +3 -0
- package/dist/types/common/vitals/time-to-first-byte.d.ts.map +1 -0
- package/dist/types/common/vitals/vital-metric.d.ts +18 -0
- package/dist/types/common/vitals/vital-metric.d.ts.map +1 -0
- package/dist/types/features/ajax/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/metrics/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/page_view_event/aggregate/index.d.ts +3 -2
- package/dist/types/features/page_view_event/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/page_view_event/constants.d.ts +0 -3
- package/dist/types/features/page_view_event/constants.d.ts.map +1 -1
- package/dist/types/features/page_view_event/instrument/index.d.ts.map +1 -1
- package/dist/types/features/page_view_timing/aggregate/index.d.ts +1 -3
- package/dist/types/features/page_view_timing/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/page_view_timing/instrument/index.d.ts.map +1 -1
- package/dist/types/features/session_replay/aggregate/index.d.ts +16 -4
- package/dist/types/features/session_replay/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/session_trace/aggregate/index.d.ts +9 -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/dist/types/loaders/agent.d.ts.map +1 -1
- package/dist/types/loaders/api/api.d.ts.map +1 -1
- package/dist/types/loaders/api/apiAsync.d.ts.map +1 -1
- package/dist/types/loaders/browser-agent.d.ts.map +1 -1
- package/dist/types/loaders/configure/configure.d.ts.map +1 -1
- package/dist/types/loaders/configure/public-path.d.ts +2 -0
- package/dist/types/loaders/configure/public-path.d.ts.map +1 -0
- package/dist/types/loaders/configure/public-path.npm.d.ts +2 -0
- package/dist/types/loaders/configure/public-path.npm.d.ts.map +1 -0
- package/package.json +2 -3
- package/src/cdn/pro.js +2 -0
- package/src/cdn/spa.js +2 -0
- package/src/common/config/state/init.js +21 -17
- package/src/common/constants/runtime.js +7 -3
- package/src/common/constants/runtime.test.js +8 -0
- package/src/common/harvest/harvest-scheduler.test.js +2 -2
- package/src/common/harvest/harvest.js +6 -4
- package/src/common/harvest/harvest.test.js +17 -0
- package/src/common/vitals/__mocks__/web-vitals.js +19 -0
- package/src/common/vitals/constants.js +10 -0
- package/src/common/vitals/cumulative-layout-shift.js +13 -0
- package/src/common/vitals/cumulative-layout-shift.test.js +71 -0
- package/src/common/vitals/first-contentful-paint.js +31 -0
- package/src/common/vitals/first-contentful-paint.test.js +124 -0
- package/src/common/vitals/first-input-delay.js +20 -0
- package/src/common/vitals/first-input-delay.test.js +88 -0
- package/src/{features/page_view_timing → common/vitals}/first-paint.js +11 -17
- package/src/common/vitals/first-paint.test.js +127 -0
- package/src/common/vitals/interaction-to-next-paint.js +13 -0
- package/src/common/vitals/interaction-to-next-paint.test.js +74 -0
- package/src/common/vitals/largest-contentful-paint.js +29 -0
- package/src/common/vitals/largest-contentful-paint.test.js +94 -0
- package/src/common/vitals/long-task.js +52 -0
- package/src/common/vitals/long-task.test.js +122 -0
- package/src/common/vitals/time-to-first-byte.js +21 -0
- package/src/common/vitals/time-to-first-byte.test.js +147 -0
- package/src/common/vitals/vital-metric.js +60 -0
- package/src/common/vitals/vital-metric.test.js +171 -0
- package/src/features/ajax/aggregate/index.js +5 -1
- package/src/features/metrics/aggregate/index.js +11 -4
- package/src/features/page_view_event/aggregate/index.js +20 -43
- package/src/features/page_view_event/constants.js +0 -3
- package/src/features/page_view_event/instrument/index.js +0 -21
- package/src/features/page_view_timing/aggregate/index.component-test.js +86 -0
- package/src/features/page_view_timing/aggregate/index.js +31 -108
- package/src/features/page_view_timing/instrument/index.js +0 -3
- package/src/features/session_replay/aggregate/index.component-test.js +10 -10
- package/src/features/session_replay/aggregate/index.js +62 -29
- package/src/features/session_trace/aggregate/index.js +15 -1
- package/src/features/spa/aggregate/index.js +4 -3
- package/src/loaders/agent.js +2 -0
- package/src/loaders/api/api.js +2 -0
- package/src/loaders/api/apiAsync.js +5 -4
- package/src/loaders/browser-agent.js +3 -1
- package/src/loaders/configure/configure.js +15 -7
- package/src/loaders/configure/public-path.js +6 -0
- package/src/loaders/configure/public-path.npm.js +4 -0
- package/dist/cjs/common/metrics/paint-metrics.js +0 -13
- package/dist/cjs/features/page_view_timing/long-tasks.js +0 -75
- package/dist/esm/common/metrics/paint-metrics.js +0 -6
- package/dist/esm/features/page_view_timing/long-tasks.js +0 -69
- package/dist/types/common/metrics/paint-metrics.d.ts +0 -2
- package/dist/types/common/metrics/paint-metrics.d.ts.map +0 -1
- package/dist/types/features/page_view_timing/first-paint.d.ts +0 -2
- package/dist/types/features/page_view_timing/first-paint.d.ts.map +0 -1
- package/dist/types/features/page_view_timing/long-tasks.d.ts +0 -2
- package/dist/types/features/page_view_timing/long-tasks.d.ts.map +0 -1
- package/src/common/metrics/paint-metrics.js +0 -6
- package/src/features/page_view_timing/long-tasks.js +0 -60
|
@@ -14,6 +14,7 @@ var _aggregateBase = require("../../utils/aggregate-base");
|
|
|
14
14
|
var _sharedChannel = require("../../../common/constants/shared-channel");
|
|
15
15
|
var _encode = require("../../../common/url/encode");
|
|
16
16
|
var _console = require("../../../common/util/console");
|
|
17
|
+
var _runtime = require("../../../common/constants/runtime");
|
|
17
18
|
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); }
|
|
18
19
|
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; } /*
|
|
19
20
|
* Copyright 2023 New Relic Corporation. All rights reserved.
|
|
@@ -72,17 +73,30 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
72
73
|
* -- When visibility changes from "hidden" -> "visible", it must capture a full snapshot for the replay to work correctly across tabs
|
|
73
74
|
*/
|
|
74
75
|
this.hasSnapshot = false;
|
|
76
|
+
/** Payload metadata -- Should indicate that the payload being sent has a meta node. The meta node should always precede a snapshot node. */
|
|
77
|
+
this.hasMeta = false;
|
|
75
78
|
/** Payload metadata -- Should indicate that the payload being sent contains an error. Used for query/filter purposes in UI */
|
|
76
79
|
this.hasError = false;
|
|
77
80
|
|
|
78
|
-
/** Payload metadata -- Should indicate when a replay blob started recording. Resets each time a harvest occurs.
|
|
81
|
+
/** Payload metadata -- Should indicate when a replay blob started recording. Resets each time a harvest occurs.
|
|
82
|
+
* cycle timestamps are used as fallbacks if event timestamps cannot be used
|
|
83
|
+
*/
|
|
79
84
|
this.timestamp = {
|
|
80
|
-
|
|
81
|
-
|
|
85
|
+
event: {
|
|
86
|
+
first: undefined,
|
|
87
|
+
last: undefined
|
|
88
|
+
},
|
|
89
|
+
cycle: {
|
|
90
|
+
first: undefined,
|
|
91
|
+
last: undefined
|
|
92
|
+
}
|
|
82
93
|
};
|
|
83
94
|
|
|
84
95
|
/** A value which increments with every new mutation node reported. Resets after a harvest is sent */
|
|
85
96
|
this.payloadBytesEstimation = 0;
|
|
97
|
+
|
|
98
|
+
/** Hold on to the last meta node, so that it can be re-inserted if the meta and snapshot nodes are broken up due to harvesting */
|
|
99
|
+
this.lastMeta = undefined;
|
|
86
100
|
const shouldSetup = (0, _config.getConfigurationValue)(agentIdentifier, 'privacy.cookies_enabled') === true && (0, _config.getConfigurationValue)(agentIdentifier, 'session_trace.enabled') === true;
|
|
87
101
|
|
|
88
102
|
/** The method to stop recording. This defaults to a noop, but is overwritten once the recording library is imported and initialized */
|
|
@@ -132,7 +146,7 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
132
146
|
}, this.featureName, this.ee);
|
|
133
147
|
this.waitForFlags(['sr']).then(_ref => {
|
|
134
148
|
let [flagOn] = _ref;
|
|
135
|
-
return this.initializeRecording(flagOn, Math.random() < (0, _config.getConfigurationValue)(this.agentIdentifier, 'session_replay.
|
|
149
|
+
return this.initializeRecording(flagOn, Math.random() * 100 < (0, _config.getConfigurationValue)(this.agentIdentifier, 'session_replay.error_sampling_rate'), Math.random() * 100 < (0, _config.getConfigurationValue)(this.agentIdentifier, 'session_replay.sampling_rate'));
|
|
136
150
|
}).then(() => _sharedChannel.sharedChannel.onReplayReady(this.mode)); // notify watchers that replay started with the mode
|
|
137
151
|
|
|
138
152
|
this.drain();
|
|
@@ -173,6 +187,12 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
173
187
|
if (this.mode === _sessionEntity.MODE.ERROR && this.errorNoticed) {
|
|
174
188
|
this.mode = _sessionEntity.MODE.FULL;
|
|
175
189
|
}
|
|
190
|
+
try {
|
|
191
|
+
// Do not change the webpackChunkName or it will break the webpack nrba-chunking plugin
|
|
192
|
+
recorder = (await Promise.resolve().then(() => _interopRequireWildcard(require( /* webpackChunkName: "recorder" */'rrweb')))).record;
|
|
193
|
+
} catch (err) {
|
|
194
|
+
return this.abort();
|
|
195
|
+
}
|
|
176
196
|
|
|
177
197
|
// FULL mode records AND reports from the beginning, while ERROR mode only records (but does not report).
|
|
178
198
|
// ERROR mode will do this until an error is thrown, and then switch into FULL mode.
|
|
@@ -181,12 +201,6 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
181
201
|
// We only report (harvest) in FULL mode
|
|
182
202
|
this.scheduler.startTimer(this.harvestTimeSeconds);
|
|
183
203
|
}
|
|
184
|
-
try {
|
|
185
|
-
// Do not change the webpackChunkName or it will break the webpack nrba-chunking plugin
|
|
186
|
-
recorder = (await Promise.resolve().then(() => _interopRequireWildcard(require( /* webpackChunkName: "recorder" */'rrweb')))).record;
|
|
187
|
-
} catch (err) {
|
|
188
|
-
return this.abort();
|
|
189
|
-
}
|
|
190
204
|
try {
|
|
191
205
|
// Do not change the webpackChunkName or it will break the webpack nrba-chunking plugin
|
|
192
206
|
const {
|
|
@@ -221,6 +235,8 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
221
235
|
getHarvestContents() {
|
|
222
236
|
const agentRuntime = (0, _config.getRuntime)(this.agentIdentifier);
|
|
223
237
|
const info = (0, _config.getInfo)(this.agentIdentifier);
|
|
238
|
+
const firstTimestamp = this.timestamp.event.first || this.timestamp.cycle.first;
|
|
239
|
+
const lastTimestamp = this.timestamp.event.last || this.timestamp.cycle.last;
|
|
224
240
|
return {
|
|
225
241
|
qs: {
|
|
226
242
|
browser_monitoring_key: info.licenseKey,
|
|
@@ -231,11 +247,12 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
231
247
|
...(this.shouldCompress && {
|
|
232
248
|
content_encoding: 'gzip'
|
|
233
249
|
}),
|
|
234
|
-
'replay.firstTimestamp':
|
|
235
|
-
'replay.lastTimestamp':
|
|
236
|
-
'replay.durationMs':
|
|
250
|
+
'replay.firstTimestamp': firstTimestamp,
|
|
251
|
+
'replay.lastTimestamp': lastTimestamp,
|
|
252
|
+
'replay.durationMs': lastTimestamp - firstTimestamp,
|
|
237
253
|
agentVersion: agentRuntime.version,
|
|
238
254
|
session: agentRuntime.session.state.value,
|
|
255
|
+
hasMeta: this.hasMeta,
|
|
239
256
|
hasSnapshot: this.hasSnapshot,
|
|
240
257
|
hasError: this.hasError,
|
|
241
258
|
isFirstChunk: this.isFirstChunk,
|
|
@@ -260,6 +277,7 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
260
277
|
this.events = [];
|
|
261
278
|
this.isFirstChunk = false;
|
|
262
279
|
this.hasSnapshot = false;
|
|
280
|
+
this.hasMeta = false;
|
|
263
281
|
this.hasError = false;
|
|
264
282
|
this.payloadBytesEstimation = 0;
|
|
265
283
|
this.clearTimestamps();
|
|
@@ -271,27 +289,30 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
271
289
|
(0, _console.warn)('Recording library was never imported');
|
|
272
290
|
return this.abort();
|
|
273
291
|
}
|
|
292
|
+
this.clearTimestamps();
|
|
293
|
+
// set the fallbacks as early as possible
|
|
294
|
+
this.setTimestamps();
|
|
274
295
|
this.recording = true;
|
|
275
296
|
const {
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
297
|
+
block_class,
|
|
298
|
+
ignore_class,
|
|
299
|
+
mask_text_class,
|
|
300
|
+
block_selector,
|
|
301
|
+
mask_input_options,
|
|
302
|
+
mask_text_selector,
|
|
303
|
+
mask_all_inputs
|
|
283
304
|
} = (0, _config.getConfigurationValue)(this.agentIdentifier, 'session_replay');
|
|
284
305
|
// set up rrweb configurations for maximum privacy --
|
|
285
306
|
// https://newrelic.atlassian.net/wiki/spaces/O11Y/pages/2792293280/2023+02+28+Browser+-+Session+Replay#Configuration-options
|
|
286
307
|
const stop = recorder({
|
|
287
308
|
emit: this.store.bind(this),
|
|
288
|
-
blockClass,
|
|
289
|
-
ignoreClass,
|
|
290
|
-
maskTextClass,
|
|
291
|
-
blockSelector,
|
|
292
|
-
maskInputOptions,
|
|
293
|
-
maskTextSelector,
|
|
294
|
-
maskAllInputs,
|
|
309
|
+
blockClass: block_class,
|
|
310
|
+
ignoreClass: ignore_class,
|
|
311
|
+
maskTextClass: mask_text_class,
|
|
312
|
+
blockSelector: block_selector,
|
|
313
|
+
maskInputOptions: mask_input_options,
|
|
314
|
+
maskTextSelector: mask_text_selector,
|
|
315
|
+
maskAllInputs: mask_all_inputs,
|
|
295
316
|
checkoutEveryNms: CHECKOUT_MS[this.mode]
|
|
296
317
|
});
|
|
297
318
|
this.stopRecording = () => {
|
|
@@ -302,6 +323,7 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
302
323
|
|
|
303
324
|
/** Store a payload in the buffer (this.events). This should be the callback to the recording lib noticing a mutation */
|
|
304
325
|
store(event, isCheckout) {
|
|
326
|
+
this.setTimestamps(event);
|
|
305
327
|
if (this.blocked) return;
|
|
306
328
|
const eventBytes = (0, _stringify.stringify)(event).length;
|
|
307
329
|
/** The estimated size of the payload after compression */
|
|
@@ -318,8 +340,22 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
318
340
|
// we are still waiting for an error to throw, so keep wiping the buffer over time
|
|
319
341
|
this.clearBuffer();
|
|
320
342
|
}
|
|
321
|
-
|
|
322
|
-
|
|
343
|
+
|
|
344
|
+
// meta event
|
|
345
|
+
if (event.type === 4) {
|
|
346
|
+
this.hasMeta = true;
|
|
347
|
+
this.lastMeta = event;
|
|
348
|
+
}
|
|
349
|
+
// snapshot event
|
|
350
|
+
if (event.type === 2) {
|
|
351
|
+
this.hasSnapshot = true;
|
|
352
|
+
// small chance that the meta event got separated from its matching snapshot across payload harvests
|
|
353
|
+
// it needs to precede the snapshot, so shove it in first.
|
|
354
|
+
if (!this.hasMeta) {
|
|
355
|
+
this.events.push(this.lastMeta);
|
|
356
|
+
this.hasMeta = true;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
323
359
|
this.events.push(event);
|
|
324
360
|
this.payloadBytesEstimation += eventBytes;
|
|
325
361
|
|
|
@@ -336,15 +372,25 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
336
372
|
if (!recorder) return;
|
|
337
373
|
recorder.takeFullSnapshot();
|
|
338
374
|
}
|
|
339
|
-
setTimestamps(
|
|
340
|
-
if
|
|
341
|
-
|
|
342
|
-
this.timestamp.
|
|
375
|
+
setTimestamps(event) {
|
|
376
|
+
// fallbacks if timestamps cannot be derived from rrweb events
|
|
377
|
+
this.timestamp.cycle.last = (0, _config.getRuntime)(this.agentIdentifier).offset + _runtime.globalScope.performance.now();
|
|
378
|
+
if (!this.timestamp.cycle.first) this.timestamp.cycle.first = this.timestamp.cycle.last;
|
|
379
|
+
// timestamps based on rrweb events
|
|
380
|
+
if (!event || !event.timestamp) return;
|
|
381
|
+
if (!this.timestamp.event.first) this.timestamp.event.first = event.timestamp;
|
|
382
|
+
this.timestamp.event.last = event.timestamp;
|
|
343
383
|
}
|
|
344
384
|
clearTimestamps() {
|
|
345
385
|
this.timestamp = {
|
|
346
|
-
|
|
347
|
-
|
|
386
|
+
event: {
|
|
387
|
+
first: undefined,
|
|
388
|
+
last: undefined
|
|
389
|
+
},
|
|
390
|
+
cycle: {
|
|
391
|
+
first: undefined,
|
|
392
|
+
last: undefined
|
|
393
|
+
}
|
|
348
394
|
};
|
|
349
395
|
}
|
|
350
396
|
|
|
@@ -492,9 +492,12 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
492
492
|
// if PO isn't supported, this checks resourcetiming buffer every harvest.
|
|
493
493
|
this.storeResources(window.performance.getEntriesByType('resource'));
|
|
494
494
|
}
|
|
495
|
+
let earliestTimeStamp = Infinity;
|
|
495
496
|
const stns = Object.entries(this.trace).flatMap(_ref3 => {
|
|
496
497
|
let [name, listOfSTNodes] = _ref3;
|
|
497
498
|
// basically take the "this.trace" map-obj and concat all the list-type values
|
|
499
|
+
const oldestNodeTS = listOfSTNodes.reduce((acc, next) => !acc || next.s < acc ? next.s : acc, undefined);
|
|
500
|
+
if (oldestNodeTS < earliestTimeStamp) earliestTimeStamp = oldestNodeTS;
|
|
498
501
|
if (!(name in toAggregate)) return listOfSTNodes;
|
|
499
502
|
// Special processing for event nodes dealing with user inputs:
|
|
500
503
|
const reindexByOriginFn = this.smearEvtsByOrigin(name);
|
|
@@ -509,8 +512,17 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
509
512
|
this.nodeCount = 0;
|
|
510
513
|
return {
|
|
511
514
|
qs: {
|
|
512
|
-
st:
|
|
515
|
+
st: this.agentRuntime.offset,
|
|
516
|
+
/** hr === "hasReplay" in NR1, standalone is always checked and processed before harvesting
|
|
517
|
+
* so a race condition between ST and SR states should not be a concern if implemented here */
|
|
518
|
+
hr: Number(!this.isStandalone),
|
|
519
|
+
/** fts === "firstTimestamp" in NR1, indicates what the earliest NODE timestamp was
|
|
520
|
+
* so that blob parsing doesn't need to happen to support UI/API functions */
|
|
521
|
+
fts: this.agentRuntime.offset + earliestTimeStamp,
|
|
522
|
+
/** n === "nodeCount" in NR1, a count of nodes in the ST payload, so that blob parsing doesn't need to happen to support UI/API functions */
|
|
523
|
+
n: stns.length // node count
|
|
513
524
|
},
|
|
525
|
+
|
|
514
526
|
body: {
|
|
515
527
|
res: stns
|
|
516
528
|
}
|
|
@@ -10,7 +10,6 @@ var _denyList = require("../../../common/deny-list/deny-list");
|
|
|
10
10
|
var _mapOwn = require("../../../common/util/map-own");
|
|
11
11
|
var _navTiming = require("../../../common/timing/nav-timing");
|
|
12
12
|
var _uniqueId = require("../../../common/ids/unique-id");
|
|
13
|
-
var _paintMetrics = require("../../../common/metrics/paint-metrics");
|
|
14
13
|
var _interaction = require("./interaction");
|
|
15
14
|
var _config = require("../../../common/config/config");
|
|
16
15
|
var _eventListenerOpts = require("../../../common/event-listener/event-listener-opts");
|
|
@@ -20,6 +19,8 @@ var _contextualEe = require("../../../common/event-emitter/contextual-ee");
|
|
|
20
19
|
var CONSTANTS = _interopRequireWildcard(require("../constants"));
|
|
21
20
|
var _features = require("../../../loaders/features/features");
|
|
22
21
|
var _aggregateBase = require("../../utils/aggregate-base");
|
|
22
|
+
var _firstContentfulPaint = require("../../../common/vitals/first-contentful-paint");
|
|
23
|
+
var _firstPaint = require("../../../common/vitals/first-paint");
|
|
23
24
|
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); }
|
|
24
25
|
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; }
|
|
25
26
|
/*
|
|
@@ -662,8 +663,8 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
662
663
|
// assign unique id, this is serialized and used to link interactions with errors
|
|
663
664
|
interaction.root.attrs.id = (0, _uniqueId.generateUuid)();
|
|
664
665
|
if (interaction.root.attrs.trigger === 'initialPageLoad') {
|
|
665
|
-
interaction.root.attrs.firstPaint =
|
|
666
|
-
interaction.root.attrs.firstContentfulPaint =
|
|
666
|
+
interaction.root.attrs.firstPaint = _firstPaint.firstPaint.current.value;
|
|
667
|
+
interaction.root.attrs.firstContentfulPaint = _firstContentfulPaint.firstContentfulPaint.current.value;
|
|
667
668
|
}
|
|
668
669
|
baseEE.emit('interactionSaved', [interaction]);
|
|
669
670
|
state.interactionsToHarvest.push(interaction);
|
|
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.Agent = void 0;
|
|
7
|
+
require("./configure/public-path.npm");
|
|
7
8
|
var _agentBase = require("./agent-base");
|
|
8
9
|
var _enabledFeatures = require("./features/enabled-features");
|
|
9
10
|
var _configure = require("./configure/configure");
|
|
@@ -17,6 +18,8 @@ var _config = require("../common/config/config");
|
|
|
17
18
|
var _console = require("../common/util/console");
|
|
18
19
|
var _stringify = require("../common/util/stringify");
|
|
19
20
|
var _runtime = require("../common/constants/runtime");
|
|
21
|
+
// important side effects
|
|
22
|
+
|
|
20
23
|
// loader files
|
|
21
24
|
|
|
22
25
|
// required features
|
|
@@ -132,6 +132,8 @@ function setAPI(agentIdentifier, forceDrain) {
|
|
|
132
132
|
};
|
|
133
133
|
apiInterface.start = features => {
|
|
134
134
|
try {
|
|
135
|
+
const smTag = !features ? 'undefined' : 'defined';
|
|
136
|
+
(0, _handle.handle)(_constants.SUPPORTABILITY_METRIC_CHANNEL, ["API/start/".concat(smTag, "/called")], undefined, _features.FEATURE_NAMES.metrics, instanceEE);
|
|
135
137
|
const featNames = Object.values(_features.FEATURE_NAMES);
|
|
136
138
|
if (features === undefined) features = featNames;else {
|
|
137
139
|
features = Array.isArray(features) && features.length ? features : [features];
|
|
@@ -18,7 +18,6 @@ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj &&
|
|
|
18
18
|
function setAPI(agentIdentifier) {
|
|
19
19
|
var instanceEE = _contextualEe.ee.get(agentIdentifier);
|
|
20
20
|
var cycle = 0;
|
|
21
|
-
var scheme = (0, _config.getConfigurationValue)(agentIdentifier, 'ssl') === false ? 'http' : 'https';
|
|
22
21
|
var api = {
|
|
23
22
|
finished: (0, _invoke.single)(finished),
|
|
24
23
|
setErrorHandler,
|
|
@@ -74,7 +73,10 @@ function setAPI(agentIdentifier) {
|
|
|
74
73
|
cycle += 1;
|
|
75
74
|
const agentInfo = (0, _config.getInfo)(agentIdentifier);
|
|
76
75
|
if (!agentInfo.beacon) return;
|
|
77
|
-
|
|
76
|
+
const agentInit = (0, _config.getConfiguration)(agentIdentifier);
|
|
77
|
+
const scheme = agentInit.ssl === false ? 'http' : 'https';
|
|
78
|
+
const beacon = agentInit.proxy.beacon || agentInfo.beacon;
|
|
79
|
+
let url = "".concat(scheme, "://").concat(beacon, "/1/").concat(agentInfo.licenseKey);
|
|
78
80
|
url += '?a=' + agentInfo.applicationID + '&';
|
|
79
81
|
url += 't=' + requestName + '&';
|
|
80
82
|
url += 'qt=' + ~~queueTime + '&';
|
|
@@ -13,6 +13,7 @@ var _instrument5 = require("../features/ajax/instrument");
|
|
|
13
13
|
var _instrument6 = require("../features/session_trace/instrument");
|
|
14
14
|
var _instrument7 = require("../features/spa/instrument");
|
|
15
15
|
var _instrument8 = require("../features/page_action/instrument");
|
|
16
|
+
var _instrument9 = require("../features/session_replay/instrument");
|
|
16
17
|
/**
|
|
17
18
|
* An agent class with all feature modules available. Features may be disabled and enabled via runtime configuration.
|
|
18
19
|
* The BrowserAgent class is the most convenient and reliable option for most use cases.
|
|
@@ -21,7 +22,7 @@ class BrowserAgent extends _agent.Agent {
|
|
|
21
22
|
constructor(args) {
|
|
22
23
|
super({
|
|
23
24
|
...args,
|
|
24
|
-
features: [_instrument5.Instrument, _instrument.Instrument, _instrument2.Instrument, _instrument6.Instrument, _instrument3.Instrument, _instrument8.Instrument, _instrument4.Instrument, _instrument7.Instrument],
|
|
25
|
+
features: [_instrument5.Instrument, _instrument.Instrument, _instrument2.Instrument, _instrument6.Instrument, _instrument3.Instrument, _instrument8.Instrument, _instrument4.Instrument, _instrument7.Instrument, _instrument9.Instrument],
|
|
25
26
|
loaderType: 'browser-agent'
|
|
26
27
|
});
|
|
27
28
|
}
|
|
@@ -9,6 +9,9 @@ var _nreum = require("../../common/window/nreum");
|
|
|
9
9
|
var _config = require("../../common/config/config");
|
|
10
10
|
var _featureFlags = require("../../common/util/feature-flags");
|
|
11
11
|
var _runtime = require("../../common/constants/runtime");
|
|
12
|
+
var _publicPath = require("./public-path");
|
|
13
|
+
let alreadySetOnce = false; // the configure() function can run multiple times in agent lifecycle
|
|
14
|
+
|
|
12
15
|
function configure(agentIdentifier) {
|
|
13
16
|
let opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
14
17
|
let loaderType = arguments.length > 2 ? arguments[2] : undefined;
|
|
@@ -40,7 +43,16 @@ function configure(agentIdentifier) {
|
|
|
40
43
|
}
|
|
41
44
|
(0, _config.setInfo)(agentIdentifier, info);
|
|
42
45
|
const updatedInit = (0, _config.getConfiguration)(agentIdentifier);
|
|
43
|
-
|
|
46
|
+
const internalTrafficList = [info.beacon, info.errorBeacon];
|
|
47
|
+
if (!alreadySetOnce) {
|
|
48
|
+
alreadySetOnce = true;
|
|
49
|
+
if (updatedInit.proxy.assets) {
|
|
50
|
+
(0, _publicPath.redefinePublicPath)(updatedInit.proxy.assets + '/'); // much like the info.beacon & init.proxy.beacon, this input should not end in a slash, but one is needed for webpack concat
|
|
51
|
+
internalTrafficList.push(updatedInit.proxy.assets);
|
|
52
|
+
}
|
|
53
|
+
if (updatedInit.proxy.beacon) internalTrafficList.push(updatedInit.proxy.beacon);
|
|
54
|
+
}
|
|
55
|
+
runtime.denyList = [...(updatedInit.ajax.deny_list || []), ...(updatedInit.ajax.block_internal ? internalTrafficList : [])];
|
|
44
56
|
(0, _config.setRuntime)(agentIdentifier, runtime);
|
|
45
57
|
(0, _api.setTopLevelCallers)();
|
|
46
58
|
const api = (0, _api.setAPI)(agentIdentifier, forceDrain);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.redefinePublicPath = void 0;
|
|
7
|
+
// Set the default CDN or remote for fetching the assets; NPM shouldn't change this var.
|
|
8
|
+
|
|
9
|
+
const redefinePublicPath = url => {
|
|
10
|
+
// There's no URL validation here, so caller should check arg if need be.
|
|
11
|
+
__webpack_public_path__ = url; // eslint-disable-line
|
|
12
|
+
};
|
|
13
|
+
exports.redefinePublicPath = redefinePublicPath;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.redefinePublicPath = void 0;
|
|
7
|
+
const redefinePublicPath = () => {
|
|
8
|
+
// We don't support setting public path in webpack via NPM build.
|
|
9
|
+
};
|
|
10
|
+
exports.redefinePublicPath = redefinePublicPath;
|
package/dist/esm/cdn/pro.js
CHANGED
|
@@ -10,8 +10,9 @@ import { Instrument as InstrumentMetrics } from '../features/metrics/instrument'
|
|
|
10
10
|
import { Instrument as InstrumentErrors } from '../features/jserrors/instrument';
|
|
11
11
|
import { Instrument as InstrumentXhr } from '../features/ajax/instrument';
|
|
12
12
|
import { Instrument as InstrumentSessionTrace } from '../features/session_trace/instrument';
|
|
13
|
+
import { Instrument as InstrumentSessionReplay } from '../features/session_replay/instrument';
|
|
13
14
|
import { Instrument as InstrumentPageAction } from '../features/page_action/instrument';
|
|
14
15
|
new Agent({
|
|
15
|
-
features: [InstrumentPageViewEvent, InstrumentPageViewTiming, InstrumentSessionTrace, InstrumentXhr, InstrumentMetrics, InstrumentPageAction, InstrumentErrors],
|
|
16
|
+
features: [InstrumentPageViewEvent, InstrumentPageViewTiming, InstrumentSessionTrace, InstrumentSessionReplay, InstrumentXhr, InstrumentMetrics, InstrumentPageAction, InstrumentErrors],
|
|
16
17
|
loaderType: 'pro'
|
|
17
18
|
});
|
package/dist/esm/cdn/spa.js
CHANGED
|
@@ -9,9 +9,10 @@ import { Instrument as InstrumentMetrics } from '../features/metrics/instrument'
|
|
|
9
9
|
import { Instrument as InstrumentErrors } from '../features/jserrors/instrument';
|
|
10
10
|
import { Instrument as InstrumentXhr } from '../features/ajax/instrument';
|
|
11
11
|
import { Instrument as InstrumentSessionTrace } from '../features/session_trace/instrument';
|
|
12
|
+
import { Instrument as InstrumentSessionReplay } from '../features/session_replay/instrument';
|
|
12
13
|
import { Instrument as InstrumentSpa } from '../features/spa/instrument';
|
|
13
14
|
import { Instrument as InstrumentPageAction } from '../features/page_action/instrument';
|
|
14
15
|
new Agent({
|
|
15
|
-
features: [InstrumentXhr, InstrumentPageViewEvent, InstrumentPageViewTiming, InstrumentSessionTrace, InstrumentMetrics, InstrumentPageAction, InstrumentErrors, InstrumentSpa],
|
|
16
|
+
features: [InstrumentXhr, InstrumentPageViewEvent, InstrumentPageViewTiming, InstrumentSessionTrace, InstrumentSessionReplay, InstrumentMetrics, InstrumentPageAction, InstrumentErrors, InstrumentSpa],
|
|
16
17
|
loaderType: 'spa'
|
|
17
18
|
});
|
|
@@ -3,12 +3,18 @@ import { gosNREUMInitializedAgents } from '../../window/nreum';
|
|
|
3
3
|
import { getModeledObject } from './configurable';
|
|
4
4
|
const model = () => {
|
|
5
5
|
const hiddenState = {
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
block_selector: '[data-nr-block]',
|
|
7
|
+
mask_input_options: {
|
|
8
8
|
password: true
|
|
9
9
|
}
|
|
10
10
|
};
|
|
11
11
|
return {
|
|
12
|
+
proxy: {
|
|
13
|
+
assets: undefined,
|
|
14
|
+
// if this value is set, it will be used to overwrite the webpack asset path used to fetch assets
|
|
15
|
+
beacon: undefined // likewise for the url to which we send analytics
|
|
16
|
+
},
|
|
17
|
+
|
|
12
18
|
privacy: {
|
|
13
19
|
cookies_enabled: true
|
|
14
20
|
},
|
|
@@ -72,35 +78,37 @@ const model = () => {
|
|
|
72
78
|
autoStart: true,
|
|
73
79
|
enabled: false,
|
|
74
80
|
harvestTimeSeconds: 60,
|
|
75
|
-
|
|
76
|
-
|
|
81
|
+
sampling_rate: 50,
|
|
82
|
+
// float from 0 - 100
|
|
83
|
+
error_sampling_rate: 50,
|
|
84
|
+
// float from 0 - 100
|
|
77
85
|
// recording config settings
|
|
78
|
-
|
|
79
|
-
|
|
86
|
+
mask_text_selector: '*',
|
|
87
|
+
mask_all_inputs: true,
|
|
80
88
|
// these properties only have getters because they are enforcable constants and should error if someone tries to override them
|
|
81
|
-
get
|
|
89
|
+
get block_class() {
|
|
82
90
|
return 'nr-block';
|
|
83
91
|
},
|
|
84
|
-
get
|
|
92
|
+
get ignore_class() {
|
|
85
93
|
return 'nr-ignore';
|
|
86
94
|
},
|
|
87
|
-
get
|
|
95
|
+
get mask_text_class() {
|
|
88
96
|
return 'nr-mask';
|
|
89
97
|
},
|
|
90
98
|
// props with a getter and setter are used to extend enforcable constants with customer input
|
|
91
99
|
// we must preserve data-nr-block no matter what else the customer sets
|
|
92
|
-
get
|
|
93
|
-
return hiddenState.
|
|
100
|
+
get block_selector() {
|
|
101
|
+
return hiddenState.block_selector;
|
|
94
102
|
},
|
|
95
|
-
set
|
|
96
|
-
hiddenState.
|
|
103
|
+
set block_selector(val) {
|
|
104
|
+
hiddenState.block_selector += ",".concat(val);
|
|
97
105
|
},
|
|
98
106
|
// password: must always be present and true no matter what customer sets
|
|
99
|
-
get
|
|
100
|
-
return hiddenState.
|
|
107
|
+
get mask_input_options() {
|
|
108
|
+
return hiddenState.mask_input_options;
|
|
101
109
|
},
|
|
102
|
-
set
|
|
103
|
-
hiddenState.
|
|
110
|
+
set mask_input_options(val) {
|
|
111
|
+
hiddenState.mask_input_options = {
|
|
104
112
|
...val,
|
|
105
113
|
password: true
|
|
106
114
|
};
|
|
@@ -15,8 +15,9 @@ export const isBrowserScope = typeof window !== 'undefined' && !!window.document
|
|
|
15
15
|
*/
|
|
16
16
|
export const isWorkerScope = typeof WorkerGlobalScope !== 'undefined' && (typeof self !== 'undefined' && self instanceof WorkerGlobalScope && self.navigator instanceof WorkerNavigator || typeof globalThis !== 'undefined' && globalThis instanceof WorkerGlobalScope && globalThis.navigator instanceof WorkerNavigator);
|
|
17
17
|
export const globalScope = isBrowserScope ? window : typeof WorkerGlobalScope !== 'undefined' && (typeof self !== 'undefined' && self instanceof WorkerGlobalScope && self || typeof globalThis !== 'undefined' && globalThis instanceof WorkerGlobalScope && globalThis);
|
|
18
|
+
export const initiallyHidden = Boolean(globalScope?.document?.visibilityState === 'hidden');
|
|
18
19
|
export const initialLocation = '' + globalScope?.location;
|
|
19
|
-
export const isiOS = /iPad|iPhone|iPod/.test(navigator
|
|
20
|
+
export const isiOS = /iPad|iPhone|iPod/.test(globalScope.navigator?.userAgent);
|
|
20
21
|
|
|
21
22
|
/**
|
|
22
23
|
* Shared Web Workers introduced in iOS 16.0+ and n/a in 15.6-
|
|
@@ -27,7 +28,7 @@ export const isiOS = /iPad|iPhone|iPod/.test(navigator.userAgent);
|
|
|
27
28
|
*/
|
|
28
29
|
export const iOSBelow16 = isiOS && typeof SharedWorker === 'undefined';
|
|
29
30
|
export const ffVersion = (() => {
|
|
30
|
-
const match = navigator
|
|
31
|
+
const match = globalScope.navigator?.userAgent?.match(/Firefox[/\s](\d+\.\d+)/);
|
|
31
32
|
if (Array.isArray(match) && match.length >= 2) {
|
|
32
33
|
return +match[1];
|
|
33
34
|
}
|
|
@@ -35,4 +36,5 @@ export const ffVersion = (() => {
|
|
|
35
36
|
})();
|
|
36
37
|
export const isIE = Boolean(isBrowserScope && window.document.documentMode); // deprecated property that only works in IE
|
|
37
38
|
|
|
38
|
-
export const supportsSendBeacon = !!navigator
|
|
39
|
+
export const supportsSendBeacon = !!globalScope.navigator?.sendBeacon;
|
|
40
|
+
export const offset = Math.floor(globalScope?.performance?.timeOrigin || globalScope?.performance?.timing?.navigationStart || Date.now());
|
|
@@ -7,7 +7,7 @@ import { obj as encodeObj, param as encodeParam } from '../url/encode';
|
|
|
7
7
|
import { stringify } from '../util/stringify';
|
|
8
8
|
import * as submitData from '../util/submit-data';
|
|
9
9
|
import { getLocation } from '../url/location';
|
|
10
|
-
import { getInfo, getConfigurationValue, getRuntime } from '../config/config';
|
|
10
|
+
import { getInfo, getConfigurationValue, getRuntime, getConfiguration } from '../config/config';
|
|
11
11
|
import { cleanURL } from '../url/clean-url';
|
|
12
12
|
import { now } from '../timing/now';
|
|
13
13
|
import { eventListenerOpts } from '../event-listener/event-listener-opts';
|
|
@@ -32,7 +32,6 @@ export class Harvest extends SharedContext {
|
|
|
32
32
|
|
|
33
33
|
this.tooManyRequestsDelay = getConfigurationValue(this.sharedContext.agentIdentifier, 'harvest.tooManyRequestsDelay') || 60;
|
|
34
34
|
this.obfuscator = new Obfuscator(this.sharedContext);
|
|
35
|
-
this.getScheme = () => getConfigurationValue(this.sharedContext.agentIdentifier, 'ssl') === false ? 'http' : 'https';
|
|
36
35
|
this._events = {};
|
|
37
36
|
}
|
|
38
37
|
|
|
@@ -123,10 +122,13 @@ export class Harvest extends SharedContext {
|
|
|
123
122
|
}
|
|
124
123
|
return false;
|
|
125
124
|
}
|
|
125
|
+
const init = getConfiguration(this.sharedContext.agentIdentifier);
|
|
126
|
+
const protocol = init.ssl === false ? 'http' : 'https';
|
|
127
|
+
const perceviedBeacon = init.proxy.beacon || info.errorBeacon;
|
|
126
128
|
const endpointURLPart = endpoint !== 'rum' ? "/".concat(endpoint) : '';
|
|
127
|
-
let url = "".concat(
|
|
129
|
+
let url = "".concat(protocol, "://").concat(perceviedBeacon).concat(endpointURLPart, "/1/").concat(info.licenseKey);
|
|
128
130
|
if (customUrl) url = customUrl;
|
|
129
|
-
if (raw) url = "".concat(
|
|
131
|
+
if (raw) url = "".concat(protocol, "://").concat(perceviedBeacon, "/").concat(endpoint);
|
|
130
132
|
const baseParams = !raw && includeBaseParams ? this.baseQueryString() : '';
|
|
131
133
|
let payloadParams = encodeObj(qs, agentRuntime.maxBytes);
|
|
132
134
|
if (!submitMethod) {
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export const VITAL_NAMES = {
|
|
2
|
+
FIRST_PAINT: 'fp',
|
|
3
|
+
FIRST_CONTENTFUL_PAINT: 'fcp',
|
|
4
|
+
FIRST_INPUT_DELAY: 'fi',
|
|
5
|
+
LARGEST_CONTENTFUL_PAINT: 'lcp',
|
|
6
|
+
CUMULATIVE_LAYOUT_SHIFT: 'cls',
|
|
7
|
+
INTERACTION_TO_NEXT_PAINT: 'inp',
|
|
8
|
+
LONG_TASK: 'lt',
|
|
9
|
+
TIME_TO_FIRST_BYTE: 'ttfb'
|
|
10
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { onCLS } from 'web-vitals';
|
|
2
|
+
import { VITAL_NAMES } from './constants';
|
|
3
|
+
import { VitalMetric } from './vital-metric';
|
|
4
|
+
import { isBrowserScope } from '../constants/runtime';
|
|
5
|
+
export const cumulativeLayoutShift = new VitalMetric(VITAL_NAMES.CUMULATIVE_LAYOUT_SHIFT, x => x);
|
|
6
|
+
if (isBrowserScope) {
|
|
7
|
+
onCLS(_ref => {
|
|
8
|
+
let {
|
|
9
|
+
value,
|
|
10
|
+
entries
|
|
11
|
+
} = _ref;
|
|
12
|
+
if (cumulativeLayoutShift.roundingMethod(value) === cumulativeLayoutShift.current.value) return;
|
|
13
|
+
cumulativeLayoutShift.update({
|
|
14
|
+
value,
|
|
15
|
+
entries
|
|
16
|
+
});
|
|
17
|
+
}, {
|
|
18
|
+
reportAllChanges: true
|
|
19
|
+
});
|
|
20
|
+
}
|