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