@newrelic/browser-agent 1.232.0 → 1.233.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/dist/cjs/cdn/polyfills.js +5 -2
- package/dist/cjs/common/config/state/configurable.js +15 -26
- package/dist/cjs/common/config/state/info.js +1 -1
- package/dist/cjs/common/config/state/init.js +101 -56
- package/dist/cjs/common/config/state/loader-config.js +1 -1
- package/dist/cjs/common/config/state/runtime.js +1 -5
- package/dist/cjs/common/constants/env.cdn.js +1 -1
- package/dist/cjs/common/constants/env.npm.js +1 -1
- package/dist/cjs/common/drain/drain.js +1 -1
- package/dist/cjs/common/harvest/harvest-scheduler.js +30 -10
- package/dist/cjs/common/harvest/harvest.js +119 -55
- package/dist/cjs/common/session/session-entity.js +35 -22
- package/dist/cjs/common/session/session-entity.test.js +73 -49
- package/dist/cjs/common/timer/interaction-timer.js +9 -12
- package/dist/cjs/common/url/canonicalize-url.js +32 -0
- package/dist/cjs/common/url/canonicalize-url.test.js +42 -0
- package/dist/cjs/common/url/clean-url.js +10 -3
- package/dist/cjs/common/url/protocol.test.js +0 -1
- package/dist/cjs/common/util/feature-flags.js +2 -1
- package/dist/cjs/common/util/global-scope.js +4 -2
- package/dist/cjs/common/util/submit-data.js +57 -18
- package/dist/cjs/common/wrap/wrap-fetch.js +1 -3
- package/dist/cjs/common/wrap/wrap-function.js +1 -3
- package/dist/cjs/common/wrap/wrap-promise.js +1 -1
- package/dist/cjs/features/ajax/aggregate/index.js +2 -2
- package/dist/cjs/features/ajax/instrument/index.js +1 -1
- package/dist/cjs/features/jserrors/aggregate/canonical-function-name.js +12 -4
- package/dist/cjs/features/jserrors/aggregate/compute-stack-trace.js +93 -10
- package/dist/cjs/features/jserrors/aggregate/compute-stack-trace.test.js +164 -38
- package/dist/cjs/features/jserrors/aggregate/index.js +29 -48
- package/dist/cjs/features/jserrors/instrument/index.js +0 -2
- package/dist/cjs/features/metrics/aggregate/framework-detection.js +67 -0
- package/dist/cjs/features/metrics/aggregate/framework-detection.test.js +137 -0
- package/dist/cjs/features/metrics/aggregate/index.js +7 -3
- package/dist/cjs/features/metrics/aggregate/polyfill-detection.es5.js +14 -0
- package/dist/cjs/features/metrics/aggregate/polyfill-detection.es5.test.js +17 -0
- package/dist/cjs/features/metrics/aggregate/polyfill-detection.js +53 -0
- package/dist/cjs/features/metrics/aggregate/polyfill-detection.test.js +165 -0
- package/dist/cjs/features/page_action/aggregate/index.js +2 -2
- package/dist/cjs/features/page_view_event/aggregate/index.js +6 -3
- package/dist/cjs/features/page_view_timing/aggregate/index.js +2 -2
- package/dist/cjs/features/session_replay/aggregate/index.js +333 -0
- package/dist/cjs/features/session_replay/constants.js +9 -0
- package/dist/cjs/features/session_replay/index.js +12 -0
- package/dist/cjs/features/session_replay/instrument/index.js +29 -0
- package/dist/cjs/features/session_trace/aggregate/index.js +163 -164
- package/dist/cjs/features/session_trace/constants.js +2 -9
- package/dist/cjs/features/session_trace/instrument/index.js +24 -66
- package/dist/cjs/features/spa/aggregate/index.js +2 -2
- package/dist/cjs/features/utils/agent-session.js +1 -2
- package/dist/cjs/features/utils/aggregate-base.js +64 -0
- package/dist/cjs/features/utils/feature-base.js +0 -31
- package/dist/cjs/features/utils/handler-cache.js +3 -4
- package/dist/cjs/features/utils/instrument-base.js +42 -10
- package/dist/cjs/features/utils/{lazy-loader.js → lazy-feature-loader.js} +4 -2
- package/dist/cjs/loaders/agent.js +1 -1
- package/dist/cjs/loaders/api/apiAsync.js +3 -1
- package/dist/cjs/loaders/configure/configure.js +3 -3
- package/dist/cjs/loaders/features/featureDependencies.js +0 -12
- package/dist/cjs/loaders/features/features.js +3 -1
- package/dist/cjs/loaders/micro-agent.js +6 -6
- package/dist/esm/cdn/polyfills.js +5 -2
- package/dist/esm/common/config/state/configurable.js +14 -24
- package/dist/esm/common/config/state/info.js +2 -2
- package/dist/esm/common/config/state/init.js +102 -57
- package/dist/esm/common/config/state/loader-config.js +2 -2
- package/dist/esm/common/config/state/runtime.js +2 -4
- package/dist/esm/common/constants/env.cdn.js +1 -1
- package/dist/esm/common/constants/env.npm.js +1 -1
- package/dist/esm/common/drain/drain.js +1 -1
- package/dist/esm/common/harvest/harvest-scheduler.js +30 -10
- package/dist/esm/common/harvest/harvest.js +121 -56
- package/dist/esm/common/session/session-entity.js +35 -22
- package/dist/esm/common/session/session-entity.test.js +73 -49
- package/dist/esm/common/timer/interaction-timer.js +9 -12
- package/dist/esm/common/url/canonicalize-url.js +27 -0
- package/dist/esm/common/url/canonicalize-url.test.js +38 -0
- package/dist/esm/common/url/clean-url.js +10 -3
- package/dist/esm/common/url/protocol.test.js +0 -1
- package/dist/esm/common/util/feature-flags.js +2 -1
- package/dist/esm/common/util/global-scope.js +1 -0
- package/dist/esm/common/util/submit-data.js +57 -18
- package/dist/esm/common/wrap/wrap-fetch.js +1 -2
- package/dist/esm/common/wrap/wrap-function.js +1 -2
- package/dist/esm/common/wrap/wrap-promise.js +1 -1
- package/dist/esm/features/ajax/aggregate/index.js +2 -2
- package/dist/esm/features/ajax/instrument/index.js +1 -1
- package/dist/esm/features/jserrors/aggregate/canonical-function-name.js +12 -4
- package/dist/esm/features/jserrors/aggregate/compute-stack-trace.js +93 -10
- package/dist/esm/features/jserrors/aggregate/compute-stack-trace.test.js +149 -25
- package/dist/esm/features/jserrors/aggregate/index.js +30 -48
- package/dist/esm/features/jserrors/instrument/index.js +0 -1
- package/dist/esm/features/metrics/aggregate/framework-detection.js +61 -0
- package/dist/esm/features/metrics/aggregate/framework-detection.test.js +133 -0
- package/dist/esm/features/metrics/aggregate/index.js +7 -3
- package/dist/esm/features/metrics/aggregate/polyfill-detection.es5.js +8 -0
- package/dist/esm/features/metrics/aggregate/polyfill-detection.es5.test.js +15 -0
- package/dist/esm/features/metrics/aggregate/polyfill-detection.js +47 -0
- package/dist/esm/features/metrics/aggregate/polyfill-detection.test.js +163 -0
- package/dist/esm/features/page_action/aggregate/index.js +2 -2
- package/dist/esm/features/page_view_event/aggregate/index.js +6 -3
- package/dist/esm/features/page_view_timing/aggregate/index.js +2 -2
- package/dist/esm/features/session_replay/aggregate/index.js +327 -0
- package/dist/esm/features/session_replay/constants.js +2 -0
- package/dist/esm/features/session_replay/index.js +12 -0
- package/dist/esm/features/session_replay/instrument/index.js +21 -0
- package/dist/esm/features/session_trace/aggregate/index.js +163 -163
- package/dist/esm/features/session_trace/constants.js +1 -5
- package/dist/esm/features/session_trace/instrument/index.js +24 -66
- package/dist/esm/features/spa/aggregate/index.js +2 -2
- package/dist/esm/features/utils/agent-session.js +1 -2
- package/dist/esm/features/utils/aggregate-base.js +57 -0
- package/dist/esm/features/utils/feature-base.js +1 -32
- package/dist/esm/features/utils/handler-cache.js +3 -4
- package/dist/esm/features/utils/instrument-base.js +42 -10
- package/dist/esm/features/utils/{lazy-loader.js → lazy-feature-loader.js} +3 -1
- package/dist/esm/loaders/agent.js +1 -1
- package/dist/esm/loaders/api/apiAsync.js +3 -1
- package/dist/esm/loaders/configure/configure.js +3 -3
- package/dist/esm/loaders/features/featureDependencies.js +0 -11
- package/dist/esm/loaders/features/features.js +3 -1
- package/dist/esm/loaders/micro-agent.js +6 -6
- package/dist/types/common/config/state/configurable.d.ts +1 -3
- package/dist/types/common/config/state/configurable.d.ts.map +1 -1
- package/dist/types/common/config/state/init.d.ts.map +1 -1
- package/dist/types/common/config/state/runtime.d.ts.map +1 -1
- package/dist/types/common/harvest/harvest-scheduler.d.ts.map +1 -1
- package/dist/types/common/harvest/harvest.d.ts +37 -34
- package/dist/types/common/harvest/harvest.d.ts.map +1 -1
- package/dist/types/common/session/session-entity.d.ts +6 -3
- package/dist/types/common/session/session-entity.d.ts.map +1 -1
- package/dist/types/common/timer/interaction-timer.d.ts +2 -1
- package/dist/types/common/timer/interaction-timer.d.ts.map +1 -1
- package/dist/types/common/url/canonicalize-url.d.ts +9 -0
- package/dist/types/common/url/canonicalize-url.d.ts.map +1 -0
- package/dist/types/common/url/clean-url.d.ts +7 -1
- package/dist/types/common/url/clean-url.d.ts.map +1 -1
- package/dist/types/common/util/feature-flags.d.ts.map +1 -1
- package/dist/types/common/util/global-scope.d.ts +1 -0
- package/dist/types/common/util/global-scope.d.ts.map +1 -1
- package/dist/types/common/util/submit-data.d.ts +40 -14
- package/dist/types/common/util/submit-data.d.ts.map +1 -1
- package/dist/types/common/wrap/wrap-fetch.d.ts.map +1 -1
- package/dist/types/common/wrap/wrap-function.d.ts.map +1 -1
- package/dist/types/features/ajax/aggregate/index.d.ts +2 -2
- package/dist/types/features/ajax/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/jserrors/aggregate/canonical-function-name.d.ts +8 -1
- package/dist/types/features/jserrors/aggregate/canonical-function-name.d.ts.map +1 -1
- package/dist/types/features/jserrors/aggregate/compute-stack-trace.d.ts +48 -19
- package/dist/types/features/jserrors/aggregate/compute-stack-trace.d.ts.map +1 -1
- package/dist/types/features/jserrors/aggregate/index.d.ts +14 -5
- package/dist/types/features/jserrors/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/jserrors/instrument/index.d.ts.map +1 -1
- package/dist/types/features/metrics/aggregate/framework-detection.d.ts.map +1 -0
- package/dist/types/features/metrics/aggregate/index.d.ts +2 -2
- package/dist/types/features/metrics/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/metrics/aggregate/polyfill-detection.d.ts +6 -0
- package/dist/types/features/metrics/aggregate/polyfill-detection.d.ts.map +1 -0
- package/dist/types/features/metrics/aggregate/polyfill-detection.es5.d.ts +7 -0
- package/dist/types/features/metrics/aggregate/polyfill-detection.es5.d.ts.map +1 -0
- package/dist/types/features/page_action/aggregate/index.d.ts +3 -3
- package/dist/types/features/page_action/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/page_view_event/aggregate/index.d.ts +2 -2
- package/dist/types/features/page_view_event/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/page_view_timing/aggregate/index.d.ts +2 -2
- package/dist/types/features/page_view_timing/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/session_replay/aggregate/index.d.ts +96 -0
- package/dist/types/features/session_replay/aggregate/index.d.ts.map +1 -0
- package/dist/types/features/session_replay/constants.d.ts +2 -0
- package/dist/types/features/session_replay/constants.d.ts.map +1 -0
- package/dist/types/features/session_replay/index.d.ts +2 -0
- package/dist/types/features/session_replay/index.d.ts.map +1 -0
- package/dist/types/features/session_replay/instrument/index.d.ts +6 -0
- package/dist/types/features/session_replay/instrument/index.d.ts.map +1 -0
- package/dist/types/features/session_trace/aggregate/index.d.ts +8 -57
- package/dist/types/features/session_trace/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/session_trace/constants.d.ts +0 -3
- package/dist/types/features/session_trace/constants.d.ts.map +1 -1
- package/dist/types/features/session_trace/instrument/index.d.ts +1 -3
- package/dist/types/features/session_trace/instrument/index.d.ts.map +1 -1
- package/dist/types/features/spa/aggregate/index.d.ts +2 -2
- package/dist/types/features/spa/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/utils/agent-session.d.ts.map +1 -1
- package/dist/types/features/utils/aggregate-base.d.ts +11 -0
- package/dist/types/features/utils/aggregate-base.d.ts.map +1 -0
- package/dist/types/features/utils/feature-base.d.ts +0 -5
- package/dist/types/features/utils/feature-base.d.ts.map +1 -1
- package/dist/types/features/utils/handler-cache.d.ts.map +1 -1
- package/dist/types/features/utils/instrument-base.d.ts +3 -1
- package/dist/types/features/utils/instrument-base.d.ts.map +1 -1
- package/dist/types/features/utils/{lazy-loader.d.ts → lazy-feature-loader.d.ts} +2 -2
- package/dist/types/features/utils/lazy-feature-loader.d.ts.map +1 -0
- package/dist/types/loaders/configure/configure.d.ts.map +1 -1
- package/dist/types/loaders/features/featureDependencies.d.ts +0 -1
- package/dist/types/loaders/features/featureDependencies.d.ts.map +1 -1
- package/dist/types/loaders/features/features.d.ts +1 -0
- package/dist/types/loaders/features/features.d.ts.map +1 -1
- package/package.json +31 -22
- package/src/cdn/polyfills.js +4 -1
- package/src/common/config/state/configurable.js +18 -24
- package/src/common/config/state/info.js +2 -2
- package/src/common/config/state/init.js +62 -28
- package/src/common/config/state/loader-config.js +2 -2
- package/src/common/config/state/runtime.js +2 -4
- package/src/common/drain/drain.js +1 -1
- package/src/common/harvest/harvest-scheduler.js +35 -10
- package/src/common/harvest/harvest.js +73 -50
- package/src/common/session/session-entity.js +34 -23
- package/src/common/session/session-entity.test.js +57 -51
- package/src/common/timer/interaction-timer.js +9 -12
- package/src/common/url/canonicalize-url.js +28 -0
- package/src/common/url/canonicalize-url.test.js +34 -0
- package/src/common/url/clean-url.js +10 -3
- package/src/common/url/protocol.test.js +0 -1
- package/src/common/util/feature-flags.js +2 -2
- package/src/common/util/global-scope.js +2 -0
- package/src/common/util/submit-data.js +28 -17
- package/src/common/wrap/wrap-fetch.js +1 -2
- package/src/common/wrap/wrap-function.js +1 -2
- package/src/common/wrap/wrap-promise.js +1 -1
- package/src/features/ajax/aggregate/index.js +2 -2
- package/src/features/ajax/instrument/index.js +1 -1
- package/src/features/jserrors/aggregate/canonical-function-name.js +12 -4
- package/src/features/jserrors/aggregate/compute-stack-trace.js +85 -11
- package/src/features/jserrors/aggregate/compute-stack-trace.test.js +141 -24
- package/src/features/jserrors/aggregate/index.js +28 -52
- package/src/features/jserrors/instrument/index.js +0 -1
- package/src/features/metrics/aggregate/framework-detection.js +73 -0
- package/src/features/metrics/aggregate/framework-detection.test.js +201 -0
- package/src/features/metrics/aggregate/index.js +8 -3
- package/src/features/metrics/aggregate/polyfill-detection.es5.js +9 -0
- package/src/features/metrics/aggregate/polyfill-detection.es5.test.js +16 -0
- package/src/features/metrics/aggregate/polyfill-detection.js +48 -0
- package/src/features/metrics/aggregate/polyfill-detection.test.js +163 -0
- package/src/features/page_action/aggregate/index.js +2 -2
- package/src/features/page_view_event/aggregate/index.js +5 -5
- package/src/features/page_view_timing/aggregate/index.js +2 -2
- package/src/features/session_replay/aggregate/index.js +314 -0
- package/src/features/session_replay/constants.js +3 -0
- package/src/features/session_replay/index.js +12 -0
- package/src/features/session_replay/instrument/index.js +22 -0
- package/src/features/session_trace/aggregate/index.js +148 -188
- package/src/features/session_trace/constants.js +0 -4
- package/src/features/session_trace/instrument/index.js +17 -69
- package/src/features/spa/aggregate/index.js +2 -2
- package/src/features/utils/agent-session.js +1 -2
- package/src/features/utils/aggregate-base.js +51 -0
- package/src/features/utils/feature-base.js +1 -31
- package/src/features/utils/handler-cache.js +3 -4
- package/src/features/utils/instrument-base.js +40 -8
- package/src/features/utils/{lazy-loader.js → lazy-feature-loader.js} +3 -1
- package/src/loaders/agent.js +1 -1
- package/src/loaders/api/apiAsync.js +1 -1
- package/src/loaders/configure/configure.js +4 -3
- package/src/loaders/features/featureDependencies.js +0 -12
- package/src/loaders/features/features.js +3 -1
- package/src/loaders/micro-agent.js +4 -4
- package/dist/cjs/common/metrics/framework-detection.js +0 -72
- package/dist/cjs/common/util/user-agent.js +0 -57
- package/dist/cjs/common/window/supports-performance-observer.js +0 -15
- package/dist/esm/common/metrics/framework-detection.js +0 -66
- package/dist/esm/common/util/user-agent.js +0 -48
- package/dist/esm/common/window/supports-performance-observer.js +0 -9
- package/dist/types/common/metrics/framework-detection.d.ts.map +0 -1
- package/dist/types/common/util/user-agent.d.ts +0 -5
- package/dist/types/common/util/user-agent.d.ts.map +0 -1
- package/dist/types/common/window/supports-performance-observer.d.ts +0 -2
- package/dist/types/common/window/supports-performance-observer.d.ts.map +0 -1
- package/dist/types/features/utils/lazy-loader.d.ts.map +0 -1
- package/src/common/metrics/framework-detection.js +0 -71
- package/src/common/util/user-agent.js +0 -56
- package/src/common/window/supports-performance-observer.js +0 -10
- /package/dist/types/{common/metrics → features/metrics/aggregate}/framework-detection.d.ts +0 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2023 New Relic Corporation. All rights reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* @file Primes the Session Replay feature for lazy loading.
|
|
7
|
+
*
|
|
8
|
+
* NOTE: This code is under development and dormant. It will not download to instrumented pages or record any data.
|
|
9
|
+
* It is not production ready, and is not intended to be imported or implemented in any build of the browser agent until
|
|
10
|
+
* functionality is validated and a full user experience is curated.
|
|
11
|
+
*/
|
|
12
|
+
import { InstrumentBase } from '../../utils/instrument-base';
|
|
13
|
+
import { FEATURE_NAME } from '../constants';
|
|
14
|
+
export class Instrument extends InstrumentBase {
|
|
15
|
+
static featureName = FEATURE_NAME;
|
|
16
|
+
constructor(agentIdentifier, aggregator) {
|
|
17
|
+
let auto = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
|
|
18
|
+
super(agentIdentifier, aggregator, FEATURE_NAME, auto);
|
|
19
|
+
this.importAggregator();
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -4,87 +4,62 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { registerHandler } from '../../../common/event-emitter/register-handler';
|
|
6
6
|
import { HarvestScheduler } from '../../../common/harvest/harvest-scheduler';
|
|
7
|
-
import { mapOwn } from '../../../common/util/map-own';
|
|
8
7
|
import { stringify } from '../../../common/util/stringify';
|
|
9
8
|
import { parseUrl } from '../../../common/url/parse-url';
|
|
10
|
-
import { supportsPerformanceObserver } from '../../../common/window/supports-performance-observer';
|
|
11
|
-
import slice from 'lodash._slice';
|
|
12
9
|
import { getConfigurationValue, getInfo, getRuntime } from '../../../common/config/config';
|
|
13
10
|
import { now } from '../../../common/timing/now';
|
|
14
11
|
import { FEATURE_NAME } from '../constants';
|
|
15
12
|
import { drain } from '../../../common/drain/drain';
|
|
16
13
|
import { HandlerCache } from '../../utils/handler-cache';
|
|
17
|
-
import {
|
|
18
|
-
|
|
14
|
+
import { AggregateBase } from '../../utils/aggregate-base';
|
|
15
|
+
const ignoredEvents = {
|
|
16
|
+
// we find that certain events make the data too noisy to be useful
|
|
17
|
+
global: {
|
|
18
|
+
mouseup: true,
|
|
19
|
+
mousedown: true
|
|
20
|
+
},
|
|
21
|
+
// certain events are present both in the window and in PVT metrics. PVT metrics are prefered so the window events should be ignored
|
|
22
|
+
window: {
|
|
23
|
+
load: true,
|
|
24
|
+
pagehide: true
|
|
25
|
+
},
|
|
26
|
+
// when ajax instrumentation is disabled, all XMLHttpRequest events will return with origin = xhrOriginMissing and should be ignored
|
|
27
|
+
xhrOriginMissing: {
|
|
28
|
+
ignoreAll: true
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
const toAggregate = {
|
|
32
|
+
typing: [1000, 2000],
|
|
33
|
+
scrolling: [100, 1000],
|
|
34
|
+
mousing: [1000, 2000],
|
|
35
|
+
touching: [1000, 2000]
|
|
36
|
+
};
|
|
37
|
+
const MAX_TRACE_DURATION = 15 * 60 * 1000; // 15 minutes
|
|
38
|
+
|
|
39
|
+
export class Aggregate extends AggregateBase {
|
|
19
40
|
static featureName = FEATURE_NAME;
|
|
20
|
-
constructor(agentIdentifier, aggregator) {
|
|
41
|
+
constructor(agentIdentifier, aggregator, argsObj) {
|
|
21
42
|
var _this;
|
|
22
43
|
// Very unlikely, but in case the existing XMLHttpRequest.prototype object on the page couldn't be wrapped.
|
|
23
44
|
super(agentIdentifier, aggregator, FEATURE_NAME);
|
|
24
45
|
_this = this;
|
|
25
46
|
if (!getRuntime(agentIdentifier).xhrWrappable) return;
|
|
26
|
-
|
|
47
|
+
this.resourceObserver = argsObj?.resourceObserver; // undefined if observer couldn't be created
|
|
27
48
|
this.ptid = '';
|
|
28
|
-
this.ignoredEvents = {
|
|
29
|
-
// we find that certain events make the data too noisy to be useful
|
|
30
|
-
global: {
|
|
31
|
-
mouseup: true,
|
|
32
|
-
mousedown: true
|
|
33
|
-
},
|
|
34
|
-
// certain events are present both in the window and in PVT metrics. PVT metrics are prefered so the window events should be ignored
|
|
35
|
-
window: {
|
|
36
|
-
load: true,
|
|
37
|
-
pagehide: true
|
|
38
|
-
},
|
|
39
|
-
// when ajax instrumentation is disabled, all XMLHttpRequest events will return with origin = xhrOriginMissing and should be ignored
|
|
40
|
-
xhrOriginMissing: {
|
|
41
|
-
ignoreAll: true
|
|
42
|
-
}
|
|
43
|
-
};
|
|
44
|
-
this.toAggregate = {
|
|
45
|
-
typing: [1000, 2000],
|
|
46
|
-
scrolling: [100, 1000],
|
|
47
|
-
mousing: [1000, 2000],
|
|
48
|
-
touching: [1000, 2000]
|
|
49
|
-
};
|
|
50
|
-
this.rename = {
|
|
51
|
-
typing: {
|
|
52
|
-
keydown: true,
|
|
53
|
-
keyup: true,
|
|
54
|
-
keypress: true
|
|
55
|
-
},
|
|
56
|
-
mousing: {
|
|
57
|
-
mousemove: true,
|
|
58
|
-
mouseenter: true,
|
|
59
|
-
mouseleave: true,
|
|
60
|
-
mouseover: true,
|
|
61
|
-
mouseout: true
|
|
62
|
-
},
|
|
63
|
-
scrolling: {
|
|
64
|
-
scroll: true
|
|
65
|
-
},
|
|
66
|
-
touching: {
|
|
67
|
-
touchstart: true,
|
|
68
|
-
touchmove: true,
|
|
69
|
-
touchend: true,
|
|
70
|
-
touchcancel: true,
|
|
71
|
-
touchenter: true,
|
|
72
|
-
touchleave: true
|
|
73
|
-
}
|
|
74
|
-
};
|
|
75
49
|
this.trace = {};
|
|
76
50
|
this.nodeCount = 0;
|
|
77
51
|
this.sentTrace = null;
|
|
78
52
|
this.harvestTimeSeconds = getConfigurationValue(agentIdentifier, 'session_trace.harvestTimeSeconds') || 10;
|
|
79
53
|
this.maxNodesPerHarvest = getConfigurationValue(agentIdentifier, 'session_trace.maxNodesPerHarvest') || 1000;
|
|
80
54
|
this.laststart = 0;
|
|
55
|
+
const handlerCache = new HandlerCache();
|
|
81
56
|
registerHandler('feat-stn', () => {
|
|
82
57
|
if (typeof PerformanceNavigationTiming !== 'undefined') {
|
|
83
|
-
this.storeTiming(window.performance
|
|
58
|
+
this.storeTiming(window.performance.getEntriesByType('navigation')[0]);
|
|
84
59
|
} else {
|
|
85
|
-
this.storeTiming(window.performance
|
|
60
|
+
this.storeTiming(window.performance.timing);
|
|
86
61
|
}
|
|
87
|
-
|
|
62
|
+
const scheduler = new HarvestScheduler('resources', {
|
|
88
63
|
onFinished: onHarvestFinished.bind(this),
|
|
89
64
|
retryDelay: this.harvestTimeSeconds
|
|
90
65
|
}, this);
|
|
@@ -92,38 +67,37 @@ export class Aggregate extends FeatureBase {
|
|
|
92
67
|
scheduler.runHarvest({
|
|
93
68
|
needResponse: true
|
|
94
69
|
}); // sends first stn harvest immediately
|
|
95
|
-
|
|
70
|
+
handlerCache.decide(true);
|
|
96
71
|
function onHarvestFinished(result) {
|
|
97
|
-
// start timer only if ptid was returned by server
|
|
98
72
|
if (result.sent && result.responseText && !this.ptid) {
|
|
99
|
-
|
|
100
|
-
getRuntime(this.agentIdentifier).ptid = this.ptid;
|
|
73
|
+
// continue interval harvest only if ptid was returned by server on the first
|
|
74
|
+
getRuntime(this.agentIdentifier).ptid = this.ptid = result.responseText;
|
|
101
75
|
scheduler.startTimer(this.harvestTimeSeconds);
|
|
102
76
|
}
|
|
103
77
|
if (result.sent && result.retry && this.sentTrace) {
|
|
104
|
-
|
|
105
|
-
|
|
78
|
+
// merge previous trace back into buffer to retry for next harvest
|
|
79
|
+
Object.entries(this.sentTrace).forEach(_ref => {
|
|
80
|
+
let [name, listOfSTNodes] = _ref;
|
|
81
|
+
if (this.nodeCount >= this.maxNodesPerHarvest) return;
|
|
82
|
+
this.nodeCount += listOfSTNodes.length;
|
|
83
|
+
this.trace[name] = this.trace[name] ? listOfSTNodes.concat(this.trace[name]) : listOfSTNodes;
|
|
106
84
|
});
|
|
107
85
|
this.sentTrace = null;
|
|
108
86
|
}
|
|
109
87
|
}
|
|
110
88
|
function prepareHarvest(options) {
|
|
111
|
-
if (now() >
|
|
89
|
+
if (now() > MAX_TRACE_DURATION) {
|
|
112
90
|
// been collecting for over 15 min, empty trace object and bail
|
|
113
91
|
scheduler.stopTimer();
|
|
114
92
|
this.trace = {};
|
|
115
93
|
return;
|
|
116
94
|
}
|
|
117
|
-
|
|
118
|
-
// only send when there are more than 30 nodes to send
|
|
95
|
+
// Only harvest when there are more than 30 nodes to send after the very first.
|
|
119
96
|
if (this.ptid && this.nodeCount <= 30) return;
|
|
120
97
|
return this.takeSTNs(options.retry);
|
|
121
98
|
}
|
|
122
|
-
handlerCache.decide(true);
|
|
123
|
-
}, this.featureName, this.ee);
|
|
124
|
-
registerHandler('block-stn', () => {
|
|
125
|
-
handlerCache.decide(false);
|
|
126
99
|
}, this.featureName, this.ee);
|
|
100
|
+
registerHandler('block-stn', () => handlerCache.decide(false), this.featureName, this.ee);
|
|
127
101
|
|
|
128
102
|
// register the handlers immediately... but let the handlerCache decide if the data should actually get stored...
|
|
129
103
|
registerHandler('bst', function () {
|
|
@@ -176,19 +150,28 @@ export class Aggregate extends FeatureBase {
|
|
|
176
150
|
}, this.featureName, this.ee);
|
|
177
151
|
drain(this.agentIdentifier, this.featureName);
|
|
178
152
|
}
|
|
153
|
+
|
|
154
|
+
// PageViewTiming (FEATURE) events and metrics, such as 'load', 'lcp', etc. pipes into ST here.
|
|
179
155
|
processPVT(name, value, attrs) {
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
if (
|
|
156
|
+
this.storeTiming({
|
|
157
|
+
[name]: value
|
|
158
|
+
});
|
|
159
|
+
if (hasFID(name, attrs)) this.storeEvent({
|
|
184
160
|
type: 'fid',
|
|
185
161
|
target: 'document'
|
|
186
162
|
}, 'document', value, value + attrs.fid);
|
|
163
|
+
function hasFID(name, attrs) {
|
|
164
|
+
return name === 'fi' && !!attrs && typeof attrs.fid === 'number';
|
|
165
|
+
}
|
|
187
166
|
}
|
|
188
|
-
|
|
167
|
+
|
|
168
|
+
// This processes the aforementioned PVT and the first navigation entry of the page.
|
|
169
|
+
storeTiming(timingEntry) {
|
|
170
|
+
if (!timingEntry) return;
|
|
171
|
+
|
|
189
172
|
// loop iterates through prototype also (for FF)
|
|
190
|
-
for (let key in
|
|
191
|
-
|
|
173
|
+
for (let key in timingEntry) {
|
|
174
|
+
let val = timingEntry[key];
|
|
192
175
|
|
|
193
176
|
// ignore size and status type nodes that do not map to timestamp metrics
|
|
194
177
|
const lck = key.toLowerCase();
|
|
@@ -197,31 +180,33 @@ export class Aggregate extends FeatureBase {
|
|
|
197
180
|
// ignore inherited methods, meaningless 0 values, and bogus timestamps
|
|
198
181
|
// that are in the future (Microsoft Edge seems to sometimes produce these)
|
|
199
182
|
if (!(typeof val === 'number' && val >= 0)) continue;
|
|
200
|
-
|
|
183
|
+
val = Math.round(val);
|
|
201
184
|
this.storeSTN({
|
|
202
185
|
n: key,
|
|
203
|
-
s:
|
|
204
|
-
e:
|
|
186
|
+
s: val,
|
|
187
|
+
e: val,
|
|
205
188
|
o: 'document',
|
|
206
189
|
t: 'timing'
|
|
207
190
|
});
|
|
208
191
|
}
|
|
209
192
|
}
|
|
193
|
+
|
|
194
|
+
// Tracks duration of native APIs wrapped by wrap-timer & wrap-raf.
|
|
210
195
|
storeTimer(target, start, end, type) {
|
|
211
|
-
|
|
212
|
-
if (type === 'requestAnimationFrame') category = type;
|
|
213
|
-
var evt = {
|
|
196
|
+
const evt = {
|
|
214
197
|
n: type,
|
|
215
198
|
s: start,
|
|
216
199
|
e: end,
|
|
217
200
|
o: 'window',
|
|
218
|
-
t:
|
|
201
|
+
t: type === 'requestAnimationFrame' ? type : 'timer'
|
|
219
202
|
};
|
|
220
203
|
this.storeSTN(evt);
|
|
221
204
|
}
|
|
205
|
+
|
|
206
|
+
// Tracks the events and their listener's duration on objects wrapped by wrap-events.
|
|
222
207
|
storeEvent(currentEvent, target, start, end) {
|
|
223
|
-
if (this.shouldIgnoreEvent(currentEvent, target)) return
|
|
224
|
-
|
|
208
|
+
if (this.shouldIgnoreEvent(currentEvent, target)) return;
|
|
209
|
+
const evt = {
|
|
225
210
|
n: this.evtName(currentEvent.type),
|
|
226
211
|
s: start,
|
|
227
212
|
e: end,
|
|
@@ -236,31 +221,60 @@ export class Aggregate extends FeatureBase {
|
|
|
236
221
|
}
|
|
237
222
|
this.storeSTN(evt);
|
|
238
223
|
}
|
|
224
|
+
shouldIgnoreEvent(event, target) {
|
|
225
|
+
const origin = this.evtOrigin(event.target, target);
|
|
226
|
+
if (event.type in ignoredEvents.global) return true;
|
|
227
|
+
if (!!ignoredEvents[origin] && ignoredEvents[origin].ignoreAll) return true;
|
|
228
|
+
if (!!ignoredEvents[origin] && event.type in ignoredEvents[origin]) return true;
|
|
229
|
+
return false;
|
|
230
|
+
}
|
|
239
231
|
evtName(type) {
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
232
|
+
switch (type) {
|
|
233
|
+
case 'keydown':
|
|
234
|
+
case 'keyup':
|
|
235
|
+
case 'keypress':
|
|
236
|
+
return 'typing';
|
|
237
|
+
case 'mousemove':
|
|
238
|
+
case 'mouseenter':
|
|
239
|
+
case 'mouseleave':
|
|
240
|
+
case 'mouseover':
|
|
241
|
+
case 'mouseout':
|
|
242
|
+
return 'mousing';
|
|
243
|
+
case 'scroll':
|
|
244
|
+
return 'scrolling';
|
|
245
|
+
case 'touchstart':
|
|
246
|
+
case 'touchmove':
|
|
247
|
+
case 'touchend':
|
|
248
|
+
case 'touchcancel':
|
|
249
|
+
case 'touchenter':
|
|
250
|
+
case 'touchleave':
|
|
251
|
+
return 'touching';
|
|
252
|
+
default:
|
|
253
|
+
return type;
|
|
254
|
+
}
|
|
245
255
|
}
|
|
246
256
|
evtOrigin(t, target) {
|
|
247
|
-
|
|
257
|
+
let origin = 'unknown';
|
|
248
258
|
if (t && t instanceof XMLHttpRequest) {
|
|
249
|
-
|
|
259
|
+
const params = this.ee.context(t).params;
|
|
250
260
|
if (!params || !params.status || !params.method || !params.host || !params.pathname) return 'xhrOriginMissing';
|
|
251
261
|
origin = params.status + ' ' + params.method + ': ' + params.host + params.pathname;
|
|
252
262
|
} else if (t && typeof t.tagName === 'string') {
|
|
253
263
|
origin = t.tagName.toLowerCase();
|
|
254
264
|
if (t.id) origin += '#' + t.id;
|
|
255
|
-
if (t.className)
|
|
265
|
+
if (t.className) {
|
|
266
|
+
for (let i = 0; i < t.classList.length; i++) origin += '.' + t.classList[i];
|
|
267
|
+
}
|
|
256
268
|
}
|
|
257
269
|
if (origin === 'unknown') {
|
|
258
270
|
if (typeof target === 'string') origin = target;else if (target === document) origin = 'document';else if (target === window) origin = 'window';else if (target instanceof FileReader) origin = 'FileReader';
|
|
259
271
|
}
|
|
260
272
|
return origin;
|
|
261
273
|
}
|
|
274
|
+
|
|
275
|
+
// Tracks when the window history API specified by wrap-history is used.
|
|
262
276
|
storeHist(path, old, time) {
|
|
263
|
-
|
|
277
|
+
const node = {
|
|
264
278
|
n: 'history.pushState',
|
|
265
279
|
s: time,
|
|
266
280
|
e: time,
|
|
@@ -269,11 +283,15 @@ export class Aggregate extends FeatureBase {
|
|
|
269
283
|
};
|
|
270
284
|
this.storeSTN(node);
|
|
271
285
|
}
|
|
286
|
+
|
|
287
|
+
// Processes all the PerformanceResourceTiming entries captured (by observer).
|
|
272
288
|
storeResources(resources) {
|
|
273
289
|
if (!resources || resources.length === 0) return;
|
|
274
290
|
resources.forEach(currentResource => {
|
|
275
|
-
|
|
276
|
-
|
|
291
|
+
if ((currentResource.fetchStart | 0) <= this.laststart) return; // don't recollect already-seen resources
|
|
292
|
+
|
|
293
|
+
const parsed = parseUrl(currentResource.name);
|
|
294
|
+
const res = {
|
|
277
295
|
n: currentResource.initiatorType,
|
|
278
296
|
s: currentResource.fetchStart | 0,
|
|
279
297
|
e: currentResource.responseEnd | 0,
|
|
@@ -281,16 +299,15 @@ export class Aggregate extends FeatureBase {
|
|
|
281
299
|
// resource.name is actually a URL so it's the source
|
|
282
300
|
t: currentResource.entryType
|
|
283
301
|
};
|
|
284
|
-
|
|
285
|
-
// don't recollect old resources
|
|
286
|
-
if (res.s <= this.laststart) return;
|
|
287
302
|
this.storeSTN(res);
|
|
288
303
|
});
|
|
289
304
|
this.laststart = resources[resources.length - 1].fetchStart | 0;
|
|
290
305
|
}
|
|
306
|
+
|
|
307
|
+
// JavascriptError (FEATURE) events pipes into ST here.
|
|
291
308
|
storeErrorAgg(type, name, params, metrics) {
|
|
292
|
-
if (type !== 'err') return;
|
|
293
|
-
|
|
309
|
+
if (type !== 'err') return; // internal errors are purposefully ignored
|
|
310
|
+
const node = {
|
|
294
311
|
n: 'error',
|
|
295
312
|
s: metrics.time,
|
|
296
313
|
e: metrics.time,
|
|
@@ -299,9 +316,11 @@ export class Aggregate extends FeatureBase {
|
|
|
299
316
|
};
|
|
300
317
|
this.storeSTN(node);
|
|
301
318
|
}
|
|
319
|
+
|
|
320
|
+
// Ajax (FEATURE) events--XML & fetches--pipes into ST here.
|
|
302
321
|
storeXhrAgg(type, name, params, metrics) {
|
|
303
322
|
if (type !== 'xhr') return;
|
|
304
|
-
|
|
323
|
+
const node = {
|
|
305
324
|
n: 'Ajax',
|
|
306
325
|
s: metrics.time,
|
|
307
326
|
e: metrics.time + metrics.duration,
|
|
@@ -310,46 +329,46 @@ export class Aggregate extends FeatureBase {
|
|
|
310
329
|
};
|
|
311
330
|
this.storeSTN(node);
|
|
312
331
|
}
|
|
332
|
+
|
|
333
|
+
// Central function called by all the other store__ & addToTrace API to append a trace node.
|
|
313
334
|
storeSTN(stn) {
|
|
314
|
-
// limit the
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
if (!traceArr) traceArr = this.trace[stn.n] = [];
|
|
318
|
-
traceArr.push(stn);
|
|
335
|
+
if (this.nodeCount >= this.maxNodesPerHarvest) return; // limit the amount of data that is stored at once
|
|
336
|
+
|
|
337
|
+
if (this.trace[stn.n]) this.trace[stn.n].push(stn);else this.trace[stn.n] = [stn];
|
|
319
338
|
this.nodeCount++;
|
|
320
339
|
}
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
if (this.nodeCount >= this.maxNodesPerHarvest) return;
|
|
324
|
-
var traceArr = this.trace[key];
|
|
325
|
-
if (!traceArr) traceArr = this.trace[key] = [];
|
|
326
|
-
this.trace[key] = nodes.concat(traceArr);
|
|
327
|
-
this.nodeCount += nodes.length;
|
|
328
|
-
}
|
|
340
|
+
|
|
341
|
+
// Used by session trace's harvester to create the payload body.
|
|
329
342
|
takeSTNs(retry) {
|
|
330
|
-
|
|
331
|
-
|
|
343
|
+
if (!this.resourceObserver) {
|
|
344
|
+
// if PO isn't supported, this checks resourcetiming buffer every harvest.
|
|
332
345
|
this.storeResources(window.performance.getEntriesByType('resource'));
|
|
333
346
|
}
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
347
|
+
const stns = Object.entries(this.trace).flatMap(_ref2 => {
|
|
348
|
+
let [name, listOfSTNodes] = _ref2;
|
|
349
|
+
// basically take the "this.trace" map-obj and concat all the list-type values
|
|
350
|
+
if (!(name in toAggregate)) return listOfSTNodes;
|
|
351
|
+
// Special processing for event nodes dealing with user inputs:
|
|
352
|
+
const reindexByOriginFn = this.smearEvtsByOrigin(name);
|
|
353
|
+
const partitionListByOriginMap = listOfSTNodes.sort((a, b) => a.s - b.s).reduce(reindexByOriginFn, {});
|
|
354
|
+
return Object.values(partitionListByOriginMap).flat(); // join the partitions back into 1-D, now ordered by origin then start time
|
|
355
|
+
}, this);
|
|
338
356
|
if (stns.length === 0) return {};
|
|
339
357
|
if (retry) {
|
|
340
358
|
this.sentTrace = this.trace;
|
|
341
359
|
}
|
|
342
360
|
this.trace = {};
|
|
343
361
|
this.nodeCount = 0;
|
|
344
|
-
|
|
362
|
+
const stnInfo = {
|
|
345
363
|
qs: {
|
|
346
|
-
st:
|
|
364
|
+
st: String(getRuntime(this.agentIdentifier).offset)
|
|
347
365
|
},
|
|
348
366
|
body: {
|
|
349
367
|
res: stns
|
|
350
368
|
}
|
|
351
369
|
};
|
|
352
370
|
if (!this.ptid) {
|
|
371
|
+
// send custom and user attributes on the very first ST harvest only
|
|
353
372
|
const {
|
|
354
373
|
userAttributes,
|
|
355
374
|
atts,
|
|
@@ -357,53 +376,34 @@ export class Aggregate extends FeatureBase {
|
|
|
357
376
|
} = getInfo(this.agentIdentifier);
|
|
358
377
|
stnInfo.qs.ua = userAttributes;
|
|
359
378
|
stnInfo.qs.at = atts;
|
|
360
|
-
|
|
379
|
+
const ja = stringify(jsAttributes);
|
|
361
380
|
stnInfo.qs.ja = ja === '{}' ? null : ja;
|
|
362
381
|
}
|
|
363
382
|
return stnInfo;
|
|
364
383
|
}
|
|
365
|
-
byStart(a, b) {
|
|
366
|
-
return a.s - b.s;
|
|
367
|
-
}
|
|
368
384
|
smearEvtsByOrigin(name) {
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
return (byOrigin,
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
if (name === 'scrolling' && !
|
|
377
|
-
lastO[
|
|
378
|
-
|
|
379
|
-
lastArr.push(
|
|
380
|
-
} else if (last &&
|
|
381
|
-
last.e =
|
|
385
|
+
const maxGap = toAggregate[name][0];
|
|
386
|
+
const maxLen = toAggregate[name][1];
|
|
387
|
+
const lastO = {};
|
|
388
|
+
return (byOrigin, evtNode) => {
|
|
389
|
+
let lastArr = byOrigin[evtNode.o];
|
|
390
|
+
if (!lastArr) lastArr = byOrigin[evtNode.o] = [];
|
|
391
|
+
const last = lastO[evtNode.o];
|
|
392
|
+
if (name === 'scrolling' && !trivial(evtNode)) {
|
|
393
|
+
lastO[evtNode.o] = null;
|
|
394
|
+
evtNode.n = 'scroll';
|
|
395
|
+
lastArr.push(evtNode);
|
|
396
|
+
} else if (last && evtNode.s - last.s < maxLen && last.e > evtNode.s - maxGap) {
|
|
397
|
+
last.e = evtNode.e;
|
|
382
398
|
} else {
|
|
383
|
-
lastO[
|
|
384
|
-
lastArr.push(
|
|
399
|
+
lastO[evtNode.o] = evtNode;
|
|
400
|
+
lastArr.push(evtNode);
|
|
385
401
|
}
|
|
386
402
|
return byOrigin;
|
|
387
403
|
};
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
flatten(a, b) {
|
|
393
|
-
return a.concat(b);
|
|
394
|
-
}
|
|
395
|
-
hasFID(name, attrs) {
|
|
396
|
-
return name === 'fi' && !!attrs && typeof attrs.fid === 'number';
|
|
397
|
-
}
|
|
398
|
-
trivial(node) {
|
|
399
|
-
var limit = 4;
|
|
400
|
-
if (node && typeof node.e === 'number' && typeof node.s === 'number' && node.e - node.s < limit) return true;else return false;
|
|
401
|
-
}
|
|
402
|
-
shouldIgnoreEvent(event, target) {
|
|
403
|
-
var origin = this.evtOrigin(event.target, target);
|
|
404
|
-
if (event.type in this.ignoredEvents.global) return true;
|
|
405
|
-
if (!!this.ignoredEvents[origin] && this.ignoredEvents[origin].ignoreAll) return true;
|
|
406
|
-
if (!!this.ignoredEvents[origin] && event.type in this.ignoredEvents[origin]) return true;
|
|
407
|
-
return false;
|
|
404
|
+
function trivial(node) {
|
|
405
|
+
const limit = 4;
|
|
406
|
+
if (node && typeof node.e === 'number' && typeof node.s === 'number' && node.e - node.s < limit) return true;else return false;
|
|
407
|
+
}
|
|
408
408
|
}
|
|
409
409
|
}
|
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
import { originals } from '../../common/config/config';
|
|
2
1
|
import { FEATURE_NAMES } from '../../loaders/features/features';
|
|
3
2
|
export const FEATURE_NAME = FEATURE_NAMES.sessionTrace;
|
|
4
|
-
export const RESOURCE_TIMING_BUFFER_FULL = 'resourcetimingbufferfull';
|
|
5
3
|
export const BST_RESOURCE = 'bstResource';
|
|
6
4
|
export const RESOURCE = 'resource';
|
|
7
5
|
export const START = '-start';
|
|
@@ -9,6 +7,4 @@ export const END = '-end';
|
|
|
9
7
|
export const FN_START = 'fn' + START;
|
|
10
8
|
export const FN_END = 'fn' + END;
|
|
11
9
|
export const BST_TIMER = 'bstTimer';
|
|
12
|
-
export const PUSH_STATE = 'pushState';
|
|
13
|
-
export const ORIG_EVENT = originals.EV;
|
|
14
|
-
export const ADD_EVENT_LISTENER = 'addEventListener';
|
|
10
|
+
export const PUSH_STATE = 'pushState';
|