@newrelic/browser-agent 1.232.1 → 1.233.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/cdn/experimental.js +27 -0
- 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 +43 -8
- package/dist/cjs/common/harvest/harvest-scheduler.test.js +39 -0
- package/dist/cjs/common/harvest/harvest.js +106 -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/protocol.test.js +0 -1
- package/dist/cjs/common/util/feature-flags.js +2 -1
- package/dist/cjs/common/util/submit-data.js +57 -18
- package/dist/cjs/common/wrap/wrap-fetch.js +1 -1
- package/dist/cjs/common/wrap/wrap-function.js +1 -1
- package/dist/cjs/common/wrap/wrap-promise.js +1 -1
- package/dist/cjs/features/ajax/aggregate/index.js +2 -2
- package/dist/cjs/features/jserrors/aggregate/index.js +7 -5
- 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 +336 -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 -162
- 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/experimental.js +24 -0
- 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 +43 -8
- package/dist/esm/common/harvest/harvest-scheduler.test.js +37 -0
- package/dist/esm/common/harvest/harvest.js +108 -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/protocol.test.js +0 -1
- package/dist/esm/common/util/feature-flags.js +2 -1
- package/dist/esm/common/util/submit-data.js +57 -18
- package/dist/esm/common/wrap/wrap-fetch.js +1 -1
- package/dist/esm/common/wrap/wrap-function.js +1 -1
- package/dist/esm/common/wrap/wrap-promise.js +1 -1
- package/dist/esm/features/ajax/aggregate/index.js +2 -2
- package/dist/esm/features/jserrors/aggregate/index.js +7 -5
- 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 +330 -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 -162
- 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/cdn/experimental.d.ts +2 -0
- package/dist/types/cdn/experimental.d.ts.map +1 -0
- 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 +26 -3
- 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/util/feature-flags.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/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/index.d.ts +2 -2
- package/dist/types/features/jserrors/aggregate/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 +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 +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 +100 -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 +30 -20
- package/src/cdn/experimental.js +36 -0
- 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 +48 -8
- package/src/common/harvest/harvest-scheduler.test.js +25 -0
- package/src/common/harvest/harvest.js +72 -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/protocol.test.js +0 -1
- package/src/common/util/feature-flags.js +2 -2
- package/src/common/util/submit-data.js +28 -17
- package/src/common/wrap/wrap-fetch.js +1 -1
- package/src/common/wrap/wrap-function.js +1 -1
- package/src/common/wrap/wrap-promise.js +1 -1
- package/src/features/ajax/aggregate/index.js +2 -2
- package/src/features/jserrors/aggregate/index.js +7 -5
- 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 +319 -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 -187
- 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
|
@@ -1,61 +1,106 @@
|
|
|
1
1
|
import { DEFAULT_EXPIRES_MS, DEFAULT_INACTIVE_MS } from '../../session/constants';
|
|
2
|
-
import { globalScope } from '../../util/global-scope';
|
|
3
2
|
import { gosNREUMInitializedAgents } from '../../window/nreum';
|
|
4
|
-
import {
|
|
5
|
-
const model = {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
3
|
+
import { getModeledObject } from './configurable';
|
|
4
|
+
const model = () => {
|
|
5
|
+
const hiddenState = {
|
|
6
|
+
blockSelector: '[data-nr-block]',
|
|
7
|
+
maskInputOptions: {
|
|
8
|
+
password: true
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
return {
|
|
12
|
+
allow_bfcache: true,
|
|
13
|
+
// *cli - temporary feature flag for BFCache work
|
|
14
|
+
privacy: {
|
|
15
|
+
cookies_enabled: true
|
|
16
|
+
},
|
|
17
|
+
// *cli - per discussion, default should be true
|
|
18
|
+
ajax: {
|
|
19
|
+
deny_list: undefined,
|
|
20
|
+
enabled: true,
|
|
21
|
+
harvestTimeSeconds: 10
|
|
22
|
+
},
|
|
23
|
+
distributed_tracing: {
|
|
24
|
+
enabled: undefined,
|
|
25
|
+
exclude_newrelic_header: undefined,
|
|
26
|
+
cors_use_newrelic_header: undefined,
|
|
27
|
+
cors_use_tracecontext_headers: undefined,
|
|
28
|
+
allowed_origins: undefined
|
|
29
|
+
},
|
|
30
|
+
session: {
|
|
31
|
+
domain: undefined,
|
|
32
|
+
// used by first party cookies to set the top-level domain
|
|
33
|
+
expiresMs: DEFAULT_EXPIRES_MS,
|
|
34
|
+
inactiveMs: DEFAULT_INACTIVE_MS
|
|
35
|
+
},
|
|
36
|
+
ssl: undefined,
|
|
37
|
+
obfuscate: undefined,
|
|
38
|
+
jserrors: {
|
|
39
|
+
enabled: true,
|
|
40
|
+
harvestTimeSeconds: 10
|
|
41
|
+
},
|
|
42
|
+
metrics: {
|
|
43
|
+
enabled: true
|
|
44
|
+
},
|
|
45
|
+
page_action: {
|
|
46
|
+
enabled: true,
|
|
47
|
+
harvestTimeSeconds: 30
|
|
48
|
+
},
|
|
49
|
+
page_view_event: {
|
|
50
|
+
enabled: true
|
|
51
|
+
},
|
|
52
|
+
page_view_timing: {
|
|
53
|
+
enabled: true,
|
|
54
|
+
harvestTimeSeconds: 30,
|
|
55
|
+
long_task: false
|
|
56
|
+
},
|
|
57
|
+
session_trace: {
|
|
58
|
+
enabled: true,
|
|
59
|
+
harvestTimeSeconds: 10
|
|
60
|
+
},
|
|
61
|
+
session_replay: {
|
|
62
|
+
// feature settings
|
|
63
|
+
enabled: false,
|
|
64
|
+
harvestTimeSeconds: 60,
|
|
65
|
+
sampleRate: 0.1,
|
|
66
|
+
errorSampleRate: 0.1,
|
|
67
|
+
// recording config settings
|
|
68
|
+
maskTextSelector: '*',
|
|
69
|
+
maskAllInputs: true,
|
|
70
|
+
// these properties only have getters because they are enforcable constants and should error if someone tries to override them
|
|
71
|
+
get blockClass() {
|
|
72
|
+
return 'nr-block';
|
|
73
|
+
},
|
|
74
|
+
get ignoreClass() {
|
|
75
|
+
return 'nr-ignore';
|
|
76
|
+
},
|
|
77
|
+
get maskTextClass() {
|
|
78
|
+
return 'nr-mask';
|
|
79
|
+
},
|
|
80
|
+
// props with a getter and setter are used to extend enforcable constants with customer input
|
|
81
|
+
// we must preserve data-nr-block no matter what else the customer sets
|
|
82
|
+
get blockSelector() {
|
|
83
|
+
return hiddenState.blockSelector;
|
|
84
|
+
},
|
|
85
|
+
set blockSelector(val) {
|
|
86
|
+
hiddenState.blockSelector += ",".concat(val);
|
|
87
|
+
},
|
|
88
|
+
// password: must always be present and true no matter what customer sets
|
|
89
|
+
get maskInputOptions() {
|
|
90
|
+
return hiddenState.maskInputOptions;
|
|
91
|
+
},
|
|
92
|
+
set maskInputOptions(val) {
|
|
93
|
+
hiddenState.maskInputOptions = {
|
|
94
|
+
...val,
|
|
95
|
+
password: true
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
spa: {
|
|
100
|
+
enabled: true,
|
|
101
|
+
harvestTimeSeconds: 10
|
|
102
|
+
}
|
|
103
|
+
};
|
|
59
104
|
};
|
|
60
105
|
const _cache = {};
|
|
61
106
|
export function getConfiguration(id) {
|
|
@@ -65,7 +110,7 @@ export function getConfiguration(id) {
|
|
|
65
110
|
}
|
|
66
111
|
export function setConfiguration(id, obj) {
|
|
67
112
|
if (!id) throw new Error('All configuration objects require an agent identifier!');
|
|
68
|
-
_cache[id] =
|
|
113
|
+
_cache[id] = getModeledObject(obj, model());
|
|
69
114
|
gosNREUMInitializedAgents(id, _cache[id], 'config');
|
|
70
115
|
}
|
|
71
116
|
export function getConfigurationValue(id, path) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { gosNREUMInitializedAgents } from '../../window/nreum';
|
|
2
|
-
import {
|
|
2
|
+
import { getModeledObject } from './configurable';
|
|
3
3
|
const model = {
|
|
4
4
|
accountID: undefined,
|
|
5
5
|
trustKey: undefined,
|
|
@@ -16,6 +16,6 @@ export function getLoaderConfig(id) {
|
|
|
16
16
|
}
|
|
17
17
|
export function setLoaderConfig(id, obj) {
|
|
18
18
|
if (!id) throw new Error('All loader-config objects require an agent identifier!');
|
|
19
|
-
_cache[id] =
|
|
19
|
+
_cache[id] = getModeledObject(obj, model);
|
|
20
20
|
gosNREUMInitializedAgents(id, _cache[id], 'loader_config');
|
|
21
21
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { Configurable } from './configurable';
|
|
1
|
+
import { getModeledObject } from './configurable';
|
|
3
2
|
import { gosNREUMInitializedAgents } from '../../window/nreum';
|
|
4
3
|
import { globalScope } from '../../util/global-scope';
|
|
5
4
|
import { BUILD_ENV, DIST_METHOD, VERSION } from "../../constants/env.npm";
|
|
@@ -24,7 +23,6 @@ const model = {
|
|
|
24
23
|
releaseIds: {},
|
|
25
24
|
session: undefined,
|
|
26
25
|
xhrWrappable: typeof globalScope.XMLHttpRequest?.prototype?.addEventListener === 'function',
|
|
27
|
-
userAgent,
|
|
28
26
|
version: VERSION
|
|
29
27
|
};
|
|
30
28
|
const _cache = {};
|
|
@@ -35,6 +33,6 @@ export function getRuntime(id) {
|
|
|
35
33
|
}
|
|
36
34
|
export function setRuntime(id, obj) {
|
|
37
35
|
if (!id) throw new Error('All runtime objects require an agent identifier!');
|
|
38
|
-
_cache[id] =
|
|
36
|
+
_cache[id] = getModeledObject(obj, model);
|
|
39
37
|
gosNREUMInitializedAgents(id, _cache[id], 'runtime');
|
|
40
38
|
}
|
|
@@ -59,7 +59,7 @@ export function drain() {
|
|
|
59
59
|
|
|
60
60
|
// Only when the event-groups for all features are ready to drain (staged) do we execute the drain. This has the effect
|
|
61
61
|
// that the last feature to call drain triggers drain for all features.
|
|
62
|
-
const items =
|
|
62
|
+
const items = [...registry[agentIdentifier]];
|
|
63
63
|
if (items.every(_ref => {
|
|
64
64
|
let [key, values] = _ref;
|
|
65
65
|
return values.staged;
|
|
@@ -13,6 +13,17 @@ import { getConfigurationValue } from '../config/config';
|
|
|
13
13
|
* Periodically invokes harvest calls and handles retries
|
|
14
14
|
*/
|
|
15
15
|
export class HarvestScheduler extends SharedContext {
|
|
16
|
+
/**
|
|
17
|
+
* Create a HarvestScheduler
|
|
18
|
+
* @param {string} endpoint - The base BAM endpoint name -- ex. 'events'
|
|
19
|
+
* @param {object} opts - The options used to configure the HarvestScheduler
|
|
20
|
+
* @param {Function} opts.onFinished - The callback to be fired when a harvest has finished
|
|
21
|
+
* @param {Function} opts.getPayload - A callback which can be triggered to return a payload for harvesting
|
|
22
|
+
* @param {number} opts.retryDelay - The number of seconds to wait before retrying after a network failure
|
|
23
|
+
* @param {boolean} opts.raw - Use a prefabricated payload shape as the harvest payload without the need for formatting
|
|
24
|
+
* @param {string} opts.customUrl - A custom url that falls outside of the shape of the standard BAM harvester url pattern. Will use directly instead of concatenating various pieces
|
|
25
|
+
* @param {*} parent - The parent object, whose state can be passed into SharedContext
|
|
26
|
+
*/
|
|
16
27
|
constructor(endpoint, opts, parent) {
|
|
17
28
|
super(parent); // gets any allowed properties from the parent and stores them in `sharedContext`
|
|
18
29
|
this.endpoint = endpoint;
|
|
@@ -64,23 +75,47 @@ export class HarvestScheduler extends SharedContext {
|
|
|
64
75
|
runHarvest(opts) {
|
|
65
76
|
if (this.aborted) return;
|
|
66
77
|
var scheduler = this;
|
|
78
|
+
let harvests = [];
|
|
79
|
+
let submitMethod;
|
|
67
80
|
if (this.opts.getPayload) {
|
|
68
|
-
// Ajax & PVT
|
|
69
|
-
|
|
81
|
+
// Ajax & PVT & SR
|
|
82
|
+
submitMethod = getSubmitMethod(this.endpoint, opts);
|
|
70
83
|
if (!submitMethod) return false;
|
|
71
|
-
|
|
84
|
+
const retry = submitMethod.method === submitData.xhr;
|
|
72
85
|
var payload = this.opts.getPayload({
|
|
73
86
|
retry: retry
|
|
74
87
|
});
|
|
75
|
-
if (payload) {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
this.harvest.send(this.endpoint, payload[i], opts, submitMethod, onHarvestFinished);
|
|
88
|
+
if (!payload) {
|
|
89
|
+
if (this.started) {
|
|
90
|
+
this.scheduleHarvest();
|
|
79
91
|
}
|
|
92
|
+
return;
|
|
80
93
|
}
|
|
94
|
+
payload = Object.prototype.toString.call(payload) === '[object Array]' ? payload : [payload];
|
|
95
|
+
harvests.push(...payload);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/** sendX is used for features that do not supply a preformatted payload via "getPayload" */
|
|
99
|
+
let send = args => this.harvest.sendX(args);
|
|
100
|
+
if (harvests.length) {
|
|
101
|
+
/** _send is the underlying method for sending in the harvest, if sending raw we can bypass the other helpers completely which format the payloads */
|
|
102
|
+
if (this.opts.raw) send = args => this.harvest._send(args);
|
|
103
|
+
/** send is used to formated the payloads from "getPayload" and obfuscate before sending */else send = args => this.harvest.send(args);
|
|
81
104
|
} else {
|
|
82
|
-
|
|
105
|
+
// force it to run at least once in sendX mode
|
|
106
|
+
harvests.push(undefined);
|
|
83
107
|
}
|
|
108
|
+
harvests.forEach(payload => {
|
|
109
|
+
send({
|
|
110
|
+
endpoint: this.endpoint,
|
|
111
|
+
payload,
|
|
112
|
+
opts,
|
|
113
|
+
submitMethod,
|
|
114
|
+
cbFinished: onHarvestFinished,
|
|
115
|
+
customUrl: this.opts.customUrl,
|
|
116
|
+
raw: this.opts.raw
|
|
117
|
+
});
|
|
118
|
+
});
|
|
84
119
|
if (this.started) {
|
|
85
120
|
this.scheduleHarvest();
|
|
86
121
|
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { setConfiguration } from '../config/state/init';
|
|
2
|
+
import { HarvestScheduler } from './harvest-scheduler';
|
|
3
|
+
describe('runHarvest', () => {
|
|
4
|
+
it('should re-schedule harvest even if there is no accumulated data', () => {
|
|
5
|
+
setConfiguration('asdf', {});
|
|
6
|
+
const scheduler = new HarvestScheduler('events', {
|
|
7
|
+
getPayload: jest.fn()
|
|
8
|
+
}, {
|
|
9
|
+
agentIdentifier: 'asdf',
|
|
10
|
+
ee: {
|
|
11
|
+
on: jest.fn()
|
|
12
|
+
}
|
|
13
|
+
});
|
|
14
|
+
scheduler.started = true;
|
|
15
|
+
jest.spyOn(scheduler, 'scheduleHarvest');
|
|
16
|
+
scheduler.runHarvest();
|
|
17
|
+
expect(scheduler.opts.getPayload()).toBeFalsy();
|
|
18
|
+
expect(scheduler.scheduleHarvest).toHaveBeenCalledTimes(1);
|
|
19
|
+
});
|
|
20
|
+
it('should also re-schedule harvest if there is accumulated data', () => {
|
|
21
|
+
setConfiguration('asdf', {});
|
|
22
|
+
const scheduler = new HarvestScheduler('events', {
|
|
23
|
+
getPayload: jest.fn().mockImplementation(() => 'payload')
|
|
24
|
+
}, {
|
|
25
|
+
agentIdentifier: 'asdf',
|
|
26
|
+
ee: {
|
|
27
|
+
on: jest.fn()
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
scheduler.started = true;
|
|
31
|
+
scheduler.harvest._send = () => {};
|
|
32
|
+
jest.spyOn(scheduler, 'scheduleHarvest');
|
|
33
|
+
scheduler.runHarvest();
|
|
34
|
+
expect(scheduler.opts.getPayload()).toBeTruthy();
|
|
35
|
+
expect(scheduler.scheduleHarvest).toHaveBeenCalledTimes(1);
|
|
36
|
+
});
|
|
37
|
+
});
|
|
@@ -8,7 +8,7 @@ import { obj as encodeObj, param as encodeParam } from '../url/encode';
|
|
|
8
8
|
import { stringify } from '../util/stringify';
|
|
9
9
|
import { submitData } from '../util/submit-data';
|
|
10
10
|
import { getLocation } from '../url/location';
|
|
11
|
-
import { getInfo, getConfigurationValue, getRuntime
|
|
11
|
+
import { getInfo, getConfigurationValue, getRuntime } from '../config/config';
|
|
12
12
|
import { cleanURL } from '../url/clean-url';
|
|
13
13
|
import { now } from '../timing/now';
|
|
14
14
|
import { eventListenerOpts } from '../event-listener/event-listener-opts';
|
|
@@ -17,6 +17,24 @@ import { applyFnToProps } from '../util/traverse';
|
|
|
17
17
|
import { SharedContext } from '../context/shared-context';
|
|
18
18
|
import { VERSION } from "../constants/env.npm";
|
|
19
19
|
import { isBrowserScope, isWorkerScope } from '../util/global-scope';
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @typedef {object} NetworkSendSpec
|
|
23
|
+
* @param {string} endpoint The endpoint to use (jserrors, events, resources etc.)
|
|
24
|
+
* @param {object} payload Object representing payload.
|
|
25
|
+
* @param {object} payload.qs Map of values that should be sent as part of the request query string.
|
|
26
|
+
* @param {string} payload.body String that should be sent as the body of the request.
|
|
27
|
+
* @param {string} payload.body.e Special case of body used for browser interactions.
|
|
28
|
+
* @param {object} opts Additional options for sending data
|
|
29
|
+
* @param {boolean} opts.needResponse Specify whether the caller expects a response data.
|
|
30
|
+
* @param {boolean} opts.unload Specify whether the call is a final harvest during page unload.
|
|
31
|
+
* @param {boolean} opts.sendEmptyBody Specify whether the call should be made even if the body is empty. Useful for rum calls.
|
|
32
|
+
* @param {function} submitMethod The submit method to use {@link ../util/submit-data}
|
|
33
|
+
* @param {string} customUrl Override the beacon url the data is sent to; must include protocol if defined
|
|
34
|
+
* @param {boolean} gzip Enabled gzip compression on the body of the request before it is sent
|
|
35
|
+
* @param {boolean} includeBaseParams Enables the use of base query parameters in the beacon url {@see Harvest.baseQueryString}
|
|
36
|
+
*/
|
|
37
|
+
|
|
20
38
|
const haveSendBeacon = !!navigator.sendBeacon; // only the web window obj has sendBeacon at this time, so 'false' for other envs
|
|
21
39
|
|
|
22
40
|
export class Harvest extends SharedContext {
|
|
@@ -32,62 +50,78 @@ export class Harvest extends SharedContext {
|
|
|
32
50
|
/**
|
|
33
51
|
* Initiate a harvest from multiple sources. An event that corresponds to the endpoint
|
|
34
52
|
* name is emitted, which gives any listeners the opportunity to provide payload data.
|
|
35
|
-
*
|
|
36
|
-
* @param {string} endpoint - The endpoint of the harvest (jserrors, events, resources etc.)
|
|
37
|
-
*
|
|
38
|
-
* @param {object} opts
|
|
39
|
-
* @param {bool} opts.needResponse - Specify whether the caller expects a response data.
|
|
40
|
-
* @param {bool} opts.unload - Specify whether the call is a final harvest during page unload.
|
|
53
|
+
* @param {NetworkSendSpec} spec Specification for sending data
|
|
41
54
|
*/
|
|
42
|
-
sendX(
|
|
55
|
+
sendX(spec) {
|
|
56
|
+
const {
|
|
57
|
+
endpoint,
|
|
58
|
+
opts
|
|
59
|
+
} = spec;
|
|
43
60
|
var submitMethod = getSubmitMethod(endpoint, opts);
|
|
44
61
|
if (!submitMethod) return false;
|
|
45
62
|
var options = {
|
|
46
63
|
retry: submitMethod.method === submitData.xhr
|
|
47
64
|
};
|
|
48
|
-
|
|
65
|
+
const payload = this.createPayload(endpoint, options);
|
|
66
|
+
var caller = this.obfuscator.shouldObfuscate() ? this.obfuscateAndSend.bind(this) : this._send.bind(this);
|
|
67
|
+
return caller({
|
|
68
|
+
...spec,
|
|
69
|
+
payload,
|
|
70
|
+
submitMethod
|
|
71
|
+
});
|
|
49
72
|
}
|
|
50
73
|
|
|
51
74
|
/**
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
* @param {string} singlePayload.body - String that should be sent as the body of the request.
|
|
60
|
-
* @param {string} singlePayload.body.e - Special case of body used for browser interactions.
|
|
61
|
-
*
|
|
62
|
-
* @param {object} opts
|
|
63
|
-
* @param {bool} opts.needResponse - Specify whether the caller expects a response data.
|
|
64
|
-
* @param {bool} opts.unload - Specify whether the call is a final harvest during page unload.
|
|
65
|
-
*/
|
|
66
|
-
send(endpoint, singlePayload, opts, submitMethod, cbFinished) {
|
|
67
|
-
var _this = this;
|
|
75
|
+
* Initiate a harvest call.
|
|
76
|
+
* @param {NetworkSendSpec} spec Specification for sending data
|
|
77
|
+
*/
|
|
78
|
+
send(spec) {
|
|
79
|
+
const {
|
|
80
|
+
payload = {}
|
|
81
|
+
} = spec;
|
|
68
82
|
var makeBody = createAccumulator();
|
|
69
83
|
var makeQueryString = createAccumulator();
|
|
70
|
-
if (
|
|
71
|
-
if (
|
|
72
|
-
var
|
|
84
|
+
if (payload.body) mapOwn(payload.body, makeBody);
|
|
85
|
+
if (payload.qs) mapOwn(payload.qs, makeQueryString);
|
|
86
|
+
var newPayload = {
|
|
73
87
|
body: makeBody(),
|
|
74
88
|
qs: makeQueryString()
|
|
75
89
|
};
|
|
76
|
-
var caller = this.obfuscator.shouldObfuscate() ?
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
};
|
|
81
|
-
return caller(endpoint, payload, opts, submitMethod, cbFinished);
|
|
90
|
+
var caller = this.obfuscator.shouldObfuscate() ? this.obfuscateAndSend.bind(this) : this._send.bind(this);
|
|
91
|
+
return caller({
|
|
92
|
+
...spec,
|
|
93
|
+
payload: newPayload
|
|
94
|
+
});
|
|
82
95
|
}
|
|
83
|
-
|
|
84
|
-
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Apply obfuscation rules to the payload and then initial the harvest network call.
|
|
99
|
+
* @param {NetworkSendSpec} spec Specification for sending data
|
|
100
|
+
*/
|
|
101
|
+
obfuscateAndSend(spec) {
|
|
102
|
+
var _this = this;
|
|
103
|
+
const {
|
|
104
|
+
payload = {}
|
|
105
|
+
} = spec;
|
|
85
106
|
applyFnToProps(payload, function () {
|
|
86
|
-
return
|
|
107
|
+
return _this.obfuscator.obfuscateString(...arguments);
|
|
87
108
|
}, 'string', ['e']);
|
|
88
|
-
return this._send(
|
|
109
|
+
return this._send({
|
|
110
|
+
...spec,
|
|
111
|
+
payload
|
|
112
|
+
});
|
|
89
113
|
}
|
|
90
|
-
_send(
|
|
114
|
+
_send(_ref) {
|
|
115
|
+
let {
|
|
116
|
+
endpoint,
|
|
117
|
+
payload = {},
|
|
118
|
+
opts = {},
|
|
119
|
+
submitMethod,
|
|
120
|
+
cbFinished,
|
|
121
|
+
customUrl,
|
|
122
|
+
raw,
|
|
123
|
+
includeBaseParams = true
|
|
124
|
+
} = _ref;
|
|
91
125
|
var info = getInfo(this.sharedContext.agentIdentifier);
|
|
92
126
|
if (!info.errorBeacon) return false;
|
|
93
127
|
var agentRuntime = getRuntime(this.sharedContext.agentIdentifier);
|
|
@@ -100,38 +134,54 @@ export class Harvest extends SharedContext {
|
|
|
100
134
|
}
|
|
101
135
|
return false;
|
|
102
136
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
137
|
+
let url = '';
|
|
138
|
+
if (customUrl) url = customUrl;else if (raw) url = "".concat(this.getScheme(), "://").concat(info.errorBeacon, "/").concat(endpoint);else url = "".concat(this.getScheme(), "://").concat(info.errorBeacon, "/").concat(endpoint, "/1/").concat(info.licenseKey);
|
|
139
|
+
var baseParams = !raw && includeBaseParams ? this.baseQueryString() : '';
|
|
140
|
+
var payloadParams = payload.qs ? encodeObj(payload.qs, agentRuntime.maxBytes) : '';
|
|
106
141
|
if (!submitMethod) {
|
|
107
142
|
submitMethod = getSubmitMethod(endpoint, opts);
|
|
108
143
|
}
|
|
109
144
|
var method = submitMethod.method;
|
|
110
145
|
var useBody = submitMethod.useBody;
|
|
111
146
|
var body;
|
|
112
|
-
var fullUrl = url;
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
147
|
+
var fullUrl = "".concat(url, "?").concat(baseParams).concat(payloadParams);
|
|
148
|
+
const gzip = payload?.qs?.content_encoding === 'gzip';
|
|
149
|
+
if (!gzip) {
|
|
150
|
+
if (useBody && endpoint === 'events') {
|
|
151
|
+
body = payload.body.e;
|
|
152
|
+
} else if (useBody) {
|
|
153
|
+
body = stringify(payload.body);
|
|
154
|
+
} else {
|
|
155
|
+
fullUrl = fullUrl + encodeObj(payload.body, agentRuntime.maxBytes);
|
|
156
|
+
}
|
|
157
|
+
} else body = payload.body;
|
|
120
158
|
|
|
121
159
|
// Get bytes harvested per endpoint as a supportability metric. See metrics aggregator (on unload).
|
|
122
160
|
agentRuntime.bytesSent[endpoint] = (agentRuntime.bytesSent[endpoint] || 0) + body?.length || 0;
|
|
123
161
|
// Get query bytes harvested per endpoint as a supportability metric. See metrics aggregator (on unload).
|
|
124
162
|
agentRuntime.queryBytesSent[endpoint] = (agentRuntime.queryBytesSent[endpoint] || 0) + fullUrl.split('?').slice(-1)[0]?.length || 0;
|
|
163
|
+
const headers = [];
|
|
164
|
+
headers.push({
|
|
165
|
+
key: 'content-type',
|
|
166
|
+
value: 'text/plain'
|
|
167
|
+
});
|
|
125
168
|
|
|
126
169
|
/* Since workers don't support sendBeacon right now, or Image(), they can only use XHR method.
|
|
127
170
|
Because they still do permit synch XHR, the idea is that at final harvest time (worker is closing),
|
|
128
171
|
we just make a BLOCKING request--trivial impact--with the remaining data as a temp fill-in for sendBeacon. */
|
|
129
|
-
|
|
172
|
+
|
|
173
|
+
var result = method({
|
|
174
|
+
url: fullUrl,
|
|
175
|
+
body,
|
|
176
|
+
sync: opts.unload && isWorkerScope,
|
|
177
|
+
headers
|
|
178
|
+
});
|
|
130
179
|
if (cbFinished && method === submitData.xhr) {
|
|
131
180
|
var xhr = result;
|
|
132
181
|
xhr.addEventListener('load', function () {
|
|
133
182
|
var result = {
|
|
134
|
-
sent: true
|
|
183
|
+
sent: true,
|
|
184
|
+
status: this.status
|
|
135
185
|
};
|
|
136
186
|
if (this.status === 429) {
|
|
137
187
|
result.retry = true;
|
|
@@ -149,7 +199,9 @@ export class Harvest extends SharedContext {
|
|
|
149
199
|
// if beacon request failed, retry with an alternative method -- will not happen for workers
|
|
150
200
|
if (!result && method === submitData.beacon) {
|
|
151
201
|
method = submitData.img;
|
|
152
|
-
result = method(
|
|
202
|
+
result = method({
|
|
203
|
+
url: fullUrl + encodeObj(payload.body, agentRuntime.maxBytes)
|
|
204
|
+
});
|
|
153
205
|
}
|
|
154
206
|
return result;
|
|
155
207
|
}
|
|
@@ -160,9 +212,9 @@ export class Harvest extends SharedContext {
|
|
|
160
212
|
var info = getInfo(this.sharedContext.agentIdentifier);
|
|
161
213
|
var location = cleanURL(getLocation());
|
|
162
214
|
var ref = this.obfuscator.shouldObfuscate() ? this.obfuscator.obfuscateString(location) : location;
|
|
163
|
-
return ['
|
|
215
|
+
return ['a=' + info.applicationID, encodeParam('sa', info.sa ? '' + info.sa : ''), encodeParam('v', VERSION), transactionNameParam(info), encodeParam('ct', runtime.customTransaction), '&rst=' + now(), '&ck=0',
|
|
164
216
|
// ck param DEPRECATED - still expected by backend
|
|
165
|
-
'&s=' + (runtime.session?.value || '0'),
|
|
217
|
+
'&s=' + (runtime.session?.state.value || '0'),
|
|
166
218
|
// the 0 id encaps all untrackable and default traffic
|
|
167
219
|
encodeParam('ref', ref), encodeParam('ptid', runtime.ptid ? '' + runtime.ptid : '')].join('');
|
|
168
220
|
}
|
|
@@ -232,7 +284,7 @@ function createAccumulator() {
|
|
|
232
284
|
var accumulator = {};
|
|
233
285
|
var hasData = false;
|
|
234
286
|
return function (key, val) {
|
|
235
|
-
if (val && val.length) {
|
|
287
|
+
if (val !== null && val !== undefined && val.length) {
|
|
236
288
|
accumulator[key] = val;
|
|
237
289
|
hasData = true;
|
|
238
290
|
}
|