@newrelic/browser-agent 1.255.0 → 1.256.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 +15 -0
- package/dist/cjs/common/constants/env.cdn.js +2 -2
- package/dist/cjs/common/constants/env.npm.js +2 -2
- package/dist/cjs/common/constants/runtime.js +1 -1
- package/dist/cjs/common/harvest/harvest.js +1 -0
- package/dist/cjs/common/session/session-entity.js +2 -1
- package/dist/cjs/common/timer/interaction-timer.js +16 -2
- package/dist/cjs/common/timing/time-keeper.js +1 -2
- package/dist/cjs/features/jserrors/aggregate/index.js +16 -6
- package/dist/cjs/features/jserrors/instrument/index.js +8 -3
- package/dist/cjs/features/session_replay/aggregate/index.js +48 -29
- package/dist/cjs/features/session_replay/constants.js +2 -1
- package/dist/cjs/features/session_replay/instrument/index.js +9 -2
- package/dist/cjs/features/session_replay/shared/recorder-events.js +1 -9
- package/dist/cjs/features/session_replay/shared/recorder.js +22 -50
- package/dist/cjs/features/session_replay/shared/utils.js +12 -0
- package/dist/cjs/features/session_trace/aggregate/index.js +19 -22
- package/dist/cjs/loaders/api/api.js +7 -1
- package/dist/cjs/loaders/configure/configure.js +1 -0
- package/dist/esm/common/constants/env.cdn.js +2 -2
- package/dist/esm/common/constants/env.npm.js +2 -2
- package/dist/esm/common/constants/runtime.js +1 -1
- package/dist/esm/common/harvest/harvest.js +1 -0
- package/dist/esm/common/session/session-entity.js +2 -1
- package/dist/esm/common/timer/interaction-timer.js +16 -2
- package/dist/esm/common/timing/time-keeper.js +1 -3
- package/dist/esm/features/jserrors/aggregate/index.js +16 -6
- package/dist/esm/features/jserrors/instrument/index.js +8 -3
- package/dist/esm/features/session_replay/aggregate/index.js +48 -29
- package/dist/esm/features/session_replay/constants.js +2 -1
- package/dist/esm/features/session_replay/instrument/index.js +9 -2
- package/dist/esm/features/session_replay/shared/recorder-events.js +1 -9
- package/dist/esm/features/session_replay/shared/recorder.js +23 -51
- package/dist/esm/features/session_replay/shared/utils.js +11 -0
- package/dist/esm/features/session_trace/aggregate/index.js +19 -22
- package/dist/esm/loaders/api/api.js +7 -1
- package/dist/esm/loaders/configure/configure.js +1 -0
- package/dist/types/common/constants/runtime.d.ts.map +1 -1
- package/dist/types/common/session/session-entity.d.ts.map +1 -1
- package/dist/types/common/timer/interaction-timer.d.ts +2 -0
- package/dist/types/common/timer/interaction-timer.d.ts.map +1 -1
- package/dist/types/common/timing/time-keeper.d.ts.map +1 -1
- package/dist/types/features/jserrors/aggregate/index.d.ts +2 -1
- package/dist/types/features/jserrors/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/jserrors/instrument/index.d.ts.map +1 -1
- package/dist/types/features/session_replay/aggregate/index.d.ts +5 -2
- package/dist/types/features/session_replay/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/session_replay/constants.d.ts +1 -0
- package/dist/types/features/session_replay/constants.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-events.d.ts +0 -8
- package/dist/types/features/session_replay/shared/recorder-events.d.ts.map +1 -1
- package/dist/types/features/session_replay/shared/recorder.d.ts +1 -17
- package/dist/types/features/session_replay/shared/recorder.d.ts.map +1 -1
- package/dist/types/features/session_replay/shared/utils.d.ts +8 -0
- package/dist/types/features/session_replay/shared/utils.d.ts.map +1 -1
- package/dist/types/features/session_trace/aggregate/index.d.ts +2 -1
- package/dist/types/features/session_trace/aggregate/index.d.ts.map +1 -1
- package/dist/types/loaders/api/api.d.ts.map +1 -1
- package/dist/types/loaders/configure/configure.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/common/constants/runtime.js +1 -1
- package/src/common/harvest/harvest.js +1 -1
- package/src/common/session/session-entity.js +2 -1
- package/src/common/timer/interaction-timer.js +17 -2
- package/src/common/timing/time-keeper.js +1 -3
- package/src/features/jserrors/aggregate/index.js +15 -6
- package/src/features/jserrors/instrument/index.js +9 -4
- package/src/features/session_replay/aggregate/index.js +43 -25
- package/src/features/session_replay/constants.js +2 -1
- package/src/features/session_replay/instrument/index.js +7 -2
- package/src/features/session_replay/shared/recorder-events.js +1 -6
- package/src/features/session_replay/shared/recorder.js +21 -27
- package/src/features/session_replay/shared/utils.js +12 -0
- package/src/features/session_trace/aggregate/index.js +18 -16
- package/src/loaders/api/api.js +10 -1
- package/src/loaders/configure/configure.js +1 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { record as recorder } from 'rrweb';
|
|
2
2
|
import { stringify } from '../../../common/util/stringify';
|
|
3
|
-
import { AVG_COMPRESSION, CHECKOUT_MS, IDEAL_PAYLOAD_SIZE, QUERY_PARAM_PADDING, RRWEB_EVENT_TYPES } from '../constants';
|
|
3
|
+
import { AVG_COMPRESSION, CHECKOUT_MS, IDEAL_PAYLOAD_SIZE, QUERY_PARAM_PADDING, RRWEB_EVENT_TYPES, SR_EVENT_EMITTER_TYPES } from '../constants';
|
|
4
4
|
import { getConfigurationValue } from '../../../common/config/config';
|
|
5
5
|
import { RecorderEvents } from './recorder-events';
|
|
6
6
|
import { MODE } from '../../../common/session/constants';
|
|
@@ -8,6 +8,7 @@ import { stylesheetEvaluator } from './stylesheet-evaluator';
|
|
|
8
8
|
import { handle } from '../../../common/event-emitter/handle';
|
|
9
9
|
import { SUPPORTABILITY_METRIC_CHANNEL } from '../../metrics/constants';
|
|
10
10
|
import { FEATURE_NAMES } from '../../../loaders/features/features';
|
|
11
|
+
import { buildNRMetaNode } from './utils';
|
|
11
12
|
export class Recorder {
|
|
12
13
|
/** Each page mutation or event will be stored (raw) in this array. This array will be cleared on each harvest */
|
|
13
14
|
#events;
|
|
@@ -18,15 +19,9 @@ export class Recorder {
|
|
|
18
19
|
/** flag that if true, blocks events from being "stored". Only set to true when a full snapshot has incomplete nodes (only stylesheets ATM) */
|
|
19
20
|
#fixing = false;
|
|
20
21
|
constructor(parent) {
|
|
21
|
-
this.#events = new RecorderEvents(
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
this.#backloggedEvents = new RecorderEvents({
|
|
25
|
-
canCorrectTimestamps: !!parent.timeKeeper?.ready
|
|
26
|
-
});
|
|
27
|
-
this.#preloaded = [new RecorderEvents({
|
|
28
|
-
canCorrectTimestamps: !!parent.timeKeeper?.ready
|
|
29
|
-
})];
|
|
22
|
+
this.#events = new RecorderEvents();
|
|
23
|
+
this.#backloggedEvents = new RecorderEvents();
|
|
24
|
+
this.#preloaded = [new RecorderEvents()];
|
|
30
25
|
/** True when actively recording, false when paused or stopped */
|
|
31
26
|
this.recording = false;
|
|
32
27
|
/** The pointer to the current bucket holding rrweb events */
|
|
@@ -43,18 +38,12 @@ export class Recorder {
|
|
|
43
38
|
this.stopRecording = () => {/* no-op until set by rrweb initializer */};
|
|
44
39
|
}
|
|
45
40
|
getEvents() {
|
|
46
|
-
if (this.#preloaded[0]?.events.length) {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
events: preloadedEvents,
|
|
51
|
-
type: 'preloaded'
|
|
52
|
-
};
|
|
53
|
-
}
|
|
54
|
-
const backloggedEvents = this.returnCorrectTimestamps(this.#backloggedEvents);
|
|
55
|
-
const events = this.returnCorrectTimestamps(this.#events);
|
|
41
|
+
if (this.#preloaded[0]?.events.length) return {
|
|
42
|
+
...this.#preloaded[0],
|
|
43
|
+
type: 'preloaded'
|
|
44
|
+
};
|
|
56
45
|
return {
|
|
57
|
-
events: [...backloggedEvents, ...events].filter(x => x),
|
|
46
|
+
events: [...this.#backloggedEvents.events, ...this.#events.events].filter(x => x),
|
|
58
47
|
type: 'standard',
|
|
59
48
|
cycleTimestamp: Math.min(this.#backloggedEvents.cycleTimestamp, this.#events.cycleTimestamp),
|
|
60
49
|
payloadBytesEstimation: this.#backloggedEvents.payloadBytesEstimation + this.#events.payloadBytesEstimation,
|
|
@@ -65,34 +54,10 @@ export class Recorder {
|
|
|
65
54
|
};
|
|
66
55
|
}
|
|
67
56
|
|
|
68
|
-
/**
|
|
69
|
-
* Returns time-corrected events. If the events were correctable from the beginning, this correction will have already been applied.
|
|
70
|
-
* @param {SessionReplayEvent[]} events The array of buffered SR nodes
|
|
71
|
-
* @returns {CorrectedSessionReplayEvent[]}
|
|
72
|
-
*/
|
|
73
|
-
returnCorrectTimestamps(events) {
|
|
74
|
-
if (!this.parent.timeKeeper?.ready) return events.events;
|
|
75
|
-
return events.canCorrectTimestamps ? events.events : events.events.map(_ref => {
|
|
76
|
-
let {
|
|
77
|
-
__serialized,
|
|
78
|
-
timestamp,
|
|
79
|
-
...e
|
|
80
|
-
} = _ref;
|
|
81
|
-
return {
|
|
82
|
-
timestamp: this.parent.timeKeeper.correctAbsoluteTimestamp(timestamp),
|
|
83
|
-
...e
|
|
84
|
-
};
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
|
|
88
57
|
/** Clears the buffer (this.#events), and resets all payload metadata properties */
|
|
89
58
|
clearBuffer() {
|
|
90
|
-
if (this.#preloaded[0]?.events.length) this.#preloaded.shift();else if (this.parent.mode === MODE.ERROR) this.#backloggedEvents = this.#events;else this.#backloggedEvents = new RecorderEvents(
|
|
91
|
-
|
|
92
|
-
});
|
|
93
|
-
this.#events = new RecorderEvents({
|
|
94
|
-
canCorrectTimestamps: !!this.parent.timeKeeper?.ready
|
|
95
|
-
});
|
|
59
|
+
if (this.#preloaded[0]?.events.length) this.#preloaded.shift();else if (this.parent.mode === MODE.ERROR) this.#backloggedEvents = this.#events;else this.#backloggedEvents = new RecorderEvents();
|
|
60
|
+
this.#events = new RecorderEvents();
|
|
96
61
|
}
|
|
97
62
|
|
|
98
63
|
/** Begin recording using configured recording lib */
|
|
@@ -110,6 +75,10 @@ export class Recorder {
|
|
|
110
75
|
inline_images,
|
|
111
76
|
collect_fonts
|
|
112
77
|
} = getConfigurationValue(this.parent.agentIdentifier, 'session_replay');
|
|
78
|
+
const customMasker = (text, element) => {
|
|
79
|
+
if (element?.type?.toLowerCase() !== 'password' && (element?.dataset.nrUnmask !== undefined || element?.classList.contains('nr-unmask'))) return text;
|
|
80
|
+
return '*'.repeat(text.length);
|
|
81
|
+
};
|
|
113
82
|
// set up rrweb configurations for maximum privacy --
|
|
114
83
|
// https://newrelic.atlassian.net/wiki/spaces/O11Y/pages/2792293280/2023+02+28+Browser+-+Session+Replay#Configuration-options
|
|
115
84
|
const stop = recorder({
|
|
@@ -120,14 +89,18 @@ export class Recorder {
|
|
|
120
89
|
blockSelector: block_selector,
|
|
121
90
|
maskInputOptions: mask_input_options,
|
|
122
91
|
maskTextSelector: mask_text_selector,
|
|
92
|
+
maskTextFn: customMasker,
|
|
123
93
|
maskAllInputs: mask_all_inputs,
|
|
94
|
+
maskInputFn: customMasker,
|
|
124
95
|
inlineStylesheet: inline_stylesheet,
|
|
125
96
|
inlineImages: inline_images,
|
|
126
97
|
collectFonts: collect_fonts,
|
|
127
98
|
checkoutEveryNms: CHECKOUT_MS[this.parent.mode]
|
|
128
99
|
});
|
|
100
|
+
this.parent.ee.emit(SR_EVENT_EMITTER_TYPES.REPLAY_RUNNING, [true, this.parent.mode]);
|
|
129
101
|
this.stopRecording = () => {
|
|
130
102
|
this.recording = false;
|
|
103
|
+
this.parent.ee.emit(SR_EVENT_EMITTER_TYPES.REPLAY_RUNNING, [false, this.parent.mode]);
|
|
131
104
|
stop();
|
|
132
105
|
};
|
|
133
106
|
}
|
|
@@ -171,7 +144,8 @@ export class Recorder {
|
|
|
171
144
|
if (!event) return;
|
|
172
145
|
if (!this.parent.scheduler && this.#preloaded.length) this.currentBufferTarget = this.#preloaded[this.#preloaded.length - 1];else this.currentBufferTarget = this.#events;
|
|
173
146
|
if (this.parent.blocked) return;
|
|
174
|
-
if (this.
|
|
147
|
+
if (this.parent.timeKeeper?.ready && !event.__newrelic) {
|
|
148
|
+
event.__newrelic = buildNRMetaNode(event.timestamp, this.parent.timeKeeper);
|
|
175
149
|
event.timestamp = this.parent.timeKeeper.correctAbsoluteTimestamp(event.timestamp);
|
|
176
150
|
}
|
|
177
151
|
event.__serialized = stringify(event);
|
|
@@ -206,9 +180,7 @@ export class Recorder {
|
|
|
206
180
|
this.parent.scheduler.runHarvest();
|
|
207
181
|
} else {
|
|
208
182
|
// we are still in "preload" and it triggered a "stop point". Make a new set, which will get pointed at on next cycle
|
|
209
|
-
this.#preloaded.push(new RecorderEvents(
|
|
210
|
-
canCorrectTimestamps: !!this.parent.timeKeeper?.ready
|
|
211
|
-
}));
|
|
183
|
+
this.#preloaded.push(new RecorderEvents());
|
|
212
184
|
}
|
|
213
185
|
}
|
|
214
186
|
}
|
|
@@ -14,4 +14,15 @@ export function isPreloadAllowed(agentId) {
|
|
|
14
14
|
export function canImportReplayAgg(agentId, sessionMgr) {
|
|
15
15
|
if (!hasReplayPrerequisite(agentId)) return false;
|
|
16
16
|
return !!sessionMgr?.isNew || !!sessionMgr?.state.sessionReplayMode; // Session Replay should only try to run if already running from a previous page, or at the beginning of a session
|
|
17
|
+
}
|
|
18
|
+
export function buildNRMetaNode(timestamp, timeKeeper) {
|
|
19
|
+
const correctedTimestamp = timeKeeper.correctAbsoluteTimestamp(timestamp);
|
|
20
|
+
return {
|
|
21
|
+
originalTimestamp: timestamp,
|
|
22
|
+
correctedTimestamp,
|
|
23
|
+
timestampDiff: timestamp - correctedTimestamp,
|
|
24
|
+
timeKeeperOriginTime: timeKeeper.originTime,
|
|
25
|
+
timeKeeperCorrectedOriginTime: timeKeeper.correctedOriginTime,
|
|
26
|
+
timeKeeperDiff: Math.floor(timeKeeper.originTime - timeKeeper.correctedOriginTime)
|
|
27
|
+
};
|
|
17
28
|
}
|
|
@@ -50,10 +50,11 @@ export class Aggregate extends AggregateBase {
|
|
|
50
50
|
// Very unlikely, but in case the existing XMLHttpRequest.prototype object on the page couldn't be wrapped.
|
|
51
51
|
if (!this.agentRuntime.xhrWrappable) return;
|
|
52
52
|
this.resourceObserver = argsObj?.resourceObserver; // undefined if observer couldn't be created
|
|
53
|
-
this.ptid =
|
|
53
|
+
this.ptid = this.agentRuntime.ptid;
|
|
54
54
|
this.trace = {};
|
|
55
55
|
this.nodeCount = 0;
|
|
56
56
|
this.sentTrace = null;
|
|
57
|
+
this.everSent = false;
|
|
57
58
|
this.harvestTimeSeconds = getConfigurationValue(agentIdentifier, 'session_trace.harvestTimeSeconds') || 10;
|
|
58
59
|
this.maxNodesPerHarvest = getConfigurationValue(agentIdentifier, 'session_trace.maxNodesPerHarvest') || 1000;
|
|
59
60
|
/**
|
|
@@ -105,9 +106,7 @@ export class Aggregate extends AggregateBase {
|
|
|
105
106
|
this.isStandalone = false;
|
|
106
107
|
if (prevMode === MODE.ERROR && this.#scheduler) {
|
|
107
108
|
this.trimSTNs(ERROR_MODE_SECONDS_WINDOW); // up until now, Trace would've been just buffering nodes up to max, which needs to be trimmed to last X seconds
|
|
108
|
-
this.#scheduler.runHarvest({
|
|
109
|
-
needResponse: true
|
|
110
|
-
});
|
|
109
|
+
this.#scheduler.runHarvest({});
|
|
111
110
|
} else {
|
|
112
111
|
controlTraceOp(MODE.FULL);
|
|
113
112
|
}
|
|
@@ -130,7 +129,7 @@ export class Aggregate extends AggregateBase {
|
|
|
130
129
|
sessionTraceMode: MODE.OFF
|
|
131
130
|
});
|
|
132
131
|
operationalGate.permanentlyDecide(false);
|
|
133
|
-
if (mostRecentModeKnown === MODE.FULL) this.#scheduler?.runHarvest(); // allow queued nodes (past opGate) to final harvest, unless they were buffered in other modes
|
|
132
|
+
if (mostRecentModeKnown === MODE.FULL) this.#scheduler?.runHarvest({}); // allow queued nodes (past opGate) to final harvest, unless they were buffered in other modes
|
|
134
133
|
this.#scheduler?.stopTimer(true); // the 'true' arg here will forcibly block any future call to runHarvest, so the last runHarvest above must be prior
|
|
135
134
|
this.#scheduler = null;
|
|
136
135
|
};
|
|
@@ -149,9 +148,7 @@ export class Aggregate extends AggregateBase {
|
|
|
149
148
|
- if trace switches to Full mode, harvest should start (prev: Error) if not already running (prev: Full). */
|
|
150
149
|
this.ee.on(SESSION_EVENTS.RESUME, () => {
|
|
151
150
|
const updatedTraceMode = sessionEntity.state.sessionTraceMode;
|
|
152
|
-
if (updatedTraceMode === MODE.OFF) stopTracePerm();else if (updatedTraceMode === MODE.FULL && this.#scheduler && !this.#scheduler.started) this.#scheduler.runHarvest({
|
|
153
|
-
needResponse: true
|
|
154
|
-
});
|
|
151
|
+
if (updatedTraceMode === MODE.OFF) stopTracePerm();else if (updatedTraceMode === MODE.FULL && this.#scheduler && !this.#scheduler.started) this.#scheduler.runHarvest({});
|
|
155
152
|
mostRecentModeKnown = updatedTraceMode;
|
|
156
153
|
});
|
|
157
154
|
this.ee.on(SESSION_EVENTS.PAUSE, () => {
|
|
@@ -242,15 +239,12 @@ export class Aggregate extends AggregateBase {
|
|
|
242
239
|
retryDelay: this.harvestTimeSeconds
|
|
243
240
|
}, this);
|
|
244
241
|
this.#scheduler.harvest.on('resources', this.#prepareHarvest.bind(this));
|
|
245
|
-
if (dontStartHarvestYet === false) this.#scheduler.runHarvest({
|
|
246
|
-
needResponse: true
|
|
247
|
-
}); // sends first stn harvest immediately
|
|
242
|
+
if (dontStartHarvestYet === false) this.#scheduler.runHarvest({}); // sends first stn harvest immediately
|
|
248
243
|
startupBuffer.decide(true); // signal to ALLOW & process data in EE's buffer into internal nodes queued for next harvest
|
|
249
244
|
}
|
|
250
245
|
#onHarvestFinished(result) {
|
|
251
|
-
if (result.sent && result.
|
|
252
|
-
// continue interval harvest only
|
|
253
|
-
this.agentRuntime.ptid = this.ptid = result.responseText;
|
|
246
|
+
if (result.sent && !result.failed && !this.#scheduler.started) {
|
|
247
|
+
// continue interval harvest only after first call
|
|
254
248
|
this.#scheduler.startTimer(this.harvestTimeSeconds);
|
|
255
249
|
}
|
|
256
250
|
if (result.sent && result.retry && this.sentTrace) {
|
|
@@ -266,15 +260,18 @@ export class Aggregate extends AggregateBase {
|
|
|
266
260
|
}
|
|
267
261
|
#prepareHarvest(options) {
|
|
268
262
|
if (this.isStandalone) {
|
|
269
|
-
if (this.
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
263
|
+
if (this.#scheduler.started) {
|
|
264
|
+
if (now() >= MAX_TRACE_DURATION) {
|
|
265
|
+
// Perform a final harvest once we hit or exceed the max session trace time
|
|
266
|
+
options.isFinalHarvest = true;
|
|
267
|
+
this.operationalGate.permanentlyDecide(false);
|
|
268
|
+
this.#scheduler.stopTimer(true);
|
|
269
|
+
} else if (this.nodeCount <= REQ_THRESHOLD_TO_SEND && !options.isFinalHarvest) {
|
|
270
|
+
// Only harvest when more than some threshold of nodes are pending, after the very first harvest, with the exception of the last outgoing harvest.
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
277
273
|
}
|
|
274
|
+
// else, we must be on the very first harvest (standalone mode), so go to next square
|
|
278
275
|
} else {
|
|
279
276
|
// -- *cli May '26 - Update: Not rate limiting backgrounded pages either for now.
|
|
280
277
|
// if (this.ptid && document.visibilityState === 'hidden' && this.nodeCount <= REQ_THRESHOLD_TO_SEND) return
|
|
@@ -15,6 +15,7 @@ import { gosCDN } from '../../common/window/nreum';
|
|
|
15
15
|
import { apiMethods, asyncApiMethods } from './api-methods';
|
|
16
16
|
import { SR_EVENT_EMITTER_TYPES } from '../../features/session_replay/constants';
|
|
17
17
|
import { now } from '../../common/timing/now';
|
|
18
|
+
import { MODE } from '../../common/session/constants';
|
|
18
19
|
export function setTopLevelCallers() {
|
|
19
20
|
const nr = gosCDN();
|
|
20
21
|
apiMethods.forEach(f => {
|
|
@@ -38,12 +39,17 @@ export function setTopLevelCallers() {
|
|
|
38
39
|
return returnVals.length > 1 ? returnVals : returnVals[0];
|
|
39
40
|
}
|
|
40
41
|
}
|
|
42
|
+
const replayRunning = {};
|
|
41
43
|
export function setAPI(agentIdentifier, forceDrain) {
|
|
42
44
|
let runSoftNavOverSpa = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
43
45
|
if (!forceDrain) registerDrain(agentIdentifier, 'api');
|
|
44
46
|
const apiInterface = {};
|
|
45
47
|
var instanceEE = ee.get(agentIdentifier);
|
|
46
48
|
var tracerEE = instanceEE.get('tracer');
|
|
49
|
+
replayRunning[agentIdentifier] = MODE.OFF;
|
|
50
|
+
instanceEE.on(SR_EVENT_EMITTER_TYPES.REPLAY_RUNNING, isRunning => {
|
|
51
|
+
replayRunning[agentIdentifier] = isRunning;
|
|
52
|
+
});
|
|
47
53
|
var prefix = 'api-';
|
|
48
54
|
var spaPrefix = prefix + 'ixn-';
|
|
49
55
|
|
|
@@ -186,7 +192,7 @@ export function setAPI(agentIdentifier, forceDrain) {
|
|
|
186
192
|
apiInterface.noticeError = function (err, customAttributes) {
|
|
187
193
|
if (typeof err === 'string') err = new Error(err);
|
|
188
194
|
handle(SUPPORTABILITY_METRIC_CHANNEL, ['API/noticeError/called'], undefined, FEATURE_NAMES.metrics, instanceEE);
|
|
189
|
-
handle('err', [err, now(), false, customAttributes], undefined, FEATURE_NAMES.jserrors, instanceEE);
|
|
195
|
+
handle('err', [err, now(), false, customAttributes, !!replayRunning[agentIdentifier]], undefined, FEATURE_NAMES.jserrors, instanceEE);
|
|
190
196
|
};
|
|
191
197
|
|
|
192
198
|
// theres no window.load event on non-browser scopes, lazy load immediately
|
|
@@ -54,6 +54,7 @@ export function configure(agent) {
|
|
|
54
54
|
agent.runSoftNavOverSpa &&= updatedInit.soft_navigations.enabled === true && updatedInit.feature_flags.includes('soft_nav');
|
|
55
55
|
}
|
|
56
56
|
runtime.denyList = [...(updatedInit.ajax.deny_list || []), ...(updatedInit.ajax.block_internal ? internalTrafficList : [])];
|
|
57
|
+
runtime.ptid = agent.agentIdentifier;
|
|
57
58
|
setRuntime(agent.agentIdentifier, runtime);
|
|
58
59
|
if (agent.api === undefined) agent.api = setAPI(agent.agentIdentifier, forceDrain, agent.runSoftNavOverSpa);
|
|
59
60
|
if (agent.exposed === undefined) agent.exposed = exposed;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../../../src/common/constants/runtime.js"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;GAEG;AACH,qCAEqB;AAErB;;GAEG;AACH,oCAeK;AAEL,oDAUI;AAEJ,oDAA6F;AAE7F,sCAA2F;AAE3F,qCAAyD;AAEzD,4BAA8E;AAE9E;;;;;;GAMG;AACH,iCAAwE;AAExE,+BAOI;AAEJ,2BAA2E;AAE3E,yCAAqE;AAErE,
|
|
1
|
+
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../../../src/common/constants/runtime.js"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;GAEG;AACH,qCAEqB;AAErB;;GAEG;AACH,oCAeK;AAEL,oDAUI;AAEJ,oDAA6F;AAE7F,sCAA2F;AAE3F,qCAAyD;AAEzD,4BAA8E;AAE9E;;;;;;GAMG;AACH,iCAAwE;AAExE,+BAOI;AAEJ,2BAA2E;AAE3E,yCAAqE;AAErE,4BAAgE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-entity.d.ts","sourceRoot":"","sources":["../../../../src/common/session/session-entity.js"],"names":[],"mappings":"AA6BA;IACE;;;;;OAKG;IACH,uBA0BC;IApBC,qBAAsC;IACtC,aAAsB;IACtB,UAAe;IAGf,SAAc;IAEd,QAAiC;IAenC;;;;
|
|
1
|
+
{"version":3,"file":"session-entity.d.ts","sourceRoot":"","sources":["../../../../src/common/session/session-entity.js"],"names":[],"mappings":"AA6BA;IACE;;;;;OAKG;IACH,uBA0BC;IApBC,qBAAsC;IACtC,aAAsB;IACtB,UAAe;IAGf,SAAc;IAEd,QAAiC;IAenC;;;;aAyEC;IAlEC,8BAA0B;IAC1B,+BAA4B;IAc1B,gCAOqC;IAUrC,4CAkBsC;IAexC,iCAAuB;IAIzB,wBAEC;IAED,sBAEC;IAED;;;OAGG;IACH,QAFa,MAAM,CA6BlB;IAED;;;;;;OAMG;IACH,YAHW,MAAM,GACJ,MAAM,CAkBlB;IAED,gBAuBC;IAED;;OAEG;IACH,gBAIC;IAED;;;OAGG;IACH,qBAHW,MAAM,GACJ,OAAO,CAInB;IAED;;;OAGG;IACH,gBAHW,MAAM,GACJ,OAAO,CAKnB;IAED,yDAUC;IAED,6DAIC;IAED;;;OAGG;IACH,6BAHW,MAAM,GACJ,MAAM,CAIlB;IAED,gDAaC;IAHG,YAAuD;CAI5D;sBArSqB,gBAAgB;iCAGL,4BAA4B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interaction-timer.d.ts","sourceRoot":"","sources":["../../../../src/common/timer/interaction-timer.js"],"names":[],"mappings":"AAKA;IAGI,aAAuF;IACvF,eAA6F;IAC7F,cAA0F;
|
|
1
|
+
{"version":3,"file":"interaction-timer.d.ts","sourceRoot":"","sources":["../../../../src/common/timer/interaction-timer.js"],"names":[],"mappings":"AAKA;IAGI,aAAuF;IACvF,eAA6F;IAC7F,cAA0F;IAE1F,mDAAmD;IACnD,iBAAmC;IAGnC,gCAA4B;IAM1B,6CAA4C;IAO1C,QAAiB;IAEjB,kDAIC;IAoBP,cAQC;IAED,cAIC;IAED,eAeC;IAED,gCAMC;CACF;sBA/FqB,SAAS"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"time-keeper.d.ts","sourceRoot":"","sources":["../../../../src/common/timing/time-keeper.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"time-keeper.d.ts","sourceRoot":"","sources":["../../../../src/common/timing/time-keeper.js"],"names":[],"mappings":"AAAA;;;;GAIG;AACH;IA+BE,oBAEC;IAED,yBAEC;IAED,kCAEC;IAED;;;;;OAKG;IACH,8BAJsB,cAAc,aACf,MAAM,WACR,MAAM,QAoBxB;IAED;;;;;OAKG;IACH,uCAHwB,MAAM,GACjB,MAAM,CAIlB;IAED;;;;OAIG;IACH,oCAHqB,MAAM,GACf,MAAM,CAIjB;;CACF"}
|
|
@@ -10,6 +10,7 @@ export class Aggregate extends AggregateBase {
|
|
|
10
10
|
bufferedErrorsUnderSpa: {};
|
|
11
11
|
currentBody: {} | null | undefined;
|
|
12
12
|
errorOnPage: boolean;
|
|
13
|
+
replayAborted: boolean;
|
|
13
14
|
onHarvestStarted(options: any): {
|
|
14
15
|
body: {} | null;
|
|
15
16
|
qs: {};
|
|
@@ -25,7 +26,7 @@ export class Aggregate extends AggregateBase {
|
|
|
25
26
|
* @returns {string} A canonical stack string built from the URLs and function names in the given `stackInfo` object.
|
|
26
27
|
*/
|
|
27
28
|
buildCanonicalStackString(stackInfo: StackInfo): string;
|
|
28
|
-
storeError(err: any, time: any, internal: any, customAttributes: any): void;
|
|
29
|
+
storeError(err: any, time: any, internal: any, customAttributes: any, hasReplay: any): void;
|
|
29
30
|
onInteractionDone(interaction: any, wasSaved: any): void;
|
|
30
31
|
onSoftNavNotification(interactionId: any, wasFinished: any, softNavAttrs: any): void;
|
|
31
32
|
#private;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/features/jserrors/aggregate/index.js"],"names":[],"mappings":"AAyBA;;GAEG;AAEH;IACE,2BAAiC;IACjC,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/features/jserrors/aggregate/index.js"],"names":[],"mappings":"AAyBA;;GAEG;AAEH;IACE,2BAAiC;IACjC,mDAmCC;IAhCC,kBAAuB;IACvB,eAAoB;IACpB,qBAA0B;IAC1B,2BAAgC;IAChC,mCAA4B;IAC5B,qBAAwB;IACxB,uBAA0B;IA4B5B;;;MA2BC;IAED,qCAWC;IAED,8BAEC;IAED,oEAMC;IAED;;;;;;OAMG;IACH,qCAHW,SAAS,GACP,MAAM,CAgBlB;IAED,4FAsFC;IA4BD,yDA6BC;IAED,qFAOC;;CACF;wBAhRY,OAAO,0BAA0B,EAAE,SAAS;8BAN3B,4BAA4B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/features/jserrors/instrument/index.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/features/jserrors/instrument/index.js"],"names":[],"mappings":"AAgBA;IACE,2BAAiC;IAKjC,mEA+CC;IA1CG,2CAA0C;IAwC5C,yBAA+B;;CAoFlC;+BAjJ8B,6BAA6B"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export class Aggregate extends AggregateBase {
|
|
2
2
|
static featureName: string;
|
|
3
3
|
constructor(agentIdentifier: any, aggregator: any, args: any);
|
|
4
|
+
mode: number;
|
|
4
5
|
/** The interval to harvest at. This gets overridden if the size of the payload exceeds certain thresholds */
|
|
5
6
|
harvestTimeSeconds: any;
|
|
6
7
|
/** Set once the recorder has fully initialized after flag checks and sampling */
|
|
@@ -9,14 +10,15 @@ export class Aggregate extends AggregateBase {
|
|
|
9
10
|
gzipper: typeof import("fflate").gzipSync | undefined;
|
|
10
11
|
/** populated with the u8 string lib async */
|
|
11
12
|
u8: typeof import("fflate").strToU8 | undefined;
|
|
12
|
-
mode: any;
|
|
13
13
|
/** set by BCS response */
|
|
14
14
|
entitled: boolean;
|
|
15
15
|
/** set at BCS response, stored in runtime */
|
|
16
16
|
timeKeeper: any;
|
|
17
17
|
recorder: any;
|
|
18
|
+
preloaded: boolean;
|
|
19
|
+
errorNoticed: any;
|
|
18
20
|
scheduler: HarvestScheduler;
|
|
19
|
-
|
|
21
|
+
handleError(e: any): void;
|
|
20
22
|
switchToFull(): void;
|
|
21
23
|
/**
|
|
22
24
|
* Evaluate entitlements and sampling before starting feature mechanics, importing and configuring recording library, and setting storage state
|
|
@@ -41,6 +43,7 @@ export class Aggregate extends AggregateBase {
|
|
|
41
43
|
};
|
|
42
44
|
body: any;
|
|
43
45
|
}[] | undefined;
|
|
46
|
+
getCorrectedTimestamp(node: any): any;
|
|
44
47
|
getHarvestContents(recorderEvents: any): {
|
|
45
48
|
qs: {
|
|
46
49
|
browser_monitoring_key: any;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/features/session_replay/aggregate/index.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/features/session_replay/aggregate/index.js"],"names":[],"mappings":"AAgCA;IACE,2BAAiC;IAIjC,8DAsGC;IAzGD,aAAe;IAKb,8GAA8G;IAC9G,wBAAgH;IAChH,iFAAiF;IACjF,qBAAwB;IAGxB,2CAA2C;IAC3C,sDAAwB;IACxB,6CAA6C;IAC7C,gDAAmB;IAEnB,0BAA0B;IAC1B,kBAAqB;IACrB,6CAA6C;IAC7C,gBAA2B;IAE3B,cAA8B;IAC9B,mBAAgC;IAChC,kBAA+C;IA4B/C,4BAKQ;IAmDV,0BAMC;IAED,qBAWC;IAED;;;;;;;OAOG;IACH,iCALW,OAAO,cACP,OAAO,iBACP,OAAO,GACL,IAAI,CA8DhB;IAED,2BASC;IAED;;;;;;;;;;;;oBAiDC;IAED,sCAIC;IAED;;;;;;;;;;MAoEC;IAED,qCAOC;IAED;;;;OAIG;IACH,mCAKC;IAED,yDAAyD;IACzD,yBAUC;IAED,yCAGC;CACF;8BAxY6B,4BAA4B;iCAHzB,2CAA2C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../../src/features/session_replay/constants.js"],"names":[],"mappings":"AAGA,kCAAuD
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../../src/features/session_replay/constants.js"],"names":[],"mappings":"AAGA,kCAAuD;;;;;;AAQvD,mCAAmC;;;;;;;;;AASnC,uCAAuC;AACvC,uCAAuC;AACvC,iCAAiC;AACjC,uCAAuC;AACvC,2GAA2G;AAC3G;;EAAsF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BtF,0CAA0C;AAC1C,uCAAuC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/features/session_replay/instrument/index.js"],"names":[],"mappings":"AAgBA;IACE,2BAAiC;IACjC,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/features/session_replay/instrument/index.js"],"names":[],"mappings":"AAgBA;IACE,2BAAiC;IACjC,mEAiBC;IAPK,sBAAwB;IAwB5B,4DAA0F;;CAK7F;+BA7C8B,6BAA6B"}
|
|
@@ -1,18 +1,10 @@
|
|
|
1
1
|
export class RecorderEvents {
|
|
2
|
-
constructor({ canCorrectTimestamps }: {
|
|
3
|
-
canCorrectTimestamps: any;
|
|
4
|
-
});
|
|
5
2
|
/** The buffer to hold recorder event nodes */
|
|
6
3
|
events: any[];
|
|
7
4
|
/** Payload metadata -- Should indicate when a replay blob started recording. Resets each time a harvest occurs.
|
|
8
5
|
* cycle timestamps are used as fallbacks if event timestamps cannot be used
|
|
9
6
|
*/
|
|
10
7
|
cycleTimestamp: number;
|
|
11
|
-
/** Payload metadata -- Whether timestamps can be corrected, defaults as false, can be set to true if timekeeper is present at init time. Used to determine
|
|
12
|
-
* if harvest needs to re-loop through nodes and correct them before sending. Ideal behavior is to correct them as they flow into the recorder
|
|
13
|
-
* to prevent re-looping, but is not always possible since the timekeeper is not set until after page load and the recorder can be preloaded.
|
|
14
|
-
*/
|
|
15
|
-
canCorrectTimestamps: boolean;
|
|
16
8
|
/** A value which increments with every new mutation node reported. Resets after a harvest is sent */
|
|
17
9
|
payloadBytesEstimation: number;
|
|
18
10
|
/** Payload metadata -- Should indicate that the payload being sent has a full DOM snapshot. This can happen
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recorder-events.d.ts","sourceRoot":"","sources":["../../../../../src/features/session_replay/shared/recorder-events.js"],"names":[],"mappings":"AAAA;
|
|
1
|
+
{"version":3,"file":"recorder-events.d.ts","sourceRoot":"","sources":["../../../../../src/features/session_replay/shared/recorder-events.js"],"names":[],"mappings":"AAAA;IAEI,8CAA8C;IAC9C,cAAgB;IAChB;;OAEG;IACH,uBAAgC;IAChC,qGAAqG;IACrG,+BAA+B;IAC/B;;;MAGE;IACF,qBAAwB;IACxB,4IAA4I;IAC5I,iBAAoB;IACpB,+HAA+H;IAC/H,kBAAqB;IACrB,0FAA0F;IAC1F,+BAAiC;IAGnC,sBAEC;CACF"}
|
|
@@ -15,31 +15,15 @@ export class Recorder {
|
|
|
15
15
|
/** The method to stop recording. This defaults to a noop, but is overwritten once the recording library is imported and initialized */
|
|
16
16
|
stopRecording: () => void;
|
|
17
17
|
getEvents(): {
|
|
18
|
-
events: CorrectedSessionReplayEvent[];
|
|
19
18
|
type: string;
|
|
19
|
+
events: any[];
|
|
20
20
|
cycleTimestamp: number;
|
|
21
|
-
canCorrectTimestamps: boolean;
|
|
22
21
|
payloadBytesEstimation: number;
|
|
23
22
|
hasSnapshot: boolean;
|
|
24
23
|
hasMeta: boolean;
|
|
25
24
|
hasError: boolean;
|
|
26
25
|
inlinedAllStylesheets: boolean;
|
|
27
|
-
} | {
|
|
28
|
-
events: any[];
|
|
29
|
-
type: string;
|
|
30
|
-
cycleTimestamp: number;
|
|
31
|
-
payloadBytesEstimation: number;
|
|
32
|
-
hasError: boolean;
|
|
33
|
-
hasMeta: boolean;
|
|
34
|
-
hasSnapshot: boolean;
|
|
35
|
-
inlinedAllStylesheets: boolean;
|
|
36
26
|
};
|
|
37
|
-
/**
|
|
38
|
-
* Returns time-corrected events. If the events were correctable from the beginning, this correction will have already been applied.
|
|
39
|
-
* @param {SessionReplayEvent[]} events The array of buffered SR nodes
|
|
40
|
-
* @returns {CorrectedSessionReplayEvent[]}
|
|
41
|
-
*/
|
|
42
|
-
returnCorrectTimestamps(events: SessionReplayEvent[]): CorrectedSessionReplayEvent[];
|
|
43
27
|
/** Clears the buffer (this.#events), and resets all payload metadata properties */
|
|
44
28
|
clearBuffer(): void;
|
|
45
29
|
/** Begin recording using configured recording lib */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recorder.d.ts","sourceRoot":"","sources":["../../../../../src/features/session_replay/shared/recorder.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"recorder.d.ts","sourceRoot":"","sources":["../../../../../src/features/session_replay/shared/recorder.js"],"names":[],"mappings":"AAYA;IAUE,yBAkBC;IAdC,iEAAiE;IACjE,mBAAsB;IACtB,6DAA6D;IAC7D,oCAAuC;IACvC,kIAAkI;IAClI,kBAAqB;IACrB,sDAAsD;IACtD,YAAoB;IACpB,oEAAoE;IACpE,6BAAqH;IACrH,0FAA0F;IAC1F,eAA6C;IAC7C,uIAAuI;IACvI,0BAAyE;IAG3E;;;;;;;;;MAYC;IAED,mFAAmF;IACnF,oBAKC;IAED,qDAAqD;IACrD,uBAiCC;IAED;;;;;OAKG;IACH,yCA0BC;IAED,0HAA0H;IAC1H,yCAgDC;IAED,0HAA0H;IAC1H,yBAOC;IAED,wBAEC;IAED,gCAAgC;IAChC,uCAGC;IAED;;;SAGK;IACL,oCAGC;;CACF;+BAjN8B,mBAAmB"}
|
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
export function isPreloadAllowed(agentId: any): any;
|
|
2
2
|
export function canImportReplayAgg(agentId: any, sessionMgr: any): boolean;
|
|
3
|
+
export function buildNRMetaNode(timestamp: any, timeKeeper: any): {
|
|
4
|
+
originalTimestamp: any;
|
|
5
|
+
correctedTimestamp: any;
|
|
6
|
+
timestampDiff: number;
|
|
7
|
+
timeKeeperOriginTime: any;
|
|
8
|
+
timeKeeperCorrectedOriginTime: any;
|
|
9
|
+
timeKeeperDiff: number;
|
|
10
|
+
};
|
|
3
11
|
export function enableSessionTracking(agentId: any): boolean;
|
|
4
12
|
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../../../src/features/session_replay/shared/utils.js"],"names":[],"mappings":"AAWA,oDAEC;AAED,2EAGC;
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../../../src/features/session_replay/shared/utils.js"],"names":[],"mappings":"AAWA,oDAEC;AAED,2EAGC;AAED;;;;;;;EAUC;AA3BM,6DAA+H"}
|
|
@@ -3,10 +3,11 @@ export class Aggregate extends AggregateBase {
|
|
|
3
3
|
constructor(agentIdentifier: any, aggregator: any, argsObj: any);
|
|
4
4
|
agentRuntime: any;
|
|
5
5
|
resourceObserver: any;
|
|
6
|
-
ptid:
|
|
6
|
+
ptid: any;
|
|
7
7
|
trace: {} | undefined;
|
|
8
8
|
nodeCount: number | undefined;
|
|
9
9
|
sentTrace: {} | null | undefined;
|
|
10
|
+
everSent: boolean | undefined;
|
|
10
11
|
harvestTimeSeconds: any;
|
|
11
12
|
maxNodesPerHarvest: any;
|
|
12
13
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/features/session_trace/aggregate/index.js"],"names":[],"mappings":"AAiCA;IACE,2BAAiC;IAGjC,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/features/session_trace/aggregate/index.js"],"names":[],"mappings":"AAiCA;IACE,2BAAiC;IAGjC,iEA6IC;IA3IC,kBAA+C;IAK/C,sBAAiD;IACjD,UAAkC;IAClC,sBAAe;IACf,8BAAkB;IAClB,iCAAqB;IACrB,8BAAqB;IACrB,wBAA0G;IAC1G,wBAA4G;IAC5G;;4EAEwE;IACxE,kCAAyB;IAGzB,0CAAsC;IA0HxC,sEAcC;IA8CD,oDAOC;IAGD,oCAwBC;IAGD,uEAkBC;IAED,oDAKC;IAED,wBAwBC;IAED,uCAuBC;IAGD,gDASC;IAID,qCAkBC;IAGD,qEAUC;IAGD,mEAUC;IAGD,yBAeC;IAED;;;;OAIG;IACH,2BAHW,MAAM,GACJ,MAAM,CAsBlB;IAGD;;;;;;;YAkCM;0GAC8F;;YAE9F;0FAC8E;;YAE9E,4IAA4I;;;;;;MAMjJ;IAED,mEA6BC;;CACF;8BAhhB6B,4BAA4B;6BAF7B,2BAA2B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../../../src/loaders/api/api.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../../../src/loaders/api/api.js"],"names":[],"mappings":"AAmBA,2CAeC;AAID;;;;IAuDE;;;;OAIG;qBAFQ,MAAM;IAWjB;;;;OAIG;iCAFQ,MAAM,GAAC,IAAI;;;;;EA0GvB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"configure.d.ts","sourceRoot":"","sources":["../../../../src/loaders/configure/configure.js"],"names":[],"mappings":"AASA;;GAEG;AACH,
|
|
1
|
+
{"version":3,"file":"configure.d.ts","sourceRoot":"","sources":["../../../../src/loaders/configure/configure.js"],"names":[],"mappings":"AASA;;GAEG;AACH,oGAgDC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@newrelic/browser-agent",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.256.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"author": "New Relic Browser Agent Team <browser-agent@newrelic.com>",
|
|
6
6
|
"description": "New Relic Browser Agent",
|
|
@@ -168,7 +168,7 @@
|
|
|
168
168
|
"dependencies": {
|
|
169
169
|
"core-js": "^3.26.0",
|
|
170
170
|
"fflate": "^0.7.4",
|
|
171
|
-
"rrweb": "2.0.0-alpha.
|
|
171
|
+
"rrweb": "2.0.0-alpha.12",
|
|
172
172
|
"web-vitals": "^3.1.0"
|
|
173
173
|
},
|
|
174
174
|
"devDependencies": {
|
|
@@ -74,4 +74,4 @@ export const isIE = Boolean(isBrowserScope && window.document.documentMode) // d
|
|
|
74
74
|
|
|
75
75
|
export const supportsSendBeacon = !!globalScope.navigator?.sendBeacon
|
|
76
76
|
|
|
77
|
-
export const offset = Math.floor(
|
|
77
|
+
export const offset = Math.floor(Date.now() - performance.now())
|
|
@@ -145,7 +145,7 @@ export class Harvest extends SharedContext {
|
|
|
145
145
|
result.addEventListener('loadend', function () {
|
|
146
146
|
// `this` refers to the XHR object in this scope, do not change this to a fat arrow
|
|
147
147
|
// status 0 refers to a local error, such as CORS or network failure, or a blocked request by the browser (e.g. adblocker)
|
|
148
|
-
const cbResult = { sent: this.status !== 0, status: this.status, xhr: this, fullUrl }
|
|
148
|
+
const cbResult = { sent: this.status !== 0, status: this.status, failed: this.status === 0 || this.status >= 400, xhr: this, fullUrl }
|
|
149
149
|
if (this.status === 429) {
|
|
150
150
|
cbResult.retry = true
|
|
151
151
|
cbResult.delay = harvestScope.tooManyRequestsDelay
|
|
@@ -117,7 +117,8 @@ export class SessionEntity {
|
|
|
117
117
|
this.write(getModeledObject(this.state, model))
|
|
118
118
|
},
|
|
119
119
|
ee: this.ee,
|
|
120
|
-
refreshEvents: ['click', 'keydown', 'scroll']
|
|
120
|
+
refreshEvents: ['click', 'keydown', 'scroll'],
|
|
121
|
+
readStorage: () => this.storage.get(this.lookupKey)
|
|
121
122
|
}, this.state.inactiveAt - Date.now())
|
|
122
123
|
} else {
|
|
123
124
|
this.state.inactiveAt = Infinity
|
|
@@ -10,6 +10,9 @@ export class InteractionTimer extends Timer {
|
|
|
10
10
|
this.onRefresh = typeof opts.onRefresh === 'function' ? opts.onRefresh : () => { /* noop */ }
|
|
11
11
|
this.onResume = typeof opts.onResume === 'function' ? opts.onResume : () => { /* noop */ }
|
|
12
12
|
|
|
13
|
+
/** used to double-check LS state at resume time */
|
|
14
|
+
this.readStorage = opts.readStorage
|
|
15
|
+
|
|
13
16
|
// used by pause/resume
|
|
14
17
|
this.remainingMs = undefined
|
|
15
18
|
|
|
@@ -67,8 +70,20 @@ export class InteractionTimer extends Timer {
|
|
|
67
70
|
}
|
|
68
71
|
|
|
69
72
|
resume () {
|
|
70
|
-
|
|
71
|
-
|
|
73
|
+
try {
|
|
74
|
+
const lsData = this.readStorage()
|
|
75
|
+
const obj = typeof lsData === 'string' ? JSON.parse(lsData) : lsData
|
|
76
|
+
if (isExpired(obj.expiresAt) || isExpired(obj.inactiveAt)) this.end()
|
|
77
|
+
else {
|
|
78
|
+
this.refresh()
|
|
79
|
+
this.onResume() // emit resume event after state updated
|
|
80
|
+
}
|
|
81
|
+
} catch (err) {
|
|
82
|
+
this.end()
|
|
83
|
+
}
|
|
84
|
+
function isExpired (timestamp) {
|
|
85
|
+
return Date.now() > timestamp
|
|
86
|
+
}
|
|
72
87
|
}
|
|
73
88
|
|
|
74
89
|
refresh (cb, ms) {
|