@oxvo/browser 7.1.0 → 7.3.0
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/common/interaction.d.ts +12 -1
- package/dist/cjs/common/messages.gen.d.ts +4 -7
- package/dist/cjs/entry.js +991 -945
- package/dist/cjs/entry.js.map +1 -1
- package/dist/cjs/index.js +918 -913
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/main/app/canvas.d.ts +8 -0
- package/dist/cjs/main/app/index.d.ts +13 -5
- package/dist/cjs/main/app/messages.gen.d.ts +0 -1
- package/dist/cjs/main/app/observer/observer.d.ts +16 -0
- package/dist/cjs/main/app/sanitizer.d.ts +5 -3
- package/dist/cjs/main/index.d.ts +16 -0
- package/dist/cjs/main/modules/analytics/batcher.d.ts +6 -1
- package/dist/cjs/main/modules/analytics/index.d.ts +5 -0
- package/dist/cjs/main/modules/input.d.ts +2 -1
- package/dist/cjs/main/modules/markerWatcher.d.ts +4 -8
- package/dist/cjs/main/modules/mouse.d.ts +1 -0
- package/dist/cjs/main/modules/tagMatcher.d.ts +28 -0
- package/dist/cjs/main/singleton.d.ts +24 -0
- package/dist/cjs/main/utils.d.ts +2 -0
- package/dist/lib/common/interaction.d.ts +12 -1
- package/dist/lib/common/messages.gen.d.ts +4 -7
- package/dist/lib/entry.js +991 -945
- package/dist/lib/entry.js.map +1 -1
- package/dist/lib/index.js +918 -913
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/main/app/canvas.d.ts +8 -0
- package/dist/lib/main/app/index.d.ts +13 -5
- package/dist/lib/main/app/messages.gen.d.ts +0 -1
- package/dist/lib/main/app/observer/observer.d.ts +16 -0
- package/dist/lib/main/app/sanitizer.d.ts +5 -3
- package/dist/lib/main/index.d.ts +16 -0
- package/dist/lib/main/modules/analytics/batcher.d.ts +6 -1
- package/dist/lib/main/modules/analytics/index.d.ts +5 -0
- package/dist/lib/main/modules/input.d.ts +2 -1
- package/dist/lib/main/modules/markerWatcher.d.ts +4 -8
- package/dist/lib/main/modules/mouse.d.ts +1 -0
- package/dist/lib/main/modules/tagMatcher.d.ts +28 -0
- package/dist/lib/main/singleton.d.ts +24 -0
- package/dist/lib/main/utils.d.ts +2 -0
- package/dist/types/common/interaction.d.ts +12 -1
- package/dist/types/common/messages.gen.d.ts +4 -7
- package/dist/types/main/app/canvas.d.ts +8 -0
- package/dist/types/main/app/index.d.ts +13 -5
- package/dist/types/main/app/messages.gen.d.ts +0 -1
- package/dist/types/main/app/observer/observer.d.ts +16 -0
- package/dist/types/main/app/sanitizer.d.ts +5 -3
- package/dist/types/main/index.d.ts +16 -0
- package/dist/types/main/modules/analytics/batcher.d.ts +6 -1
- package/dist/types/main/modules/analytics/index.d.ts +5 -0
- package/dist/types/main/modules/input.d.ts +2 -1
- package/dist/types/main/modules/markerWatcher.d.ts +4 -8
- package/dist/types/main/modules/mouse.d.ts +1 -0
- package/dist/types/main/modules/tagMatcher.d.ts +28 -0
- package/dist/types/main/singleton.d.ts +24 -0
- package/dist/types/main/utils.d.ts +2 -0
- package/package.json +11 -12
|
@@ -5,6 +5,8 @@ interface Options {
|
|
|
5
5
|
isDebug?: boolean;
|
|
6
6
|
fixedScaling?: boolean;
|
|
7
7
|
useAnimationFrame?: boolean;
|
|
8
|
+
framesSupport?: boolean;
|
|
9
|
+
/** @deprecated webp is the default format for pipeline optimization */
|
|
8
10
|
fileExt?: 'webp' | 'png' | 'jpeg' | 'avif';
|
|
9
11
|
}
|
|
10
12
|
declare class CanvasRecorder {
|
|
@@ -22,6 +24,12 @@ declare class CanvasRecorder {
|
|
|
22
24
|
private isProcessingQueue;
|
|
23
25
|
constructor(app: App, options: Options);
|
|
24
26
|
startTracking(): void;
|
|
27
|
+
/**
|
|
28
|
+
* Reacts to a runtime sanitization change on a canvas: stop capturing if it
|
|
29
|
+
* just became masked, start if it just became visible. Already-sent frames
|
|
30
|
+
* cannot be retracted, so escalation only stops future capture.
|
|
31
|
+
*/
|
|
32
|
+
resanitizeCanvas: (node: Node, id: number) => void;
|
|
25
33
|
restartTracking: () => void;
|
|
26
34
|
captureCanvas: (node: Node) => void;
|
|
27
35
|
recordCanvas: (node: Node, id: number) => void;
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import type { Options as WebworkerOptions } from '../../common/interaction.js';
|
|
2
2
|
import AttributeSender from '../modules/attributeSender.js';
|
|
3
3
|
import type { Options as NetworkOptions } from '../modules/network.js';
|
|
4
|
+
import type TagMatcher from '../modules/tagMatcher.js';
|
|
4
5
|
import Logger, { ILogLevel } from './logger.js';
|
|
5
6
|
import Message from './messages.gen.js';
|
|
6
7
|
import Nodes from './nodes/index.js';
|
|
7
8
|
import type { Options as ObserverOptions } from './observer/top_observer.js';
|
|
8
9
|
import Observer from './observer/top_observer.js';
|
|
9
10
|
import type { Options as SanitizerOptions } from './sanitizer.js';
|
|
10
|
-
import Sanitizer from './sanitizer.js';
|
|
11
|
+
import Sanitizer, { SanitizeLevel } from './sanitizer.js';
|
|
11
12
|
import type { Options as SessOptions } from './session.js';
|
|
12
13
|
import Session from './session.js';
|
|
13
14
|
import Ticker from './ticker.js';
|
|
@@ -64,6 +65,7 @@ type AppOptions = {
|
|
|
64
65
|
__is_snippet: boolean;
|
|
65
66
|
__debug_report_edp: string | null;
|
|
66
67
|
__debug__?: ILogLevel;
|
|
68
|
+
__local_debug?: boolean;
|
|
67
69
|
localStorage: Storage | null;
|
|
68
70
|
sessionStorage: Storage | null;
|
|
69
71
|
forceSingleTab?: boolean;
|
|
@@ -129,6 +131,7 @@ export default class App {
|
|
|
129
131
|
readonly ticker: Ticker;
|
|
130
132
|
readonly projectKey: string;
|
|
131
133
|
readonly sanitizer: Sanitizer;
|
|
134
|
+
private readonly resanitizeCallbacks;
|
|
132
135
|
readonly debug: Logger;
|
|
133
136
|
readonly notify: Logger;
|
|
134
137
|
readonly session: Session;
|
|
@@ -159,6 +162,7 @@ export default class App {
|
|
|
159
162
|
private canvasRecorder;
|
|
160
163
|
private conditionsManager;
|
|
161
164
|
private readonly markerWatcher;
|
|
165
|
+
get tagMatcher(): TagMatcher;
|
|
162
166
|
private canStart;
|
|
163
167
|
private rootId;
|
|
164
168
|
private pageFrames;
|
|
@@ -170,11 +174,10 @@ export default class App {
|
|
|
170
174
|
parentActive: boolean;
|
|
171
175
|
checkStatus: () => boolean;
|
|
172
176
|
parentCrossDomainFrameListener: (event: MessageEvent) => void;
|
|
173
|
-
/**
|
|
174
|
-
* context ids for iframes,
|
|
175
|
-
* order is not so important as long as its consistent
|
|
176
|
-
* */
|
|
177
177
|
trackedFrames: string[];
|
|
178
|
+
private frameLastSeen;
|
|
179
|
+
private readonly FRAME_STALE_MS;
|
|
180
|
+
private pruneStaleFrames;
|
|
178
181
|
crossDomainIframeListener: (event: MessageEvent) => void;
|
|
179
182
|
/**
|
|
180
183
|
* { command : [remaining iframes] }
|
|
@@ -290,8 +293,13 @@ export default class App {
|
|
|
290
293
|
* */
|
|
291
294
|
uploadOfflineRecording(): Promise<void>;
|
|
292
295
|
prevOpts: StartOptions;
|
|
296
|
+
private userStartCallback?;
|
|
293
297
|
private _start;
|
|
294
298
|
restartCanvasTracking: () => void;
|
|
299
|
+
attachResanitizeCallback: (cb: (node: Node, id: number) => void) => void;
|
|
300
|
+
callResanitizeCallbacks: (node: Node, id: number) => void;
|
|
301
|
+
resanitize: (el?: Element) => void;
|
|
302
|
+
checkSanitization: (el: Node) => SanitizeLevel | undefined;
|
|
295
303
|
flushBuffer: (buffer: Message[]) => Promise<unknown>;
|
|
296
304
|
waitStart(): Promise<unknown>;
|
|
297
305
|
waitStarted(): Promise<unknown>;
|
|
@@ -62,7 +62,6 @@ export declare function AdoptedSSRemoveOwner(sheetID: number, id: number): Messa
|
|
|
62
62
|
export declare function JSException(name: string, message: string, payload: string, metadata: string): Messages.JSException;
|
|
63
63
|
export declare function Zustand(mutation: string, state: string): Messages.Zustand;
|
|
64
64
|
export declare function BatchMetadata(version: number, pageNo: number, firstIndex: number, timestamp: number, location: string): Messages.BatchMetadata;
|
|
65
|
-
export declare function PartitionedMessage(partNo: number, partTotal: number): Messages.PartitionedMessage;
|
|
66
65
|
export declare function NetworkRequest(type: string, method: string, url: string, request: string, response: string, status: number, timestamp: number, duration: number, transferredBodySize: number): Messages.NetworkRequest;
|
|
67
66
|
export declare function WSChannel(chType: string, channelName: string, data: string, timestamp: number, dir: string, messageType: string): Messages.WSChannel;
|
|
68
67
|
export declare function ResourceTiming(timestamp: number, duration: number, ttfb: number, headerSize: number, encodedBodySize: number, decodedBodySize: number, url: string, initiator: string, transferredSize: number, cached: boolean, queueing: number, dnsLookup: number, initialConnection: number, ssl: number, contentDownload: number, total: number, stalled: number): Messages.ResourceTiming;
|
|
@@ -28,6 +28,12 @@ export default abstract class Observer {
|
|
|
28
28
|
private readonly inlineRemoteCss;
|
|
29
29
|
private readonly inlinerOptions;
|
|
30
30
|
private readonly domParser;
|
|
31
|
+
/**
|
|
32
|
+
* Bumped on every disconnect(). Stale async CSS-inlining callbacks from a
|
|
33
|
+
* previous session (e.g. agent reload → tracker restart) compare against
|
|
34
|
+
* this and bail instead of sending messages that reference vanished node ids.
|
|
35
|
+
*/
|
|
36
|
+
private generation;
|
|
31
37
|
constructor(app: App, isTopContext?: boolean, options?: Options);
|
|
32
38
|
private clear;
|
|
33
39
|
/**
|
|
@@ -47,6 +53,16 @@ export default abstract class Observer {
|
|
|
47
53
|
private commitNode;
|
|
48
54
|
private commitNodes;
|
|
49
55
|
protected observeRoot(node: Node, beforeCommit: (id?: number) => unknown, nodeToBind?: Node): void;
|
|
56
|
+
/**
|
|
57
|
+
* Re-evaluates sanitization for every tracked node in `root`'s subtree against
|
|
58
|
+
* the current DOM and re-emits whatever changed. Pass the highest node you
|
|
59
|
+
* changed (or the document root) so inherited levels propagate correctly.
|
|
60
|
+
*/
|
|
61
|
+
resanitizeSubtree(root: Node): void;
|
|
62
|
+
private resanitizeNode;
|
|
63
|
+
private recreateSubtree;
|
|
64
|
+
private clearSubtreeRegistration;
|
|
65
|
+
private reemitNode;
|
|
50
66
|
disconnect(): void;
|
|
51
67
|
}
|
|
52
68
|
export {};
|
|
@@ -35,8 +35,7 @@ export interface Options {
|
|
|
35
35
|
}
|
|
36
36
|
export declare const stringWiper: (input: string) => string;
|
|
37
37
|
export default class Sanitizer {
|
|
38
|
-
private readonly
|
|
39
|
-
private readonly hidden;
|
|
38
|
+
private readonly levels;
|
|
40
39
|
private readonly options;
|
|
41
40
|
readonly maskAllByDefault: boolean;
|
|
42
41
|
private readonly app;
|
|
@@ -44,7 +43,10 @@ export default class Sanitizer {
|
|
|
44
43
|
app: App;
|
|
45
44
|
options?: Partial<Options>;
|
|
46
45
|
});
|
|
47
|
-
|
|
46
|
+
computeLevel(node: Node, parentLevel: SanitizeLevel): SanitizeLevel;
|
|
47
|
+
getLevel(id: number): SanitizeLevel;
|
|
48
|
+
setLevel(id: number, level: SanitizeLevel): SanitizeLevel;
|
|
49
|
+
handleNode(id: number, parentID: number, node: Node): void;
|
|
48
50
|
sanitize(id: number, data: string): string;
|
|
49
51
|
isObscured(id: number): boolean;
|
|
50
52
|
isHidden(id: number): boolean;
|
package/dist/lib/main/index.d.ts
CHANGED
|
@@ -27,6 +27,7 @@ export type Options = Partial<AppOptions & ConsoleOptions & ExceptionOptions & I
|
|
|
27
27
|
resetTabOnWindowOpen?: boolean;
|
|
28
28
|
networkCapture?: Partial<NetworkOptions>;
|
|
29
29
|
mouse?: Partial<MouseHandlerOptions>;
|
|
30
|
+
customAttributes?: string[];
|
|
30
31
|
devAllowInsecure?: boolean;
|
|
31
32
|
css: CssRulesOptions;
|
|
32
33
|
webAnimations?: WapOptions;
|
|
@@ -46,6 +47,21 @@ export default class API {
|
|
|
46
47
|
checkDoNotTrack: () => boolean | undefined;
|
|
47
48
|
signalStartIssue: (reason: string, missingApi: string[]) => void;
|
|
48
49
|
restartCanvasTracking: () => void;
|
|
50
|
+
/**
|
|
51
|
+
* Re-evaluates sanitization against the current DOM and re-emits whatever
|
|
52
|
+
* changed, updating already-recorded nodes mid-session. Call after toggling
|
|
53
|
+
* `data-oxvosessions-*` attributes or after changing whatever your `domSanitizer`
|
|
54
|
+
* keys on (class/id/etc).
|
|
55
|
+
*
|
|
56
|
+
* @param el - the highest node you changed; omit to re-scan the whole document;
|
|
57
|
+
* scanning the entire doc is O(dom size)
|
|
58
|
+
* */
|
|
59
|
+
resanitize: (el?: Element) => void;
|
|
60
|
+
/**
|
|
61
|
+
* Returns the sanitization level the tracker currently has for a node
|
|
62
|
+
* (0 = Plain, 1 = Obscured, 2 = Hidden), or undefined if it isn't tracked.
|
|
63
|
+
* */
|
|
64
|
+
checkSanitization: (el: Node) => import("./app/sanitizer.js").SanitizeLevel | undefined;
|
|
49
65
|
use<T>(fn: (app: App | null, options?: Partial<Options>) => T): T;
|
|
50
66
|
isActive(): boolean;
|
|
51
67
|
/**
|
|
@@ -15,13 +15,15 @@ declare class Batcher {
|
|
|
15
15
|
private readonly backendUrl;
|
|
16
16
|
private readonly getToken;
|
|
17
17
|
private readonly init;
|
|
18
|
+
private readonly standalone;
|
|
18
19
|
private readonly autosendInterval;
|
|
19
20
|
private readonly retryTimeout;
|
|
20
21
|
private readonly retryLimit;
|
|
21
22
|
private readonly apiEdp;
|
|
22
23
|
private batch;
|
|
23
24
|
private intervalId;
|
|
24
|
-
|
|
25
|
+
private stopped;
|
|
26
|
+
constructor(backendUrl: string, getToken: () => string | null, init: () => Promise<void>, standalone: boolean);
|
|
25
27
|
getBatches(): {
|
|
26
28
|
data: {
|
|
27
29
|
user_actions: PeopleEvent[];
|
|
@@ -38,8 +40,11 @@ declare class Batcher {
|
|
|
38
40
|
dedupePeopleEvents(): PeopleEvent[];
|
|
39
41
|
private squashPeopleEvents;
|
|
40
42
|
private sendBatch;
|
|
43
|
+
private paused;
|
|
44
|
+
private onVisibilityChange;
|
|
41
45
|
startAutosend(): void;
|
|
42
46
|
flush(): void;
|
|
43
47
|
stop(): void;
|
|
48
|
+
restart(): void;
|
|
44
49
|
}
|
|
45
50
|
export default Batcher;
|
|
@@ -51,6 +51,11 @@ export default class Analytics {
|
|
|
51
51
|
_getToken: () => string | null;
|
|
52
52
|
_getTimestamp: () => number;
|
|
53
53
|
init: () => Promise<void>;
|
|
54
|
+
/**
|
|
55
|
+
* Used by tracker when running in blundled mode
|
|
56
|
+
*/
|
|
57
|
+
onStart: () => void;
|
|
58
|
+
onStop: () => void;
|
|
54
59
|
reset: () => void;
|
|
55
60
|
/**
|
|
56
61
|
* COMPATIBILITY LAYER
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type App from '../app/index.js';
|
|
2
2
|
type TextFieldElement = HTMLInputElement | HTMLTextAreaElement;
|
|
3
|
-
export declare function getInputLabel(node: TextFieldElement): string;
|
|
3
|
+
export declare function getInputLabel(node: TextFieldElement, customAttributes?: string[]): string;
|
|
4
4
|
export declare const InputMode: {
|
|
5
5
|
readonly Plain: 0;
|
|
6
6
|
readonly Obscured: 1;
|
|
@@ -29,6 +29,7 @@ export interface Options {
|
|
|
29
29
|
* will override other settings.
|
|
30
30
|
* */
|
|
31
31
|
inputPrivacyMode: InputModeT;
|
|
32
|
+
customAttributes?: string[];
|
|
32
33
|
}
|
|
33
34
|
export default function (app: App, opts: Partial<Options>): void;
|
|
34
35
|
export {};
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
+
import TagMatcher, { type Tag } from './tagMatcher.js';
|
|
1
2
|
export declare const WATCHED_MARKERS_KEY = "__or__watched_markers__";
|
|
2
3
|
declare class MarkerWatcher {
|
|
3
4
|
interval: ReturnType<typeof setInterval> | null;
|
|
4
|
-
tags:
|
|
5
|
-
|
|
6
|
-
selector: string;
|
|
7
|
-
}[];
|
|
5
|
+
tags: Tag[];
|
|
6
|
+
readonly matcher: TagMatcher;
|
|
8
7
|
observer: IntersectionObserver;
|
|
9
8
|
private readonly sessionStorage;
|
|
10
9
|
private readonly errLog;
|
|
@@ -15,10 +14,7 @@ declare class MarkerWatcher {
|
|
|
15
14
|
onMarkerHit: (markerId: number) => void;
|
|
16
15
|
});
|
|
17
16
|
fetchTags(ingest: string, token: string): Promise<void>;
|
|
18
|
-
setTags(tags:
|
|
19
|
-
id: number;
|
|
20
|
-
selector: string;
|
|
21
|
-
}[]): void;
|
|
17
|
+
setTags(tags: Tag[]): void;
|
|
22
18
|
onMarkerRendered(markerId: number): void;
|
|
23
19
|
clear(): void;
|
|
24
20
|
}
|
|
@@ -8,6 +8,7 @@ export interface MouseHandlerOptions {
|
|
|
8
8
|
* default 7 = 210ms
|
|
9
9
|
* */
|
|
10
10
|
trackingOffset?: number;
|
|
11
|
+
customAttributes?: string[];
|
|
11
12
|
}
|
|
12
13
|
export default function (app: App, options?: MouseHandlerOptions): void;
|
|
13
14
|
export declare function getCSSPath(el: any): string | false;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export type Tag = {
|
|
2
|
+
id: number;
|
|
3
|
+
selector: string;
|
|
4
|
+
location?: string;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Two-tier tag matching:
|
|
8
|
+
* 1. Fast fingerprint lookup by id, data-attr,
|
|
9
|
+
* or class from the selector's last segment
|
|
10
|
+
* 2. Fallback iteration using native element.matches()
|
|
11
|
+
*/
|
|
12
|
+
declare class TagMatcher {
|
|
13
|
+
private tags;
|
|
14
|
+
private byId;
|
|
15
|
+
private byDataAttr;
|
|
16
|
+
private byClass;
|
|
17
|
+
private fallback;
|
|
18
|
+
setTags(tags: Tag[]): void;
|
|
19
|
+
getTags(): Tag[];
|
|
20
|
+
/** Match element, its parent, or direct children against known tag selectors */
|
|
21
|
+
match(el: Element): Tag | null;
|
|
22
|
+
private matchExact;
|
|
23
|
+
clear(): void;
|
|
24
|
+
}
|
|
25
|
+
export declare function matchesLocation(tag: {
|
|
26
|
+
location?: string;
|
|
27
|
+
}): boolean;
|
|
28
|
+
export default TagMatcher;
|
|
@@ -97,6 +97,30 @@ declare class BrowserSingleton {
|
|
|
97
97
|
forceFlushBatch(): void;
|
|
98
98
|
getSessionMeta(): import("./app/session.js").SessionInfo | null;
|
|
99
99
|
getTabId(): string | null;
|
|
100
|
+
/**
|
|
101
|
+
* Re-evaluates sanitization against the current DOM and re-emits whatever
|
|
102
|
+
* changed, updating already-recorded nodes mid-session. Call after toggling
|
|
103
|
+
* `data-oxvosessions-*` attributes or after changing whatever your `domSanitizer`
|
|
104
|
+
* keys on (class/id/etc).
|
|
105
|
+
*
|
|
106
|
+
* @param el - the highest node you changed; omit to re-scan the whole document.
|
|
107
|
+
* */
|
|
108
|
+
resanitize(el?: Element): void;
|
|
109
|
+
/**
|
|
110
|
+
* Returns the sanitization level the tracker currently has for a node
|
|
111
|
+
* (0 = Plain, 1 = Obscured, 2 = Hidden), or undefined if it isn't tracked.
|
|
112
|
+
* */
|
|
113
|
+
checkSanitization(el: Node): import("./index.js").SanitizeLevel | undefined;
|
|
114
|
+
incident(options: {
|
|
115
|
+
label?: string;
|
|
116
|
+
startTime: number;
|
|
117
|
+
endTime?: number;
|
|
118
|
+
}): void;
|
|
119
|
+
/**
|
|
120
|
+
* Use custom token for analytics events without session recording.
|
|
121
|
+
* */
|
|
122
|
+
setAnalyticsToken(token: string): void;
|
|
123
|
+
getAnalyticsToken(): string | undefined;
|
|
100
124
|
}
|
|
101
125
|
declare const browser: BrowserSingleton;
|
|
102
126
|
export default browser;
|
package/dist/lib/main/utils.d.ts
CHANGED
|
@@ -11,6 +11,8 @@ export declare const DOCS_HOST = "https://docs.oxvo.com";
|
|
|
11
11
|
export declare function isLoopbackHost(hostname: string): boolean;
|
|
12
12
|
export declare function canUseTrackerOrigin(protocol: string, hostname: string, devAllowInsecure?: boolean): boolean;
|
|
13
13
|
export declare function deprecationWarn(nameOfFeature: string, useInstead: string, docsPath?: string): void;
|
|
14
|
+
export declare function getCustomAttributeLabel(e: Element, customAttributes?: string[]): string;
|
|
15
|
+
export declare function getClassSelector(e: Element): string;
|
|
14
16
|
export declare function getLabelAttribute(e: Element): string | null;
|
|
15
17
|
export declare function hasOxvoSessionsAttribute(e: Element, attr: string): boolean;
|
|
16
18
|
/**
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import Message from './messages.gen.js';
|
|
2
|
+
export type DataType = 'player' | 'assets' | 'devtools' | 'analytics';
|
|
2
3
|
export interface Options {
|
|
3
4
|
connAttemptCount?: number;
|
|
4
5
|
connAttemptGap?: number;
|
|
@@ -10,18 +11,22 @@ type Start = {
|
|
|
10
11
|
timestamp: number;
|
|
11
12
|
url: string;
|
|
12
13
|
tabId: string;
|
|
14
|
+
localDebug?: boolean;
|
|
13
15
|
} & Options;
|
|
14
16
|
type Auth = {
|
|
15
17
|
type: 'auth';
|
|
16
18
|
token: string;
|
|
17
19
|
beaconSizeLimit?: number;
|
|
20
|
+
protocolVersion?: number;
|
|
18
21
|
};
|
|
19
22
|
export type ToWorkerData = null | 'stop' | Start | Auth | Array<Message> | {
|
|
20
23
|
type: 'compressed';
|
|
21
24
|
batch: Uint8Array;
|
|
25
|
+
dataType: DataType;
|
|
22
26
|
} | {
|
|
23
27
|
type: 'uncompressed';
|
|
24
28
|
batch: Uint8Array;
|
|
29
|
+
dataType: DataType;
|
|
25
30
|
} | 'forceFlushBatch' | 'closing' | 'check_queue';
|
|
26
31
|
type Failure = {
|
|
27
32
|
type: 'failure';
|
|
@@ -30,8 +35,14 @@ type Failure = {
|
|
|
30
35
|
type QEmpty = {
|
|
31
36
|
type: 'queue_empty';
|
|
32
37
|
};
|
|
38
|
+
type LocalSave = {
|
|
39
|
+
type: 'local_save';
|
|
40
|
+
name: string;
|
|
41
|
+
batch: Uint8Array;
|
|
42
|
+
};
|
|
33
43
|
export type FromWorkerData = 'a_stop' | 'a_start' | Failure | 'not_init' | {
|
|
34
44
|
type: 'compress';
|
|
35
45
|
batch: Uint8Array;
|
|
36
|
-
|
|
46
|
+
dataType: DataType;
|
|
47
|
+
} | QEmpty | LocalSave;
|
|
37
48
|
export {};
|
|
@@ -61,7 +61,6 @@ export declare const enum Type {
|
|
|
61
61
|
JSException = 78,
|
|
62
62
|
Zustand = 79,
|
|
63
63
|
BatchMetadata = 81,
|
|
64
|
-
PartitionedMessage = 82,
|
|
65
64
|
NetworkRequest = 83,
|
|
66
65
|
WSChannel = 84,
|
|
67
66
|
ResourceTiming = 85,
|
|
@@ -442,11 +441,6 @@ export type BatchMetadata = [
|
|
|
442
441
|
number,
|
|
443
442
|
string
|
|
444
443
|
];
|
|
445
|
-
export type PartitionedMessage = [
|
|
446
|
-
Type.PartitionedMessage,
|
|
447
|
-
number,
|
|
448
|
-
number
|
|
449
|
-
];
|
|
450
444
|
export type NetworkRequest = [
|
|
451
445
|
Type.NetworkRequest,
|
|
452
446
|
string,
|
|
@@ -583,5 +577,8 @@ export type WebVitals = [
|
|
|
583
577
|
string,
|
|
584
578
|
string
|
|
585
579
|
];
|
|
586
|
-
|
|
580
|
+
export declare const ASSET_MESSAGES: ReadonlySet<number>;
|
|
581
|
+
export declare const DEVTOOLS_MESSAGES: ReadonlySet<number>;
|
|
582
|
+
export declare const ANALYTICS_MESSAGES: ReadonlySet<number>;
|
|
583
|
+
type Message = Timestamp | SetPageLocationDeprecated | SetViewportSize | SetViewportScroll | CreateDocument | CreateElementNode | CreateTextNode | MoveNode | RemoveNode | SetNodeAttribute | RemoveNodeAttribute | SetNodeData | SetNodeScroll | SetInputTarget | SetInputValue | SetInputChecked | MouseMove | NetworkRequestDeprecated | ConsoleLog | PageLoadTiming | PageRenderTiming | CustomEvent | UserID | UserAnonymousID | Metadata | StringDictGlobal | SetNodeAttributeDictGlobal | NodeAnimationResult | Profiler | OTable | StateAction | ReduxDeprecated | Vuex | MobX | NgRx | GraphQLDeprecated | PerformanceTrack | StringDictDeprecated | SetNodeAttributeDictDeprecated | StringDict | SetNodeAttributeDict | ResourceTimingDeprecatedDeprecated | ConnectionInformation | SetPageVisibility | LoadFontFace | SetNodeFocus | SetNodeAttributeURLBased | SetCSSDataURLBased | TechnicalInfo | CustomIssue | SetNodeSlot | MouseClick | MouseClickDeprecated | CreateIFrameDocument | AdoptedSSReplaceURLBased | AdoptedSSInsertRuleURLBased | AdoptedSSDeleteRule | AdoptedSSAddOwner | AdoptedSSRemoveOwner | JSException | Zustand | BatchMetadata | NetworkRequest | WSChannel | ResourceTiming | Incident | LongAnimationTask | InputChange | SelectionChange | MouseThrashing | UnbindNodes | ResourceTimingDeprecated | TabChange | TabData | CanvasNode | TagTrigger | Redux | SetPageLocation | GraphQL | WebVitals;
|
|
587
584
|
export default Message;
|
|
@@ -5,6 +5,8 @@ interface Options {
|
|
|
5
5
|
isDebug?: boolean;
|
|
6
6
|
fixedScaling?: boolean;
|
|
7
7
|
useAnimationFrame?: boolean;
|
|
8
|
+
framesSupport?: boolean;
|
|
9
|
+
/** @deprecated webp is the default format for pipeline optimization */
|
|
8
10
|
fileExt?: 'webp' | 'png' | 'jpeg' | 'avif';
|
|
9
11
|
}
|
|
10
12
|
declare class CanvasRecorder {
|
|
@@ -22,6 +24,12 @@ declare class CanvasRecorder {
|
|
|
22
24
|
private isProcessingQueue;
|
|
23
25
|
constructor(app: App, options: Options);
|
|
24
26
|
startTracking(): void;
|
|
27
|
+
/**
|
|
28
|
+
* Reacts to a runtime sanitization change on a canvas: stop capturing if it
|
|
29
|
+
* just became masked, start if it just became visible. Already-sent frames
|
|
30
|
+
* cannot be retracted, so escalation only stops future capture.
|
|
31
|
+
*/
|
|
32
|
+
resanitizeCanvas: (node: Node, id: number) => void;
|
|
25
33
|
restartTracking: () => void;
|
|
26
34
|
captureCanvas: (node: Node) => void;
|
|
27
35
|
recordCanvas: (node: Node, id: number) => void;
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import type { Options as WebworkerOptions } from '../../common/interaction.js';
|
|
2
2
|
import AttributeSender from '../modules/attributeSender.js';
|
|
3
3
|
import type { Options as NetworkOptions } from '../modules/network.js';
|
|
4
|
+
import type TagMatcher from '../modules/tagMatcher.js';
|
|
4
5
|
import Logger, { ILogLevel } from './logger.js';
|
|
5
6
|
import Message from './messages.gen.js';
|
|
6
7
|
import Nodes from './nodes/index.js';
|
|
7
8
|
import type { Options as ObserverOptions } from './observer/top_observer.js';
|
|
8
9
|
import Observer from './observer/top_observer.js';
|
|
9
10
|
import type { Options as SanitizerOptions } from './sanitizer.js';
|
|
10
|
-
import Sanitizer from './sanitizer.js';
|
|
11
|
+
import Sanitizer, { SanitizeLevel } from './sanitizer.js';
|
|
11
12
|
import type { Options as SessOptions } from './session.js';
|
|
12
13
|
import Session from './session.js';
|
|
13
14
|
import Ticker from './ticker.js';
|
|
@@ -64,6 +65,7 @@ type AppOptions = {
|
|
|
64
65
|
__is_snippet: boolean;
|
|
65
66
|
__debug_report_edp: string | null;
|
|
66
67
|
__debug__?: ILogLevel;
|
|
68
|
+
__local_debug?: boolean;
|
|
67
69
|
localStorage: Storage | null;
|
|
68
70
|
sessionStorage: Storage | null;
|
|
69
71
|
forceSingleTab?: boolean;
|
|
@@ -129,6 +131,7 @@ export default class App {
|
|
|
129
131
|
readonly ticker: Ticker;
|
|
130
132
|
readonly projectKey: string;
|
|
131
133
|
readonly sanitizer: Sanitizer;
|
|
134
|
+
private readonly resanitizeCallbacks;
|
|
132
135
|
readonly debug: Logger;
|
|
133
136
|
readonly notify: Logger;
|
|
134
137
|
readonly session: Session;
|
|
@@ -159,6 +162,7 @@ export default class App {
|
|
|
159
162
|
private canvasRecorder;
|
|
160
163
|
private conditionsManager;
|
|
161
164
|
private readonly markerWatcher;
|
|
165
|
+
get tagMatcher(): TagMatcher;
|
|
162
166
|
private canStart;
|
|
163
167
|
private rootId;
|
|
164
168
|
private pageFrames;
|
|
@@ -170,11 +174,10 @@ export default class App {
|
|
|
170
174
|
parentActive: boolean;
|
|
171
175
|
checkStatus: () => boolean;
|
|
172
176
|
parentCrossDomainFrameListener: (event: MessageEvent) => void;
|
|
173
|
-
/**
|
|
174
|
-
* context ids for iframes,
|
|
175
|
-
* order is not so important as long as its consistent
|
|
176
|
-
* */
|
|
177
177
|
trackedFrames: string[];
|
|
178
|
+
private frameLastSeen;
|
|
179
|
+
private readonly FRAME_STALE_MS;
|
|
180
|
+
private pruneStaleFrames;
|
|
178
181
|
crossDomainIframeListener: (event: MessageEvent) => void;
|
|
179
182
|
/**
|
|
180
183
|
* { command : [remaining iframes] }
|
|
@@ -290,8 +293,13 @@ export default class App {
|
|
|
290
293
|
* */
|
|
291
294
|
uploadOfflineRecording(): Promise<void>;
|
|
292
295
|
prevOpts: StartOptions;
|
|
296
|
+
private userStartCallback?;
|
|
293
297
|
private _start;
|
|
294
298
|
restartCanvasTracking: () => void;
|
|
299
|
+
attachResanitizeCallback: (cb: (node: Node, id: number) => void) => void;
|
|
300
|
+
callResanitizeCallbacks: (node: Node, id: number) => void;
|
|
301
|
+
resanitize: (el?: Element) => void;
|
|
302
|
+
checkSanitization: (el: Node) => SanitizeLevel | undefined;
|
|
295
303
|
flushBuffer: (buffer: Message[]) => Promise<unknown>;
|
|
296
304
|
waitStart(): Promise<unknown>;
|
|
297
305
|
waitStarted(): Promise<unknown>;
|
|
@@ -62,7 +62,6 @@ export declare function AdoptedSSRemoveOwner(sheetID: number, id: number): Messa
|
|
|
62
62
|
export declare function JSException(name: string, message: string, payload: string, metadata: string): Messages.JSException;
|
|
63
63
|
export declare function Zustand(mutation: string, state: string): Messages.Zustand;
|
|
64
64
|
export declare function BatchMetadata(version: number, pageNo: number, firstIndex: number, timestamp: number, location: string): Messages.BatchMetadata;
|
|
65
|
-
export declare function PartitionedMessage(partNo: number, partTotal: number): Messages.PartitionedMessage;
|
|
66
65
|
export declare function NetworkRequest(type: string, method: string, url: string, request: string, response: string, status: number, timestamp: number, duration: number, transferredBodySize: number): Messages.NetworkRequest;
|
|
67
66
|
export declare function WSChannel(chType: string, channelName: string, data: string, timestamp: number, dir: string, messageType: string): Messages.WSChannel;
|
|
68
67
|
export declare function ResourceTiming(timestamp: number, duration: number, ttfb: number, headerSize: number, encodedBodySize: number, decodedBodySize: number, url: string, initiator: string, transferredSize: number, cached: boolean, queueing: number, dnsLookup: number, initialConnection: number, ssl: number, contentDownload: number, total: number, stalled: number): Messages.ResourceTiming;
|
|
@@ -28,6 +28,12 @@ export default abstract class Observer {
|
|
|
28
28
|
private readonly inlineRemoteCss;
|
|
29
29
|
private readonly inlinerOptions;
|
|
30
30
|
private readonly domParser;
|
|
31
|
+
/**
|
|
32
|
+
* Bumped on every disconnect(). Stale async CSS-inlining callbacks from a
|
|
33
|
+
* previous session (e.g. agent reload → tracker restart) compare against
|
|
34
|
+
* this and bail instead of sending messages that reference vanished node ids.
|
|
35
|
+
*/
|
|
36
|
+
private generation;
|
|
31
37
|
constructor(app: App, isTopContext?: boolean, options?: Options);
|
|
32
38
|
private clear;
|
|
33
39
|
/**
|
|
@@ -47,6 +53,16 @@ export default abstract class Observer {
|
|
|
47
53
|
private commitNode;
|
|
48
54
|
private commitNodes;
|
|
49
55
|
protected observeRoot(node: Node, beforeCommit: (id?: number) => unknown, nodeToBind?: Node): void;
|
|
56
|
+
/**
|
|
57
|
+
* Re-evaluates sanitization for every tracked node in `root`'s subtree against
|
|
58
|
+
* the current DOM and re-emits whatever changed. Pass the highest node you
|
|
59
|
+
* changed (or the document root) so inherited levels propagate correctly.
|
|
60
|
+
*/
|
|
61
|
+
resanitizeSubtree(root: Node): void;
|
|
62
|
+
private resanitizeNode;
|
|
63
|
+
private recreateSubtree;
|
|
64
|
+
private clearSubtreeRegistration;
|
|
65
|
+
private reemitNode;
|
|
50
66
|
disconnect(): void;
|
|
51
67
|
}
|
|
52
68
|
export {};
|
|
@@ -35,8 +35,7 @@ export interface Options {
|
|
|
35
35
|
}
|
|
36
36
|
export declare const stringWiper: (input: string) => string;
|
|
37
37
|
export default class Sanitizer {
|
|
38
|
-
private readonly
|
|
39
|
-
private readonly hidden;
|
|
38
|
+
private readonly levels;
|
|
40
39
|
private readonly options;
|
|
41
40
|
readonly maskAllByDefault: boolean;
|
|
42
41
|
private readonly app;
|
|
@@ -44,7 +43,10 @@ export default class Sanitizer {
|
|
|
44
43
|
app: App;
|
|
45
44
|
options?: Partial<Options>;
|
|
46
45
|
});
|
|
47
|
-
|
|
46
|
+
computeLevel(node: Node, parentLevel: SanitizeLevel): SanitizeLevel;
|
|
47
|
+
getLevel(id: number): SanitizeLevel;
|
|
48
|
+
setLevel(id: number, level: SanitizeLevel): SanitizeLevel;
|
|
49
|
+
handleNode(id: number, parentID: number, node: Node): void;
|
|
48
50
|
sanitize(id: number, data: string): string;
|
|
49
51
|
isObscured(id: number): boolean;
|
|
50
52
|
isHidden(id: number): boolean;
|
|
@@ -27,6 +27,7 @@ export type Options = Partial<AppOptions & ConsoleOptions & ExceptionOptions & I
|
|
|
27
27
|
resetTabOnWindowOpen?: boolean;
|
|
28
28
|
networkCapture?: Partial<NetworkOptions>;
|
|
29
29
|
mouse?: Partial<MouseHandlerOptions>;
|
|
30
|
+
customAttributes?: string[];
|
|
30
31
|
devAllowInsecure?: boolean;
|
|
31
32
|
css: CssRulesOptions;
|
|
32
33
|
webAnimations?: WapOptions;
|
|
@@ -46,6 +47,21 @@ export default class API {
|
|
|
46
47
|
checkDoNotTrack: () => boolean | undefined;
|
|
47
48
|
signalStartIssue: (reason: string, missingApi: string[]) => void;
|
|
48
49
|
restartCanvasTracking: () => void;
|
|
50
|
+
/**
|
|
51
|
+
* Re-evaluates sanitization against the current DOM and re-emits whatever
|
|
52
|
+
* changed, updating already-recorded nodes mid-session. Call after toggling
|
|
53
|
+
* `data-oxvosessions-*` attributes or after changing whatever your `domSanitizer`
|
|
54
|
+
* keys on (class/id/etc).
|
|
55
|
+
*
|
|
56
|
+
* @param el - the highest node you changed; omit to re-scan the whole document;
|
|
57
|
+
* scanning the entire doc is O(dom size)
|
|
58
|
+
* */
|
|
59
|
+
resanitize: (el?: Element) => void;
|
|
60
|
+
/**
|
|
61
|
+
* Returns the sanitization level the tracker currently has for a node
|
|
62
|
+
* (0 = Plain, 1 = Obscured, 2 = Hidden), or undefined if it isn't tracked.
|
|
63
|
+
* */
|
|
64
|
+
checkSanitization: (el: Node) => import("./app/sanitizer.js").SanitizeLevel | undefined;
|
|
49
65
|
use<T>(fn: (app: App | null, options?: Partial<Options>) => T): T;
|
|
50
66
|
isActive(): boolean;
|
|
51
67
|
/**
|
|
@@ -15,13 +15,15 @@ declare class Batcher {
|
|
|
15
15
|
private readonly backendUrl;
|
|
16
16
|
private readonly getToken;
|
|
17
17
|
private readonly init;
|
|
18
|
+
private readonly standalone;
|
|
18
19
|
private readonly autosendInterval;
|
|
19
20
|
private readonly retryTimeout;
|
|
20
21
|
private readonly retryLimit;
|
|
21
22
|
private readonly apiEdp;
|
|
22
23
|
private batch;
|
|
23
24
|
private intervalId;
|
|
24
|
-
|
|
25
|
+
private stopped;
|
|
26
|
+
constructor(backendUrl: string, getToken: () => string | null, init: () => Promise<void>, standalone: boolean);
|
|
25
27
|
getBatches(): {
|
|
26
28
|
data: {
|
|
27
29
|
user_actions: PeopleEvent[];
|
|
@@ -38,8 +40,11 @@ declare class Batcher {
|
|
|
38
40
|
dedupePeopleEvents(): PeopleEvent[];
|
|
39
41
|
private squashPeopleEvents;
|
|
40
42
|
private sendBatch;
|
|
43
|
+
private paused;
|
|
44
|
+
private onVisibilityChange;
|
|
41
45
|
startAutosend(): void;
|
|
42
46
|
flush(): void;
|
|
43
47
|
stop(): void;
|
|
48
|
+
restart(): void;
|
|
44
49
|
}
|
|
45
50
|
export default Batcher;
|
|
@@ -51,6 +51,11 @@ export default class Analytics {
|
|
|
51
51
|
_getToken: () => string | null;
|
|
52
52
|
_getTimestamp: () => number;
|
|
53
53
|
init: () => Promise<void>;
|
|
54
|
+
/**
|
|
55
|
+
* Used by tracker when running in blundled mode
|
|
56
|
+
*/
|
|
57
|
+
onStart: () => void;
|
|
58
|
+
onStop: () => void;
|
|
54
59
|
reset: () => void;
|
|
55
60
|
/**
|
|
56
61
|
* COMPATIBILITY LAYER
|