@newrelic/browser-agent 1.320.0 → 1.320.1-rc.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/CHANGELOG.md +8 -0
- package/dist/cjs/common/config/runtime.js +1 -0
- package/dist/cjs/common/constants/env.cdn.js +1 -1
- package/dist/cjs/common/constants/env.npm.js +1 -1
- package/dist/cjs/common/event-listener/event-listener-opts.js +1 -1
- package/dist/cjs/common/harvest/connector.js +200 -0
- package/dist/cjs/common/harvest/harvester.js +5 -8
- package/dist/cjs/common/harvest/send.js +8 -7
- package/dist/cjs/common/payloads/payloads.js +3 -2
- package/dist/cjs/common/serialize/bel-serializer.js +17 -4
- package/dist/cjs/common/timer/interaction-timer.js +2 -2
- package/dist/cjs/common/unload/eol.js +3 -3
- package/dist/cjs/common/util/console.js +2 -1
- package/dist/cjs/common/util/feature-flags.js +2 -1
- package/dist/cjs/common/v2/mfe-vitals.js +34 -11
- package/dist/cjs/common/window/page-visibility.js +1 -1
- package/dist/cjs/features/ajax/aggregate/index.js +19 -8
- package/dist/cjs/features/page_view_event/aggregate/index.js +2 -6
- package/dist/cjs/features/page_view_event/aggregate_v2/index.js +109 -0
- package/dist/cjs/features/page_view_event/instrument/index.js +6 -1
- package/dist/cjs/features/page_view_timing/aggregate/index.js +33 -14
- package/dist/cjs/features/session_replay/instrument/index.js +9 -0
- package/dist/cjs/features/session_replay/shared/recorder.js +2 -1
- package/dist/cjs/features/soft_navigations/aggregate/ajax-node.js +16 -4
- package/dist/cjs/features/soft_navigations/aggregate/interaction.js +10 -3
- package/dist/cjs/features/utils/aggregate-base.js +0 -12
- package/dist/cjs/features/utils/instrument-base.js +72 -29
- package/dist/cjs/loaders/agent.js +2 -1
- package/dist/cjs/loaders/api/consent.js +2 -2
- package/dist/cjs/loaders/features/features.js +2 -1
- package/dist/esm/common/config/runtime.js +1 -0
- package/dist/esm/common/constants/env.cdn.js +1 -1
- package/dist/esm/common/constants/env.npm.js +1 -1
- package/dist/esm/common/event-listener/event-listener-opts.js +1 -1
- package/dist/esm/common/harvest/connector.js +193 -0
- package/dist/esm/common/harvest/harvester.js +5 -8
- package/dist/esm/common/harvest/send.js +10 -9
- package/dist/esm/common/payloads/payloads.js +3 -2
- package/dist/esm/common/serialize/bel-serializer.js +17 -4
- package/dist/esm/common/timer/interaction-timer.js +2 -2
- package/dist/esm/common/unload/eol.js +3 -3
- package/dist/esm/common/util/console.js +2 -1
- package/dist/esm/common/util/feature-flags.js +2 -1
- package/dist/esm/common/v2/mfe-vitals.js +34 -11
- package/dist/esm/common/window/page-visibility.js +1 -1
- package/dist/esm/features/ajax/aggregate/index.js +19 -8
- package/dist/esm/features/page_view_event/aggregate/index.js +2 -6
- package/dist/esm/features/page_view_event/aggregate_v2/index.js +100 -0
- package/dist/esm/features/page_view_event/instrument/index.js +6 -1
- package/dist/esm/features/page_view_timing/aggregate/index.js +33 -14
- package/dist/esm/features/session_replay/instrument/index.js +9 -0
- package/dist/esm/features/session_replay/shared/recorder.js +2 -1
- package/dist/esm/features/soft_navigations/aggregate/ajax-node.js +16 -4
- package/dist/esm/features/soft_navigations/aggregate/interaction.js +10 -3
- package/dist/esm/features/utils/aggregate-base.js +0 -12
- package/dist/esm/features/utils/instrument-base.js +71 -28
- package/dist/esm/loaders/agent.js +2 -1
- package/dist/esm/loaders/api/consent.js +2 -2
- package/dist/esm/loaders/features/features.js +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/common/config/runtime.d.ts.map +1 -1
- package/dist/types/common/event-listener/event-listener-opts.d.ts +1 -1
- package/dist/types/common/harvest/connector.d.ts +6 -0
- package/dist/types/common/harvest/connector.d.ts.map +1 -0
- package/dist/types/common/harvest/harvester.d.ts.map +1 -1
- package/dist/types/common/harvest/send.d.ts.map +1 -1
- package/dist/types/common/payloads/payloads.d.ts +3 -2
- package/dist/types/common/payloads/payloads.d.ts.map +1 -1
- package/dist/types/common/serialize/bel-serializer.d.ts +9 -1
- package/dist/types/common/serialize/bel-serializer.d.ts.map +1 -1
- package/dist/types/common/unload/eol.d.ts +1 -1
- package/dist/types/common/unload/eol.d.ts.map +1 -1
- package/dist/types/common/util/console.d.ts +2 -1
- package/dist/types/common/util/console.d.ts.map +1 -1
- package/dist/types/common/v2/mfe-vitals.d.ts.map +1 -1
- package/dist/types/features/ajax/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_event/aggregate_v2/index.d.ts +20 -0
- package/dist/types/features/page_view_event/aggregate_v2/index.d.ts.map +1 -0
- package/dist/types/features/page_view_event/instrument/index.d.ts.map +1 -1
- package/dist/types/features/page_view_timing/aggregate/index.d.ts +0 -1
- package/dist/types/features/page_view_timing/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/session_replay/instrument/index.d.ts +1 -0
- package/dist/types/features/session_replay/instrument/index.d.ts.map +1 -1
- package/dist/types/features/session_replay/shared/recorder.d.ts.map +1 -1
- package/dist/types/features/soft_navigations/aggregate/ajax-node.d.ts.map +1 -1
- package/dist/types/features/soft_navigations/aggregate/interaction.d.ts.map +1 -1
- package/dist/types/features/utils/aggregate-base.d.ts +0 -5
- package/dist/types/features/utils/aggregate-base.d.ts.map +1 -1
- package/dist/types/features/utils/instrument-base.d.ts.map +1 -1
- package/dist/types/loaders/agent.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 +2 -2
- package/src/common/config/runtime.js +1 -0
- package/src/common/event-listener/event-listener-opts.js +1 -1
- package/src/common/harvest/connector.js +168 -0
- package/src/common/harvest/harvester.js +7 -9
- package/src/common/harvest/send.js +9 -7
- package/src/common/payloads/payloads.js +3 -2
- package/src/common/serialize/bel-serializer.js +13 -4
- package/src/common/timer/interaction-timer.js +2 -2
- package/src/common/unload/eol.js +3 -3
- package/src/common/util/console.js +2 -1
- package/src/common/util/feature-flags.js +1 -1
- package/src/common/v2/mfe-vitals.js +39 -12
- package/src/common/window/page-visibility.js +1 -1
- package/src/features/ajax/aggregate/index.js +12 -9
- package/src/features/page_view_event/aggregate/index.js +2 -6
- package/src/features/page_view_event/aggregate_v2/index.js +97 -0
- package/src/features/page_view_event/instrument/index.js +6 -1
- package/src/features/page_view_timing/aggregate/index.js +24 -15
- package/src/features/session_replay/instrument/index.js +9 -0
- package/src/features/session_replay/shared/recorder.js +2 -1
- package/src/features/soft_navigations/aggregate/ajax-node.js +10 -7
- package/src/features/soft_navigations/aggregate/interaction.js +6 -5
- package/src/features/utils/aggregate-base.js +0 -12
- package/src/features/utils/instrument-base.js +71 -25
- package/src/loaders/agent.js +2 -1
- package/src/loaders/api/consent.js +2 -2
- package/src/loaders/features/features.js +1 -0
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2020-2026 New Relic, Inc. All rights reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
import { globalScope, isBrowserScope, originTime, getNavigationEntry } from '../../../common/constants/runtime';
|
|
6
|
+
import { addPT, addPN } from '../../../common/timing/nav-timing';
|
|
7
|
+
import { stringify } from '../../../common/util/stringify';
|
|
8
|
+
import * as CONSTANTS from '../constants';
|
|
9
|
+
import { getActivatedFeaturesFlags } from '../aggregate/initialized-features';
|
|
10
|
+
import { AggregateBase } from '../../utils/aggregate-base';
|
|
11
|
+
import { firstContentfulPaint } from '../../../common/vitals/first-contentful-paint';
|
|
12
|
+
import { firstPaint } from '../../../common/vitals/first-paint';
|
|
13
|
+
import { timeToFirstByte } from '../../../common/vitals/time-to-first-byte';
|
|
14
|
+
import { Obfuscator } from '../../../common/util/obfuscate';
|
|
15
|
+
import { webdriverDetected } from '../../../common/util/webdriver-detection';
|
|
16
|
+
import { EVENT_TYPES } from '../../../common/constants/events';
|
|
17
|
+
export class Aggregate extends AggregateBase {
|
|
18
|
+
static featureName = CONSTANTS.FEATURE_NAME;
|
|
19
|
+
#timeToFirstByte = 0;
|
|
20
|
+
#firstByteToWindowLoad = 0; // our "frontend" duration
|
|
21
|
+
#firstByteToDomContent = 0; // our "dom processing" duration
|
|
22
|
+
#obfuscator;
|
|
23
|
+
constructor(agentRef) {
|
|
24
|
+
super(agentRef, CONSTANTS.FEATURE_NAME);
|
|
25
|
+
this.#obfuscator = new Obfuscator(agentRef, EVENT_TYPES.PVE);
|
|
26
|
+
if (isBrowserScope) {
|
|
27
|
+
timeToFirstByte.subscribe(({
|
|
28
|
+
value,
|
|
29
|
+
attrs
|
|
30
|
+
}) => {
|
|
31
|
+
const navEntry = attrs.navigationEntry;
|
|
32
|
+
this.#timeToFirstByte = Math.max(value, this.#timeToFirstByte);
|
|
33
|
+
this.#firstByteToWindowLoad = Math.max(Math.round(navEntry.loadEventEnd - this.#timeToFirstByte), this.#firstByteToWindowLoad); // our "frontend" duration
|
|
34
|
+
this.#firstByteToDomContent = Math.max(Math.round(navEntry.domContentLoadedEventEnd - this.#timeToFirstByte), this.#firstByteToDomContent); // our "dom processing" duration
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
this.waitForFlags([]).then(() => {
|
|
38
|
+
const body = this.#obfuscator.traverseAndObfuscateEvents({
|
|
39
|
+
ja: {
|
|
40
|
+
...agentRef.info.jsAttributes,
|
|
41
|
+
webdriverDetected
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
this.events.add(body);
|
|
45
|
+
this.drain();
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
queryStringsBuilder() {
|
|
49
|
+
const info = this.agentRef.info;
|
|
50
|
+
const measures = {};
|
|
51
|
+
if (info.queueTime) measures.qt = info.queueTime;
|
|
52
|
+
if (info.applicationTime) measures.ap = info.applicationTime;
|
|
53
|
+
|
|
54
|
+
// These 3 values should've been recorded after load and before this func runs. They are part of the minimum required for PageView events to be created.
|
|
55
|
+
// Following PR #428, which demands that the BA must drive entity indexing, these need to be sent even outside of the main window context where PerformanceTiming
|
|
56
|
+
// or PerformanceNavigationTiming do not exists. Hence, they'll be filled in by 0s instead in, for example, worker threads that still init the PVE module.
|
|
57
|
+
measures.be = this.#timeToFirstByte;
|
|
58
|
+
measures.fe = this.#firstByteToWindowLoad;
|
|
59
|
+
measures.dc = this.#firstByteToDomContent;
|
|
60
|
+
const queryParameters = {
|
|
61
|
+
at: info.atts,
|
|
62
|
+
af: getActivatedFeaturesFlags(this.agentRef).join(','),
|
|
63
|
+
igp: this.agentRef.runtime.appMetadata.igp,
|
|
64
|
+
...measures,
|
|
65
|
+
fp: firstPaint.current.value,
|
|
66
|
+
fcp: firstContentfulPaint.current.value
|
|
67
|
+
};
|
|
68
|
+
if (globalScope.performance) {
|
|
69
|
+
const navTimingEntry = getNavigationEntry();
|
|
70
|
+
if (navTimingEntry) {
|
|
71
|
+
// Navigation Timing level 2 API that replaced PerformanceTiming & PerformanceNavigation
|
|
72
|
+
const perf = {
|
|
73
|
+
timing: addPT(originTime, navTimingEntry, {}),
|
|
74
|
+
navigation: addPN(navTimingEntry, {})
|
|
75
|
+
};
|
|
76
|
+
queryParameters.perf = stringify(perf);
|
|
77
|
+
} else if (typeof PerformanceTiming !== 'undefined') {
|
|
78
|
+
// Modern Safari iFrames and Safari pre-15 do not support level 2 timing.
|
|
79
|
+
const perf = {
|
|
80
|
+
timing: addPT(originTime, globalScope.performance.timing, {}, true),
|
|
81
|
+
navigation: addPN(globalScope.performance.navigation, {})
|
|
82
|
+
};
|
|
83
|
+
queryParameters.perf = stringify(perf);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
const {
|
|
87
|
+
correctedOriginTime
|
|
88
|
+
} = this.agentRef.runtime.timeKeeper;
|
|
89
|
+
if (correctedOriginTime) queryParameters.timestamp = correctedOriginTime; // a "PageView" is set to represent the page's (server adjusted) origin time rather than when event is recorded/harvested
|
|
90
|
+
|
|
91
|
+
return queryParameters;
|
|
92
|
+
}
|
|
93
|
+
get harvestEndpointVersion() {
|
|
94
|
+
return 2;
|
|
95
|
+
}
|
|
96
|
+
serializer(eventBuffer) {
|
|
97
|
+
// this is necessary because PVE sends a single item rather than an array; in the case of undefined, this prevents sending [null] as body
|
|
98
|
+
return eventBuffer[0];
|
|
99
|
+
}
|
|
100
|
+
}
|
|
@@ -18,7 +18,12 @@ export class Instrument extends InstrumentBase {
|
|
|
18
18
|
|
|
19
19
|
/** feature specific APIs */
|
|
20
20
|
setupSetPageViewNameAPI(agentRef);
|
|
21
|
-
this.importAggregator(agentRef, () =>
|
|
21
|
+
this.importAggregator(agentRef, () => {
|
|
22
|
+
if (agentRef.init.feature_flags.includes('rum_v2')) {
|
|
23
|
+
return import(/* webpackChunkName: "page_view_event-aggregate" */'../aggregate_v2');
|
|
24
|
+
}
|
|
25
|
+
return import(/* webpackChunkName: "page_view_event-aggregate" */'../aggregate');
|
|
26
|
+
});
|
|
22
27
|
}
|
|
23
28
|
setupInspectionEvents() {
|
|
24
29
|
const dispatch = (evt, name) => {
|
|
@@ -23,6 +23,7 @@ import { loadTime } from '../../../common/vitals/load-time';
|
|
|
23
23
|
import { webdriverDetected } from '../../../common/util/webdriver-detection';
|
|
24
24
|
import { cleanURL } from '../../../common/url/clean-url';
|
|
25
25
|
import { EVENT_TYPES } from '../../../common/constants/events';
|
|
26
|
+
import { createStringAdders } from '../../../common/payloads/payloads';
|
|
26
27
|
export class Aggregate extends AggregateBase {
|
|
27
28
|
static featureName = FEATURE_NAME;
|
|
28
29
|
#handleVitalMetric = ({
|
|
@@ -65,7 +66,11 @@ export class Aggregate extends AggregateBase {
|
|
|
65
66
|
} = cumulativeLayoutShift.current;
|
|
66
67
|
if (value === undefined) return;
|
|
67
68
|
this.addTiming(name, value * 1000, attrs);
|
|
68
|
-
}, true, true); // CLS node should only
|
|
69
|
+
}, true, true); // CLS node should only report on vis change rather than on every change.
|
|
70
|
+
/* NOTE: the capture=true is required -- empirically verified against a real browser (Chrome) for CLS
|
|
71
|
+
timing node to reliably be in the same final harvest as the rest, alongside Harvester#startTimer's
|
|
72
|
+
queueMicrotask deferral of the EOL harvest itself. Dropping this flag caused CLS to be split into its own,
|
|
73
|
+
separate, later harvest instead of going out together with pageHide/INP. */
|
|
69
74
|
|
|
70
75
|
this.drain();
|
|
71
76
|
});
|
|
@@ -98,6 +103,7 @@ export class Aggregate extends AggregateBase {
|
|
|
98
103
|
if (name !== VITAL_NAMES.CUMULATIVE_LAYOUT_SHIFT && cumulativeLayoutShift.current.value >= 0) {
|
|
99
104
|
attrs.cls = cumulativeLayoutShift.current.value;
|
|
100
105
|
}
|
|
106
|
+
attrs.webdriverDetected = webdriverDetected;
|
|
101
107
|
const timing = {
|
|
102
108
|
name,
|
|
103
109
|
value,
|
|
@@ -127,15 +133,9 @@ export class Aggregate extends AggregateBase {
|
|
|
127
133
|
loadState: document.readyState
|
|
128
134
|
});
|
|
129
135
|
}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
Object.entries(this.agentRef.info.jsAttributes || {}).forEach(([key, val]) => {
|
|
134
|
-
if (reservedAttributes.indexOf(key) < 0) {
|
|
135
|
-
timingAttributes[key] = val;
|
|
136
|
-
}
|
|
137
|
-
});
|
|
138
|
-
timingAttributes.webdriverDetected = webdriverDetected;
|
|
136
|
+
#getGlobalCustomAttributes() {
|
|
137
|
+
const reservedAttributes = ['size', 'eid', 'cls', 'type', 'fid', 'elTag', 'elUrl', 'net-type', 'net-etype', 'net-rtt', 'net-dlink', 'webdriverDetected'];
|
|
138
|
+
return Object.fromEntries(Object.entries(this.agentRef.info.jsAttributes || {}).filter(([key]) => !reservedAttributes.includes(key)));
|
|
139
139
|
}
|
|
140
140
|
preHarvestChecks() {
|
|
141
141
|
this.checkForFirstInteraction();
|
|
@@ -145,15 +145,34 @@ export class Aggregate extends AggregateBase {
|
|
|
145
145
|
// serialize array of timing data
|
|
146
146
|
serializer(eventBuffer) {
|
|
147
147
|
if (!eventBuffer?.length) return '';
|
|
148
|
-
|
|
148
|
+
const {
|
|
149
|
+
addString,
|
|
150
|
+
addStringRaw
|
|
151
|
+
} = createStringAdders(getAddStringContext, this.obfuscator);
|
|
152
|
+
const keepOrigValue = {
|
|
153
|
+
addKey: addStringRaw,
|
|
154
|
+
addVal: addStringRaw
|
|
155
|
+
};
|
|
156
|
+
const obfuscateValue = {
|
|
157
|
+
addKey: addStringRaw,
|
|
158
|
+
addVal: addString
|
|
159
|
+
};
|
|
149
160
|
var payload = 'bel.6;';
|
|
150
161
|
for (var i = 0; i < eventBuffer.length; i++) {
|
|
151
162
|
var timing = eventBuffer[i];
|
|
152
163
|
payload += 'e,';
|
|
153
|
-
payload +=
|
|
164
|
+
payload += addStringRaw(timing.name) + ',';
|
|
154
165
|
payload += nullable(timing.value, numeric, false) + ',';
|
|
155
|
-
this
|
|
156
|
-
|
|
166
|
+
const userAttrs = this.#getGlobalCustomAttributes();
|
|
167
|
+
const {
|
|
168
|
+
pageUrl,
|
|
169
|
+
...systemReservedAttrs
|
|
170
|
+
} = timing.attrs || {};
|
|
171
|
+
var attrParts = addCustomAttributes(systemReservedAttrs, keepOrigValue);
|
|
172
|
+
attrParts.push(...addCustomAttributes(userAttrs, obfuscateValue));
|
|
173
|
+
if (pageUrl) attrParts.push(...addCustomAttributes({
|
|
174
|
+
pageUrl
|
|
175
|
+
}, obfuscateValue));
|
|
157
176
|
if (attrParts && attrParts.length > 0) {
|
|
158
177
|
payload += numeric(attrParts.length) + ';' + attrParts.join(';');
|
|
159
178
|
}
|
|
@@ -40,6 +40,10 @@ export class Instrument extends InstrumentBase {
|
|
|
40
40
|
recorder.startRecording(TRIGGERS.PRELOAD, session?.sessionReplayMode);
|
|
41
41
|
}); // could handle specific fail-state behaviors with a .catch block here
|
|
42
42
|
}
|
|
43
|
+
|
|
44
|
+
// If the aggregate never successfully loads (missing session prerequisite, or the aggregate module itself
|
|
45
|
+
// fails to import/construct), any preload recording that already started needs to be stopped.
|
|
46
|
+
this.abortHandler = this.#abort;
|
|
43
47
|
this.importAggregator(this.agentRef, () => import(/* webpackChunkName: "session_replay-aggregate" */'../aggregate'), this);
|
|
44
48
|
|
|
45
49
|
/** If the recorder is running, we can pass error events on to the agg to help it switch to full mode later */
|
|
@@ -104,5 +108,10 @@ export class Instrument extends InstrumentBase {
|
|
|
104
108
|
}); // could handle specific fail-state behaviors with a .catch block here
|
|
105
109
|
}
|
|
106
110
|
}
|
|
111
|
+
|
|
112
|
+
/** Stops any preload recording that already started if the aggregate never ends up successfully loading. */
|
|
113
|
+
#abort() {
|
|
114
|
+
this.recorder?.stopRecording();
|
|
115
|
+
}
|
|
107
116
|
}
|
|
108
117
|
export const SessionReplay = Instrument;
|
|
@@ -209,7 +209,8 @@ export class Recorder {
|
|
|
209
209
|
|
|
210
210
|
// We are making an effort to try to keep payloads manageable for unloading. If they reach the unload limit before their interval,
|
|
211
211
|
// it will send immediately. This often happens on the first snapshot, which can be significantly larger than the other payloads.
|
|
212
|
-
|
|
212
|
+
// (the aggregate may not exist yet/at all if its own bootstrap hasn't finished or failed -- nothing to harvest for in that case.)
|
|
213
|
+
if ((this.events.hasSnapshot && this.events.hasMeta || payloadSize > IDEAL_PAYLOAD_SIZE) && !this.isErrorMode && this.srInstrument.featAggregate) {
|
|
213
214
|
// if we've made it to the ideal size of ~16kb before the interval timer, we should send early.
|
|
214
215
|
this.agentRef.runtime.harvester.triggerHarvestFor(this.srInstrument.featAggregate);
|
|
215
216
|
}
|
|
@@ -41,6 +41,7 @@ export class AjaxNode extends BelNode {
|
|
|
41
41
|
serialize(parentStartTimestamp, agentRef, ajaxObfuscator) {
|
|
42
42
|
const {
|
|
43
43
|
addString,
|
|
44
|
+
addStringRaw,
|
|
44
45
|
addStringWithTruncation
|
|
45
46
|
} = createStringAdders(getAddStringContext, ajaxObfuscator);
|
|
46
47
|
const nodeList = [];
|
|
@@ -56,13 +57,21 @@ export class AjaxNode extends BelNode {
|
|
|
56
57
|
// callbackEnd is relative to end
|
|
57
58
|
numeric(this.callbackDuration),
|
|
58
59
|
// not relative
|
|
59
|
-
|
|
60
|
+
addStringRaw(this.method), numeric(this.status), addString(this.domain), addString(this.path), numeric(this.txSize), numeric(this.rxSize), this.requestedWith, addStringRaw(this.nodeId), nullable(this.spanId, addStringRaw, true) + nullable(this.traceId, addStringRaw, true) + nullable(this.spanTimestamp, numeric)];
|
|
60
61
|
// Regular attributes: obfuscate only
|
|
61
62
|
const regularAttrs = addCustomAttributes({
|
|
62
|
-
[AJAX_ID]: this[AJAX_ID],
|
|
63
63
|
...(this.targetAttributes || {}),
|
|
64
64
|
...(this.gql || {})
|
|
65
|
-
},
|
|
65
|
+
}, {
|
|
66
|
+
addKey: addStringRaw,
|
|
67
|
+
addVal: addString
|
|
68
|
+
});
|
|
69
|
+
regularAttrs.push(...addCustomAttributes({
|
|
70
|
+
[AJAX_ID]: this[AJAX_ID]
|
|
71
|
+
}, {
|
|
72
|
+
addKey: addStringRaw,
|
|
73
|
+
addVal: addStringRaw
|
|
74
|
+
}));
|
|
66
75
|
|
|
67
76
|
// Payload attributes: obfuscate then truncate
|
|
68
77
|
const payloadAttrs = addCustomAttributes({
|
|
@@ -81,7 +90,10 @@ export class AjaxNode extends BelNode {
|
|
|
81
90
|
...(this.responseHeaders ? {
|
|
82
91
|
responseHeaders: this.responseHeaders
|
|
83
92
|
} : {})
|
|
84
|
-
},
|
|
93
|
+
}, {
|
|
94
|
+
addKey: addStringRaw,
|
|
95
|
+
addVal: addStringWithTruncation
|
|
96
|
+
});
|
|
85
97
|
let allAttachedNodes = [...regularAttrs, ...payloadAttrs];
|
|
86
98
|
this.children.forEach(node => allAttachedNodes.push(node.serialize())); // no children is expected under ajax nodes at this time
|
|
87
99
|
|
|
@@ -9,6 +9,7 @@ import { now } from '../../../common/timing/now';
|
|
|
9
9
|
import { cleanURL } from '../../../common/url/clean-url';
|
|
10
10
|
import { NODE_TYPE, INTERACTION_STATUS, INTERACTION_TYPE, API_TRIGGER_NAME, IPL_TRIGGER_NAME, NO_LONG_TASK_WINDOW } from '../constants';
|
|
11
11
|
import { BelNode } from './bel-node';
|
|
12
|
+
import { createStringAdders } from '../../../common/payloads/payloads';
|
|
12
13
|
|
|
13
14
|
/**
|
|
14
15
|
* link https://github.com/newrelic/nr-querypack/blob/main/schemas/bel/7.qpschema
|
|
@@ -127,7 +128,10 @@ export class Interaction extends BelNode {
|
|
|
127
128
|
*/
|
|
128
129
|
serialize(firstStartTimeOfPayload, agentRef, interactionObfuscator, ajaxObfuscator) {
|
|
129
130
|
const isFirstIxnOfPayload = firstStartTimeOfPayload === undefined;
|
|
130
|
-
const
|
|
131
|
+
const {
|
|
132
|
+
addString,
|
|
133
|
+
addStringRaw
|
|
134
|
+
} = createStringAdders(getAddStringContext, interactionObfuscator);
|
|
131
135
|
const nodeList = [];
|
|
132
136
|
let ixnType;
|
|
133
137
|
if (this.trigger === IPL_TRIGGER_NAME) ixnType = INTERACTION_TYPE.INITIAL_PAGE_LOAD;else if (this.newURL !== this.oldURL) ixnType = INTERACTION_TYPE.ROUTE_CHANGE;else ixnType = INTERACTION_TYPE.UNSPECIFIED;
|
|
@@ -143,12 +147,15 @@ export class Interaction extends BelNode {
|
|
|
143
147
|
// callbackEnd -- relative to start; not used by BrowserInteraction events so these are always 0
|
|
144
148
|
numeric(0),
|
|
145
149
|
// not relative; always 0 for BrowserInteraction
|
|
146
|
-
|
|
150
|
+
addStringRaw(this.trigger), addString(cleanURL(this.initialPageURL, true)), addString(cleanURL(this.oldURL, true)), addString(cleanURL(this.newURL, true)), addString(this.customName), ixnType, nullable(this.queueTime, numeric, true) + nullable(this.appTime, numeric, true) + nullable(this.oldRoute, addString, true) + nullable(this.newRoute, addString, true) + addStringRaw(this.id), addStringRaw(this.nodeId), nullable(this.firstPaint, numeric, true) + nullable(this.firstContentfulPaint, numeric)];
|
|
147
151
|
const customAttributes = {
|
|
148
152
|
...agentRef.info.jsAttributes,
|
|
149
153
|
...this.customAttributes
|
|
150
154
|
}; // attrs specific to this interaction should have precedence over the general custom attrs
|
|
151
|
-
const allAttachedNodes = addCustomAttributes(customAttributes || {},
|
|
155
|
+
const allAttachedNodes = addCustomAttributes(customAttributes || {}, {
|
|
156
|
+
addKey: addStringRaw,
|
|
157
|
+
addVal: addString
|
|
158
|
+
}); // start with all custom attributes
|
|
152
159
|
if (agentRef.info.atts) allAttachedNodes.push('a,' + addString(agentRef.info.atts)); // add apm provided attributes
|
|
153
160
|
/* Querypack encoder+decoder quirkiness:
|
|
154
161
|
- If first ixn node of payload is being processed, its children's start time must be offset by this node's start. (firstStartTime should be undefined.)
|
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
import { FeatureBase } from './feature-base';
|
|
6
6
|
import { drain } from '../../common/drain/drain';
|
|
7
7
|
import { FEATURE_NAMES } from '../../loaders/features/features';
|
|
8
|
-
import { Harvester } from '../../common/harvest/harvester';
|
|
9
8
|
import { EventBuffer } from './event-buffer';
|
|
10
9
|
import { handle } from '../../common/event-emitter/handle';
|
|
11
10
|
import { SUPPORTABILITY_METRIC_CHANNEL } from '../metrics/constants';
|
|
@@ -20,7 +19,6 @@ export class AggregateBase extends FeatureBase {
|
|
|
20
19
|
*/
|
|
21
20
|
constructor(agentRef, featureName) {
|
|
22
21
|
super(agentRef, featureName);
|
|
23
|
-
this.doOnceForAllAggregate(agentRef);
|
|
24
22
|
|
|
25
23
|
/** @type {Boolean} indicates if custom attributes are combined in each event payload for size estimation purposes. this is set to true in derived classes that need to evaluate custom attributes separately from the event payload */
|
|
26
24
|
this.customAttributesAreSeparate = false;
|
|
@@ -172,16 +170,6 @@ export class AggregateBase extends FeatureBase {
|
|
|
172
170
|
this.events.clearSave(this.harvestOpts);
|
|
173
171
|
}
|
|
174
172
|
|
|
175
|
-
/**
|
|
176
|
-
* These are actions related to shared resources that should be initialized once by whichever feature Aggregate subclass loads first.
|
|
177
|
-
* This method should run after checkConfiguration, which may reset the agent's info/runtime object that is used here.
|
|
178
|
-
*/
|
|
179
|
-
doOnceForAllAggregate(agentRef) {
|
|
180
|
-
// Note: obfuscator is now created per-feature for their specific event types
|
|
181
|
-
|
|
182
|
-
if (!agentRef.runtime.harvester) agentRef.runtime.harvester = new Harvester(agentRef);
|
|
183
|
-
}
|
|
184
|
-
|
|
185
173
|
/**
|
|
186
174
|
* Report a supportability metric
|
|
187
175
|
* @param {*} metricName The tag of the name matching the Angler aggregation tag
|
|
@@ -24,6 +24,7 @@ import { single } from '../../common/util/invoke';
|
|
|
24
24
|
import { SESSION_ERROR } from '../../common/constants/agent-constants';
|
|
25
25
|
import { handle } from '../../common/event-emitter/handle';
|
|
26
26
|
const checkedAgents = new WeakSet();
|
|
27
|
+
const runtimeBootstrapPromises = new WeakMap();
|
|
27
28
|
|
|
28
29
|
/**
|
|
29
30
|
* Base class for instrumenting a feature.
|
|
@@ -99,32 +100,14 @@ export class InstrumentBase extends FeatureBase {
|
|
|
99
100
|
this.loadedSuccessfully(false);
|
|
100
101
|
return;
|
|
101
102
|
}
|
|
102
|
-
let session;
|
|
103
103
|
try {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
const {
|
|
107
|
-
setupAgentSession
|
|
108
|
-
} = await import(/* webpackChunkName: "session-manager" */'./agent-session');
|
|
109
|
-
session = setupAgentSession(agentRef);
|
|
110
|
-
}
|
|
104
|
+
// in the interest of keeping loader file size small, some modules are lazy-loaded as part of the larger async chunk
|
|
105
|
+
await ensureRuntimeBootstrap(agentRef, this.ee, this.featureName);
|
|
111
106
|
} catch (e) {
|
|
112
|
-
warn(
|
|
113
|
-
this.ee.
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
if (agentRef.init.api.register.allow_iframe_bridge) {
|
|
117
|
-
try {
|
|
118
|
-
// This chunk doesn't exist in the lite build (see webpack IgnorePlugin config) since none
|
|
119
|
-
// of lite's features wire up agent.register -- guard against that rather than letting an
|
|
120
|
-
// unhandled rejection surface if this flag is ever set on a lite page.
|
|
121
|
-
const {
|
|
122
|
-
setupIframeMFEMessageListener
|
|
123
|
-
} = await import(/* webpackChunkName: "iframe-message-handler" */'../../loaders/configure/iframe-message-handler');
|
|
124
|
-
setupIframeMFEMessageListener(agentRef);
|
|
125
|
-
} catch (e) {
|
|
126
|
-
warn(23, e);
|
|
127
|
-
}
|
|
107
|
+
warn(79, e);
|
|
108
|
+
this.ee.abort(); // failed Connector or Harvester will cause entire agent to shutdown
|
|
109
|
+
this.loadedSuccessfully(false);
|
|
110
|
+
return;
|
|
128
111
|
}
|
|
129
112
|
|
|
130
113
|
/**
|
|
@@ -132,7 +115,8 @@ export class InstrumentBase extends FeatureBase {
|
|
|
132
115
|
* it's only responsible for aborting its one specific feature, rather than all.
|
|
133
116
|
*/
|
|
134
117
|
try {
|
|
135
|
-
if (!this.#shouldImportAgg(this.featureName, session, agentRef.init)) {
|
|
118
|
+
if (!this.#shouldImportAgg(this.featureName, agentRef.runtime.session, agentRef.init)) {
|
|
119
|
+
this.abortHandler?.();
|
|
136
120
|
drain(this.agentRef, this.featureName);
|
|
137
121
|
this.loadedSuccessfully(false); // aggregate module isn't loaded at all
|
|
138
122
|
return;
|
|
@@ -141,15 +125,14 @@ export class InstrumentBase extends FeatureBase {
|
|
|
141
125
|
Aggregate
|
|
142
126
|
} = await fetchAggregator();
|
|
143
127
|
this.featAggregate = new Aggregate(agentRef, argsObjFromInstrument);
|
|
144
|
-
agentRef.runtime.harvester.initializedAggregates.push(this.featAggregate); // "subscribe" the feature to future harvest intervals
|
|
128
|
+
agentRef.runtime.harvester.initializedAggregates.push(this.featAggregate); // "subscribe" the feature to future harvest intervals
|
|
145
129
|
this.loadedSuccessfully(true);
|
|
146
130
|
} catch (e) {
|
|
147
131
|
warn(34, e);
|
|
148
|
-
this.abortHandler?.();
|
|
132
|
+
this.abortHandler?.();
|
|
149
133
|
// not supported yet but nice to do: "abort" this agent's EE for this feature specifically
|
|
150
134
|
drain(this.agentRef, this.featureName, true);
|
|
151
135
|
this.loadedSuccessfully(false);
|
|
152
|
-
if (this.ee) this.ee.abort();
|
|
153
136
|
}
|
|
154
137
|
};
|
|
155
138
|
|
|
@@ -208,4 +191,64 @@ export class InstrumentBase extends FeatureBase {
|
|
|
208
191
|
}, existingAgent.runtime.loaderType);
|
|
209
192
|
}
|
|
210
193
|
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Lazily initializes the shared runtime bootstrap for a given agent exactly once. This loads session setup, Connector, and
|
|
198
|
+
* Harvester through shared async chunks and returns the same in-flight Promise to any concurrent callers.
|
|
199
|
+
*
|
|
200
|
+
* Session setup failures are reported but do not stop bootstrap. Connector or Harvester failures are allowed to bubble so the caller can abort the agent.
|
|
201
|
+
*
|
|
202
|
+
* @param {Object} agentRef - The agent reference object.
|
|
203
|
+
* @param {Object} ee - The feature event emitter used for error reporting.
|
|
204
|
+
* @param {string} featureName - The feature name used when reporting session setup errors.
|
|
205
|
+
* @returns {Promise<void>} Resolves when the shared bootstrap completes.
|
|
206
|
+
*/
|
|
207
|
+
async function ensureRuntimeBootstrap(agentRef, ee, featureName) {
|
|
208
|
+
if (runtimeBootstrapPromises.has(agentRef)) return runtimeBootstrapPromises.get(agentRef);
|
|
209
|
+
const bootstrapPromise = (async () => {
|
|
210
|
+
if (canEnableSessionTracking(agentRef.init)) {
|
|
211
|
+
try {
|
|
212
|
+
const {
|
|
213
|
+
setupAgentSession
|
|
214
|
+
} = await import(/* webpackChunkName: "session-manager" */'./agent-session');
|
|
215
|
+
setupAgentSession(agentRef); // sets agentRef.runtime.session, if successful
|
|
216
|
+
} catch (e) {
|
|
217
|
+
warn(20, e);
|
|
218
|
+
ee.emit('internal-error', [e]);
|
|
219
|
+
handle(SESSION_ERROR, [e], undefined, featureName, ee);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
if (agentRef.init.api.register.allow_iframe_bridge) {
|
|
223
|
+
try {
|
|
224
|
+
// This chunk doesn't exist in the lite build (see webpack IgnorePlugin config) since none
|
|
225
|
+
// of lite's features wire up agent.register -- guard against that rather than letting an
|
|
226
|
+
// unhandled rejection surface if this flag is ever set on a lite page.
|
|
227
|
+
const {
|
|
228
|
+
setupIframeMFEMessageListener
|
|
229
|
+
} = await import(/* webpackChunkName: "iframe-message-handler" */'../../loaders/configure/iframe-message-handler');
|
|
230
|
+
setupIframeMFEMessageListener(agentRef);
|
|
231
|
+
} catch (e) {
|
|
232
|
+
warn(23, e);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
const [{
|
|
236
|
+
Connector
|
|
237
|
+
}, {
|
|
238
|
+
Harvester
|
|
239
|
+
}] = await Promise.all([import(/* webpackChunkName: "connector" */'../../common/harvest/connector'), import(/* webpackChunkName: "harvester" */'../../common/harvest/harvester')]);
|
|
240
|
+
agentRef.runtime.connector = new Connector(agentRef);
|
|
241
|
+
agentRef.runtime.harvester = new Harvester(agentRef);
|
|
242
|
+
|
|
243
|
+
/* Wait for auto-started features' aggregates to load before starting the harvest timer, so Harvester's EOL
|
|
244
|
+
listener registers after aggregate-level listeners like web-vitals' CWV APIs. Not awaited here to avoid
|
|
245
|
+
deadlock, since every feature awaits this same bootstrap promise before its own aggregate load.
|
|
246
|
+
Only auto-started features are waited on: an autoStart:false feature only registers in drainRegistry once
|
|
247
|
+
`start` is called, so filtering on that registry excludes any feature that's never started instead of
|
|
248
|
+
blocking startTimer() forever. */
|
|
249
|
+
const autoStartedFeatures = Object.values(agentRef.features).filter(feature => agentRef.runtime.drainRegistry.has(feature.featureName));
|
|
250
|
+
Promise.all(autoStartedFeatures.map(feature => feature.onAggregateImported)).then(() => agentRef.runtime.harvester.startTimer());
|
|
251
|
+
})();
|
|
252
|
+
runtimeBootstrapPromises.set(agentRef, bootstrapPromise);
|
|
253
|
+
await bootstrapPromise;
|
|
211
254
|
}
|
|
@@ -86,9 +86,10 @@ export class Agent extends AgentBase {
|
|
|
86
86
|
try {
|
|
87
87
|
const enabledFeatures = getEnabledFeatures(this.init);
|
|
88
88
|
const featuresToStart = [...this.desiredFeatures];
|
|
89
|
+
const isRumV2Enabled = this.init.feature_flags.includes('rum_v2');
|
|
89
90
|
featuresToStart.sort((a, b) => featurePriority[a.featureName] - featurePriority[b.featureName]);
|
|
90
91
|
featuresToStart.forEach(InstrumentCtor => {
|
|
91
|
-
if (!enabledFeatures[InstrumentCtor.featureName] && InstrumentCtor.featureName !== FEATURE_NAMES.pageViewEvent) return; // PVE is required to run even if it's marked disabled
|
|
92
|
+
if (!enabledFeatures[InstrumentCtor.featureName] && (isRumV2Enabled || InstrumentCtor.featureName !== FEATURE_NAMES.pageViewEvent)) return; // PVE is required to run even if it's marked disabled unless rum_v2 is enabled
|
|
92
93
|
|
|
93
94
|
const dependencies = getFeatureDependencyNames(InstrumentCtor.featureName);
|
|
94
95
|
const missingDependencies = dependencies.filter(featName => !(featName in this.features)); // any other feature(s) this depends on should've been initialized on prior iterations by priority order
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Copyright 2020-
|
|
2
|
+
* Copyright 2020-2026 New Relic, Inc. All rights reserved.
|
|
3
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
*/
|
|
5
5
|
import { prefix, CONSENT } from './constants';
|
|
@@ -22,7 +22,7 @@ export function setupConsentAPI(agent) {
|
|
|
22
22
|
pveInst.onAggregateImported.then(loaded => {
|
|
23
23
|
const pveAgg = pveInst.featAggregate;
|
|
24
24
|
if (loaded && !pveAgg.sentRum) {
|
|
25
|
-
pveAgg.sendRum();
|
|
25
|
+
pveAgg.sendRum?.(); // only the old v1 aggregate has a sendRum method that acts as a blocker for the rest of the agent; v2 aggregate will auto report when harvester becomes unblocked
|
|
26
26
|
}
|
|
27
27
|
});
|
|
28
28
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"root":["../src/index.js","../src/cdn/experimental.js","../src/cdn/lite.js","../src/cdn/pro.js","../src/cdn/spa.js","../src/common/aggregate/aggregator.js","../src/common/aggregate/event-aggregator.js","../src/common/config/configurable.js","../src/common/config/info.js","../src/common/config/init-types.js","../src/common/config/init.js","../src/common/config/loader-config.js","../src/common/config/runtime.js","../src/common/constants/agent-constants.js","../src/common/constants/env.cdn.js","../src/common/constants/env.js","../src/common/constants/env.npm.js","../src/common/constants/events.js","../src/common/constants/iframe-constants.js","../src/common/constants/runtime.js","../src/common/constants/shared-channel.js","../src/common/deny-list/deny-list.js","../src/common/dispatch/global-event.js","../src/common/dom/iframe.js","../src/common/dom/query-selector.js","../src/common/dom/selector-path.js","../src/common/drain/drain.js","../src/common/event-emitter/contextual-ee.js","../src/common/event-emitter/event-context.js","../src/common/event-emitter/handle.js","../src/common/event-emitter/register-handler.js","../src/common/event-listener/event-listener-opts.js","../src/common/harvest/harvester.js","../src/common/harvest/send.js","../src/common/harvest/types.js","../src/common/ids/bundle-id.js","../src/common/ids/id.js","../src/common/ids/unique-id.js","../src/common/payloads/payloads.js","../src/common/serialize/bel-serializer.js","../src/common/session/constants.js","../src/common/session/session-entity.js","../src/common/session/session-key.js","../src/common/storage/local-storage.js","../src/common/timer/interaction-timer.js","../src/common/timer/timer.js","../src/common/timing/nav-timing.js","../src/common/timing/now.js","../src/common/timing/time-keeper.js","../src/common/unload/eol.js","../src/common/url/add-url.js","../src/common/url/canonicalize-url.js","../src/common/url/clean-url.js","../src/common/url/encode.js","../src/common/url/extract-url.js","../src/common/url/location.js","../src/common/url/parse-url.js","../src/common/url/protocol.js","../src/common/util/attribute-size.js","../src/common/util/browser-stack-matchers.js","../src/common/util/console.js","../src/common/util/data-size.js","../src/common/util/event-origin.js","../src/common/util/feature-flags.js","../src/common/util/get-or-set.js","../src/common/util/invoke.js","../src/common/util/monkey-patched.js","../src/common/util/obfuscate.js","../src/common/util/short-circuit.js","../src/common/util/stringify.js","../src/common/util/submit-data.js","../src/common/util/text.js","../src/common/util/traverse.js","../src/common/util/type-check.js","../src/common/util/webdriver-detection.js","../src/common/v2/mfe-vitals.js","../src/common/v2/script-correlation.js","../src/common/v2/script-tracker-constants.js","../src/common/v2/script-tracker.js","../src/common/v2/timing-factory.js","../src/common/v2/utils.js","../src/common/vitals/constants.js","../src/common/vitals/cumulative-layout-shift.js","../src/common/vitals/first-contentful-paint.js","../src/common/vitals/first-paint.js","../src/common/vitals/interaction-to-next-paint.js","../src/common/vitals/largest-contentful-paint.js","../src/common/vitals/load-time.js","../src/common/vitals/time-to-first-byte.js","../src/common/vitals/vital-metric.js","../src/common/window/load.js","../src/common/window/nreum.js","../src/common/window/page-visibility.js","../src/common/wrap/wrap-events.js","../src/common/wrap/wrap-fetch.js","../src/common/wrap/wrap-function.js","../src/common/wrap/wrap-history.js","../src/common/wrap/wrap-logger.js","../src/common/wrap/wrap-websocket.js","../src/common/wrap/wrap-xhr.js","../src/features/ajax/constants.js","../src/features/ajax/index.js","../src/features/ajax/aggregate/gql.js","../src/features/ajax/aggregate/index.js","../src/features/ajax/instrument/distributed-tracing.js","../src/features/ajax/instrument/index.js","../src/features/ajax/instrument/response-size.js","../src/features/generic_events/constants.js","../src/features/generic_events/index.js","../src/features/generic_events/aggregate/index.js","../src/features/generic_events/aggregate/user-actions/aggregated-user-action.js","../src/features/generic_events/aggregate/user-actions/user-actions-aggregator.js","../src/features/generic_events/instrument/index.js","../src/features/jserrors/constants.js","../src/features/jserrors/index.js","../src/features/jserrors/aggregate/canonical-function-name.js","../src/features/jserrors/aggregate/cause-string.js","../src/features/jserrors/aggregate/compute-stack-trace.js","../src/features/jserrors/aggregate/format-stack-trace.js","../src/features/jserrors/aggregate/index.js","../src/features/jserrors/aggregate/internal-errors.js","../src/features/jserrors/aggregate/string-hash-code.js","../src/features/jserrors/instrument/index.js","../src/features/jserrors/shared/cast-error.js","../src/features/jserrors/shared/uncaught-error.js","../src/features/logging/constants.js","../src/features/logging/index.js","../src/features/logging/aggregate/index.js","../src/features/logging/instrument/index.js","../src/features/logging/shared/log.js","../src/features/logging/shared/utils.js","../src/features/metrics/constants.js","../src/features/metrics/index.js","../src/features/metrics/aggregate/framework-detection.js","../src/features/metrics/aggregate/harvest-metadata.js","../src/features/metrics/aggregate/index.js","../src/features/metrics/instrument/index.js","../src/features/page_action/constants.js","../src/features/page_action/index.js","../src/features/page_action/instrument/index.js","../src/features/page_view_event/constants.js","../src/features/page_view_event/index.js","../src/features/page_view_event/aggregate/index.js","../src/features/page_view_event/aggregate/initialized-features.js","../src/features/page_view_event/instrument/index.js","../src/features/page_view_timing/constants.js","../src/features/page_view_timing/index.js","../src/features/page_view_timing/aggregate/index.js","../src/features/page_view_timing/instrument/index.js","../src/features/session_replay/constants.js","../src/features/session_replay/index.js","../src/features/session_replay/aggregate/index.js","../src/features/session_replay/instrument/index.js","../src/features/session_replay/shared/recorder-events.js","../src/features/session_replay/shared/recorder.js","../src/features/session_replay/shared/stylesheet-evaluator.js","../src/features/session_replay/shared/utils.js","../src/features/session_trace/constants.js","../src/features/session_trace/index.js","../src/features/session_trace/aggregate/index.js","../src/features/session_trace/aggregate/trace/node.js","../src/features/session_trace/aggregate/trace/storage.js","../src/features/session_trace/aggregate/trace/utils.js","../src/features/session_trace/instrument/index.js","../src/features/soft_navigations/constants.js","../src/features/soft_navigations/index.js","../src/features/soft_navigations/aggregate/ajax-node.js","../src/features/soft_navigations/aggregate/bel-node.js","../src/features/soft_navigations/aggregate/index.js","../src/features/soft_navigations/aggregate/initial-page-load-interaction.js","../src/features/soft_navigations/aggregate/interaction.js","../src/features/soft_navigations/instrument/index.js","../src/features/utils/agent-session.js","../src/features/utils/aggregate-base.js","../src/features/utils/event-buffer.js","../src/features/utils/feature-base.js","../src/features/utils/feature-gates.js","../src/features/utils/instrument-base.js","../src/interfaces/registered-entity.js","../src/interfaces/registered-iframe-entity.js","../src/loaders/agent-base.js","../src/loaders/agent.js","../src/loaders/api-base.js","../src/loaders/browser-agent.js","../src/loaders/micro-agent-base.js","../src/loaders/micro-agent.js","../src/loaders/api/addPageAction.js","../src/loaders/api/addRelease.js","../src/loaders/api/addToTrace.js","../src/loaders/api/consent.js","../src/loaders/api/constants.js","../src/loaders/api/finished.js","../src/loaders/api/interaction-types.js","../src/loaders/api/interaction.js","../src/loaders/api/log.js","../src/loaders/api/measure.js","../src/loaders/api/noticeError.js","../src/loaders/api/pauseReplay.js","../src/loaders/api/recordCustomEvent.js","../src/loaders/api/recordReplay.js","../src/loaders/api/register-api-types.js","../src/loaders/api/register.js","../src/loaders/api/setApplicationVersion.js","../src/loaders/api/setCustomAttribute.js","../src/loaders/api/setErrorHandler.js","../src/loaders/api/setPageViewName.js","../src/loaders/api/setUserId.js","../src/loaders/api/sharedHandlers.js","../src/loaders/api/start.js","../src/loaders/api/topLevelCallers.js","../src/loaders/api/wrapLogger.js","../src/loaders/configure/configure.js","../src/loaders/configure/iframe-message-handler.js","../src/loaders/configure/nonce.js","../src/loaders/configure/public-path.js","../src/loaders/features/enabled-features.js","../src/loaders/features/featureDependencies.js","../src/loaders/features/features.js"],"version":"5.9.3"}
|
|
1
|
+
{"root":["../src/index.js","../src/cdn/experimental.js","../src/cdn/lite.js","../src/cdn/pro.js","../src/cdn/spa.js","../src/common/aggregate/aggregator.js","../src/common/aggregate/event-aggregator.js","../src/common/config/configurable.js","../src/common/config/info.js","../src/common/config/init-types.js","../src/common/config/init.js","../src/common/config/loader-config.js","../src/common/config/runtime.js","../src/common/constants/agent-constants.js","../src/common/constants/env.cdn.js","../src/common/constants/env.js","../src/common/constants/env.npm.js","../src/common/constants/events.js","../src/common/constants/iframe-constants.js","../src/common/constants/runtime.js","../src/common/constants/shared-channel.js","../src/common/deny-list/deny-list.js","../src/common/dispatch/global-event.js","../src/common/dom/iframe.js","../src/common/dom/query-selector.js","../src/common/dom/selector-path.js","../src/common/drain/drain.js","../src/common/event-emitter/contextual-ee.js","../src/common/event-emitter/event-context.js","../src/common/event-emitter/handle.js","../src/common/event-emitter/register-handler.js","../src/common/event-listener/event-listener-opts.js","../src/common/harvest/connector.js","../src/common/harvest/harvester.js","../src/common/harvest/send.js","../src/common/harvest/types.js","../src/common/ids/bundle-id.js","../src/common/ids/id.js","../src/common/ids/unique-id.js","../src/common/payloads/payloads.js","../src/common/serialize/bel-serializer.js","../src/common/session/constants.js","../src/common/session/session-entity.js","../src/common/session/session-key.js","../src/common/storage/local-storage.js","../src/common/timer/interaction-timer.js","../src/common/timer/timer.js","../src/common/timing/nav-timing.js","../src/common/timing/now.js","../src/common/timing/time-keeper.js","../src/common/unload/eol.js","../src/common/url/add-url.js","../src/common/url/canonicalize-url.js","../src/common/url/clean-url.js","../src/common/url/encode.js","../src/common/url/extract-url.js","../src/common/url/location.js","../src/common/url/parse-url.js","../src/common/url/protocol.js","../src/common/util/attribute-size.js","../src/common/util/browser-stack-matchers.js","../src/common/util/console.js","../src/common/util/data-size.js","../src/common/util/event-origin.js","../src/common/util/feature-flags.js","../src/common/util/get-or-set.js","../src/common/util/invoke.js","../src/common/util/monkey-patched.js","../src/common/util/obfuscate.js","../src/common/util/short-circuit.js","../src/common/util/stringify.js","../src/common/util/submit-data.js","../src/common/util/text.js","../src/common/util/traverse.js","../src/common/util/type-check.js","../src/common/util/webdriver-detection.js","../src/common/v2/mfe-vitals.js","../src/common/v2/script-correlation.js","../src/common/v2/script-tracker-constants.js","../src/common/v2/script-tracker.js","../src/common/v2/timing-factory.js","../src/common/v2/utils.js","../src/common/vitals/constants.js","../src/common/vitals/cumulative-layout-shift.js","../src/common/vitals/first-contentful-paint.js","../src/common/vitals/first-paint.js","../src/common/vitals/interaction-to-next-paint.js","../src/common/vitals/largest-contentful-paint.js","../src/common/vitals/load-time.js","../src/common/vitals/time-to-first-byte.js","../src/common/vitals/vital-metric.js","../src/common/window/load.js","../src/common/window/nreum.js","../src/common/window/page-visibility.js","../src/common/wrap/wrap-events.js","../src/common/wrap/wrap-fetch.js","../src/common/wrap/wrap-function.js","../src/common/wrap/wrap-history.js","../src/common/wrap/wrap-logger.js","../src/common/wrap/wrap-websocket.js","../src/common/wrap/wrap-xhr.js","../src/features/ajax/constants.js","../src/features/ajax/index.js","../src/features/ajax/aggregate/gql.js","../src/features/ajax/aggregate/index.js","../src/features/ajax/instrument/distributed-tracing.js","../src/features/ajax/instrument/index.js","../src/features/ajax/instrument/response-size.js","../src/features/generic_events/constants.js","../src/features/generic_events/index.js","../src/features/generic_events/aggregate/index.js","../src/features/generic_events/aggregate/user-actions/aggregated-user-action.js","../src/features/generic_events/aggregate/user-actions/user-actions-aggregator.js","../src/features/generic_events/instrument/index.js","../src/features/jserrors/constants.js","../src/features/jserrors/index.js","../src/features/jserrors/aggregate/canonical-function-name.js","../src/features/jserrors/aggregate/cause-string.js","../src/features/jserrors/aggregate/compute-stack-trace.js","../src/features/jserrors/aggregate/format-stack-trace.js","../src/features/jserrors/aggregate/index.js","../src/features/jserrors/aggregate/internal-errors.js","../src/features/jserrors/aggregate/string-hash-code.js","../src/features/jserrors/instrument/index.js","../src/features/jserrors/shared/cast-error.js","../src/features/jserrors/shared/uncaught-error.js","../src/features/logging/constants.js","../src/features/logging/index.js","../src/features/logging/aggregate/index.js","../src/features/logging/instrument/index.js","../src/features/logging/shared/log.js","../src/features/logging/shared/utils.js","../src/features/metrics/constants.js","../src/features/metrics/index.js","../src/features/metrics/aggregate/framework-detection.js","../src/features/metrics/aggregate/harvest-metadata.js","../src/features/metrics/aggregate/index.js","../src/features/metrics/instrument/index.js","../src/features/page_action/constants.js","../src/features/page_action/index.js","../src/features/page_action/instrument/index.js","../src/features/page_view_event/constants.js","../src/features/page_view_event/index.js","../src/features/page_view_event/aggregate/index.js","../src/features/page_view_event/aggregate/initialized-features.js","../src/features/page_view_event/aggregate_v2/index.js","../src/features/page_view_event/instrument/index.js","../src/features/page_view_timing/constants.js","../src/features/page_view_timing/index.js","../src/features/page_view_timing/aggregate/index.js","../src/features/page_view_timing/instrument/index.js","../src/features/session_replay/constants.js","../src/features/session_replay/index.js","../src/features/session_replay/aggregate/index.js","../src/features/session_replay/instrument/index.js","../src/features/session_replay/shared/recorder-events.js","../src/features/session_replay/shared/recorder.js","../src/features/session_replay/shared/stylesheet-evaluator.js","../src/features/session_replay/shared/utils.js","../src/features/session_trace/constants.js","../src/features/session_trace/index.js","../src/features/session_trace/aggregate/index.js","../src/features/session_trace/aggregate/trace/node.js","../src/features/session_trace/aggregate/trace/storage.js","../src/features/session_trace/aggregate/trace/utils.js","../src/features/session_trace/instrument/index.js","../src/features/soft_navigations/constants.js","../src/features/soft_navigations/index.js","../src/features/soft_navigations/aggregate/ajax-node.js","../src/features/soft_navigations/aggregate/bel-node.js","../src/features/soft_navigations/aggregate/index.js","../src/features/soft_navigations/aggregate/initial-page-load-interaction.js","../src/features/soft_navigations/aggregate/interaction.js","../src/features/soft_navigations/instrument/index.js","../src/features/utils/agent-session.js","../src/features/utils/aggregate-base.js","../src/features/utils/event-buffer.js","../src/features/utils/feature-base.js","../src/features/utils/feature-gates.js","../src/features/utils/instrument-base.js","../src/interfaces/registered-entity.js","../src/interfaces/registered-iframe-entity.js","../src/loaders/agent-base.js","../src/loaders/agent.js","../src/loaders/api-base.js","../src/loaders/browser-agent.js","../src/loaders/micro-agent-base.js","../src/loaders/micro-agent.js","../src/loaders/api/addPageAction.js","../src/loaders/api/addRelease.js","../src/loaders/api/addToTrace.js","../src/loaders/api/consent.js","../src/loaders/api/constants.js","../src/loaders/api/finished.js","../src/loaders/api/interaction-types.js","../src/loaders/api/interaction.js","../src/loaders/api/log.js","../src/loaders/api/measure.js","../src/loaders/api/noticeError.js","../src/loaders/api/pauseReplay.js","../src/loaders/api/recordCustomEvent.js","../src/loaders/api/recordReplay.js","../src/loaders/api/register-api-types.js","../src/loaders/api/register.js","../src/loaders/api/setApplicationVersion.js","../src/loaders/api/setCustomAttribute.js","../src/loaders/api/setErrorHandler.js","../src/loaders/api/setPageViewName.js","../src/loaders/api/setUserId.js","../src/loaders/api/sharedHandlers.js","../src/loaders/api/start.js","../src/loaders/api/topLevelCallers.js","../src/loaders/api/wrapLogger.js","../src/loaders/configure/configure.js","../src/loaders/configure/iframe-message-handler.js","../src/loaders/configure/nonce.js","../src/loaders/configure/public-path.js","../src/loaders/features/enabled-features.js","../src/loaders/features/featureDependencies.js","../src/loaders/features/features.js"],"version":"5.9.3"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../../../src/common/config/runtime.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../../../src/common/config/runtime.js"],"names":[],"mappings":"AA8DO,gDAON"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connector.d.ts","sourceRoot":"","sources":["../../../../src/common/harvest/connector.js"],"names":[],"mappings":"AAmBA;IAKE,2BAeC;IAED,+CAiBC;;CA6GF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"harvester.d.ts","sourceRoot":"","sources":["../../../../src/common/harvest/harvester.js"],"names":[],"mappings":"AAiBA;IAIE,
|
|
1
|
+
{"version":3,"file":"harvester.d.ts","sourceRoot":"","sources":["../../../../src/common/harvest/harvester.js"],"names":[],"mappings":"AAiBA;IAIE,2BAKC;IAPD,6BAA0B;IAGxB,cAAwB;IAGxB,uBAA0C;IAG5C,wCAgBC;IAED;;;;;OAKG;IACH,iCAJW,MAAM,cACN,MAAM,GACJ,OAAO,CA+CnB;;CACF;2BAxF0B,mBAAmB"}
|