@newrelic/browser-agent 1.237.1 → 1.239.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/common/config/state/init.js +21 -13
- package/dist/cjs/common/config/state/runtime.js +0 -4
- 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 +3 -3
- package/dist/cjs/common/constants/shared-channel.js +3 -1
- package/dist/cjs/common/deny-list/deny-list.js +3 -9
- package/dist/cjs/common/drain/drain.js +1 -1
- package/dist/cjs/common/event-emitter/contextual-ee.js +24 -32
- package/dist/cjs/common/event-emitter/event-context.js +12 -0
- package/dist/cjs/common/harvest/harvest-scheduler.js +2 -4
- package/dist/cjs/common/harvest/harvest.js +4 -7
- package/dist/cjs/common/ids/bundle-id.js +19 -0
- package/dist/cjs/common/serialize/bel-serializer.js +1 -1
- package/dist/cjs/common/session/session-entity.js +16 -12
- package/dist/cjs/common/storage/first-party-cookies.js +5 -4
- package/dist/cjs/common/storage/local-storage.js +3 -2
- package/dist/cjs/common/timer/interaction-timer.js +14 -6
- package/dist/cjs/common/timing/nav-timing.js +1 -1
- package/dist/cjs/common/unload/eol.js +4 -30
- package/dist/cjs/common/util/feature-flags.js +14 -15
- package/dist/cjs/common/util/invoke.js +3 -1
- package/dist/cjs/common/util/obfuscate.js +3 -5
- package/dist/cjs/common/util/traverse.js +1 -0
- package/dist/cjs/common/window/page-visibility.js +1 -2
- package/dist/cjs/common/wrap/wrap-events.js +3 -2
- package/dist/cjs/common/wrap/wrap-fetch.js +1 -3
- package/dist/cjs/common/wrap/wrap-function.js +15 -46
- package/dist/cjs/common/wrap/wrap-jsonp.js +1 -1
- package/dist/cjs/common/wrap/wrap-mutation.js +1 -2
- package/dist/cjs/common/wrap/wrap-promise.js +2 -3
- package/dist/cjs/common/wrap/wrap-xhr.js +23 -27
- package/dist/cjs/features/ajax/aggregate/index.js +5 -7
- package/dist/cjs/features/ajax/instrument/distributed-tracing.js +8 -12
- package/dist/cjs/features/ajax/instrument/index.js +66 -24
- package/dist/cjs/features/jserrors/aggregate/canonical-function-name.js +0 -1
- package/dist/cjs/features/jserrors/aggregate/compute-stack-trace.js +4 -4
- package/dist/cjs/features/jserrors/aggregate/index.js +4 -5
- package/dist/cjs/features/metrics/aggregate/framework-detection.js +103 -7
- package/dist/cjs/features/metrics/aggregate/index.js +20 -37
- package/dist/cjs/features/metrics/instrument/index.js +0 -2
- package/dist/cjs/features/page_action/aggregate/index.js +17 -19
- package/dist/cjs/features/page_view_event/aggregate/index.js +1 -2
- package/dist/cjs/features/page_view_event/instrument/index.js +4 -2
- package/dist/cjs/features/page_view_timing/aggregate/index.js +6 -7
- package/dist/cjs/features/session_replay/aggregate/index.js +5 -3
- package/dist/cjs/features/session_trace/aggregate/index.js +22 -16
- package/dist/cjs/features/spa/aggregate/index.js +14 -20
- package/dist/cjs/features/spa/aggregate/interaction.js +0 -2
- package/dist/cjs/features/spa/aggregate/serializer.js +1 -1
- package/dist/cjs/features/utils/aggregate-base.js +4 -0
- package/dist/cjs/features/utils/handler-cache.js +3 -1
- package/dist/cjs/features/utils/instrument-base.js +24 -6
- package/dist/cjs/loaders/agent-base.js +23 -0
- package/dist/cjs/loaders/agent.js +7 -7
- package/dist/cjs/loaders/api/api.js +34 -4
- package/dist/cjs/loaders/api/apiAsync.js +19 -20
- package/dist/cjs/loaders/api/interaction-types.js +11 -4
- package/dist/cjs/loaders/configure/configure.js +3 -0
- package/dist/cjs/loaders/micro-agent.js +20 -3
- package/dist/esm/common/config/state/init.js +21 -13
- package/dist/esm/common/config/state/runtime.js +0 -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/constants/runtime.js +1 -1
- package/dist/esm/common/constants/shared-channel.js +3 -1
- package/dist/esm/common/deny-list/deny-list.js +3 -9
- package/dist/esm/common/drain/drain.js +1 -1
- package/dist/esm/common/event-emitter/contextual-ee.js +22 -29
- package/dist/esm/common/event-emitter/event-context.js +5 -0
- package/dist/esm/common/harvest/harvest-scheduler.js +2 -4
- package/dist/esm/common/harvest/harvest.js +4 -7
- package/dist/esm/common/ids/bundle-id.js +13 -0
- package/dist/esm/common/serialize/bel-serializer.js +1 -1
- package/dist/esm/common/session/session-entity.js +16 -12
- package/dist/esm/common/storage/first-party-cookies.js +5 -4
- package/dist/esm/common/storage/local-storage.js +3 -2
- package/dist/esm/common/timer/interaction-timer.js +14 -6
- package/dist/esm/common/timing/nav-timing.js +1 -1
- package/dist/esm/common/unload/eol.js +5 -31
- package/dist/esm/common/util/feature-flags.js +14 -15
- package/dist/esm/common/util/invoke.js +3 -1
- package/dist/esm/common/util/obfuscate.js +3 -5
- package/dist/esm/common/util/traverse.js +1 -0
- package/dist/esm/common/window/page-visibility.js +1 -2
- package/dist/esm/common/wrap/wrap-events.js +4 -3
- package/dist/esm/common/wrap/wrap-fetch.js +2 -4
- package/dist/esm/common/wrap/wrap-function.js +15 -44
- package/dist/esm/common/wrap/wrap-jsonp.js +1 -1
- package/dist/esm/common/wrap/wrap-mutation.js +2 -3
- package/dist/esm/common/wrap/wrap-promise.js +3 -4
- package/dist/esm/common/wrap/wrap-xhr.js +23 -27
- package/dist/esm/features/ajax/aggregate/index.js +5 -7
- package/dist/esm/features/ajax/instrument/distributed-tracing.js +8 -12
- package/dist/esm/features/ajax/instrument/index.js +67 -25
- package/dist/esm/features/jserrors/aggregate/canonical-function-name.js +0 -1
- package/dist/esm/features/jserrors/aggregate/compute-stack-trace.js +4 -4
- package/dist/esm/features/jserrors/aggregate/index.js +4 -5
- package/dist/esm/features/metrics/aggregate/framework-detection.js +103 -7
- package/dist/esm/features/metrics/aggregate/index.js +22 -39
- package/dist/esm/features/metrics/instrument/index.js +1 -3
- package/dist/esm/features/page_action/aggregate/index.js +17 -19
- package/dist/esm/features/page_view_event/aggregate/index.js +1 -2
- package/dist/esm/features/page_view_event/instrument/index.js +4 -2
- package/dist/esm/features/page_view_timing/aggregate/index.js +7 -8
- package/dist/esm/features/session_replay/aggregate/index.js +4 -2
- package/dist/esm/features/session_trace/aggregate/index.js +22 -16
- package/dist/esm/features/spa/aggregate/index.js +14 -20
- package/dist/esm/features/spa/aggregate/interaction.js +0 -2
- package/dist/esm/features/spa/aggregate/serializer.js +1 -1
- package/dist/esm/features/utils/aggregate-base.js +4 -0
- package/dist/esm/features/utils/handler-cache.js +3 -1
- package/dist/esm/features/utils/instrument-base.js +24 -6
- package/dist/esm/loaders/agent-base.js +23 -0
- package/dist/esm/loaders/agent.js +7 -7
- package/dist/esm/loaders/api/api.js +34 -4
- package/dist/esm/loaders/api/apiAsync.js +19 -20
- package/dist/esm/loaders/api/interaction-types.js +11 -4
- package/dist/esm/loaders/configure/configure.js +3 -0
- package/dist/esm/loaders/features/enabled-features.js +1 -1
- package/dist/esm/loaders/micro-agent.js +21 -4
- 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/constants/runtime.d.ts +1 -1
- package/dist/types/common/constants/runtime.d.ts.map +1 -1
- package/dist/types/common/event-emitter/contextual-ee.d.ts +22 -2
- package/dist/types/common/event-emitter/contextual-ee.d.ts.map +1 -1
- package/dist/types/common/event-emitter/event-context.d.ts +5 -0
- package/dist/types/common/event-emitter/event-context.d.ts.map +1 -0
- package/dist/types/common/event-emitter/register-handler.d.ts +1 -1
- package/dist/types/common/harvest/harvest-scheduler.d.ts.map +1 -1
- package/dist/types/common/harvest/harvest.d.ts.map +1 -1
- package/dist/types/common/ids/bundle-id.d.ts +5 -0
- package/dist/types/common/ids/bundle-id.d.ts.map +1 -0
- package/dist/types/common/session/session-entity.d.ts +12 -15
- package/dist/types/common/session/session-entity.d.ts.map +1 -1
- package/dist/types/common/storage/first-party-cookies.d.ts +1 -1
- package/dist/types/common/storage/first-party-cookies.d.ts.map +1 -1
- package/dist/types/common/storage/local-storage.d.ts.map +1 -1
- package/dist/types/common/timer/interaction-timer.d.ts +3 -0
- package/dist/types/common/timer/interaction-timer.d.ts.map +1 -1
- package/dist/types/common/unload/eol.d.ts +1 -2
- package/dist/types/common/unload/eol.d.ts.map +1 -1
- package/dist/types/common/util/feature-flags.d.ts.map +1 -1
- package/dist/types/common/util/obfuscate.d.ts.map +1 -1
- package/dist/types/common/util/traverse.d.ts.map +1 -1
- package/dist/types/common/window/nreum.d.ts +2 -2
- package/dist/types/common/window/page-visibility.d.ts.map +1 -1
- package/dist/types/common/wrap/wrap-events.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 +1 -19
- package/dist/types/common/wrap/wrap-function.d.ts.map +1 -1
- package/dist/types/common/wrap/wrap-mutation.d.ts.map +1 -1
- package/dist/types/common/wrap/wrap-promise.d.ts.map +1 -1
- package/dist/types/common/wrap/wrap-xhr.d.ts.map +1 -1
- package/dist/types/features/ajax/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/ajax/instrument/distributed-tracing.d.ts +1 -1
- package/dist/types/features/ajax/instrument/distributed-tracing.d.ts.map +1 -1
- package/dist/types/features/ajax/instrument/index.d.ts.map +1 -1
- package/dist/types/features/jserrors/aggregate/canonical-function-name.d.ts.map +1 -1
- package/dist/types/features/jserrors/aggregate/index.d.ts +1 -1
- package/dist/types/features/jserrors/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/metrics/aggregate/framework-detection.d.ts.map +1 -1
- package/dist/types/features/metrics/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/metrics/instrument/index.d.ts.map +1 -1
- package/dist/types/features/page_action/aggregate/index.d.ts +2 -2
- package/dist/types/features/page_action/aggregate/index.d.ts.map +1 -1
- 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.map +1 -1
- package/dist/types/features/session_replay/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/session_trace/aggregate/index.d.ts +5 -0
- 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/features/spa/aggregate/interaction.d.ts.map +1 -1
- package/dist/types/features/utils/aggregate-base.d.ts +1 -0
- package/dist/types/features/utils/aggregate-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.map +1 -1
- package/dist/types/loaders/agent-base.d.ts +15 -0
- package/dist/types/loaders/agent-base.d.ts.map +1 -1
- package/dist/types/loaders/agent.d.ts +1 -1
- package/dist/types/loaders/agent.d.ts.map +1 -1
- package/dist/types/loaders/api/api.d.ts +7 -0
- 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/api/interaction-types.d.ts +18 -7
- package/dist/types/loaders/api/interaction-types.d.ts.map +1 -1
- package/dist/types/loaders/configure/configure.d.ts +2 -0
- package/dist/types/loaders/configure/configure.d.ts.map +1 -1
- package/dist/types/loaders/features/features.d.ts +9 -9
- package/dist/types/loaders/micro-agent.d.ts +7 -1
- package/dist/types/loaders/micro-agent.d.ts.map +1 -1
- package/package.json +62 -38
- package/src/common/aggregate/aggregator.test.js +107 -0
- package/src/common/config/state/configurable.test.js +73 -0
- package/src/common/config/state/info.test.js +31 -0
- package/src/common/config/state/init.js +13 -12
- package/src/common/config/state/init.test.js +28 -0
- package/src/common/config/state/loader-config.test.js +21 -0
- package/src/common/config/state/runtime.js +0 -2
- package/src/common/config/state/runtime.test.js +21 -0
- package/src/common/constants/__mocks__/runtime.js +1 -1
- package/src/common/constants/runtime.js +1 -1
- package/src/common/constants/runtime.test.js +2 -2
- package/src/common/constants/shared-channel.js +1 -1
- package/src/common/deny-list/deny-list.js +3 -11
- package/src/common/deny-list/deny-list.test.js +103 -30
- package/src/common/drain/drain.js +1 -1
- package/src/common/drain/drain.test.js +74 -0
- package/src/common/event-emitter/{contextual-ee.test.js → contextual-ee.component-test.js} +15 -32
- package/src/common/event-emitter/contextual-ee.js +26 -37
- package/src/common/event-emitter/event-context.js +5 -0
- package/src/common/harvest/harvest-scheduler.js +2 -5
- package/src/common/harvest/harvest-scheduler.test.js +2 -6
- package/src/common/harvest/harvest.js +4 -7
- package/src/common/harvest/harvest.test.js +1 -3
- package/src/common/ids/__mocks__/bundle-id.js +2 -0
- package/src/common/ids/__mocks__/unique-id.js +17 -0
- package/src/common/ids/bundle-id.js +13 -0
- package/src/common/ids/id.test.js +6 -6
- package/src/common/serialize/bel-serializer.js +1 -1
- package/src/common/session/session-entity.component-test.js +3 -2
- package/src/common/session/session-entity.js +11 -9
- package/src/common/storage/first-party-cookies.js +5 -4
- package/src/common/storage/local-storage.js +3 -2
- package/src/common/timer/interaction-timer.component-test.js +52 -7
- package/src/common/timer/interaction-timer.js +15 -6
- package/src/common/timer/timer.test.js +0 -1
- package/src/common/timing/nav-timing.js +1 -1
- package/src/common/unload/eol.js +5 -31
- package/src/common/url/__mocks__/parse-url.js +15 -0
- package/src/common/url/{encode.component-test.js → encode.test.js} +1 -0
- package/src/common/util/__mocks__/get-or-set.js +5 -0
- package/src/common/util/__mocks__/invoke.js +1 -0
- package/src/common/util/data-size.test.js +0 -1
- package/src/common/util/feature-flags.js +15 -17
- package/src/common/util/feature-flags.test.js +4 -8
- package/src/common/util/invoke.js +1 -1
- package/src/common/util/obfuscate.js +3 -5
- package/src/common/util/submit-data.test.js +1 -1
- package/src/common/util/traverse.js +1 -0
- package/src/common/window/__mocks__/nreum.js +12 -0
- package/src/common/window/page-visibility.js +1 -2
- package/src/common/wrap/wrap-events.js +4 -3
- package/src/common/wrap/wrap-fetch.js +2 -4
- package/src/common/wrap/wrap-function.js +16 -44
- package/src/common/wrap/wrap-jsonp.js +1 -1
- package/src/common/wrap/wrap-mutation.js +2 -3
- package/src/common/wrap/{wrap-promise.test.js → wrap-promise.component-test.js} +2 -32
- package/src/common/wrap/wrap-promise.js +3 -4
- package/src/common/wrap/wrap-xhr.js +24 -28
- package/src/features/ajax/aggregate/index.js +5 -7
- package/src/features/ajax/instrument/distributed-tracing.js +8 -12
- package/src/features/ajax/instrument/distributed-tracing.test.js +375 -0
- package/src/features/ajax/instrument/index.js +62 -27
- package/src/features/jserrors/aggregate/canonical-function-name.js +0 -2
- package/src/features/jserrors/aggregate/compute-stack-trace.js +4 -4
- package/src/features/jserrors/aggregate/compute-stack-trace.test.js +1 -1
- package/src/features/jserrors/aggregate/index.js +4 -5
- package/src/features/metrics/aggregate/framework-detection.js +129 -8
- package/src/features/metrics/aggregate/framework-detection.test.js +213 -82
- package/src/features/metrics/aggregate/index.js +22 -45
- package/src/features/metrics/instrument/index.js +1 -3
- package/src/features/page_action/aggregate/index.js +12 -13
- package/src/features/page_view_event/aggregate/index.js +1 -2
- package/src/features/page_view_event/instrument/index.js +2 -2
- package/src/features/page_view_timing/aggregate/index.js +7 -8
- package/src/features/session_replay/aggregate/index.component-test.js +3 -15
- package/src/features/session_replay/aggregate/index.js +4 -2
- package/src/features/session_trace/aggregate/index.js +22 -16
- package/src/features/spa/aggregate/index.js +14 -20
- package/src/features/spa/aggregate/interaction.js +0 -2
- package/src/features/spa/aggregate/serializer.js +1 -1
- package/src/features/utils/aggregate-base.js +5 -0
- package/src/features/utils/aggregate-base.test.js +2 -1
- package/src/features/utils/handler-cache.js +3 -2
- package/src/features/utils/instrument-base.js +25 -6
- package/src/features/utils/instrument-base.test.js +2 -2
- package/src/loaders/agent-base.js +23 -0
- package/src/loaders/agent.js +7 -7
- package/src/loaders/api/api.component-test.js +45 -0
- package/src/loaders/api/api.js +34 -4
- package/src/loaders/api/api.test.js +85 -0
- package/src/loaders/api/apiAsync.js +19 -20
- package/src/loaders/api/apiAsync.test.js +17 -0
- package/src/loaders/api/interaction-types.js +11 -4
- package/src/loaders/configure/configure.js +3 -0
- package/src/loaders/features/enabled-features.js +1 -1
- package/src/loaders/micro-agent.js +22 -4
- package/dist/cjs/features/metrics/aggregate/endpoint-map.js +0 -14
- package/dist/cjs/features/metrics/aggregate/polyfill-detection.es5.js +0 -14
- package/dist/cjs/features/metrics/aggregate/polyfill-detection.js +0 -53
- package/dist/esm/features/metrics/aggregate/endpoint-map.js +0 -7
- package/dist/esm/features/metrics/aggregate/polyfill-detection.es5.js +0 -8
- package/dist/esm/features/metrics/aggregate/polyfill-detection.js +0 -47
- package/dist/types/features/metrics/aggregate/endpoint-map.d.ts +0 -8
- package/dist/types/features/metrics/aggregate/endpoint-map.d.ts.map +0 -1
- package/dist/types/features/metrics/aggregate/polyfill-detection.d.ts +0 -6
- package/dist/types/features/metrics/aggregate/polyfill-detection.d.ts.map +0 -1
- package/dist/types/features/metrics/aggregate/polyfill-detection.es5.d.ts +0 -7
- package/dist/types/features/metrics/aggregate/polyfill-detection.es5.d.ts.map +0 -1
- package/src/features/metrics/aggregate/endpoint-map.js +0 -7
- package/src/features/metrics/aggregate/polyfill-detection.es5.js +0 -8
- package/src/features/metrics/aggregate/polyfill-detection.es5.test.js +0 -16
- package/src/features/metrics/aggregate/polyfill-detection.js +0 -48
- package/src/features/metrics/aggregate/polyfill-detection.test.js +0 -163
- /package/src/common/url/{protocol.component-test.js → protocol.test.js} +0 -0
|
@@ -1,31 +1,59 @@
|
|
|
1
1
|
import { isBrowserScope } from '../../../common/constants/runtime';
|
|
2
2
|
const FRAMEWORKS = {
|
|
3
3
|
REACT: 'React',
|
|
4
|
+
NEXTJS: 'NextJS',
|
|
5
|
+
VUE: 'Vue',
|
|
6
|
+
NUXTJS: 'NuxtJS',
|
|
4
7
|
ANGULAR: 'Angular',
|
|
8
|
+
ANGULARUNIVERSAL: 'AngularUniversal',
|
|
9
|
+
SVELTE: 'Svelte',
|
|
10
|
+
SVELTEKIT: 'SvelteKit',
|
|
11
|
+
PREACT: 'Preact',
|
|
12
|
+
PREACTSSR: 'PreactSSR',
|
|
5
13
|
ANGULARJS: 'AngularJS',
|
|
6
14
|
BACKBONE: 'Backbone',
|
|
7
15
|
EMBER: 'Ember',
|
|
8
|
-
VUE: 'Vue',
|
|
9
16
|
METEOR: 'Meteor',
|
|
10
17
|
ZEPTO: 'Zepto',
|
|
11
18
|
JQUERY: 'Jquery',
|
|
12
|
-
MOOTOOLS: 'MooTools'
|
|
19
|
+
MOOTOOLS: 'MooTools',
|
|
20
|
+
QWIK: 'Qwik',
|
|
21
|
+
ELECTRON: 'Electron'
|
|
13
22
|
};
|
|
14
23
|
export function getFrameworks() {
|
|
15
24
|
if (!isBrowserScope) return []; // don't bother detecting frameworks if not in the main window context
|
|
16
25
|
|
|
17
26
|
const frameworks = [];
|
|
18
27
|
try {
|
|
19
|
-
if (detectReact())
|
|
28
|
+
if (detectReact()) {
|
|
29
|
+
frameworks.push(FRAMEWORKS.REACT);
|
|
30
|
+
if (detectNextJS()) frameworks.push(FRAMEWORKS.NEXTJS);
|
|
31
|
+
}
|
|
32
|
+
if (detectVue()) {
|
|
33
|
+
frameworks.push(FRAMEWORKS.VUE);
|
|
34
|
+
if (detectNuxtJS()) frameworks.push(FRAMEWORKS.NUXTJS);
|
|
35
|
+
}
|
|
36
|
+
if (detectAngular()) {
|
|
37
|
+
frameworks.push(FRAMEWORKS.ANGULAR);
|
|
38
|
+
if (detectAngularUniversal()) frameworks.push(FRAMEWORKS.ANGULARUNIVERSAL);
|
|
39
|
+
}
|
|
40
|
+
if (detectSvelte()) {
|
|
41
|
+
frameworks.push(FRAMEWORKS.SVELTE);
|
|
42
|
+
if (detectSvelteKit()) frameworks.push(FRAMEWORKS.SVELTEKIT);
|
|
43
|
+
}
|
|
44
|
+
if (detectPreact()) {
|
|
45
|
+
frameworks.push(FRAMEWORKS.PREACT);
|
|
46
|
+
if (detectPreactSSR()) frameworks.push(FRAMEWORKS.PREACTSSR);
|
|
47
|
+
}
|
|
20
48
|
if (detectAngularJs()) frameworks.push(FRAMEWORKS.ANGULARJS);
|
|
21
|
-
if (detectAngular()) frameworks.push(FRAMEWORKS.ANGULAR);
|
|
22
49
|
if (Object.prototype.hasOwnProperty.call(window, 'Backbone')) frameworks.push(FRAMEWORKS.BACKBONE);
|
|
23
50
|
if (Object.prototype.hasOwnProperty.call(window, 'Ember')) frameworks.push(FRAMEWORKS.EMBER);
|
|
24
|
-
if (Object.prototype.hasOwnProperty.call(window, 'Vue')) frameworks.push(FRAMEWORKS.VUE);
|
|
25
51
|
if (Object.prototype.hasOwnProperty.call(window, 'Meteor')) frameworks.push(FRAMEWORKS.METEOR);
|
|
26
52
|
if (Object.prototype.hasOwnProperty.call(window, 'Zepto')) frameworks.push(FRAMEWORKS.ZEPTO);
|
|
27
53
|
if (Object.prototype.hasOwnProperty.call(window, 'jQuery')) frameworks.push(FRAMEWORKS.JQUERY);
|
|
28
54
|
if (Object.prototype.hasOwnProperty.call(window, 'MooTools')) frameworks.push(FRAMEWORKS.MOOTOOLS);
|
|
55
|
+
if (Object.prototype.hasOwnProperty.call(window, 'qwikevents')) frameworks.push(FRAMEWORKS.QWIK);
|
|
56
|
+
if (detectElectron()) frameworks.push(FRAMEWORKS.ELECTRON);
|
|
29
57
|
} catch (err) {
|
|
30
58
|
// Possibly not supported
|
|
31
59
|
}
|
|
@@ -45,9 +73,25 @@ function detectReact() {
|
|
|
45
73
|
return false;
|
|
46
74
|
}
|
|
47
75
|
}
|
|
48
|
-
function
|
|
76
|
+
function detectNextJS() {
|
|
77
|
+
// React SSR
|
|
49
78
|
try {
|
|
50
|
-
return Object.prototype.hasOwnProperty.call(window, '
|
|
79
|
+
return Object.prototype.hasOwnProperty.call(window, 'next') && Object.prototype.hasOwnProperty.call(window.next, 'version');
|
|
80
|
+
} catch (err) {
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
function detectVue() {
|
|
85
|
+
try {
|
|
86
|
+
return Object.prototype.hasOwnProperty.call(window, 'Vue');
|
|
87
|
+
} catch (err) {
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
function detectNuxtJS() {
|
|
92
|
+
// Vue SSR
|
|
93
|
+
try {
|
|
94
|
+
return Object.prototype.hasOwnProperty.call(window, '$nuxt') && Object.prototype.hasOwnProperty.call(window.$nuxt, 'nuxt');
|
|
51
95
|
} catch (err) {
|
|
52
96
|
return false;
|
|
53
97
|
}
|
|
@@ -58,4 +102,56 @@ function detectAngular() {
|
|
|
58
102
|
} catch (err) {
|
|
59
103
|
return false;
|
|
60
104
|
}
|
|
105
|
+
}
|
|
106
|
+
function detectAngularUniversal() {
|
|
107
|
+
// Anguler SSR
|
|
108
|
+
try {
|
|
109
|
+
return document.querySelector('[ng-server-context]');
|
|
110
|
+
} catch (err) {
|
|
111
|
+
return false;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
function detectSvelte() {
|
|
115
|
+
try {
|
|
116
|
+
return Object.prototype.hasOwnProperty.call(window, '__svelte');
|
|
117
|
+
} catch (err) {
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
function detectSvelteKit() {
|
|
122
|
+
// Svelte SSR
|
|
123
|
+
try {
|
|
124
|
+
return !!Object.keys(window).find(prop => prop.startsWith('__sveltekit'));
|
|
125
|
+
} catch (err) {
|
|
126
|
+
return false;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
function detectPreact() {
|
|
130
|
+
try {
|
|
131
|
+
return Object.prototype.hasOwnProperty.call(window, 'preact');
|
|
132
|
+
} catch (err) {
|
|
133
|
+
return false;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
function detectPreactSSR() {
|
|
137
|
+
// Svelte SSR
|
|
138
|
+
try {
|
|
139
|
+
return document.querySelector('script[type="__PREACT_CLI_DATA__"]');
|
|
140
|
+
} catch (err) {
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
function detectAngularJs() {
|
|
145
|
+
try {
|
|
146
|
+
return Object.prototype.hasOwnProperty.call(window, 'angular') || document.querySelector('.ng-binding, [ng-app], [data-ng-app], [ng-controller], [data-ng-controller], [ng-repeat], [data-ng-repeat]') || document.querySelector('script[src*="angular.js"], script[src*="angular.min.js"]');
|
|
147
|
+
} catch (err) {
|
|
148
|
+
return false;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
function detectElectron() {
|
|
152
|
+
try {
|
|
153
|
+
return typeof navigator === 'object' && typeof navigator.userAgent === 'string' && navigator.userAgent.indexOf('Electron') >= 0;
|
|
154
|
+
} catch (err) {
|
|
155
|
+
return false;
|
|
156
|
+
}
|
|
61
157
|
}
|
|
@@ -1,19 +1,14 @@
|
|
|
1
|
-
import { getRuntime
|
|
1
|
+
import { getRuntime } from '../../../common/config/config';
|
|
2
2
|
import { registerHandler } from '../../../common/event-emitter/register-handler';
|
|
3
3
|
import { HarvestScheduler } from '../../../common/harvest/harvest-scheduler';
|
|
4
4
|
import { FEATURE_NAME, SUPPORTABILITY_METRIC, CUSTOM_METRIC, SUPPORTABILITY_METRIC_CHANNEL, CUSTOM_METRIC_CHANNEL } from '../constants';
|
|
5
|
-
import { drain } from '../../../common/drain/drain';
|
|
6
5
|
import { getFrameworks } from './framework-detection';
|
|
7
|
-
import { getPolyfills } from './polyfill-detection';
|
|
8
6
|
import { isFileProtocol } from '../../../common/url/protocol';
|
|
9
7
|
import { getRules, validateRules } from '../../../common/util/obfuscate';
|
|
10
|
-
import { VERSION } from "../../../common/constants/env.npm";
|
|
11
8
|
import { onDOMContentLoaded } from '../../../common/window/load';
|
|
12
9
|
import { windowAddEventListener } from '../../../common/event-listener/event-listener-opts';
|
|
13
|
-
import { isBrowserScope } from '../../../common/constants/runtime';
|
|
10
|
+
import { isBrowserScope, isWorkerScope } from '../../../common/constants/runtime';
|
|
14
11
|
import { AggregateBase } from '../../utils/aggregate-base';
|
|
15
|
-
import { stringify } from '../../../common/util/stringify';
|
|
16
|
-
import { endpointMap } from './endpoint-map';
|
|
17
12
|
export class Aggregate extends AggregateBase {
|
|
18
13
|
static featureName = FEATURE_NAME;
|
|
19
14
|
constructor(agentIdentifier, aggregator) {
|
|
@@ -39,9 +34,8 @@ export class Aggregate extends AggregateBase {
|
|
|
39
34
|
scheduler.harvest.on('jserrors', () => ({
|
|
40
35
|
body: this.aggregator.take(['cm', 'sm'])
|
|
41
36
|
}));
|
|
42
|
-
|
|
37
|
+
this.drain();
|
|
43
38
|
}
|
|
44
|
-
|
|
45
39
|
storeSupportabilityMetrics(name, value) {
|
|
46
40
|
if (this.blocked) return;
|
|
47
41
|
const type = SUPPORTABILITY_METRIC;
|
|
@@ -59,9 +53,6 @@ export class Aggregate extends AggregateBase {
|
|
|
59
53
|
this.aggregator.store(type, name, params, metrics);
|
|
60
54
|
}
|
|
61
55
|
singleChecks() {
|
|
62
|
-
// report generic info about the agent itself
|
|
63
|
-
// note the browser agent version
|
|
64
|
-
this.storeSupportabilityMetrics("Generic/Version/".concat(VERSION, "/Detected"));
|
|
65
56
|
// report loaderType
|
|
66
57
|
const {
|
|
67
58
|
distMethod,
|
|
@@ -72,22 +63,27 @@ export class Aggregate extends AggregateBase {
|
|
|
72
63
|
|
|
73
64
|
// frameworks on page
|
|
74
65
|
if (isBrowserScope) {
|
|
66
|
+
this.storeSupportabilityMetrics('Generic/Runtime/Browser/Detected');
|
|
67
|
+
|
|
68
|
+
// These SMs are used by the AppExp team
|
|
75
69
|
onDOMContentLoaded(() => {
|
|
76
70
|
getFrameworks().forEach(framework => {
|
|
77
71
|
this.storeSupportabilityMetrics('Framework/' + framework + '/Detected');
|
|
78
72
|
});
|
|
79
73
|
});
|
|
74
|
+
} else if (isWorkerScope) {
|
|
75
|
+
this.storeSupportabilityMetrics('Generic/Runtime/Worker/Detected');
|
|
76
|
+
} else {
|
|
77
|
+
this.storeSupportabilityMetrics('Generic/Runtime/Unknown/Detected');
|
|
80
78
|
}
|
|
81
|
-
getPolyfills().forEach(polyfill => {
|
|
82
|
-
this.storeSupportabilityMetrics('Polyfill/' + polyfill + '/Detected');
|
|
83
|
-
});
|
|
84
79
|
|
|
85
|
-
// file protocol
|
|
80
|
+
// Track if the agent is being loaded using a file protocol such as is the case in some
|
|
81
|
+
// set-top box applications or Electron applications
|
|
86
82
|
if (isFileProtocol()) {
|
|
87
83
|
this.storeSupportabilityMetrics('Generic/FileProtocol/Detected');
|
|
88
84
|
}
|
|
89
85
|
|
|
90
|
-
// obfuscation
|
|
86
|
+
// Capture SMs to assess customer engagement with the obfuscation config
|
|
91
87
|
const rules = getRules(this.agentIdentifier);
|
|
92
88
|
if (rules.length > 0) this.storeSupportabilityMetrics('Generic/Obfuscate/Detected');
|
|
93
89
|
if (rules.length > 0 && !validateRules(rules)) this.storeSupportabilityMetrics('Generic/Obfuscate/Invalid');
|
|
@@ -100,18 +96,17 @@ export class Aggregate extends AggregateBase {
|
|
|
100
96
|
if (evt.persisted) {
|
|
101
97
|
this.storeSupportabilityMetrics('Generic/BFCache/PageRestored');
|
|
102
98
|
}
|
|
103
|
-
return;
|
|
104
99
|
});
|
|
105
100
|
}
|
|
106
101
|
unload() {
|
|
107
|
-
// Page Resources detection for estimations with resources feature work
|
|
108
|
-
// TODO - these SMs are to be removed when we implement the actual resources feature
|
|
109
102
|
try {
|
|
110
103
|
if (this.resourcesSent) return;
|
|
104
|
+
this.resourcesSent = true; // make sure this only gets sent once
|
|
105
|
+
|
|
111
106
|
const agentRuntime = getRuntime(this.agentIdentifier);
|
|
112
|
-
|
|
113
|
-
//
|
|
114
|
-
this
|
|
107
|
+
|
|
108
|
+
// Capture SMs around network resources using the performance API to assess
|
|
109
|
+
// work to split this out from the ST nodes
|
|
115
110
|
// differentiate between internal+external and ajax+non-ajax
|
|
116
111
|
const ajaxResources = ['beacon', 'fetch', 'xmlhttprequest'];
|
|
117
112
|
const internalUrls = ['nr-data.net', 'newrelic.com', 'nr-local.net', 'localhost'];
|
|
@@ -130,26 +125,14 @@ export class Aggregate extends AggregateBase {
|
|
|
130
125
|
}
|
|
131
126
|
});
|
|
132
127
|
|
|
133
|
-
// Capture
|
|
134
|
-
|
|
135
|
-
this.storeSupportabilityMetrics("PageSession/Endpoint/".concat(endpointMap[endpoint], "/BytesSent"), agentRuntime.bytesSent[endpoint]);
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
// Capture per-agent query bytes sent for each endpoint (see harvest) and RUM call (see page_view_event aggregator).
|
|
139
|
-
Object.keys(agentRuntime.bytesSent).forEach(endpoint => {
|
|
140
|
-
this.storeSupportabilityMetrics("PageSession/Endpoint/".concat(endpointMap[endpoint], "/QueryBytesSent"), agentRuntime.queryBytesSent[endpoint]);
|
|
141
|
-
});
|
|
142
|
-
|
|
143
|
-
// Capture metrics for session trace if active (`ptid` is set when returned by replay ingest).
|
|
128
|
+
// Capture SMs for session trace if active (`ptid` is set when returned by replay ingest).
|
|
129
|
+
// Retain these SMs while we are working through the session_replay feature
|
|
144
130
|
if (agentRuntime.ptid) {
|
|
145
131
|
this.storeSupportabilityMetrics('PageSession/Feature/SessionTrace/DurationMs', Math.round(performance.now()));
|
|
146
132
|
}
|
|
147
133
|
|
|
148
|
-
// Capture
|
|
149
|
-
|
|
150
|
-
this.storeSupportabilityMetrics('PageSession/Feature/CustomData/Bytes', jsAttributes === '{}' ? 0 : jsAttributes.length);
|
|
151
|
-
|
|
152
|
-
// Capture metrics for performance markers and measures
|
|
134
|
+
// Capture SMs for performance markers and measures to assess the usage and possible inclusion of this
|
|
135
|
+
// data in the agent for use in NR
|
|
153
136
|
if (typeof performance !== 'undefined') {
|
|
154
137
|
const markers = performance.getEntriesByType('mark');
|
|
155
138
|
const measures = performance.getEntriesByType('measure');
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import { InstrumentBase } from '../../utils/instrument-base';
|
|
2
|
-
import { FEATURE_NAME
|
|
3
|
-
import { handle } from '../../../common/event-emitter/handle';
|
|
4
|
-
import { FEATURE_NAMES } from '../../../loaders/features/features';
|
|
2
|
+
import { FEATURE_NAME } from '../constants';
|
|
5
3
|
export class Instrument extends InstrumentBase {
|
|
6
4
|
static featureName = FEATURE_NAME;
|
|
7
5
|
constructor(agentIdentifier, aggregator) {
|
|
@@ -10,7 +10,6 @@ import { HarvestScheduler } from '../../../common/harvest/harvest-scheduler';
|
|
|
10
10
|
import { cleanURL } from '../../../common/url/clean-url';
|
|
11
11
|
import { getConfigurationValue, getInfo, getRuntime } from '../../../common/config/config';
|
|
12
12
|
import { FEATURE_NAME } from '../constants';
|
|
13
|
-
import { drain } from '../../../common/drain/drain';
|
|
14
13
|
import { isBrowserScope } from '../../../common/constants/runtime';
|
|
15
14
|
import { AggregateBase } from '../../utils/aggregate-base';
|
|
16
15
|
export class Aggregate extends AggregateBase {
|
|
@@ -22,8 +21,8 @@ export class Aggregate extends AggregateBase {
|
|
|
22
21
|
this.eventsPerMinute = 240;
|
|
23
22
|
this.harvestTimeSeconds = getConfigurationValue(this.agentIdentifier, 'page_action.harvestTimeSeconds') || getConfigurationValue(this.agentIdentifier, 'ins.harvestTimeSeconds') || 30;
|
|
24
23
|
this.eventsPerHarvest = this.eventsPerMinute * this.harvestTimeSeconds / 60;
|
|
25
|
-
this.referrerUrl;
|
|
26
|
-
this.currentEvents;
|
|
24
|
+
this.referrerUrl = undefined;
|
|
25
|
+
this.currentEvents = undefined;
|
|
27
26
|
this.events = [];
|
|
28
27
|
this.att = getInfo(this.agentIdentifier).jsAttributes; // per-agent, aggregators-shared info context
|
|
29
28
|
|
|
@@ -31,24 +30,23 @@ export class Aggregate extends AggregateBase {
|
|
|
31
30
|
register('api-addPageAction', function () {
|
|
32
31
|
return _this.addPageAction(...arguments);
|
|
33
32
|
}, this.featureName, this.ee);
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
33
|
+
this.waitForFlags(['ins']).then(_ref => {
|
|
34
|
+
let [enabled] = _ref;
|
|
35
|
+
if (enabled) {
|
|
36
|
+
const scheduler = new HarvestScheduler('ins', {
|
|
37
|
+
onFinished: function () {
|
|
38
|
+
return _this.onHarvestFinished(...arguments);
|
|
39
|
+
}
|
|
40
|
+
}, this);
|
|
41
|
+
scheduler.harvest.on('ins', function () {
|
|
42
|
+
return _this.onHarvestStarted(...arguments);
|
|
43
|
+
});
|
|
44
|
+
scheduler.startTimer(this.harvestTimeSeconds, 0);
|
|
45
|
+
} else {
|
|
46
|
+
this.blocked = true;
|
|
37
47
|
}
|
|
38
|
-
}, this);
|
|
39
|
-
scheduler.harvest.on('ins', function () {
|
|
40
|
-
return _this.onHarvestStarted(...arguments);
|
|
41
48
|
});
|
|
42
|
-
this.
|
|
43
|
-
if (!this.blocked) scheduler.startTimer(this.harvestTimeSeconds, 0);
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
// if rum response determines that customer lacks entitlements for ins endpoint, block it
|
|
47
|
-
register('block-ins', () => {
|
|
48
|
-
this.blocked = true;
|
|
49
|
-
scheduler.stopTimer(true);
|
|
50
|
-
}, this.featureName, this.ee);
|
|
51
|
-
drain(this.agentIdentifier, this.featureName);
|
|
49
|
+
this.drain();
|
|
52
50
|
}
|
|
53
51
|
onHarvestStarted(options) {
|
|
54
52
|
const {
|
|
@@ -9,7 +9,6 @@ import { getConfigurationValue, getInfo, getRuntime } from '../../../common/conf
|
|
|
9
9
|
import { Harvest } from '../../../common/harvest/harvest';
|
|
10
10
|
import * as CONSTANTS from '../constants';
|
|
11
11
|
import { getActivatedFeaturesFlags } from './initialized-features';
|
|
12
|
-
import { drain } from '../../../common/drain/drain';
|
|
13
12
|
import { activateFeatures } from '../../../common/util/feature-flags';
|
|
14
13
|
import { warn } from '../../../common/util/console';
|
|
15
14
|
import { AggregateBase } from '../../utils/aggregate-base';
|
|
@@ -147,7 +146,7 @@ export class Aggregate extends AggregateBase {
|
|
|
147
146
|
}
|
|
148
147
|
try {
|
|
149
148
|
activateFeatures(JSON.parse(responseText), this.agentIdentifier);
|
|
150
|
-
drain(
|
|
149
|
+
this.drain();
|
|
151
150
|
} catch (err) {
|
|
152
151
|
this.ee.abort();
|
|
153
152
|
warn('RUM call failed. Agent shutting down.');
|
|
@@ -13,10 +13,12 @@ export class Instrument extends InstrumentBase {
|
|
|
13
13
|
super(agentIdentifier, aggregator, CONSTANTS.FEATURE_NAME, auto);
|
|
14
14
|
if ((typeof PerformanceNavigationTiming === 'undefined' || isiOS) && typeof PerformanceTiming !== 'undefined') {
|
|
15
15
|
// For majority browser versions in which PNT exists, we can get load timings later from the nav entry (in the aggregate portion). At minimum, PT should exist for main window.
|
|
16
|
-
// *cli Mar'23 - iOS 15.2 & 15.4 testing in Sauce still fails with onTTFB. Hence, all iOS will fallback to this for now. Unknown if this is similar in nature to
|
|
16
|
+
// *cli Mar'23 - iOS 15.2 & 15.4 testing in Sauce still fails with onTTFB. Hence, all iOS will fallback to this for now. Unknown if this is similar in nature to iOSBelow16 bug.
|
|
17
17
|
const agentRuntime = getRuntime(agentIdentifier);
|
|
18
18
|
agentRuntime[CONSTANTS.TTFB] = Math.max(Date.now() - agentRuntime.offset, 0);
|
|
19
|
-
onDOMContentLoaded(() =>
|
|
19
|
+
onDOMContentLoaded(() => {
|
|
20
|
+
agentRuntime[CONSTANTS.FBTDC] = Math.max(now() - agentRuntime[CONSTANTS.TTFB], 0);
|
|
21
|
+
});
|
|
20
22
|
onWindowLoad(() => {
|
|
21
23
|
const timeNow = now();
|
|
22
24
|
agentRuntime[CONSTANTS.FBTWL] = Math.max(timeNow - agentRuntime[CONSTANTS.TTFB], 0);
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
import { onFCP, onFID, onLCP, onCLS, onINP } from 'web-vitals';
|
|
7
7
|
import { onFirstPaint } from '../first-paint';
|
|
8
8
|
import { onLongTask } from '../long-tasks';
|
|
9
|
-
import {
|
|
9
|
+
import { iOSBelow16 } from '../../../common/constants/runtime';
|
|
10
10
|
import { nullable, numeric, getAddStringContext, addCustomAttributes } from '../../../common/serialize/bel-serializer';
|
|
11
11
|
import { mapOwn } from '../../../common/util/map-own';
|
|
12
12
|
import { HarvestScheduler } from '../../../common/harvest/harvest-scheduler';
|
|
@@ -15,7 +15,6 @@ import { cleanURL } from '../../../common/url/clean-url';
|
|
|
15
15
|
import { handle } from '../../../common/event-emitter/handle';
|
|
16
16
|
import { getInfo, getConfigurationValue, getRuntime } from '../../../common/config/config';
|
|
17
17
|
import { FEATURE_NAME } from '../constants';
|
|
18
|
-
import { drain } from '../../../common/drain/drain';
|
|
19
18
|
import { FEATURE_NAMES } from '../../../loaders/features/features';
|
|
20
19
|
import { AggregateBase } from '../../utils/aggregate-base';
|
|
21
20
|
export class Aggregate extends AggregateBase {
|
|
@@ -45,7 +44,7 @@ export class Aggregate extends AggregateBase {
|
|
|
45
44
|
});
|
|
46
45
|
|
|
47
46
|
/* First Contentful Paint - As of WV v3, it still imperfectly tries to detect document vis state asap and isn't supposed to report if page starts hidden. */
|
|
48
|
-
if (
|
|
47
|
+
if (iOSBelow16) {
|
|
49
48
|
try {
|
|
50
49
|
if (!pageStartedHidden) {
|
|
51
50
|
// see ios-version.js for detail on this following bug case; tldr: buffered flag doesn't work but getEntriesByType does
|
|
@@ -121,7 +120,7 @@ export class Aggregate extends AggregateBase {
|
|
|
121
120
|
let {
|
|
122
121
|
value
|
|
123
122
|
} = _ref5;
|
|
124
|
-
|
|
123
|
+
this.cls = value;
|
|
125
124
|
}, {
|
|
126
125
|
reportAllChanges: true
|
|
127
126
|
});
|
|
@@ -170,7 +169,7 @@ export class Aggregate extends AggregateBase {
|
|
|
170
169
|
this.ee.on("drain-".concat(this.featureName), () => {
|
|
171
170
|
this.scheduler.startTimer(harvestTimeSeconds, initialHarvestSeconds);
|
|
172
171
|
});
|
|
173
|
-
drain(
|
|
172
|
+
this.drain();
|
|
174
173
|
}
|
|
175
174
|
|
|
176
175
|
// takes an attributes object and appends connection attributes if available
|
|
@@ -224,9 +223,9 @@ export class Aggregate extends AggregateBase {
|
|
|
224
223
|
attrs.cls = this.cls;
|
|
225
224
|
}
|
|
226
225
|
this.timings.push({
|
|
227
|
-
name
|
|
228
|
-
value
|
|
229
|
-
attrs
|
|
226
|
+
name,
|
|
227
|
+
value,
|
|
228
|
+
attrs
|
|
230
229
|
});
|
|
231
230
|
handle('pvtAdded', [name, value, attrs], undefined, FEATURE_NAMES.sessionTrace, this.ee);
|
|
232
231
|
}
|
|
@@ -10,7 +10,6 @@
|
|
|
10
10
|
* functionality is validated and a full user experience is curated.
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
import { drain } from '../../../common/drain/drain';
|
|
14
13
|
import { registerHandler } from '../../../common/event-emitter/register-handler';
|
|
15
14
|
import { HarvestScheduler } from '../../../common/harvest/harvest-scheduler';
|
|
16
15
|
import { FEATURE_NAME } from '../constants';
|
|
@@ -20,6 +19,7 @@ import { SESSION_EVENTS, MODE } from '../../../common/session/session-entity';
|
|
|
20
19
|
import { AggregateBase } from '../../utils/aggregate-base';
|
|
21
20
|
import { sharedChannel } from '../../../common/constants/shared-channel';
|
|
22
21
|
import { obj as encodeObj } from '../../../common/url/encode';
|
|
22
|
+
import { warn } from '../../../common/util/console';
|
|
23
23
|
|
|
24
24
|
// would be better to get this dynamically in some way
|
|
25
25
|
export const RRWEB_VERSION = '2.0.0-alpha.8';
|
|
@@ -127,7 +127,7 @@ export class Aggregate extends AggregateBase {
|
|
|
127
127
|
return this.initializeRecording(flagOn, Math.random() < getConfigurationValue(this.agentIdentifier, 'session_replay.errorSampleRate'), Math.random() < getConfigurationValue(this.agentIdentifier, 'session_replay.sampleRate'));
|
|
128
128
|
}).then(() => sharedChannel.onReplayReady(this.mode)); // notify watchers that replay started with the mode
|
|
129
129
|
|
|
130
|
-
drain(
|
|
130
|
+
this.drain();
|
|
131
131
|
}
|
|
132
132
|
}
|
|
133
133
|
|
|
@@ -174,11 +174,13 @@ export class Aggregate extends AggregateBase {
|
|
|
174
174
|
this.scheduler.startTimer(this.harvestTimeSeconds);
|
|
175
175
|
}
|
|
176
176
|
try {
|
|
177
|
+
// Do not change the webpackChunkName or it will break the webpack nrba-chunking plugin
|
|
177
178
|
recorder = (await import( /* webpackChunkName: "recorder" */'rrweb')).record;
|
|
178
179
|
} catch (err) {
|
|
179
180
|
return this.abort();
|
|
180
181
|
}
|
|
181
182
|
try {
|
|
183
|
+
// Do not change the webpackChunkName or it will break the webpack nrba-chunking plugin
|
|
182
184
|
const {
|
|
183
185
|
gzipSync,
|
|
184
186
|
strToU8
|
|
@@ -8,7 +8,6 @@ import { parseUrl } from '../../../common/url/parse-url';
|
|
|
8
8
|
import { getConfigurationValue, getRuntime } from '../../../common/config/config';
|
|
9
9
|
import { now } from '../../../common/timing/now';
|
|
10
10
|
import { FEATURE_NAME } from '../constants';
|
|
11
|
-
import { drain } from '../../../common/drain/drain';
|
|
12
11
|
import { HandlerCache } from '../../utils/handler-cache';
|
|
13
12
|
import { MODE, SESSION_EVENTS } from '../../../common/session/session-entity';
|
|
14
13
|
import { getSessionReplayMode } from '../../session_replay/replay-mode';
|
|
@@ -57,9 +56,13 @@ export class Aggregate extends AggregateBase {
|
|
|
57
56
|
this.sentTrace = null;
|
|
58
57
|
this.harvestTimeSeconds = getConfigurationValue(agentIdentifier, 'session_trace.harvestTimeSeconds') || 10;
|
|
59
58
|
this.maxNodesPerHarvest = getConfigurationValue(agentIdentifier, 'session_trace.maxNodesPerHarvest') || 1000;
|
|
59
|
+
/**
|
|
60
|
+
* Standalone (mode) refers to the legacy version of ST before the idea of 'session' or the Replay feature existed.
|
|
61
|
+
* It has some different behavior vs when used in tandem with replay. */
|
|
60
62
|
this.isStandalone = false;
|
|
61
63
|
const operationalGate = new HandlerCache(); // acts as a controller-intermediary that can enable or disable this feature's collection dynamically
|
|
62
64
|
const sessionEntity = this.agentRuntime.session;
|
|
65
|
+
this.operationalGate = operationalGate;
|
|
63
66
|
|
|
64
67
|
/* --- The following section deals with user sessions concept & contains non-trivial control flow. --- */
|
|
65
68
|
const controlTraceOp = traceMode => {
|
|
@@ -133,7 +136,9 @@ export class Aggregate extends AggregateBase {
|
|
|
133
136
|
});
|
|
134
137
|
mostRecentModeKnown = updatedTraceMode;
|
|
135
138
|
});
|
|
136
|
-
this.ee.on(SESSION_EVENTS.PAUSE, () =>
|
|
139
|
+
this.ee.on(SESSION_EVENTS.PAUSE, () => {
|
|
140
|
+
mostRecentModeKnown = sessionEntity.state.sessionTraceMode;
|
|
141
|
+
});
|
|
137
142
|
if (!sessionEntity.isNew) {
|
|
138
143
|
// inherit the same mode as existing session's Trace
|
|
139
144
|
if (sessionEntity.state.sessionReplay === MODE.OFF) this.isStandalone = true;
|
|
@@ -205,7 +210,7 @@ export class Aggregate extends AggregateBase {
|
|
|
205
210
|
}
|
|
206
211
|
return operationalGate.settle(() => _this.processPVT(...args));
|
|
207
212
|
}, this.featureName, this.ee);
|
|
208
|
-
drain(
|
|
213
|
+
this.drain();
|
|
209
214
|
}
|
|
210
215
|
startTracing(startupBuffer) {
|
|
211
216
|
let dontStartHarvestYet = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
@@ -243,17 +248,16 @@ export class Aggregate extends AggregateBase {
|
|
|
243
248
|
}
|
|
244
249
|
}
|
|
245
250
|
#prepareHarvest(options) {
|
|
246
|
-
/* Standalone refers to the legacy version of ST before the idea of 'session' or the Replay feature existed.
|
|
247
|
-
It has a different behavior on returning a payload for harvest than when used in tandem with either of those concepts. */
|
|
248
251
|
if (this.isStandalone) {
|
|
249
|
-
if (now()
|
|
250
|
-
//
|
|
251
|
-
|
|
252
|
-
this.
|
|
252
|
+
if (this.ptid && now() >= MAX_TRACE_DURATION) {
|
|
253
|
+
// Perform a final harvest once we hit or exceed the max session trace time
|
|
254
|
+
options.isFinalHarvest = true;
|
|
255
|
+
this.operationalGate.permanentlyDecide(false);
|
|
256
|
+
this.#scheduler.stopTimer(true);
|
|
257
|
+
} else if (this.ptid && this.nodeCount <= REQ_THRESHOLD_TO_SEND && !options.isFinalHarvest) {
|
|
258
|
+
// Only harvest when more than some threshold of nodes are pending, after the very first harvest, with the exception of the last outgoing harvest.
|
|
253
259
|
return;
|
|
254
260
|
}
|
|
255
|
-
// Only harvest when more than some threshold of nodes are pending, after the very first harvest.
|
|
256
|
-
if (this.ptid && this.nodeCount <= REQ_THRESHOLD_TO_SEND) return;
|
|
257
261
|
} else {
|
|
258
262
|
// -- *cli May '26 - Update: Not rate limiting backgrounded pages either for now.
|
|
259
263
|
// if (this.ptid && document.visibilityState === 'hidden' && this.nodeCount <= REQ_THRESHOLD_TO_SEND) return
|
|
@@ -330,8 +334,7 @@ export class Aggregate extends AggregateBase {
|
|
|
330
334
|
const origin = this.evtOrigin(event.target, target);
|
|
331
335
|
if (event.type in ignoredEvents.global) return true;
|
|
332
336
|
if (!!ignoredEvents[origin] && ignoredEvents[origin].ignoreAll) return true;
|
|
333
|
-
|
|
334
|
-
return false;
|
|
337
|
+
return !!(!!ignoredEvents[origin] && event.type in ignoredEvents[origin]);
|
|
335
338
|
}
|
|
336
339
|
evtName(type) {
|
|
337
340
|
switch (type) {
|
|
@@ -441,7 +444,10 @@ export class Aggregate extends AggregateBase {
|
|
|
441
444
|
// limit the amount of pending data awaiting next harvest
|
|
442
445
|
if (this.isStandalone || this.agentRuntime.session.state.sessionTraceMode !== MODE.ERROR) return;
|
|
443
446
|
const openedSpace = this.trimSTNs(ERROR_MODE_SECONDS_WINDOW); // but maybe we could make some space by discarding irrelevant nodes if we're in sessioned Error mode
|
|
444
|
-
if (openedSpace
|
|
447
|
+
if (openedSpace === 0) return;
|
|
448
|
+
}
|
|
449
|
+
if (this.isStandalone && now() >= MAX_TRACE_DURATION) {
|
|
450
|
+
return;
|
|
445
451
|
}
|
|
446
452
|
if (this.trace[stn.n]) this.trace[stn.n].push(stn);else this.trace[stn.n] = [stn];
|
|
447
453
|
this.nodeCount++;
|
|
@@ -461,7 +467,7 @@ export class Aggregate extends AggregateBase {
|
|
|
461
467
|
* This isn't exact since nodes go through some processing & EE handlers chain, but it's close enough as we still capture nodes whose duration overlaps the lookback window.
|
|
462
468
|
* ASSUMPTION: all 'end' timings stored are relative to timeOrigin (DOMHighResTimeStamp) and not Unix epoch based. */
|
|
463
469
|
let cutoffIdx = nodeList.findIndex(node => cutoffHighResTime <= node.e);
|
|
464
|
-
if (cutoffIdx
|
|
470
|
+
if (cutoffIdx === 0) return;else if (cutoffIdx < 0) {
|
|
465
471
|
// whole list falls outside lookback window and is irrelevant
|
|
466
472
|
cutoffIdx = nodeList.length;
|
|
467
473
|
delete this.trace[nameCategory];
|
|
@@ -525,7 +531,7 @@ export class Aggregate extends AggregateBase {
|
|
|
525
531
|
};
|
|
526
532
|
function trivial(node) {
|
|
527
533
|
const limit = 4;
|
|
528
|
-
|
|
534
|
+
return !!(node && typeof node.e === 'number' && typeof node.s === 'number' && node.e - node.s < limit);
|
|
529
535
|
}
|
|
530
536
|
}
|
|
531
537
|
}
|
|
@@ -17,7 +17,6 @@ import { HarvestScheduler } from '../../../common/harvest/harvest-scheduler';
|
|
|
17
17
|
import { Serializer } from './serializer';
|
|
18
18
|
import { ee } from '../../../common/event-emitter/contextual-ee';
|
|
19
19
|
import * as CONSTANTS from '../constants';
|
|
20
|
-
import { drain } from '../../../common/drain/drain';
|
|
21
20
|
import { FEATURE_NAMES } from '../../../loaders/features/features';
|
|
22
21
|
import { AggregateBase } from '../../utils/aggregate-base';
|
|
23
22
|
const {
|
|
@@ -135,8 +134,8 @@ export class Aggregate extends AggregateBase {
|
|
|
135
134
|
|
|
136
135
|
// register plugins
|
|
137
136
|
var pluginApi = {
|
|
138
|
-
getCurrentNode
|
|
139
|
-
setCurrentNode
|
|
137
|
+
getCurrentNode,
|
|
138
|
+
setCurrentNode
|
|
140
139
|
};
|
|
141
140
|
register('spa-register', function (init) {
|
|
142
141
|
if (typeof init === 'function') {
|
|
@@ -201,21 +200,19 @@ export class Aggregate extends AggregateBase {
|
|
|
201
200
|
// If this event was emitted by an XHR, restore the node ID associated with
|
|
202
201
|
// that XHR.
|
|
203
202
|
setCurrentNode(baseEE.context(eventSource).spaNode);
|
|
204
|
-
} else if (!state.currentNode) {
|
|
203
|
+
} else if (!state.currentNode && INTERACTION_EVENTS.indexOf(evName) !== -1) {
|
|
205
204
|
// Otherwise, if no interaction is currently active, create a new node ID,
|
|
206
205
|
// and let the aggregator know that we entered a new event handler callback
|
|
207
206
|
// so that it has a chance to possibly start an interaction.
|
|
208
|
-
|
|
209
|
-
var ixn = new Interaction(evName, this[FN_START], state.lastSeenUrl, state.lastSeenRouteName, onInteractionFinished, agentIdentifier);
|
|
207
|
+
var ixn = new Interaction(evName, this[FN_START], state.lastSeenUrl, state.lastSeenRouteName, onInteractionFinished, agentIdentifier);
|
|
210
208
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
}
|
|
209
|
+
// Store the interaction as prevInteraction in case it is prematurely discarded
|
|
210
|
+
state.prevInteraction = ixn;
|
|
211
|
+
setCurrentNode(ixn.root);
|
|
212
|
+
if (evName === 'click') {
|
|
213
|
+
var value = getActionText(ev.target);
|
|
214
|
+
if (value) {
|
|
215
|
+
state.currentNode.attrs.custom.actionText = value;
|
|
219
216
|
}
|
|
220
217
|
}
|
|
221
218
|
}
|
|
@@ -497,7 +494,7 @@ export class Aggregate extends AggregateBase {
|
|
|
497
494
|
}, this.featureName, promiseEE);
|
|
498
495
|
register(INTERACTION_API + 'get', function (t) {
|
|
499
496
|
var interaction;
|
|
500
|
-
if (state?.currentNode?.[INTERACTION]) interaction = this.ixn = state.currentNode[INTERACTION];else if (state?.prevNode?.end === null && state?.prevNode?.[INTERACTION]?.root?.[INTERACTION]?.eventName
|
|
497
|
+
if (state?.currentNode?.[INTERACTION]) interaction = this.ixn = state.currentNode[INTERACTION];else if (state?.prevNode?.end === null && state?.prevNode?.[INTERACTION]?.root?.[INTERACTION]?.eventName !== 'initialPageLoad') interaction = this.ixn = state.prevNode[INTERACTION];else interaction = this.ixn = new Interaction('api', t, state.lastSeenUrl, state.lastSeenRouteName, onInteractionFinished, agentIdentifier);
|
|
501
498
|
if (!state.currentNode) {
|
|
502
499
|
interaction.checkFinish();
|
|
503
500
|
if (state.depth) setCurrentNode(interaction.root);
|
|
@@ -665,11 +662,8 @@ export class Aggregate extends AggregateBase {
|
|
|
665
662
|
}
|
|
666
663
|
function isEnabled() {
|
|
667
664
|
var enabled = getConfigurationValue(agentIdentifier, 'spa.enabled');
|
|
668
|
-
|
|
669
|
-
return false;
|
|
670
|
-
}
|
|
671
|
-
return true;
|
|
665
|
+
return enabled !== false;
|
|
672
666
|
}
|
|
673
|
-
drain(
|
|
667
|
+
this.drain();
|
|
674
668
|
}
|
|
675
669
|
}
|