@newrelic/browser-agent 1.276.0 → 1.278.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -0
- package/dist/cjs/common/aggregate/event-aggregator.js +1 -1
- package/dist/cjs/common/config/init.js +1 -10
- package/dist/cjs/common/config/runtime.js +2 -1
- package/dist/cjs/common/constants/env.cdn.js +1 -1
- package/dist/cjs/common/constants/env.npm.js +1 -1
- package/dist/cjs/common/harvest/harvester.js +255 -0
- package/dist/cjs/common/harvest/types.js +5 -21
- package/dist/cjs/features/ajax/aggregate/index.js +2 -11
- package/dist/cjs/features/generic_events/aggregate/index.js +17 -13
- package/dist/cjs/features/generic_events/constants.js +2 -1
- package/dist/cjs/features/jserrors/aggregate/index.js +3 -14
- package/dist/cjs/features/logging/aggregate/index.js +4 -12
- package/dist/cjs/features/metrics/aggregate/index.js +7 -15
- package/dist/cjs/features/page_view_event/aggregate/index.js +46 -48
- package/dist/cjs/features/page_view_timing/aggregate/index.js +0 -9
- package/dist/cjs/features/session_replay/aggregate/index.js +21 -43
- package/dist/cjs/features/session_replay/instrument/index.js +2 -1
- package/dist/cjs/features/session_replay/shared/recorder.js +6 -6
- package/dist/cjs/features/session_trace/aggregate/index.js +9 -24
- package/dist/cjs/features/session_trace/aggregate/trace/storage.js +8 -2
- package/dist/cjs/features/soft_navigations/aggregate/index.js +31 -21
- package/dist/cjs/features/soft_navigations/aggregate/initial-page-load-interaction.js +2 -1
- package/dist/cjs/features/soft_navigations/aggregate/interaction.js +12 -12
- package/dist/cjs/features/soft_navigations/constants.js +5 -2
- package/dist/cjs/features/spa/aggregate/index.js +7 -10
- package/dist/cjs/features/utils/aggregate-base.js +66 -27
- package/dist/cjs/features/utils/event-buffer.js +0 -1
- package/dist/cjs/features/utils/event-store-manager.js +109 -0
- package/dist/cjs/features/utils/instrument-base.js +1 -10
- package/dist/cjs/loaders/api/api-methods.js +1 -1
- package/dist/cjs/loaders/api/api.js +2 -1
- package/dist/cjs/loaders/features/features.js +16 -10
- package/dist/cjs/loaders/micro-agent-base.js +10 -0
- package/dist/cjs/loaders/micro-agent.js +1 -0
- package/dist/esm/common/aggregate/event-aggregator.js +1 -1
- package/dist/esm/common/config/init.js +1 -10
- package/dist/esm/common/config/runtime.js +2 -1
- package/dist/esm/common/constants/env.cdn.js +1 -1
- package/dist/esm/common/constants/env.npm.js +1 -1
- package/dist/esm/common/harvest/harvester.js +249 -0
- package/dist/esm/common/harvest/types.js +5 -21
- package/dist/esm/features/ajax/aggregate/index.js +3 -12
- package/dist/esm/features/generic_events/aggregate/index.js +18 -14
- package/dist/esm/features/generic_events/constants.js +1 -0
- package/dist/esm/features/jserrors/aggregate/index.js +4 -15
- package/dist/esm/features/logging/aggregate/index.js +4 -12
- package/dist/esm/features/metrics/aggregate/index.js +7 -15
- package/dist/esm/features/page_view_event/aggregate/index.js +46 -48
- package/dist/esm/features/page_view_timing/aggregate/index.js +1 -10
- package/dist/esm/features/session_replay/aggregate/index.js +22 -44
- package/dist/esm/features/session_replay/instrument/index.js +2 -1
- package/dist/esm/features/session_replay/shared/recorder.js +6 -6
- package/dist/esm/features/session_trace/aggregate/index.js +9 -24
- package/dist/esm/features/session_trace/aggregate/trace/storage.js +8 -2
- package/dist/esm/features/soft_navigations/aggregate/index.js +33 -23
- package/dist/esm/features/soft_navigations/aggregate/initial-page-load-interaction.js +2 -1
- package/dist/esm/features/soft_navigations/aggregate/interaction.js +13 -13
- package/dist/esm/features/soft_navigations/constants.js +4 -1
- package/dist/esm/features/spa/aggregate/index.js +8 -11
- package/dist/esm/features/utils/aggregate-base.js +66 -27
- package/dist/esm/features/utils/event-buffer.js +0 -1
- package/dist/esm/features/utils/event-store-manager.js +103 -0
- package/dist/esm/features/utils/instrument-base.js +1 -10
- package/dist/esm/loaders/api/api-methods.js +1 -1
- package/dist/esm/loaders/api/api.js +2 -1
- package/dist/esm/loaders/features/features.js +15 -9
- package/dist/esm/loaders/micro-agent-base.js +10 -0
- package/dist/esm/loaders/micro-agent.js +1 -0
- package/dist/types/common/aggregate/event-aggregator.d.ts +1 -1
- package/dist/types/common/aggregate/event-aggregator.d.ts.map +1 -1
- package/dist/types/common/config/init.d.ts.map +1 -1
- package/dist/types/common/config/runtime.d.ts.map +1 -1
- package/dist/types/common/harvest/harvester.d.ts +16 -0
- package/dist/types/common/harvest/harvester.d.ts.map +1 -0
- package/dist/types/common/harvest/types.d.ts +8 -45
- package/dist/types/common/harvest/types.d.ts.map +1 -1
- package/dist/types/features/ajax/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/generic_events/aggregate/index.d.ts +1 -3
- package/dist/types/features/generic_events/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/generic_events/constants.d.ts +1 -0
- package/dist/types/features/generic_events/constants.d.ts.map +1 -1
- package/dist/types/features/jserrors/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/logging/aggregate/index.d.ts +0 -3
- package/dist/types/features/logging/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/metrics/aggregate/index.d.ts +1 -1
- package/dist/types/features/metrics/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/page_view_event/aggregate/index.d.ts +6 -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.map +1 -1
- package/dist/types/features/session_replay/aggregate/index.d.ts +12 -15
- package/dist/types/features/session_replay/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/session_replay/shared/recorder.d.ts.map +1 -1
- package/dist/types/features/session_trace/aggregate/index.d.ts +0 -5
- package/dist/types/features/session_trace/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/session_trace/aggregate/trace/storage.d.ts +8 -5
- package/dist/types/features/session_trace/aggregate/trace/storage.d.ts.map +1 -1
- package/dist/types/features/soft_navigations/aggregate/index.d.ts +1 -0
- package/dist/types/features/soft_navigations/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/soft_navigations/aggregate/initial-page-load-interaction.d.ts.map +1 -1
- package/dist/types/features/soft_navigations/aggregate/interaction.d.ts +3 -3
- package/dist/types/features/soft_navigations/aggregate/interaction.d.ts.map +1 -1
- package/dist/types/features/soft_navigations/constants.d.ts +1 -0
- package/dist/types/features/soft_navigations/constants.d.ts.map +1 -1
- package/dist/types/features/spa/aggregate/index.d.ts +0 -1
- package/dist/types/features/spa/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/utils/aggregate-base.d.ts +12 -7
- package/dist/types/features/utils/aggregate-base.d.ts.map +1 -1
- package/dist/types/features/utils/event-buffer.d.ts +1 -2
- package/dist/types/features/utils/event-buffer.d.ts.map +1 -1
- package/dist/types/features/utils/event-store-manager.d.ts +43 -0
- package/dist/types/features/utils/event-store-manager.d.ts.map +1 -0
- package/dist/types/features/utils/instrument-base.d.ts +0 -1
- package/dist/types/features/utils/instrument-base.d.ts.map +1 -1
- package/dist/types/loaders/api/api.d.ts +1 -0
- package/dist/types/loaders/api/api.d.ts.map +1 -1
- package/dist/types/loaders/features/features.d.ts +15 -12
- package/dist/types/loaders/features/features.d.ts.map +1 -1
- package/dist/types/loaders/micro-agent-base.d.ts +7 -0
- package/dist/types/loaders/micro-agent-base.d.ts.map +1 -1
- package/dist/types/loaders/micro-agent.d.ts.map +1 -1
- package/package.json +6 -6
- package/src/common/aggregate/event-aggregator.js +1 -1
- package/src/common/config/init.js +9 -10
- package/src/common/config/runtime.js +2 -1
- package/src/common/harvest/__mocks__/harvester.js +6 -0
- package/src/common/harvest/harvester.js +230 -0
- package/src/common/harvest/types.js +5 -21
- package/src/features/ajax/aggregate/index.js +3 -14
- package/src/features/generic_events/aggregate/index.js +20 -17
- package/src/features/generic_events/constants.js +2 -0
- package/src/features/jserrors/aggregate/index.js +4 -11
- package/src/features/logging/aggregate/index.js +4 -12
- package/src/features/metrics/aggregate/index.js +5 -12
- package/src/features/page_view_event/aggregate/index.js +38 -38
- package/src/features/page_view_timing/aggregate/index.js +1 -12
- package/src/features/session_replay/aggregate/index.js +19 -42
- package/src/features/session_replay/instrument/index.js +1 -1
- package/src/features/session_replay/shared/recorder.js +6 -6
- package/src/features/session_trace/aggregate/index.js +8 -25
- package/src/features/session_trace/aggregate/trace/storage.js +5 -2
- package/src/features/soft_navigations/aggregate/index.js +26 -23
- package/src/features/soft_navigations/aggregate/initial-page-load-interaction.js +2 -1
- package/src/features/soft_navigations/aggregate/interaction.js +13 -12
- package/src/features/soft_navigations/constants.js +3 -1
- package/src/features/spa/aggregate/index.js +8 -11
- package/src/features/utils/aggregate-base.js +59 -27
- package/src/features/utils/event-buffer.js +0 -1
- package/src/features/utils/event-store-manager.js +101 -0
- package/src/features/utils/instrument-base.js +2 -8
- package/src/loaders/api/api-methods.js +1 -1
- package/src/loaders/api/api.js +3 -1
- package/src/loaders/features/features.js +16 -9
- package/src/loaders/micro-agent-base.js +10 -0
- package/src/loaders/micro-agent.js +1 -0
- package/dist/cjs/common/harvest/harvest-scheduler.js +0 -168
- package/dist/cjs/common/harvest/harvest.js +0 -295
- package/dist/esm/common/harvest/harvest-scheduler.js +0 -160
- package/dist/esm/common/harvest/harvest.js +0 -286
- package/dist/types/common/harvest/harvest-scheduler.d.ts +0 -50
- package/dist/types/common/harvest/harvest-scheduler.d.ts.map +0 -1
- package/dist/types/common/harvest/harvest.d.ts +0 -65
- package/dist/types/common/harvest/harvest.d.ts.map +0 -1
- package/src/common/harvest/__mocks__/harvest.js +0 -13
- package/src/common/harvest/harvest-scheduler.js +0 -166
- package/src/common/harvest/harvest.js +0 -282
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,25 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [1.278.0](https://github.com/newrelic/newrelic-browser-agent/compare/v1.277.0...v1.278.0) (2025-01-07)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* Centralized harvesting ([#1298](https://github.com/newrelic/newrelic-browser-agent/issues/1298)) ([32c0e3f](https://github.com/newrelic/newrelic-browser-agent/commit/32c0e3f7008423a3e327d17b926d1702d08ae21f))
|
|
12
|
+
|
|
13
|
+
## [1.277.0](https://github.com/newrelic/newrelic-browser-agent/compare/v1.276.0...v1.277.0) (2024-12-18)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
### Features
|
|
17
|
+
|
|
18
|
+
* Add custom events API ([#1263](https://github.com/newrelic/newrelic-browser-agent/issues/1263)) ([9395415](https://github.com/newrelic/newrelic-browser-agent/commit/9395415d942b55e88e89438aa203c6a1642d9e6b))
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
### Bug Fixes
|
|
22
|
+
|
|
23
|
+
* Soft navigation bug fixes and new soft navigation tests ([#1268](https://github.com/newrelic/newrelic-browser-agent/issues/1268)) ([7624928](https://github.com/newrelic/newrelic-browser-agent/commit/762492896a7b96564269aab1aadeb6e44a4da242))
|
|
24
|
+
|
|
6
25
|
## [1.276.0](https://github.com/newrelic/newrelic-browser-agent/compare/v1.275.0...v1.276.0) (2024-12-16)
|
|
7
26
|
|
|
8
27
|
|
|
@@ -18,7 +18,7 @@ class EventAggregator {
|
|
|
18
18
|
if (!aggregatorTypes) return Object.keys(this.#aggregator.aggregatedData).length === 0;
|
|
19
19
|
return aggregatorTypes.every(type => !this.#aggregator.aggregatedData[type]); // no bucket exist for any of the types we're looking for
|
|
20
20
|
}
|
|
21
|
-
add(type, name, params, newMetrics, customParams) {
|
|
21
|
+
add([type, name, params, newMetrics, customParams]) {
|
|
22
22
|
// Do we need to track byte size here like EventBuffer?
|
|
23
23
|
this.#aggregator.store(type, name, params, newMetrics, customParams);
|
|
24
24
|
return true;
|
|
@@ -49,7 +49,6 @@ const model = () => {
|
|
|
49
49
|
deny_list: undefined,
|
|
50
50
|
block_internal: true,
|
|
51
51
|
enabled: true,
|
|
52
|
-
harvestTimeSeconds: 10,
|
|
53
52
|
autoStart: true
|
|
54
53
|
},
|
|
55
54
|
distributed_tracing: {
|
|
@@ -67,20 +66,17 @@ const model = () => {
|
|
|
67
66
|
},
|
|
68
67
|
generic_events: {
|
|
69
68
|
enabled: true,
|
|
70
|
-
harvestTimeSeconds: 30,
|
|
71
69
|
autoStart: true
|
|
72
70
|
},
|
|
73
71
|
harvest: {
|
|
74
|
-
|
|
72
|
+
interval: 30
|
|
75
73
|
},
|
|
76
74
|
jserrors: {
|
|
77
75
|
enabled: true,
|
|
78
|
-
harvestTimeSeconds: 10,
|
|
79
76
|
autoStart: true
|
|
80
77
|
},
|
|
81
78
|
logging: {
|
|
82
79
|
enabled: true,
|
|
83
|
-
harvestTimeSeconds: 10,
|
|
84
80
|
autoStart: true,
|
|
85
81
|
level: _constants2.LOG_LEVELS.INFO
|
|
86
82
|
},
|
|
@@ -98,7 +94,6 @@ const model = () => {
|
|
|
98
94
|
},
|
|
99
95
|
page_view_timing: {
|
|
100
96
|
enabled: true,
|
|
101
|
-
harvestTimeSeconds: 30,
|
|
102
97
|
autoStart: true
|
|
103
98
|
},
|
|
104
99
|
performance: {
|
|
@@ -146,7 +141,6 @@ const model = () => {
|
|
|
146
141
|
// feature settings
|
|
147
142
|
autoStart: true,
|
|
148
143
|
enabled: false,
|
|
149
|
-
harvestTimeSeconds: 60,
|
|
150
144
|
preload: false,
|
|
151
145
|
// if true, enables the agent to load rrweb immediately instead of waiting to do so after the window.load event
|
|
152
146
|
sampling_rate: 10,
|
|
@@ -199,17 +193,14 @@ const model = () => {
|
|
|
199
193
|
},
|
|
200
194
|
session_trace: {
|
|
201
195
|
enabled: true,
|
|
202
|
-
harvestTimeSeconds: 10,
|
|
203
196
|
autoStart: true
|
|
204
197
|
},
|
|
205
198
|
soft_navigations: {
|
|
206
199
|
enabled: true,
|
|
207
|
-
harvestTimeSeconds: 10,
|
|
208
200
|
autoStart: true
|
|
209
201
|
},
|
|
210
202
|
spa: {
|
|
211
203
|
enabled: true,
|
|
212
|
-
harvestTimeSeconds: 10,
|
|
213
204
|
autoStart: true
|
|
214
205
|
},
|
|
215
206
|
ssl: undefined,
|
|
@@ -12,7 +12,7 @@ exports.VERSION = exports.RRWEB_VERSION = exports.DIST_METHOD = exports.BUILD_EN
|
|
|
12
12
|
/**
|
|
13
13
|
* Exposes the version of the agent
|
|
14
14
|
*/
|
|
15
|
-
const VERSION = exports.VERSION = "1.
|
|
15
|
+
const VERSION = exports.VERSION = "1.278.0";
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
18
|
* Exposes the build type of the agent
|
|
@@ -12,7 +12,7 @@ exports.VERSION = exports.RRWEB_VERSION = exports.DIST_METHOD = exports.BUILD_EN
|
|
|
12
12
|
/**
|
|
13
13
|
* Exposes the version of the agent
|
|
14
14
|
*/
|
|
15
|
-
const VERSION = exports.VERSION = "1.
|
|
15
|
+
const VERSION = exports.VERSION = "1.278.0";
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
18
|
* Exposes the build type of the agent
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.Harvester = void 0;
|
|
7
|
+
var _features = require("../../loaders/features/features");
|
|
8
|
+
var _env = require("../constants/env.npm");
|
|
9
|
+
var _runtime = require("../constants/runtime");
|
|
10
|
+
var _eventListenerOpts = require("../event-listener/event-listener-opts");
|
|
11
|
+
var _constants = require("../session/constants");
|
|
12
|
+
var _now = require("../timing/now");
|
|
13
|
+
var _eol = require("../unload/eol");
|
|
14
|
+
var _cleanUrl = require("../url/clean-url");
|
|
15
|
+
var _encode = require("../url/encode");
|
|
16
|
+
var _console = require("../util/console");
|
|
17
|
+
var _stringify = require("../util/stringify");
|
|
18
|
+
var _submitData = require("../util/submit-data");
|
|
19
|
+
class Harvester {
|
|
20
|
+
#started = false;
|
|
21
|
+
initializedAggregates = [];
|
|
22
|
+
constructor(agentRef) {
|
|
23
|
+
this.agentRef = agentRef;
|
|
24
|
+
(0, _eol.subscribeToEOL)(() => {
|
|
25
|
+
// do one last harvest round or check
|
|
26
|
+
this.initializedAggregates.forEach(aggregateInst => {
|
|
27
|
+
// let all features wrap up things needed to do before ANY harvest in case there's last minute cross-feature data dependencies
|
|
28
|
+
if (typeof aggregateInst.harvestOpts.beforeUnload === 'function') aggregateInst.harvestOpts.beforeUnload();
|
|
29
|
+
});
|
|
30
|
+
this.initializedAggregates.forEach(aggregateInst => this.triggerHarvestFor(aggregateInst, {
|
|
31
|
+
isFinalHarvest: true
|
|
32
|
+
}));
|
|
33
|
+
/* This callback should run in bubble phase, so that that CWV api, like "onLCP", is called before the final harvest so that emitted timings are part of last outgoing. */
|
|
34
|
+
}, false);
|
|
35
|
+
|
|
36
|
+
/* Flush all buffered data if session resets and give up retries. This should be synchronous to ensure that the correct `session` value is sent.
|
|
37
|
+
Since session-reset generates a new session ID and the ID is grabbed at send-time, any delays or retries would cause the payload to be sent under the wrong session ID. */
|
|
38
|
+
agentRef.ee.on(_constants.SESSION_EVENTS.RESET, () => this.initializedAggregates.forEach(aggregateInst => this.triggerHarvestFor(aggregateInst, {
|
|
39
|
+
forceNoRetry: true
|
|
40
|
+
})));
|
|
41
|
+
}
|
|
42
|
+
startTimer(harvestInterval = this.agentRef.init.harvest.interval) {
|
|
43
|
+
if (this.#started) return;
|
|
44
|
+
this.#started = true;
|
|
45
|
+
const onHarvestInterval = () => {
|
|
46
|
+
this.initializedAggregates.forEach(aggregateInst => this.triggerHarvestFor(aggregateInst));
|
|
47
|
+
setTimeout(onHarvestInterval, harvestInterval * 1000); // repeat in X seconds
|
|
48
|
+
};
|
|
49
|
+
setTimeout(onHarvestInterval, harvestInterval * 1000);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Given a feature (aggregate), execute a harvest on-demand.
|
|
54
|
+
* @param {object} aggregateInst
|
|
55
|
+
* @param {object} localOpts
|
|
56
|
+
* @returns {boolean} True if 1+ network call was made. Note that this does not mean or guarantee that it was successful (or that all were in the case of more than 1).
|
|
57
|
+
*/
|
|
58
|
+
triggerHarvestFor(aggregateInst, localOpts = {}) {
|
|
59
|
+
if (aggregateInst.blocked) return false;
|
|
60
|
+
const submitMethod = (0, _submitData.getSubmitMethod)(localOpts);
|
|
61
|
+
if (!submitMethod) return false;
|
|
62
|
+
const shouldRetryOnFail = !localOpts.isFinalHarvest && submitMethod === _submitData.xhr; // always retry all features harvests except for final
|
|
63
|
+
let dataToSendArr;
|
|
64
|
+
let ranSend = false;
|
|
65
|
+
if (!localOpts.directSend) {
|
|
66
|
+
// primarily used by rum call to bypass makeHarvestPayload by providing payload directly
|
|
67
|
+
dataToSendArr = aggregateInst.makeHarvestPayload(shouldRetryOnFail); // be sure the 'this' of makeHarvestPayload is the aggregate w/ access to its harvestOpts
|
|
68
|
+
if (!dataToSendArr) return false; // can be undefined if storage is empty or preharvest checks failed
|
|
69
|
+
} else dataToSendArr = [localOpts.directSend];
|
|
70
|
+
dataToSendArr.forEach(({
|
|
71
|
+
targetApp,
|
|
72
|
+
payload
|
|
73
|
+
}) => {
|
|
74
|
+
if (!payload) return;
|
|
75
|
+
send(this.agentRef, {
|
|
76
|
+
endpoint: _features.FEATURE_TO_ENDPOINT[aggregateInst.featureName],
|
|
77
|
+
targetApp,
|
|
78
|
+
payload,
|
|
79
|
+
localOpts,
|
|
80
|
+
submitMethod,
|
|
81
|
+
cbFinished,
|
|
82
|
+
raw: aggregateInst.harvestOpts.raw
|
|
83
|
+
});
|
|
84
|
+
ranSend = true;
|
|
85
|
+
});
|
|
86
|
+
return ranSend;
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* This is executed immediately after harvest sends the data via XHR, or if there's nothing to send. Note that this excludes on unloading / sendBeacon.
|
|
90
|
+
* @param {Object} result - information regarding the result of the harvest attempt
|
|
91
|
+
*/
|
|
92
|
+
function cbFinished(result) {
|
|
93
|
+
if (localOpts.forceNoRetry) result.retry = false; // discard unsent data rather than re-queuing for next harvest attempt
|
|
94
|
+
aggregateInst.postHarvestCleanup(result);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* @typedef {import('./types.js').NetworkSendSpec} NetworkSendSpec
|
|
101
|
+
*/
|
|
102
|
+
exports.Harvester = Harvester;
|
|
103
|
+
const warnings = {};
|
|
104
|
+
/**
|
|
105
|
+
* Initiate a harvest call.
|
|
106
|
+
* @param {NetworkSendSpec} param0 Specification for sending data
|
|
107
|
+
* @returns {boolean} True if a network call was made. Note that this does not mean or guarantee that it was successful.
|
|
108
|
+
*/
|
|
109
|
+
function send(agentRef, {
|
|
110
|
+
endpoint,
|
|
111
|
+
targetApp,
|
|
112
|
+
payload,
|
|
113
|
+
localOpts = {},
|
|
114
|
+
submitMethod,
|
|
115
|
+
cbFinished,
|
|
116
|
+
raw
|
|
117
|
+
}) {
|
|
118
|
+
if (!agentRef.info.errorBeacon) return false;
|
|
119
|
+
let {
|
|
120
|
+
body,
|
|
121
|
+
qs
|
|
122
|
+
} = cleanPayload(payload);
|
|
123
|
+
if (Object.keys(body).length === 0 && !localOpts.sendEmptyBody) {
|
|
124
|
+
// if there's no body to send, just run onfinish stuff and return
|
|
125
|
+
if (cbFinished) cbFinished({
|
|
126
|
+
sent: false,
|
|
127
|
+
targetApp
|
|
128
|
+
});
|
|
129
|
+
return false;
|
|
130
|
+
}
|
|
131
|
+
const protocol = agentRef.init.ssl === false ? 'http' : 'https';
|
|
132
|
+
const perceivedBeacon = agentRef.init.proxy.beacon || agentRef.info.errorBeacon;
|
|
133
|
+
const url = raw ? "".concat(protocol, "://").concat(perceivedBeacon, "/").concat(endpoint) : "".concat(protocol, "://").concat(perceivedBeacon).concat(endpoint !== _features.RUM ? '/' + endpoint : '', "/1/").concat(targetApp.licenseKey);
|
|
134
|
+
const baseParams = !raw ? baseQueryString(agentRef, qs, endpoint, targetApp.appId) : '';
|
|
135
|
+
let payloadParams = (0, _encode.obj)(qs, agentRef.runtime.maxBytes);
|
|
136
|
+
if (baseParams === '' && payloadParams.startsWith('&')) {
|
|
137
|
+
payloadParams = payloadParams.substring(1);
|
|
138
|
+
}
|
|
139
|
+
const fullUrl = "".concat(url, "?").concat(baseParams).concat(payloadParams);
|
|
140
|
+
const gzip = !!qs?.attributes?.includes('gzip');
|
|
141
|
+
if (!gzip) {
|
|
142
|
+
if (endpoint !== _features.EVENTS) body = (0, _stringify.stringify)(body); // all features going to 'events' endpoint should already be serialized & stringified
|
|
143
|
+
// Warn--once per endpoint--if the agent tries to send large payloads
|
|
144
|
+
if (body.length > 750000 && (warnings[endpoint] = (warnings[endpoint] || 0) + 1) === 1) (0, _console.warn)(28, endpoint);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// If body is null, undefined, or an empty object or array after stringifying, send an empty string instead.
|
|
148
|
+
if (!body || body.length === 0 || body === '{}' || body === '[]') body = '';
|
|
149
|
+
const headers = [{
|
|
150
|
+
key: 'content-type',
|
|
151
|
+
value: 'text/plain'
|
|
152
|
+
}];
|
|
153
|
+
|
|
154
|
+
/* Since workers don't support sendBeacon right now, they can only use XHR method.
|
|
155
|
+
Because they still do permit synch XHR, the idea is that at final harvest time (worker is closing),
|
|
156
|
+
we just make a BLOCKING request--trivial impact--with the remaining data as a temp fill-in for sendBeacon.
|
|
157
|
+
Following the removal of img-element method. */
|
|
158
|
+
let result = submitMethod({
|
|
159
|
+
url: fullUrl,
|
|
160
|
+
body,
|
|
161
|
+
sync: localOpts.isFinalHarvest && _runtime.isWorkerScope,
|
|
162
|
+
headers
|
|
163
|
+
});
|
|
164
|
+
if (!localOpts.isFinalHarvest && cbFinished) {
|
|
165
|
+
// final harvests don't hold onto buffer data (shouldRetryOnFail is false), so cleanup isn't needed
|
|
166
|
+
if (submitMethod === _submitData.xhr) {
|
|
167
|
+
result.addEventListener('loadend', function () {
|
|
168
|
+
// `this` here in block refers to the XHR object in this scope, do not change the anon function to an arrow function
|
|
169
|
+
// status 0 refers to a local error, such as CORS or network failure, or a blocked request by the browser (e.g. adblocker)
|
|
170
|
+
const cbResult = {
|
|
171
|
+
sent: this.status !== 0,
|
|
172
|
+
status: this.status,
|
|
173
|
+
retry: shouldRetry(this.status),
|
|
174
|
+
xhr: this,
|
|
175
|
+
fullUrl,
|
|
176
|
+
targetApp
|
|
177
|
+
};
|
|
178
|
+
if (localOpts.needResponse) cbResult.responseText = this.responseText;
|
|
179
|
+
cbFinished(cbResult);
|
|
180
|
+
}, (0, _eventListenerOpts.eventListenerOpts)(false));
|
|
181
|
+
} else if (submitMethod === _submitData.xhrFetch) {
|
|
182
|
+
result.then(async function (response) {
|
|
183
|
+
const status = response.status;
|
|
184
|
+
const cbResult = {
|
|
185
|
+
sent: true,
|
|
186
|
+
status,
|
|
187
|
+
retry: shouldRetry(status),
|
|
188
|
+
fullUrl,
|
|
189
|
+
fetchResponse: response,
|
|
190
|
+
targetApp
|
|
191
|
+
};
|
|
192
|
+
if (localOpts.needResponse) cbResult.responseText = await response.text();
|
|
193
|
+
cbFinished(cbResult);
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
return true;
|
|
198
|
+
function shouldRetry(status) {
|
|
199
|
+
switch (status) {
|
|
200
|
+
case 429:
|
|
201
|
+
case 408:
|
|
202
|
+
case 500:
|
|
203
|
+
case 503:
|
|
204
|
+
return true;
|
|
205
|
+
default:
|
|
206
|
+
return false;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Cleans and returns a payload object containing a body and qs
|
|
213
|
+
* object with key/value pairs. KV pairs where the value is null,
|
|
214
|
+
* undefined, or an empty string are removed to save on transmission
|
|
215
|
+
* size.
|
|
216
|
+
* @param {HarvestPayload} payload Payload to be sent to the endpoint.
|
|
217
|
+
* @returns {HarvestPayload} Cleaned payload payload to be sent to the endpoint.
|
|
218
|
+
*/
|
|
219
|
+
function cleanPayload(payload = {}) {
|
|
220
|
+
const clean = input => {
|
|
221
|
+
if (typeof Uint8Array !== 'undefined' && input instanceof Uint8Array || Array.isArray(input)) return input;
|
|
222
|
+
if (typeof input === 'string') return input.length > 0 ? input : null;
|
|
223
|
+
return Object.entries(input || {}).reduce((accumulator, [key, value]) => {
|
|
224
|
+
if (typeof value === 'number' || typeof value === 'string' && value.length > 0 || typeof value === 'object' && Object.keys(value || {}).length > 0) {
|
|
225
|
+
accumulator[key] = value;
|
|
226
|
+
}
|
|
227
|
+
return accumulator;
|
|
228
|
+
}, {});
|
|
229
|
+
};
|
|
230
|
+
return {
|
|
231
|
+
body: clean(payload.body),
|
|
232
|
+
qs: clean(payload.qs)
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// The stuff that gets sent every time.
|
|
237
|
+
function baseQueryString(agentRef, qs, endpoint, applicationID) {
|
|
238
|
+
const ref = agentRef.runtime.obfuscator.obfuscateString((0, _cleanUrl.cleanURL)('' + _runtime.globalScope.location));
|
|
239
|
+
const hr = agentRef.runtime.session?.state.sessionReplayMode === 1 && endpoint !== _features.JSERRORS;
|
|
240
|
+
const qps = ['a=' + applicationID, (0, _encode.param)('sa', agentRef.info.sa ? '' + agentRef.info.sa : ''), (0, _encode.param)('v', _env.VERSION), transactionNameParam(), (0, _encode.param)('ct', agentRef.runtime.customTransaction), '&rst=' + (0, _now.now)(), '&ck=0',
|
|
241
|
+
// ck param DEPRECATED - still expected by backend
|
|
242
|
+
'&s=' + (agentRef.runtime.session?.state.value || '0'),
|
|
243
|
+
// the 0 id encaps all untrackable and default traffic
|
|
244
|
+
(0, _encode.param)('ref', ref), (0, _encode.param)('ptid', agentRef.runtime.ptid ? '' + agentRef.runtime.ptid : '')];
|
|
245
|
+
if (hr) qps.push((0, _encode.param)('hr', '1', qs));
|
|
246
|
+
return qps.join('');
|
|
247
|
+
|
|
248
|
+
// Constructs the transaction name param for the beacon URL.
|
|
249
|
+
// Prefers the obfuscated transaction name over the plain text.
|
|
250
|
+
// Falls back to making up a name.
|
|
251
|
+
function transactionNameParam() {
|
|
252
|
+
if (agentRef.info.transactionName) return (0, _encode.param)('to', agentRef.info.transactionName);
|
|
253
|
+
return (0, _encode.param)('t', agentRef.info.tNamePlain || 'Unnamed Transaction');
|
|
254
|
+
}
|
|
255
|
+
}
|
|
@@ -20,32 +20,16 @@ exports.unused = void 0;
|
|
|
20
20
|
* @property {object} body Map of values that should be sent as the body of the request.
|
|
21
21
|
*/
|
|
22
22
|
|
|
23
|
-
/**
|
|
24
|
-
* @typedef {object} FeatureHarvestCallbackOptions Options for aggregating data for harvesting.
|
|
25
|
-
* @property {boolean} options.retry Indicates if the feature should store the aggregated
|
|
26
|
-
* data in anticipation of a possible need to retry the transmission.
|
|
27
|
-
*/
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* @callback FeatureHarvestCallback
|
|
31
|
-
* @param {FeatureHarvestCallbackOptions} options Options for aggregating data for harvesting.
|
|
32
|
-
* @returns {HarvestPayload} Payload of data to transmit to bam endpoint.
|
|
33
|
-
*/
|
|
34
|
-
|
|
35
23
|
/**
|
|
36
24
|
* @typedef {object} NetworkSendSpec
|
|
37
25
|
* @property {HarvestEndpointIdentifier} endpoint The endpoint to use (jserrors, events, resources etc.)
|
|
38
26
|
* @property {HarvestPayload} payload Object representing payload.
|
|
39
|
-
* @property {object}
|
|
40
|
-
* @property {boolean}
|
|
41
|
-
* @property {boolean}
|
|
42
|
-
* @property {boolean}
|
|
43
|
-
* @property {boolean}
|
|
44
|
-
* retry the transmission.
|
|
27
|
+
* @property {object} localOpts Additional options for sending data
|
|
28
|
+
* @property {boolean} localOpts.needResponse Specify whether the caller expects a response data.
|
|
29
|
+
* @property {boolean} localOpts.isFinalHarvest Specify whether the call is a final harvest during page unload.
|
|
30
|
+
* @property {boolean} localOpts.sendEmptyBody Specify whether the call should be made even if the body is empty. Useful for rum calls.
|
|
31
|
+
* @property {boolean} localOpts.forceNoRetry Don't save the buffered data in the case of a need to retry the transmission.
|
|
45
32
|
* @property {import('../util/submit-data.js').NetworkMethods} submitMethod The network method to use {@link ../util/submit-data.js}
|
|
46
|
-
* @property {string} customUrl Override the beacon url the data is sent to; must include protocol if defined
|
|
47
|
-
* @property {boolean} raw If true, disables adding the license key to the url
|
|
48
|
-
* @property {boolean} includeBaseParams Enables the use of base query parameters in the beacon url
|
|
49
33
|
*/
|
|
50
34
|
|
|
51
35
|
/* istanbul ignore next */
|
|
@@ -7,7 +7,6 @@ exports.Aggregate = void 0;
|
|
|
7
7
|
var _registerHandler = require("../../../common/event-emitter/register-handler");
|
|
8
8
|
var _stringify = require("../../../common/util/stringify");
|
|
9
9
|
var _handle = require("../../../common/event-emitter/handle");
|
|
10
|
-
var _harvestScheduler = require("../../../common/harvest/harvest-scheduler");
|
|
11
10
|
var _denyList = require("../../../common/deny-list/deny-list");
|
|
12
11
|
var _constants = require("../constants");
|
|
13
12
|
var _features = require("../../../loaders/features/features");
|
|
@@ -24,7 +23,6 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
24
23
|
static featureName = _constants.FEATURE_NAME;
|
|
25
24
|
constructor(agentRef) {
|
|
26
25
|
super(agentRef, _constants.FEATURE_NAME);
|
|
27
|
-
const harvestTimeSeconds = agentRef.init.ajax.harvestTimeSeconds || 10;
|
|
28
26
|
(0, _denyList.setDenyList)(agentRef.runtime.denyList);
|
|
29
27
|
this.underSpaEvents = {};
|
|
30
28
|
const classThis = this;
|
|
@@ -46,14 +44,7 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
46
44
|
// the EE-drain system not only switches "this" but also passes a new EventContext with info. Should consider platform refactor to another system which passes a mutable context around separately and predictably to avoid problems like this.
|
|
47
45
|
classThis.storeXhr(...arguments, this); // this switches the context back to the class instance while passing the NR context as an argument -- see "ctx" in storeXhr
|
|
48
46
|
}, this.featureName, this.ee);
|
|
49
|
-
this.waitForFlags([]).then(() =>
|
|
50
|
-
const scheduler = new _harvestScheduler.HarvestScheduler(_features.FEATURE_TO_ENDPOINT[this.featureName], {
|
|
51
|
-
onFinished: result => this.postHarvestCleanup(result.sent && result.retry),
|
|
52
|
-
getPayload: options => this.makeHarvestPayload(options.retry)
|
|
53
|
-
}, this);
|
|
54
|
-
scheduler.startTimer(harvestTimeSeconds);
|
|
55
|
-
this.drain();
|
|
56
|
-
});
|
|
47
|
+
this.waitForFlags([]).then(() => this.drain());
|
|
57
48
|
}
|
|
58
49
|
storeXhr(params, metrics, startTime, endTime, type, ctx) {
|
|
59
50
|
metrics.time = startTime;
|
|
@@ -71,7 +62,7 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
71
62
|
|
|
72
63
|
// Report ajax timeslice metric (to be harvested by jserrors feature, but only if it's running).
|
|
73
64
|
if (jserrorsInUse && (shouldCollect || !shouldOmitAjaxMetrics)) {
|
|
74
|
-
this.agentRef.sharedAggregator.add('xhr', hash, params, metrics);
|
|
65
|
+
this.agentRef.sharedAggregator.add(['xhr', hash, params, metrics]);
|
|
75
66
|
}
|
|
76
67
|
if (!shouldCollect) {
|
|
77
68
|
if (params.hostname === this.agentRef.info.errorBeacon || this.agentRef.init.proxy?.beacon && params.hostname === this.agentRef.init.proxy.beacon) {
|
|
@@ -5,7 +5,6 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.Aggregate = void 0;
|
|
7
7
|
var _stringify = require("../../../common/util/stringify");
|
|
8
|
-
var _harvestScheduler = require("../../../common/harvest/harvest-scheduler");
|
|
9
8
|
var _cleanUrl = require("../../../common/url/clean-url");
|
|
10
9
|
var _constants = require("../constants");
|
|
11
10
|
var _runtime = require("../../../common/constants/runtime");
|
|
@@ -15,7 +14,6 @@ var _now = require("../../../common/timing/now");
|
|
|
15
14
|
var _registerHandler = require("../../../common/event-emitter/register-handler");
|
|
16
15
|
var _constants2 = require("../../metrics/constants");
|
|
17
16
|
var _traverse = require("../../../common/util/traverse");
|
|
18
|
-
var _features = require("../../../loaders/features/features");
|
|
19
17
|
var _userActionsAggregator = require("./user-actions/user-actions-aggregator");
|
|
20
18
|
var _iframe = require("../../../common/dom/iframe");
|
|
21
19
|
var _handle = require("../../../common/event-emitter/handle");
|
|
@@ -29,7 +27,6 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
29
27
|
constructor(agentRef) {
|
|
30
28
|
super(agentRef, _constants.FEATURE_NAME);
|
|
31
29
|
this.eventsPerHarvest = 1000;
|
|
32
|
-
this.harvestTimeSeconds = agentRef.init.generic_events.harvestTimeSeconds;
|
|
33
30
|
this.referrerUrl = _runtime.isBrowserScope && document.referrer ? (0, _cleanUrl.cleanURL)(document.referrer) : undefined;
|
|
34
31
|
this.waitForFlags(['ins']).then(([ins]) => {
|
|
35
32
|
if (!ins) {
|
|
@@ -38,12 +35,20 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
38
35
|
return;
|
|
39
36
|
}
|
|
40
37
|
this.trackSupportabilityMetrics();
|
|
38
|
+
(0, _registerHandler.registerHandler)('api-recordCustomEvent', (timestamp, eventType, attributes) => {
|
|
39
|
+
if (_constants.RESERVED_EVENT_TYPES.includes(eventType)) return (0, _console.warn)(46);
|
|
40
|
+
this.addEvent({
|
|
41
|
+
eventType,
|
|
42
|
+
timestamp: this.toEpoch(timestamp),
|
|
43
|
+
...attributes
|
|
44
|
+
});
|
|
45
|
+
}, this.featureName, this.ee);
|
|
41
46
|
if (agentRef.init.page_action.enabled) {
|
|
42
47
|
(0, _registerHandler.registerHandler)('api-addPageAction', (timestamp, name, attributes) => {
|
|
43
48
|
this.addEvent({
|
|
44
49
|
...attributes,
|
|
45
50
|
eventType: 'PageAction',
|
|
46
|
-
timestamp:
|
|
51
|
+
timestamp: this.toEpoch(timestamp),
|
|
47
52
|
timeSinceLoad: timestamp / 1000,
|
|
48
53
|
actionName: name,
|
|
49
54
|
referrerUrl: this.referrerUrl,
|
|
@@ -57,6 +62,7 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
57
62
|
let addUserAction;
|
|
58
63
|
if (_runtime.isBrowserScope && agentRef.init.user_actions.enabled) {
|
|
59
64
|
this.userActionAggregator = new _userActionsAggregator.UserActionsAggregator();
|
|
65
|
+
this.harvestOpts.beforeUnload = () => addUserAction?.(this.userActionAggregator.aggregationEvent);
|
|
60
66
|
addUserAction = aggregatedUserAction => {
|
|
61
67
|
try {
|
|
62
68
|
/** The aggregator process only returns an event when it is "done" aggregating -
|
|
@@ -69,7 +75,7 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
69
75
|
} = aggregatedUserAction.event;
|
|
70
76
|
this.addEvent({
|
|
71
77
|
eventType: 'UserAction',
|
|
72
|
-
timestamp:
|
|
78
|
+
timestamp: this.toEpoch(timeStamp),
|
|
73
79
|
action: type,
|
|
74
80
|
actionCount: aggregatedUserAction.count,
|
|
75
81
|
actionDuration: aggregatedUserAction.relativeMs[aggregatedUserAction.relativeMs.length - 1],
|
|
@@ -130,7 +136,7 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
130
136
|
(0, _handle.handle)(_constants2.SUPPORTABILITY_METRIC_CHANNEL, ['Generic/Performance/' + type + '/Seen']);
|
|
131
137
|
this.addEvent({
|
|
132
138
|
eventType: 'BrowserPerformance',
|
|
133
|
-
timestamp:
|
|
139
|
+
timestamp: this.toEpoch(entry.startTime),
|
|
134
140
|
entryName: (0, _cleanUrl.cleanURL)(entry.name),
|
|
135
141
|
entryDuration: entry.duration,
|
|
136
142
|
entryType: type,
|
|
@@ -192,12 +198,7 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
192
198
|
}
|
|
193
199
|
}, this.featureName, this.ee);
|
|
194
200
|
}
|
|
195
|
-
|
|
196
|
-
onFinished: result => this.postHarvestCleanup(result.sent && result.retry),
|
|
197
|
-
onUnload: () => addUserAction?.(this.userActionAggregator.aggregationEvent)
|
|
198
|
-
}, this);
|
|
199
|
-
this.harvestScheduler.harvest.on(_features.FEATURE_TO_ENDPOINT[this.featureName], options => this.makeHarvestPayload(options.retry));
|
|
200
|
-
this.harvestScheduler.startTimer(this.harvestTimeSeconds, 0);
|
|
201
|
+
agentRef.runtime.harvester.triggerHarvestFor(this);
|
|
201
202
|
this.drain();
|
|
202
203
|
});
|
|
203
204
|
}
|
|
@@ -247,7 +248,7 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
247
248
|
* if it fails again, we do nothing
|
|
248
249
|
*/
|
|
249
250
|
this.ee.emit(_constants2.SUPPORTABILITY_METRIC_CHANNEL, ['GenericEvents/Harvest/Max/Seen']);
|
|
250
|
-
this.
|
|
251
|
+
this.agentRef.runtime.harvester.triggerHarvestFor(this);
|
|
251
252
|
this.events.add(eventAttributes);
|
|
252
253
|
}
|
|
253
254
|
}
|
|
@@ -262,6 +263,9 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
262
263
|
at: this.agentRef.info.atts
|
|
263
264
|
};
|
|
264
265
|
}
|
|
266
|
+
toEpoch(timestamp) {
|
|
267
|
+
return Math.floor(this.agentRef.runtime.timeKeeper.correctRelativeTimestamp(timestamp));
|
|
268
|
+
}
|
|
265
269
|
trackSupportabilityMetrics() {
|
|
266
270
|
/** track usage SMs to improve these experimental features */
|
|
267
271
|
const configPerfTag = 'Config/Performance/';
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.RAGE_CLICK_THRESHOLD_MS = exports.RAGE_CLICK_THRESHOLD_EVENTS = exports.OBSERVED_WINDOW_EVENTS = exports.OBSERVED_EVENTS = exports.MAX_PAYLOAD_SIZE = exports.IDEAL_PAYLOAD_SIZE = exports.FEATURE_NAME = exports.FEATURE_FLAGS = void 0;
|
|
6
|
+
exports.RESERVED_EVENT_TYPES = exports.RAGE_CLICK_THRESHOLD_MS = exports.RAGE_CLICK_THRESHOLD_EVENTS = exports.OBSERVED_WINDOW_EVENTS = exports.OBSERVED_EVENTS = exports.MAX_PAYLOAD_SIZE = exports.IDEAL_PAYLOAD_SIZE = exports.FEATURE_NAME = exports.FEATURE_FLAGS = void 0;
|
|
7
7
|
var _features = require("../../loaders/features/features");
|
|
8
8
|
const FEATURE_NAME = exports.FEATURE_NAME = _features.FEATURE_NAMES.genericEvents;
|
|
9
9
|
const IDEAL_PAYLOAD_SIZE = exports.IDEAL_PAYLOAD_SIZE = 64000;
|
|
@@ -12,6 +12,7 @@ const OBSERVED_EVENTS = exports.OBSERVED_EVENTS = ['auxclick', 'click', 'copy',
|
|
|
12
12
|
const OBSERVED_WINDOW_EVENTS = exports.OBSERVED_WINDOW_EVENTS = ['focus', 'blur'];
|
|
13
13
|
const RAGE_CLICK_THRESHOLD_EVENTS = exports.RAGE_CLICK_THRESHOLD_EVENTS = 4;
|
|
14
14
|
const RAGE_CLICK_THRESHOLD_MS = exports.RAGE_CLICK_THRESHOLD_MS = 1000;
|
|
15
|
+
const RESERVED_EVENT_TYPES = exports.RESERVED_EVENT_TYPES = ['PageAction', 'UserAction', 'BrowserPerformance'];
|
|
15
16
|
const FEATURE_FLAGS = exports.FEATURE_FLAGS = {
|
|
16
17
|
MARKS: 'experimental.marks',
|
|
17
18
|
MEASURES: 'experimental.measures',
|
|
@@ -9,7 +9,6 @@ var _computeStackTrace = require("./compute-stack-trace");
|
|
|
9
9
|
var _stringHashCode = require("./string-hash-code");
|
|
10
10
|
var _formatStackTrace = require("./format-stack-trace");
|
|
11
11
|
var _registerHandler = require("../../../common/event-emitter/register-handler");
|
|
12
|
-
var _harvestScheduler = require("../../../common/harvest/harvest-scheduler");
|
|
13
12
|
var _stringify = require("../../../common/util/stringify");
|
|
14
13
|
var _handle = require("../../../common/event-emitter/handle");
|
|
15
14
|
var _runtime = require("../../../common/constants/runtime");
|
|
@@ -45,21 +44,11 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
45
44
|
(0, _registerHandler.registerHandler)('ierr', (...args) => this.storeError(...args), this.featureName, this.ee);
|
|
46
45
|
(0, _registerHandler.registerHandler)('softNavFlush', (interactionId, wasFinished, softNavAttrs) => this.onSoftNavNotification(interactionId, wasFinished, softNavAttrs), this.featureName, this.ee); // when an ixn is done or cancelled
|
|
47
46
|
|
|
48
|
-
|
|
49
|
-
const aggregatorTypes = ['err', 'ierr', 'xhr']; // the types in EventAggregator this feature cares about
|
|
47
|
+
this.harvestOpts.aggregatorTypes = ['err', 'ierr', 'xhr']; // the types in EventAggregator this feature cares about
|
|
50
48
|
|
|
51
49
|
// 0 == off, 1 == on
|
|
52
50
|
this.waitForFlags(['err']).then(([errFlag]) => {
|
|
53
51
|
if (errFlag) {
|
|
54
|
-
const scheduler = new _harvestScheduler.HarvestScheduler(_features.FEATURE_TO_ENDPOINT[this.featureName], {
|
|
55
|
-
onFinished: result => this.postHarvestCleanup(result.sent && result.retry, {
|
|
56
|
-
aggregatorTypes
|
|
57
|
-
})
|
|
58
|
-
}, this);
|
|
59
|
-
scheduler.harvest.on(_features.FEATURE_TO_ENDPOINT[this.featureName], options => this.makeHarvestPayload(options.retry, {
|
|
60
|
-
aggregatorTypes
|
|
61
|
-
}));
|
|
62
|
-
scheduler.startTimer(harvestTimeSeconds);
|
|
63
52
|
this.drain();
|
|
64
53
|
} else {
|
|
65
54
|
this.blocked = true; // if rum response determines that customer lacks entitlements for spa endpoint, this feature shouldn't harvest
|
|
@@ -225,7 +214,7 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
225
214
|
|
|
226
215
|
const jsAttributesHash = (0, _stringHashCode.stringHashCode)((0, _stringify.stringify)(allCustomAttrs));
|
|
227
216
|
const aggregateHash = bucketHash + ':' + jsAttributesHash;
|
|
228
|
-
this.events.add(type, aggregateHash, params, newMetrics, allCustomAttrs);
|
|
217
|
+
this.events.add([type, aggregateHash, params, newMetrics, allCustomAttrs]);
|
|
229
218
|
function setCustom(key, val) {
|
|
230
219
|
allCustomAttrs[key] = val && typeof val === 'object' ? (0, _stringify.stringify)(val) : val;
|
|
231
220
|
}
|
|
@@ -249,7 +238,7 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
249
238
|
var hash = wasSaved ? item[1] + interaction.root.attrs.id : item[1];
|
|
250
239
|
var jsAttributesHash = (0, _stringHashCode.stringHashCode)((0, _stringify.stringify)(allCustomAttrs));
|
|
251
240
|
var aggregateHash = hash + ':' + jsAttributesHash;
|
|
252
|
-
this.events.add(item[0], aggregateHash, params, item[3], allCustomAttrs);
|
|
241
|
+
this.events.add([item[0], aggregateHash, params, item[3], allCustomAttrs]);
|
|
253
242
|
function setCustom([key, val]) {
|
|
254
243
|
allCustomAttrs[key] = val && typeof val === 'object' ? (0, _stringify.stringify)(val) : val;
|
|
255
244
|
}
|