@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.
Files changed (63) hide show
  1. package/lib/cjs/config.d.ts +0 -3
  2. package/lib/cjs/config.d.ts.map +1 -1
  3. package/lib/cjs/config.js +0 -9
  4. package/lib/cjs/config.js.map +1 -1
  5. package/lib/cjs/identifiers.d.ts +9 -0
  6. package/lib/cjs/identifiers.d.ts.map +1 -0
  7. package/lib/cjs/identifiers.js +18 -0
  8. package/lib/cjs/identifiers.js.map +1 -0
  9. package/lib/cjs/session-idb-store.d.ts +15 -0
  10. package/lib/cjs/session-idb-store.d.ts.map +1 -0
  11. package/lib/cjs/session-idb-store.js +107 -0
  12. package/lib/cjs/session-idb-store.js.map +1 -0
  13. package/lib/cjs/session-replay.d.ts +6 -23
  14. package/lib/cjs/session-replay.d.ts.map +1 -1
  15. package/lib/cjs/session-replay.js +62 -312
  16. package/lib/cjs/session-replay.js.map +1 -1
  17. package/lib/cjs/track-destination.d.ts +28 -0
  18. package/lib/cjs/track-destination.d.ts.map +1 -0
  19. package/lib/cjs/track-destination.js +204 -0
  20. package/lib/cjs/track-destination.js.map +1 -0
  21. package/lib/cjs/typings/session-replay.d.ts +27 -7
  22. package/lib/cjs/typings/session-replay.d.ts.map +1 -1
  23. package/lib/cjs/typings/session-replay.js.map +1 -1
  24. package/lib/esm/config.d.ts +0 -3
  25. package/lib/esm/config.d.ts.map +1 -1
  26. package/lib/esm/config.js +0 -9
  27. package/lib/esm/config.js.map +1 -1
  28. package/lib/esm/identifiers.d.ts +9 -0
  29. package/lib/esm/identifiers.d.ts.map +1 -0
  30. package/lib/esm/identifiers.js +16 -0
  31. package/lib/esm/identifiers.js.map +1 -0
  32. package/lib/esm/session-idb-store.d.ts +15 -0
  33. package/lib/esm/session-idb-store.d.ts.map +1 -0
  34. package/lib/esm/session-idb-store.js +105 -0
  35. package/lib/esm/session-idb-store.js.map +1 -0
  36. package/lib/esm/session-replay.d.ts +6 -23
  37. package/lib/esm/session-replay.d.ts.map +1 -1
  38. package/lib/esm/session-replay.js +66 -316
  39. package/lib/esm/session-replay.js.map +1 -1
  40. package/lib/esm/track-destination.d.ts +28 -0
  41. package/lib/esm/track-destination.d.ts.map +1 -0
  42. package/lib/esm/track-destination.js +202 -0
  43. package/lib/esm/track-destination.js.map +1 -0
  44. package/lib/esm/typings/session-replay.d.ts +27 -7
  45. package/lib/esm/typings/session-replay.d.ts.map +1 -1
  46. package/lib/esm/typings/session-replay.js.map +1 -1
  47. package/lib/scripts/amplitude-min.js +1 -1
  48. package/lib/scripts/amplitude-min.js.gz +0 -0
  49. package/lib/scripts/amplitude-min.umd.js +1 -1
  50. package/lib/scripts/amplitude-min.umd.js.gz +0 -0
  51. package/lib/scripts/config.d.ts +0 -3
  52. package/lib/scripts/config.d.ts.map +1 -1
  53. package/lib/scripts/identifiers.d.ts +9 -0
  54. package/lib/scripts/identifiers.d.ts.map +1 -0
  55. package/lib/scripts/session-idb-store.d.ts +15 -0
  56. package/lib/scripts/session-idb-store.d.ts.map +1 -0
  57. package/lib/scripts/session-replay.d.ts +6 -23
  58. package/lib/scripts/session-replay.d.ts.map +1 -1
  59. package/lib/scripts/track-destination.d.ts +28 -0
  60. package/lib/scripts/track-destination.d.ts.map +1 -0
  61. package/lib/scripts/typings/session-replay.d.ts +27 -7
  62. package/lib/scripts/typings/session-replay.d.ts.map +1 -1
  63. package/package.json +2 -2
@@ -1,25 +1,20 @@
1
- import { __assign, __awaiter, __generator, __read } from "tslib";
1
+ import { __awaiter, __generator } from "tslib";
2
2
  import { getAnalyticsConnector, getGlobalScope } from '@amplitude/analytics-client-common';
3
- import { BaseTransport, Logger, returnWrapper } from '@amplitude/analytics-core';
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, DEFAULT_SAMPLE_RATE, DEFAULT_SESSION_REPLAY_PROPERTY, MASK_TEXT_CLASS, MAX_EVENT_LIST_SIZE_IN_BYTES, MAX_IDB_STORAGE_LENGTH, MAX_INTERVAL, MIN_INTERVAL, SESSION_REPLAY_DEBUG_PROPERTY, SESSION_REPLAY_EU_URL as SESSION_REPLAY_EU_SERVER_URL, SESSION_REPLAY_SERVER_URL, SESSION_REPLAY_STAGING_URL as SESSION_REPLAY_STAGING_SERVER_URL, STORAGE_PREFIX, defaultSessionStore, } from './constants';
9
- import { generateHashCode, generateSessionReplayId, getCurrentUrl, isSessionInSample, maskInputFn } from './helpers';
10
- import { MAX_RETRIES_EXCEEDED_MESSAGE, MISSING_API_KEY_MESSAGE, MISSING_DEVICE_ID_MESSAGE, STORAGE_FAILURE, UNEXPECTED_ERROR_MESSAGE, UNEXPECTED_NETWORK_ERROR_MESSAGE, getSuccessMessage, } from './messages';
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.config) {
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.config.deviceId = deviceId;
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.config.sessionReplayId = generateSessionReplayId(sessionId, deviceIdForReplayId);
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.config.sessionId);
100
- this.config.sessionId = sessionId;
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.config.sessionReplayId ? this.config.sessionReplayId : null,
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.config) === null || _a === void 0 ? void 0 : _a.sessionId);
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 (_b) {
160
- switch (_b.label) {
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.config) === null || _a === void 0 ? void 0 : _a.sessionId)) {
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
- return [4 /*yield*/, this.getAllSessionEventsFromStore()];
169
+ _b = this.sessionIDBStore;
170
+ if (!_b) return [3 /*break*/, 2];
171
+ return [4 /*yield*/, this.sessionIDBStore.getAllSessionDataFromStore()];
168
172
  case 1:
169
- storedReplaySessions = _b.sent();
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.config.sessionId];
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.config.sessionId) {
217
- this.loggerProvider.log("Session ".concat(this.config.sessionId, " temporarily not recording due to lack of browser focus."));
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.config.sessionId) {
223
- this.loggerProvider.log("Opting session ".concat(this.config.sessionId, " out of recording due to optOut config."));
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.config.sessionId) {
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.config.sessionId, this.getSampleRate());
238
+ var isInSample = isSessionInSample(this.identifiers.sessionId, this.config.sampleRate);
232
239
  if (!isInSample) {
233
- this.loggerProvider.log("Opting session ".concat(this.config.sessionId, " out of recording due to sample rate."));
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.config) === null || _a === void 0 ? void 0 : _a.sessionId) && numericSeqId === this.currentSequenceId) {
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.config) === null || _a === void 0 ? void 0 : _a.sessionId;
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
- void _this.storeEventsForSession(_this.events, _this.currentSequenceId, sessionId);
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.addToQueue({
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.config) === null || _b === void 0 ? void 0 : _b.deviceId);
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.config) === null || _a === void 0 ? void 0 : _a.sessionId;
343
+ return (_a = this.identifiers) === null || _a === void 0 ? void 0 : _a.sessionId;
408
344
  };
409
- SessionReplay.prototype.send = function (context, useRetry) {
410
- var _a;
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
- switch (_a.label) {
556
- case 0:
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) {