@openreplay/tracker 15.0.0 → 15.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index.js +9058 -68
- package/dist/cjs/index.js.map +1 -1
- package/dist/lib/index.js +4 -4
- package/dist/lib/index.js.map +1 -1
- package/dist/types/common/interaction.d.ts +37 -0
- package/dist/types/common/messages.gen.d.ts +567 -0
- package/dist/types/main/app/canvas.d.ts +28 -0
- package/dist/types/main/app/guards.d.ts +22 -0
- package/dist/types/main/app/index.d.ts +322 -0
- package/dist/types/main/app/logger.d.ts +17 -0
- package/dist/types/main/app/messages.gen.d.ts +81 -0
- package/dist/types/main/app/nodes/index.d.ts +31 -0
- package/dist/types/main/app/nodes/maintainer.d.ts +28 -0
- package/dist/types/main/app/observer/iframe_observer.d.ts +6 -0
- package/dist/types/main/app/observer/iframe_offsets.d.ts +8 -0
- package/dist/types/main/app/observer/observer.d.ts +29 -0
- package/dist/types/main/app/observer/shadow_root_observer.d.ts +4 -0
- package/dist/types/main/app/observer/top_observer.d.ts +31 -0
- package/dist/types/main/app/sanitizer.d.ts +48 -0
- package/dist/types/main/app/session.d.ts +57 -0
- package/dist/types/main/app/ticker.d.ts +18 -0
- package/dist/types/main/index.d.ts +111 -0
- package/dist/types/main/modules/attributeSender.d.ts +23 -0
- package/dist/types/main/modules/axiosSpy.d.ts +54 -0
- package/dist/types/main/modules/conditionsManager.d.ts +84 -0
- package/dist/types/main/modules/connection.d.ts +2 -0
- package/dist/types/main/modules/console.d.ts +6 -0
- package/dist/types/main/modules/constructedStyleSheets.d.ts +4 -0
- package/dist/types/main/modules/cssrules.d.ts +2 -0
- package/dist/types/main/modules/exception.d.ts +16 -0
- package/dist/types/main/modules/featureFlags.d.ts +25 -0
- package/dist/types/main/modules/focus.d.ts +2 -0
- package/dist/types/main/modules/fonts.d.ts +2 -0
- package/dist/types/main/modules/img.d.ts +2 -0
- package/dist/types/main/modules/input.d.ts +34 -0
- package/dist/types/main/modules/mouse.d.ts +31 -0
- package/dist/types/main/modules/network.d.ts +31 -0
- package/dist/types/main/modules/performance.d.ts +7 -0
- package/dist/types/main/modules/scroll.d.ts +2 -0
- package/dist/types/main/modules/selection.d.ts +7 -0
- package/dist/types/main/modules/tabs.d.ts +2 -0
- package/dist/types/main/modules/tagWatcher.d.ts +25 -0
- package/dist/types/main/modules/timing.d.ts +8 -0
- package/dist/types/main/modules/userTesting/SignalManager.d.ts +29 -0
- package/dist/types/main/modules/userTesting/dnd.d.ts +1 -0
- package/dist/types/main/modules/userTesting/index.d.ts +45 -0
- package/dist/types/main/modules/userTesting/recorder.d.ts +24 -0
- package/dist/types/main/modules/userTesting/styles.d.ts +277 -0
- package/dist/types/main/modules/userTesting/utils.d.ts +9 -0
- package/dist/types/main/modules/viewport.d.ts +2 -0
- package/dist/types/main/utils.d.ts +30 -0
- package/package.json +9 -5
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
import type { Options as WebworkerOptions } from '../../common/interaction.js';
|
|
2
|
+
import AttributeSender from '../modules/attributeSender.js';
|
|
3
|
+
import FeatureFlags from '../modules/featureFlags.js';
|
|
4
|
+
import type { Options as NetworkOptions } from '../modules/network.js';
|
|
5
|
+
import Logger, { ILogLevel } from './logger.js';
|
|
6
|
+
import Message from './messages.gen.js';
|
|
7
|
+
import Nodes from './nodes/index.js';
|
|
8
|
+
import type { Options as ObserverOptions } from './observer/top_observer.js';
|
|
9
|
+
import Observer from './observer/top_observer.js';
|
|
10
|
+
import type { Options as SanitizerOptions } from './sanitizer.js';
|
|
11
|
+
import Sanitizer from './sanitizer.js';
|
|
12
|
+
import type { Options as SessOptions } from './session.js';
|
|
13
|
+
import Session from './session.js';
|
|
14
|
+
import Ticker from './ticker.js';
|
|
15
|
+
import { MaintainerOptions } from './nodes/maintainer.js';
|
|
16
|
+
export interface StartOptions {
|
|
17
|
+
userID?: string;
|
|
18
|
+
metadata?: Record<string, string>;
|
|
19
|
+
forceNew?: boolean;
|
|
20
|
+
sessionHash?: string;
|
|
21
|
+
assistOnly?: boolean;
|
|
22
|
+
/**
|
|
23
|
+
* @deprecated We strongly advise to use .start().then instead.
|
|
24
|
+
*
|
|
25
|
+
* This method is kept for snippet compatibility only
|
|
26
|
+
* */
|
|
27
|
+
startCallback?: (result: StartPromiseReturn) => void;
|
|
28
|
+
}
|
|
29
|
+
interface OnStartInfo {
|
|
30
|
+
sessionID: string;
|
|
31
|
+
sessionToken: string;
|
|
32
|
+
userUUID: string;
|
|
33
|
+
}
|
|
34
|
+
declare const CANCELED: "canceled";
|
|
35
|
+
type SuccessfulStart = OnStartInfo & {
|
|
36
|
+
success: true;
|
|
37
|
+
};
|
|
38
|
+
type UnsuccessfulStart = {
|
|
39
|
+
reason: typeof CANCELED | string;
|
|
40
|
+
success: false;
|
|
41
|
+
};
|
|
42
|
+
declare const UnsuccessfulStart: (reason: string) => UnsuccessfulStart;
|
|
43
|
+
declare const SuccessfulStart: (body: OnStartInfo) => SuccessfulStart;
|
|
44
|
+
export type StartPromiseReturn = SuccessfulStart | UnsuccessfulStart;
|
|
45
|
+
type StartCallback = (i: OnStartInfo) => void;
|
|
46
|
+
type CommitCallback = (messages: Array<Message>) => void;
|
|
47
|
+
declare enum ActivityState {
|
|
48
|
+
NotActive = 0,
|
|
49
|
+
Starting = 1,
|
|
50
|
+
Active = 2,
|
|
51
|
+
ColdStart = 3
|
|
52
|
+
}
|
|
53
|
+
type AppOptions = {
|
|
54
|
+
revID: string;
|
|
55
|
+
node_id: string;
|
|
56
|
+
session_reset_key: string;
|
|
57
|
+
session_token_key: string;
|
|
58
|
+
session_pageno_key: string;
|
|
59
|
+
session_tabid_key: string;
|
|
60
|
+
local_uuid_key: string;
|
|
61
|
+
ingestPoint: string;
|
|
62
|
+
resourceBaseHref: string | null;
|
|
63
|
+
__is_snippet: boolean;
|
|
64
|
+
__debug_report_edp: string | null;
|
|
65
|
+
__debug__?: ILogLevel;
|
|
66
|
+
/** @deprecated see canvas prop */
|
|
67
|
+
__save_canvas_locally?: boolean;
|
|
68
|
+
/** @deprecated see canvas prop */
|
|
69
|
+
fixedCanvasScaling?: boolean;
|
|
70
|
+
localStorage: Storage | null;
|
|
71
|
+
sessionStorage: Storage | null;
|
|
72
|
+
forceSingleTab?: boolean;
|
|
73
|
+
/** Sometimes helps to prevent session breaking due to dict reset */
|
|
74
|
+
disableStringDict?: boolean;
|
|
75
|
+
assistSocketHost?: string;
|
|
76
|
+
/** @deprecated see canvas prop */
|
|
77
|
+
disableCanvas?: boolean;
|
|
78
|
+
canvas: {
|
|
79
|
+
disableCanvas?: boolean;
|
|
80
|
+
/**
|
|
81
|
+
* If you expect HI-DPI users mostly, this will render canvas
|
|
82
|
+
* in 1:1 pixel ratio
|
|
83
|
+
* */
|
|
84
|
+
fixedCanvasScaling?: boolean;
|
|
85
|
+
__save_canvas_locally?: boolean;
|
|
86
|
+
/**
|
|
87
|
+
* Use with care since it hijacks one frame each time it captures
|
|
88
|
+
* snapshot for every canvas
|
|
89
|
+
* */
|
|
90
|
+
useAnimationFrame?: boolean;
|
|
91
|
+
/**
|
|
92
|
+
* Use webp unless it produces too big images
|
|
93
|
+
* @default webp
|
|
94
|
+
* */
|
|
95
|
+
fileExt?: 'webp' | 'png' | 'jpeg' | 'avif';
|
|
96
|
+
};
|
|
97
|
+
crossdomain?: {
|
|
98
|
+
/**
|
|
99
|
+
* @default false
|
|
100
|
+
* */
|
|
101
|
+
enabled?: boolean;
|
|
102
|
+
/**
|
|
103
|
+
* used to send message up, will be '*' by default
|
|
104
|
+
* (check your CSP settings)
|
|
105
|
+
* @default '*'
|
|
106
|
+
* */
|
|
107
|
+
parentDomain?: string;
|
|
108
|
+
};
|
|
109
|
+
network?: NetworkOptions;
|
|
110
|
+
/**
|
|
111
|
+
* use this flag to force angular detection to be offline
|
|
112
|
+
*
|
|
113
|
+
* basically goes around window.Zone api changes to mutation observer
|
|
114
|
+
* and event listeners
|
|
115
|
+
* */
|
|
116
|
+
forceNgOff?: boolean;
|
|
117
|
+
/**
|
|
118
|
+
* This option is used to change how tracker handles potentially detached nodes
|
|
119
|
+
*
|
|
120
|
+
* defaults here are tested and proven to be lightweight and easy on cpu
|
|
121
|
+
*
|
|
122
|
+
* consult the docs before changing it
|
|
123
|
+
* */
|
|
124
|
+
nodes?: {
|
|
125
|
+
maintainer: Partial<MaintainerOptions>;
|
|
126
|
+
};
|
|
127
|
+
} & WebworkerOptions & SessOptions;
|
|
128
|
+
export type Options = AppOptions & ObserverOptions & SanitizerOptions;
|
|
129
|
+
export declare const DEFAULT_INGEST_POINT = "https://api.openreplay.com/ingest";
|
|
130
|
+
export default class App {
|
|
131
|
+
private readonly signalError;
|
|
132
|
+
readonly insideIframe: boolean;
|
|
133
|
+
readonly nodes: Nodes;
|
|
134
|
+
readonly ticker: Ticker;
|
|
135
|
+
readonly projectKey: string;
|
|
136
|
+
readonly sanitizer: Sanitizer;
|
|
137
|
+
readonly debug: Logger;
|
|
138
|
+
readonly notify: Logger;
|
|
139
|
+
readonly session: Session;
|
|
140
|
+
readonly localStorage: Storage;
|
|
141
|
+
readonly sessionStorage: Storage;
|
|
142
|
+
private readonly messages;
|
|
143
|
+
/**
|
|
144
|
+
* we need 2 buffers, so we don't lose anything
|
|
145
|
+
* @read coldStart implementation
|
|
146
|
+
* */
|
|
147
|
+
private bufferedMessages1;
|
|
148
|
+
private readonly bufferedMessages2;
|
|
149
|
+
readonly observer: Observer;
|
|
150
|
+
private readonly startCallbacks;
|
|
151
|
+
private readonly stopCallbacks;
|
|
152
|
+
private readonly commitCallbacks;
|
|
153
|
+
readonly options: AppOptions;
|
|
154
|
+
readonly networkOptions?: NetworkOptions;
|
|
155
|
+
private readonly revID;
|
|
156
|
+
private activityState;
|
|
157
|
+
private readonly version;
|
|
158
|
+
private worker?;
|
|
159
|
+
attributeSender: AttributeSender;
|
|
160
|
+
featureFlags: FeatureFlags;
|
|
161
|
+
socketMode: boolean;
|
|
162
|
+
private compressionThreshold;
|
|
163
|
+
private readonly bc;
|
|
164
|
+
private readonly contextId;
|
|
165
|
+
private canvasRecorder;
|
|
166
|
+
private uxtManager;
|
|
167
|
+
private conditionsManager;
|
|
168
|
+
private readonly tagWatcher;
|
|
169
|
+
private canStart;
|
|
170
|
+
private rootId;
|
|
171
|
+
private pageFrames;
|
|
172
|
+
private frameOderNumber;
|
|
173
|
+
private features;
|
|
174
|
+
constructor(projectKey: string, sessionToken: string | undefined, options: Partial<Options>, signalError: (error: string, apis: string[]) => void, insideIframe: boolean);
|
|
175
|
+
/** used by child iframes for crossdomain only */
|
|
176
|
+
parentActive: boolean;
|
|
177
|
+
checkStatus: () => boolean;
|
|
178
|
+
parentCrossDomainFrameListener: (event: MessageEvent) => void;
|
|
179
|
+
/**
|
|
180
|
+
* context ids for iframes,
|
|
181
|
+
* order is not so important as long as its consistent
|
|
182
|
+
* */
|
|
183
|
+
trackedFrames: string[];
|
|
184
|
+
crossDomainIframeListener: (event: MessageEvent) => void;
|
|
185
|
+
/**
|
|
186
|
+
* { command : [remaining iframes] }
|
|
187
|
+
* + order of commands
|
|
188
|
+
**/
|
|
189
|
+
pollingQueue: Record<string, any>;
|
|
190
|
+
private readonly addCommand;
|
|
191
|
+
bootChildrenFrames: () => Promise<void>;
|
|
192
|
+
killChildrenFrames: () => void;
|
|
193
|
+
signalIframeTracker: () => void;
|
|
194
|
+
startTimeout: ReturnType<typeof setTimeout> | null;
|
|
195
|
+
allowAppStart(): void;
|
|
196
|
+
private checkNodeId;
|
|
197
|
+
private initWorker;
|
|
198
|
+
private handleWorkerMsg;
|
|
199
|
+
private _debug;
|
|
200
|
+
send(message: Message, urgent?: boolean): void;
|
|
201
|
+
/**
|
|
202
|
+
* Normal workflow: add timestamp and tab data to batch, then commit it
|
|
203
|
+
* every ~30ms
|
|
204
|
+
* */
|
|
205
|
+
private _nCommit;
|
|
206
|
+
coldStartCommitN: number;
|
|
207
|
+
/**
|
|
208
|
+
* Cold start: add timestamp and tab data to both batches
|
|
209
|
+
* every 2nd tick, ~60ms
|
|
210
|
+
* this will make batches a bit larger and replay will work with bigger jumps every frame
|
|
211
|
+
* but in turn we don't overload batch writer on session start with 1000 batches
|
|
212
|
+
* */
|
|
213
|
+
private _cStartCommit;
|
|
214
|
+
private commit;
|
|
215
|
+
private postToWorker;
|
|
216
|
+
private delay;
|
|
217
|
+
timestamp(): number;
|
|
218
|
+
safe<T extends (this: any, ...args: any[]) => void>(fn: T): T;
|
|
219
|
+
attachCommitCallback(cb: CommitCallback): void;
|
|
220
|
+
attachStartCallback: (cb: StartCallback, useSafe?: boolean) => void;
|
|
221
|
+
attachStopCallback: (cb: () => any, useSafe?: boolean) => void;
|
|
222
|
+
attachEventListener: (target: EventTarget, type: string, listener: EventListener, useSafe?: boolean, useCapture?: boolean) => void;
|
|
223
|
+
checkRequiredVersion(version: string): boolean;
|
|
224
|
+
private getTrackerInfo;
|
|
225
|
+
getSessionInfo(): {
|
|
226
|
+
userUUID: string | null;
|
|
227
|
+
projectKey: string;
|
|
228
|
+
revID: string;
|
|
229
|
+
trackerVersion: string;
|
|
230
|
+
isSnippet: boolean;
|
|
231
|
+
sessionID: string | undefined;
|
|
232
|
+
metadata: Record<string, string>;
|
|
233
|
+
userID: string | null;
|
|
234
|
+
timestamp: number;
|
|
235
|
+
projectID?: string;
|
|
236
|
+
};
|
|
237
|
+
getSessionToken(): string | undefined;
|
|
238
|
+
getSessionID(): string | undefined;
|
|
239
|
+
getSessionURL(options?: {
|
|
240
|
+
withCurrentTime?: boolean;
|
|
241
|
+
}): string | undefined;
|
|
242
|
+
getHost(): string;
|
|
243
|
+
getProjectKey(): string;
|
|
244
|
+
getBaseHref(): string;
|
|
245
|
+
resolveResourceURL(resourceURL: string): string;
|
|
246
|
+
isServiceURL(url: string): boolean;
|
|
247
|
+
active(): boolean;
|
|
248
|
+
resetNextPageSession(flag: boolean): void;
|
|
249
|
+
coldInterval: ReturnType<typeof setInterval> | null;
|
|
250
|
+
orderNumber: number;
|
|
251
|
+
coldStartTs: number;
|
|
252
|
+
singleBuffer: boolean;
|
|
253
|
+
private checkSessionToken;
|
|
254
|
+
/**
|
|
255
|
+
* start buffering messages without starting the actual session, which gives
|
|
256
|
+
* user 30 seconds to "activate" and record session by calling `start()` on conditional trigger,
|
|
257
|
+
* and we will then send buffered batch, so it won't get lost
|
|
258
|
+
* */
|
|
259
|
+
coldStart(startOpts?: StartOptions, conditional?: boolean): Promise<void>;
|
|
260
|
+
private setupConditionalStart;
|
|
261
|
+
onSessionSent: () => void;
|
|
262
|
+
/**
|
|
263
|
+
* Starts offline session recording
|
|
264
|
+
* @param {Object} startOpts - options for session start, same as .start()
|
|
265
|
+
* @param {Function} onSessionSent - callback that will be called once session is fully sent
|
|
266
|
+
* */
|
|
267
|
+
offlineRecording(startOpts: StartOptions | undefined, onSessionSent: () => void): {
|
|
268
|
+
saveBuffer: () => void;
|
|
269
|
+
getBuffer: () => Message[];
|
|
270
|
+
setBuffer: (buffer: Message[]) => void;
|
|
271
|
+
};
|
|
272
|
+
/**
|
|
273
|
+
* Saves the captured messages in localStorage (or whatever is used in its place)
|
|
274
|
+
*
|
|
275
|
+
* Then, when this.offlineRecording is called, it will preload this messages and clear the storage item
|
|
276
|
+
*
|
|
277
|
+
* Keeping the size of local storage reasonable is up to the end users of this library
|
|
278
|
+
* */
|
|
279
|
+
saveBuffer(): void;
|
|
280
|
+
/**
|
|
281
|
+
* @returns buffer with stored messages for offline recording
|
|
282
|
+
* */
|
|
283
|
+
getBuffer(): Message[];
|
|
284
|
+
/**
|
|
285
|
+
* Used to set a buffer with messages array
|
|
286
|
+
* */
|
|
287
|
+
setBuffer(buffer: Message[]): void;
|
|
288
|
+
/**
|
|
289
|
+
* Uploads the stored session buffer to backend
|
|
290
|
+
* @returns promise that resolves once messages are loaded, it has to be awaited
|
|
291
|
+
* so the session can be uploaded properly
|
|
292
|
+
* @resolve - if messages were loaded in service worker successfully
|
|
293
|
+
* @reject {string} - error message
|
|
294
|
+
* */
|
|
295
|
+
uploadOfflineRecording(): Promise<void>;
|
|
296
|
+
prevOpts: StartOptions;
|
|
297
|
+
private _start;
|
|
298
|
+
restartCanvasTracking: () => void;
|
|
299
|
+
flushBuffer: (buffer: Message[]) => Promise<unknown>;
|
|
300
|
+
onUxtCb: never[];
|
|
301
|
+
addOnUxtCb(cb: (id: number) => void): void;
|
|
302
|
+
getUxtId(): number | null;
|
|
303
|
+
waitStart(): Promise<unknown>;
|
|
304
|
+
waitStarted(): Promise<unknown>;
|
|
305
|
+
waitStatus(status: ActivityState): Promise<unknown>;
|
|
306
|
+
/**
|
|
307
|
+
* basically we ask other tabs during constructor
|
|
308
|
+
* and here we just apply 10ms delay just in case
|
|
309
|
+
* */
|
|
310
|
+
start(...args: Parameters<App['_start']>): Promise<StartPromiseReturn>;
|
|
311
|
+
forceFlushBatch(): void;
|
|
312
|
+
getTabId(): string;
|
|
313
|
+
clearBuffers(): void;
|
|
314
|
+
/**
|
|
315
|
+
* Creates a named hook that expects event name, data string and msg direction (up/down),
|
|
316
|
+
* it will skip any message bigger than 5 mb or event name bigger than 255 symbols
|
|
317
|
+
* @returns {(msgType: string, data: string, dir: "up" | "down") => void}
|
|
318
|
+
* */
|
|
319
|
+
trackWs(channelName: string): (msgType: string, data: string, dir: 'up' | 'down') => void;
|
|
320
|
+
stop(stopWorker?: boolean): void;
|
|
321
|
+
}
|
|
322
|
+
export {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export declare const LogLevel: {
|
|
2
|
+
readonly Verbose: 5;
|
|
3
|
+
readonly Log: 4;
|
|
4
|
+
readonly Warnings: 3;
|
|
5
|
+
readonly Errors: 2;
|
|
6
|
+
readonly Silent: 0;
|
|
7
|
+
};
|
|
8
|
+
export type ILogLevel = (typeof LogLevel)[keyof typeof LogLevel];
|
|
9
|
+
export default class Logger {
|
|
10
|
+
private readonly level;
|
|
11
|
+
constructor(debugLevel?: ILogLevel);
|
|
12
|
+
private readonly shouldLog;
|
|
13
|
+
info: (...args: any[]) => void;
|
|
14
|
+
log: (...args: any[]) => void;
|
|
15
|
+
warn: (...args: any[]) => void;
|
|
16
|
+
error: (...args: any[]) => void;
|
|
17
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import * as Messages from '../../common/messages.gen.js';
|
|
2
|
+
export { default, Type } from '../../common/messages.gen.js';
|
|
3
|
+
export declare function Timestamp(timestamp: number): Messages.Timestamp;
|
|
4
|
+
export declare function SetPageLocationDeprecated(url: string, referrer: string, navigationStart: number): Messages.SetPageLocationDeprecated;
|
|
5
|
+
export declare function SetViewportSize(width: number, height: number): Messages.SetViewportSize;
|
|
6
|
+
export declare function SetViewportScroll(x: number, y: number): Messages.SetViewportScroll;
|
|
7
|
+
export declare function CreateDocument(): Messages.CreateDocument;
|
|
8
|
+
export declare function CreateElementNode(id: number, parentID: number, index: number, tag: string, svg: boolean): Messages.CreateElementNode;
|
|
9
|
+
export declare function CreateTextNode(id: number, parentID: number, index: number): Messages.CreateTextNode;
|
|
10
|
+
export declare function MoveNode(id: number, parentID: number, index: number): Messages.MoveNode;
|
|
11
|
+
export declare function RemoveNode(id: number): Messages.RemoveNode;
|
|
12
|
+
export declare function SetNodeAttribute(id: number, name: string, value: string): Messages.SetNodeAttribute;
|
|
13
|
+
export declare function RemoveNodeAttribute(id: number, name: string): Messages.RemoveNodeAttribute;
|
|
14
|
+
export declare function SetNodeData(id: number, data: string): Messages.SetNodeData;
|
|
15
|
+
export declare function SetNodeScroll(id: number, x: number, y: number): Messages.SetNodeScroll;
|
|
16
|
+
export declare function SetInputTarget(id: number, label: string): Messages.SetInputTarget;
|
|
17
|
+
export declare function SetInputValue(id: number, value: string, mask: number): Messages.SetInputValue;
|
|
18
|
+
export declare function SetInputChecked(id: number, checked: boolean): Messages.SetInputChecked;
|
|
19
|
+
export declare function MouseMove(x: number, y: number): Messages.MouseMove;
|
|
20
|
+
export declare function NetworkRequestDeprecated(type: string, method: string, url: string, request: string, response: string, status: number, timestamp: number, duration: number): Messages.NetworkRequestDeprecated;
|
|
21
|
+
export declare function ConsoleLog(level: string, value: string): Messages.ConsoleLog;
|
|
22
|
+
export declare function PageLoadTiming(requestStart: number, responseStart: number, responseEnd: number, domContentLoadedEventStart: number, domContentLoadedEventEnd: number, loadEventStart: number, loadEventEnd: number, firstPaint: number, firstContentfulPaint: number): Messages.PageLoadTiming;
|
|
23
|
+
export declare function PageRenderTiming(speedIndex: number, visuallyComplete: number, timeToInteractive: number): Messages.PageRenderTiming;
|
|
24
|
+
export declare function CustomEvent(name: string, payload: string): Messages.CustomEvent;
|
|
25
|
+
export declare function UserID(id: string): Messages.UserID;
|
|
26
|
+
export declare function UserAnonymousID(id: string): Messages.UserAnonymousID;
|
|
27
|
+
export declare function Metadata(key: string, value: string): Messages.Metadata;
|
|
28
|
+
export declare function CSSInsertRule(id: number, rule: string, index: number): Messages.CSSInsertRule;
|
|
29
|
+
export declare function CSSDeleteRule(id: number, index: number): Messages.CSSDeleteRule;
|
|
30
|
+
export declare function Fetch(method: string, url: string, request: string, response: string, status: number, timestamp: number, duration: number): Messages.Fetch;
|
|
31
|
+
export declare function Profiler(name: string, duration: number, args: string, result: string): Messages.Profiler;
|
|
32
|
+
export declare function OTable(key: string, value: string): Messages.OTable;
|
|
33
|
+
export declare function StateAction(type: string): Messages.StateAction;
|
|
34
|
+
export declare function ReduxDeprecated(action: string, state: string, duration: number): Messages.ReduxDeprecated;
|
|
35
|
+
export declare function Vuex(mutation: string, state: string): Messages.Vuex;
|
|
36
|
+
export declare function MobX(type: string, payload: string): Messages.MobX;
|
|
37
|
+
export declare function NgRx(action: string, state: string, duration: number): Messages.NgRx;
|
|
38
|
+
export declare function GraphQLDeprecated(operationKind: string, operationName: string, variables: string, response: string, duration: number): Messages.GraphQLDeprecated;
|
|
39
|
+
export declare function PerformanceTrack(frames: number, ticks: number, totalJSHeapSize: number, usedJSHeapSize: number): Messages.PerformanceTrack;
|
|
40
|
+
export declare function StringDictDeprecated(key: number, value: string): Messages.StringDictDeprecated;
|
|
41
|
+
export declare function SetNodeAttributeDictDeprecated(id: number, nameKey: number, valueKey: number): Messages.SetNodeAttributeDictDeprecated;
|
|
42
|
+
export declare function StringDict(key: string, value: string): Messages.StringDict;
|
|
43
|
+
export declare function SetNodeAttributeDict(id: number, name: string, value: string): Messages.SetNodeAttributeDict;
|
|
44
|
+
export declare function ResourceTimingDeprecated(timestamp: number, duration: number, ttfb: number, headerSize: number, encodedBodySize: number, decodedBodySize: number, url: string, initiator: string): Messages.ResourceTimingDeprecated;
|
|
45
|
+
export declare function ConnectionInformation(downlink: number, type: string): Messages.ConnectionInformation;
|
|
46
|
+
export declare function SetPageVisibility(hidden: boolean): Messages.SetPageVisibility;
|
|
47
|
+
export declare function LoadFontFace(parentID: number, family: string, source: string, descriptors: string): Messages.LoadFontFace;
|
|
48
|
+
export declare function SetNodeFocus(id: number): Messages.SetNodeFocus;
|
|
49
|
+
export declare function LongTask(timestamp: number, duration: number, context: number, containerType: number, containerSrc: string, containerId: string, containerName: string): Messages.LongTask;
|
|
50
|
+
export declare function SetNodeAttributeURLBased(id: number, name: string, value: string, baseURL: string): Messages.SetNodeAttributeURLBased;
|
|
51
|
+
export declare function SetCSSDataURLBased(id: number, data: string, baseURL: string): Messages.SetCSSDataURLBased;
|
|
52
|
+
export declare function TechnicalInfo(type: string, value: string): Messages.TechnicalInfo;
|
|
53
|
+
export declare function CustomIssue(name: string, payload: string): Messages.CustomIssue;
|
|
54
|
+
export declare function CSSInsertRuleURLBased(id: number, rule: string, index: number, baseURL: string): Messages.CSSInsertRuleURLBased;
|
|
55
|
+
export declare function MouseClick(id: number, hesitationTime: number, label: string, selector: string, normalizedX: number, normalizedY: number): Messages.MouseClick;
|
|
56
|
+
export declare function MouseClickDeprecated(id: number, hesitationTime: number, label: string, selector: string): Messages.MouseClickDeprecated;
|
|
57
|
+
export declare function CreateIFrameDocument(frameID: number, id: number): Messages.CreateIFrameDocument;
|
|
58
|
+
export declare function AdoptedSSReplaceURLBased(sheetID: number, text: string, baseURL: string): Messages.AdoptedSSReplaceURLBased;
|
|
59
|
+
export declare function AdoptedSSInsertRuleURLBased(sheetID: number, rule: string, index: number, baseURL: string): Messages.AdoptedSSInsertRuleURLBased;
|
|
60
|
+
export declare function AdoptedSSDeleteRule(sheetID: number, index: number): Messages.AdoptedSSDeleteRule;
|
|
61
|
+
export declare function AdoptedSSAddOwner(sheetID: number, id: number): Messages.AdoptedSSAddOwner;
|
|
62
|
+
export declare function AdoptedSSRemoveOwner(sheetID: number, id: number): Messages.AdoptedSSRemoveOwner;
|
|
63
|
+
export declare function JSException(name: string, message: string, payload: string, metadata: string): Messages.JSException;
|
|
64
|
+
export declare function Zustand(mutation: string, state: string): Messages.Zustand;
|
|
65
|
+
export declare function BatchMetadata(version: number, pageNo: number, firstIndex: number, timestamp: number, location: string): Messages.BatchMetadata;
|
|
66
|
+
export declare function PartitionedMessage(partNo: number, partTotal: number): Messages.PartitionedMessage;
|
|
67
|
+
export declare function NetworkRequest(type: string, method: string, url: string, request: string, response: string, status: number, timestamp: number, duration: number, transferredBodySize: number): Messages.NetworkRequest;
|
|
68
|
+
export declare function WSChannel(chType: string, channelName: string, data: string, timestamp: number, dir: string, messageType: string): Messages.WSChannel;
|
|
69
|
+
export declare function InputChange(id: number, value: string, valueMasked: boolean, label: string, hesitationTime: number, inputDuration: number): Messages.InputChange;
|
|
70
|
+
export declare function SelectionChange(selectionStart: number, selectionEnd: number, selection: string): Messages.SelectionChange;
|
|
71
|
+
export declare function MouseThrashing(timestamp: number): Messages.MouseThrashing;
|
|
72
|
+
export declare function UnbindNodes(totalRemovedPercent: number): Messages.UnbindNodes;
|
|
73
|
+
export declare function ResourceTiming(timestamp: number, duration: number, ttfb: number, headerSize: number, encodedBodySize: number, decodedBodySize: number, url: string, initiator: string, transferredSize: number, cached: boolean): Messages.ResourceTiming;
|
|
74
|
+
export declare function TabChange(tabId: string): Messages.TabChange;
|
|
75
|
+
export declare function TabData(tabId: string): Messages.TabData;
|
|
76
|
+
export declare function CanvasNode(nodeId: string, timestamp: number): Messages.CanvasNode;
|
|
77
|
+
export declare function TagTrigger(tagId: number): Messages.TagTrigger;
|
|
78
|
+
export declare function Redux(action: string, state: string, duration: number, actionTime: number): Messages.Redux;
|
|
79
|
+
export declare function SetPageLocation(url: string, referrer: string, navigationStart: number, documentTitle: string): Messages.SetPageLocation;
|
|
80
|
+
export declare function GraphQL(operationKind: string, operationName: string, variables: string, response: string, duration: number): Messages.GraphQL;
|
|
81
|
+
export declare function WebVitals(name: string, value: string): Messages.WebVitals;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { MaintainerOptions } from './maintainer.js';
|
|
2
|
+
type NodeCallback = (node: Node, isStart: boolean) => void;
|
|
3
|
+
export interface NodesOptions {
|
|
4
|
+
node_id: string;
|
|
5
|
+
forceNgOff: boolean;
|
|
6
|
+
maintainer?: Partial<MaintainerOptions>;
|
|
7
|
+
}
|
|
8
|
+
export default class Nodes {
|
|
9
|
+
private readonly nodes;
|
|
10
|
+
private totalNodeAmount;
|
|
11
|
+
private readonly nodeCallbacks;
|
|
12
|
+
private readonly elementListeners;
|
|
13
|
+
private nextNodeId;
|
|
14
|
+
private readonly node_id;
|
|
15
|
+
private readonly forceNgOff;
|
|
16
|
+
private readonly maintainer;
|
|
17
|
+
constructor(params: NodesOptions);
|
|
18
|
+
syntheticMode(frameOrder: number): void;
|
|
19
|
+
attachNodeCallback: (nodeCallback: NodeCallback) => number;
|
|
20
|
+
scanTree: (cb: (node: Node | void) => void) => void;
|
|
21
|
+
attachNodeListener: (node: Node, type: string, listener: EventListener, useCapture?: boolean) => void;
|
|
22
|
+
registerNode(node: Node): [/*id:*/ number, /*isNew:*/ boolean];
|
|
23
|
+
unregisterNode: (node: Node) => number | undefined;
|
|
24
|
+
cleanTree(): void;
|
|
25
|
+
callNodeCallbacks(node: Node, isStart: boolean): void;
|
|
26
|
+
getID(node: Node): number | undefined;
|
|
27
|
+
getNode(id: number): void | Node | undefined;
|
|
28
|
+
getNodeCount(): number;
|
|
29
|
+
clear(): void;
|
|
30
|
+
}
|
|
31
|
+
export {};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export interface MaintainerOptions {
|
|
2
|
+
/**
|
|
3
|
+
* Run cleanup each X ms
|
|
4
|
+
*
|
|
5
|
+
* @default 30 * 1000
|
|
6
|
+
* */
|
|
7
|
+
interval: number;
|
|
8
|
+
/**
|
|
9
|
+
* Maintainer checks nodes in small batches over 50ms timeouts
|
|
10
|
+
*
|
|
11
|
+
* @default 2500
|
|
12
|
+
* */
|
|
13
|
+
batchSize: number;
|
|
14
|
+
/**
|
|
15
|
+
* @default true
|
|
16
|
+
* */
|
|
17
|
+
enabled: boolean;
|
|
18
|
+
}
|
|
19
|
+
declare class Maintainer {
|
|
20
|
+
private readonly nodes;
|
|
21
|
+
private readonly unregisterNode;
|
|
22
|
+
private interval;
|
|
23
|
+
private readonly options;
|
|
24
|
+
constructor(nodes: Map<number, Node | void>, unregisterNode: (node: Node) => void, options?: Partial<MaintainerOptions>);
|
|
25
|
+
start: () => void;
|
|
26
|
+
stop: () => void;
|
|
27
|
+
}
|
|
28
|
+
export default Maintainer;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import App from '../index.js';
|
|
2
|
+
export default abstract class Observer {
|
|
3
|
+
protected readonly app: App;
|
|
4
|
+
protected readonly isTopContext: boolean;
|
|
5
|
+
private readonly observer;
|
|
6
|
+
private readonly commited;
|
|
7
|
+
private readonly recents;
|
|
8
|
+
private readonly indexes;
|
|
9
|
+
private readonly attributesMap;
|
|
10
|
+
private readonly textSet;
|
|
11
|
+
constructor(app: App, isTopContext?: boolean);
|
|
12
|
+
private clear;
|
|
13
|
+
/**
|
|
14
|
+
* EXPERIMENTAL: Unbinds the removed nodes in case of iframe src change.
|
|
15
|
+
*
|
|
16
|
+
* right now, we're relying on nodes.maintainer
|
|
17
|
+
*/
|
|
18
|
+
private handleIframeSrcChange;
|
|
19
|
+
private sendNodeAttribute;
|
|
20
|
+
private sendNodeData;
|
|
21
|
+
private bindNode;
|
|
22
|
+
private bindTree;
|
|
23
|
+
private unbindTree;
|
|
24
|
+
private _commitNode;
|
|
25
|
+
private commitNode;
|
|
26
|
+
private commitNodes;
|
|
27
|
+
protected observeRoot(node: Node, beforeCommit: (id?: number) => unknown, nodeToBind?: Node): void;
|
|
28
|
+
disconnect(): void;
|
|
29
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import Observer from './observer.js';
|
|
2
|
+
import { Offset } from './iframe_offsets.js';
|
|
3
|
+
import App from '../index.js';
|
|
4
|
+
export interface Options {
|
|
5
|
+
captureIFrames: boolean;
|
|
6
|
+
}
|
|
7
|
+
type Context = Window & typeof globalThis;
|
|
8
|
+
type ContextCallback = (context: Context) => void;
|
|
9
|
+
export default class TopObserver extends Observer {
|
|
10
|
+
private readonly options;
|
|
11
|
+
private readonly iframeOffsets;
|
|
12
|
+
readonly app: App;
|
|
13
|
+
constructor(params: {
|
|
14
|
+
app: App;
|
|
15
|
+
options: Partial<Options>;
|
|
16
|
+
});
|
|
17
|
+
private readonly contextCallbacks;
|
|
18
|
+
private readonly contextsSet;
|
|
19
|
+
attachContextCallback(cb: ContextCallback): void;
|
|
20
|
+
getDocumentOffset(doc: Document): Offset;
|
|
21
|
+
private iframeObserversArr;
|
|
22
|
+
private iframeObservers;
|
|
23
|
+
private docObservers;
|
|
24
|
+
private handleIframe;
|
|
25
|
+
private shadowRootObservers;
|
|
26
|
+
private handleShadowRoot;
|
|
27
|
+
observe(): void;
|
|
28
|
+
crossdomainObserve(rootNodeId: number, frameOder: number): void;
|
|
29
|
+
disconnect(): void;
|
|
30
|
+
}
|
|
31
|
+
export {};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type App from './index.js';
|
|
2
|
+
export declare enum SanitizeLevel {
|
|
3
|
+
Plain = 0,
|
|
4
|
+
Obscured = 1,
|
|
5
|
+
Hidden = 2
|
|
6
|
+
}
|
|
7
|
+
export interface Options {
|
|
8
|
+
/**
|
|
9
|
+
* Sanitize emails in text DOM nodes
|
|
10
|
+
*
|
|
11
|
+
* (for inputs, look for obscureInputEmails)
|
|
12
|
+
* */
|
|
13
|
+
obscureTextEmails: boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Sanitize emails in text DOM nodes
|
|
16
|
+
*
|
|
17
|
+
* (for inputs, look for obscureInputNumbers)
|
|
18
|
+
* */
|
|
19
|
+
obscureTextNumbers: boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Sanitize the DOM node based on the returned level
|
|
22
|
+
* (Plain = 0, Obscured = 1, Hidden = 2)
|
|
23
|
+
*
|
|
24
|
+
* higher security levels will override other settings or data-params.
|
|
25
|
+
*
|
|
26
|
+
* @param node - the DOM node to sanitize
|
|
27
|
+
* @returns the level of sanitization to apply
|
|
28
|
+
*
|
|
29
|
+
* */
|
|
30
|
+
domSanitizer?: (node: Element) => SanitizeLevel;
|
|
31
|
+
}
|
|
32
|
+
export declare const stringWiper: (input: string) => string;
|
|
33
|
+
export default class Sanitizer {
|
|
34
|
+
private readonly obscured;
|
|
35
|
+
private readonly hidden;
|
|
36
|
+
private readonly options;
|
|
37
|
+
private readonly app;
|
|
38
|
+
constructor(params: {
|
|
39
|
+
app: App;
|
|
40
|
+
options?: Partial<Options>;
|
|
41
|
+
});
|
|
42
|
+
handleNode(id: number, parentID: number, node: Node): void;
|
|
43
|
+
sanitize(id: number, data: string): string;
|
|
44
|
+
isObscured(id: number): boolean;
|
|
45
|
+
isHidden(id: number): boolean;
|
|
46
|
+
getInnerTextSecure(el: HTMLElement): string;
|
|
47
|
+
clear(): void;
|
|
48
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type App from './index.js';
|
|
2
|
+
interface UserInfo {
|
|
3
|
+
userBrowser: string;
|
|
4
|
+
userCity: string;
|
|
5
|
+
userCountry: string;
|
|
6
|
+
userDevice: string;
|
|
7
|
+
userOS: string;
|
|
8
|
+
userState: string;
|
|
9
|
+
}
|
|
10
|
+
export interface SessionInfo {
|
|
11
|
+
sessionID: string | undefined;
|
|
12
|
+
metadata: Record<string, string>;
|
|
13
|
+
userID: string | null;
|
|
14
|
+
timestamp: number;
|
|
15
|
+
projectID?: string;
|
|
16
|
+
}
|
|
17
|
+
type OnUpdateCallback = (i: Partial<SessionInfo>) => void;
|
|
18
|
+
export type Options = {
|
|
19
|
+
session_token_key: string;
|
|
20
|
+
session_pageno_key: string;
|
|
21
|
+
session_tabid_key: string;
|
|
22
|
+
};
|
|
23
|
+
export default class Session {
|
|
24
|
+
private metadata;
|
|
25
|
+
private userID;
|
|
26
|
+
private sessionID;
|
|
27
|
+
private readonly callbacks;
|
|
28
|
+
private timestamp;
|
|
29
|
+
private projectID;
|
|
30
|
+
private tabId;
|
|
31
|
+
userInfo: UserInfo;
|
|
32
|
+
private token;
|
|
33
|
+
private readonly app;
|
|
34
|
+
private readonly options;
|
|
35
|
+
constructor(params: {
|
|
36
|
+
app: App;
|
|
37
|
+
options: Options;
|
|
38
|
+
});
|
|
39
|
+
attachUpdateCallback(cb: OnUpdateCallback): void;
|
|
40
|
+
private handleUpdate;
|
|
41
|
+
assign(newInfo: Partial<SessionInfo>): void;
|
|
42
|
+
setMetadata(key: string, value: string): void;
|
|
43
|
+
setUserID(userID: string): void;
|
|
44
|
+
setUserInfo(userInfo: UserInfo): void;
|
|
45
|
+
getPageNumber: () => number | undefined;
|
|
46
|
+
incPageNo: () => number;
|
|
47
|
+
getSessionToken(): string | undefined;
|
|
48
|
+
setSessionToken(token: string): void;
|
|
49
|
+
applySessionHash(hash: string): void;
|
|
50
|
+
getSessionHash(): string | undefined;
|
|
51
|
+
getTabId(): string;
|
|
52
|
+
regenerateTabId(): void;
|
|
53
|
+
private createTabId;
|
|
54
|
+
getInfo(): SessionInfo;
|
|
55
|
+
reset(): void;
|
|
56
|
+
}
|
|
57
|
+
export {};
|