@amplitude/plugin-session-replay-browser
Advanced tools
Comparing version 0.1.3 to 0.2.0
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.sessionReplayPlugin = void 0; | ||
var tslib_1 = require("tslib"); | ||
var analytics_client_common_1 = require("@amplitude/analytics-client-common"); | ||
var analytics_core_1 = require("@amplitude/analytics-core"); | ||
@@ -10,2 +11,3 @@ var analytics_types_1 = require("@amplitude/analytics-types"); | ||
var messages_1 = require("./messages"); | ||
var session_replay_1 = require("./typings/session-replay"); | ||
var SESSION_REPLAY_SERVER_URL = 'https://api-secure.amplitude.com/sessions/track'; | ||
@@ -15,3 +17,3 @@ var STORAGE_PREFIX = "".concat(analytics_core_1.AMPLITUDE_PREFIX, "_replay_unsent"); | ||
var MAX_EVENT_LIST_SIZE_IN_BYTES = 20 * 1000000 - PAYLOAD_ESTIMATED_SIZE_IN_BYTES_WITHOUT_EVENTS; | ||
var MIN_INTERVAL = 1 * 1000; // 1 second | ||
var MIN_INTERVAL = 500; // 500 ms | ||
var MAX_INTERVAL = 10 * 1000; // 10 seconds | ||
@@ -45,4 +47,5 @@ var SessionReplay = /** @class */ (function () { | ||
} | ||
if (_this.timeAtLastSend !== null && Date.now() - _this.timeAtLastSend > _this.interval) { | ||
if (_this.timeAtLastSend !== null && Date.now() - _this.timeAtLastSend > _this.interval && _this.events.length) { | ||
_this.interval = Math.min(MAX_INTERVAL, _this.interval + MIN_INTERVAL); | ||
_this.timeAtLastSend = Date.now(); | ||
return true; | ||
@@ -55,8 +58,25 @@ } | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { | ||
var GlobalScope; | ||
var _this = this; | ||
return tslib_1.__generator(this, function (_a) { | ||
config.loggerProvider.log('Installing @amplitude/plugin-session-replay.'); | ||
this.config = config; | ||
this.storageKey = "".concat(STORAGE_PREFIX, "_").concat(this.config.apiKey.substring(0, 10)); | ||
void this.emptyStoreAndReset(); | ||
return [2 /*return*/]; | ||
switch (_a.label) { | ||
case 0: | ||
config.loggerProvider.log('Installing @amplitude/plugin-session-replay.'); | ||
this.config = config; | ||
this.storageKey = "".concat(STORAGE_PREFIX, "_").concat(this.config.apiKey.substring(0, 10)); | ||
return [4 /*yield*/, this.initialize(true)]; | ||
case 1: | ||
_a.sent(); | ||
GlobalScope = (0, analytics_client_common_1.getGlobalScope)(); | ||
if (GlobalScope && GlobalScope.window) { | ||
GlobalScope.window.addEventListener('blur', function () { | ||
_this.stopRecordingEvents && _this.stopRecordingEvents(); | ||
_this.stopRecordingEvents = null; | ||
}); | ||
GlobalScope.window.addEventListener('focus', function () { | ||
void _this.initialize(); | ||
}); | ||
} | ||
return [2 /*return*/]; | ||
} | ||
}); | ||
@@ -82,2 +102,3 @@ }); | ||
this.stopRecordingEvents && this.stopRecordingEvents(); | ||
this.stopRecordingEvents = null; | ||
this.events = []; | ||
@@ -90,27 +111,36 @@ this.currentSequenceId = 0; | ||
}; | ||
SessionReplay.prototype.emptyStoreAndReset = function () { | ||
SessionReplay.prototype.initialize = function (shouldSendStoredEvents) { | ||
if (shouldSendStoredEvents === void 0) { shouldSendStoredEvents = false; } | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { | ||
var storedReplaySessions, sessionId, storedReplayEvents, currentSessionStoredEvents; | ||
var storedReplaySessions, storedSequencesForSession, storedSeqId, lastSequence; | ||
return tslib_1.__generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, this.getAllSessionEventsFromStore()]; | ||
case 0: | ||
this.timeAtLastSend = Date.now(); // Initialize this so we have a point of comparison when events are recorded | ||
if (!this.config.sessionId) { | ||
return [2 /*return*/]; | ||
} | ||
return [4 /*yield*/, this.getAllSessionEventsFromStore()]; | ||
case 1: | ||
storedReplaySessions = _a.sent(); | ||
if (storedReplaySessions) { | ||
for (sessionId in storedReplaySessions) { | ||
storedReplayEvents = storedReplaySessions[sessionId]; | ||
if (storedReplayEvents.events.length) { | ||
this.sendEventsList({ | ||
events: storedReplayEvents.events, | ||
sequenceId: storedReplayEvents.sequenceId, | ||
sessionId: parseInt(sessionId, 10), | ||
}); | ||
} | ||
storedSequencesForSession = storedReplaySessions && storedReplaySessions[this.config.sessionId]; | ||
if (storedReplaySessions && storedSequencesForSession && storedSequencesForSession.sessionSequences) { | ||
storedSeqId = storedSequencesForSession.currentSequenceId; | ||
lastSequence = storedSequencesForSession.sessionSequences[storedSeqId]; | ||
if (lastSequence.status !== session_replay_1.RecordingStatus.RECORDING) { | ||
this.currentSequenceId = storedSeqId + 1; | ||
this.events = []; | ||
} | ||
this.events = []; | ||
currentSessionStoredEvents = this.config.sessionId && storedReplaySessions[this.config.sessionId]; | ||
this.currentSequenceId = currentSessionStoredEvents ? currentSessionStoredEvents.sequenceId + 1 : 0; | ||
void this.storeEventsForSession([], this.currentSequenceId); | ||
else { | ||
// Pick up recording where it was left off in another tab or window | ||
this.currentSequenceId = storedSeqId; | ||
this.events = lastSequence.events; | ||
} | ||
} | ||
this.recordEvents(); | ||
if (shouldSendStoredEvents && storedReplaySessions) { | ||
this.sendStoredEvents(storedReplaySessions); | ||
} | ||
if (!this.stopRecordingEvents) { | ||
this.recordEvents(); | ||
} | ||
return [2 /*return*/]; | ||
@@ -121,2 +151,22 @@ } | ||
}; | ||
SessionReplay.prototype.sendStoredEvents = function (storedReplaySessions) { | ||
for (var sessionId in storedReplaySessions) { | ||
var storedSequences = storedReplaySessions[sessionId].sessionSequences; | ||
for (var storedSeqId in storedSequences) { | ||
var seq = storedSequences[storedSeqId]; | ||
var numericSeqId = parseInt(storedSeqId, 10); | ||
var numericSessionId = parseInt(sessionId, 10); | ||
if (numericSessionId === this.config.sessionId && numericSeqId === this.currentSequenceId) { | ||
continue; | ||
} | ||
if (seq.events.length && seq.status === session_replay_1.RecordingStatus.RECORDING) { | ||
this.sendEventsList({ | ||
events: seq.events, | ||
sequenceId: numericSeqId, | ||
sessionId: numericSessionId, | ||
}); | ||
} | ||
} | ||
} | ||
}; | ||
SessionReplay.prototype.recordEvents = function () { | ||
@@ -127,13 +177,2 @@ var _this = this; | ||
var eventString = JSON.stringify(event); | ||
// Send the first two recorded events immediately | ||
if (_this.events.length === 1 && _this.currentSequenceId === 0) { | ||
_this.sendEventsList({ | ||
events: _this.events.concat(eventString), | ||
sequenceId: _this.currentSequenceId, | ||
sessionId: _this.config.sessionId, | ||
}); | ||
_this.events = []; | ||
_this.currentSequenceId++; | ||
return; | ||
} | ||
var shouldSplit = _this.shouldSplitEventsList(eventString); | ||
@@ -150,3 +189,3 @@ if (shouldSplit) { | ||
_this.events.push(eventString); | ||
void _this.storeEventsForSession(_this.events, _this.currentSequenceId); | ||
void _this.storeEventsForSession(_this.events, _this.currentSequenceId, _this.config.sessionId); | ||
}, | ||
@@ -327,6 +366,5 @@ packFn: rrweb_1.pack, | ||
}; | ||
SessionReplay.prototype.storeEventsForSession = function (events, sequenceId) { | ||
SessionReplay.prototype.storeEventsForSession = function (events, sequenceId, sessionId) { | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { | ||
var e_3; | ||
var _this = this; | ||
return tslib_1.__generator(this, function (_a) { | ||
@@ -337,9 +375,13 @@ switch (_a.label) { | ||
return [4 /*yield*/, IDBKeyVal.update(this.storageKey, function (sessionMap) { | ||
var _a; | ||
return tslib_1.__assign(tslib_1.__assign({}, sessionMap), (_this.config.sessionId && (_a = {}, | ||
_a[_this.config.sessionId] = { | ||
events: events, | ||
sequenceId: sequenceId, | ||
}, | ||
_a))); | ||
var _a, _b; | ||
if (sessionMap === void 0) { sessionMap = {}; } | ||
var session = sessionMap[sessionId] || { | ||
currentSequenceId: 0, | ||
sessionSequences: [], | ||
}; | ||
session.currentSequenceId = sequenceId; | ||
var currentSequence = (session.sessionSequences && session.sessionSequences[sequenceId]) || {}; | ||
currentSequence.events = events; | ||
currentSequence.status = session_replay_1.RecordingStatus.RECORDING; | ||
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)); | ||
})]; | ||
@@ -358,3 +400,3 @@ case 1: | ||
}; | ||
SessionReplay.prototype.removeSessionEventsStore = function (sessionId) { | ||
SessionReplay.prototype.cleanUpSessionEventsStore = function (sessionId, sequenceId) { | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { | ||
@@ -368,3 +410,16 @@ var e_4; | ||
if (sessionMap === void 0) { sessionMap = {}; } | ||
delete sessionMap[sessionId]; | ||
var session = sessionMap[sessionId]; | ||
var sequenceToUpdate = (session === null || session === void 0 ? void 0 : session.sessionSequences) && session.sessionSequences[sequenceId]; | ||
if (!sequenceToUpdate) { | ||
return sessionMap; | ||
} | ||
sequenceToUpdate.events = []; | ||
sequenceToUpdate.status = session_replay_1.RecordingStatus.SENT; | ||
Object.entries(session.sessionSequences).forEach(function (_a) { | ||
var _b = tslib_1.__read(_a, 2), storedSeqId = _b[0], sequence = _b[1]; | ||
var numericStoredSeqId = parseInt(storedSeqId, 10); | ||
if (sequence.status === session_replay_1.RecordingStatus.SENT && sequenceId !== numericStoredSeqId) { | ||
delete session.sessionSequences[numericStoredSeqId]; | ||
} | ||
}); | ||
return sessionMap; | ||
@@ -386,3 +441,3 @@ })]; | ||
var context = _a.context, err = _a.err, success = _a.success, _b = _a.removeEvents, removeEvents = _b === void 0 ? true : _b; | ||
removeEvents && context.sessionId && this.removeSessionEventsStore(context.sessionId); | ||
removeEvents && context.sessionId && this.cleanUpSessionEventsStore(context.sessionId, context.sequenceId); | ||
if (err) { | ||
@@ -392,3 +447,2 @@ this.config.loggerProvider.error(err); | ||
else if (success) { | ||
this.timeAtLastSend = Date.now(); | ||
this.config.loggerProvider.log(success); | ||
@@ -395,0 +449,0 @@ } |
@@ -13,6 +13,17 @@ import { BrowserClient, BrowserConfig, EnrichmentPlugin } from '@amplitude/analytics-types'; | ||
} | ||
export declare enum RecordingStatus { | ||
RECORDING = "recording", | ||
SENDING = "sending", | ||
SENT = "sent" | ||
} | ||
export interface IDBStoreSequence { | ||
events: Events; | ||
status: RecordingStatus; | ||
} | ||
export interface IDBStore { | ||
[sessionId: number]: { | ||
events: Events; | ||
sequenceId: number; | ||
currentSequenceId: number; | ||
sessionSequences: { | ||
[sequenceId: number]: IDBStoreSequence; | ||
}; | ||
}; | ||
@@ -31,3 +42,3 @@ } | ||
maxPersistedEventsSize: number; | ||
emptyStoreAndReset: () => Promise<void>; | ||
initialize: (shouldSendStoredEvents?: boolean) => Promise<void>; | ||
recordEvents: () => void; | ||
@@ -51,4 +62,4 @@ shouldSplitEventsList: (nextEventString: string) => boolean; | ||
getAllSessionEventsFromStore: () => Promise<IDBStore | undefined>; | ||
storeEventsForSession: (events: Events, sequenceId: number) => Promise<void>; | ||
removeSessionEventsStore: (sessionId: number) => Promise<void>; | ||
storeEventsForSession: (events: Events, sequenceId: number, sessionId: number) => Promise<void>; | ||
cleanUpSessionEventsStore: (sessionId: number, sequenceId: number) => Promise<void>; | ||
} | ||
@@ -55,0 +66,0 @@ export interface SessionReplayPlugin { |
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.RecordingStatus = void 0; | ||
var RecordingStatus; | ||
(function (RecordingStatus) { | ||
RecordingStatus["RECORDING"] = "recording"; | ||
RecordingStatus["SENDING"] = "sending"; | ||
RecordingStatus["SENT"] = "sent"; | ||
})(RecordingStatus = exports.RecordingStatus || (exports.RecordingStatus = {})); | ||
//# sourceMappingURL=session-replay.js.map |
@@ -1,2 +0,3 @@ | ||
import { __assign, __awaiter, __generator } from "tslib"; | ||
import { __assign, __awaiter, __generator, __read } from "tslib"; | ||
import { getGlobalScope } from '@amplitude/analytics-client-common'; | ||
import { AMPLITUDE_PREFIX, BaseTransport } from '@amplitude/analytics-core'; | ||
@@ -8,2 +9,3 @@ import { Status } from '@amplitude/analytics-types'; | ||
import { MAX_RETRIES_EXCEEDED_MESSAGE, STORAGE_FAILURE, SUCCESS_MESSAGE, UNEXPECTED_ERROR_MESSAGE } from './messages'; | ||
import { RecordingStatus, } from './typings/session-replay'; | ||
var SESSION_REPLAY_SERVER_URL = 'https://api-secure.amplitude.com/sessions/track'; | ||
@@ -13,3 +15,3 @@ var STORAGE_PREFIX = "".concat(AMPLITUDE_PREFIX, "_replay_unsent"); | ||
var MAX_EVENT_LIST_SIZE_IN_BYTES = 20 * 1000000 - PAYLOAD_ESTIMATED_SIZE_IN_BYTES_WITHOUT_EVENTS; | ||
var MIN_INTERVAL = 1 * 1000; // 1 second | ||
var MIN_INTERVAL = 500; // 500 ms | ||
var MAX_INTERVAL = 10 * 1000; // 10 seconds | ||
@@ -43,4 +45,5 @@ var SessionReplay = /** @class */ (function () { | ||
} | ||
if (_this.timeAtLastSend !== null && Date.now() - _this.timeAtLastSend > _this.interval) { | ||
if (_this.timeAtLastSend !== null && Date.now() - _this.timeAtLastSend > _this.interval && _this.events.length) { | ||
_this.interval = Math.min(MAX_INTERVAL, _this.interval + MIN_INTERVAL); | ||
_this.timeAtLastSend = Date.now(); | ||
return true; | ||
@@ -53,8 +56,25 @@ } | ||
return __awaiter(this, void 0, void 0, function () { | ||
var GlobalScope; | ||
var _this = this; | ||
return __generator(this, function (_a) { | ||
config.loggerProvider.log('Installing @amplitude/plugin-session-replay.'); | ||
this.config = config; | ||
this.storageKey = "".concat(STORAGE_PREFIX, "_").concat(this.config.apiKey.substring(0, 10)); | ||
void this.emptyStoreAndReset(); | ||
return [2 /*return*/]; | ||
switch (_a.label) { | ||
case 0: | ||
config.loggerProvider.log('Installing @amplitude/plugin-session-replay.'); | ||
this.config = config; | ||
this.storageKey = "".concat(STORAGE_PREFIX, "_").concat(this.config.apiKey.substring(0, 10)); | ||
return [4 /*yield*/, this.initialize(true)]; | ||
case 1: | ||
_a.sent(); | ||
GlobalScope = getGlobalScope(); | ||
if (GlobalScope && GlobalScope.window) { | ||
GlobalScope.window.addEventListener('blur', function () { | ||
_this.stopRecordingEvents && _this.stopRecordingEvents(); | ||
_this.stopRecordingEvents = null; | ||
}); | ||
GlobalScope.window.addEventListener('focus', function () { | ||
void _this.initialize(); | ||
}); | ||
} | ||
return [2 /*return*/]; | ||
} | ||
}); | ||
@@ -80,2 +100,3 @@ }); | ||
this.stopRecordingEvents && this.stopRecordingEvents(); | ||
this.stopRecordingEvents = null; | ||
this.events = []; | ||
@@ -88,27 +109,36 @@ this.currentSequenceId = 0; | ||
}; | ||
SessionReplay.prototype.emptyStoreAndReset = function () { | ||
SessionReplay.prototype.initialize = function (shouldSendStoredEvents) { | ||
if (shouldSendStoredEvents === void 0) { shouldSendStoredEvents = false; } | ||
return __awaiter(this, void 0, void 0, function () { | ||
var storedReplaySessions, sessionId, storedReplayEvents, currentSessionStoredEvents; | ||
var storedReplaySessions, storedSequencesForSession, storedSeqId, lastSequence; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, this.getAllSessionEventsFromStore()]; | ||
case 0: | ||
this.timeAtLastSend = Date.now(); // Initialize this so we have a point of comparison when events are recorded | ||
if (!this.config.sessionId) { | ||
return [2 /*return*/]; | ||
} | ||
return [4 /*yield*/, this.getAllSessionEventsFromStore()]; | ||
case 1: | ||
storedReplaySessions = _a.sent(); | ||
if (storedReplaySessions) { | ||
for (sessionId in storedReplaySessions) { | ||
storedReplayEvents = storedReplaySessions[sessionId]; | ||
if (storedReplayEvents.events.length) { | ||
this.sendEventsList({ | ||
events: storedReplayEvents.events, | ||
sequenceId: storedReplayEvents.sequenceId, | ||
sessionId: parseInt(sessionId, 10), | ||
}); | ||
} | ||
storedSequencesForSession = storedReplaySessions && storedReplaySessions[this.config.sessionId]; | ||
if (storedReplaySessions && storedSequencesForSession && storedSequencesForSession.sessionSequences) { | ||
storedSeqId = storedSequencesForSession.currentSequenceId; | ||
lastSequence = storedSequencesForSession.sessionSequences[storedSeqId]; | ||
if (lastSequence.status !== RecordingStatus.RECORDING) { | ||
this.currentSequenceId = storedSeqId + 1; | ||
this.events = []; | ||
} | ||
this.events = []; | ||
currentSessionStoredEvents = this.config.sessionId && storedReplaySessions[this.config.sessionId]; | ||
this.currentSequenceId = currentSessionStoredEvents ? currentSessionStoredEvents.sequenceId + 1 : 0; | ||
void this.storeEventsForSession([], this.currentSequenceId); | ||
else { | ||
// Pick up recording where it was left off in another tab or window | ||
this.currentSequenceId = storedSeqId; | ||
this.events = lastSequence.events; | ||
} | ||
} | ||
this.recordEvents(); | ||
if (shouldSendStoredEvents && storedReplaySessions) { | ||
this.sendStoredEvents(storedReplaySessions); | ||
} | ||
if (!this.stopRecordingEvents) { | ||
this.recordEvents(); | ||
} | ||
return [2 /*return*/]; | ||
@@ -119,2 +149,22 @@ } | ||
}; | ||
SessionReplay.prototype.sendStoredEvents = function (storedReplaySessions) { | ||
for (var sessionId in storedReplaySessions) { | ||
var storedSequences = storedReplaySessions[sessionId].sessionSequences; | ||
for (var storedSeqId in storedSequences) { | ||
var seq = storedSequences[storedSeqId]; | ||
var numericSeqId = parseInt(storedSeqId, 10); | ||
var numericSessionId = parseInt(sessionId, 10); | ||
if (numericSessionId === this.config.sessionId && numericSeqId === this.currentSequenceId) { | ||
continue; | ||
} | ||
if (seq.events.length && seq.status === RecordingStatus.RECORDING) { | ||
this.sendEventsList({ | ||
events: seq.events, | ||
sequenceId: numericSeqId, | ||
sessionId: numericSessionId, | ||
}); | ||
} | ||
} | ||
} | ||
}; | ||
SessionReplay.prototype.recordEvents = function () { | ||
@@ -125,13 +175,2 @@ var _this = this; | ||
var eventString = JSON.stringify(event); | ||
// Send the first two recorded events immediately | ||
if (_this.events.length === 1 && _this.currentSequenceId === 0) { | ||
_this.sendEventsList({ | ||
events: _this.events.concat(eventString), | ||
sequenceId: _this.currentSequenceId, | ||
sessionId: _this.config.sessionId, | ||
}); | ||
_this.events = []; | ||
_this.currentSequenceId++; | ||
return; | ||
} | ||
var shouldSplit = _this.shouldSplitEventsList(eventString); | ||
@@ -148,3 +187,3 @@ if (shouldSplit) { | ||
_this.events.push(eventString); | ||
void _this.storeEventsForSession(_this.events, _this.currentSequenceId); | ||
void _this.storeEventsForSession(_this.events, _this.currentSequenceId, _this.config.sessionId); | ||
}, | ||
@@ -325,6 +364,5 @@ packFn: pack, | ||
}; | ||
SessionReplay.prototype.storeEventsForSession = function (events, sequenceId) { | ||
SessionReplay.prototype.storeEventsForSession = function (events, sequenceId, sessionId) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var e_3; | ||
var _this = this; | ||
return __generator(this, function (_a) { | ||
@@ -335,9 +373,13 @@ switch (_a.label) { | ||
return [4 /*yield*/, IDBKeyVal.update(this.storageKey, function (sessionMap) { | ||
var _a; | ||
return __assign(__assign({}, sessionMap), (_this.config.sessionId && (_a = {}, | ||
_a[_this.config.sessionId] = { | ||
events: events, | ||
sequenceId: sequenceId, | ||
}, | ||
_a))); | ||
var _a, _b; | ||
if (sessionMap === void 0) { sessionMap = {}; } | ||
var session = sessionMap[sessionId] || { | ||
currentSequenceId: 0, | ||
sessionSequences: [], | ||
}; | ||
session.currentSequenceId = sequenceId; | ||
var currentSequence = (session.sessionSequences && session.sessionSequences[sequenceId]) || {}; | ||
currentSequence.events = events; | ||
currentSequence.status = RecordingStatus.RECORDING; | ||
return __assign(__assign({}, sessionMap), (_a = {}, _a[sessionId] = __assign(__assign({}, session), { sessionSequences: __assign(__assign({}, session.sessionSequences), (_b = {}, _b[sequenceId] = currentSequence, _b)) }), _a)); | ||
})]; | ||
@@ -356,3 +398,3 @@ case 1: | ||
}; | ||
SessionReplay.prototype.removeSessionEventsStore = function (sessionId) { | ||
SessionReplay.prototype.cleanUpSessionEventsStore = function (sessionId, sequenceId) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
@@ -366,3 +408,16 @@ var e_4; | ||
if (sessionMap === void 0) { sessionMap = {}; } | ||
delete sessionMap[sessionId]; | ||
var session = sessionMap[sessionId]; | ||
var sequenceToUpdate = (session === null || session === void 0 ? void 0 : session.sessionSequences) && session.sessionSequences[sequenceId]; | ||
if (!sequenceToUpdate) { | ||
return sessionMap; | ||
} | ||
sequenceToUpdate.events = []; | ||
sequenceToUpdate.status = RecordingStatus.SENT; | ||
Object.entries(session.sessionSequences).forEach(function (_a) { | ||
var _b = __read(_a, 2), storedSeqId = _b[0], sequence = _b[1]; | ||
var numericStoredSeqId = parseInt(storedSeqId, 10); | ||
if (sequence.status === RecordingStatus.SENT && sequenceId !== numericStoredSeqId) { | ||
delete session.sessionSequences[numericStoredSeqId]; | ||
} | ||
}); | ||
return sessionMap; | ||
@@ -384,3 +439,3 @@ })]; | ||
var context = _a.context, err = _a.err, success = _a.success, _b = _a.removeEvents, removeEvents = _b === void 0 ? true : _b; | ||
removeEvents && context.sessionId && this.removeSessionEventsStore(context.sessionId); | ||
removeEvents && context.sessionId && this.cleanUpSessionEventsStore(context.sessionId, context.sequenceId); | ||
if (err) { | ||
@@ -390,3 +445,2 @@ this.config.loggerProvider.error(err); | ||
else if (success) { | ||
this.timeAtLastSend = Date.now(); | ||
this.config.loggerProvider.log(success); | ||
@@ -393,0 +447,0 @@ } |
@@ -13,6 +13,17 @@ import { BrowserClient, BrowserConfig, EnrichmentPlugin } from '@amplitude/analytics-types'; | ||
} | ||
export declare enum RecordingStatus { | ||
RECORDING = "recording", | ||
SENDING = "sending", | ||
SENT = "sent" | ||
} | ||
export interface IDBStoreSequence { | ||
events: Events; | ||
status: RecordingStatus; | ||
} | ||
export interface IDBStore { | ||
[sessionId: number]: { | ||
events: Events; | ||
sequenceId: number; | ||
currentSequenceId: number; | ||
sessionSequences: { | ||
[sequenceId: number]: IDBStoreSequence; | ||
}; | ||
}; | ||
@@ -31,3 +42,3 @@ } | ||
maxPersistedEventsSize: number; | ||
emptyStoreAndReset: () => Promise<void>; | ||
initialize: (shouldSendStoredEvents?: boolean) => Promise<void>; | ||
recordEvents: () => void; | ||
@@ -51,4 +62,4 @@ shouldSplitEventsList: (nextEventString: string) => boolean; | ||
getAllSessionEventsFromStore: () => Promise<IDBStore | undefined>; | ||
storeEventsForSession: (events: Events, sequenceId: number) => Promise<void>; | ||
removeSessionEventsStore: (sessionId: number) => Promise<void>; | ||
storeEventsForSession: (events: Events, sequenceId: number, sessionId: number) => Promise<void>; | ||
cleanUpSessionEventsStore: (sessionId: number, sequenceId: number) => Promise<void>; | ||
} | ||
@@ -55,0 +66,0 @@ export interface SessionReplayPlugin { |
@@ -1,2 +0,7 @@ | ||
export {}; | ||
export var RecordingStatus; | ||
(function (RecordingStatus) { | ||
RecordingStatus["RECORDING"] = "recording"; | ||
RecordingStatus["SENDING"] = "sending"; | ||
RecordingStatus["SENT"] = "sent"; | ||
})(RecordingStatus || (RecordingStatus = {})); | ||
//# sourceMappingURL=session-replay.js.map |
@@ -13,6 +13,17 @@ import { BrowserClient, BrowserConfig, EnrichmentPlugin } from '@amplitude/analytics-types'; | ||
} | ||
export declare enum RecordingStatus { | ||
RECORDING = "recording", | ||
SENDING = "sending", | ||
SENT = "sent" | ||
} | ||
export interface IDBStoreSequence { | ||
events: Events; | ||
status: RecordingStatus; | ||
} | ||
export interface IDBStore { | ||
[sessionId: number]: { | ||
events: Events; | ||
sequenceId: number; | ||
currentSequenceId: number; | ||
sessionSequences: { | ||
[sequenceId: number]: IDBStoreSequence; | ||
}; | ||
}; | ||
@@ -31,3 +42,3 @@ } | ||
maxPersistedEventsSize: number; | ||
emptyStoreAndReset: () => Promise<void>; | ||
initialize: (shouldSendStoredEvents?: boolean) => Promise<void>; | ||
recordEvents: () => void; | ||
@@ -51,4 +62,4 @@ shouldSplitEventsList: (nextEventString: string) => boolean; | ||
getAllSessionEventsFromStore: () => Promise<IDBStore | undefined>; | ||
storeEventsForSession: (events: Events, sequenceId: number) => Promise<void>; | ||
removeSessionEventsStore: (sessionId: number) => Promise<void>; | ||
storeEventsForSession: (events: Events, sequenceId: number, sessionId: number) => Promise<void>; | ||
cleanUpSessionEventsStore: (sessionId: number, sequenceId: number) => Promise<void>; | ||
} | ||
@@ -55,0 +66,0 @@ export interface SessionReplayPlugin { |
{ | ||
"name": "@amplitude/plugin-session-replay-browser", | ||
"version": "0.1.3", | ||
"version": "0.2.0", | ||
"description": "", | ||
@@ -58,3 +58,3 @@ "author": "Amplitude Inc", | ||
], | ||
"gitHead": "392e3d9b080374d805e32d9e8a99f92175ea2218" | ||
"gitHead": "2c95641a226169afa89936f06afbbeef030f78e1" | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
367916
1845