@openreplay/tracker 18.0.12-beta.1 → 18.0.13
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 +81 -44
- package/dist/cjs/entry.js.map +1 -1
- package/dist/cjs/index.js +81 -44
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/main/app/nodes/index.d.ts +1 -0
- package/dist/lib/entry.js +81 -44
- package/dist/lib/entry.js.map +1 -1
- package/dist/lib/index.js +81 -44
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/main/app/nodes/index.d.ts +1 -0
- package/dist/types/main/app/nodes/index.d.ts +1 -0
- package/package.json +1 -1
|
@@ -25,6 +25,7 @@ export default class Nodes {
|
|
|
25
25
|
cleanTree(): void;
|
|
26
26
|
callNodeCallbacks(node: Node, isStart: boolean): void;
|
|
27
27
|
getID(node: Node): number | undefined;
|
|
28
|
+
isBound(node: Node): boolean;
|
|
28
29
|
getNode(id: number): void | Node | undefined;
|
|
29
30
|
getNodeCount(): number;
|
|
30
31
|
clear(): void;
|
package/dist/lib/entry.js
CHANGED
|
@@ -2340,8 +2340,9 @@ class Nodes {
|
|
|
2340
2340
|
this.nextNodeId = this.createFrameId(level, frameOrder);
|
|
2341
2341
|
}
|
|
2342
2342
|
registerNode(node) {
|
|
2343
|
-
|
|
2344
|
-
const isNew =
|
|
2343
|
+
const existing = node[this.node_id];
|
|
2344
|
+
const isNew = existing === undefined || this.nodes.get(existing) !== node;
|
|
2345
|
+
let id = existing;
|
|
2345
2346
|
if (isNew) {
|
|
2346
2347
|
id = this.nextNodeId;
|
|
2347
2348
|
this.totalNodeAmount++;
|
|
@@ -2370,6 +2371,12 @@ class Nodes {
|
|
|
2370
2371
|
return undefined;
|
|
2371
2372
|
return node[this.node_id];
|
|
2372
2373
|
}
|
|
2374
|
+
isBound(node) {
|
|
2375
|
+
if (!node)
|
|
2376
|
+
return false;
|
|
2377
|
+
const id = node[this.node_id];
|
|
2378
|
+
return id !== undefined && this.nodes.get(id) === node;
|
|
2379
|
+
}
|
|
2373
2380
|
getNode(id) {
|
|
2374
2381
|
return this.nodes.get(id);
|
|
2375
2382
|
}
|
|
@@ -2968,46 +2975,57 @@ class Observer {
|
|
|
2968
2975
|
this.inlinerOptions = options.inlinerOptions;
|
|
2969
2976
|
this.observer = createMutationObserver(this.app.safe((mutations) => {
|
|
2970
2977
|
for (const mutation of mutations) {
|
|
2971
|
-
//
|
|
2972
|
-
|
|
2973
|
-
|
|
2974
|
-
|
|
2975
|
-
|
|
2976
|
-
|
|
2977
|
-
|
|
2978
|
-
|
|
2979
|
-
|
|
2980
|
-
|
|
2981
|
-
|
|
2978
|
+
// THEORY S1: app.safe() wraps this whole callback in a try/catch that
|
|
2979
|
+
// SILENTLY swallows — so a throw while processing one mutation aborts
|
|
2980
|
+
// the entire batch (the single commitNodes() below never runs) and
|
|
2981
|
+
// every pending node in it is lost. Isolating + logging per mutation
|
|
2982
|
+
// both surfaces it into the session and prevents one bad node from
|
|
2983
|
+
// dropping the rest of the batch.
|
|
2984
|
+
try {
|
|
2985
|
+
// mutations order is sequential
|
|
2986
|
+
const target = mutation.target;
|
|
2987
|
+
const type = mutation.type;
|
|
2988
|
+
if (!isObservable(target)) {
|
|
2989
|
+
continue;
|
|
2990
|
+
}
|
|
2991
|
+
if (type === 'childList') {
|
|
2992
|
+
for (let i = 0; i < mutation.removedNodes.length; i++) {
|
|
2993
|
+
// Should be the same as bindTree(mutation.removedNodes[i]), but logic needs to be be untied
|
|
2994
|
+
if (isObservable(mutation.removedNodes[i])) {
|
|
2995
|
+
this.bindNode(mutation.removedNodes[i]);
|
|
2996
|
+
}
|
|
2982
2997
|
}
|
|
2998
|
+
for (let i = 0; i < mutation.addedNodes.length; i++) {
|
|
2999
|
+
this.bindTree(mutation.addedNodes[i]);
|
|
3000
|
+
}
|
|
3001
|
+
continue;
|
|
2983
3002
|
}
|
|
2984
|
-
|
|
2985
|
-
|
|
3003
|
+
const id = this.app.nodes.getID(target);
|
|
3004
|
+
if (id === undefined) {
|
|
3005
|
+
continue;
|
|
2986
3006
|
}
|
|
2987
|
-
|
|
2988
|
-
|
|
2989
|
-
|
|
2990
|
-
|
|
2991
|
-
|
|
2992
|
-
|
|
2993
|
-
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
|
|
2997
|
-
|
|
2998
|
-
|
|
3007
|
+
if (!this.recents.has(id)) {
|
|
3008
|
+
this.recents.set(id, RecentsType.Changed); // TODO only when altered
|
|
3009
|
+
}
|
|
3010
|
+
if (type === 'attributes') {
|
|
3011
|
+
const name = mutation.attributeName;
|
|
3012
|
+
if (name === null) {
|
|
3013
|
+
continue;
|
|
3014
|
+
}
|
|
3015
|
+
let attr = this.attributesMap.get(id);
|
|
3016
|
+
if (attr === undefined) {
|
|
3017
|
+
this.attributesMap.set(id, (attr = new Set()));
|
|
3018
|
+
}
|
|
3019
|
+
attr.add(name);
|
|
2999
3020
|
continue;
|
|
3000
3021
|
}
|
|
3001
|
-
|
|
3002
|
-
|
|
3003
|
-
|
|
3022
|
+
if (type === 'characterData') {
|
|
3023
|
+
this.textSet.add(id);
|
|
3024
|
+
continue;
|
|
3004
3025
|
}
|
|
3005
|
-
attr.add(name);
|
|
3006
|
-
continue;
|
|
3007
3026
|
}
|
|
3008
|
-
|
|
3009
|
-
|
|
3010
|
-
continue;
|
|
3027
|
+
catch (mutationErr) {
|
|
3028
|
+
mutation.target;
|
|
3011
3029
|
}
|
|
3012
3030
|
}
|
|
3013
3031
|
this.commitNodes();
|
|
@@ -3173,10 +3191,11 @@ class Observer {
|
|
|
3173
3191
|
this.bindNode(node);
|
|
3174
3192
|
const walker = document.createTreeWalker(node, NodeFilter.SHOW_ELEMENT + NodeFilter.SHOW_TEXT, {
|
|
3175
3193
|
acceptNode: (node) => {
|
|
3176
|
-
|
|
3177
|
-
|
|
3178
|
-
|
|
3179
|
-
|
|
3194
|
+
// Use the Map-aware isBound() rather than the raw __openreplay_id
|
|
3195
|
+
// property: a node carrying a stale id from a previous observe cycle
|
|
3196
|
+
// must be re-accepted and re-bound here, otherwise the snapshot walk
|
|
3197
|
+
// silently skips it (and its subtree, e.g. a <style>'s CSS text).
|
|
3198
|
+
return isIgnored(node) || this.app.nodes.isBound(node)
|
|
3180
3199
|
? NodeFilter.FILTER_REJECT
|
|
3181
3200
|
: NodeFilter.FILTER_ACCEPT;
|
|
3182
3201
|
},
|
|
@@ -3228,8 +3247,6 @@ class Observer {
|
|
|
3228
3247
|
// TODO: Clean the logic (though now it workd fine)
|
|
3229
3248
|
if (!hasTag(node, 'html') || !this.isTopContext) {
|
|
3230
3249
|
if (parent === null) {
|
|
3231
|
-
// Sometimes one observation contains attribute mutations for the removimg node, which gets ignored here.
|
|
3232
|
-
// That shouldn't affect the visual rendering ( should it? maybe when transition applied? )
|
|
3233
3250
|
this.unbindTree(node);
|
|
3234
3251
|
return false;
|
|
3235
3252
|
}
|
|
@@ -3383,6 +3400,26 @@ class Observer {
|
|
|
3383
3400
|
this.commitNodes(true);
|
|
3384
3401
|
}
|
|
3385
3402
|
disconnect() {
|
|
3403
|
+
// THEORY S3: a disconnect may discard MutationRecords still queued by the
|
|
3404
|
+
// browser. takeRecords() drains them — they would be discarded by
|
|
3405
|
+
// disconnect() below anyway, so this changes nothing functionally, it only
|
|
3406
|
+
// lets us SEE whether a disconnect strands un-processed DOM additions
|
|
3407
|
+
// (e.g. a freshly appended <head> <style>). NOTE: if this disconnect is part
|
|
3408
|
+
// of stop(), the surrounding buffer may be cleared and this log lost; it is
|
|
3409
|
+
// most reliable for mid-session re-observes (cold-start cycle / iframe).
|
|
3410
|
+
const pending = this.observer.takeRecords();
|
|
3411
|
+
if (pending.length) {
|
|
3412
|
+
const tags = [];
|
|
3413
|
+
for (const m of pending) {
|
|
3414
|
+
for (let i = 0; i < m.addedNodes.length; i++) {
|
|
3415
|
+
const n = m.addedNodes[i];
|
|
3416
|
+
if (n.tagName) {
|
|
3417
|
+
if (tags.length < 10)
|
|
3418
|
+
tags.push(n.tagName);
|
|
3419
|
+
}
|
|
3420
|
+
}
|
|
3421
|
+
}
|
|
3422
|
+
}
|
|
3386
3423
|
this.observer.disconnect();
|
|
3387
3424
|
this.clear();
|
|
3388
3425
|
this.throttledSetNodeData.clear();
|
|
@@ -4058,7 +4095,7 @@ class App {
|
|
|
4058
4095
|
this.stopCallbacks = [];
|
|
4059
4096
|
this.commitCallbacks = [];
|
|
4060
4097
|
this.activityState = ActivityState.NotActive;
|
|
4061
|
-
this.version = '18.0.
|
|
4098
|
+
this.version = '18.0.13'; // TODO: version compatability check inside each plugin.
|
|
4062
4099
|
this.socketMode = false;
|
|
4063
4100
|
this.compressionThreshold = 24 * 1000;
|
|
4064
4101
|
this.bc = null;
|
|
@@ -9356,7 +9393,7 @@ class ConstantProperties {
|
|
|
9356
9393
|
user_id: this.user_id,
|
|
9357
9394
|
distinct_id: this.deviceId,
|
|
9358
9395
|
sdk_edition: 'web',
|
|
9359
|
-
sdk_version: '18.0.
|
|
9396
|
+
sdk_version: '18.0.13',
|
|
9360
9397
|
timezone: getUTCOffsetString(),
|
|
9361
9398
|
search_engine: this.searchEngine,
|
|
9362
9399
|
};
|
|
@@ -10058,7 +10095,7 @@ class API {
|
|
|
10058
10095
|
this.signalStartIssue = (reason, missingApi) => {
|
|
10059
10096
|
const doNotTrack = this.checkDoNotTrack();
|
|
10060
10097
|
console.log("Tracker couldn't start due to:", JSON.stringify({
|
|
10061
|
-
trackerVersion: '18.0.
|
|
10098
|
+
trackerVersion: '18.0.13',
|
|
10062
10099
|
projectKey: this.options.projectKey,
|
|
10063
10100
|
doNotTrack,
|
|
10064
10101
|
reason: missingApi.length ? `missing api: ${missingApi.join(',')}` : reason,
|