@openreplay/tracker 17.2.8 → 17.2.10
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 +86 -16
- package/dist/cjs/entry.js.map +1 -1
- package/dist/cjs/index.js +86 -16
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/main/app/index.d.ts +4 -4
- package/dist/cjs/main/app/observer/observer.d.ts +6 -0
- package/dist/lib/entry.js +86 -16
- package/dist/lib/entry.js.map +1 -1
- package/dist/lib/index.js +86 -16
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/main/app/index.d.ts +4 -4
- package/dist/lib/main/app/observer/observer.d.ts +6 -0
- package/dist/types/main/app/index.d.ts +4 -4
- package/dist/types/main/app/observer/observer.d.ts +6 -0
- package/package.json +1 -1
package/dist/cjs/entry.js
CHANGED
|
@@ -2913,6 +2913,12 @@ class Observer {
|
|
|
2913
2913
|
this.inlineRemoteCss = false;
|
|
2914
2914
|
this.inlinerOptions = undefined;
|
|
2915
2915
|
this.domParser = new DOMParser();
|
|
2916
|
+
/**
|
|
2917
|
+
* Bumped on every disconnect(). Stale async CSS-inlining callbacks from a
|
|
2918
|
+
* previous session (e.g. agent reload → tracker restart) compare against
|
|
2919
|
+
* this and bail instead of sending messages that reference vanished node ids.
|
|
2920
|
+
*/
|
|
2921
|
+
this.generation = 0;
|
|
2916
2922
|
this.throttling = true;
|
|
2917
2923
|
this.throttledSetNodeData = throttleWithTrailing((id, parentElement, data) => this.sendNodeData(id, parentElement, data), 30);
|
|
2918
2924
|
this.throttling = !Boolean(options.disableThrottling);
|
|
@@ -3059,14 +3065,21 @@ class Observer {
|
|
|
3059
3065
|
}
|
|
3060
3066
|
if (name === 'style' || (name === 'href' && hasTag(node, 'link'))) {
|
|
3061
3067
|
if ('rel' in node && node.rel === 'stylesheet' && this.inlineRemoteCss) {
|
|
3068
|
+
const gen = this.generation;
|
|
3062
3069
|
setTimeout(() => {
|
|
3063
3070
|
inlineRemoteCss(
|
|
3064
3071
|
// @ts-ignore
|
|
3065
3072
|
node, id, this.app.getBaseHref(), nextID, (id, cssText, index, baseHref) => {
|
|
3073
|
+
if (this.generation !== gen)
|
|
3074
|
+
return;
|
|
3066
3075
|
this.app.send(AdoptedSSInsertRuleURLBased(id, cssText, index, baseHref));
|
|
3067
3076
|
}, (sheetId, ownerId) => {
|
|
3077
|
+
if (this.generation !== gen)
|
|
3078
|
+
return;
|
|
3068
3079
|
this.app.send(AdoptedSSAddOwner(sheetId, ownerId));
|
|
3069
3080
|
}, this.inlinerOptions?.forceFetch, this.inlinerOptions?.forcePlain, (cssText, fakeTextId) => {
|
|
3081
|
+
if (this.generation !== gen)
|
|
3082
|
+
return;
|
|
3070
3083
|
this.app.send(CreateTextNode(fakeTextId, id, 0));
|
|
3071
3084
|
this.app.send(SetCSSDataURLBased(fakeTextId, cssText, this.app.getBaseHref()));
|
|
3072
3085
|
});
|
|
@@ -3332,6 +3345,7 @@ class Observer {
|
|
|
3332
3345
|
this.observer.disconnect();
|
|
3333
3346
|
this.clear();
|
|
3334
3347
|
this.throttledSetNodeData.clear();
|
|
3348
|
+
this.generation++;
|
|
3335
3349
|
}
|
|
3336
3350
|
}
|
|
3337
3351
|
|
|
@@ -3995,7 +4009,7 @@ class App {
|
|
|
3995
4009
|
this.stopCallbacks = [];
|
|
3996
4010
|
this.commitCallbacks = [];
|
|
3997
4011
|
this.activityState = ActivityState.NotActive;
|
|
3998
|
-
this.version = '17.2.
|
|
4012
|
+
this.version = '17.2.10'; // TODO: version compatability check inside each plugin.
|
|
3999
4013
|
this.socketMode = false;
|
|
4000
4014
|
this.compressionThreshold = 24 * 1000;
|
|
4001
4015
|
this.bc = null;
|
|
@@ -4017,9 +4031,13 @@ class App {
|
|
|
4017
4031
|
if (!data || event.source === window)
|
|
4018
4032
|
return;
|
|
4019
4033
|
if (data.line === proto.startIframe) {
|
|
4020
|
-
|
|
4034
|
+
// Avoid corrupting an in-flight start; let it complete.
|
|
4035
|
+
if (this.activityState === ActivityState.Starting)
|
|
4021
4036
|
return;
|
|
4022
4037
|
try {
|
|
4038
|
+
if (this.active()) {
|
|
4039
|
+
this.stop();
|
|
4040
|
+
}
|
|
4023
4041
|
if (data.token) {
|
|
4024
4042
|
this.session.setSessionToken(data.token, this.projectKey);
|
|
4025
4043
|
}
|
|
@@ -4051,17 +4069,22 @@ class App {
|
|
|
4051
4069
|
}
|
|
4052
4070
|
}
|
|
4053
4071
|
};
|
|
4054
|
-
/**
|
|
4055
|
-
* context ids for iframes,
|
|
4056
|
-
* order is not so important as long as its consistent
|
|
4057
|
-
* */
|
|
4058
4072
|
this.trackedFrames = [];
|
|
4073
|
+
this.frameLastSeen = new Map();
|
|
4074
|
+
this.FRAME_STALE_MS = 1500;
|
|
4059
4075
|
this.crossDomainIframeListener = (event) => {
|
|
4060
|
-
if (
|
|
4076
|
+
if (event.source === window)
|
|
4061
4077
|
return;
|
|
4062
4078
|
const { data } = event;
|
|
4063
4079
|
if (!data)
|
|
4064
4080
|
return;
|
|
4081
|
+
// Record liveness regardless of our own active state so the queue can prune
|
|
4082
|
+
// stale contexts reliably once we resume dispatching commands after a cycle.
|
|
4083
|
+
if ((data.line === proto.polling || data.line === proto.iframeSignal) && data.context) {
|
|
4084
|
+
this.frameLastSeen.set(data.context, Date.now());
|
|
4085
|
+
}
|
|
4086
|
+
if (!this.active())
|
|
4087
|
+
return;
|
|
4065
4088
|
if (data.line === proto.iframeSignal) {
|
|
4066
4089
|
// @ts-ignore
|
|
4067
4090
|
event.source?.postMessage({ ping: true, line: proto.parentAlive }, '*');
|
|
@@ -4159,11 +4182,23 @@ class App {
|
|
|
4159
4182
|
if (!this.pollingQueue.order.length) {
|
|
4160
4183
|
return;
|
|
4161
4184
|
}
|
|
4162
|
-
|
|
4163
|
-
|
|
4164
|
-
|
|
4185
|
+
this.pruneStaleFrames();
|
|
4186
|
+
const liveSet = new Set(this.trackedFrames);
|
|
4187
|
+
while (this.pollingQueue.order.length > 0) {
|
|
4188
|
+
const head = this.pollingQueue.order[0];
|
|
4189
|
+
this.pollingQueue[head] = this.pollingQueue[head].filter((ctx) => liveSet.has(ctx));
|
|
4190
|
+
if (this.pollingQueue[head].length === 0) {
|
|
4191
|
+
delete this.pollingQueue[head];
|
|
4192
|
+
this.pollingQueue.order.shift();
|
|
4193
|
+
}
|
|
4194
|
+
else {
|
|
4195
|
+
break;
|
|
4196
|
+
}
|
|
4197
|
+
}
|
|
4198
|
+
if (!this.pollingQueue.order.length) {
|
|
4165
4199
|
return;
|
|
4166
4200
|
}
|
|
4201
|
+
const nextCommand = this.pollingQueue.order[0];
|
|
4167
4202
|
if (this.pollingQueue[nextCommand].includes(data.context)) {
|
|
4168
4203
|
this.pollingQueue[nextCommand] = this.pollingQueue[nextCommand].filter((c) => c !== data.context);
|
|
4169
4204
|
const message = { line: nextCommand };
|
|
@@ -4181,6 +4216,7 @@ class App {
|
|
|
4181
4216
|
// @ts-ignore
|
|
4182
4217
|
event.source?.postMessage(message, '*');
|
|
4183
4218
|
if (this.pollingQueue[nextCommand].length === 0) {
|
|
4219
|
+
delete this.pollingQueue[nextCommand];
|
|
4184
4220
|
this.pollingQueue.order.shift();
|
|
4185
4221
|
}
|
|
4186
4222
|
}
|
|
@@ -4194,6 +4230,11 @@ class App {
|
|
|
4194
4230
|
order: [],
|
|
4195
4231
|
};
|
|
4196
4232
|
this.addCommand = (cmd) => {
|
|
4233
|
+
this.pruneStaleFrames();
|
|
4234
|
+
if (this.pollingQueue[cmd]) {
|
|
4235
|
+
this.pollingQueue[cmd] = Array.from(new Set([...this.pollingQueue[cmd], ...this.trackedFrames]));
|
|
4236
|
+
return;
|
|
4237
|
+
}
|
|
4197
4238
|
this.pollingQueue.order.push(cmd);
|
|
4198
4239
|
this.pollingQueue[cmd] = [...this.trackedFrames];
|
|
4199
4240
|
};
|
|
@@ -4505,6 +4546,16 @@ class App {
|
|
|
4505
4546
|
};
|
|
4506
4547
|
}
|
|
4507
4548
|
}
|
|
4549
|
+
pruneStaleFrames() {
|
|
4550
|
+
const staleAfter = Date.now() - this.FRAME_STALE_MS;
|
|
4551
|
+
this.trackedFrames = this.trackedFrames.filter((ctx) => {
|
|
4552
|
+
const last = this.frameLastSeen.get(ctx);
|
|
4553
|
+
if (last !== undefined && last >= staleAfter)
|
|
4554
|
+
return true;
|
|
4555
|
+
this.frameLastSeen.delete(ctx);
|
|
4556
|
+
return false;
|
|
4557
|
+
});
|
|
4558
|
+
}
|
|
4508
4559
|
allowAppStart() {
|
|
4509
4560
|
this.canStart = true;
|
|
4510
4561
|
if (this.startTimeout) {
|
|
@@ -5055,6 +5106,9 @@ class App {
|
|
|
5055
5106
|
if (Object.keys(startOpts).length !== 0) {
|
|
5056
5107
|
this.prevOpts = startOpts;
|
|
5057
5108
|
}
|
|
5109
|
+
if (startOpts.startCallback) {
|
|
5110
|
+
this.userStartCallback = startOpts.startCallback;
|
|
5111
|
+
}
|
|
5058
5112
|
const isColdStart = this.activityState === ActivityState.ColdStart;
|
|
5059
5113
|
if (isColdStart && this.coldInterval) {
|
|
5060
5114
|
clearInterval(this.coldInterval);
|
|
@@ -5194,8 +5248,8 @@ class App {
|
|
|
5194
5248
|
// TODO: start as early as possible (before receiving the token)
|
|
5195
5249
|
/** after start */
|
|
5196
5250
|
this.startCallbacks.forEach((cb) => cb(onStartInfo)); // MBTODO: callbacks after DOM "mounted" (observed)
|
|
5197
|
-
if (
|
|
5198
|
-
|
|
5251
|
+
if (this.userStartCallback) {
|
|
5252
|
+
this.userStartCallback(SuccessfulStart(onStartInfo));
|
|
5199
5253
|
}
|
|
5200
5254
|
this.activityState = ActivityState.Active;
|
|
5201
5255
|
if (this.options.crossdomain?.enabled) {
|
|
@@ -5358,6 +5412,7 @@ class App {
|
|
|
5358
5412
|
this.canvasRecorder?.clear();
|
|
5359
5413
|
this.messages.length = 0;
|
|
5360
5414
|
this.parentActive = false;
|
|
5415
|
+
this.pageFrames = [];
|
|
5361
5416
|
}
|
|
5362
5417
|
finally {
|
|
5363
5418
|
this.activityState = ActivityState.NotActive;
|
|
@@ -5984,9 +6039,11 @@ function Input (app, opts) {
|
|
|
5984
6039
|
}
|
|
5985
6040
|
const inputValues = new Map();
|
|
5986
6041
|
const checkboxValues = new Map();
|
|
6042
|
+
const selectValues = new Map();
|
|
5987
6043
|
app.attachStopCallback(() => {
|
|
5988
6044
|
inputValues.clear();
|
|
5989
6045
|
checkboxValues.clear();
|
|
6046
|
+
selectValues.clear();
|
|
5990
6047
|
tagSelectorMap.clear();
|
|
5991
6048
|
});
|
|
5992
6049
|
function trackInputValue(id, node) {
|
|
@@ -6003,6 +6060,13 @@ function Input (app, opts) {
|
|
|
6003
6060
|
checkboxValues.set(id, value);
|
|
6004
6061
|
app.send(SetInputChecked(id, value));
|
|
6005
6062
|
}
|
|
6063
|
+
function trackSelectValue(id, node) {
|
|
6064
|
+
if (selectValues.get(id) === node.value) {
|
|
6065
|
+
return;
|
|
6066
|
+
}
|
|
6067
|
+
selectValues.set(id, node.value);
|
|
6068
|
+
sendInputValue(id, node);
|
|
6069
|
+
}
|
|
6006
6070
|
// The only way (to our knowledge) to track all kinds of input changes, including those made by JS
|
|
6007
6071
|
app.ticker.attach(() => {
|
|
6008
6072
|
inputValues.forEach((value, id) => {
|
|
@@ -6017,6 +6081,12 @@ function Input (app, opts) {
|
|
|
6017
6081
|
return checkboxValues.delete(id);
|
|
6018
6082
|
trackCheckboxValue(id, node.checked);
|
|
6019
6083
|
});
|
|
6084
|
+
selectValues.forEach((_, id) => {
|
|
6085
|
+
const node = app.nodes.getNode(id);
|
|
6086
|
+
if (!node)
|
|
6087
|
+
return selectValues.delete(id);
|
|
6088
|
+
trackSelectValue(id, node);
|
|
6089
|
+
});
|
|
6020
6090
|
}, 3);
|
|
6021
6091
|
function sendInputChange(id, node, hesitationTime, inputTime) {
|
|
6022
6092
|
const { value, mask } = getInputValue(id, node);
|
|
@@ -6033,8 +6103,8 @@ function Input (app, opts) {
|
|
|
6033
6103
|
}
|
|
6034
6104
|
// TODO: support multiple select (?): use selectedOptions;
|
|
6035
6105
|
if (hasTag(node, 'select')) {
|
|
6036
|
-
|
|
6037
|
-
app.nodes.attachNodeListener(node, 'change', () =>
|
|
6106
|
+
trackSelectValue(id, node);
|
|
6107
|
+
app.nodes.attachNodeListener(node, 'change', () => trackSelectValue(id, node));
|
|
6038
6108
|
}
|
|
6039
6109
|
if (isTextFieldElement(node)) {
|
|
6040
6110
|
trackInputValue(id, node);
|
|
@@ -8887,7 +8957,7 @@ class ConstantProperties {
|
|
|
8887
8957
|
user_id: this.user_id,
|
|
8888
8958
|
distinct_id: this.deviceId,
|
|
8889
8959
|
sdk_edition: 'web',
|
|
8890
|
-
sdk_version: '17.2.
|
|
8960
|
+
sdk_version: '17.2.10',
|
|
8891
8961
|
timezone: getUTCOffsetString(),
|
|
8892
8962
|
search_engine: this.searchEngine,
|
|
8893
8963
|
};
|
|
@@ -9589,7 +9659,7 @@ class API {
|
|
|
9589
9659
|
this.signalStartIssue = (reason, missingApi) => {
|
|
9590
9660
|
const doNotTrack = this.checkDoNotTrack();
|
|
9591
9661
|
console.log("Tracker couldn't start due to:", JSON.stringify({
|
|
9592
|
-
trackerVersion: '17.2.
|
|
9662
|
+
trackerVersion: '17.2.10',
|
|
9593
9663
|
projectKey: this.options.projectKey,
|
|
9594
9664
|
doNotTrack,
|
|
9595
9665
|
reason: missingApi.length ? `missing api: ${missingApi.join(',')}` : reason,
|