@openreplay/tracker 16.4.2 → 16.4.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.
- package/dist/cjs/entry.js +167 -166
- package/dist/cjs/entry.js.map +1 -1
- package/dist/cjs/index.js +167 -166
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/main/app/index.d.ts +5 -5
- package/dist/lib/entry.js +167 -166
- package/dist/lib/entry.js.map +1 -1
- package/dist/lib/index.js +167 -166
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/main/app/index.d.ts +5 -5
- package/dist/types/main/app/index.d.ts +5 -5
- package/package.json +1 -1
package/dist/cjs/entry.js
CHANGED
|
@@ -5098,15 +5098,16 @@ class Session {
|
|
|
5098
5098
|
this.userInfo = userInfo;
|
|
5099
5099
|
}
|
|
5100
5100
|
getSessionToken(projectKey) {
|
|
5101
|
-
const
|
|
5102
|
-
if (projectKey &&
|
|
5103
|
-
const savedProject =
|
|
5101
|
+
const tokenWithProject = this.token || this.app.sessionStorage.getItem(this.options.session_token_key);
|
|
5102
|
+
if (projectKey && tokenWithProject) {
|
|
5103
|
+
const savedProject = tokenWithProject.split('_&_')[1];
|
|
5104
5104
|
if (!savedProject || savedProject !== projectKey) {
|
|
5105
5105
|
this.app.sessionStorage.removeItem(this.options.session_token_key);
|
|
5106
5106
|
this.token = undefined;
|
|
5107
5107
|
return undefined;
|
|
5108
5108
|
}
|
|
5109
5109
|
}
|
|
5110
|
+
const token = tokenWithProject ? tokenWithProject.split('_&_')[0] : null;
|
|
5110
5111
|
return token || undefined;
|
|
5111
5112
|
}
|
|
5112
5113
|
setSessionToken(token, projectKey) {
|
|
@@ -5275,7 +5276,7 @@ class App {
|
|
|
5275
5276
|
this.stopCallbacks = [];
|
|
5276
5277
|
this.commitCallbacks = [];
|
|
5277
5278
|
this.activityState = ActivityState.NotActive;
|
|
5278
|
-
this.version = '16.4.
|
|
5279
|
+
this.version = '16.4.3'; // TODO: version compatability check inside each plugin.
|
|
5279
5280
|
this.socketMode = false;
|
|
5280
5281
|
this.compressionThreshold = 24 * 1000;
|
|
5281
5282
|
this.bc = null;
|
|
@@ -5563,9 +5564,170 @@ class App {
|
|
|
5563
5564
|
this.orderNumber = 0;
|
|
5564
5565
|
this.coldStartTs = 0;
|
|
5565
5566
|
this.singleBuffer = false;
|
|
5567
|
+
/**
|
|
5568
|
+
* start buffering messages without starting the actual session, which gives
|
|
5569
|
+
* user 30 seconds to "activate" and record session by calling `start()` on conditional trigger,
|
|
5570
|
+
* and we will then send buffered batch, so it won't get lost
|
|
5571
|
+
* */
|
|
5572
|
+
this.coldStart = async (startOpts = {}, conditional) => {
|
|
5573
|
+
this.singleBuffer = false;
|
|
5574
|
+
const second = 1000;
|
|
5575
|
+
const isNewSession = this.checkSessionToken(startOpts.forceNew);
|
|
5576
|
+
if (conditional) {
|
|
5577
|
+
await this.setupConditionalStart(startOpts);
|
|
5578
|
+
}
|
|
5579
|
+
const cycle = () => {
|
|
5580
|
+
this.orderNumber += 1;
|
|
5581
|
+
adjustTimeOrigin();
|
|
5582
|
+
this.coldStartTs = now();
|
|
5583
|
+
if (this.orderNumber % 2 === 0) {
|
|
5584
|
+
this.bufferedMessages1.length = 0;
|
|
5585
|
+
this.bufferedMessages1.push(Timestamp(this.timestamp()));
|
|
5586
|
+
this.bufferedMessages1.push(TabData(this.session.getTabId()));
|
|
5587
|
+
}
|
|
5588
|
+
else {
|
|
5589
|
+
this.bufferedMessages2.length = 0;
|
|
5590
|
+
this.bufferedMessages2.push(Timestamp(this.timestamp()));
|
|
5591
|
+
this.bufferedMessages2.push(TabData(this.session.getTabId()));
|
|
5592
|
+
}
|
|
5593
|
+
this.stop(false);
|
|
5594
|
+
this.activityState = ActivityState.ColdStart;
|
|
5595
|
+
if (startOpts.sessionHash) {
|
|
5596
|
+
this.session.applySessionHash(startOpts.sessionHash);
|
|
5597
|
+
}
|
|
5598
|
+
if (startOpts.forceNew) {
|
|
5599
|
+
this.session.reset();
|
|
5600
|
+
}
|
|
5601
|
+
this.session.assign({
|
|
5602
|
+
userID: startOpts.userID,
|
|
5603
|
+
metadata: startOpts.metadata,
|
|
5604
|
+
});
|
|
5605
|
+
if (!isNewSession) {
|
|
5606
|
+
this.debug.log('continuing session on new tab', this.session.getTabId());
|
|
5607
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
5608
|
+
this.send(TabChange(this.session.getTabId()));
|
|
5609
|
+
}
|
|
5610
|
+
this.observer.observe();
|
|
5611
|
+
this.ticker.start();
|
|
5612
|
+
};
|
|
5613
|
+
this.coldInterval = setInterval(() => {
|
|
5614
|
+
cycle();
|
|
5615
|
+
}, 30 * second);
|
|
5616
|
+
cycle();
|
|
5617
|
+
};
|
|
5618
|
+
this.setupConditionalStart = async (startOpts) => {
|
|
5619
|
+
this.conditionsManager = new ConditionsManager(this, startOpts);
|
|
5620
|
+
const r = await fetch(this.options.ingestPoint + '/v1/web/start', {
|
|
5621
|
+
method: 'POST',
|
|
5622
|
+
headers: {
|
|
5623
|
+
'Content-Type': 'application/json',
|
|
5624
|
+
},
|
|
5625
|
+
body: JSON.stringify({
|
|
5626
|
+
...this.getTrackerInfo(),
|
|
5627
|
+
timestamp: now(),
|
|
5628
|
+
doNotRecord: true,
|
|
5629
|
+
bufferDiff: 0,
|
|
5630
|
+
userID: this.session.getInfo().userID,
|
|
5631
|
+
token: undefined,
|
|
5632
|
+
deviceMemory,
|
|
5633
|
+
jsHeapSizeLimit,
|
|
5634
|
+
timezone: getTimezone(),
|
|
5635
|
+
width: window.screen.width,
|
|
5636
|
+
height: window.screen.height,
|
|
5637
|
+
}),
|
|
5638
|
+
});
|
|
5639
|
+
const {
|
|
5640
|
+
// this token is needed to fetch conditions and flags,
|
|
5641
|
+
// but it can't be used to record a session
|
|
5642
|
+
token, userBrowser, userCity, userCountry, userDevice, userOS, userState, projectID, features, } = await r.json();
|
|
5643
|
+
this.features = features ? features : this.features;
|
|
5644
|
+
this.session.assign({ projectID });
|
|
5645
|
+
this.session.setUserInfo({
|
|
5646
|
+
userBrowser,
|
|
5647
|
+
userCity,
|
|
5648
|
+
userCountry,
|
|
5649
|
+
userDevice,
|
|
5650
|
+
userOS,
|
|
5651
|
+
userState,
|
|
5652
|
+
});
|
|
5653
|
+
const onStartInfo = { sessionToken: token, userUUID: '', sessionID: '' };
|
|
5654
|
+
this.startCallbacks.forEach((cb) => cb(onStartInfo));
|
|
5655
|
+
await this.conditionsManager?.fetchConditions(projectID, token);
|
|
5656
|
+
if (this.features['feature-flags']) {
|
|
5657
|
+
await this.featureFlags.reloadFlags(token);
|
|
5658
|
+
this.conditionsManager?.processFlags(this.featureFlags.flags);
|
|
5659
|
+
}
|
|
5660
|
+
await this.tagWatcher.fetchTags(this.options.ingestPoint, token);
|
|
5661
|
+
};
|
|
5566
5662
|
this.onSessionSent = () => {
|
|
5567
5663
|
return;
|
|
5568
5664
|
};
|
|
5665
|
+
/**
|
|
5666
|
+
* Starts offline session recording
|
|
5667
|
+
* @param {Object} startOpts - options for session start, same as .start()
|
|
5668
|
+
* @param {Function} onSessionSent - callback that will be called once session is fully sent
|
|
5669
|
+
* */
|
|
5670
|
+
this.offlineRecording = (startOpts = {}, onSessionSent) => {
|
|
5671
|
+
this.onSessionSent = onSessionSent;
|
|
5672
|
+
this.singleBuffer = true;
|
|
5673
|
+
const isNewSession = this.checkSessionToken(startOpts.forceNew);
|
|
5674
|
+
adjustTimeOrigin();
|
|
5675
|
+
this.coldStartTs = now();
|
|
5676
|
+
const saverBuffer = this.localStorage.getItem(bufferStorageKey);
|
|
5677
|
+
if (saverBuffer) {
|
|
5678
|
+
const data = JSON.parse(saverBuffer);
|
|
5679
|
+
this.bufferedMessages1 = Array.isArray(data) ? data : this.bufferedMessages1;
|
|
5680
|
+
this.localStorage.removeItem(bufferStorageKey);
|
|
5681
|
+
}
|
|
5682
|
+
this.bufferedMessages1.push(Timestamp(this.timestamp()));
|
|
5683
|
+
this.bufferedMessages1.push(TabData(this.session.getTabId()));
|
|
5684
|
+
this.activityState = ActivityState.ColdStart;
|
|
5685
|
+
if (startOpts.sessionHash) {
|
|
5686
|
+
this.session.applySessionHash(startOpts.sessionHash);
|
|
5687
|
+
}
|
|
5688
|
+
if (startOpts.forceNew) {
|
|
5689
|
+
this.session.reset();
|
|
5690
|
+
}
|
|
5691
|
+
this.session.assign({
|
|
5692
|
+
userID: startOpts.userID,
|
|
5693
|
+
metadata: startOpts.metadata,
|
|
5694
|
+
});
|
|
5695
|
+
const onStartInfo = { sessionToken: '', userUUID: '', sessionID: '' };
|
|
5696
|
+
this.startCallbacks.forEach((cb) => cb(onStartInfo));
|
|
5697
|
+
if (!isNewSession) {
|
|
5698
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
5699
|
+
this.send(TabChange(this.session.getTabId()));
|
|
5700
|
+
}
|
|
5701
|
+
this.observer.observe();
|
|
5702
|
+
this.ticker.start();
|
|
5703
|
+
return {
|
|
5704
|
+
saveBuffer: this.saveBuffer,
|
|
5705
|
+
getBuffer: this.getBuffer,
|
|
5706
|
+
setBuffer: this.setBuffer,
|
|
5707
|
+
};
|
|
5708
|
+
};
|
|
5709
|
+
/**
|
|
5710
|
+
* Saves the captured messages in localStorage (or whatever is used in its place)
|
|
5711
|
+
*
|
|
5712
|
+
* Then, when this.offlineRecording is called, it will preload this messages and clear the storage item
|
|
5713
|
+
*
|
|
5714
|
+
* Keeping the size of local storage reasonable is up to the end users of this library
|
|
5715
|
+
* */
|
|
5716
|
+
this.saveBuffer = () => {
|
|
5717
|
+
this.localStorage.setItem(bufferStorageKey, JSON.stringify(this.bufferedMessages1));
|
|
5718
|
+
};
|
|
5719
|
+
/**
|
|
5720
|
+
* @returns buffer with stored messages for offline recording
|
|
5721
|
+
* */
|
|
5722
|
+
this.getBuffer = () => {
|
|
5723
|
+
return this.bufferedMessages1;
|
|
5724
|
+
};
|
|
5725
|
+
/**
|
|
5726
|
+
* Used to set a buffer with messages array
|
|
5727
|
+
* */
|
|
5728
|
+
this.setBuffer = (buffer) => {
|
|
5729
|
+
this.bufferedMessages1 = buffer;
|
|
5730
|
+
};
|
|
5569
5731
|
this.prevOpts = {};
|
|
5570
5732
|
this.restartCanvasTracking = () => {
|
|
5571
5733
|
this.canvasRecorder?.restartTracking();
|
|
@@ -6072,167 +6234,6 @@ class App {
|
|
|
6072
6234
|
const sessionToken = this.session.getSessionToken(this.projectKey);
|
|
6073
6235
|
return needNewSessionID || !sessionToken;
|
|
6074
6236
|
}
|
|
6075
|
-
/**
|
|
6076
|
-
* start buffering messages without starting the actual session, which gives
|
|
6077
|
-
* user 30 seconds to "activate" and record session by calling `start()` on conditional trigger,
|
|
6078
|
-
* and we will then send buffered batch, so it won't get lost
|
|
6079
|
-
* */
|
|
6080
|
-
async coldStart(startOpts = {}, conditional) {
|
|
6081
|
-
this.singleBuffer = false;
|
|
6082
|
-
const second = 1000;
|
|
6083
|
-
const isNewSession = this.checkSessionToken(startOpts.forceNew);
|
|
6084
|
-
if (conditional) {
|
|
6085
|
-
await this.setupConditionalStart(startOpts);
|
|
6086
|
-
}
|
|
6087
|
-
const cycle = () => {
|
|
6088
|
-
this.orderNumber += 1;
|
|
6089
|
-
adjustTimeOrigin();
|
|
6090
|
-
this.coldStartTs = now();
|
|
6091
|
-
if (this.orderNumber % 2 === 0) {
|
|
6092
|
-
this.bufferedMessages1.length = 0;
|
|
6093
|
-
this.bufferedMessages1.push(Timestamp(this.timestamp()));
|
|
6094
|
-
this.bufferedMessages1.push(TabData(this.session.getTabId()));
|
|
6095
|
-
}
|
|
6096
|
-
else {
|
|
6097
|
-
this.bufferedMessages2.length = 0;
|
|
6098
|
-
this.bufferedMessages2.push(Timestamp(this.timestamp()));
|
|
6099
|
-
this.bufferedMessages2.push(TabData(this.session.getTabId()));
|
|
6100
|
-
}
|
|
6101
|
-
this.stop(false);
|
|
6102
|
-
this.activityState = ActivityState.ColdStart;
|
|
6103
|
-
if (startOpts.sessionHash) {
|
|
6104
|
-
this.session.applySessionHash(startOpts.sessionHash);
|
|
6105
|
-
}
|
|
6106
|
-
if (startOpts.forceNew) {
|
|
6107
|
-
this.session.reset();
|
|
6108
|
-
}
|
|
6109
|
-
this.session.assign({
|
|
6110
|
-
userID: startOpts.userID,
|
|
6111
|
-
metadata: startOpts.metadata,
|
|
6112
|
-
});
|
|
6113
|
-
if (!isNewSession) {
|
|
6114
|
-
this.debug.log('continuing session on new tab', this.session.getTabId());
|
|
6115
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
6116
|
-
this.send(TabChange(this.session.getTabId()));
|
|
6117
|
-
}
|
|
6118
|
-
this.observer.observe();
|
|
6119
|
-
this.ticker.start();
|
|
6120
|
-
};
|
|
6121
|
-
this.coldInterval = setInterval(() => {
|
|
6122
|
-
cycle();
|
|
6123
|
-
}, 30 * second);
|
|
6124
|
-
cycle();
|
|
6125
|
-
}
|
|
6126
|
-
async setupConditionalStart(startOpts) {
|
|
6127
|
-
this.conditionsManager = new ConditionsManager(this, startOpts);
|
|
6128
|
-
const r = await fetch(this.options.ingestPoint + '/v1/web/start', {
|
|
6129
|
-
method: 'POST',
|
|
6130
|
-
headers: {
|
|
6131
|
-
'Content-Type': 'application/json',
|
|
6132
|
-
},
|
|
6133
|
-
body: JSON.stringify({
|
|
6134
|
-
...this.getTrackerInfo(),
|
|
6135
|
-
timestamp: now(),
|
|
6136
|
-
doNotRecord: true,
|
|
6137
|
-
bufferDiff: 0,
|
|
6138
|
-
userID: this.session.getInfo().userID,
|
|
6139
|
-
token: undefined,
|
|
6140
|
-
deviceMemory,
|
|
6141
|
-
jsHeapSizeLimit,
|
|
6142
|
-
timezone: getTimezone(),
|
|
6143
|
-
width: window.screen.width,
|
|
6144
|
-
height: window.screen.height,
|
|
6145
|
-
}),
|
|
6146
|
-
});
|
|
6147
|
-
const {
|
|
6148
|
-
// this token is needed to fetch conditions and flags,
|
|
6149
|
-
// but it can't be used to record a session
|
|
6150
|
-
token, userBrowser, userCity, userCountry, userDevice, userOS, userState, projectID, features, } = await r.json();
|
|
6151
|
-
this.features = features ? features : this.features;
|
|
6152
|
-
this.session.assign({ projectID });
|
|
6153
|
-
this.session.setUserInfo({
|
|
6154
|
-
userBrowser,
|
|
6155
|
-
userCity,
|
|
6156
|
-
userCountry,
|
|
6157
|
-
userDevice,
|
|
6158
|
-
userOS,
|
|
6159
|
-
userState,
|
|
6160
|
-
});
|
|
6161
|
-
const onStartInfo = { sessionToken: token, userUUID: '', sessionID: '' };
|
|
6162
|
-
this.startCallbacks.forEach((cb) => cb(onStartInfo));
|
|
6163
|
-
await this.conditionsManager?.fetchConditions(projectID, token);
|
|
6164
|
-
if (this.features['feature-flags']) {
|
|
6165
|
-
await this.featureFlags.reloadFlags(token);
|
|
6166
|
-
this.conditionsManager?.processFlags(this.featureFlags.flags);
|
|
6167
|
-
}
|
|
6168
|
-
await this.tagWatcher.fetchTags(this.options.ingestPoint, token);
|
|
6169
|
-
}
|
|
6170
|
-
/**
|
|
6171
|
-
* Starts offline session recording
|
|
6172
|
-
* @param {Object} startOpts - options for session start, same as .start()
|
|
6173
|
-
* @param {Function} onSessionSent - callback that will be called once session is fully sent
|
|
6174
|
-
* */
|
|
6175
|
-
offlineRecording(startOpts = {}, onSessionSent) {
|
|
6176
|
-
this.onSessionSent = onSessionSent;
|
|
6177
|
-
this.singleBuffer = true;
|
|
6178
|
-
const isNewSession = this.checkSessionToken(startOpts.forceNew);
|
|
6179
|
-
adjustTimeOrigin();
|
|
6180
|
-
this.coldStartTs = now();
|
|
6181
|
-
const saverBuffer = this.localStorage.getItem(bufferStorageKey);
|
|
6182
|
-
if (saverBuffer) {
|
|
6183
|
-
const data = JSON.parse(saverBuffer);
|
|
6184
|
-
this.bufferedMessages1 = Array.isArray(data) ? data : this.bufferedMessages1;
|
|
6185
|
-
this.localStorage.removeItem(bufferStorageKey);
|
|
6186
|
-
}
|
|
6187
|
-
this.bufferedMessages1.push(Timestamp(this.timestamp()));
|
|
6188
|
-
this.bufferedMessages1.push(TabData(this.session.getTabId()));
|
|
6189
|
-
this.activityState = ActivityState.ColdStart;
|
|
6190
|
-
if (startOpts.sessionHash) {
|
|
6191
|
-
this.session.applySessionHash(startOpts.sessionHash);
|
|
6192
|
-
}
|
|
6193
|
-
if (startOpts.forceNew) {
|
|
6194
|
-
this.session.reset();
|
|
6195
|
-
}
|
|
6196
|
-
this.session.assign({
|
|
6197
|
-
userID: startOpts.userID,
|
|
6198
|
-
metadata: startOpts.metadata,
|
|
6199
|
-
});
|
|
6200
|
-
const onStartInfo = { sessionToken: '', userUUID: '', sessionID: '' };
|
|
6201
|
-
this.startCallbacks.forEach((cb) => cb(onStartInfo));
|
|
6202
|
-
if (!isNewSession) {
|
|
6203
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
6204
|
-
this.send(TabChange(this.session.getTabId()));
|
|
6205
|
-
}
|
|
6206
|
-
this.observer.observe();
|
|
6207
|
-
this.ticker.start();
|
|
6208
|
-
return {
|
|
6209
|
-
saveBuffer: this.saveBuffer,
|
|
6210
|
-
getBuffer: this.getBuffer,
|
|
6211
|
-
setBuffer: this.setBuffer,
|
|
6212
|
-
};
|
|
6213
|
-
}
|
|
6214
|
-
/**
|
|
6215
|
-
* Saves the captured messages in localStorage (or whatever is used in its place)
|
|
6216
|
-
*
|
|
6217
|
-
* Then, when this.offlineRecording is called, it will preload this messages and clear the storage item
|
|
6218
|
-
*
|
|
6219
|
-
* Keeping the size of local storage reasonable is up to the end users of this library
|
|
6220
|
-
* */
|
|
6221
|
-
saveBuffer() {
|
|
6222
|
-
this.localStorage.setItem(bufferStorageKey, JSON.stringify(this.bufferedMessages1));
|
|
6223
|
-
}
|
|
6224
|
-
/**
|
|
6225
|
-
* @returns buffer with stored messages for offline recording
|
|
6226
|
-
* */
|
|
6227
|
-
getBuffer() {
|
|
6228
|
-
return this.bufferedMessages1;
|
|
6229
|
-
}
|
|
6230
|
-
/**
|
|
6231
|
-
* Used to set a buffer with messages array
|
|
6232
|
-
* */
|
|
6233
|
-
setBuffer(buffer) {
|
|
6234
|
-
this.bufferedMessages1 = buffer;
|
|
6235
|
-
}
|
|
6236
6237
|
/**
|
|
6237
6238
|
* Uploads the stored session buffer to backend
|
|
6238
6239
|
* @returns promise that resolves once messages are loaded, it has to be awaited
|
|
@@ -9655,7 +9656,7 @@ class API {
|
|
|
9655
9656
|
this.signalStartIssue = (reason, missingApi) => {
|
|
9656
9657
|
const doNotTrack = this.checkDoNotTrack();
|
|
9657
9658
|
console.log("Tracker couldn't start due to:", JSON.stringify({
|
|
9658
|
-
trackerVersion: '16.4.
|
|
9659
|
+
trackerVersion: '16.4.3',
|
|
9659
9660
|
projectKey: this.options.projectKey,
|
|
9660
9661
|
doNotTrack,
|
|
9661
9662
|
reason: missingApi.length ? `missing api: ${missingApi.join(',')}` : reason,
|