@amplitude/session-replay-browser 1.2.1 → 1.2.3

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 (73) 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/events-manager.d.ts +49 -0
  6. package/lib/cjs/events-manager.d.ts.map +1 -0
  7. package/lib/cjs/events-manager.js +157 -0
  8. package/lib/cjs/events-manager.js.map +1 -0
  9. package/lib/cjs/identifiers.d.ts +9 -0
  10. package/lib/cjs/identifiers.d.ts.map +1 -0
  11. package/lib/cjs/identifiers.js +18 -0
  12. package/lib/cjs/identifiers.js.map +1 -0
  13. package/lib/cjs/session-idb-store.d.ts +15 -0
  14. package/lib/cjs/session-idb-store.d.ts.map +1 -0
  15. package/lib/cjs/session-idb-store.js +107 -0
  16. package/lib/cjs/session-idb-store.js.map +1 -0
  17. package/lib/cjs/session-replay.d.ts +5 -41
  18. package/lib/cjs/session-replay.d.ts.map +1 -1
  19. package/lib/cjs/session-replay.js +55 -406
  20. package/lib/cjs/session-replay.js.map +1 -1
  21. package/lib/cjs/track-destination.d.ts +27 -0
  22. package/lib/cjs/track-destination.d.ts.map +1 -0
  23. package/lib/cjs/track-destination.js +201 -0
  24. package/lib/cjs/track-destination.js.map +1 -0
  25. package/lib/cjs/typings/session-replay.d.ts +45 -7
  26. package/lib/cjs/typings/session-replay.d.ts.map +1 -1
  27. package/lib/cjs/typings/session-replay.js.map +1 -1
  28. package/lib/esm/config.d.ts +0 -3
  29. package/lib/esm/config.d.ts.map +1 -1
  30. package/lib/esm/config.js +0 -9
  31. package/lib/esm/config.js.map +1 -1
  32. package/lib/esm/events-manager.d.ts +49 -0
  33. package/lib/esm/events-manager.d.ts.map +1 -0
  34. package/lib/esm/events-manager.js +155 -0
  35. package/lib/esm/events-manager.js.map +1 -0
  36. package/lib/esm/identifiers.d.ts +9 -0
  37. package/lib/esm/identifiers.d.ts.map +1 -0
  38. package/lib/esm/identifiers.js +16 -0
  39. package/lib/esm/identifiers.js.map +1 -0
  40. package/lib/esm/session-idb-store.d.ts +15 -0
  41. package/lib/esm/session-idb-store.d.ts.map +1 -0
  42. package/lib/esm/session-idb-store.js +105 -0
  43. package/lib/esm/session-idb-store.js.map +1 -0
  44. package/lib/esm/session-replay.d.ts +5 -41
  45. package/lib/esm/session-replay.d.ts.map +1 -1
  46. package/lib/esm/session-replay.js +59 -410
  47. package/lib/esm/session-replay.js.map +1 -1
  48. package/lib/esm/track-destination.d.ts +27 -0
  49. package/lib/esm/track-destination.d.ts.map +1 -0
  50. package/lib/esm/track-destination.js +199 -0
  51. package/lib/esm/track-destination.js.map +1 -0
  52. package/lib/esm/typings/session-replay.d.ts +45 -7
  53. package/lib/esm/typings/session-replay.d.ts.map +1 -1
  54. package/lib/esm/typings/session-replay.js.map +1 -1
  55. package/lib/scripts/amplitude-min.js +1 -1
  56. package/lib/scripts/amplitude-min.js.gz +0 -0
  57. package/lib/scripts/amplitude-min.umd.js +1 -1
  58. package/lib/scripts/amplitude-min.umd.js.gz +0 -0
  59. package/lib/scripts/config.d.ts +0 -3
  60. package/lib/scripts/config.d.ts.map +1 -1
  61. package/lib/scripts/events-manager.d.ts +49 -0
  62. package/lib/scripts/events-manager.d.ts.map +1 -0
  63. package/lib/scripts/identifiers.d.ts +9 -0
  64. package/lib/scripts/identifiers.d.ts.map +1 -0
  65. package/lib/scripts/session-idb-store.d.ts +15 -0
  66. package/lib/scripts/session-idb-store.d.ts.map +1 -0
  67. package/lib/scripts/session-replay.d.ts +5 -41
  68. package/lib/scripts/session-replay.d.ts.map +1 -1
  69. package/lib/scripts/track-destination.d.ts +27 -0
  70. package/lib/scripts/track-destination.d.ts.map +1 -0
  71. package/lib/scripts/typings/session-replay.d.ts +45 -7
  72. package/lib/scripts/typings/session-replay.d.ts.map +1 -1
  73. package/package.json +2 -2
@@ -3,54 +3,23 @@ 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");
9
+ var events_manager_1 = require("./events-manager");
11
10
  var helpers_1 = require("./helpers");
12
- var messages_1 = require("./messages");
13
- var session_replay_1 = require("./typings/session-replay");
14
- var version_1 = require("./version");
11
+ var identifiers_1 = require("./identifiers");
15
12
  var SessionReplay = /** @class */ (function () {
16
13
  function SessionReplay() {
17
14
  var _this = this;
18
15
  this.name = '@amplitude/session-replay-browser';
19
- this.storageKey = '';
20
- this.retryTimeout = 1000;
21
- this.events = [];
22
- this.currentSequenceId = 0;
23
- this.scheduled = null;
24
- this.queue = [];
25
16
  this.stopRecordingEvents = null;
26
- this.maxPersistedEventsSize = constants_1.MAX_EVENT_LIST_SIZE_IN_BYTES;
27
- this.interval = constants_1.MIN_INTERVAL;
28
- this.timeAtLastSend = null;
29
17
  this.blurListener = function () {
30
18
  _this.stopRecordingAndSendEvents();
31
19
  };
32
20
  this.focusListener = function () {
33
21
  void _this.initialize();
34
22
  };
35
- /**
36
- * Determines whether to send the events list to the backend and start a new
37
- * empty events list, based on the size of the list as well as the last time sent
38
- * @param nextEventString
39
- * @returns boolean
40
- */
41
- this.shouldSplitEventsList = function (nextEventString) {
42
- var sizeOfNextEvent = new Blob([nextEventString]).size;
43
- var sizeOfEventsList = new Blob(_this.events).size;
44
- if (sizeOfEventsList + sizeOfNextEvent >= _this.maxPersistedEventsSize) {
45
- return true;
46
- }
47
- if (_this.timeAtLastSend !== null && Date.now() - _this.timeAtLastSend > _this.interval && _this.events.length) {
48
- _this.interval = Math.min(constants_1.MAX_INTERVAL, _this.interval + constants_1.MIN_INTERVAL);
49
- _this.timeAtLastSend = Date.now();
50
- return true;
51
- }
52
- return false;
53
- };
54
23
  this.loggerProvider = new analytics_core_1.Logger();
55
24
  }
56
25
  SessionReplay.prototype.init = function (apiKey, options) {
@@ -64,8 +33,11 @@ var SessionReplay = /** @class */ (function () {
64
33
  case 0:
65
34
  this.config = new config_1.SessionReplayConfig(apiKey, options);
66
35
  this.loggerProvider = this.config.loggerProvider;
36
+ this.identifiers = new identifiers_1.SessionIdentifiers(options, this.loggerProvider);
37
+ this.eventsManager = new events_manager_1.SessionReplayEventsManager({
38
+ config: this.config,
39
+ });
67
40
  this.loggerProvider.log('Installing @amplitude/session-replay-browser.');
68
- this.storageKey = "".concat(constants_1.STORAGE_PREFIX, "_").concat(this.config.apiKey.substring(0, 10));
69
41
  globalScope = (0, analytics_client_common_1.getGlobalScope)();
70
42
  if (globalScope) {
71
43
  globalScope.addEventListener('blur', this.blurListener);
@@ -82,26 +54,25 @@ var SessionReplay = /** @class */ (function () {
82
54
  });
83
55
  };
84
56
  SessionReplay.prototype.setSessionId = function (sessionId, deviceId) {
85
- if (!this.config) {
57
+ if (!this.identifiers) {
86
58
  this.loggerProvider.error('Session replay init has not been called, cannot set session id.');
87
59
  return;
88
60
  }
89
61
  if (deviceId) {
90
- this.config.deviceId = deviceId;
62
+ this.identifiers.deviceId = deviceId;
91
63
  }
92
64
  // use a consistent device id.
93
65
  var deviceIdForReplayId = this.getDeviceId();
94
66
  if (sessionId && deviceIdForReplayId) {
95
- this.config.sessionReplayId = (0, helpers_1.generateSessionReplayId)(sessionId, deviceIdForReplayId);
67
+ this.identifiers.sessionReplayId = (0, helpers_1.generateSessionReplayId)(sessionId, deviceIdForReplayId);
96
68
  }
97
69
  else {
98
70
  this.loggerProvider.error('Must provide either session replay id or session id when starting a new session.');
99
71
  return;
100
72
  }
101
- this.stopRecordingAndSendEvents(this.config.sessionId);
102
- this.config.sessionId = sessionId;
103
- this.events = [];
104
- this.currentSequenceId = 0;
73
+ this.stopRecordingAndSendEvents(this.identifiers.sessionId);
74
+ this.identifiers.sessionId = sessionId;
75
+ this.eventsManager && this.eventsManager.resetSequence();
105
76
  this.recordEvents();
106
77
  };
107
78
  SessionReplay.prototype.getSessionReplayDebugPropertyValue = function () {
@@ -115,7 +86,7 @@ var SessionReplay = /** @class */ (function () {
115
86
  };
116
87
  SessionReplay.prototype.getSessionReplayProperties = function () {
117
88
  var _a;
118
- if (!this.config) {
89
+ if (!this.config || !this.identifiers) {
119
90
  this.loggerProvider.error('Session replay init has not been called, cannot get session recording properties.');
120
91
  return {};
121
92
  }
@@ -125,7 +96,7 @@ var SessionReplay = /** @class */ (function () {
125
96
  var shouldRecord = this.getShouldRecord(ignoreFocus);
126
97
  if (shouldRecord) {
127
98
  var eventProperties = (_a = {},
128
- _a[constants_1.DEFAULT_SESSION_REPLAY_PROPERTY] = this.config.sessionReplayId ? this.config.sessionReplayId : null,
99
+ _a[constants_1.DEFAULT_SESSION_REPLAY_PROPERTY] = this.identifiers.sessionReplayId ? this.identifiers.sessionReplayId : null,
129
100
  _a);
130
101
  if (this.config.debugMode) {
131
102
  eventProperties[constants_1.SESSION_REPLAY_DEBUG_PROPERTY] = this.getSessionReplayDebugPropertyValue();
@@ -144,54 +115,39 @@ var SessionReplay = /** @class */ (function () {
144
115
  var typedError = error;
145
116
  this.loggerProvider.warn("Error occurred while stopping recording: ".concat(typedError.toString()));
146
117
  }
147
- var sessionIdToSend = sessionId || ((_a = this.config) === null || _a === void 0 ? void 0 : _a.sessionId);
148
- if (this.events.length && sessionIdToSend) {
149
- this.sendEventsList({
150
- events: this.events,
151
- sequenceId: this.currentSequenceId,
152
- sessionId: sessionIdToSend,
153
- });
154
- }
118
+ var sessionIdToSend = sessionId || ((_a = this.identifiers) === null || _a === void 0 ? void 0 : _a.sessionId);
119
+ var deviceId = this.getDeviceId();
120
+ this.eventsManager &&
121
+ sessionIdToSend &&
122
+ deviceId &&
123
+ this.eventsManager.sendEvents({ sessionId: sessionIdToSend, deviceId: deviceId });
155
124
  };
156
125
  SessionReplay.prototype.initialize = function (shouldSendStoredEvents) {
157
126
  var _a;
158
127
  if (shouldSendStoredEvents === void 0) { shouldSendStoredEvents = false; }
159
128
  return tslib_1.__awaiter(this, void 0, void 0, function () {
160
- var storedReplaySessions, storedSequencesForSession, storedSeqId, lastSequence;
161
- return tslib_1.__generator(this, function (_b) {
162
- switch (_b.label) {
129
+ var deviceId, _b;
130
+ return tslib_1.__generator(this, function (_c) {
131
+ switch (_c.label) {
163
132
  case 0:
164
- this.timeAtLastSend = Date.now(); // Initialize this so we have a point of comparison when events are recorded
165
- if (!((_a = this.config) === null || _a === void 0 ? void 0 : _a.sessionId)) {
133
+ if (!((_a = this.identifiers) === null || _a === void 0 ? void 0 : _a.sessionId)) {
166
134
  this.loggerProvider.warn("Session is not being recorded due to lack of session id.");
167
135
  return [2 /*return*/];
168
136
  }
169
- return [4 /*yield*/, this.getAllSessionEventsFromStore()];
137
+ deviceId = this.getDeviceId();
138
+ _b = this.eventsManager &&
139
+ deviceId;
140
+ if (!_b) return [3 /*break*/, 2];
141
+ return [4 /*yield*/, this.eventsManager.initialize({
142
+ sessionId: this.identifiers.sessionId,
143
+ shouldSendStoredEvents: shouldSendStoredEvents,
144
+ deviceId: deviceId,
145
+ })];
170
146
  case 1:
171
- storedReplaySessions = _b.sent();
172
- // This resolves a timing issue when focus is fired multiple times in short succession,
173
- // we only want the rest of this function to run once. We can be sure that initialize has
174
- // already been called if this.stopRecordingEvents is defined
175
- if (this.stopRecordingEvents) {
176
- return [2 /*return*/];
177
- }
178
- storedSequencesForSession = storedReplaySessions && storedReplaySessions[this.config.sessionId];
179
- if (storedReplaySessions && storedSequencesForSession && storedSequencesForSession.sessionSequences) {
180
- storedSeqId = storedSequencesForSession.currentSequenceId;
181
- lastSequence = storedSequencesForSession.sessionSequences[storedSeqId];
182
- if (lastSequence && lastSequence.status !== session_replay_1.RecordingStatus.RECORDING) {
183
- this.currentSequenceId = storedSeqId + 1;
184
- this.events = [];
185
- }
186
- else {
187
- // Pick up recording where it was left off in another tab or window
188
- this.currentSequenceId = storedSeqId;
189
- this.events = (lastSequence === null || lastSequence === void 0 ? void 0 : lastSequence.events) || [];
190
- }
191
- }
192
- if (shouldSendStoredEvents && storedReplaySessions) {
193
- this.sendStoredEvents(storedReplaySessions);
194
- }
147
+ _b = (_c.sent());
148
+ _c.label = 2;
149
+ case 2:
150
+ _b;
195
151
  this.recordEvents();
196
152
  return [2 /*return*/];
197
153
  }
@@ -209,30 +165,30 @@ var SessionReplay = /** @class */ (function () {
209
165
  };
210
166
  SessionReplay.prototype.getShouldRecord = function (ignoreFocus) {
211
167
  if (ignoreFocus === void 0) { ignoreFocus = false; }
212
- if (!this.config) {
168
+ if (!this.identifiers || !this.config) {
213
169
  this.loggerProvider.error("Session is not being recorded due to lack of config, please call sessionReplay.init.");
214
170
  return false;
215
171
  }
216
172
  var globalScope = (0, analytics_client_common_1.getGlobalScope)();
217
173
  if (!ignoreFocus && globalScope && globalScope.document && !globalScope.document.hasFocus()) {
218
- if (this.config.sessionId) {
219
- this.loggerProvider.log("Session ".concat(this.config.sessionId, " temporarily not recording due to lack of browser focus."));
174
+ if (this.identifiers.sessionId) {
175
+ this.loggerProvider.log("Session ".concat(this.identifiers.sessionId, " temporarily not recording due to lack of browser focus."));
220
176
  }
221
177
  return false;
222
178
  }
223
179
  else if (this.shouldOptOut()) {
224
- if (this.config.sessionId) {
225
- this.loggerProvider.log("Opting session ".concat(this.config.sessionId, " out of recording due to optOut config."));
180
+ if (this.identifiers.sessionId) {
181
+ this.loggerProvider.log("Opting session ".concat(this.identifiers.sessionId, " out of recording due to optOut config."));
226
182
  }
227
183
  return false;
228
184
  }
229
- else if (!this.config.sessionId) {
185
+ else if (!this.identifiers.sessionId) {
230
186
  this.loggerProvider.warn("Session is not being recorded due to lack of session id.");
231
187
  return false;
232
188
  }
233
- var isInSample = (0, helpers_1.isSessionInSample)(this.config.sessionId, this.getSampleRate());
189
+ var isInSample = (0, helpers_1.isSessionInSample)(this.identifiers.sessionId, this.config.sampleRate);
234
190
  if (!isInSample) {
235
- this.loggerProvider.log("Opting session ".concat(this.config.sessionId, " out of recording due to sample rate."));
191
+ this.loggerProvider.log("Opting session ".concat(this.identifiers.sessionId, " out of recording due to sample rate."));
236
192
  }
237
193
  return isInSample;
238
194
  };
@@ -240,32 +196,11 @@ var SessionReplay = /** @class */ (function () {
240
196
  var _a, _b;
241
197
  return (_b = (_a = this.config) === null || _a === void 0 ? void 0 : _a.privacyConfig) === null || _b === void 0 ? void 0 : _b.blockSelector;
242
198
  };
243
- SessionReplay.prototype.sendStoredEvents = function (storedReplaySessions) {
244
- var _a;
245
- for (var sessionId in storedReplaySessions) {
246
- var storedSequences = storedReplaySessions[sessionId].sessionSequences;
247
- for (var storedSeqId in storedSequences) {
248
- var seq = storedSequences[storedSeqId];
249
- var numericSeqId = parseInt(storedSeqId, 10);
250
- var numericSessionId = parseInt(sessionId, 10);
251
- if (numericSessionId === ((_a = this.config) === null || _a === void 0 ? void 0 : _a.sessionId) && numericSeqId === this.currentSequenceId) {
252
- continue;
253
- }
254
- if (seq.events && seq.events.length && seq.status === session_replay_1.RecordingStatus.RECORDING) {
255
- this.sendEventsList({
256
- events: seq.events,
257
- sequenceId: numericSeqId,
258
- sessionId: numericSessionId,
259
- });
260
- }
261
- }
262
- }
263
- };
264
199
  SessionReplay.prototype.recordEvents = function () {
265
200
  var _this = this;
266
201
  var _a;
267
202
  var shouldRecord = this.getShouldRecord();
268
- var sessionId = (_a = this.config) === null || _a === void 0 ? void 0 : _a.sessionId;
203
+ var sessionId = (_a = this.identifiers) === null || _a === void 0 ? void 0 : _a.sessionId;
269
204
  if (!shouldRecord || !sessionId) {
270
205
  return;
271
206
  }
@@ -277,18 +212,8 @@ var SessionReplay = /** @class */ (function () {
277
212
  return;
278
213
  }
279
214
  var eventString = JSON.stringify(event);
280
- var shouldSplit = _this.shouldSplitEventsList(eventString);
281
- if (shouldSplit) {
282
- _this.sendEventsList({
283
- events: _this.events,
284
- sequenceId: _this.currentSequenceId,
285
- sessionId: sessionId,
286
- });
287
- _this.events = [];
288
- _this.currentSequenceId++;
289
- }
290
- _this.events.push(eventString);
291
- void _this.storeEventsForSession(_this.events, _this.currentSequenceId, sessionId);
215
+ var deviceId = _this.getDeviceId();
216
+ deviceId && _this.eventsManager && _this.eventsManager.addEvent({ event: eventString, sessionId: sessionId, deviceId: deviceId });
292
217
  },
293
218
  packFn: rrweb_1.pack,
294
219
  maskAllInputs: true,
@@ -305,96 +230,6 @@ var SessionReplay = /** @class */ (function () {
305
230
  },
306
231
  });
307
232
  };
308
- SessionReplay.prototype.sendEventsList = function (_a) {
309
- var events = _a.events, sequenceId = _a.sequenceId, sessionId = _a.sessionId;
310
- this.addToQueue({
311
- events: events,
312
- sequenceId: sequenceId,
313
- attempts: 0,
314
- timeout: 0,
315
- sessionId: sessionId,
316
- });
317
- };
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
233
  SessionReplay.prototype.getDeviceId = function () {
399
234
  var _a, _b;
400
235
  var identityStoreDeviceId;
@@ -402,209 +237,23 @@ var SessionReplay = /** @class */ (function () {
402
237
  var identityStore = (0, analytics_client_common_1.getAnalyticsConnector)(this.config.instanceName).identityStore;
403
238
  identityStoreDeviceId = identityStore.getIdentity().deviceId;
404
239
  }
405
- return identityStoreDeviceId || ((_b = this.config) === null || _b === void 0 ? void 0 : _b.deviceId);
240
+ return identityStoreDeviceId || ((_b = this.identifiers) === null || _b === void 0 ? void 0 : _b.deviceId);
406
241
  };
407
242
  SessionReplay.prototype.getSessionId = function () {
408
243
  var _a;
409
- return (_a = this.config) === null || _a === void 0 ? void 0 : _a.sessionId;
244
+ return (_a = this.identifiers) === null || _a === void 0 ? void 0 : _a.sessionId;
410
245
  };
411
- SessionReplay.prototype.send = function (context, useRetry) {
412
- var _a;
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) {
246
+ SessionReplay.prototype.flush = function (useRetry) {
247
+ if (useRetry === void 0) { useRetry = false; }
554
248
  return tslib_1.__awaiter(this, void 0, void 0, function () {
555
- var e_4;
556
249
  return tslib_1.__generator(this, function (_a) {
557
- switch (_a.label) {
558
- case 0:
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*/];
250
+ if (this.eventsManager) {
251
+ return [2 /*return*/, this.eventsManager.flush(useRetry)];
594
252
  }
253
+ return [2 /*return*/];
595
254
  });
596
255
  });
597
256
  };
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
257
  SessionReplay.prototype.shutdown = function () {
609
258
  var globalScope = (0, analytics_client_common_1.getGlobalScope)();
610
259
  if (globalScope) {