@openreplay/tracker 11.0.6 → 12.0.0-beta.99

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 (121) hide show
  1. package/CHANGELOG.md +4 -2
  2. package/cjs/app/index.d.ts +88 -9
  3. package/cjs/app/index.js +492 -125
  4. package/cjs/app/logger.d.ts +7 -17
  5. package/cjs/app/logger.js +11 -19
  6. package/cjs/app/messages.gen.d.ts +2 -0
  7. package/cjs/app/messages.gen.js +20 -1
  8. package/cjs/app/observer/iframe_observer.js +4 -1
  9. package/cjs/app/observer/shadow_root_observer.js +4 -1
  10. package/cjs/app/observer/top_observer.js +7 -4
  11. package/cjs/app/workerManager/QueueSender.d.ts +23 -0
  12. package/cjs/app/workerManager/QueueSender.js +126 -0
  13. package/cjs/app/workerManager/index.d.ts +37 -0
  14. package/cjs/app/workerManager/index.js +167 -0
  15. package/cjs/common/interaction.d.ts +56 -18
  16. package/cjs/common/messages.gen.d.ts +17 -2
  17. package/cjs/index.d.ts +45 -2
  18. package/cjs/index.js +237 -106
  19. package/cjs/modules/Network/beaconProxy.js +4 -1
  20. package/cjs/modules/Network/fetchProxy.js +24 -1
  21. package/cjs/modules/Network/index.js +6 -3
  22. package/cjs/modules/Network/xhrProxy.js +24 -1
  23. package/cjs/modules/conditionsManager.d.ts +84 -0
  24. package/cjs/modules/conditionsManager.js +343 -0
  25. package/cjs/modules/exception.js +4 -1
  26. package/cjs/modules/featureFlags.d.ts +1 -1
  27. package/cjs/modules/featureFlags.js +36 -46
  28. package/cjs/modules/network.js +5 -2
  29. package/cjs/modules/tagWatcher.d.ts +21 -0
  30. package/cjs/modules/tagWatcher.js +77 -0
  31. package/cjs/modules/userTesting/index.js +30 -4
  32. package/cjs/modules/userTesting/recorder.js +71 -88
  33. package/coverage/clover.xml +577 -544
  34. package/coverage/coverage-final.json +8 -8
  35. package/coverage/lcov-report/index.html +28 -28
  36. package/coverage/lcov-report/main/app/canvas.ts.html +97 -46
  37. package/coverage/lcov-report/main/app/guards.ts.html +1 -1
  38. package/coverage/lcov-report/main/app/index.html +19 -19
  39. package/coverage/lcov-report/main/app/index.ts.html +62 -35
  40. package/coverage/lcov-report/main/app/logger.ts.html +1 -1
  41. package/coverage/lcov-report/main/app/messages.gen.ts.html +32 -5
  42. package/coverage/lcov-report/main/app/nodes.ts.html +17 -5
  43. package/coverage/lcov-report/main/app/observer/iframe_observer.ts.html +1 -1
  44. package/coverage/lcov-report/main/app/observer/iframe_offsets.ts.html +1 -1
  45. package/coverage/lcov-report/main/app/observer/index.html +1 -1
  46. package/coverage/lcov-report/main/app/observer/shadow_root_observer.ts.html +1 -1
  47. package/coverage/lcov-report/main/app/observer/top_observer.ts.html +1 -1
  48. package/coverage/lcov-report/main/app/sanitizer.ts.html +1 -1
  49. package/coverage/lcov-report/main/app/session.ts.html +1 -1
  50. package/coverage/lcov-report/main/app/ticker.ts.html +1 -1
  51. package/coverage/lcov-report/main/index.html +9 -9
  52. package/coverage/lcov-report/main/index.ts.html +27 -6
  53. package/coverage/lcov-report/main/modules/Network/beaconProxy.ts.html +1 -1
  54. package/coverage/lcov-report/main/modules/Network/fetchProxy.ts.html +1 -1
  55. package/coverage/lcov-report/main/modules/Network/index.html +1 -1
  56. package/coverage/lcov-report/main/modules/Network/index.ts.html +1 -1
  57. package/coverage/lcov-report/main/modules/Network/networkMessage.ts.html +1 -1
  58. package/coverage/lcov-report/main/modules/Network/utils.ts.html +1 -1
  59. package/coverage/lcov-report/main/modules/Network/xhrProxy.ts.html +1 -1
  60. package/coverage/lcov-report/main/modules/attributeSender.ts.html +1 -1
  61. package/coverage/lcov-report/main/modules/axiosSpy.ts.html +1 -1
  62. package/coverage/lcov-report/main/modules/conditionsManager.ts.html +92 -38
  63. package/coverage/lcov-report/main/modules/connection.ts.html +1 -1
  64. package/coverage/lcov-report/main/modules/console.ts.html +1 -1
  65. package/coverage/lcov-report/main/modules/constructedStyleSheets.ts.html +1 -1
  66. package/coverage/lcov-report/main/modules/cssrules.ts.html +1 -1
  67. package/coverage/lcov-report/main/modules/exception.ts.html +1 -1
  68. package/coverage/lcov-report/main/modules/featureFlags.ts.html +1 -1
  69. package/coverage/lcov-report/main/modules/focus.ts.html +1 -1
  70. package/coverage/lcov-report/main/modules/fonts.ts.html +1 -1
  71. package/coverage/lcov-report/main/modules/img.ts.html +1 -1
  72. package/coverage/lcov-report/main/modules/index.html +21 -21
  73. package/coverage/lcov-report/main/modules/input.ts.html +1 -1
  74. package/coverage/lcov-report/main/modules/mouse.ts.html +1 -1
  75. package/coverage/lcov-report/main/modules/network.ts.html +1 -1
  76. package/coverage/lcov-report/main/modules/performance.ts.html +1 -1
  77. package/coverage/lcov-report/main/modules/scroll.ts.html +1 -1
  78. package/coverage/lcov-report/main/modules/selection.ts.html +1 -1
  79. package/coverage/lcov-report/main/modules/tabs.ts.html +1 -1
  80. package/coverage/lcov-report/main/modules/tagWatcher.ts.html +54 -27
  81. package/coverage/lcov-report/main/modules/timing.ts.html +1 -1
  82. package/coverage/lcov-report/main/modules/userTesting/SignalManager.ts.html +1 -1
  83. package/coverage/lcov-report/main/modules/userTesting/dnd.ts.html +1 -1
  84. package/coverage/lcov-report/main/modules/userTesting/index.html +1 -1
  85. package/coverage/lcov-report/main/modules/userTesting/index.ts.html +1 -1
  86. package/coverage/lcov-report/main/modules/userTesting/recorder.ts.html +1 -1
  87. package/coverage/lcov-report/main/modules/userTesting/styles.ts.html +1 -1
  88. package/coverage/lcov-report/main/modules/userTesting/utils.ts.html +1 -1
  89. package/coverage/lcov-report/main/modules/viewport.ts.html +1 -1
  90. package/coverage/lcov-report/main/utils.ts.html +1 -1
  91. package/coverage/lcov-report/webworker/BatchWriter.ts.html +1 -1
  92. package/coverage/lcov-report/webworker/MessageEncoder.gen.ts.html +17 -5
  93. package/coverage/lcov-report/webworker/PrimitiveEncoder.ts.html +1 -1
  94. package/coverage/lcov-report/webworker/QueueSender.ts.html +1 -1
  95. package/coverage/lcov-report/webworker/index.html +7 -7
  96. package/coverage/lcov-report/webworker/index.ts.html +1 -1
  97. package/coverage/lcov.info +1100 -1033
  98. package/lib/app/index.d.ts +88 -9
  99. package/lib/app/index.js +452 -111
  100. package/lib/app/logger.d.ts +7 -17
  101. package/lib/app/logger.js +11 -19
  102. package/lib/app/messages.gen.d.ts +2 -0
  103. package/lib/app/messages.gen.js +17 -0
  104. package/lib/app/workerManager/QueueSender.d.ts +23 -0
  105. package/lib/app/workerManager/QueueSender.js +123 -0
  106. package/lib/app/workerManager/index.d.ts +37 -0
  107. package/lib/app/workerManager/index.js +162 -0
  108. package/lib/common/interaction.d.ts +56 -18
  109. package/lib/common/messages.gen.d.ts +17 -2
  110. package/lib/common/tsconfig.tsbuildinfo +1 -1
  111. package/lib/index.d.ts +45 -2
  112. package/lib/index.js +191 -86
  113. package/lib/modules/conditionsManager.d.ts +84 -0
  114. package/lib/modules/conditionsManager.js +340 -0
  115. package/lib/modules/featureFlags.d.ts +1 -1
  116. package/lib/modules/featureFlags.js +36 -46
  117. package/lib/modules/tagWatcher.d.ts +21 -0
  118. package/lib/modules/tagWatcher.js +74 -0
  119. package/lib/modules/userTesting/recorder.js +71 -88
  120. package/package.json +1 -1
  121. package/tsconfig-base.json +3 -2
@@ -5,22 +5,12 @@ export declare const LogLevel: {
5
5
  readonly Errors: 2;
6
6
  readonly Silent: 0;
7
7
  };
8
- type LogLevel = (typeof LogLevel)[keyof typeof LogLevel];
9
- type CustomLevel = {
10
- error: boolean;
11
- warn: boolean;
12
- log: boolean;
13
- };
14
- interface _Options {
15
- level: LogLevel | CustomLevel;
16
- messages?: number[];
17
- }
18
- export type Options = true | _Options | LogLevel;
8
+ export type ILogLevel = (typeof LogLevel)[keyof typeof LogLevel];
19
9
  export default class Logger {
20
- private readonly options;
21
- constructor(options?: Options);
22
- log(...args: any): void;
23
- warn(...args: any): void;
24
- error(...args: any): void;
10
+ private readonly level;
11
+ constructor(debugLevel?: ILogLevel);
12
+ private shouldLog;
13
+ log(...args: any[]): void;
14
+ warn(...args: any[]): void;
15
+ error(...args: any[]): void;
25
16
  }
26
- export {};
package/lib/app/logger.js CHANGED
@@ -5,36 +5,28 @@ export const LogLevel = {
5
5
  Errors: 2,
6
6
  Silent: 0,
7
7
  };
8
- function IsCustomLevel(l) {
9
- return typeof l === 'object';
10
- }
11
8
  export default class Logger {
12
- constructor(options = LogLevel.Silent) {
13
- this.options =
14
- options === true
15
- ? { level: LogLevel.Verbose }
16
- : typeof options === 'number'
17
- ? { level: options }
18
- : options;
9
+ constructor(debugLevel = LogLevel.Silent) {
10
+ this.level = debugLevel;
11
+ }
12
+ shouldLog(level) {
13
+ return this.level >= level;
19
14
  }
20
15
  log(...args) {
21
- if (IsCustomLevel(this.options.level)
22
- ? this.options.level.log
23
- : this.options.level >= LogLevel.Log) {
16
+ if (this.shouldLog(LogLevel.Log)) {
17
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
24
18
  console.log(...args);
25
19
  }
26
20
  }
27
21
  warn(...args) {
28
- if (IsCustomLevel(this.options.level)
29
- ? this.options.level.warn
30
- : this.options.level >= LogLevel.Warnings) {
22
+ if (this.shouldLog(LogLevel.Warnings)) {
23
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
31
24
  console.warn(...args);
32
25
  }
33
26
  }
34
27
  error(...args) {
35
- if (IsCustomLevel(this.options.level)
36
- ? this.options.level.error
37
- : this.options.level >= LogLevel.Errors) {
28
+ if (this.shouldLog(LogLevel.Errors)) {
29
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
38
30
  console.error(...args);
39
31
  }
40
32
  }
@@ -62,6 +62,7 @@ export declare function Zustand(mutation: string, state: string): Messages.Zusta
62
62
  export declare function BatchMetadata(version: number, pageNo: number, firstIndex: number, timestamp: number, location: string): Messages.BatchMetadata;
63
63
  export declare function PartitionedMessage(partNo: number, partTotal: number): Messages.PartitionedMessage;
64
64
  export declare function NetworkRequest(type: string, method: string, url: string, request: string, response: string, status: number, timestamp: number, duration: number, transferredBodySize: number): Messages.NetworkRequest;
65
+ export declare function WSChannel(chType: string, channelName: string, data: string, timestamp: number, dir: string, messageType: string): Messages.WSChannel;
65
66
  export declare function InputChange(id: number, value: string, valueMasked: boolean, label: string, hesitationTime: number, inputDuration: number): Messages.InputChange;
66
67
  export declare function SelectionChange(selectionStart: number, selectionEnd: number, selection: string): Messages.SelectionChange;
67
68
  export declare function MouseThrashing(timestamp: number): Messages.MouseThrashing;
@@ -70,3 +71,4 @@ export declare function ResourceTiming(timestamp: number, duration: number, ttfb
70
71
  export declare function TabChange(tabId: string): Messages.TabChange;
71
72
  export declare function TabData(tabId: string): Messages.TabData;
72
73
  export declare function CanvasNode(nodeId: string, timestamp: number): Messages.CanvasNode;
74
+ export declare function TagTrigger(tagId: number): Messages.TagTrigger;
@@ -498,6 +498,17 @@ export function NetworkRequest(type, method, url, request, response, status, tim
498
498
  transferredBodySize,
499
499
  ];
500
500
  }
501
+ export function WSChannel(chType, channelName, data, timestamp, dir, messageType) {
502
+ return [
503
+ 84 /* Messages.Type.WSChannel */,
504
+ chType,
505
+ channelName,
506
+ data,
507
+ timestamp,
508
+ dir,
509
+ messageType,
510
+ ];
511
+ }
501
512
  export function InputChange(id, value, valueMasked, label, hesitationTime, inputDuration) {
502
513
  return [
503
514
  112 /* Messages.Type.InputChange */,
@@ -563,3 +574,9 @@ export function CanvasNode(nodeId, timestamp) {
563
574
  timestamp,
564
575
  ];
565
576
  }
577
+ export function TagTrigger(tagId) {
578
+ return [
579
+ 120 /* Messages.Type.TagTrigger */,
580
+ tagId,
581
+ ];
582
+ }
@@ -0,0 +1,23 @@
1
+ export default class QueueSender {
2
+ private readonly onUnauthorised;
3
+ private readonly onFailure;
4
+ private readonly MAX_ATTEMPTS_COUNT;
5
+ private readonly ATTEMPT_TIMEOUT;
6
+ private readonly onCompress?;
7
+ private attemptsCount;
8
+ private busy;
9
+ private readonly queue;
10
+ private readonly ingestURL;
11
+ private token;
12
+ private readonly isCompressing;
13
+ constructor(ingestBaseURL: string, onUnauthorised: () => any, onFailure: (reason: string) => any, MAX_ATTEMPTS_COUNT?: number, ATTEMPT_TIMEOUT?: number, onCompress?: ((batch: Uint8Array) => any) | undefined);
14
+ getQueueStatus(): boolean;
15
+ authorise(token: string): void;
16
+ push(batch: Uint8Array): void;
17
+ private sendNext;
18
+ private retry;
19
+ private sendBatch;
20
+ sendCompressed(batch: Uint8Array): void;
21
+ sendUncompressed(batch: Uint8Array): void;
22
+ clean(): void;
23
+ }
@@ -0,0 +1,123 @@
1
+ const INGEST_PATH = '/v1/web/i';
2
+ const KEEPALIVE_SIZE_LIMIT = 64 << 10; // 64 kB
3
+ export default class QueueSender {
4
+ constructor(ingestBaseURL, onUnauthorised, onFailure, MAX_ATTEMPTS_COUNT = 10, ATTEMPT_TIMEOUT = 1000, onCompress) {
5
+ this.onUnauthorised = onUnauthorised;
6
+ this.onFailure = onFailure;
7
+ this.MAX_ATTEMPTS_COUNT = MAX_ATTEMPTS_COUNT;
8
+ this.ATTEMPT_TIMEOUT = ATTEMPT_TIMEOUT;
9
+ this.onCompress = onCompress;
10
+ this.attemptsCount = 0;
11
+ this.busy = false;
12
+ this.queue = [];
13
+ this.token = null;
14
+ this.ingestURL = ingestBaseURL + INGEST_PATH;
15
+ this.isCompressing = onCompress !== undefined;
16
+ }
17
+ getQueueStatus() {
18
+ return this.queue.length === 0 && !this.busy;
19
+ }
20
+ authorise(token) {
21
+ this.token = token;
22
+ if (!this.busy) {
23
+ // TODO: transparent busy/send logic
24
+ this.sendNext();
25
+ }
26
+ }
27
+ push(batch) {
28
+ if (this.busy || !this.token) {
29
+ this.queue.push(batch);
30
+ }
31
+ else {
32
+ this.busy = true;
33
+ if (this.isCompressing && this.onCompress) {
34
+ this.onCompress(batch);
35
+ }
36
+ else {
37
+ this.sendBatch(batch);
38
+ }
39
+ }
40
+ }
41
+ sendNext() {
42
+ const nextBatch = this.queue.shift();
43
+ if (nextBatch) {
44
+ this.busy = true;
45
+ if (this.isCompressing && this.onCompress) {
46
+ this.onCompress(nextBatch);
47
+ }
48
+ else {
49
+ this.sendBatch(nextBatch);
50
+ }
51
+ }
52
+ else {
53
+ this.busy = false;
54
+ }
55
+ }
56
+ retry(batch, isCompressed) {
57
+ if (this.attemptsCount >= this.MAX_ATTEMPTS_COUNT) {
58
+ this.onFailure(`Failed to send batch after ${this.attemptsCount} attempts.`);
59
+ // remains this.busy === true
60
+ return;
61
+ }
62
+ this.attemptsCount++;
63
+ setTimeout(() => this.sendBatch(batch, isCompressed), this.ATTEMPT_TIMEOUT * this.attemptsCount);
64
+ }
65
+ // would be nice to use Beacon API, but it is not available in WebWorker
66
+ sendBatch(batch, isCompressed) {
67
+ this.busy = true;
68
+ const headers = {
69
+ Authorization: `Bearer ${this.token}`,
70
+ };
71
+ if (isCompressed) {
72
+ headers['Content-Encoding'] = 'gzip';
73
+ }
74
+ /**
75
+ * sometimes happen during assist connects for some reason
76
+ * */
77
+ if (this.token === null) {
78
+ setTimeout(() => {
79
+ this.sendBatch(batch, isCompressed);
80
+ }, 500);
81
+ return;
82
+ }
83
+ fetch(this.ingestURL, {
84
+ body: batch,
85
+ method: 'POST',
86
+ headers,
87
+ keepalive: batch.length < KEEPALIVE_SIZE_LIMIT,
88
+ })
89
+ .then((r) => {
90
+ if (r.status === 401) {
91
+ // TODO: continuous session ?
92
+ this.busy = false;
93
+ this.onUnauthorised();
94
+ return;
95
+ }
96
+ else if (r.status >= 400) {
97
+ this.retry(batch, isCompressed);
98
+ return;
99
+ }
100
+ // Success
101
+ this.attemptsCount = 0;
102
+ this.sendNext();
103
+ })
104
+ .catch((e) => {
105
+ console.warn('OpenReplay:', e);
106
+ this.retry(batch, isCompressed);
107
+ });
108
+ }
109
+ sendCompressed(batch) {
110
+ this.sendBatch(batch, true);
111
+ }
112
+ sendUncompressed(batch) {
113
+ this.sendBatch(batch, false);
114
+ }
115
+ clean() {
116
+ // sending last batch and closing the shop
117
+ this.sendNext();
118
+ setTimeout(() => {
119
+ this.token = null;
120
+ this.queue.length = 0;
121
+ }, 10);
122
+ }
123
+ }
@@ -0,0 +1,37 @@
1
+ import { FromWorkerData, ToWorkerData, WorkerAuth, WorkerStart } from '../../common/interaction.js';
2
+ import App from '../index.js';
3
+ import QueueSender from './QueueSender.js';
4
+ declare enum WorkerStatus {
5
+ NotActive = 0,
6
+ Starting = 1,
7
+ Stopping = 2,
8
+ Active = 3,
9
+ Stopped = 4
10
+ }
11
+ interface TypedWorker extends Omit<Worker, 'postMessage'> {
12
+ postMessage(data: ToWorkerData): void;
13
+ }
14
+ declare class WebWorkerManager {
15
+ private readonly app;
16
+ private readonly worker;
17
+ private readonly onError;
18
+ sendIntervalID: ReturnType<typeof setInterval> | null;
19
+ restartTimeoutID: ReturnType<typeof setTimeout> | null;
20
+ workerStatus: WorkerStatus;
21
+ sender: QueueSender | null;
22
+ constructor(app: App, worker: TypedWorker, onError: (ctx: string, e: any) => any);
23
+ finalize: () => void;
24
+ resetWebWorker: () => void;
25
+ resetSender: () => void;
26
+ reset: () => void;
27
+ initiateRestart: () => void;
28
+ initiateFailure: (reason: string) => void;
29
+ processMessage: (data: ToWorkerData | null) => void;
30
+ startWorker: (data: WorkerStart) => void;
31
+ stopWorker: () => void;
32
+ authorizeWorker: (data: WorkerAuth) => void;
33
+ sendCompressedBatch: (data: Uint8Array) => void;
34
+ sendUncompressedBatch: (data: Uint8Array) => void;
35
+ postMessage: (data: FromWorkerData) => void;
36
+ }
37
+ export default WebWorkerManager;
@@ -0,0 +1,162 @@
1
+ import QueueSender from './QueueSender.js';
2
+ var WorkerStatus;
3
+ (function (WorkerStatus) {
4
+ WorkerStatus[WorkerStatus["NotActive"] = 0] = "NotActive";
5
+ WorkerStatus[WorkerStatus["Starting"] = 1] = "Starting";
6
+ WorkerStatus[WorkerStatus["Stopping"] = 2] = "Stopping";
7
+ WorkerStatus[WorkerStatus["Active"] = 3] = "Active";
8
+ WorkerStatus[WorkerStatus["Stopped"] = 4] = "Stopped";
9
+ })(WorkerStatus || (WorkerStatus = {}));
10
+ const AUTO_SEND_INTERVAL = 10 * 1000;
11
+ const rebroadcastEvents = ['queue_empty', 'not_init', 'restart'];
12
+ class WebWorkerManager {
13
+ constructor(app, worker, onError) {
14
+ this.app = app;
15
+ this.worker = worker;
16
+ this.onError = onError;
17
+ this.sendIntervalID = null;
18
+ this.restartTimeoutID = null;
19
+ this.workerStatus = WorkerStatus.NotActive;
20
+ this.sender = null;
21
+ this.finalize = () => {
22
+ this.worker.postMessage({ type: 'writer_finalize' });
23
+ };
24
+ this.resetWebWorker = () => {
25
+ this.worker.postMessage({ type: 'reset_writer' });
26
+ };
27
+ this.resetSender = () => {
28
+ if (!this.sender) {
29
+ return;
30
+ }
31
+ this.sender.clean();
32
+ setTimeout(() => {
33
+ this.sender = null;
34
+ }, 20);
35
+ };
36
+ this.reset = () => {
37
+ this.workerStatus = WorkerStatus.Stopping;
38
+ if (this.sendIntervalID !== null) {
39
+ clearInterval(this.sendIntervalID);
40
+ this.sendIntervalID = null;
41
+ }
42
+ this.resetSender();
43
+ this.resetWebWorker();
44
+ setTimeout(() => {
45
+ this.workerStatus = WorkerStatus.NotActive;
46
+ }, 100);
47
+ };
48
+ this.initiateRestart = () => {
49
+ if (this.workerStatus === WorkerStatus.Stopped) {
50
+ return;
51
+ }
52
+ this.postMessage({ type: 'restart' });
53
+ this.reset();
54
+ };
55
+ this.initiateFailure = (reason) => {
56
+ if ([WorkerStatus.Stopped, WorkerStatus.Stopping, WorkerStatus.NotActive].includes(this.workerStatus)) {
57
+ return;
58
+ }
59
+ this.postMessage({ type: 'failure', reason });
60
+ this.reset();
61
+ };
62
+ this.processMessage = (data) => {
63
+ if (data === null) {
64
+ this.finalize();
65
+ return;
66
+ }
67
+ if (data.type === 'batch' && Array.isArray(data.data)) {
68
+ data.data.forEach((message) => {
69
+ if (message[0] === 55 /* MType.SetPageVisibility */) {
70
+ // document is hidden
71
+ if (message[1]) {
72
+ this.restartTimeoutID = setTimeout(() => this.initiateRestart(), 30 * 60 * 1000);
73
+ }
74
+ else {
75
+ if (this.restartTimeoutID) {
76
+ clearTimeout(this.restartTimeoutID);
77
+ }
78
+ }
79
+ }
80
+ });
81
+ this.worker.postMessage({ type: 'to_writer', data: data.data });
82
+ }
83
+ };
84
+ this.startWorker = (data) => {
85
+ this.sender = new QueueSender(data.ingestPoint, () => {
86
+ // onUnauthorised
87
+ this.initiateRestart();
88
+ }, (reason) => {
89
+ // onFailure
90
+ this.initiateFailure(reason);
91
+ }, data.connAttemptCount, data.connAttemptGap, (batch) => {
92
+ this.postMessage({ type: 'compress', batch });
93
+ });
94
+ if (this.sendIntervalID === null) {
95
+ this.sendIntervalID = setInterval(this.finalize, AUTO_SEND_INTERVAL);
96
+ }
97
+ this.worker.postMessage(data);
98
+ return;
99
+ };
100
+ this.stopWorker = () => {
101
+ this.finalize();
102
+ this.reset();
103
+ return;
104
+ };
105
+ this.authorizeWorker = (data) => {
106
+ if (!this.sender) {
107
+ console.debug('OR WebWorker: sender not initialised. Received auth.');
108
+ this.initiateRestart();
109
+ return;
110
+ }
111
+ this.sender.authorise(data.token);
112
+ if (data.beaconSizeLimit) {
113
+ this.worker.postMessage({ type: 'beacon_size_limit', data: data.beaconSizeLimit });
114
+ }
115
+ return;
116
+ };
117
+ this.sendCompressedBatch = (data) => {
118
+ var _a;
119
+ if (!this.sender) {
120
+ console.debug('OR Worker: sender not init. Compressed batch');
121
+ this.initiateRestart();
122
+ return;
123
+ }
124
+ (_a = this.sender) === null || _a === void 0 ? void 0 : _a.sendCompressed(data);
125
+ return;
126
+ };
127
+ this.sendUncompressedBatch = (data) => {
128
+ if (!this.sender) {
129
+ console.debug('OR Worker: sender not init. Compressed batch.');
130
+ this.initiateRestart();
131
+ return;
132
+ }
133
+ if (data) {
134
+ this.sender.sendUncompressed(data);
135
+ return;
136
+ }
137
+ };
138
+ this.postMessage = (data) => {
139
+ this.app.handleWorkerMsg(data);
140
+ };
141
+ this.worker.onerror = (e) => {
142
+ this.onError('webworker_error', e);
143
+ };
144
+ this.worker.onmessage = ({ data }) => {
145
+ if (rebroadcastEvents.includes(data.type)) {
146
+ this.postMessage(data);
147
+ return;
148
+ }
149
+ switch (data.type) {
150
+ case 'status':
151
+ this.workerStatus = data.data;
152
+ return;
153
+ case 'batch_ready':
154
+ if (this.sender) {
155
+ this.app.debug.log('Openreplay: msg batch to sender: ', data.data);
156
+ this.sender.push(data.data);
157
+ }
158
+ }
159
+ };
160
+ }
161
+ }
162
+ export default WebWorkerManager;
@@ -3,7 +3,61 @@ export interface Options {
3
3
  connAttemptCount?: number;
4
4
  connAttemptGap?: number;
5
5
  }
6
- type Start = {
6
+ export type ToWorkerData = null | Stop | Batch | WorkerStart | BeaconSizeLimit | ToWriterData | ForceFlushBatch | CheckQueue | ResetWriter | WriterFinalize;
7
+ export type FromWorkerData = Restart | Failure | NotInit | Compress | QEmpty | Status | BatchReady;
8
+ type BatchReady = {
9
+ type: 'batch_ready';
10
+ data: Uint8Array;
11
+ };
12
+ type Status = {
13
+ type: 'status';
14
+ data: number;
15
+ };
16
+ type Compress = {
17
+ type: 'compress';
18
+ batch: Uint8Array;
19
+ };
20
+ type Restart = {
21
+ type: 'restart';
22
+ };
23
+ type NotInit = {
24
+ type: 'not_init';
25
+ };
26
+ type Stop = {
27
+ type: 'stop';
28
+ };
29
+ type Batch = {
30
+ type: 'batch';
31
+ data: Array<Message>;
32
+ };
33
+ type ForceFlushBatch = {
34
+ type: 'forceFlushBatch';
35
+ };
36
+ type CheckQueue = {
37
+ type: 'check_queue';
38
+ };
39
+ type WriterFinalize = {
40
+ type: 'writer_finalize';
41
+ };
42
+ type ResetWriter = {
43
+ type: 'reset_writer';
44
+ };
45
+ type BeaconSizeLimit = {
46
+ type: 'beacon_size_limit';
47
+ data: number;
48
+ };
49
+ type ToWriterData = {
50
+ type: 'to_writer';
51
+ data: Array<Message>;
52
+ };
53
+ type Failure = {
54
+ type: 'failure';
55
+ reason: string;
56
+ };
57
+ type QEmpty = {
58
+ type: 'queue_empty';
59
+ };
60
+ export type WorkerStart = {
7
61
  type: 'start';
8
62
  ingestPoint: string;
9
63
  pageNo: number;
@@ -11,24 +65,8 @@ type Start = {
11
65
  url: string;
12
66
  tabId: string;
13
67
  } & Options;
14
- type Auth = {
15
- type: 'auth';
68
+ export type WorkerAuth = {
16
69
  token: string;
17
70
  beaconSizeLimit?: number;
18
71
  };
19
- export type ToWorkerData = null | 'stop' | Start | Auth | Array<Message> | {
20
- type: 'compressed';
21
- batch: Uint8Array;
22
- } | {
23
- type: 'uncompressed';
24
- batch: Uint8Array;
25
- } | 'forceFlushBatch';
26
- type Failure = {
27
- type: 'failure';
28
- reason: string;
29
- };
30
- export type FromWorkerData = 'restart' | Failure | 'not_init' | {
31
- type: 'compress';
32
- batch: Uint8Array;
33
- };
34
72
  export {};
@@ -61,6 +61,7 @@ export declare const enum Type {
61
61
  BatchMetadata = 81,
62
62
  PartitionedMessage = 82,
63
63
  NetworkRequest = 83,
64
+ WSChannel = 84,
64
65
  InputChange = 112,
65
66
  SelectionChange = 113,
66
67
  MouseThrashing = 114,
@@ -68,7 +69,8 @@ export declare const enum Type {
68
69
  ResourceTiming = 116,
69
70
  TabChange = 117,
70
71
  TabData = 118,
71
- CanvasNode = 119
72
+ CanvasNode = 119,
73
+ TagTrigger = 120
72
74
  }
73
75
  export type Timestamp = [
74
76
  Type.Timestamp,
@@ -444,6 +446,15 @@ export type NetworkRequest = [
444
446
  number,
445
447
  number
446
448
  ];
449
+ export type WSChannel = [
450
+ Type.WSChannel,
451
+ string,
452
+ string,
453
+ string,
454
+ number,
455
+ string,
456
+ string
457
+ ];
447
458
  export type InputChange = [
448
459
  Type.InputChange,
449
460
  number,
@@ -493,5 +504,9 @@ export type CanvasNode = [
493
504
  string,
494
505
  number
495
506
  ];
496
- type Message = Timestamp | SetPageLocation | SetViewportSize | SetViewportScroll | CreateDocument | CreateElementNode | CreateTextNode | MoveNode | RemoveNode | SetNodeAttribute | RemoveNodeAttribute | SetNodeData | SetNodeScroll | SetInputTarget | SetInputValue | SetInputChecked | MouseMove | NetworkRequestDeprecated | ConsoleLog | PageLoadTiming | PageRenderTiming | CustomEvent | UserID | UserAnonymousID | Metadata | CSSInsertRule | CSSDeleteRule | Fetch | Profiler | OTable | StateAction | Redux | Vuex | MobX | NgRx | GraphQL | PerformanceTrack | StringDict | SetNodeAttributeDict | ResourceTimingDeprecated | ConnectionInformation | SetPageVisibility | LoadFontFace | SetNodeFocus | LongTask | SetNodeAttributeURLBased | SetCSSDataURLBased | TechnicalInfo | CustomIssue | CSSInsertRuleURLBased | MouseClick | CreateIFrameDocument | AdoptedSSReplaceURLBased | AdoptedSSInsertRuleURLBased | AdoptedSSDeleteRule | AdoptedSSAddOwner | AdoptedSSRemoveOwner | JSException | Zustand | BatchMetadata | PartitionedMessage | NetworkRequest | InputChange | SelectionChange | MouseThrashing | UnbindNodes | ResourceTiming | TabChange | TabData | CanvasNode;
507
+ export type TagTrigger = [
508
+ Type.TagTrigger,
509
+ number
510
+ ];
511
+ type Message = Timestamp | SetPageLocation | SetViewportSize | SetViewportScroll | CreateDocument | CreateElementNode | CreateTextNode | MoveNode | RemoveNode | SetNodeAttribute | RemoveNodeAttribute | SetNodeData | SetNodeScroll | SetInputTarget | SetInputValue | SetInputChecked | MouseMove | NetworkRequestDeprecated | ConsoleLog | PageLoadTiming | PageRenderTiming | CustomEvent | UserID | UserAnonymousID | Metadata | CSSInsertRule | CSSDeleteRule | Fetch | Profiler | OTable | StateAction | Redux | Vuex | MobX | NgRx | GraphQL | PerformanceTrack | StringDict | SetNodeAttributeDict | ResourceTimingDeprecated | ConnectionInformation | SetPageVisibility | LoadFontFace | SetNodeFocus | LongTask | SetNodeAttributeURLBased | SetCSSDataURLBased | TechnicalInfo | CustomIssue | CSSInsertRuleURLBased | MouseClick | CreateIFrameDocument | AdoptedSSReplaceURLBased | AdoptedSSInsertRuleURLBased | AdoptedSSDeleteRule | AdoptedSSAddOwner | AdoptedSSRemoveOwner | JSException | Zustand | BatchMetadata | PartitionedMessage | NetworkRequest | WSChannel | InputChange | SelectionChange | MouseThrashing | UnbindNodes | ResourceTiming | TabChange | TabData | CanvasNode | TagTrigger;
497
512
  export default Message;