@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.
Files changed (95) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/bun.lockb +0 -0
  3. package/cjs/app/canvas.d.ts +2 -1
  4. package/cjs/app/canvas.js +27 -13
  5. package/cjs/app/index.d.ts +15 -8
  6. package/cjs/app/index.js +134 -88
  7. package/cjs/app/messages.gen.d.ts +2 -2
  8. package/cjs/app/messages.gen.js +8 -8
  9. package/cjs/common/interaction.d.ts +21 -56
  10. package/cjs/common/messages.gen.d.ts +7 -7
  11. package/cjs/index.js +2 -2
  12. package/coverage/clover.xml +1054 -964
  13. package/coverage/coverage-final.json +21 -21
  14. package/coverage/lcov-report/index.html +43 -43
  15. package/coverage/lcov-report/main/app/canvas.ts.html +224 -47
  16. package/coverage/lcov-report/main/app/guards.ts.html +26 -26
  17. package/coverage/lcov-report/main/app/index.html +42 -42
  18. package/coverage/lcov-report/main/app/index.ts.html +157 -37
  19. package/coverage/lcov-report/main/app/logger.ts.html +1 -1
  20. package/coverage/lcov-report/main/app/messages.gen.ts.html +244 -154
  21. package/coverage/lcov-report/main/app/nodes.ts.html +7 -4
  22. package/coverage/lcov-report/main/app/observer/iframe_observer.ts.html +1 -1
  23. package/coverage/lcov-report/main/app/observer/iframe_offsets.ts.html +1 -1
  24. package/coverage/lcov-report/main/app/observer/index.html +5 -5
  25. package/coverage/lcov-report/main/app/observer/shadow_root_observer.ts.html +1 -1
  26. package/coverage/lcov-report/main/app/observer/top_observer.ts.html +7 -4
  27. package/coverage/lcov-report/main/app/sanitizer.ts.html +2 -2
  28. package/coverage/lcov-report/main/app/session.ts.html +2 -2
  29. package/coverage/lcov-report/main/app/ticker.ts.html +1 -1
  30. package/coverage/lcov-report/main/index.html +13 -13
  31. package/coverage/lcov-report/main/index.ts.html +32 -14
  32. package/coverage/lcov-report/main/modules/Network/beaconProxy.ts.html +17 -8
  33. package/coverage/lcov-report/main/modules/Network/fetchProxy.ts.html +40 -13
  34. package/coverage/lcov-report/main/modules/Network/index.html +21 -21
  35. package/coverage/lcov-report/main/modules/Network/index.ts.html +2 -2
  36. package/coverage/lcov-report/main/modules/Network/networkMessage.ts.html +12 -6
  37. package/coverage/lcov-report/main/modules/Network/utils.ts.html +17 -8
  38. package/coverage/lcov-report/main/modules/Network/xhrProxy.ts.html +39 -12
  39. package/coverage/lcov-report/main/modules/attributeSender.ts.html +1 -1
  40. package/coverage/lcov-report/main/modules/axiosSpy.ts.html +1 -1
  41. package/coverage/lcov-report/main/modules/conditionsManager.ts.html +4 -22
  42. package/coverage/lcov-report/main/modules/connection.ts.html +1 -1
  43. package/coverage/lcov-report/main/modules/console.ts.html +1 -1
  44. package/coverage/lcov-report/main/modules/constructedStyleSheets.ts.html +3 -3
  45. package/coverage/lcov-report/main/modules/cssrules.ts.html +1 -1
  46. package/coverage/lcov-report/main/modules/exception.ts.html +1 -1
  47. package/coverage/lcov-report/main/modules/featureFlags.ts.html +1 -1
  48. package/coverage/lcov-report/main/modules/focus.ts.html +1 -1
  49. package/coverage/lcov-report/main/modules/fonts.ts.html +1 -1
  50. package/coverage/lcov-report/main/modules/img.ts.html +4 -4
  51. package/coverage/lcov-report/main/modules/index.html +24 -24
  52. package/coverage/lcov-report/main/modules/input.ts.html +1 -1
  53. package/coverage/lcov-report/main/modules/mouse.ts.html +1 -1
  54. package/coverage/lcov-report/main/modules/network.ts.html +2 -2
  55. package/coverage/lcov-report/main/modules/performance.ts.html +1 -1
  56. package/coverage/lcov-report/main/modules/scroll.ts.html +1 -1
  57. package/coverage/lcov-report/main/modules/selection.ts.html +1 -1
  58. package/coverage/lcov-report/main/modules/tabs.ts.html +1 -1
  59. package/coverage/lcov-report/main/modules/tagWatcher.ts.html +95 -92
  60. package/coverage/lcov-report/main/modules/timing.ts.html +1 -1
  61. package/coverage/lcov-report/main/modules/userTesting/SignalManager.ts.html +1 -1
  62. package/coverage/lcov-report/main/modules/userTesting/dnd.ts.html +1 -1
  63. package/coverage/lcov-report/main/modules/userTesting/index.html +1 -1
  64. package/coverage/lcov-report/main/modules/userTesting/index.ts.html +1 -1
  65. package/coverage/lcov-report/main/modules/userTesting/recorder.ts.html +1 -1
  66. package/coverage/lcov-report/main/modules/userTesting/styles.ts.html +1 -1
  67. package/coverage/lcov-report/main/modules/userTesting/utils.ts.html +1 -1
  68. package/coverage/lcov-report/main/modules/viewport.ts.html +4 -4
  69. package/coverage/lcov-report/main/utils.ts.html +181 -31
  70. package/coverage/lcov-report/webworker/BatchWriter.ts.html +1 -1
  71. package/coverage/lcov-report/webworker/MessageEncoder.gen.ts.html +31 -7
  72. package/coverage/lcov-report/webworker/PrimitiveEncoder.ts.html +1 -1
  73. package/coverage/lcov-report/webworker/QueueSender.ts.html +48 -18
  74. package/coverage/lcov-report/webworker/index.html +14 -14
  75. package/coverage/lcov-report/webworker/index.ts.html +51 -21
  76. package/coverage/lcov.info +1882 -1653
  77. package/lib/app/canvas.d.ts +2 -1
  78. package/lib/app/canvas.js +27 -13
  79. package/lib/app/index.d.ts +15 -8
  80. package/lib/app/index.js +134 -88
  81. package/lib/app/messages.gen.d.ts +2 -2
  82. package/lib/app/messages.gen.js +4 -4
  83. package/lib/common/interaction.d.ts +21 -56
  84. package/lib/common/messages.gen.d.ts +7 -7
  85. package/lib/common/tsconfig.tsbuildinfo +1 -1
  86. package/lib/index.js +2 -2
  87. package/package.json +2 -2
  88. package/cjs/app/workerManager/QueueSender.d.ts +0 -25
  89. package/cjs/app/workerManager/QueueSender.js +0 -133
  90. package/cjs/app/workerManager/index.d.ts +0 -37
  91. package/cjs/app/workerManager/index.js +0 -166
  92. package/lib/app/workerManager/QueueSender.d.ts +0 -25
  93. package/lib/app/workerManager/QueueSender.js +0 -130
  94. package/lib/app/workerManager/index.d.ts +0 -37
  95. 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
@@ -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: string;
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
- const snapshot = captureSnapshot(canvas, this.options.quality, this.snapshots[id].dummy, this.options.fixedScaling);
71
- this.snapshots[id].images.push({ id: this.app.timestamp(), data: snapshot });
72
- if (this.snapshots[id].images.length > 9) {
73
- this.sendSnaps(this.snapshots[id].images, id, this.snapshots[id].createdAt);
74
- this.snapshots[id].images = [];
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 = dataUrlToBlob(snapshot.data);
110
+ const blob = snapshot.data;
98
111
  if (!blob)
99
112
  return;
100
- formData.append('snapshot', blob[0], `${createdAt}_${canvasId}_${snapshot.id}.jpeg`);
113
+ formData.append('snapshot', blob, `${createdAt}_${canvasId}_${snapshot.id}.webp`);
101
114
  if (this.options.isDebug) {
102
- saveImageData(snapshot.data, `${createdAt}_${canvasId}_${snapshot.id}.jpeg`);
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/jpeg'; // or /png'
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
- return dummy.toDataURL(imageFormat, qualityInt[quality]);
153
+ dummy.toBlob(onBlob, imageFormat, qualityInt[quality]);
141
154
  }
142
155
  else {
143
- return canvas.toDataURL(imageFormat, qualityInt[quality]);
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(imageDataUrl, name) {
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;
@@ -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, FromWorkerData } from '../common/interaction.js';
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 workerManager?;
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
- handleWorkerMsg(data: FromWorkerData): void;
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, when this.offlineRecording is called, it will preload this messages and clear the storage item
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 = '12.1.0-beta.99'; // TODO: version compatability check inside each plugin.
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.workerManager = new index_js_2.default(this, webworker, this._debug);
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.workerManager) {
197
- this.workerManager.processMessage(null);
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
- regen: 'never-gonna-run-around-and-desert-you',
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.regen) {
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.regen : proto.resp,
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
- handleWorkerMsg(data) {
254
- if (data.type === 'restart') {
255
- this.stop(false);
256
- void this.start({}, true);
257
- }
258
- else if (data.type === 'not_init') {
259
- this.debug.warn('OR WebWorker: writer not initialised; restarting worker');
260
- }
261
- else if (data.type === 'failure') {
262
- this.stop(false);
263
- this.debug.error('worker_failed', data.reason);
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.workerManager !== undefined && this.messages.length) {
331
- (0, utils_js_1.requestIdleCb)(() => {
332
- this.messages.unshift((0, messages_gen_js_2.TabData)(this.session.getTabId()));
333
- this.messages.unshift((0, messages_gen_js_2.Timestamp)(this.timestamp()));
334
- // why I need to add opt chaining?
335
- this.workerManager?.processMessage({ type: 'batch', data: this.messages });
336
- this.commitCallbacks.forEach((cb) => cb(this.messages));
337
- this.messages.length = 0;
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.workerManager?.processMessage({ type: 'batch', data: messages });
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, when this.offlineRecording is called, it will preload this messages and clear the storage item
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.workerManager?.processMessage({
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.workerManager?.authorizeWorker({
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.workerManager) {
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.workerManager?.startWorker({
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.workerManager) {
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
- this.workerManager?.authorizeWorker({
844
- token,
845
- beaconSizeLimit,
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.workerManager?.processMessage({ type: 'forceFlushBatch' });
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.workerManager && stopWorker) {
1016
- this.workerManager?.stopWorker();
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 Redux(action: string, state: string, duration: number): Messages.Redux;
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 ReduxNew(action: string, state: string, duration: number, actionTime: number): Messages.ReduxNew;
75
+ export declare function Redux(action: string, state: string, duration: number, actionTime: number): Messages.Redux;