@amplitude/session-replay-browser 1.2.2 → 1.2.4
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/events-manager.d.ts +49 -0
- package/lib/cjs/events-manager.d.ts.map +1 -0
- package/lib/cjs/events-manager.js +157 -0
- package/lib/cjs/events-manager.js.map +1 -0
- package/lib/cjs/session-replay.d.ts +4 -22
- package/lib/cjs/session-replay.d.ts.map +1 -1
- package/lib/cjs/session-replay.js +34 -131
- package/lib/cjs/session-replay.js.map +1 -1
- package/lib/cjs/track-destination.d.ts +0 -1
- package/lib/cjs/track-destination.d.ts.map +1 -1
- package/lib/cjs/track-destination.js +0 -3
- package/lib/cjs/track-destination.js.map +1 -1
- package/lib/cjs/typings/session-replay.d.ts +19 -1
- package/lib/cjs/typings/session-replay.d.ts.map +1 -1
- package/lib/cjs/typings/session-replay.js.map +1 -1
- package/lib/esm/events-manager.d.ts +49 -0
- package/lib/esm/events-manager.d.ts.map +1 -0
- package/lib/esm/events-manager.js +155 -0
- package/lib/esm/events-manager.js.map +1 -0
- package/lib/esm/session-replay.d.ts +4 -22
- package/lib/esm/session-replay.d.ts.map +1 -1
- package/lib/esm/session-replay.js +35 -132
- package/lib/esm/session-replay.js.map +1 -1
- package/lib/esm/track-destination.d.ts +0 -1
- package/lib/esm/track-destination.d.ts.map +1 -1
- package/lib/esm/track-destination.js +0 -3
- package/lib/esm/track-destination.js.map +1 -1
- package/lib/esm/typings/session-replay.d.ts +19 -1
- 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/events-manager.d.ts +49 -0
- package/lib/scripts/events-manager.d.ts.map +1 -0
- package/lib/scripts/session-replay.d.ts +4 -22
- package/lib/scripts/session-replay.d.ts.map +1 -1
- package/lib/scripts/track-destination.d.ts +0 -1
- package/lib/scripts/track-destination.d.ts.map +1 -1
- package/lib/scripts/typings/session-replay.d.ts +19 -1
- package/lib/scripts/typings/session-replay.d.ts.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { SessionReplayEventsManager as AmplitudeSessionReplayEventsManager, SessionReplaySessionIDBStore as AmplitudeSessionReplayEventsStorage, SessionReplayTrackDestination as AmplitudeSessionReplayTrackDestination, Events, IDBStore, SessionReplayConfig } from './typings/session-replay';
|
|
2
|
+
export declare class SessionReplayEventsManager implements AmplitudeSessionReplayEventsManager {
|
|
3
|
+
events: Events;
|
|
4
|
+
currentSequenceId: number;
|
|
5
|
+
maxPersistedEventsSize: number;
|
|
6
|
+
interval: number;
|
|
7
|
+
timeAtLastSend: number | null;
|
|
8
|
+
sessionIDBStore: AmplitudeSessionReplayEventsStorage;
|
|
9
|
+
trackDestination: AmplitudeSessionReplayTrackDestination;
|
|
10
|
+
config: SessionReplayConfig;
|
|
11
|
+
constructor({ config }: {
|
|
12
|
+
config: SessionReplayConfig;
|
|
13
|
+
});
|
|
14
|
+
initialize({ sessionId, deviceId, shouldSendStoredEvents, }: {
|
|
15
|
+
sessionId: number;
|
|
16
|
+
deviceId: string;
|
|
17
|
+
shouldSendStoredEvents?: boolean;
|
|
18
|
+
}): Promise<void>;
|
|
19
|
+
sendStoredEvents({ storedReplaySessions, sessionId, deviceId, }: {
|
|
20
|
+
storedReplaySessions: IDBStore;
|
|
21
|
+
sessionId: number;
|
|
22
|
+
deviceId: string;
|
|
23
|
+
}): void;
|
|
24
|
+
resetSequence(): void;
|
|
25
|
+
addEvent({ event, sessionId, deviceId }: {
|
|
26
|
+
event: string;
|
|
27
|
+
sessionId: number;
|
|
28
|
+
deviceId: string;
|
|
29
|
+
}): void;
|
|
30
|
+
/**
|
|
31
|
+
* Determines whether to send the events list to the backend and start a new
|
|
32
|
+
* empty events list, based on the size of the list as well as the last time sent
|
|
33
|
+
* @param nextEventString
|
|
34
|
+
* @returns boolean
|
|
35
|
+
*/
|
|
36
|
+
shouldSplitEventsList: (nextEventString: string) => boolean;
|
|
37
|
+
sendEvents({ sessionId, deviceId }: {
|
|
38
|
+
sessionId: number;
|
|
39
|
+
deviceId: string;
|
|
40
|
+
}): void;
|
|
41
|
+
sendEventsList({ events, sequenceId, sessionId, deviceId, }: {
|
|
42
|
+
events: string[];
|
|
43
|
+
sequenceId: number;
|
|
44
|
+
sessionId: number;
|
|
45
|
+
deviceId: string;
|
|
46
|
+
}): void;
|
|
47
|
+
flush(useRetry?: boolean): Promise<void>;
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=events-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events-manager.d.ts","sourceRoot":"","sources":["../../src/events-manager.ts"],"names":[],"mappings":"AACA,OAAO,EACL,0BAA0B,IAAI,mCAAmC,EACjE,4BAA4B,IAAI,mCAAmC,EACnE,6BAA6B,IAAI,sCAAsC,EACvE,MAAM,EACN,QAAQ,EAER,mBAAmB,EACpB,MAAM,0BAA0B,CAAC;AAKlC,qBAAa,0BAA2B,YAAW,mCAAmC;IACpF,MAAM,EAAE,MAAM,CAAM;IACpB,iBAAiB,SAAK;IACtB,sBAAsB,SAAgC;IACtD,QAAQ,SAAgB;IACxB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAQ;IACrC,eAAe,EAAE,mCAAmC,CAAC;IACrD,gBAAgB,EAAE,sCAAsC,CAAC;IACzD,MAAM,EAAE,mBAAmB,CAAC;gBAEhB,EAAE,MAAM,EAAE,EAAE;QAAE,MAAM,EAAE,mBAAmB,CAAA;KAAE;IASjD,UAAU,CAAC,EACf,SAAS,EACT,QAAQ,EACR,sBAA8B,GAC/B,EAAE;QACD,SAAS,EAAE,MAAM,CAAC;QAClB,QAAQ,EAAE,MAAM,CAAC;QACjB,sBAAsB,CAAC,EAAE,OAAO,CAAC;KAClC;IAsBD,gBAAgB,CAAC,EACf,oBAAoB,EACpB,SAAS,EACT,QAAQ,GACT,EAAE;QACD,oBAAoB,EAAE,QAAQ,CAAC;QAC/B,SAAS,EAAE,MAAM,CAAC;QAClB,QAAQ,EAAE,MAAM,CAAC;KAClB;IAuBD,aAAa;IAKb,QAAQ,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE;IAgB/F;;;;;OAKG;IACH,qBAAqB,oBAAqB,MAAM,KAAG,OAAO,CAYxD;IAEF,UAAU,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE;IAW3E,cAAc,CAAC,EACb,MAAM,EACN,UAAU,EACV,SAAS,EACT,QAAQ,GACT,EAAE;QACD,MAAM,EAAE,MAAM,EAAE,CAAC;QACjB,UAAU,EAAE,MAAM,CAAC;QACnB,SAAS,EAAE,MAAM,CAAC;QAClB,QAAQ,EAAE,MAAM,CAAC;KAClB;IAcK,KAAK,CAAC,QAAQ,UAAQ;CAK7B"}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
2
|
+
exports.SessionReplayEventsManager = void 0;
|
|
3
|
+
var tslib_1 = require("tslib");
|
|
4
|
+
var constants_1 = require("./constants");
|
|
5
|
+
var session_replay_1 = require("./typings/session-replay");
|
|
6
|
+
var session_idb_store_1 = require("./session-idb-store");
|
|
7
|
+
var track_destination_1 = require("./track-destination");
|
|
8
|
+
var SessionReplayEventsManager = /** @class */ (function () {
|
|
9
|
+
function SessionReplayEventsManager(_a) {
|
|
10
|
+
var config = _a.config;
|
|
11
|
+
var _this = this;
|
|
12
|
+
this.events = [];
|
|
13
|
+
this.currentSequenceId = 0;
|
|
14
|
+
this.maxPersistedEventsSize = constants_1.MAX_EVENT_LIST_SIZE_IN_BYTES;
|
|
15
|
+
this.interval = constants_1.MIN_INTERVAL;
|
|
16
|
+
this.timeAtLastSend = null;
|
|
17
|
+
/**
|
|
18
|
+
* Determines whether to send the events list to the backend and start a new
|
|
19
|
+
* empty events list, based on the size of the list as well as the last time sent
|
|
20
|
+
* @param nextEventString
|
|
21
|
+
* @returns boolean
|
|
22
|
+
*/
|
|
23
|
+
this.shouldSplitEventsList = function (nextEventString) {
|
|
24
|
+
var sizeOfNextEvent = new Blob([nextEventString]).size;
|
|
25
|
+
var sizeOfEventsList = new Blob(_this.events).size;
|
|
26
|
+
if (sizeOfEventsList + sizeOfNextEvent >= _this.maxPersistedEventsSize) {
|
|
27
|
+
return true;
|
|
28
|
+
}
|
|
29
|
+
if (_this.timeAtLastSend !== null && Date.now() - _this.timeAtLastSend > _this.interval && _this.events.length) {
|
|
30
|
+
_this.interval = Math.min(constants_1.MAX_INTERVAL, _this.interval + constants_1.MIN_INTERVAL);
|
|
31
|
+
_this.timeAtLastSend = Date.now();
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
return false;
|
|
35
|
+
};
|
|
36
|
+
this.config = config;
|
|
37
|
+
this.trackDestination = new track_destination_1.SessionReplayTrackDestination({ loggerProvider: this.config.loggerProvider });
|
|
38
|
+
this.sessionIDBStore = new session_idb_store_1.SessionReplaySessionIDBStore({
|
|
39
|
+
loggerProvider: this.config.loggerProvider,
|
|
40
|
+
apiKey: this.config.apiKey,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
SessionReplayEventsManager.prototype.initialize = function (_a) {
|
|
44
|
+
var sessionId = _a.sessionId, deviceId = _a.deviceId, _b = _a.shouldSendStoredEvents, shouldSendStoredEvents = _b === void 0 ? false : _b;
|
|
45
|
+
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
46
|
+
var storedReplaySessions, storedSequencesForSession, storedSeqId, lastSequence;
|
|
47
|
+
return tslib_1.__generator(this, function (_c) {
|
|
48
|
+
switch (_c.label) {
|
|
49
|
+
case 0:
|
|
50
|
+
this.timeAtLastSend = Date.now(); // Initialize this so we have a point of comparison when events are recorded
|
|
51
|
+
return [4 /*yield*/, this.sessionIDBStore.getAllSessionDataFromStore()];
|
|
52
|
+
case 1:
|
|
53
|
+
storedReplaySessions = _c.sent();
|
|
54
|
+
storedSequencesForSession = storedReplaySessions && storedReplaySessions[sessionId];
|
|
55
|
+
if (storedReplaySessions && storedSequencesForSession && storedSequencesForSession.sessionSequences) {
|
|
56
|
+
storedSeqId = storedSequencesForSession.currentSequenceId;
|
|
57
|
+
lastSequence = storedSequencesForSession.sessionSequences[storedSeqId];
|
|
58
|
+
if (lastSequence && lastSequence.status !== session_replay_1.RecordingStatus.RECORDING) {
|
|
59
|
+
this.currentSequenceId = storedSeqId + 1;
|
|
60
|
+
this.events = [];
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
// Pick up recording where it was left off in another tab or window
|
|
64
|
+
this.currentSequenceId = storedSeqId;
|
|
65
|
+
this.events = (lastSequence === null || lastSequence === void 0 ? void 0 : lastSequence.events) || [];
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
if (shouldSendStoredEvents && storedReplaySessions) {
|
|
69
|
+
this.sendStoredEvents({ storedReplaySessions: storedReplaySessions, deviceId: deviceId, sessionId: sessionId });
|
|
70
|
+
}
|
|
71
|
+
return [2 /*return*/];
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
};
|
|
76
|
+
SessionReplayEventsManager.prototype.sendStoredEvents = function (_a) {
|
|
77
|
+
var storedReplaySessions = _a.storedReplaySessions, sessionId = _a.sessionId, deviceId = _a.deviceId;
|
|
78
|
+
for (var storedSessionId in storedReplaySessions) {
|
|
79
|
+
var storedSequences = storedReplaySessions[storedSessionId].sessionSequences;
|
|
80
|
+
for (var storedSeqId in storedSequences) {
|
|
81
|
+
var seq = storedSequences[storedSeqId];
|
|
82
|
+
var numericSeqId = parseInt(storedSeqId, 10);
|
|
83
|
+
var numericSessionId = parseInt(storedSessionId, 10);
|
|
84
|
+
if (numericSessionId === sessionId && numericSeqId === this.currentSequenceId) {
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
if (seq.events && seq.events.length && seq.status === session_replay_1.RecordingStatus.RECORDING) {
|
|
88
|
+
this.sendEventsList({
|
|
89
|
+
events: seq.events,
|
|
90
|
+
sequenceId: numericSeqId,
|
|
91
|
+
sessionId: numericSessionId,
|
|
92
|
+
deviceId: deviceId,
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
SessionReplayEventsManager.prototype.resetSequence = function () {
|
|
99
|
+
this.events = [];
|
|
100
|
+
this.currentSequenceId = 0;
|
|
101
|
+
};
|
|
102
|
+
SessionReplayEventsManager.prototype.addEvent = function (_a) {
|
|
103
|
+
var event = _a.event, sessionId = _a.sessionId, deviceId = _a.deviceId;
|
|
104
|
+
var shouldSplit = this.shouldSplitEventsList(event);
|
|
105
|
+
if (shouldSplit) {
|
|
106
|
+
this.sendEventsList({
|
|
107
|
+
events: this.events,
|
|
108
|
+
sequenceId: this.currentSequenceId,
|
|
109
|
+
sessionId: sessionId,
|
|
110
|
+
deviceId: deviceId,
|
|
111
|
+
});
|
|
112
|
+
this.events = [];
|
|
113
|
+
this.currentSequenceId++;
|
|
114
|
+
}
|
|
115
|
+
this.events.push(event);
|
|
116
|
+
void this.sessionIDBStore.storeEventsForSession(this.events, this.currentSequenceId, sessionId);
|
|
117
|
+
};
|
|
118
|
+
SessionReplayEventsManager.prototype.sendEvents = function (_a) {
|
|
119
|
+
var sessionId = _a.sessionId, deviceId = _a.deviceId;
|
|
120
|
+
if (this.events.length && sessionId) {
|
|
121
|
+
this.sendEventsList({
|
|
122
|
+
events: this.events,
|
|
123
|
+
sequenceId: this.currentSequenceId,
|
|
124
|
+
sessionId: sessionId,
|
|
125
|
+
deviceId: deviceId,
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
SessionReplayEventsManager.prototype.sendEventsList = function (_a) {
|
|
130
|
+
var events = _a.events, sequenceId = _a.sequenceId, sessionId = _a.sessionId, deviceId = _a.deviceId;
|
|
131
|
+
this.trackDestination.sendEventsList({
|
|
132
|
+
events: events,
|
|
133
|
+
sequenceId: sequenceId,
|
|
134
|
+
sessionId: sessionId,
|
|
135
|
+
flushMaxRetries: this.config.flushMaxRetries,
|
|
136
|
+
apiKey: this.config.apiKey,
|
|
137
|
+
deviceId: deviceId,
|
|
138
|
+
sampleRate: this.config.sampleRate,
|
|
139
|
+
serverZone: this.config.serverZone,
|
|
140
|
+
onComplete: this.sessionIDBStore.cleanUpSessionEventsStore.bind(this.sessionIDBStore),
|
|
141
|
+
});
|
|
142
|
+
};
|
|
143
|
+
SessionReplayEventsManager.prototype.flush = function (useRetry) {
|
|
144
|
+
if (useRetry === void 0) { useRetry = false; }
|
|
145
|
+
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
146
|
+
return tslib_1.__generator(this, function (_a) {
|
|
147
|
+
if (this.trackDestination) {
|
|
148
|
+
return [2 /*return*/, this.trackDestination.flush(useRetry)];
|
|
149
|
+
}
|
|
150
|
+
return [2 /*return*/];
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
};
|
|
154
|
+
return SessionReplayEventsManager;
|
|
155
|
+
}());
|
|
156
|
+
exports.SessionReplayEventsManager = SessionReplayEventsManager;
|
|
157
|
+
//# sourceMappingURL=events-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events-manager.js","sourceRoot":"","sources":["../../src/events-manager.ts"],"names":[],"mappings":"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","sourcesContent":["import { MAX_EVENT_LIST_SIZE_IN_BYTES, MAX_INTERVAL, MIN_INTERVAL } from './constants';\nimport {\n SessionReplayEventsManager as AmplitudeSessionReplayEventsManager,\n SessionReplaySessionIDBStore as AmplitudeSessionReplayEventsStorage,\n SessionReplayTrackDestination as AmplitudeSessionReplayTrackDestination,\n Events,\n IDBStore,\n RecordingStatus,\n SessionReplayConfig,\n} from './typings/session-replay';\n\nimport { SessionReplaySessionIDBStore } from './session-idb-store';\nimport { SessionReplayTrackDestination } from './track-destination';\n\nexport class SessionReplayEventsManager implements AmplitudeSessionReplayEventsManager {\n events: Events = [];\n currentSequenceId = 0;\n maxPersistedEventsSize = MAX_EVENT_LIST_SIZE_IN_BYTES;\n interval = MIN_INTERVAL;\n timeAtLastSend: number | null = null;\n sessionIDBStore: AmplitudeSessionReplayEventsStorage;\n trackDestination: AmplitudeSessionReplayTrackDestination;\n config: SessionReplayConfig;\n\n constructor({ config }: { config: SessionReplayConfig }) {\n this.config = config;\n this.trackDestination = new SessionReplayTrackDestination({ loggerProvider: this.config.loggerProvider });\n this.sessionIDBStore = new SessionReplaySessionIDBStore({\n loggerProvider: this.config.loggerProvider,\n apiKey: this.config.apiKey,\n });\n }\n\n async initialize({\n sessionId,\n deviceId,\n shouldSendStoredEvents = false,\n }: {\n sessionId: number;\n deviceId: string;\n shouldSendStoredEvents?: boolean;\n }) {\n this.timeAtLastSend = Date.now(); // Initialize this so we have a point of comparison when events are recorded\n const storedReplaySessions = await this.sessionIDBStore.getAllSessionDataFromStore();\n\n const storedSequencesForSession = storedReplaySessions && storedReplaySessions[sessionId];\n if (storedReplaySessions && storedSequencesForSession && storedSequencesForSession.sessionSequences) {\n const storedSeqId = storedSequencesForSession.currentSequenceId;\n const lastSequence = storedSequencesForSession.sessionSequences[storedSeqId];\n if (lastSequence && lastSequence.status !== RecordingStatus.RECORDING) {\n this.currentSequenceId = storedSeqId + 1;\n this.events = [];\n } else {\n // Pick up recording where it was left off in another tab or window\n this.currentSequenceId = storedSeqId;\n this.events = lastSequence?.events || [];\n }\n }\n if (shouldSendStoredEvents && storedReplaySessions) {\n this.sendStoredEvents({ storedReplaySessions, deviceId, sessionId });\n }\n }\n\n sendStoredEvents({\n storedReplaySessions,\n sessionId,\n deviceId,\n }: {\n storedReplaySessions: IDBStore;\n sessionId: number;\n deviceId: string;\n }) {\n for (const storedSessionId in storedReplaySessions) {\n const storedSequences = storedReplaySessions[storedSessionId].sessionSequences;\n for (const storedSeqId in storedSequences) {\n const seq = storedSequences[storedSeqId];\n const numericSeqId = parseInt(storedSeqId, 10);\n const numericSessionId = parseInt(storedSessionId, 10);\n if (numericSessionId === sessionId && numericSeqId === this.currentSequenceId) {\n continue;\n }\n\n if (seq.events && seq.events.length && seq.status === RecordingStatus.RECORDING) {\n this.sendEventsList({\n events: seq.events,\n sequenceId: numericSeqId,\n sessionId: numericSessionId,\n deviceId,\n });\n }\n }\n }\n }\n\n resetSequence() {\n this.events = [];\n this.currentSequenceId = 0;\n }\n\n addEvent({ event, sessionId, deviceId }: { event: string; sessionId: number; deviceId: string }) {\n const shouldSplit = this.shouldSplitEventsList(event);\n if (shouldSplit) {\n this.sendEventsList({\n events: this.events,\n sequenceId: this.currentSequenceId,\n sessionId,\n deviceId,\n });\n this.events = [];\n this.currentSequenceId++;\n }\n this.events.push(event);\n void this.sessionIDBStore.storeEventsForSession(this.events, this.currentSequenceId, sessionId);\n }\n\n /**\n * Determines whether to send the events list to the backend and start a new\n * empty events list, based on the size of the list as well as the last time sent\n * @param nextEventString\n * @returns boolean\n */\n shouldSplitEventsList = (nextEventString: string): boolean => {\n const sizeOfNextEvent = new Blob([nextEventString]).size;\n const sizeOfEventsList = new Blob(this.events).size;\n if (sizeOfEventsList + sizeOfNextEvent >= this.maxPersistedEventsSize) {\n return true;\n }\n if (this.timeAtLastSend !== null && Date.now() - this.timeAtLastSend > this.interval && this.events.length) {\n this.interval = Math.min(MAX_INTERVAL, this.interval + MIN_INTERVAL);\n this.timeAtLastSend = Date.now();\n return true;\n }\n return false;\n };\n\n sendEvents({ sessionId, deviceId }: { sessionId: number; deviceId: string }) {\n if (this.events.length && sessionId) {\n this.sendEventsList({\n events: this.events,\n sequenceId: this.currentSequenceId,\n sessionId,\n deviceId,\n });\n }\n }\n\n sendEventsList({\n events,\n sequenceId,\n sessionId,\n deviceId,\n }: {\n events: string[];\n sequenceId: number;\n sessionId: number;\n deviceId: string;\n }) {\n this.trackDestination.sendEventsList({\n events: events,\n sequenceId: sequenceId,\n sessionId: sessionId,\n flushMaxRetries: this.config.flushMaxRetries,\n apiKey: this.config.apiKey,\n deviceId: deviceId,\n sampleRate: this.config.sampleRate,\n serverZone: this.config.serverZone,\n onComplete: this.sessionIDBStore.cleanUpSessionEventsStore.bind(this.sessionIDBStore),\n });\n }\n\n async flush(useRetry = false) {\n if (this.trackDestination) {\n return this.trackDestination.flush(useRetry);\n }\n }\n}\n"]}
|
|
@@ -1,19 +1,13 @@
|
|
|
1
1
|
import { Logger as ILogger } from '@amplitude/analytics-types';
|
|
2
2
|
import { record } from '@amplitude/rrweb';
|
|
3
|
-
import { AmplitudeSessionReplay,
|
|
3
|
+
import { AmplitudeSessionReplay, SessionReplayEventsManager as AmplitudeSessionReplayEventsManager, SessionIdentifiers as ISessionIdentifiers, SessionReplayConfig as ISessionReplayConfig, SessionReplayOptions } from './typings/session-replay';
|
|
4
4
|
export declare class SessionReplay implements AmplitudeSessionReplay {
|
|
5
5
|
name: string;
|
|
6
6
|
config: ISessionReplayConfig | undefined;
|
|
7
7
|
identifiers: ISessionIdentifiers | undefined;
|
|
8
|
-
|
|
9
|
-
sessionIDBStore: AmplitudeSessionReplaySessionIDBStore | undefined;
|
|
8
|
+
eventsManager: AmplitudeSessionReplayEventsManager | undefined;
|
|
10
9
|
loggerProvider: ILogger;
|
|
11
|
-
|
|
12
|
-
currentSequenceId: number;
|
|
13
|
-
stopRecordingEvents: ReturnType<typeof record> | null;
|
|
14
|
-
maxPersistedEventsSize: number;
|
|
15
|
-
interval: number;
|
|
16
|
-
timeAtLastSend: number | null;
|
|
10
|
+
recordCancelCallback: ReturnType<typeof record> | null;
|
|
17
11
|
constructor();
|
|
18
12
|
init(apiKey: string, options: SessionReplayOptions): import("@amplitude/analytics-types").AmplitudeReturn<void>;
|
|
19
13
|
protected _init(apiKey: string, options: SessionReplayOptions): Promise<void>;
|
|
@@ -29,20 +23,8 @@ export declare class SessionReplay implements AmplitudeSessionReplay {
|
|
|
29
23
|
shouldOptOut(): boolean | undefined;
|
|
30
24
|
getShouldRecord(ignoreFocus?: boolean): boolean;
|
|
31
25
|
getBlockSelectors(): string | string[] | undefined;
|
|
32
|
-
sendStoredEvents(storedReplaySessions: IDBStore): void;
|
|
33
26
|
recordEvents(): void;
|
|
34
|
-
|
|
35
|
-
* Determines whether to send the events list to the backend and start a new
|
|
36
|
-
* empty events list, based on the size of the list as well as the last time sent
|
|
37
|
-
* @param nextEventString
|
|
38
|
-
* @returns boolean
|
|
39
|
-
*/
|
|
40
|
-
shouldSplitEventsList: (nextEventString: string) => boolean;
|
|
41
|
-
sendEventsList({ events, sequenceId, sessionId }: {
|
|
42
|
-
events: string[];
|
|
43
|
-
sequenceId: number;
|
|
44
|
-
sessionId: number;
|
|
45
|
-
}): void;
|
|
27
|
+
stopRecordingEvents: () => void;
|
|
46
28
|
getDeviceId(): string | undefined;
|
|
47
29
|
getSessionId(): number | undefined;
|
|
48
30
|
flush(useRetry?: boolean): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-replay.d.ts","sourceRoot":"","sources":["../../src/session-replay.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,IAAI,OAAO,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAQ,MAAM,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"session-replay.d.ts","sourceRoot":"","sources":["../../src/session-replay.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,IAAI,OAAO,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAQ,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAWhD,OAAO,EACL,sBAAsB,EACtB,0BAA0B,IAAI,mCAAmC,EACjE,kBAAkB,IAAI,mBAAmB,EACzC,mBAAmB,IAAI,oBAAoB,EAC3C,oBAAoB,EACrB,MAAM,0BAA0B,CAAC;AAElC,qBAAa,aAAc,YAAW,sBAAsB;IAC1D,IAAI,SAAuC;IAC3C,MAAM,EAAE,oBAAoB,GAAG,SAAS,CAAC;IACzC,WAAW,EAAE,mBAAmB,GAAG,SAAS,CAAC;IAC7C,aAAa,EAAE,mCAAmC,GAAG,SAAS,CAAC;IAC/D,cAAc,EAAE,OAAO,CAAC;IACxB,oBAAoB,EAAE,UAAU,CAAC,OAAO,MAAM,CAAC,GAAG,IAAI,CAAQ;;IAM9D,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,oBAAoB;cAIlC,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,oBAAoB;IAsBnE,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM;IAwBjD,kCAAkC;IAUlC,0BAA0B;;;IAwB1B,YAAY,aAEV;IAEF,aAAa,aAEX;IAEF,0BAA0B,CAAC,SAAS,CAAC,EAAE,MAAM;IAWvC,UAAU,CAAC,sBAAsB,UAAQ;IAkB/C,YAAY;IAUZ,eAAe,CAAC,WAAW,UAAQ;IA8BnC,iBAAiB,IAAI,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS;IAIlD,YAAY;IAmCZ,mBAAmB,aAQjB;IAEF,WAAW;IAUX,YAAY;IAIN,KAAK,CAAC,QAAQ,UAAQ;IAM5B,QAAQ;CAST"}
|
|
@@ -6,48 +6,31 @@ var analytics_core_1 = require("@amplitude/analytics-core");
|
|
|
6
6
|
var rrweb_1 = require("@amplitude/rrweb");
|
|
7
7
|
var config_1 = require("./config");
|
|
8
8
|
var constants_1 = require("./constants");
|
|
9
|
+
var events_manager_1 = require("./events-manager");
|
|
9
10
|
var helpers_1 = require("./helpers");
|
|
10
11
|
var identifiers_1 = require("./identifiers");
|
|
11
|
-
var session_idb_store_1 = require("./session-idb-store");
|
|
12
|
-
var track_destination_1 = require("./track-destination");
|
|
13
|
-
var session_replay_1 = require("./typings/session-replay");
|
|
14
12
|
var SessionReplay = /** @class */ (function () {
|
|
15
13
|
function SessionReplay() {
|
|
16
14
|
var _this = this;
|
|
17
15
|
this.name = '@amplitude/session-replay-browser';
|
|
18
|
-
this.
|
|
19
|
-
this.currentSequenceId = 0;
|
|
20
|
-
this.stopRecordingEvents = null;
|
|
21
|
-
this.maxPersistedEventsSize = constants_1.MAX_EVENT_LIST_SIZE_IN_BYTES;
|
|
22
|
-
this.interval = constants_1.MIN_INTERVAL;
|
|
23
|
-
this.timeAtLastSend = null;
|
|
16
|
+
this.recordCancelCallback = null;
|
|
24
17
|
this.blurListener = function () {
|
|
25
18
|
_this.stopRecordingAndSendEvents();
|
|
26
19
|
};
|
|
27
20
|
this.focusListener = function () {
|
|
28
21
|
void _this.initialize();
|
|
29
22
|
};
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
* @returns boolean
|
|
35
|
-
*/
|
|
36
|
-
this.shouldSplitEventsList = function (nextEventString) {
|
|
37
|
-
var sizeOfNextEvent = new Blob([nextEventString]).size;
|
|
38
|
-
var sizeOfEventsList = new Blob(_this.events).size;
|
|
39
|
-
if (sizeOfEventsList + sizeOfNextEvent >= _this.maxPersistedEventsSize) {
|
|
40
|
-
return true;
|
|
23
|
+
this.stopRecordingEvents = function () {
|
|
24
|
+
try {
|
|
25
|
+
_this.recordCancelCallback && _this.recordCancelCallback();
|
|
26
|
+
_this.recordCancelCallback = null;
|
|
41
27
|
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
_this.
|
|
45
|
-
return true;
|
|
28
|
+
catch (error) {
|
|
29
|
+
var typedError = error;
|
|
30
|
+
_this.loggerProvider.warn("Error occurred while stopping recording: ".concat(typedError.toString()));
|
|
46
31
|
}
|
|
47
|
-
return false;
|
|
48
32
|
};
|
|
49
33
|
this.loggerProvider = new analytics_core_1.Logger();
|
|
50
|
-
this.trackDestination = new track_destination_1.SessionReplayTrackDestination({ loggerProvider: this.loggerProvider });
|
|
51
34
|
}
|
|
52
35
|
SessionReplay.prototype.init = function (apiKey, options) {
|
|
53
36
|
return (0, analytics_core_1.returnWrapper)(this._init(apiKey, options));
|
|
@@ -61,11 +44,8 @@ var SessionReplay = /** @class */ (function () {
|
|
|
61
44
|
this.config = new config_1.SessionReplayConfig(apiKey, options);
|
|
62
45
|
this.loggerProvider = this.config.loggerProvider;
|
|
63
46
|
this.identifiers = new identifiers_1.SessionIdentifiers(options, this.loggerProvider);
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
this.sessionIDBStore = new session_idb_store_1.SessionReplaySessionIDBStore({
|
|
67
|
-
loggerProvider: this.loggerProvider,
|
|
68
|
-
apiKey: this.config.apiKey,
|
|
47
|
+
this.eventsManager = new events_manager_1.SessionReplayEventsManager({
|
|
48
|
+
config: this.config,
|
|
69
49
|
});
|
|
70
50
|
this.loggerProvider.log('Installing @amplitude/session-replay-browser.');
|
|
71
51
|
globalScope = (0, analytics_client_common_1.getGlobalScope)();
|
|
@@ -102,8 +82,7 @@ var SessionReplay = /** @class */ (function () {
|
|
|
102
82
|
}
|
|
103
83
|
this.stopRecordingAndSendEvents(this.identifiers.sessionId);
|
|
104
84
|
this.identifiers.sessionId = sessionId;
|
|
105
|
-
this.
|
|
106
|
-
this.currentSequenceId = 0;
|
|
85
|
+
this.eventsManager && this.eventsManager.resetSequence();
|
|
107
86
|
this.recordEvents();
|
|
108
87
|
};
|
|
109
88
|
SessionReplay.prototype.getSessionReplayDebugPropertyValue = function () {
|
|
@@ -138,67 +117,40 @@ var SessionReplay = /** @class */ (function () {
|
|
|
138
117
|
};
|
|
139
118
|
SessionReplay.prototype.stopRecordingAndSendEvents = function (sessionId) {
|
|
140
119
|
var _a;
|
|
141
|
-
|
|
142
|
-
this.stopRecordingEvents && this.stopRecordingEvents();
|
|
143
|
-
this.stopRecordingEvents = null;
|
|
144
|
-
}
|
|
145
|
-
catch (error) {
|
|
146
|
-
var typedError = error;
|
|
147
|
-
this.loggerProvider.warn("Error occurred while stopping recording: ".concat(typedError.toString()));
|
|
148
|
-
}
|
|
120
|
+
this.stopRecordingEvents();
|
|
149
121
|
var sessionIdToSend = sessionId || ((_a = this.identifiers) === null || _a === void 0 ? void 0 : _a.sessionId);
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
});
|
|
156
|
-
}
|
|
122
|
+
var deviceId = this.getDeviceId();
|
|
123
|
+
this.eventsManager &&
|
|
124
|
+
sessionIdToSend &&
|
|
125
|
+
deviceId &&
|
|
126
|
+
this.eventsManager.sendEvents({ sessionId: sessionIdToSend, deviceId: deviceId });
|
|
157
127
|
};
|
|
158
128
|
SessionReplay.prototype.initialize = function (shouldSendStoredEvents) {
|
|
159
129
|
var _a;
|
|
160
130
|
if (shouldSendStoredEvents === void 0) { shouldSendStoredEvents = false; }
|
|
161
131
|
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
162
|
-
var
|
|
132
|
+
var deviceId, _b;
|
|
163
133
|
return tslib_1.__generator(this, function (_c) {
|
|
164
134
|
switch (_c.label) {
|
|
165
135
|
case 0:
|
|
166
|
-
this.timeAtLastSend = Date.now(); // Initialize this so we have a point of comparison when events are recorded
|
|
167
136
|
if (!((_a = this.identifiers) === null || _a === void 0 ? void 0 : _a.sessionId)) {
|
|
168
137
|
this.loggerProvider.warn("Session is not being recorded due to lack of session id.");
|
|
169
138
|
return [2 /*return*/];
|
|
170
139
|
}
|
|
171
|
-
|
|
140
|
+
deviceId = this.getDeviceId();
|
|
141
|
+
_b = this.eventsManager &&
|
|
142
|
+
deviceId;
|
|
172
143
|
if (!_b) return [3 /*break*/, 2];
|
|
173
|
-
return [4 /*yield*/, this.
|
|
144
|
+
return [4 /*yield*/, this.eventsManager.initialize({
|
|
145
|
+
sessionId: this.identifiers.sessionId,
|
|
146
|
+
shouldSendStoredEvents: shouldSendStoredEvents,
|
|
147
|
+
deviceId: deviceId,
|
|
148
|
+
})];
|
|
174
149
|
case 1:
|
|
175
150
|
_b = (_c.sent());
|
|
176
151
|
_c.label = 2;
|
|
177
152
|
case 2:
|
|
178
|
-
|
|
179
|
-
// This resolves a timing issue when focus is fired multiple times in short succession,
|
|
180
|
-
// we only want the rest of this function to run once. We can be sure that initialize has
|
|
181
|
-
// already been called if this.stopRecordingEvents is defined
|
|
182
|
-
if (this.stopRecordingEvents) {
|
|
183
|
-
return [2 /*return*/];
|
|
184
|
-
}
|
|
185
|
-
storedSequencesForSession = storedReplaySessions && storedReplaySessions[this.identifiers.sessionId];
|
|
186
|
-
if (storedReplaySessions && storedSequencesForSession && storedSequencesForSession.sessionSequences) {
|
|
187
|
-
storedSeqId = storedSequencesForSession.currentSequenceId;
|
|
188
|
-
lastSequence = storedSequencesForSession.sessionSequences[storedSeqId];
|
|
189
|
-
if (lastSequence && lastSequence.status !== session_replay_1.RecordingStatus.RECORDING) {
|
|
190
|
-
this.currentSequenceId = storedSeqId + 1;
|
|
191
|
-
this.events = [];
|
|
192
|
-
}
|
|
193
|
-
else {
|
|
194
|
-
// Pick up recording where it was left off in another tab or window
|
|
195
|
-
this.currentSequenceId = storedSeqId;
|
|
196
|
-
this.events = (lastSequence === null || lastSequence === void 0 ? void 0 : lastSequence.events) || [];
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
if (shouldSendStoredEvents && storedReplaySessions) {
|
|
200
|
-
this.sendStoredEvents(storedReplaySessions);
|
|
201
|
-
}
|
|
153
|
+
_b;
|
|
202
154
|
this.recordEvents();
|
|
203
155
|
return [2 /*return*/];
|
|
204
156
|
}
|
|
@@ -247,27 +199,6 @@ var SessionReplay = /** @class */ (function () {
|
|
|
247
199
|
var _a, _b;
|
|
248
200
|
return (_b = (_a = this.config) === null || _a === void 0 ? void 0 : _a.privacyConfig) === null || _b === void 0 ? void 0 : _b.blockSelector;
|
|
249
201
|
};
|
|
250
|
-
SessionReplay.prototype.sendStoredEvents = function (storedReplaySessions) {
|
|
251
|
-
var _a;
|
|
252
|
-
for (var sessionId in storedReplaySessions) {
|
|
253
|
-
var storedSequences = storedReplaySessions[sessionId].sessionSequences;
|
|
254
|
-
for (var storedSeqId in storedSequences) {
|
|
255
|
-
var seq = storedSequences[storedSeqId];
|
|
256
|
-
var numericSeqId = parseInt(storedSeqId, 10);
|
|
257
|
-
var numericSessionId = parseInt(sessionId, 10);
|
|
258
|
-
if (numericSessionId === ((_a = this.identifiers) === null || _a === void 0 ? void 0 : _a.sessionId) && numericSeqId === this.currentSequenceId) {
|
|
259
|
-
continue;
|
|
260
|
-
}
|
|
261
|
-
if (seq.events && seq.events.length && seq.status === session_replay_1.RecordingStatus.RECORDING) {
|
|
262
|
-
this.sendEventsList({
|
|
263
|
-
events: seq.events,
|
|
264
|
-
sequenceId: numericSeqId,
|
|
265
|
-
sessionId: numericSessionId,
|
|
266
|
-
});
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
};
|
|
271
202
|
SessionReplay.prototype.recordEvents = function () {
|
|
272
203
|
var _this = this;
|
|
273
204
|
var _a;
|
|
@@ -276,7 +207,8 @@ var SessionReplay = /** @class */ (function () {
|
|
|
276
207
|
if (!shouldRecord || !sessionId) {
|
|
277
208
|
return;
|
|
278
209
|
}
|
|
279
|
-
this.stopRecordingEvents
|
|
210
|
+
this.stopRecordingEvents();
|
|
211
|
+
this.recordCancelCallback = (0, rrweb_1.record)({
|
|
280
212
|
emit: function (event) {
|
|
281
213
|
var globalScope = (0, analytics_client_common_1.getGlobalScope)();
|
|
282
214
|
if ((globalScope && globalScope.document && !globalScope.document.hasFocus()) || !_this.getShouldRecord()) {
|
|
@@ -284,19 +216,8 @@ var SessionReplay = /** @class */ (function () {
|
|
|
284
216
|
return;
|
|
285
217
|
}
|
|
286
218
|
var eventString = JSON.stringify(event);
|
|
287
|
-
var
|
|
288
|
-
|
|
289
|
-
_this.sendEventsList({
|
|
290
|
-
events: _this.events,
|
|
291
|
-
sequenceId: _this.currentSequenceId,
|
|
292
|
-
sessionId: sessionId,
|
|
293
|
-
});
|
|
294
|
-
_this.events = [];
|
|
295
|
-
_this.currentSequenceId++;
|
|
296
|
-
}
|
|
297
|
-
_this.events.push(eventString);
|
|
298
|
-
_this.sessionIDBStore &&
|
|
299
|
-
void _this.sessionIDBStore.storeEventsForSession(_this.events, _this.currentSequenceId, sessionId);
|
|
219
|
+
var deviceId = _this.getDeviceId();
|
|
220
|
+
deviceId && _this.eventsManager && _this.eventsManager.addEvent({ event: eventString, sessionId: sessionId, deviceId: deviceId });
|
|
300
221
|
},
|
|
301
222
|
packFn: rrweb_1.pack,
|
|
302
223
|
maskAllInputs: true,
|
|
@@ -313,24 +234,6 @@ var SessionReplay = /** @class */ (function () {
|
|
|
313
234
|
},
|
|
314
235
|
});
|
|
315
236
|
};
|
|
316
|
-
SessionReplay.prototype.sendEventsList = function (_a) {
|
|
317
|
-
var events = _a.events, sequenceId = _a.sequenceId, sessionId = _a.sessionId;
|
|
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({
|
|
323
|
-
events: events,
|
|
324
|
-
sequenceId: sequenceId,
|
|
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),
|
|
332
|
-
});
|
|
333
|
-
};
|
|
334
237
|
SessionReplay.prototype.getDeviceId = function () {
|
|
335
238
|
var _a, _b;
|
|
336
239
|
var identityStoreDeviceId;
|
|
@@ -348,8 +251,8 @@ var SessionReplay = /** @class */ (function () {
|
|
|
348
251
|
if (useRetry === void 0) { useRetry = false; }
|
|
349
252
|
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
350
253
|
return tslib_1.__generator(this, function (_a) {
|
|
351
|
-
if (this.
|
|
352
|
-
return [2 /*return*/, this.
|
|
254
|
+
if (this.eventsManager) {
|
|
255
|
+
return [2 /*return*/, this.eventsManager.flush(useRetry)];
|
|
353
256
|
}
|
|
354
257
|
return [2 /*return*/];
|
|
355
258
|
});
|