@openreplay/tracker 12.1.0-beta.99 → 13.0.1
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/CHANGELOG.md +9 -0
- package/bun.lockb +0 -0
- package/cjs/app/canvas.d.ts +2 -1
- package/cjs/app/canvas.js +27 -13
- package/cjs/app/index.d.ts +15 -8
- package/cjs/app/index.js +134 -88
- package/cjs/app/messages.gen.d.ts +2 -2
- package/cjs/app/messages.gen.js +8 -8
- package/cjs/common/interaction.d.ts +21 -56
- package/cjs/common/messages.gen.d.ts +7 -7
- package/cjs/index.js +2 -2
- package/coverage/clover.xml +1054 -964
- package/coverage/coverage-final.json +21 -21
- package/coverage/lcov-report/index.html +43 -43
- package/coverage/lcov-report/main/app/canvas.ts.html +224 -47
- package/coverage/lcov-report/main/app/guards.ts.html +26 -26
- package/coverage/lcov-report/main/app/index.html +42 -42
- package/coverage/lcov-report/main/app/index.ts.html +157 -37
- package/coverage/lcov-report/main/app/logger.ts.html +1 -1
- package/coverage/lcov-report/main/app/messages.gen.ts.html +244 -154
- package/coverage/lcov-report/main/app/nodes.ts.html +7 -4
- package/coverage/lcov-report/main/app/observer/iframe_observer.ts.html +1 -1
- package/coverage/lcov-report/main/app/observer/iframe_offsets.ts.html +1 -1
- package/coverage/lcov-report/main/app/observer/index.html +5 -5
- package/coverage/lcov-report/main/app/observer/shadow_root_observer.ts.html +1 -1
- package/coverage/lcov-report/main/app/observer/top_observer.ts.html +7 -4
- package/coverage/lcov-report/main/app/sanitizer.ts.html +2 -2
- package/coverage/lcov-report/main/app/session.ts.html +2 -2
- package/coverage/lcov-report/main/app/ticker.ts.html +1 -1
- package/coverage/lcov-report/main/index.html +13 -13
- package/coverage/lcov-report/main/index.ts.html +32 -14
- package/coverage/lcov-report/main/modules/Network/beaconProxy.ts.html +17 -8
- package/coverage/lcov-report/main/modules/Network/fetchProxy.ts.html +40 -13
- package/coverage/lcov-report/main/modules/Network/index.html +21 -21
- package/coverage/lcov-report/main/modules/Network/index.ts.html +2 -2
- package/coverage/lcov-report/main/modules/Network/networkMessage.ts.html +12 -6
- package/coverage/lcov-report/main/modules/Network/utils.ts.html +17 -8
- package/coverage/lcov-report/main/modules/Network/xhrProxy.ts.html +39 -12
- package/coverage/lcov-report/main/modules/attributeSender.ts.html +1 -1
- package/coverage/lcov-report/main/modules/axiosSpy.ts.html +1 -1
- package/coverage/lcov-report/main/modules/conditionsManager.ts.html +4 -22
- package/coverage/lcov-report/main/modules/connection.ts.html +1 -1
- package/coverage/lcov-report/main/modules/console.ts.html +1 -1
- package/coverage/lcov-report/main/modules/constructedStyleSheets.ts.html +3 -3
- package/coverage/lcov-report/main/modules/cssrules.ts.html +1 -1
- package/coverage/lcov-report/main/modules/exception.ts.html +1 -1
- package/coverage/lcov-report/main/modules/featureFlags.ts.html +1 -1
- package/coverage/lcov-report/main/modules/focus.ts.html +1 -1
- package/coverage/lcov-report/main/modules/fonts.ts.html +1 -1
- package/coverage/lcov-report/main/modules/img.ts.html +4 -4
- package/coverage/lcov-report/main/modules/index.html +24 -24
- package/coverage/lcov-report/main/modules/input.ts.html +1 -1
- package/coverage/lcov-report/main/modules/mouse.ts.html +1 -1
- package/coverage/lcov-report/main/modules/network.ts.html +2 -2
- package/coverage/lcov-report/main/modules/performance.ts.html +1 -1
- package/coverage/lcov-report/main/modules/scroll.ts.html +1 -1
- package/coverage/lcov-report/main/modules/selection.ts.html +1 -1
- package/coverage/lcov-report/main/modules/tabs.ts.html +1 -1
- package/coverage/lcov-report/main/modules/tagWatcher.ts.html +95 -92
- package/coverage/lcov-report/main/modules/timing.ts.html +1 -1
- package/coverage/lcov-report/main/modules/userTesting/SignalManager.ts.html +1 -1
- package/coverage/lcov-report/main/modules/userTesting/dnd.ts.html +1 -1
- package/coverage/lcov-report/main/modules/userTesting/index.html +1 -1
- package/coverage/lcov-report/main/modules/userTesting/index.ts.html +1 -1
- package/coverage/lcov-report/main/modules/userTesting/recorder.ts.html +1 -1
- package/coverage/lcov-report/main/modules/userTesting/styles.ts.html +1 -1
- package/coverage/lcov-report/main/modules/userTesting/utils.ts.html +1 -1
- package/coverage/lcov-report/main/modules/viewport.ts.html +4 -4
- package/coverage/lcov-report/main/utils.ts.html +181 -31
- package/coverage/lcov-report/webworker/BatchWriter.ts.html +1 -1
- package/coverage/lcov-report/webworker/MessageEncoder.gen.ts.html +31 -7
- package/coverage/lcov-report/webworker/PrimitiveEncoder.ts.html +1 -1
- package/coverage/lcov-report/webworker/QueueSender.ts.html +48 -18
- package/coverage/lcov-report/webworker/index.html +14 -14
- package/coverage/lcov-report/webworker/index.ts.html +51 -21
- package/coverage/lcov.info +1882 -1653
- package/lib/app/canvas.d.ts +2 -1
- package/lib/app/canvas.js +27 -13
- package/lib/app/index.d.ts +15 -8
- package/lib/app/index.js +134 -88
- package/lib/app/messages.gen.d.ts +2 -2
- package/lib/app/messages.gen.js +4 -4
- package/lib/common/interaction.d.ts +21 -56
- package/lib/common/messages.gen.d.ts +7 -7
- package/lib/common/tsconfig.tsbuildinfo +1 -1
- package/lib/index.js +2 -2
- package/package.json +2 -2
- package/cjs/app/workerManager/QueueSender.d.ts +0 -25
- package/cjs/app/workerManager/QueueSender.js +0 -133
- package/cjs/app/workerManager/index.d.ts +0 -37
- package/cjs/app/workerManager/index.js +0 -166
- package/lib/app/workerManager/QueueSender.d.ts +0 -25
- package/lib/app/workerManager/QueueSender.js +0 -130
- package/lib/app/workerManager/index.d.ts +0 -37
- package/lib/app/workerManager/index.js +0 -161
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
# 13.0.1
|
|
2
|
+
|
|
3
|
+
- moved canvas snapshots to webp, additional option to utilize useAnimationFrame method (for webgl)
|
|
4
|
+
- simpler, faster canvas recording manager
|
|
5
|
+
|
|
6
|
+
# 13.0.0
|
|
7
|
+
|
|
8
|
+
- `assistOnly` flag for tracker options (EE only feature)
|
|
9
|
+
|
|
1
10
|
# 12.0.12
|
|
2
11
|
|
|
3
12
|
- fix for potential redux plugin issues after .11 ...
|
package/bun.lockb
CHANGED
|
Binary file
|
package/cjs/app/canvas.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ interface Options {
|
|
|
4
4
|
quality: 'low' | 'medium' | 'high';
|
|
5
5
|
isDebug?: boolean;
|
|
6
6
|
fixedScaling?: boolean;
|
|
7
|
+
useAnimationFrame?: boolean;
|
|
7
8
|
}
|
|
8
9
|
declare class CanvasRecorder {
|
|
9
10
|
private readonly app;
|
|
@@ -17,7 +18,7 @@ declare class CanvasRecorder {
|
|
|
17
18
|
captureCanvas: (node: Node) => void;
|
|
18
19
|
recordCanvas: (node: Node, id: number) => void;
|
|
19
20
|
sendSnaps(images: {
|
|
20
|
-
data:
|
|
21
|
+
data: Blob;
|
|
21
22
|
id: number;
|
|
22
23
|
}[], canvasId: number, createdAt: number): void;
|
|
23
24
|
clear(): void;
|
package/cjs/app/canvas.js
CHANGED
|
@@ -58,6 +58,17 @@ class CanvasRecorder {
|
|
|
58
58
|
};
|
|
59
59
|
const canvasMsg = (0, messages_gen_js_1.CanvasNode)(id.toString(), ts);
|
|
60
60
|
this.app.send(canvasMsg);
|
|
61
|
+
const captureFn = (canvas) => {
|
|
62
|
+
captureSnapshot(canvas, this.options.quality, this.snapshots[id].dummy, this.options.fixedScaling, (blob) => {
|
|
63
|
+
if (!blob)
|
|
64
|
+
return;
|
|
65
|
+
this.snapshots[id].images.push({ id: this.app.timestamp(), data: blob });
|
|
66
|
+
if (this.snapshots[id].images.length > 9) {
|
|
67
|
+
this.sendSnaps(this.snapshots[id].images, id, this.snapshots[id].createdAt);
|
|
68
|
+
this.snapshots[id].images = [];
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
};
|
|
61
72
|
const int = setInterval(() => {
|
|
62
73
|
const cid = this.app.nodes.getID(node);
|
|
63
74
|
const canvas = cid ? this.app.nodes.getNode(cid) : undefined;
|
|
@@ -67,11 +78,13 @@ class CanvasRecorder {
|
|
|
67
78
|
}
|
|
68
79
|
else {
|
|
69
80
|
if (!this.snapshots[id].paused) {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
81
|
+
if (this.options.useAnimationFrame) {
|
|
82
|
+
requestAnimationFrame(() => {
|
|
83
|
+
captureFn(canvas);
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
captureFn(canvas);
|
|
75
88
|
}
|
|
76
89
|
}
|
|
77
90
|
}
|
|
@@ -94,12 +107,12 @@ class CanvasRecorder {
|
|
|
94
107
|
}
|
|
95
108
|
const formData = new FormData();
|
|
96
109
|
images.forEach((snapshot) => {
|
|
97
|
-
const blob =
|
|
110
|
+
const blob = snapshot.data;
|
|
98
111
|
if (!blob)
|
|
99
112
|
return;
|
|
100
|
-
formData.append('snapshot', blob
|
|
113
|
+
formData.append('snapshot', blob, `${createdAt}_${canvasId}_${snapshot.id}.webp`);
|
|
101
114
|
if (this.options.isDebug) {
|
|
102
|
-
saveImageData(
|
|
115
|
+
saveImageData(blob, `${createdAt}_${canvasId}_${snapshot.id}.webp`);
|
|
103
116
|
}
|
|
104
117
|
});
|
|
105
118
|
fetch(this.app.options.ingestPoint + '/v1/web/images', {
|
|
@@ -126,8 +139,8 @@ const qualityInt = {
|
|
|
126
139
|
medium: 0.55,
|
|
127
140
|
high: 0.8,
|
|
128
141
|
};
|
|
129
|
-
function captureSnapshot(canvas, quality = 'medium', dummy, fixedScaling = false) {
|
|
130
|
-
const imageFormat = 'image/
|
|
142
|
+
function captureSnapshot(canvas, quality = 'medium', dummy, fixedScaling = false, onBlob) {
|
|
143
|
+
const imageFormat = 'image/webp';
|
|
131
144
|
if (fixedScaling) {
|
|
132
145
|
const canvasScaleRatio = window.devicePixelRatio || 1;
|
|
133
146
|
dummy.width = canvas.width / canvasScaleRatio;
|
|
@@ -137,10 +150,10 @@ function captureSnapshot(canvas, quality = 'medium', dummy, fixedScaling = false
|
|
|
137
150
|
return '';
|
|
138
151
|
}
|
|
139
152
|
ctx.drawImage(canvas, 0, 0, dummy.width, dummy.height);
|
|
140
|
-
|
|
153
|
+
dummy.toBlob(onBlob, imageFormat, qualityInt[quality]);
|
|
141
154
|
}
|
|
142
155
|
else {
|
|
143
|
-
|
|
156
|
+
canvas.toBlob(onBlob, imageFormat, qualityInt[quality]);
|
|
144
157
|
}
|
|
145
158
|
}
|
|
146
159
|
function dataUrlToBlob(dataUrl) {
|
|
@@ -159,7 +172,8 @@ function dataUrlToBlob(dataUrl) {
|
|
|
159
172
|
}
|
|
160
173
|
return [new Blob([u8arr], { type: mime }), u8arr];
|
|
161
174
|
}
|
|
162
|
-
function saveImageData(
|
|
175
|
+
function saveImageData(imageDataBlob, name) {
|
|
176
|
+
const imageDataUrl = URL.createObjectURL(imageDataBlob);
|
|
163
177
|
const link = document.createElement('a');
|
|
164
178
|
link.href = imageDataUrl;
|
|
165
179
|
link.download = name;
|
package/cjs/app/index.d.ts
CHANGED
|
@@ -11,12 +11,13 @@ import type { Options as ObserverOptions } from './observer/top_observer.js';
|
|
|
11
11
|
import type { Options as SanitizerOptions } from './sanitizer.js';
|
|
12
12
|
import type { Options as SessOptions } from './session.js';
|
|
13
13
|
import type { Options as NetworkOptions } from '../modules/network.js';
|
|
14
|
-
import type { Options as WebworkerOptions
|
|
14
|
+
import type { Options as WebworkerOptions } from '../common/interaction.js';
|
|
15
15
|
export interface StartOptions {
|
|
16
16
|
userID?: string;
|
|
17
17
|
metadata?: Record<string, string>;
|
|
18
18
|
forceNew?: boolean;
|
|
19
19
|
sessionHash?: string;
|
|
20
|
+
assistOnly?: boolean;
|
|
20
21
|
}
|
|
21
22
|
interface OnStartInfo {
|
|
22
23
|
sessionID: string;
|
|
@@ -57,6 +58,12 @@ type AppOptions = {
|
|
|
57
58
|
disableStringDict?: boolean;
|
|
58
59
|
assistSocketHost?: string;
|
|
59
60
|
disableCanvas?: boolean;
|
|
61
|
+
canvas: {
|
|
62
|
+
disableCanvas?: boolean;
|
|
63
|
+
fixedCanvasScaling?: boolean;
|
|
64
|
+
__save_canvas_locally?: boolean;
|
|
65
|
+
useAnimationFrame?: boolean;
|
|
66
|
+
};
|
|
60
67
|
/** @deprecated */
|
|
61
68
|
onStart?: StartCallback;
|
|
62
69
|
network?: NetworkOptions;
|
|
@@ -90,20 +97,20 @@ export default class App {
|
|
|
90
97
|
private readonly revID;
|
|
91
98
|
private activityState;
|
|
92
99
|
private readonly version;
|
|
93
|
-
private readonly
|
|
100
|
+
private readonly worker?;
|
|
101
|
+
attributeSender: AttributeSender;
|
|
102
|
+
featureFlags: FeatureFlags;
|
|
103
|
+
socketMode: boolean;
|
|
94
104
|
private compressionThreshold;
|
|
95
105
|
private restartAttempts;
|
|
96
106
|
private readonly bc;
|
|
97
107
|
private readonly contextId;
|
|
98
|
-
attributeSender: AttributeSender;
|
|
99
108
|
private canvasRecorder;
|
|
100
109
|
private uxtManager;
|
|
101
110
|
private conditionsManager;
|
|
102
|
-
featureFlags: FeatureFlags;
|
|
103
111
|
private readonly tagWatcher;
|
|
104
112
|
constructor(projectKey: string, sessionToken: string | undefined, options: Partial<Options>, signalError: (error: string, apis: string[]) => void);
|
|
105
|
-
|
|
106
|
-
private readonly _debug;
|
|
113
|
+
private _debug;
|
|
107
114
|
private _usingOldFetchPlugin;
|
|
108
115
|
send(message: Message, urgent?: boolean): void;
|
|
109
116
|
/**
|
|
@@ -161,7 +168,7 @@ export default class App {
|
|
|
161
168
|
private checkSessionToken;
|
|
162
169
|
/**
|
|
163
170
|
* start buffering messages without starting the actual session, which gives
|
|
164
|
-
* user 30 seconds to "activate" and record session by calling `start()` on conditional trigger
|
|
171
|
+
* user 30 seconds to "activate" and record session by calling `start()` on conditional trigger
|
|
165
172
|
* and we will then send buffered batch, so it won't get lost
|
|
166
173
|
* */
|
|
167
174
|
coldStart(startOpts?: StartOptions, conditional?: boolean): Promise<void>;
|
|
@@ -179,7 +186,7 @@ export default class App {
|
|
|
179
186
|
/**
|
|
180
187
|
* Saves the captured messages in localStorage (or whatever is used in its place)
|
|
181
188
|
*
|
|
182
|
-
* Then
|
|
189
|
+
* Then when this.offlineRecording is called, it will preload this messages and clear the storage item
|
|
183
190
|
*
|
|
184
191
|
* Keeping the size of local storage reasonable is up to the end users of this library
|
|
185
192
|
* */
|
package/cjs/app/index.js
CHANGED
|
@@ -44,7 +44,6 @@ const attributeSender_js_1 = __importDefault(require("../modules/attributeSender
|
|
|
44
44
|
const canvas_js_1 = __importDefault(require("./canvas.js"));
|
|
45
45
|
const index_js_1 = __importDefault(require("../modules/userTesting/index.js"));
|
|
46
46
|
const tagWatcher_js_1 = __importDefault(require("../modules/tagWatcher.js"));
|
|
47
|
-
const index_js_2 = __importDefault(require("./workerManager/index.js"));
|
|
48
47
|
const CANCELED = 'canceled';
|
|
49
48
|
const uxtStorageKey = 'or_uxt_active';
|
|
50
49
|
const bufferStorageKey = 'or_buffer_1';
|
|
@@ -81,26 +80,13 @@ class App {
|
|
|
81
80
|
this.stopCallbacks = [];
|
|
82
81
|
this.commitCallbacks = [];
|
|
83
82
|
this.activityState = ActivityState.NotActive;
|
|
84
|
-
this.version = '
|
|
83
|
+
this.version = '13.0.1'; // TODO: version compatability check inside each plugin.
|
|
84
|
+
this.socketMode = false;
|
|
85
85
|
this.compressionThreshold = 24 * 1000;
|
|
86
86
|
this.restartAttempts = 0;
|
|
87
87
|
this.bc = null;
|
|
88
88
|
this.canvasRecorder = null;
|
|
89
89
|
this.conditionsManager = null;
|
|
90
|
-
this._debug = (context, e) => {
|
|
91
|
-
if (this.options.__debug_report_edp !== null) {
|
|
92
|
-
void fetch(this.options.__debug_report_edp, {
|
|
93
|
-
method: 'POST',
|
|
94
|
-
headers: { 'Content-Type': 'application/json' },
|
|
95
|
-
body: JSON.stringify({
|
|
96
|
-
context,
|
|
97
|
-
// @ts-ignore
|
|
98
|
-
error: `${e}`,
|
|
99
|
-
}),
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
this.debug.error('OpenReplay error: ', context, e);
|
|
103
|
-
};
|
|
104
90
|
this._usingOldFetchPlugin = false;
|
|
105
91
|
this.coldStartCommitN = 0;
|
|
106
92
|
this.delay = 0;
|
|
@@ -132,6 +118,18 @@ class App {
|
|
|
132
118
|
});
|
|
133
119
|
};
|
|
134
120
|
this.onUxtCb = [];
|
|
121
|
+
if (Object.keys(options).findIndex((k) => ['fixedCanvasScaling', 'disableCanvas'].includes(k)) !==
|
|
122
|
+
-1) {
|
|
123
|
+
console.warn('Openreplay: canvas options are moving to separate key "canvas" in next update. Please update your configuration.');
|
|
124
|
+
options = {
|
|
125
|
+
...options,
|
|
126
|
+
canvas: {
|
|
127
|
+
__save_canvas_locally: options.__save_canvas_locally,
|
|
128
|
+
fixedCanvasScaling: options.fixedCanvasScaling,
|
|
129
|
+
disableCanvas: options.disableCanvas,
|
|
130
|
+
},
|
|
131
|
+
};
|
|
132
|
+
}
|
|
135
133
|
this.contextId = Math.random().toString(36).slice(2);
|
|
136
134
|
this.projectKey = projectKey;
|
|
137
135
|
this.networkOptions = options.network;
|
|
@@ -156,6 +154,13 @@ class App {
|
|
|
156
154
|
assistSocketHost: '',
|
|
157
155
|
fixedCanvasScaling: false,
|
|
158
156
|
disableCanvas: false,
|
|
157
|
+
assistOnly: false,
|
|
158
|
+
canvas: {
|
|
159
|
+
disableCanvas: false,
|
|
160
|
+
fixedCanvasScaling: false,
|
|
161
|
+
__save_canvas_locally: false,
|
|
162
|
+
useAnimationFrame: false,
|
|
163
|
+
},
|
|
159
164
|
}, options);
|
|
160
165
|
if (!this.options.forceSingleTab && globalThis && 'BroadcastChannel' in globalThis) {
|
|
161
166
|
const host = location.hostname.split('.').slice(-2).join('_');
|
|
@@ -190,11 +195,51 @@ class App {
|
|
|
190
195
|
this.session.applySessionHash(sessionToken);
|
|
191
196
|
}
|
|
192
197
|
try {
|
|
193
|
-
const webworker = new Worker(URL.createObjectURL(new Blob(['"use strict";const t="function"==typeof TextEncoder?new TextEncoder:{encode(t){const i=t.length,s=new Uint8Array(3*i);let e=-1;for(let n=0,r=0,h=0;h!==i;){if(n=t.charCodeAt(h),h+=1,n>=55296&&n<=56319){if(h===i){s[e+=1]=239,s[e+=1]=191,s[e+=1]=189;break}if(r=t.charCodeAt(h),!(r>=56320&&r<=57343)){s[e+=1]=239,s[e+=1]=191,s[e+=1]=189;continue}if(n=1024*(n-55296)+r-56320+65536,h+=1,n>65535){s[e+=1]=240|n>>>18,s[e+=1]=128|n>>>12&63,s[e+=1]=128|n>>>6&63,s[e+=1]=128|63&n;continue}}n<=127?s[e+=1]=0|n:n<=2047?(s[e+=1]=192|n>>>6,s[e+=1]=128|63&n):(s[e+=1]=224|n>>>12,s[e+=1]=128|n>>>6&63,s[e+=1]=128|63&n)}return s.subarray(0,e+1)}};class i{constructor(t){this.size=t,this.offset=0,this.checkpointOffset=0,this.data=new Uint8Array(t)}getCurrentOffset(){return this.offset}checkpoint(){this.checkpointOffset=this.offset}get isEmpty(){return 0===this.offset}skip(t){return this.offset+=t,this.offset<=this.size}set(t,i){this.data.set(t,i)}boolean(t){return this.data[this.offset++]=+t,this.offset<=this.size}uint(t){for((t<0||t>Number.MAX_SAFE_INTEGER)&&(t=0);t>=128;)this.data[this.offset++]=t%256|128,t=Math.floor(t/128);return this.data[this.offset++]=t,this.offset<=this.size}int(t){return t=Math.round(t),this.uint(t>=0?2*t:-2*t-1)}string(i){const s=t.encode(i),e=s.byteLength;return!(!this.uint(e)||this.offset+e>this.size)&&(this.data.set(s,this.offset),this.offset+=e,!0)}reset(){this.offset=0,this.checkpointOffset=0}flush(){const t=this.data.slice(0,this.checkpointOffset);return this.reset(),t}}class s extends i{encode(t){switch(t[0]){case 0:case 11:case 114:case 115:return this.uint(t[1]);case 4:case 44:case 47:return this.string(t[1])&&this.string(t[2])&&this.uint(t[3]);case 5:case 20:case 38:case 70:case 75:case 76:case 77:case 82:return this.uint(t[1])&&this.uint(t[2]);case 6:return this.int(t[1])&&this.int(t[2]);case 7:return!0;case 8:return this.uint(t[1])&&this.uint(t[2])&&this.uint(t[3])&&this.string(t[4])&&this.boolean(t[5]);case 9:case 10:case 24:case 51:return this.uint(t[1])&&this.uint(t[2])&&this.uint(t[3]);case 12:case 61:case 71:return this.uint(t[1])&&this.string(t[2])&&this.string(t[3]);case 13:case 14:case 17:case 50:case 54:return this.uint(t[1])&&this.string(t[2]);case 16:return this.uint(t[1])&&this.int(t[2])&&this.int(t[3]);case 18:return this.uint(t[1])&&this.string(t[2])&&this.int(t[3]);case 19:return this.uint(t[1])&&this.boolean(t[2]);case 21:return this.string(t[1])&&this.string(t[2])&&this.string(t[3])&&this.string(t[4])&&this.string(t[5])&&this.uint(t[6])&&this.uint(t[7])&&this.uint(t[8]);case 22:case 27:case 30:case 41:case 45:case 46:case 63:case 64:case 79:return this.string(t[1])&&this.string(t[2]);case 23:return this.uint(t[1])&&this.uint(t[2])&&this.uint(t[3])&&this.uint(t[4])&&this.uint(t[5])&&this.uint(t[6])&&this.uint(t[7])&&this.uint(t[8])&&this.uint(t[9]);case 28:case 29:case 42:case 117:case 118:return this.string(t[1]);case 37:return this.uint(t[1])&&this.string(t[2])&&this.uint(t[3]);case 39:return this.string(t[1])&&this.string(t[2])&&this.string(t[3])&&this.string(t[4])&&this.uint(t[5])&&this.uint(t[6])&&this.uint(t[7]);case 40:return this.string(t[1])&&this.uint(t[2])&&this.string(t[3])&&this.string(t[4]);case 48:case 78:return this.string(t[1])&&this.string(t[2])&&this.string(t[3])&&this.string(t[4]);case 49:return this.int(t[1])&&this.int(t[2])&&this.uint(t[3])&&this.uint(t[4]);case 53:return this.uint(t[1])&&this.uint(t[2])&&this.uint(t[3])&&this.uint(t[4])&&this.uint(t[5])&&this.uint(t[6])&&this.string(t[7])&&this.string(t[8]);case 55:return this.boolean(t[1]);case 57:case 60:return this.uint(t[1])&&this.string(t[2])&&this.string(t[3])&&this.string(t[4]);case 58:case 120:return this.int(t[1]);case 59:return this.uint(t[1])&&this.uint(t[2])&&this.uint(t[3])&&this.uint(t[4])&&this.string(t[5])&&this.string(t[6])&&this.string(t[7]);case 67:case 73:return this.uint(t[1])&&this.string(t[2])&&this.uint(t[3])&&this.string(t[4]);case 69:return this.uint(t[1])&&this.uint(t[2])&&this.string(t[3])&&this.string(t[4]);case 81:return this.uint(t[1])&&this.uint(t[2])&&this.uint(t[3])&&this.int(t[4])&&this.string(t[5]);case 83:return this.string(t[1])&&this.string(t[2])&&this.string(t[3])&&this.string(t[4])&&this.string(t[5])&&this.uint(t[6])&&this.uint(t[7])&&this.uint(t[8])&&this.uint(t[9]);case 84:return this.string(t[1])&&this.string(t[2])&&this.string(t[3])&&this.uint(t[4])&&this.string(t[5])&&this.string(t[6]);case 112:return this.uint(t[1])&&this.string(t[2])&&this.boolean(t[3])&&this.string(t[4])&&this.int(t[5])&&this.int(t[6]);case 113:return this.uint(t[1])&&this.uint(t[2])&&this.string(t[3]);case 116:return this.uint(t[1])&&this.uint(t[2])&&this.uint(t[3])&&this.uint(t[4])&&this.uint(t[5])&&this.uint(t[6])&&this.string(t[7])&&this.string(t[8])&&this.uint(t[9])&&this.boolean(t[10]);case 119:return this.string(t[1])&&this.uint(t[2]);case 121:return this.string(t[1])&&this.string(t[2])&&this.uint(t[3])&&this.uint(t[4])}}}class e{constructor(t,i,e,n,r,h){this.pageNo=t,this.timestamp=i,this.url=e,this.onBatch=n,this.tabId=r,this.onOfflineEnd=h,this.nextIndex=0,this.beaconSize=2e5,this.encoder=new s(this.beaconSize),this.sizeBuffer=new Uint8Array(3),this.isEmpty=!0,this.beaconSizeLimit=1e6,this.prepare()}writeType(t){return this.encoder.uint(t[0])}writeFields(t){return this.encoder.encode(t)}writeSizeAt(t,i){for(let i=0;i<3;i++)this.sizeBuffer[i]=t>>8*i;this.encoder.set(this.sizeBuffer,i)}prepare(){if(!this.encoder.isEmpty)return;const t=[81,1,this.pageNo,this.nextIndex,this.timestamp,this.url],i=[118,this.tabId];this.writeType(t),this.writeFields(t),this.writeWithSize(i),this.isEmpty=!0}writeWithSize(t){const i=this.encoder;if(!this.writeType(t)||!i.skip(3))return!1;const s=i.getCurrentOffset(),e=this.writeFields(t);if(e){const e=i.getCurrentOffset()-s;if(e>16777215)return console.warn("OpenReplay: max message size overflow."),!1;this.writeSizeAt(e,s-3),i.checkpoint(),this.isEmpty=this.isEmpty&&0===t[0],this.nextIndex++}return e}setBeaconSizeLimit(t){this.beaconSizeLimit=t}writeMessage(t){if("q_end"===t[0])return this.finaliseBatch(),this.onOfflineEnd();0===t[0]&&(this.timestamp=t[1]),4===t[0]&&(this.url=t[1]),this.writeWithSize(t)||(this.finaliseBatch(),this.writeWithSize(t)||(this.encoder=new s(this.beaconSizeLimit),this.prepare(),this.writeWithSize(t)?this.finaliseBatch():console.warn("OpenReplay: beacon size overflow. Skipping large message.",t,this),this.encoder=new s(this.beaconSize),this.prepare()))}finaliseBatch(){if(this.isEmpty)return;const t=this.encoder.flush();this.onBatch(t),this.prepare()}clean(){this.encoder.reset()}}var n;!function(t){t[t.NotActive=0]="NotActive",t[t.Starting=1]="Starting",t[t.Stopping=2]="Stopping",t[t.Active=3]="Active",t[t.Stopped=4]="Stopped"}(n||(n={}));let r=null,h=n.NotActive;function a(t){postMessage({type:"status",data:t}),h=t}function u(){r&&r.finaliseBatch()}function c(){a(n.Stopping),null!==f&&(clearInterval(f),f=null),r&&(r.clean(),r=null),setTimeout((()=>{a(n.NotActive)}),100)}function o(){h!==n.Stopped&&(postMessage({type:"restart"}),c())}let f=null;self.onmessage=({data:t})=>{if(null!=t){if("writer_finalize"===t.type)return u(),h=n.Stopped;if("reset_writer"!==t.type){if("forceFlushBatch"!==t.type){if("to_writer"===t.type){let i=!1;t.data.forEach((t=>{r?r.writeMessage(t):i||(i=!0,postMessage({type:"not_init"}),o())}))}return"start"===t.type?(h=n.Starting,r=new e(t.pageNo,t.timestamp,t.url,(t=>{postMessage({type:"batch_ready",data:t},[t.buffer])}),t.tabId,(()=>postMessage({type:"queue_empty"}))),null===f&&(f=setInterval(u,1e4)),h=n.Active):"beacon_size_limit"===t.type?r?void(t.beaconSizeLimit&&r.setBeaconSizeLimit(t.beaconSizeLimit)):(console.debug("OR WebWorker: writer not initialised. Received auth."),void o()):void("restart"===t.type&&o())}u()}else c()}else u()};'], { type: 'text/javascript' })));
|
|
194
|
-
this.
|
|
198
|
+
this.worker = new Worker(URL.createObjectURL(new Blob(['"use strict";class t{constructor(t,s,i,e=10,n=250,h,r){this.onUnauthorised=s,this.onFailure=i,this.MAX_ATTEMPTS_COUNT=e,this.ATTEMPT_TIMEOUT=n,this.onCompress=h,this.pageNo=r,this.attemptsCount=0,this.busy=!1,this.queue=[],this.token=null,this.lastBatchNum=0,this.ingestURL=t+"/v1/web/i",this.isCompressing=void 0!==h}getQueueStatus(){return 0===this.queue.length&&!this.busy}authorise(t){this.token=t,this.busy||this.sendNext()}push(t){if(this.busy||!this.token)this.queue.push(t);else if(this.busy=!0,this.isCompressing&&this.onCompress)this.onCompress(t);else{const s=++this.lastBatchNum;this.sendBatch(t,!1,s)}}sendNext(){const t=this.queue.shift();if(t)if(this.busy=!0,this.isCompressing&&this.onCompress)this.onCompress(t);else{const s=++this.lastBatchNum;this.sendBatch(t,!1,s)}else this.busy=!1}retry(t,s,i){this.attemptsCount>=this.MAX_ATTEMPTS_COUNT?this.onFailure(`Failed to send batch after ${this.attemptsCount} attempts.`):(this.attemptsCount++,setTimeout((()=>this.sendBatch(t,s,i)),this.ATTEMPT_TIMEOUT*this.attemptsCount))}sendBatch(t,s,i){const e=i?.toString().replace(/^([^_]+)_([^_]+).*/,"$1_$2_$3");this.busy=!0;const n={Authorization:`Bearer ${this.token}`};s&&(n["Content-Encoding"]="gzip"),null!==this.token?fetch(`${this.ingestURL}?batch=${this.pageNo??"noPageNum"}_${e??"noBatchNum"}`,{body:t,method:"POST",headers:n,keepalive:t.length<65536}).then((e=>{if(401===e.status)return this.busy=!1,void this.onUnauthorised();e.status>=400?this.retry(t,s,`${i??"noBatchNum"}_network:${e.status}`):(this.attemptsCount=0,this.sendNext())})).catch((e=>{console.warn("OpenReplay:",e),this.retry(t,s,`${i??"noBatchNum"}_reject:${e.message}`)})):setTimeout((()=>{this.sendBatch(t,s,`${i??"noBatchNum"}_newToken`)}),500)}sendCompressed(t){const s=++this.lastBatchNum;this.sendBatch(t,!0,s)}sendUncompressed(t){const s=++this.lastBatchNum;this.sendBatch(t,!1,s)}clean(){this.sendNext(),setTimeout((()=>{this.token=null,this.queue.length=0}),10)}}const s="function"==typeof TextEncoder?new TextEncoder:{encode(t){const s=t.length,i=new Uint8Array(3*s);let e=-1;for(let n=0,h=0,r=0;r!==s;){if(n=t.charCodeAt(r),r+=1,n>=55296&&n<=56319){if(r===s){i[e+=1]=239,i[e+=1]=191,i[e+=1]=189;break}if(h=t.charCodeAt(r),!(h>=56320&&h<=57343)){i[e+=1]=239,i[e+=1]=191,i[e+=1]=189;continue}if(n=1024*(n-55296)+h-56320+65536,r+=1,n>65535){i[e+=1]=240|n>>>18,i[e+=1]=128|n>>>12&63,i[e+=1]=128|n>>>6&63,i[e+=1]=128|63&n;continue}}n<=127?i[e+=1]=0|n:n<=2047?(i[e+=1]=192|n>>>6,i[e+=1]=128|63&n):(i[e+=1]=224|n>>>12,i[e+=1]=128|n>>>6&63,i[e+=1]=128|63&n)}return i.subarray(0,e+1)}};class i{constructor(t){this.size=t,this.offset=0,this.checkpointOffset=0,this.data=new Uint8Array(t)}getCurrentOffset(){return this.offset}checkpoint(){this.checkpointOffset=this.offset}get isEmpty(){return 0===this.offset}skip(t){return this.offset+=t,this.offset<=this.size}set(t,s){this.data.set(t,s)}boolean(t){return this.data[this.offset++]=+t,this.offset<=this.size}uint(t){for((t<0||t>Number.MAX_SAFE_INTEGER)&&(t=0);t>=128;)this.data[this.offset++]=t%256|128,t=Math.floor(t/128);return this.data[this.offset++]=t,this.offset<=this.size}int(t){return t=Math.round(t),this.uint(t>=0?2*t:-2*t-1)}string(t){const i=s.encode(t),e=i.byteLength;return!(!this.uint(e)||this.offset+e>this.size)&&(this.data.set(i,this.offset),this.offset+=e,!0)}reset(){this.offset=0,this.checkpointOffset=0}flush(){const t=this.data.slice(0,this.checkpointOffset);return this.reset(),t}}class e extends i{encode(t){switch(t[0]){case 0:case 11:case 114:case 115:return this.uint(t[1]);case 4:case 44:case 47:return this.string(t[1])&&this.string(t[2])&&this.uint(t[3]);case 5:case 20:case 38:case 70:case 75:case 76:case 77:case 82:return this.uint(t[1])&&this.uint(t[2]);case 6:return this.int(t[1])&&this.int(t[2]);case 7:return!0;case 8:return this.uint(t[1])&&this.uint(t[2])&&this.uint(t[3])&&this.string(t[4])&&this.boolean(t[5]);case 9:case 10:case 24:case 51:return this.uint(t[1])&&this.uint(t[2])&&this.uint(t[3]);case 12:case 61:case 71:return this.uint(t[1])&&this.string(t[2])&&this.string(t[3]);case 13:case 14:case 17:case 50:case 54:return this.uint(t[1])&&this.string(t[2]);case 16:return this.uint(t[1])&&this.int(t[2])&&this.int(t[3]);case 18:return this.uint(t[1])&&this.string(t[2])&&this.int(t[3]);case 19:return this.uint(t[1])&&this.boolean(t[2]);case 21:return this.string(t[1])&&this.string(t[2])&&this.string(t[3])&&this.string(t[4])&&this.string(t[5])&&this.uint(t[6])&&this.uint(t[7])&&this.uint(t[8]);case 22:case 27:case 30:case 41:case 45:case 46:case 63:case 64:case 79:return this.string(t[1])&&this.string(t[2]);case 23:return this.uint(t[1])&&this.uint(t[2])&&this.uint(t[3])&&this.uint(t[4])&&this.uint(t[5])&&this.uint(t[6])&&this.uint(t[7])&&this.uint(t[8])&&this.uint(t[9]);case 28:case 29:case 42:case 117:case 118:return this.string(t[1]);case 37:return this.uint(t[1])&&this.string(t[2])&&this.uint(t[3]);case 39:return this.string(t[1])&&this.string(t[2])&&this.string(t[3])&&this.string(t[4])&&this.uint(t[5])&&this.uint(t[6])&&this.uint(t[7]);case 40:return this.string(t[1])&&this.uint(t[2])&&this.string(t[3])&&this.string(t[4]);case 48:case 78:return this.string(t[1])&&this.string(t[2])&&this.string(t[3])&&this.string(t[4]);case 49:return this.int(t[1])&&this.int(t[2])&&this.uint(t[3])&&this.uint(t[4]);case 53:return this.uint(t[1])&&this.uint(t[2])&&this.uint(t[3])&&this.uint(t[4])&&this.uint(t[5])&&this.uint(t[6])&&this.string(t[7])&&this.string(t[8]);case 55:return this.boolean(t[1]);case 57:case 60:return this.uint(t[1])&&this.string(t[2])&&this.string(t[3])&&this.string(t[4]);case 58:case 120:return this.int(t[1]);case 59:return this.uint(t[1])&&this.uint(t[2])&&this.uint(t[3])&&this.uint(t[4])&&this.string(t[5])&&this.string(t[6])&&this.string(t[7]);case 67:case 73:return this.uint(t[1])&&this.string(t[2])&&this.uint(t[3])&&this.string(t[4]);case 69:return this.uint(t[1])&&this.uint(t[2])&&this.string(t[3])&&this.string(t[4]);case 81:return this.uint(t[1])&&this.uint(t[2])&&this.uint(t[3])&&this.int(t[4])&&this.string(t[5]);case 83:return this.string(t[1])&&this.string(t[2])&&this.string(t[3])&&this.string(t[4])&&this.string(t[5])&&this.uint(t[6])&&this.uint(t[7])&&this.uint(t[8])&&this.uint(t[9]);case 84:return this.string(t[1])&&this.string(t[2])&&this.string(t[3])&&this.uint(t[4])&&this.string(t[5])&&this.string(t[6]);case 112:return this.uint(t[1])&&this.string(t[2])&&this.boolean(t[3])&&this.string(t[4])&&this.int(t[5])&&this.int(t[6]);case 113:return this.uint(t[1])&&this.uint(t[2])&&this.string(t[3]);case 116:return this.uint(t[1])&&this.uint(t[2])&&this.uint(t[3])&&this.uint(t[4])&&this.uint(t[5])&&this.uint(t[6])&&this.string(t[7])&&this.string(t[8])&&this.uint(t[9])&&this.boolean(t[10]);case 119:return this.string(t[1])&&this.uint(t[2]);case 121:return this.string(t[1])&&this.string(t[2])&&this.uint(t[3])&&this.uint(t[4])}}}class n{constructor(t,s,i,n,h,r){this.pageNo=t,this.timestamp=s,this.url=i,this.onBatch=n,this.tabId=h,this.onOfflineEnd=r,this.nextIndex=0,this.beaconSize=2e5,this.encoder=new e(this.beaconSize),this.sizeBuffer=new Uint8Array(3),this.isEmpty=!0,this.beaconSizeLimit=1e6,this.prepare()}writeType(t){return this.encoder.uint(t[0])}writeFields(t){return this.encoder.encode(t)}writeSizeAt(t,s){for(let s=0;s<3;s++)this.sizeBuffer[s]=t>>8*s;this.encoder.set(this.sizeBuffer,s)}prepare(){if(!this.encoder.isEmpty)return;const t=[81,1,this.pageNo,this.nextIndex,this.timestamp,this.url],s=[118,this.tabId];this.writeType(t),this.writeFields(t),this.writeWithSize(s),this.isEmpty=!0}writeWithSize(t){const s=this.encoder;if(!this.writeType(t)||!s.skip(3))return!1;const i=s.getCurrentOffset(),e=this.writeFields(t);if(e){const e=s.getCurrentOffset()-i;if(e>16777215)return console.warn("OpenReplay: max message size overflow."),!1;this.writeSizeAt(e,i-3),s.checkpoint(),this.isEmpty=this.isEmpty&&0===t[0],this.nextIndex++}return e}setBeaconSizeLimit(t){this.beaconSizeLimit=t}writeMessage(t){if("q_end"===t[0])return this.finaliseBatch(),this.onOfflineEnd();0===t[0]&&(this.timestamp=t[1]),4===t[0]&&(this.url=t[1]),this.writeWithSize(t)||(this.finaliseBatch(),this.writeWithSize(t)||(this.encoder=new e(this.beaconSizeLimit),this.prepare(),this.writeWithSize(t)?this.finaliseBatch():console.warn("OpenReplay: beacon size overflow. Skipping large message.",t,this),this.encoder=new e(this.beaconSize),this.prepare()))}finaliseBatch(){if(this.isEmpty)return;const t=this.encoder.flush();this.onBatch(t),this.prepare()}clean(){this.encoder.reset()}}var h;!function(t){t[t.NotActive=0]="NotActive",t[t.Starting=1]="Starting",t[t.Stopping=2]="Stopping",t[t.Active=3]="Active",t[t.Stopped=4]="Stopped"}(h||(h={}));let r=null,a=null,u=h.NotActive;function o(){a&&a.finaliseBatch()}function c(){return new Promise((t=>{u=h.Stopping,null!==l&&(clearInterval(l),l=null),a&&(a.clean(),a=null),r&&(r.clean(),setTimeout((()=>{r=null}),20)),setTimeout((()=>{u=h.NotActive,t(null)}),100)}))}function p(){u!==h.Stopped&&(postMessage("a_stop"),c().then((()=>{postMessage("a_start")})))}let g,l=null;self.onmessage=({data:s})=>{if(null!=s){if("stop"===s)return o(),void c().then((()=>{u=h.Stopped}));if("forceFlushBatch"!==s){if(!Array.isArray(s)){if("compressed"===s.type){if(!r)return console.debug("OR WebWorker: sender not initialised. Compressed batch."),void p();s.batch&&r.sendCompressed(s.batch)}if("uncompressed"===s.type){if(!r)return console.debug("OR WebWorker: sender not initialised. Uncompressed batch."),void p();s.batch&&r.sendUncompressed(s.batch)}return"start"===s.type?(u=h.Starting,r=new t(s.ingestPoint,(()=>{p()}),(t=>{!function(t){postMessage({type:"failure",reason:t}),c()}(t)}),s.connAttemptCount,s.connAttemptGap,(t=>{postMessage({type:"compress",batch:t},[t.buffer])}),s.pageNo),a=new n(s.pageNo,s.timestamp,s.url,(t=>{r&&r.push(t)}),s.tabId,(()=>postMessage({type:"queue_empty"}))),null===l&&(l=setInterval(o,1e4)),u=h.Active):"auth"===s.type?r?a?(r.authorise(s.token),void(s.beaconSizeLimit&&a.setBeaconSizeLimit(s.beaconSizeLimit))):(console.debug("OR WebWorker: writer not initialised. Received auth."),void p()):(console.debug("OR WebWorker: sender not initialised. Received auth."),void p()):void 0}if(a){const t=a;s.forEach((s=>{55===s[0]&&(s[1]?g=setTimeout((()=>p()),18e5):clearTimeout(g)),t.writeMessage(s)}))}else postMessage("not_init"),p()}else o()}else o()};'], { type: 'text/javascript' })));
|
|
199
|
+
this.worker.onerror = (e) => {
|
|
200
|
+
this._debug('webworker_error', e);
|
|
201
|
+
};
|
|
202
|
+
this.worker.onmessage = ({ data }) => {
|
|
203
|
+
// handling 401 auth restart (new token assignment)
|
|
204
|
+
if (data === 'a_stop') {
|
|
205
|
+
this.stop(false);
|
|
206
|
+
}
|
|
207
|
+
else if (data === 'a_start') {
|
|
208
|
+
void this.start({}, true);
|
|
209
|
+
}
|
|
210
|
+
else if (data === 'not_init') {
|
|
211
|
+
this.debug.warn('OR WebWorker: writer not initialised. Restarting tracker');
|
|
212
|
+
}
|
|
213
|
+
else if (data.type === 'failure') {
|
|
214
|
+
this.stop(false);
|
|
215
|
+
this.debug.error('worker_failed', data.reason);
|
|
216
|
+
this._debug('worker_failed', data.reason);
|
|
217
|
+
}
|
|
218
|
+
else if (data.type === 'compress') {
|
|
219
|
+
const batch = data.batch;
|
|
220
|
+
const batchSize = batch.byteLength;
|
|
221
|
+
if (batchSize > this.compressionThreshold) {
|
|
222
|
+
(0, fflate_1.gzip)(data.batch, { mtime: 0 }, (err, result) => {
|
|
223
|
+
if (err) {
|
|
224
|
+
this.debug.error('Openreplay compression error:', err);
|
|
225
|
+
this.worker?.postMessage({ type: 'uncompressed', batch: batch });
|
|
226
|
+
}
|
|
227
|
+
else {
|
|
228
|
+
this.worker?.postMessage({ type: 'compressed', batch: result });
|
|
229
|
+
}
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
else {
|
|
233
|
+
this.worker?.postMessage({ type: 'uncompressed', batch: batch });
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
else if (data.type === 'queue_empty') {
|
|
237
|
+
this.onSessionSent();
|
|
238
|
+
}
|
|
239
|
+
};
|
|
195
240
|
const alertWorker = () => {
|
|
196
|
-
if (this.
|
|
197
|
-
this.
|
|
241
|
+
if (this.worker) {
|
|
242
|
+
this.worker.postMessage(null);
|
|
198
243
|
}
|
|
199
244
|
};
|
|
200
245
|
// keep better tactics, discard others?
|
|
@@ -213,7 +258,7 @@ class App {
|
|
|
213
258
|
// yes, there are someone out there
|
|
214
259
|
resp: 'never-gonna-let-you-down',
|
|
215
260
|
// you stole someone's identity
|
|
216
|
-
|
|
261
|
+
reg: 'never-gonna-run-around-and-desert-you',
|
|
217
262
|
};
|
|
218
263
|
if (this.bc) {
|
|
219
264
|
this.bc.postMessage({
|
|
@@ -231,7 +276,7 @@ class App {
|
|
|
231
276
|
const sessionToken = ev.data.token;
|
|
232
277
|
this.session.setSessionToken(sessionToken);
|
|
233
278
|
}
|
|
234
|
-
if (ev.data.line === proto.
|
|
279
|
+
if (ev.data.line === proto.reg) {
|
|
235
280
|
const sessionToken = ev.data.token;
|
|
236
281
|
this.session.regenerateTabId();
|
|
237
282
|
this.session.setSessionToken(sessionToken);
|
|
@@ -240,7 +285,7 @@ class App {
|
|
|
240
285
|
const token = this.session.getSessionToken();
|
|
241
286
|
if (token && this.bc) {
|
|
242
287
|
this.bc.postMessage({
|
|
243
|
-
line: ev.data.source === thisTab ? proto.
|
|
288
|
+
line: ev.data.source === thisTab ? proto.reg : proto.resp,
|
|
244
289
|
token,
|
|
245
290
|
source: thisTab,
|
|
246
291
|
context: this.contextId,
|
|
@@ -250,44 +295,19 @@ class App {
|
|
|
250
295
|
};
|
|
251
296
|
}
|
|
252
297
|
}
|
|
253
|
-
|
|
254
|
-
if (
|
|
255
|
-
this.
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
this._debug('worker_failed', data.reason);
|
|
265
|
-
}
|
|
266
|
-
else if (data.type === 'compress') {
|
|
267
|
-
const batch = data.batch;
|
|
268
|
-
const batchSize = batch.byteLength;
|
|
269
|
-
if (batchSize > this.compressionThreshold) {
|
|
270
|
-
(0, fflate_1.gzip)(data.batch, { mtime: 0 }, (err, result) => {
|
|
271
|
-
if (err) {
|
|
272
|
-
this.debug.error('Openreplay compression error:', err);
|
|
273
|
-
this.stop(false);
|
|
274
|
-
if (this.restartAttempts < 3) {
|
|
275
|
-
this.restartAttempts += 1;
|
|
276
|
-
void this.start({}, true);
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
else {
|
|
280
|
-
this.workerManager?.sendCompressedBatch(result);
|
|
281
|
-
}
|
|
282
|
-
});
|
|
283
|
-
}
|
|
284
|
-
else {
|
|
285
|
-
this.workerManager?.sendUncompressedBatch(batch);
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
else if (data.type === 'queue_empty') {
|
|
289
|
-
this.onSessionSent();
|
|
298
|
+
_debug(context, e) {
|
|
299
|
+
if (this.options.__debug_report_edp !== null) {
|
|
300
|
+
void fetch(this.options.__debug_report_edp, {
|
|
301
|
+
method: 'POST',
|
|
302
|
+
headers: { 'Content-Type': 'application/json' },
|
|
303
|
+
body: JSON.stringify({
|
|
304
|
+
context,
|
|
305
|
+
// @ts-ignore
|
|
306
|
+
error: `${e}`,
|
|
307
|
+
}),
|
|
308
|
+
});
|
|
290
309
|
}
|
|
310
|
+
this.debug.error('OpenReplay error: ', context, e);
|
|
291
311
|
}
|
|
292
312
|
send(message, urgent = false) {
|
|
293
313
|
if (this.activityState === ActivityState.NotActive) {
|
|
@@ -327,15 +347,31 @@ class App {
|
|
|
327
347
|
* every ~30ms
|
|
328
348
|
* */
|
|
329
349
|
_nCommit() {
|
|
330
|
-
if (this.
|
|
331
|
-
(0,
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
350
|
+
if (this.socketMode) {
|
|
351
|
+
this.messages.unshift((0, messages_gen_js_2.TabData)(this.session.getTabId()));
|
|
352
|
+
this.messages.unshift((0, messages_gen_js_2.Timestamp)(this.timestamp()));
|
|
353
|
+
this.commitCallbacks.forEach((cb) => cb(this.messages));
|
|
354
|
+
this.messages.length = 0;
|
|
355
|
+
return;
|
|
356
|
+
}
|
|
357
|
+
if (this.worker !== undefined && this.messages.length) {
|
|
358
|
+
try {
|
|
359
|
+
(0, utils_js_1.requestIdleCb)(() => {
|
|
360
|
+
this.messages.unshift((0, messages_gen_js_2.TabData)(this.session.getTabId()));
|
|
361
|
+
this.messages.unshift((0, messages_gen_js_2.Timestamp)(this.timestamp()));
|
|
362
|
+
// why I need to add opt chaining?
|
|
363
|
+
this.worker?.postMessage(this.messages);
|
|
364
|
+
this.commitCallbacks.forEach((cb) => cb(this.messages));
|
|
365
|
+
this.messages.length = 0;
|
|
366
|
+
});
|
|
367
|
+
}
|
|
368
|
+
catch (e) {
|
|
369
|
+
this._debug('worker_commit', e);
|
|
370
|
+
this.stop(true);
|
|
371
|
+
setTimeout(() => {
|
|
372
|
+
void this.start();
|
|
373
|
+
}, 500);
|
|
374
|
+
}
|
|
339
375
|
}
|
|
340
376
|
}
|
|
341
377
|
/**
|
|
@@ -363,7 +399,7 @@ class App {
|
|
|
363
399
|
}
|
|
364
400
|
}
|
|
365
401
|
postToWorker(messages) {
|
|
366
|
-
this.
|
|
402
|
+
this.worker?.postMessage(messages);
|
|
367
403
|
this.commitCallbacks.forEach((cb) => cb(messages));
|
|
368
404
|
messages.length = 0;
|
|
369
405
|
}
|
|
@@ -510,7 +546,7 @@ class App {
|
|
|
510
546
|
}
|
|
511
547
|
/**
|
|
512
548
|
* start buffering messages without starting the actual session, which gives
|
|
513
|
-
* user 30 seconds to "activate" and record session by calling `start()` on conditional trigger
|
|
549
|
+
* user 30 seconds to "activate" and record session by calling `start()` on conditional trigger
|
|
514
550
|
* and we will then send buffered batch, so it won't get lost
|
|
515
551
|
* */
|
|
516
552
|
async coldStart(startOpts = {}, conditional) {
|
|
@@ -646,7 +682,7 @@ class App {
|
|
|
646
682
|
/**
|
|
647
683
|
* Saves the captured messages in localStorage (or whatever is used in its place)
|
|
648
684
|
*
|
|
649
|
-
* Then
|
|
685
|
+
* Then when this.offlineRecording is called, it will preload this messages and clear the storage item
|
|
650
686
|
*
|
|
651
687
|
* Keeping the size of local storage reasonable is up to the end users of this library
|
|
652
688
|
* */
|
|
@@ -675,7 +711,7 @@ class App {
|
|
|
675
711
|
async uploadOfflineRecording() {
|
|
676
712
|
this.stop(false);
|
|
677
713
|
const timestamp = (0, utils_js_1.now)();
|
|
678
|
-
this.
|
|
714
|
+
this.worker?.postMessage({
|
|
679
715
|
type: 'start',
|
|
680
716
|
pageNo: this.session.incPageNo(),
|
|
681
717
|
ingestPoint: this.options.ingestPoint,
|
|
@@ -703,7 +739,8 @@ class App {
|
|
|
703
739
|
}),
|
|
704
740
|
});
|
|
705
741
|
const { token, userBrowser, userCity, userCountry, userDevice, userOS, userState, beaconSizeLimit, projectID, } = await r.json();
|
|
706
|
-
this.
|
|
742
|
+
this.worker?.postMessage({
|
|
743
|
+
type: 'auth',
|
|
707
744
|
token,
|
|
708
745
|
beaconSizeLimit,
|
|
709
746
|
});
|
|
@@ -727,7 +764,7 @@ class App {
|
|
|
727
764
|
if (isColdStart && this.coldInterval) {
|
|
728
765
|
clearInterval(this.coldInterval);
|
|
729
766
|
}
|
|
730
|
-
if (!this.
|
|
767
|
+
if (!this.worker) {
|
|
731
768
|
const reason = 'No worker found: perhaps, CSP is not set.';
|
|
732
769
|
this.signalError(reason, []);
|
|
733
770
|
return Promise.resolve(UnsuccessfulStart(reason));
|
|
@@ -754,7 +791,7 @@ class App {
|
|
|
754
791
|
metadata: startOpts.metadata,
|
|
755
792
|
});
|
|
756
793
|
const timestamp = (0, utils_js_1.now)();
|
|
757
|
-
this.
|
|
794
|
+
this.worker.postMessage({
|
|
758
795
|
type: 'start',
|
|
759
796
|
pageNo: this.session.incPageNo(),
|
|
760
797
|
ingestPoint: this.options.ingestPoint,
|
|
@@ -785,6 +822,7 @@ class App {
|
|
|
785
822
|
jsHeapSizeLimit: performance_js_1.jsHeapSizeLimit,
|
|
786
823
|
timezone: getTimezone(),
|
|
787
824
|
condition: conditionName,
|
|
825
|
+
assistOnly: startOpts.assistOnly ?? this.socketMode,
|
|
788
826
|
}),
|
|
789
827
|
})
|
|
790
828
|
.then((r) => {
|
|
@@ -800,7 +838,7 @@ class App {
|
|
|
800
838
|
}
|
|
801
839
|
})
|
|
802
840
|
.then(async (r) => {
|
|
803
|
-
if (!this.
|
|
841
|
+
if (!this.worker) {
|
|
804
842
|
const reason = 'no worker found after start request (this might not happen)';
|
|
805
843
|
this.signalError(reason, []);
|
|
806
844
|
return Promise.reject(reason);
|
|
@@ -814,7 +852,7 @@ class App {
|
|
|
814
852
|
delay, // derived from token
|
|
815
853
|
sessionID, // derived from token
|
|
816
854
|
startTimestamp, // real startTS (server time), derived from sessionID
|
|
817
|
-
userBrowser, userCity, userCountry, userDevice, userOS, userState, canvasEnabled, canvasQuality, canvasFPS, } = r;
|
|
855
|
+
userBrowser, userCity, userCountry, userDevice, userOS, userState, canvasEnabled, canvasQuality, canvasFPS, assistOnly: socketOnly, } = r;
|
|
818
856
|
if (typeof token !== 'string' ||
|
|
819
857
|
typeof userUUID !== 'string' ||
|
|
820
858
|
(typeof startTimestamp !== 'number' && typeof startTimestamp !== 'undefined') ||
|
|
@@ -840,10 +878,17 @@ class App {
|
|
|
840
878
|
timestamp: startTimestamp || timestamp,
|
|
841
879
|
projectID,
|
|
842
880
|
});
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
}
|
|
881
|
+
if (socketOnly) {
|
|
882
|
+
this.socketMode = true;
|
|
883
|
+
this.worker.postMessage('stop');
|
|
884
|
+
}
|
|
885
|
+
else {
|
|
886
|
+
this.worker.postMessage({
|
|
887
|
+
type: 'auth',
|
|
888
|
+
token,
|
|
889
|
+
beaconSizeLimit,
|
|
890
|
+
});
|
|
891
|
+
}
|
|
847
892
|
if (!isNewSession && token === sessionToken) {
|
|
848
893
|
this.debug.log('continuing session on new tab', this.session.getTabId());
|
|
849
894
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
@@ -860,14 +905,15 @@ class App {
|
|
|
860
905
|
void this.featureFlags.reloadFlags();
|
|
861
906
|
await this.tagWatcher.fetchTags(this.options.ingestPoint, token);
|
|
862
907
|
this.activityState = ActivityState.Active;
|
|
863
|
-
if (canvasEnabled && !this.options.disableCanvas) {
|
|
908
|
+
if (canvasEnabled && !this.options.canvas.disableCanvas) {
|
|
864
909
|
this.canvasRecorder =
|
|
865
910
|
this.canvasRecorder ??
|
|
866
911
|
new canvas_js_1.default(this, {
|
|
867
912
|
fps: canvasFPS,
|
|
868
913
|
quality: canvasQuality,
|
|
869
|
-
isDebug: this.options.__save_canvas_locally,
|
|
870
|
-
fixedScaling: this.options.fixedCanvasScaling,
|
|
914
|
+
isDebug: this.options.canvas.__save_canvas_locally,
|
|
915
|
+
fixedScaling: this.options.canvas.fixedCanvasScaling,
|
|
916
|
+
useAnimationFrame: this.options.canvas.useAnimationFrame,
|
|
871
917
|
});
|
|
872
918
|
this.canvasRecorder.startTracking();
|
|
873
919
|
}
|
|
@@ -975,7 +1021,7 @@ class App {
|
|
|
975
1021
|
}
|
|
976
1022
|
}
|
|
977
1023
|
forceFlushBatch() {
|
|
978
|
-
this.
|
|
1024
|
+
this.worker?.postMessage('forceFlushBatch');
|
|
979
1025
|
}
|
|
980
1026
|
getTabId() {
|
|
981
1027
|
return this.session.getTabId();
|
|
@@ -1012,8 +1058,8 @@ class App {
|
|
|
1012
1058
|
this.stopCallbacks.forEach((cb) => cb());
|
|
1013
1059
|
this.debug.log('OpenReplay tracking stopped.');
|
|
1014
1060
|
this.tagWatcher.clear();
|
|
1015
|
-
if (this.
|
|
1016
|
-
this.
|
|
1061
|
+
if (this.worker && stopWorker) {
|
|
1062
|
+
this.worker.postMessage('stop');
|
|
1017
1063
|
}
|
|
1018
1064
|
this.canvasRecorder?.clear();
|
|
1019
1065
|
}
|
|
@@ -31,7 +31,7 @@ export declare function Fetch(method: string, url: string, request: string, resp
|
|
|
31
31
|
export declare function Profiler(name: string, duration: number, args: string, result: string): Messages.Profiler;
|
|
32
32
|
export declare function OTable(key: string, value: string): Messages.OTable;
|
|
33
33
|
export declare function StateAction(type: string): Messages.StateAction;
|
|
34
|
-
export declare function
|
|
34
|
+
export declare function ReduxDeprecated(action: string, state: string, duration: number): Messages.ReduxDeprecated;
|
|
35
35
|
export declare function Vuex(mutation: string, state: string): Messages.Vuex;
|
|
36
36
|
export declare function MobX(type: string, payload: string): Messages.MobX;
|
|
37
37
|
export declare function NgRx(action: string, state: string, duration: number): Messages.NgRx;
|
|
@@ -72,4 +72,4 @@ export declare function TabChange(tabId: string): Messages.TabChange;
|
|
|
72
72
|
export declare function TabData(tabId: string): Messages.TabData;
|
|
73
73
|
export declare function CanvasNode(nodeId: string, timestamp: number): Messages.CanvasNode;
|
|
74
74
|
export declare function TagTrigger(tagId: number): Messages.TagTrigger;
|
|
75
|
-
export declare function
|
|
75
|
+
export declare function Redux(action: string, state: string, duration: number, actionTime: number): Messages.Redux;
|