@amplitude/session-replay-browser 1.2.1 → 1.2.2
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/lib/cjs/config.d.ts +0 -3
- package/lib/cjs/config.d.ts.map +1 -1
- package/lib/cjs/config.js +0 -9
- package/lib/cjs/config.js.map +1 -1
- package/lib/cjs/identifiers.d.ts +9 -0
- package/lib/cjs/identifiers.d.ts.map +1 -0
- package/lib/cjs/identifiers.js +18 -0
- package/lib/cjs/identifiers.js.map +1 -0
- package/lib/cjs/session-idb-store.d.ts +15 -0
- package/lib/cjs/session-idb-store.d.ts.map +1 -0
- package/lib/cjs/session-idb-store.js +107 -0
- package/lib/cjs/session-idb-store.js.map +1 -0
- package/lib/cjs/session-replay.d.ts +6 -23
- package/lib/cjs/session-replay.d.ts.map +1 -1
- package/lib/cjs/session-replay.js +62 -312
- package/lib/cjs/session-replay.js.map +1 -1
- package/lib/cjs/track-destination.d.ts +28 -0
- package/lib/cjs/track-destination.d.ts.map +1 -0
- package/lib/cjs/track-destination.js +204 -0
- package/lib/cjs/track-destination.js.map +1 -0
- package/lib/cjs/typings/session-replay.d.ts +27 -7
- package/lib/cjs/typings/session-replay.d.ts.map +1 -1
- package/lib/cjs/typings/session-replay.js.map +1 -1
- package/lib/esm/config.d.ts +0 -3
- package/lib/esm/config.d.ts.map +1 -1
- package/lib/esm/config.js +0 -9
- package/lib/esm/config.js.map +1 -1
- package/lib/esm/identifiers.d.ts +9 -0
- package/lib/esm/identifiers.d.ts.map +1 -0
- package/lib/esm/identifiers.js +16 -0
- package/lib/esm/identifiers.js.map +1 -0
- package/lib/esm/session-idb-store.d.ts +15 -0
- package/lib/esm/session-idb-store.d.ts.map +1 -0
- package/lib/esm/session-idb-store.js +105 -0
- package/lib/esm/session-idb-store.js.map +1 -0
- package/lib/esm/session-replay.d.ts +6 -23
- package/lib/esm/session-replay.d.ts.map +1 -1
- package/lib/esm/session-replay.js +66 -316
- package/lib/esm/session-replay.js.map +1 -1
- package/lib/esm/track-destination.d.ts +28 -0
- package/lib/esm/track-destination.d.ts.map +1 -0
- package/lib/esm/track-destination.js +202 -0
- package/lib/esm/track-destination.js.map +1 -0
- package/lib/esm/typings/session-replay.d.ts +27 -7
- package/lib/esm/typings/session-replay.d.ts.map +1 -1
- package/lib/esm/typings/session-replay.js.map +1 -1
- package/lib/scripts/amplitude-min.js +1 -1
- package/lib/scripts/amplitude-min.js.gz +0 -0
- package/lib/scripts/amplitude-min.umd.js +1 -1
- package/lib/scripts/amplitude-min.umd.js.gz +0 -0
- package/lib/scripts/config.d.ts +0 -3
- package/lib/scripts/config.d.ts.map +1 -1
- package/lib/scripts/identifiers.d.ts +9 -0
- package/lib/scripts/identifiers.d.ts.map +1 -0
- package/lib/scripts/session-idb-store.d.ts +15 -0
- package/lib/scripts/session-idb-store.d.ts.map +1 -0
- package/lib/scripts/session-replay.d.ts +6 -23
- package/lib/scripts/session-replay.d.ts.map +1 -1
- package/lib/scripts/track-destination.d.ts +28 -0
- package/lib/scripts/track-destination.d.ts.map +1 -0
- package/lib/scripts/typings/session-replay.d.ts +27 -7
- package/lib/scripts/typings/session-replay.d.ts.map +1 -1
- package/package.json +2 -2
|
@@ -1,25 +1,20 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { __awaiter, __generator } from "tslib";
|
|
2
2
|
import { getAnalyticsConnector, getGlobalScope } from '@amplitude/analytics-client-common';
|
|
3
|
-
import {
|
|
4
|
-
import { ServerZone, Status } from '@amplitude/analytics-types';
|
|
3
|
+
import { Logger, returnWrapper } from '@amplitude/analytics-core';
|
|
5
4
|
import { pack, record } from '@amplitude/rrweb';
|
|
6
|
-
import * as IDBKeyVal from 'idb-keyval';
|
|
7
5
|
import { SessionReplayConfig } from './config';
|
|
8
|
-
import { BLOCK_CLASS,
|
|
9
|
-
import { generateHashCode, generateSessionReplayId,
|
|
10
|
-
import {
|
|
6
|
+
import { BLOCK_CLASS, DEFAULT_SESSION_REPLAY_PROPERTY, MASK_TEXT_CLASS, MAX_EVENT_LIST_SIZE_IN_BYTES, MAX_INTERVAL, MIN_INTERVAL, SESSION_REPLAY_DEBUG_PROPERTY, } from './constants';
|
|
7
|
+
import { generateHashCode, generateSessionReplayId, isSessionInSample, maskInputFn } from './helpers';
|
|
8
|
+
import { SessionIdentifiers } from './identifiers';
|
|
9
|
+
import { SessionReplaySessionIDBStore } from './session-idb-store';
|
|
10
|
+
import { SessionReplayTrackDestination } from './track-destination';
|
|
11
11
|
import { RecordingStatus, } from './typings/session-replay';
|
|
12
|
-
import { VERSION } from './version';
|
|
13
12
|
var SessionReplay = /** @class */ (function () {
|
|
14
13
|
function SessionReplay() {
|
|
15
14
|
var _this = this;
|
|
16
15
|
this.name = '@amplitude/session-replay-browser';
|
|
17
|
-
this.storageKey = '';
|
|
18
|
-
this.retryTimeout = 1000;
|
|
19
16
|
this.events = [];
|
|
20
17
|
this.currentSequenceId = 0;
|
|
21
|
-
this.scheduled = null;
|
|
22
|
-
this.queue = [];
|
|
23
18
|
this.stopRecordingEvents = null;
|
|
24
19
|
this.maxPersistedEventsSize = MAX_EVENT_LIST_SIZE_IN_BYTES;
|
|
25
20
|
this.interval = MIN_INTERVAL;
|
|
@@ -50,6 +45,7 @@ var SessionReplay = /** @class */ (function () {
|
|
|
50
45
|
return false;
|
|
51
46
|
};
|
|
52
47
|
this.loggerProvider = new Logger();
|
|
48
|
+
this.trackDestination = new SessionReplayTrackDestination({ loggerProvider: this.loggerProvider });
|
|
53
49
|
}
|
|
54
50
|
SessionReplay.prototype.init = function (apiKey, options) {
|
|
55
51
|
return returnWrapper(this._init(apiKey, options));
|
|
@@ -62,8 +58,14 @@ var SessionReplay = /** @class */ (function () {
|
|
|
62
58
|
case 0:
|
|
63
59
|
this.config = new SessionReplayConfig(apiKey, options);
|
|
64
60
|
this.loggerProvider = this.config.loggerProvider;
|
|
61
|
+
this.identifiers = new SessionIdentifiers(options, this.loggerProvider);
|
|
62
|
+
// Update logger provider in trackDestination
|
|
63
|
+
this.trackDestination.setLoggerProvider(this.loggerProvider);
|
|
64
|
+
this.sessionIDBStore = new SessionReplaySessionIDBStore({
|
|
65
|
+
loggerProvider: this.loggerProvider,
|
|
66
|
+
apiKey: this.config.apiKey,
|
|
67
|
+
});
|
|
65
68
|
this.loggerProvider.log('Installing @amplitude/session-replay-browser.');
|
|
66
|
-
this.storageKey = "".concat(STORAGE_PREFIX, "_").concat(this.config.apiKey.substring(0, 10));
|
|
67
69
|
globalScope = getGlobalScope();
|
|
68
70
|
if (globalScope) {
|
|
69
71
|
globalScope.addEventListener('blur', this.blurListener);
|
|
@@ -80,24 +82,24 @@ var SessionReplay = /** @class */ (function () {
|
|
|
80
82
|
});
|
|
81
83
|
};
|
|
82
84
|
SessionReplay.prototype.setSessionId = function (sessionId, deviceId) {
|
|
83
|
-
if (!this.
|
|
85
|
+
if (!this.identifiers) {
|
|
84
86
|
this.loggerProvider.error('Session replay init has not been called, cannot set session id.');
|
|
85
87
|
return;
|
|
86
88
|
}
|
|
87
89
|
if (deviceId) {
|
|
88
|
-
this.
|
|
90
|
+
this.identifiers.deviceId = deviceId;
|
|
89
91
|
}
|
|
90
92
|
// use a consistent device id.
|
|
91
93
|
var deviceIdForReplayId = this.getDeviceId();
|
|
92
94
|
if (sessionId && deviceIdForReplayId) {
|
|
93
|
-
this.
|
|
95
|
+
this.identifiers.sessionReplayId = generateSessionReplayId(sessionId, deviceIdForReplayId);
|
|
94
96
|
}
|
|
95
97
|
else {
|
|
96
98
|
this.loggerProvider.error('Must provide either session replay id or session id when starting a new session.');
|
|
97
99
|
return;
|
|
98
100
|
}
|
|
99
|
-
this.stopRecordingAndSendEvents(this.
|
|
100
|
-
this.
|
|
101
|
+
this.stopRecordingAndSendEvents(this.identifiers.sessionId);
|
|
102
|
+
this.identifiers.sessionId = sessionId;
|
|
101
103
|
this.events = [];
|
|
102
104
|
this.currentSequenceId = 0;
|
|
103
105
|
this.recordEvents();
|
|
@@ -113,7 +115,7 @@ var SessionReplay = /** @class */ (function () {
|
|
|
113
115
|
};
|
|
114
116
|
SessionReplay.prototype.getSessionReplayProperties = function () {
|
|
115
117
|
var _a;
|
|
116
|
-
if (!this.config) {
|
|
118
|
+
if (!this.config || !this.identifiers) {
|
|
117
119
|
this.loggerProvider.error('Session replay init has not been called, cannot get session recording properties.');
|
|
118
120
|
return {};
|
|
119
121
|
}
|
|
@@ -123,7 +125,7 @@ var SessionReplay = /** @class */ (function () {
|
|
|
123
125
|
var shouldRecord = this.getShouldRecord(ignoreFocus);
|
|
124
126
|
if (shouldRecord) {
|
|
125
127
|
var eventProperties = (_a = {},
|
|
126
|
-
_a[DEFAULT_SESSION_REPLAY_PROPERTY] = this.
|
|
128
|
+
_a[DEFAULT_SESSION_REPLAY_PROPERTY] = this.identifiers.sessionReplayId ? this.identifiers.sessionReplayId : null,
|
|
127
129
|
_a);
|
|
128
130
|
if (this.config.debugMode) {
|
|
129
131
|
eventProperties[SESSION_REPLAY_DEBUG_PROPERTY] = this.getSessionReplayDebugPropertyValue();
|
|
@@ -142,7 +144,7 @@ var SessionReplay = /** @class */ (function () {
|
|
|
142
144
|
var typedError = error;
|
|
143
145
|
this.loggerProvider.warn("Error occurred while stopping recording: ".concat(typedError.toString()));
|
|
144
146
|
}
|
|
145
|
-
var sessionIdToSend = sessionId || ((_a = this.
|
|
147
|
+
var sessionIdToSend = sessionId || ((_a = this.identifiers) === null || _a === void 0 ? void 0 : _a.sessionId);
|
|
146
148
|
if (this.events.length && sessionIdToSend) {
|
|
147
149
|
this.sendEventsList({
|
|
148
150
|
events: this.events,
|
|
@@ -155,25 +157,30 @@ var SessionReplay = /** @class */ (function () {
|
|
|
155
157
|
var _a;
|
|
156
158
|
if (shouldSendStoredEvents === void 0) { shouldSendStoredEvents = false; }
|
|
157
159
|
return __awaiter(this, void 0, void 0, function () {
|
|
158
|
-
var storedReplaySessions, storedSequencesForSession, storedSeqId, lastSequence;
|
|
159
|
-
return __generator(this, function (
|
|
160
|
-
switch (
|
|
160
|
+
var storedReplaySessions, _b, storedSequencesForSession, storedSeqId, lastSequence;
|
|
161
|
+
return __generator(this, function (_c) {
|
|
162
|
+
switch (_c.label) {
|
|
161
163
|
case 0:
|
|
162
164
|
this.timeAtLastSend = Date.now(); // Initialize this so we have a point of comparison when events are recorded
|
|
163
|
-
if (!((_a = this.
|
|
165
|
+
if (!((_a = this.identifiers) === null || _a === void 0 ? void 0 : _a.sessionId)) {
|
|
164
166
|
this.loggerProvider.warn("Session is not being recorded due to lack of session id.");
|
|
165
167
|
return [2 /*return*/];
|
|
166
168
|
}
|
|
167
|
-
|
|
169
|
+
_b = this.sessionIDBStore;
|
|
170
|
+
if (!_b) return [3 /*break*/, 2];
|
|
171
|
+
return [4 /*yield*/, this.sessionIDBStore.getAllSessionDataFromStore()];
|
|
168
172
|
case 1:
|
|
169
|
-
|
|
173
|
+
_b = (_c.sent());
|
|
174
|
+
_c.label = 2;
|
|
175
|
+
case 2:
|
|
176
|
+
storedReplaySessions = _b;
|
|
170
177
|
// This resolves a timing issue when focus is fired multiple times in short succession,
|
|
171
178
|
// we only want the rest of this function to run once. We can be sure that initialize has
|
|
172
179
|
// already been called if this.stopRecordingEvents is defined
|
|
173
180
|
if (this.stopRecordingEvents) {
|
|
174
181
|
return [2 /*return*/];
|
|
175
182
|
}
|
|
176
|
-
storedSequencesForSession = storedReplaySessions && storedReplaySessions[this.
|
|
183
|
+
storedSequencesForSession = storedReplaySessions && storedReplaySessions[this.identifiers.sessionId];
|
|
177
184
|
if (storedReplaySessions && storedSequencesForSession && storedSequencesForSession.sessionSequences) {
|
|
178
185
|
storedSeqId = storedSequencesForSession.currentSequenceId;
|
|
179
186
|
lastSequence = storedSequencesForSession.sessionSequences[storedSeqId];
|
|
@@ -207,30 +214,30 @@ var SessionReplay = /** @class */ (function () {
|
|
|
207
214
|
};
|
|
208
215
|
SessionReplay.prototype.getShouldRecord = function (ignoreFocus) {
|
|
209
216
|
if (ignoreFocus === void 0) { ignoreFocus = false; }
|
|
210
|
-
if (!this.config) {
|
|
217
|
+
if (!this.identifiers || !this.config) {
|
|
211
218
|
this.loggerProvider.error("Session is not being recorded due to lack of config, please call sessionReplay.init.");
|
|
212
219
|
return false;
|
|
213
220
|
}
|
|
214
221
|
var globalScope = getGlobalScope();
|
|
215
222
|
if (!ignoreFocus && globalScope && globalScope.document && !globalScope.document.hasFocus()) {
|
|
216
|
-
if (this.
|
|
217
|
-
this.loggerProvider.log("Session ".concat(this.
|
|
223
|
+
if (this.identifiers.sessionId) {
|
|
224
|
+
this.loggerProvider.log("Session ".concat(this.identifiers.sessionId, " temporarily not recording due to lack of browser focus."));
|
|
218
225
|
}
|
|
219
226
|
return false;
|
|
220
227
|
}
|
|
221
228
|
else if (this.shouldOptOut()) {
|
|
222
|
-
if (this.
|
|
223
|
-
this.loggerProvider.log("Opting session ".concat(this.
|
|
229
|
+
if (this.identifiers.sessionId) {
|
|
230
|
+
this.loggerProvider.log("Opting session ".concat(this.identifiers.sessionId, " out of recording due to optOut config."));
|
|
224
231
|
}
|
|
225
232
|
return false;
|
|
226
233
|
}
|
|
227
|
-
else if (!this.
|
|
234
|
+
else if (!this.identifiers.sessionId) {
|
|
228
235
|
this.loggerProvider.warn("Session is not being recorded due to lack of session id.");
|
|
229
236
|
return false;
|
|
230
237
|
}
|
|
231
|
-
var isInSample = isSessionInSample(this.
|
|
238
|
+
var isInSample = isSessionInSample(this.identifiers.sessionId, this.config.sampleRate);
|
|
232
239
|
if (!isInSample) {
|
|
233
|
-
this.loggerProvider.log("Opting session ".concat(this.
|
|
240
|
+
this.loggerProvider.log("Opting session ".concat(this.identifiers.sessionId, " out of recording due to sample rate."));
|
|
234
241
|
}
|
|
235
242
|
return isInSample;
|
|
236
243
|
};
|
|
@@ -246,7 +253,7 @@ var SessionReplay = /** @class */ (function () {
|
|
|
246
253
|
var seq = storedSequences[storedSeqId];
|
|
247
254
|
var numericSeqId = parseInt(storedSeqId, 10);
|
|
248
255
|
var numericSessionId = parseInt(sessionId, 10);
|
|
249
|
-
if (numericSessionId === ((_a = this.
|
|
256
|
+
if (numericSessionId === ((_a = this.identifiers) === null || _a === void 0 ? void 0 : _a.sessionId) && numericSeqId === this.currentSequenceId) {
|
|
250
257
|
continue;
|
|
251
258
|
}
|
|
252
259
|
if (seq.events && seq.events.length && seq.status === RecordingStatus.RECORDING) {
|
|
@@ -263,7 +270,7 @@ var SessionReplay = /** @class */ (function () {
|
|
|
263
270
|
var _this = this;
|
|
264
271
|
var _a;
|
|
265
272
|
var shouldRecord = this.getShouldRecord();
|
|
266
|
-
var sessionId = (_a = this.
|
|
273
|
+
var sessionId = (_a = this.identifiers) === null || _a === void 0 ? void 0 : _a.sessionId;
|
|
267
274
|
if (!shouldRecord || !sessionId) {
|
|
268
275
|
return;
|
|
269
276
|
}
|
|
@@ -276,7 +283,7 @@ var SessionReplay = /** @class */ (function () {
|
|
|
276
283
|
}
|
|
277
284
|
var eventString = JSON.stringify(event);
|
|
278
285
|
var shouldSplit = _this.shouldSplitEventsList(eventString);
|
|
279
|
-
if (shouldSplit) {
|
|
286
|
+
if (shouldSplit && _this.config) {
|
|
280
287
|
_this.sendEventsList({
|
|
281
288
|
events: _this.events,
|
|
282
289
|
sequenceId: _this.currentSequenceId,
|
|
@@ -286,7 +293,8 @@ var SessionReplay = /** @class */ (function () {
|
|
|
286
293
|
_this.currentSequenceId++;
|
|
287
294
|
}
|
|
288
295
|
_this.events.push(eventString);
|
|
289
|
-
|
|
296
|
+
_this.sessionIDBStore &&
|
|
297
|
+
void _this.sessionIDBStore.storeEventsForSession(_this.events, _this.currentSequenceId, sessionId);
|
|
290
298
|
},
|
|
291
299
|
packFn: pack,
|
|
292
300
|
maskAllInputs: true,
|
|
@@ -305,94 +313,22 @@ var SessionReplay = /** @class */ (function () {
|
|
|
305
313
|
};
|
|
306
314
|
SessionReplay.prototype.sendEventsList = function (_a) {
|
|
307
315
|
var events = _a.events, sequenceId = _a.sequenceId, sessionId = _a.sessionId;
|
|
308
|
-
this.
|
|
316
|
+
if (!this.config || !this.sessionIDBStore) {
|
|
317
|
+
this.loggerProvider.error("Session is not being recorded due to lack of config, please call sessionReplay.init.");
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
this.trackDestination.sendEventsList({
|
|
309
321
|
events: events,
|
|
310
322
|
sequenceId: sequenceId,
|
|
311
|
-
attempts: 0,
|
|
312
|
-
timeout: 0,
|
|
313
323
|
sessionId: sessionId,
|
|
324
|
+
flushMaxRetries: this.config.flushMaxRetries,
|
|
325
|
+
apiKey: this.config.apiKey,
|
|
326
|
+
deviceId: this.getDeviceId(),
|
|
327
|
+
sampleRate: this.config.sampleRate,
|
|
328
|
+
serverZone: this.config.serverZone,
|
|
329
|
+
onComplete: this.sessionIDBStore.cleanUpSessionEventsStore.bind(this.sessionIDBStore),
|
|
314
330
|
});
|
|
315
331
|
};
|
|
316
|
-
SessionReplay.prototype.addToQueue = function () {
|
|
317
|
-
var _this = this;
|
|
318
|
-
var list = [];
|
|
319
|
-
for (var _i = 0; _i < arguments.length; _i++) {
|
|
320
|
-
list[_i] = arguments[_i];
|
|
321
|
-
}
|
|
322
|
-
var tryable = list.filter(function (context) {
|
|
323
|
-
var _a;
|
|
324
|
-
if (context.attempts < (((_a = _this.config) === null || _a === void 0 ? void 0 : _a.flushMaxRetries) || 0)) {
|
|
325
|
-
context.attempts += 1;
|
|
326
|
-
return true;
|
|
327
|
-
}
|
|
328
|
-
_this.completeRequest({
|
|
329
|
-
context: context,
|
|
330
|
-
err: "".concat(MAX_RETRIES_EXCEEDED_MESSAGE, ", batch sequence id, ").concat(context.sequenceId),
|
|
331
|
-
});
|
|
332
|
-
return false;
|
|
333
|
-
});
|
|
334
|
-
tryable.forEach(function (context) {
|
|
335
|
-
_this.queue = _this.queue.concat(context);
|
|
336
|
-
if (context.timeout === 0) {
|
|
337
|
-
_this.schedule(0);
|
|
338
|
-
return;
|
|
339
|
-
}
|
|
340
|
-
setTimeout(function () {
|
|
341
|
-
context.timeout = 0;
|
|
342
|
-
_this.schedule(0);
|
|
343
|
-
}, context.timeout);
|
|
344
|
-
});
|
|
345
|
-
};
|
|
346
|
-
SessionReplay.prototype.schedule = function (timeout) {
|
|
347
|
-
var _this = this;
|
|
348
|
-
if (this.scheduled)
|
|
349
|
-
return;
|
|
350
|
-
this.scheduled = setTimeout(function () {
|
|
351
|
-
void _this.flush(true).then(function () {
|
|
352
|
-
if (_this.queue.length > 0) {
|
|
353
|
-
_this.schedule(timeout);
|
|
354
|
-
}
|
|
355
|
-
});
|
|
356
|
-
}, timeout);
|
|
357
|
-
};
|
|
358
|
-
SessionReplay.prototype.flush = function (useRetry) {
|
|
359
|
-
if (useRetry === void 0) { useRetry = false; }
|
|
360
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
361
|
-
var list, later;
|
|
362
|
-
var _this = this;
|
|
363
|
-
return __generator(this, function (_a) {
|
|
364
|
-
switch (_a.label) {
|
|
365
|
-
case 0:
|
|
366
|
-
list = [];
|
|
367
|
-
later = [];
|
|
368
|
-
this.queue.forEach(function (context) { return (context.timeout === 0 ? list.push(context) : later.push(context)); });
|
|
369
|
-
this.queue = later;
|
|
370
|
-
if (this.scheduled) {
|
|
371
|
-
clearTimeout(this.scheduled);
|
|
372
|
-
this.scheduled = null;
|
|
373
|
-
}
|
|
374
|
-
return [4 /*yield*/, Promise.all(list.map(function (context) { return _this.send(context, useRetry); }))];
|
|
375
|
-
case 1:
|
|
376
|
-
_a.sent();
|
|
377
|
-
return [2 /*return*/];
|
|
378
|
-
}
|
|
379
|
-
});
|
|
380
|
-
});
|
|
381
|
-
};
|
|
382
|
-
SessionReplay.prototype.getSampleRate = function () {
|
|
383
|
-
var _a;
|
|
384
|
-
return ((_a = this.config) === null || _a === void 0 ? void 0 : _a.sampleRate) || DEFAULT_SAMPLE_RATE;
|
|
385
|
-
};
|
|
386
|
-
SessionReplay.prototype.getServerUrl = function () {
|
|
387
|
-
var _a, _b;
|
|
388
|
-
if (((_a = this.config) === null || _a === void 0 ? void 0 : _a.serverZone) === ServerZone.STAGING) {
|
|
389
|
-
return SESSION_REPLAY_STAGING_SERVER_URL;
|
|
390
|
-
}
|
|
391
|
-
if (((_b = this.config) === null || _b === void 0 ? void 0 : _b.serverZone) === ServerZone.EU) {
|
|
392
|
-
return SESSION_REPLAY_EU_SERVER_URL;
|
|
393
|
-
}
|
|
394
|
-
return SESSION_REPLAY_SERVER_URL;
|
|
395
|
-
};
|
|
396
332
|
SessionReplay.prototype.getDeviceId = function () {
|
|
397
333
|
var _a, _b;
|
|
398
334
|
var identityStoreDeviceId;
|
|
@@ -400,209 +336,23 @@ var SessionReplay = /** @class */ (function () {
|
|
|
400
336
|
var identityStore = getAnalyticsConnector(this.config.instanceName).identityStore;
|
|
401
337
|
identityStoreDeviceId = identityStore.getIdentity().deviceId;
|
|
402
338
|
}
|
|
403
|
-
return identityStoreDeviceId || ((_b = this.
|
|
339
|
+
return identityStoreDeviceId || ((_b = this.identifiers) === null || _b === void 0 ? void 0 : _b.deviceId);
|
|
404
340
|
};
|
|
405
341
|
SessionReplay.prototype.getSessionId = function () {
|
|
406
342
|
var _a;
|
|
407
|
-
return (_a = this.
|
|
343
|
+
return (_a = this.identifiers) === null || _a === void 0 ? void 0 : _a.sessionId;
|
|
408
344
|
};
|
|
409
|
-
SessionReplay.prototype.
|
|
410
|
-
|
|
411
|
-
if (useRetry === void 0) { useRetry = true; }
|
|
412
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
413
|
-
var apiKey, deviceId, url, version, sampleRate, urlParams, payload, options, server_url, res, responseBody, e_1;
|
|
414
|
-
return __generator(this, function (_b) {
|
|
415
|
-
switch (_b.label) {
|
|
416
|
-
case 0:
|
|
417
|
-
apiKey = (_a = this.config) === null || _a === void 0 ? void 0 : _a.apiKey;
|
|
418
|
-
if (!apiKey) {
|
|
419
|
-
return [2 /*return*/, this.completeRequest({ context: context, err: MISSING_API_KEY_MESSAGE })];
|
|
420
|
-
}
|
|
421
|
-
deviceId = this.getDeviceId();
|
|
422
|
-
if (!deviceId) {
|
|
423
|
-
return [2 /*return*/, this.completeRequest({ context: context, err: MISSING_DEVICE_ID_MESSAGE })];
|
|
424
|
-
}
|
|
425
|
-
url = getCurrentUrl();
|
|
426
|
-
version = VERSION;
|
|
427
|
-
sampleRate = this.getSampleRate();
|
|
428
|
-
urlParams = new URLSearchParams({
|
|
429
|
-
device_id: deviceId,
|
|
430
|
-
session_id: "".concat(context.sessionId),
|
|
431
|
-
seq_number: "".concat(context.sequenceId),
|
|
432
|
-
});
|
|
433
|
-
payload = {
|
|
434
|
-
version: 1,
|
|
435
|
-
events: context.events,
|
|
436
|
-
};
|
|
437
|
-
_b.label = 1;
|
|
438
|
-
case 1:
|
|
439
|
-
_b.trys.push([1, 3, , 4]);
|
|
440
|
-
options = {
|
|
441
|
-
headers: {
|
|
442
|
-
'Content-Type': 'application/json',
|
|
443
|
-
Accept: '*/*',
|
|
444
|
-
Authorization: "Bearer ".concat(apiKey),
|
|
445
|
-
'X-Client-Version': version,
|
|
446
|
-
'X-Client-Url': url,
|
|
447
|
-
'X-Client-Sample-Rate': "".concat(sampleRate),
|
|
448
|
-
},
|
|
449
|
-
body: JSON.stringify(payload),
|
|
450
|
-
method: 'POST',
|
|
451
|
-
};
|
|
452
|
-
server_url = "".concat(this.getServerUrl(), "?").concat(urlParams.toString());
|
|
453
|
-
return [4 /*yield*/, fetch(server_url, options)];
|
|
454
|
-
case 2:
|
|
455
|
-
res = _b.sent();
|
|
456
|
-
if (res === null) {
|
|
457
|
-
this.completeRequest({ context: context, err: UNEXPECTED_ERROR_MESSAGE });
|
|
458
|
-
return [2 /*return*/];
|
|
459
|
-
}
|
|
460
|
-
if (!useRetry) {
|
|
461
|
-
responseBody = '';
|
|
462
|
-
try {
|
|
463
|
-
responseBody = JSON.stringify(res.body, null, 2);
|
|
464
|
-
}
|
|
465
|
-
catch (_c) {
|
|
466
|
-
// to avoid crash, but don't care about the error, add comment to avoid empty block lint error
|
|
467
|
-
}
|
|
468
|
-
this.completeRequest({ context: context, success: "".concat(res.status, ": ").concat(responseBody) });
|
|
469
|
-
}
|
|
470
|
-
else {
|
|
471
|
-
this.handleReponse(res.status, context);
|
|
472
|
-
}
|
|
473
|
-
return [3 /*break*/, 4];
|
|
474
|
-
case 3:
|
|
475
|
-
e_1 = _b.sent();
|
|
476
|
-
this.completeRequest({ context: context, err: e_1 });
|
|
477
|
-
return [3 /*break*/, 4];
|
|
478
|
-
case 4: return [2 /*return*/];
|
|
479
|
-
}
|
|
480
|
-
});
|
|
481
|
-
});
|
|
482
|
-
};
|
|
483
|
-
SessionReplay.prototype.handleReponse = function (status, context) {
|
|
484
|
-
var parsedStatus = new BaseTransport().buildStatus(status);
|
|
485
|
-
switch (parsedStatus) {
|
|
486
|
-
case Status.Success:
|
|
487
|
-
this.handleSuccessResponse(context);
|
|
488
|
-
break;
|
|
489
|
-
case Status.Failed:
|
|
490
|
-
this.handleOtherResponse(context);
|
|
491
|
-
break;
|
|
492
|
-
default:
|
|
493
|
-
this.completeRequest({ context: context, err: UNEXPECTED_NETWORK_ERROR_MESSAGE });
|
|
494
|
-
}
|
|
495
|
-
};
|
|
496
|
-
SessionReplay.prototype.handleSuccessResponse = function (context) {
|
|
497
|
-
this.completeRequest({ context: context, success: getSuccessMessage(context.sessionId) });
|
|
498
|
-
};
|
|
499
|
-
SessionReplay.prototype.handleOtherResponse = function (context) {
|
|
500
|
-
this.addToQueue(__assign(__assign({}, context), { timeout: context.attempts * this.retryTimeout }));
|
|
501
|
-
};
|
|
502
|
-
SessionReplay.prototype.getAllSessionEventsFromStore = function () {
|
|
503
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
504
|
-
var storedReplaySessionContexts, e_2;
|
|
505
|
-
return __generator(this, function (_a) {
|
|
506
|
-
switch (_a.label) {
|
|
507
|
-
case 0:
|
|
508
|
-
_a.trys.push([0, 2, , 3]);
|
|
509
|
-
return [4 /*yield*/, IDBKeyVal.get(this.storageKey)];
|
|
510
|
-
case 1:
|
|
511
|
-
storedReplaySessionContexts = _a.sent();
|
|
512
|
-
return [2 /*return*/, storedReplaySessionContexts];
|
|
513
|
-
case 2:
|
|
514
|
-
e_2 = _a.sent();
|
|
515
|
-
this.loggerProvider.warn("".concat(STORAGE_FAILURE, ": ").concat(e_2));
|
|
516
|
-
return [3 /*break*/, 3];
|
|
517
|
-
case 3: return [2 /*return*/, undefined];
|
|
518
|
-
}
|
|
519
|
-
});
|
|
520
|
-
});
|
|
521
|
-
};
|
|
522
|
-
SessionReplay.prototype.storeEventsForSession = function (events, sequenceId, sessionId) {
|
|
523
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
524
|
-
var e_3;
|
|
525
|
-
return __generator(this, function (_a) {
|
|
526
|
-
switch (_a.label) {
|
|
527
|
-
case 0:
|
|
528
|
-
_a.trys.push([0, 2, , 3]);
|
|
529
|
-
return [4 /*yield*/, IDBKeyVal.update(this.storageKey, function (sessionMap) {
|
|
530
|
-
var _a, _b;
|
|
531
|
-
if (sessionMap === void 0) { sessionMap = {}; }
|
|
532
|
-
var session = sessionMap[sessionId] || __assign({}, defaultSessionStore);
|
|
533
|
-
session.currentSequenceId = sequenceId;
|
|
534
|
-
var currentSequence = (session.sessionSequences && session.sessionSequences[sequenceId]) || {};
|
|
535
|
-
currentSequence.events = events;
|
|
536
|
-
currentSequence.status = RecordingStatus.RECORDING;
|
|
537
|
-
return __assign(__assign({}, sessionMap), (_a = {}, _a[sessionId] = __assign(__assign({}, session), { sessionSequences: __assign(__assign({}, session.sessionSequences), (_b = {}, _b[sequenceId] = currentSequence, _b)) }), _a));
|
|
538
|
-
})];
|
|
539
|
-
case 1:
|
|
540
|
-
_a.sent();
|
|
541
|
-
return [3 /*break*/, 3];
|
|
542
|
-
case 2:
|
|
543
|
-
e_3 = _a.sent();
|
|
544
|
-
this.loggerProvider.warn("".concat(STORAGE_FAILURE, ": ").concat(e_3));
|
|
545
|
-
return [3 /*break*/, 3];
|
|
546
|
-
case 3: return [2 /*return*/];
|
|
547
|
-
}
|
|
548
|
-
});
|
|
549
|
-
});
|
|
550
|
-
};
|
|
551
|
-
SessionReplay.prototype.cleanUpSessionEventsStore = function (sessionId, sequenceId) {
|
|
345
|
+
SessionReplay.prototype.flush = function (useRetry) {
|
|
346
|
+
if (useRetry === void 0) { useRetry = false; }
|
|
552
347
|
return __awaiter(this, void 0, void 0, function () {
|
|
553
|
-
var e_4;
|
|
554
348
|
return __generator(this, function (_a) {
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
_a.trys.push([0, 2, , 3]);
|
|
558
|
-
return [4 /*yield*/, IDBKeyVal.update(this.storageKey, function (sessionMap) {
|
|
559
|
-
if (sessionMap === void 0) { sessionMap = {}; }
|
|
560
|
-
var session = sessionMap[sessionId];
|
|
561
|
-
var sequenceToUpdate = (session === null || session === void 0 ? void 0 : session.sessionSequences) && session.sessionSequences[sequenceId];
|
|
562
|
-
if (!sequenceToUpdate) {
|
|
563
|
-
return sessionMap;
|
|
564
|
-
}
|
|
565
|
-
sequenceToUpdate.events = [];
|
|
566
|
-
sequenceToUpdate.status = RecordingStatus.SENT;
|
|
567
|
-
// Delete sent sequences for current session
|
|
568
|
-
Object.entries(session.sessionSequences).forEach(function (_a) {
|
|
569
|
-
var _b = __read(_a, 2), storedSeqId = _b[0], sequence = _b[1];
|
|
570
|
-
var numericStoredSeqId = parseInt(storedSeqId, 10);
|
|
571
|
-
if (sequence.status === RecordingStatus.SENT && sequenceId !== numericStoredSeqId) {
|
|
572
|
-
delete session.sessionSequences[numericStoredSeqId];
|
|
573
|
-
}
|
|
574
|
-
});
|
|
575
|
-
// Delete any sessions that are older than 3 days
|
|
576
|
-
Object.keys(sessionMap).forEach(function (sessionId) {
|
|
577
|
-
var numericSessionId = parseInt(sessionId, 10);
|
|
578
|
-
if (Date.now() - numericSessionId >= MAX_IDB_STORAGE_LENGTH) {
|
|
579
|
-
delete sessionMap[numericSessionId];
|
|
580
|
-
}
|
|
581
|
-
});
|
|
582
|
-
return sessionMap;
|
|
583
|
-
})];
|
|
584
|
-
case 1:
|
|
585
|
-
_a.sent();
|
|
586
|
-
return [3 /*break*/, 3];
|
|
587
|
-
case 2:
|
|
588
|
-
e_4 = _a.sent();
|
|
589
|
-
this.loggerProvider.warn("".concat(STORAGE_FAILURE, ": ").concat(e_4));
|
|
590
|
-
return [3 /*break*/, 3];
|
|
591
|
-
case 3: return [2 /*return*/];
|
|
349
|
+
if (this.trackDestination) {
|
|
350
|
+
return [2 /*return*/, this.trackDestination.flush(useRetry)];
|
|
592
351
|
}
|
|
352
|
+
return [2 /*return*/];
|
|
593
353
|
});
|
|
594
354
|
});
|
|
595
355
|
};
|
|
596
|
-
SessionReplay.prototype.completeRequest = function (_a) {
|
|
597
|
-
var context = _a.context, err = _a.err, success = _a.success;
|
|
598
|
-
context.sessionId && this.cleanUpSessionEventsStore(context.sessionId, context.sequenceId);
|
|
599
|
-
if (err) {
|
|
600
|
-
this.loggerProvider.warn(err);
|
|
601
|
-
}
|
|
602
|
-
else if (success) {
|
|
603
|
-
this.loggerProvider.log(success);
|
|
604
|
-
}
|
|
605
|
-
};
|
|
606
356
|
SessionReplay.prototype.shutdown = function () {
|
|
607
357
|
var globalScope = getGlobalScope();
|
|
608
358
|
if (globalScope) {
|