writetrack 0.1.0 → 0.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/README.md +28 -21
- package/dist/browser/index.js +1 -1
- package/dist/browser/pipes.js +1 -0
- package/dist/esm/index.d.ts +31 -203
- package/dist/esm/index.js +1 -1
- package/dist/esm/pipes.d.ts +1 -0
- package/dist/esm/pipes.js +1 -0
- package/dist/index.cjs +1 -1
- package/dist/pipes.cjs +1 -0
- package/dist/react/index.d.ts +21 -296
- package/dist/vue/index.d.ts +21 -296
- package/package.json +11 -1
package/dist/react/index.d.ts
CHANGED
|
@@ -1,300 +1,24 @@
|
|
|
1
|
+
import { WriteTrack } from 'writetrack';
|
|
1
2
|
import { RefObject } from 'react';
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
* Defines the structure for raw input events collected during typing sessions.
|
|
7
|
-
* This is the foundation layer containing unprocessed user interaction data.
|
|
8
|
-
*/
|
|
9
|
-
/**
|
|
10
|
-
* Raw session data containing all collected events
|
|
11
|
-
*/
|
|
12
|
-
interface RawEventData {
|
|
13
|
-
/** Primary keystroke events */
|
|
14
|
-
events: KeystrokeEvent[];
|
|
15
|
-
/** Clipboard operation events (optional) */
|
|
16
|
-
clipboardEvents?: ClipboardEvent[];
|
|
17
|
-
/** Undo/redo operation events (optional) */
|
|
18
|
-
undoRedoEvents?: UndoRedoEvent[];
|
|
19
|
-
/** Text selection events (optional) */
|
|
20
|
-
selectionEvents?: SelectionEvent[];
|
|
21
|
-
/** Final text that was typed */
|
|
22
|
-
rawText: string;
|
|
23
|
-
/** Session start time (unix timestamp) */
|
|
24
|
-
sessionStartTime: number;
|
|
25
|
-
/** Session end time (unix timestamp) */
|
|
26
|
-
sessionEndTime: number;
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* Individual keystroke event
|
|
30
|
-
*/
|
|
31
|
-
interface KeystrokeEvent {
|
|
32
|
-
/** Key identifier (character or key name) */
|
|
33
|
-
key: string;
|
|
34
|
-
/** Physical key code */
|
|
35
|
-
code: string;
|
|
36
|
-
/** Event type */
|
|
37
|
-
type: 'keydown' | 'keyup';
|
|
38
|
-
/** High-precision timestamp (performance.now()) */
|
|
39
|
-
timestamp: number;
|
|
40
|
-
/** Key hold duration (for keyup events) */
|
|
41
|
-
dwellTime?: number;
|
|
42
|
-
/** Time to next key press (for keydown events) */
|
|
43
|
-
flightTime?: number;
|
|
44
|
-
/** Whether this keystroke was part of a correction */
|
|
45
|
-
isCorrection?: boolean;
|
|
46
|
-
/** Whether this keystroke was part of a typing burst */
|
|
47
|
-
isBurst?: boolean;
|
|
48
|
-
/** Window focus state at time of keystroke */
|
|
49
|
-
windowFocused: boolean;
|
|
50
|
-
/** Time since last mouse interaction */
|
|
51
|
-
timeSinceLastMouse: number;
|
|
52
|
-
/** Character position in text at time of keystroke */
|
|
53
|
-
cursorPosition?: number;
|
|
54
|
-
/** Modifier key states */
|
|
55
|
-
modifiers?: ModifierState;
|
|
56
|
-
}
|
|
57
|
-
/**
|
|
58
|
-
* Modifier key states
|
|
59
|
-
*/
|
|
60
|
-
interface ModifierState {
|
|
61
|
-
ctrl: boolean;
|
|
62
|
-
alt: boolean;
|
|
63
|
-
shift: boolean;
|
|
64
|
-
meta: boolean;
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* Clipboard operation event
|
|
68
|
-
*/
|
|
69
|
-
interface ClipboardEvent {
|
|
70
|
-
/** Clipboard operation type */
|
|
71
|
-
type: 'copy' | 'paste' | 'cut';
|
|
72
|
-
/** Event timestamp */
|
|
73
|
-
timestamp: number;
|
|
74
|
-
/** Text position where operation occurred */
|
|
75
|
-
position: number;
|
|
76
|
-
/** Length of text affected */
|
|
77
|
-
length: number;
|
|
78
|
-
/** Keyboard shortcut used */
|
|
79
|
-
shortcut: string;
|
|
80
|
-
/** Actual clipboard content (optional for privacy) */
|
|
81
|
-
content?: string;
|
|
82
|
-
/** Text state before operation (optional) */
|
|
83
|
-
beforeText?: string;
|
|
84
|
-
/** Text state after operation (optional) */
|
|
85
|
-
afterText?: string;
|
|
86
|
-
/** Text that was replaced by paste (optional) */
|
|
87
|
-
replacedText?: string;
|
|
88
|
-
/** Range of text replaced by paste (optional) */
|
|
89
|
-
replacedRange?: {
|
|
90
|
-
start: number;
|
|
91
|
-
end: number;
|
|
92
|
-
};
|
|
93
|
-
}
|
|
94
|
-
/**
|
|
95
|
-
* Text selection event
|
|
96
|
-
*/
|
|
97
|
-
interface SelectionEvent {
|
|
98
|
-
/** Event type */
|
|
99
|
-
type: 'select';
|
|
100
|
-
/** Event timestamp */
|
|
101
|
-
timestamp: number;
|
|
102
|
-
/** Start position of selection */
|
|
103
|
-
startPosition: number;
|
|
104
|
-
/** End position of selection */
|
|
105
|
-
endPosition: number;
|
|
106
|
-
/** Length of selected text */
|
|
107
|
-
selectedLength: number;
|
|
108
|
-
/** Selected text content (optional for privacy) */
|
|
109
|
-
selectedText?: string;
|
|
110
|
-
/** How the selection was made */
|
|
111
|
-
method: 'mouse' | 'keyboard' | 'programmatic';
|
|
112
|
-
}
|
|
113
|
-
/**
|
|
114
|
-
* Undo/Redo operation event
|
|
115
|
-
*/
|
|
116
|
-
interface UndoRedoEvent {
|
|
117
|
-
/** Operation type */
|
|
118
|
-
type: 'undo' | 'redo';
|
|
119
|
-
/** Event timestamp */
|
|
120
|
-
timestamp: number;
|
|
121
|
-
/** Keyboard shortcut used */
|
|
122
|
-
shortcut: string;
|
|
123
|
-
/** Text state before operation */
|
|
124
|
-
beforeText: string;
|
|
125
|
-
/** Text state after operation */
|
|
126
|
-
afterText: string;
|
|
4
|
+
export interface UseWriteTrackOptions {
|
|
5
|
+
/** Auto-start tracking when element is available (default: true) */
|
|
6
|
+
autoStart?: boolean;
|
|
127
7
|
}
|
|
128
8
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
/**
|
|
135
|
-
|
|
136
|
-
*/
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
/** Target element type (e.g., 'textarea', 'input', 'div') */
|
|
141
|
-
targetElement: string;
|
|
142
|
-
/** Collection timestamp (ISO8601) */
|
|
143
|
-
timestamp: string;
|
|
144
|
-
/** Session duration in milliseconds */
|
|
145
|
-
duration: number;
|
|
146
|
-
}
|
|
147
|
-
/**
|
|
148
|
-
* Tool identification
|
|
149
|
-
*/
|
|
150
|
-
interface ToolInfo {
|
|
151
|
-
/** Tool name */
|
|
152
|
-
name: string;
|
|
153
|
-
/** Tool version */
|
|
154
|
-
version: string;
|
|
155
|
-
/** Tool category (internal use — set by training pipeline, not capture SDK) */
|
|
156
|
-
category?: 'human' | 'selenium' | 'playwright' | 'puppeteer' | 'cypress' | 'webdriverio' | 'other';
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
/**
|
|
160
|
-
* WriteTrack Data Schema v2.0.0 - Main Schema Definition
|
|
161
|
-
*
|
|
162
|
-
* This is the unified, versioned schema for all WriteTrack data structures.
|
|
163
|
-
* It provides a single source of truth for data formats across the entire system.
|
|
164
|
-
*/
|
|
165
|
-
|
|
166
|
-
/**
|
|
167
|
-
* Main WriteTrack Data Schema Interface
|
|
168
|
-
* This is the top-level structure for all WriteTrack data exports
|
|
169
|
-
*/
|
|
170
|
-
interface WriteTrackDataSchema {
|
|
171
|
-
/** Schema version for compatibility and migration */
|
|
172
|
-
version: '2.0.0';
|
|
173
|
-
/** Session metadata */
|
|
174
|
-
metadata: SessionMetadata;
|
|
175
|
-
/** Raw session data (keystrokes, clipboard, selection events) */
|
|
176
|
-
session: RawEventData;
|
|
177
|
-
/** Data quality metrics and validation status */
|
|
178
|
-
quality: DataQualityMetrics;
|
|
179
|
-
/** True when data was captured without a valid license (production use) */
|
|
180
|
-
unlicensed?: boolean;
|
|
181
|
-
}
|
|
182
|
-
/**
|
|
183
|
-
* Data Quality Assessment
|
|
184
|
-
*/
|
|
185
|
-
interface DataQualityMetrics {
|
|
186
|
-
/** Overall data quality score (0-1) */
|
|
187
|
-
overallScore: number;
|
|
188
|
-
/** Data completeness percentage */
|
|
189
|
-
completeness: number;
|
|
190
|
-
/** Event sequence consistency validation */
|
|
191
|
-
sequenceValid: boolean;
|
|
192
|
-
/** Timing data integrity status */
|
|
193
|
-
timingValid: boolean;
|
|
194
|
-
/** Session duration in milliseconds */
|
|
195
|
-
sessionDuration: number;
|
|
196
|
-
/** Total number of events collected */
|
|
197
|
-
eventCount: number;
|
|
198
|
-
/** Quality assessment level */
|
|
199
|
-
qualityLevel: 'POOR' | 'FAIR' | 'GOOD' | 'EXCELLENT';
|
|
200
|
-
/** Quality issues identified */
|
|
201
|
-
issues: string[];
|
|
202
|
-
/** Validation timestamp */
|
|
203
|
-
validatedAt: string;
|
|
9
|
+
export interface UseWriteTrackReturn {
|
|
10
|
+
/** Reset the tracker and clear state */
|
|
11
|
+
reset: () => void;
|
|
12
|
+
/** Start tracking (if autoStart was false) */
|
|
13
|
+
start: () => void;
|
|
14
|
+
/** Stop tracking */
|
|
15
|
+
stop: () => void;
|
|
16
|
+
/** Whether the tracker is currently active */
|
|
17
|
+
isTracking: boolean;
|
|
18
|
+
/** Access to the underlying WriteTrack instance */
|
|
19
|
+
tracker: WriteTrack | null;
|
|
204
20
|
}
|
|
205
21
|
|
|
206
|
-
interface WriteTrackOptions {
|
|
207
|
-
target: HTMLElement;
|
|
208
|
-
license?: string;
|
|
209
|
-
}
|
|
210
|
-
declare class WriteTrack {
|
|
211
|
-
protected keystrokeEvents: KeystrokeEvent[];
|
|
212
|
-
protected clipboardEvents: ClipboardEvent[];
|
|
213
|
-
protected undoRedoEvents: UndoRedoEvent[];
|
|
214
|
-
protected selectionEvents: SelectionEvent[];
|
|
215
|
-
private pendingKeydowns;
|
|
216
|
-
protected lastMouseActivity: number;
|
|
217
|
-
protected sessionStartTime: number;
|
|
218
|
-
protected lastKeyTime: number;
|
|
219
|
-
protected lastKeyUpTime: number;
|
|
220
|
-
protected repeatedKeyTracker: Map<string, number[]>;
|
|
221
|
-
private focusStartTime;
|
|
222
|
-
private lastSelection;
|
|
223
|
-
protected readonly BURST_THRESHOLD = 150;
|
|
224
|
-
protected readonly PAUSE_THRESHOLD = 1000;
|
|
225
|
-
protected readonly CORRECTION_KEYS: Set<string>;
|
|
226
|
-
private readonly targetType;
|
|
227
|
-
protected readonly target: HTMLElement;
|
|
228
|
-
private readonly license?;
|
|
229
|
-
/**
|
|
230
|
-
* Create a WriteTrack instance
|
|
231
|
-
* @param optionsOrTarget - Either an HTMLElement (demo mode) or WriteTrackOptions object
|
|
232
|
-
*/
|
|
233
|
-
constructor(optionsOrTarget: WriteTrackOptions | HTMLElement);
|
|
234
|
-
private validateLicenseAsync;
|
|
235
|
-
private setupEventListeners;
|
|
236
|
-
/**
|
|
237
|
-
* Technique 6: Observe target's parent for childList changes.
|
|
238
|
-
* If target is removed from DOM, stop recording.
|
|
239
|
-
*/
|
|
240
|
-
private setupTargetObserver;
|
|
241
|
-
private isRecordingEnabled;
|
|
242
|
-
private recordKeydown;
|
|
243
|
-
private recordKeyup;
|
|
244
|
-
private recordMouseActivity;
|
|
245
|
-
private recordWindowFocus;
|
|
246
|
-
private detectKeyboardShortcuts;
|
|
247
|
-
private recordClipboardEvent;
|
|
248
|
-
private recordSelection;
|
|
249
|
-
private checkSelectionAfterMouse;
|
|
250
|
-
private recordSelectionChange;
|
|
251
|
-
private getSelection;
|
|
252
|
-
private getSelectedTextLength;
|
|
253
|
-
private recordVisibilityChange;
|
|
254
|
-
private getShortcutString;
|
|
255
|
-
private getCurrentCursorPosition;
|
|
256
|
-
private isMacPlatform;
|
|
257
|
-
private trackRepeatedKey;
|
|
258
|
-
/**
|
|
259
|
-
* Check if the license is valid
|
|
260
|
-
*/
|
|
261
|
-
isLicenseValid(): boolean;
|
|
262
|
-
/**
|
|
263
|
-
* Check if license validation has completed
|
|
264
|
-
*/
|
|
265
|
-
isLicenseValidated(): boolean;
|
|
266
|
-
/**
|
|
267
|
-
* Check if the target element was detached from the DOM
|
|
268
|
-
*/
|
|
269
|
-
isTargetDetached(): boolean;
|
|
270
|
-
start(): void;
|
|
271
|
-
stop(): void;
|
|
272
|
-
getRawEvents(): KeystrokeEvent[];
|
|
273
|
-
getClipboardEvents(): ClipboardEvent[];
|
|
274
|
-
getUndoRedoEvents(): UndoRedoEvent[];
|
|
275
|
-
getSelectionEvents(): SelectionEvent[];
|
|
276
|
-
getSessionDuration(): number;
|
|
277
|
-
getKeystrokeCount(): number;
|
|
278
|
-
getText(): string;
|
|
279
|
-
getData(): WriteTrackDataSchema;
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
interface UseWriteTrackOptions {
|
|
283
|
-
/** Auto-start tracking when element is available (default: true) */
|
|
284
|
-
autoStart?: boolean;
|
|
285
|
-
}
|
|
286
|
-
interface UseWriteTrackReturn {
|
|
287
|
-
/** Reset the tracker and clear state */
|
|
288
|
-
reset: () => void;
|
|
289
|
-
/** Start tracking (if autoStart was false) */
|
|
290
|
-
start: () => void;
|
|
291
|
-
/** Stop tracking */
|
|
292
|
-
stop: () => void;
|
|
293
|
-
/** Whether the tracker is currently active */
|
|
294
|
-
isTracking: boolean;
|
|
295
|
-
/** Access to the underlying WriteTrack instance */
|
|
296
|
-
tracker: WriteTrack | null;
|
|
297
|
-
}
|
|
298
22
|
/**
|
|
299
23
|
* React hook for WriteTrack keystroke analysis
|
|
300
24
|
*
|
|
@@ -307,8 +31,8 @@ interface UseWriteTrackReturn {
|
|
|
307
31
|
* const handleSubmit = (e: FormEvent) => {
|
|
308
32
|
* e.preventDefault();
|
|
309
33
|
* if (tracker) {
|
|
310
|
-
* const
|
|
311
|
-
* console.log('
|
|
34
|
+
* const data = tracker.getData();
|
|
35
|
+
* console.log('Data:', data);
|
|
312
36
|
* }
|
|
313
37
|
* };
|
|
314
38
|
*
|
|
@@ -321,6 +45,7 @@ interface UseWriteTrackReturn {
|
|
|
321
45
|
* }
|
|
322
46
|
* ```
|
|
323
47
|
*/
|
|
324
|
-
declare function useWriteTrack(
|
|
325
|
-
|
|
326
|
-
|
|
48
|
+
export declare function useWriteTrack(
|
|
49
|
+
ref: RefObject<HTMLElement | null>,
|
|
50
|
+
options?: UseWriteTrackOptions
|
|
51
|
+
): UseWriteTrackReturn;
|
package/dist/vue/index.d.ts
CHANGED
|
@@ -1,300 +1,24 @@
|
|
|
1
|
+
import { WriteTrack } from 'writetrack';
|
|
1
2
|
import { Ref, ShallowRef } from 'vue';
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
* Defines the structure for raw input events collected during typing sessions.
|
|
7
|
-
* This is the foundation layer containing unprocessed user interaction data.
|
|
8
|
-
*/
|
|
9
|
-
/**
|
|
10
|
-
* Raw session data containing all collected events
|
|
11
|
-
*/
|
|
12
|
-
interface RawEventData {
|
|
13
|
-
/** Primary keystroke events */
|
|
14
|
-
events: KeystrokeEvent[];
|
|
15
|
-
/** Clipboard operation events (optional) */
|
|
16
|
-
clipboardEvents?: ClipboardEvent[];
|
|
17
|
-
/** Undo/redo operation events (optional) */
|
|
18
|
-
undoRedoEvents?: UndoRedoEvent[];
|
|
19
|
-
/** Text selection events (optional) */
|
|
20
|
-
selectionEvents?: SelectionEvent[];
|
|
21
|
-
/** Final text that was typed */
|
|
22
|
-
rawText: string;
|
|
23
|
-
/** Session start time (unix timestamp) */
|
|
24
|
-
sessionStartTime: number;
|
|
25
|
-
/** Session end time (unix timestamp) */
|
|
26
|
-
sessionEndTime: number;
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* Individual keystroke event
|
|
30
|
-
*/
|
|
31
|
-
interface KeystrokeEvent {
|
|
32
|
-
/** Key identifier (character or key name) */
|
|
33
|
-
key: string;
|
|
34
|
-
/** Physical key code */
|
|
35
|
-
code: string;
|
|
36
|
-
/** Event type */
|
|
37
|
-
type: 'keydown' | 'keyup';
|
|
38
|
-
/** High-precision timestamp (performance.now()) */
|
|
39
|
-
timestamp: number;
|
|
40
|
-
/** Key hold duration (for keyup events) */
|
|
41
|
-
dwellTime?: number;
|
|
42
|
-
/** Time to next key press (for keydown events) */
|
|
43
|
-
flightTime?: number;
|
|
44
|
-
/** Whether this keystroke was part of a correction */
|
|
45
|
-
isCorrection?: boolean;
|
|
46
|
-
/** Whether this keystroke was part of a typing burst */
|
|
47
|
-
isBurst?: boolean;
|
|
48
|
-
/** Window focus state at time of keystroke */
|
|
49
|
-
windowFocused: boolean;
|
|
50
|
-
/** Time since last mouse interaction */
|
|
51
|
-
timeSinceLastMouse: number;
|
|
52
|
-
/** Character position in text at time of keystroke */
|
|
53
|
-
cursorPosition?: number;
|
|
54
|
-
/** Modifier key states */
|
|
55
|
-
modifiers?: ModifierState;
|
|
56
|
-
}
|
|
57
|
-
/**
|
|
58
|
-
* Modifier key states
|
|
59
|
-
*/
|
|
60
|
-
interface ModifierState {
|
|
61
|
-
ctrl: boolean;
|
|
62
|
-
alt: boolean;
|
|
63
|
-
shift: boolean;
|
|
64
|
-
meta: boolean;
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* Clipboard operation event
|
|
68
|
-
*/
|
|
69
|
-
interface ClipboardEvent {
|
|
70
|
-
/** Clipboard operation type */
|
|
71
|
-
type: 'copy' | 'paste' | 'cut';
|
|
72
|
-
/** Event timestamp */
|
|
73
|
-
timestamp: number;
|
|
74
|
-
/** Text position where operation occurred */
|
|
75
|
-
position: number;
|
|
76
|
-
/** Length of text affected */
|
|
77
|
-
length: number;
|
|
78
|
-
/** Keyboard shortcut used */
|
|
79
|
-
shortcut: string;
|
|
80
|
-
/** Actual clipboard content (optional for privacy) */
|
|
81
|
-
content?: string;
|
|
82
|
-
/** Text state before operation (optional) */
|
|
83
|
-
beforeText?: string;
|
|
84
|
-
/** Text state after operation (optional) */
|
|
85
|
-
afterText?: string;
|
|
86
|
-
/** Text that was replaced by paste (optional) */
|
|
87
|
-
replacedText?: string;
|
|
88
|
-
/** Range of text replaced by paste (optional) */
|
|
89
|
-
replacedRange?: {
|
|
90
|
-
start: number;
|
|
91
|
-
end: number;
|
|
92
|
-
};
|
|
93
|
-
}
|
|
94
|
-
/**
|
|
95
|
-
* Text selection event
|
|
96
|
-
*/
|
|
97
|
-
interface SelectionEvent {
|
|
98
|
-
/** Event type */
|
|
99
|
-
type: 'select';
|
|
100
|
-
/** Event timestamp */
|
|
101
|
-
timestamp: number;
|
|
102
|
-
/** Start position of selection */
|
|
103
|
-
startPosition: number;
|
|
104
|
-
/** End position of selection */
|
|
105
|
-
endPosition: number;
|
|
106
|
-
/** Length of selected text */
|
|
107
|
-
selectedLength: number;
|
|
108
|
-
/** Selected text content (optional for privacy) */
|
|
109
|
-
selectedText?: string;
|
|
110
|
-
/** How the selection was made */
|
|
111
|
-
method: 'mouse' | 'keyboard' | 'programmatic';
|
|
112
|
-
}
|
|
113
|
-
/**
|
|
114
|
-
* Undo/Redo operation event
|
|
115
|
-
*/
|
|
116
|
-
interface UndoRedoEvent {
|
|
117
|
-
/** Operation type */
|
|
118
|
-
type: 'undo' | 'redo';
|
|
119
|
-
/** Event timestamp */
|
|
120
|
-
timestamp: number;
|
|
121
|
-
/** Keyboard shortcut used */
|
|
122
|
-
shortcut: string;
|
|
123
|
-
/** Text state before operation */
|
|
124
|
-
beforeText: string;
|
|
125
|
-
/** Text state after operation */
|
|
126
|
-
afterText: string;
|
|
4
|
+
export interface UseWriteTrackOptions {
|
|
5
|
+
/** Auto-start tracking when element is available (default: true) */
|
|
6
|
+
autoStart?: boolean;
|
|
127
7
|
}
|
|
128
8
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
/**
|
|
135
|
-
|
|
136
|
-
*/
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
/** Target element type (e.g., 'textarea', 'input', 'div') */
|
|
141
|
-
targetElement: string;
|
|
142
|
-
/** Collection timestamp (ISO8601) */
|
|
143
|
-
timestamp: string;
|
|
144
|
-
/** Session duration in milliseconds */
|
|
145
|
-
duration: number;
|
|
146
|
-
}
|
|
147
|
-
/**
|
|
148
|
-
* Tool identification
|
|
149
|
-
*/
|
|
150
|
-
interface ToolInfo {
|
|
151
|
-
/** Tool name */
|
|
152
|
-
name: string;
|
|
153
|
-
/** Tool version */
|
|
154
|
-
version: string;
|
|
155
|
-
/** Tool category (internal use — set by training pipeline, not capture SDK) */
|
|
156
|
-
category?: 'human' | 'selenium' | 'playwright' | 'puppeteer' | 'cypress' | 'webdriverio' | 'other';
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
/**
|
|
160
|
-
* WriteTrack Data Schema v2.0.0 - Main Schema Definition
|
|
161
|
-
*
|
|
162
|
-
* This is the unified, versioned schema for all WriteTrack data structures.
|
|
163
|
-
* It provides a single source of truth for data formats across the entire system.
|
|
164
|
-
*/
|
|
165
|
-
|
|
166
|
-
/**
|
|
167
|
-
* Main WriteTrack Data Schema Interface
|
|
168
|
-
* This is the top-level structure for all WriteTrack data exports
|
|
169
|
-
*/
|
|
170
|
-
interface WriteTrackDataSchema {
|
|
171
|
-
/** Schema version for compatibility and migration */
|
|
172
|
-
version: '2.0.0';
|
|
173
|
-
/** Session metadata */
|
|
174
|
-
metadata: SessionMetadata;
|
|
175
|
-
/** Raw session data (keystrokes, clipboard, selection events) */
|
|
176
|
-
session: RawEventData;
|
|
177
|
-
/** Data quality metrics and validation status */
|
|
178
|
-
quality: DataQualityMetrics;
|
|
179
|
-
/** True when data was captured without a valid license (production use) */
|
|
180
|
-
unlicensed?: boolean;
|
|
181
|
-
}
|
|
182
|
-
/**
|
|
183
|
-
* Data Quality Assessment
|
|
184
|
-
*/
|
|
185
|
-
interface DataQualityMetrics {
|
|
186
|
-
/** Overall data quality score (0-1) */
|
|
187
|
-
overallScore: number;
|
|
188
|
-
/** Data completeness percentage */
|
|
189
|
-
completeness: number;
|
|
190
|
-
/** Event sequence consistency validation */
|
|
191
|
-
sequenceValid: boolean;
|
|
192
|
-
/** Timing data integrity status */
|
|
193
|
-
timingValid: boolean;
|
|
194
|
-
/** Session duration in milliseconds */
|
|
195
|
-
sessionDuration: number;
|
|
196
|
-
/** Total number of events collected */
|
|
197
|
-
eventCount: number;
|
|
198
|
-
/** Quality assessment level */
|
|
199
|
-
qualityLevel: 'POOR' | 'FAIR' | 'GOOD' | 'EXCELLENT';
|
|
200
|
-
/** Quality issues identified */
|
|
201
|
-
issues: string[];
|
|
202
|
-
/** Validation timestamp */
|
|
203
|
-
validatedAt: string;
|
|
9
|
+
export interface UseWriteTrackReturn {
|
|
10
|
+
/** Reset the tracker and clear state */
|
|
11
|
+
reset: () => void;
|
|
12
|
+
/** Start tracking (if autoStart was false) */
|
|
13
|
+
start: () => void;
|
|
14
|
+
/** Stop tracking */
|
|
15
|
+
stop: () => void;
|
|
16
|
+
/** Whether the tracker is currently active */
|
|
17
|
+
isTracking: Ref<boolean>;
|
|
18
|
+
/** Access to the underlying WriteTrack instance */
|
|
19
|
+
tracker: ShallowRef<WriteTrack | null>;
|
|
204
20
|
}
|
|
205
21
|
|
|
206
|
-
interface WriteTrackOptions {
|
|
207
|
-
target: HTMLElement;
|
|
208
|
-
license?: string;
|
|
209
|
-
}
|
|
210
|
-
declare class WriteTrack {
|
|
211
|
-
protected keystrokeEvents: KeystrokeEvent[];
|
|
212
|
-
protected clipboardEvents: ClipboardEvent[];
|
|
213
|
-
protected undoRedoEvents: UndoRedoEvent[];
|
|
214
|
-
protected selectionEvents: SelectionEvent[];
|
|
215
|
-
private pendingKeydowns;
|
|
216
|
-
protected lastMouseActivity: number;
|
|
217
|
-
protected sessionStartTime: number;
|
|
218
|
-
protected lastKeyTime: number;
|
|
219
|
-
protected lastKeyUpTime: number;
|
|
220
|
-
protected repeatedKeyTracker: Map<string, number[]>;
|
|
221
|
-
private focusStartTime;
|
|
222
|
-
private lastSelection;
|
|
223
|
-
protected readonly BURST_THRESHOLD = 150;
|
|
224
|
-
protected readonly PAUSE_THRESHOLD = 1000;
|
|
225
|
-
protected readonly CORRECTION_KEYS: Set<string>;
|
|
226
|
-
private readonly targetType;
|
|
227
|
-
protected readonly target: HTMLElement;
|
|
228
|
-
private readonly license?;
|
|
229
|
-
/**
|
|
230
|
-
* Create a WriteTrack instance
|
|
231
|
-
* @param optionsOrTarget - Either an HTMLElement (demo mode) or WriteTrackOptions object
|
|
232
|
-
*/
|
|
233
|
-
constructor(optionsOrTarget: WriteTrackOptions | HTMLElement);
|
|
234
|
-
private validateLicenseAsync;
|
|
235
|
-
private setupEventListeners;
|
|
236
|
-
/**
|
|
237
|
-
* Technique 6: Observe target's parent for childList changes.
|
|
238
|
-
* If target is removed from DOM, stop recording.
|
|
239
|
-
*/
|
|
240
|
-
private setupTargetObserver;
|
|
241
|
-
private isRecordingEnabled;
|
|
242
|
-
private recordKeydown;
|
|
243
|
-
private recordKeyup;
|
|
244
|
-
private recordMouseActivity;
|
|
245
|
-
private recordWindowFocus;
|
|
246
|
-
private detectKeyboardShortcuts;
|
|
247
|
-
private recordClipboardEvent;
|
|
248
|
-
private recordSelection;
|
|
249
|
-
private checkSelectionAfterMouse;
|
|
250
|
-
private recordSelectionChange;
|
|
251
|
-
private getSelection;
|
|
252
|
-
private getSelectedTextLength;
|
|
253
|
-
private recordVisibilityChange;
|
|
254
|
-
private getShortcutString;
|
|
255
|
-
private getCurrentCursorPosition;
|
|
256
|
-
private isMacPlatform;
|
|
257
|
-
private trackRepeatedKey;
|
|
258
|
-
/**
|
|
259
|
-
* Check if the license is valid
|
|
260
|
-
*/
|
|
261
|
-
isLicenseValid(): boolean;
|
|
262
|
-
/**
|
|
263
|
-
* Check if license validation has completed
|
|
264
|
-
*/
|
|
265
|
-
isLicenseValidated(): boolean;
|
|
266
|
-
/**
|
|
267
|
-
* Check if the target element was detached from the DOM
|
|
268
|
-
*/
|
|
269
|
-
isTargetDetached(): boolean;
|
|
270
|
-
start(): void;
|
|
271
|
-
stop(): void;
|
|
272
|
-
getRawEvents(): KeystrokeEvent[];
|
|
273
|
-
getClipboardEvents(): ClipboardEvent[];
|
|
274
|
-
getUndoRedoEvents(): UndoRedoEvent[];
|
|
275
|
-
getSelectionEvents(): SelectionEvent[];
|
|
276
|
-
getSessionDuration(): number;
|
|
277
|
-
getKeystrokeCount(): number;
|
|
278
|
-
getText(): string;
|
|
279
|
-
getData(): WriteTrackDataSchema;
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
interface UseWriteTrackOptions {
|
|
283
|
-
/** Auto-start tracking when element is available (default: true) */
|
|
284
|
-
autoStart?: boolean;
|
|
285
|
-
}
|
|
286
|
-
interface UseWriteTrackReturn {
|
|
287
|
-
/** Reset the tracker and clear state */
|
|
288
|
-
reset: () => void;
|
|
289
|
-
/** Start tracking (if autoStart was false) */
|
|
290
|
-
start: () => void;
|
|
291
|
-
/** Stop tracking */
|
|
292
|
-
stop: () => void;
|
|
293
|
-
/** Whether the tracker is currently active */
|
|
294
|
-
isTracking: Ref<boolean>;
|
|
295
|
-
/** Access to the underlying WriteTrack instance */
|
|
296
|
-
tracker: ShallowRef<WriteTrack | null>;
|
|
297
|
-
}
|
|
298
22
|
/**
|
|
299
23
|
* Vue 3 composable for WriteTrack keystroke analysis
|
|
300
24
|
*
|
|
@@ -309,8 +33,8 @@ interface UseWriteTrackReturn {
|
|
|
309
33
|
*
|
|
310
34
|
* function handleSubmit() {
|
|
311
35
|
* if (tracker.value) {
|
|
312
|
-
* const
|
|
313
|
-
* console.log('
|
|
36
|
+
* const data = tracker.value.getData();
|
|
37
|
+
* console.log('Data:', data);
|
|
314
38
|
* }
|
|
315
39
|
* }
|
|
316
40
|
* </script>
|
|
@@ -323,6 +47,7 @@ interface UseWriteTrackReturn {
|
|
|
323
47
|
* </template>
|
|
324
48
|
* ```
|
|
325
49
|
*/
|
|
326
|
-
declare function useWriteTrack(
|
|
327
|
-
|
|
328
|
-
|
|
50
|
+
export declare function useWriteTrack(
|
|
51
|
+
elementRef: Ref<HTMLElement | null>,
|
|
52
|
+
options?: UseWriteTrackOptions
|
|
53
|
+
): UseWriteTrackReturn;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "writetrack",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Lightweight keystroke telemetry capture for web applications",
|
|
6
6
|
"main": "dist/index.cjs",
|
|
@@ -26,6 +26,12 @@
|
|
|
26
26
|
"./browser": {
|
|
27
27
|
"types": "./dist/esm/index.d.ts",
|
|
28
28
|
"import": "./dist/browser/index.js"
|
|
29
|
+
},
|
|
30
|
+
"./pipes": {
|
|
31
|
+
"types": "./dist/esm/pipes.d.ts",
|
|
32
|
+
"browser": "./dist/browser/pipes.js",
|
|
33
|
+
"import": "./dist/esm/pipes.js",
|
|
34
|
+
"require": "./dist/pipes.cjs"
|
|
29
35
|
}
|
|
30
36
|
},
|
|
31
37
|
"peerDependencies": {
|
|
@@ -45,6 +51,10 @@
|
|
|
45
51
|
"dist/esm/index.d.ts",
|
|
46
52
|
"dist/browser/index.js",
|
|
47
53
|
"dist/index.cjs",
|
|
54
|
+
"dist/esm/pipes.js",
|
|
55
|
+
"dist/esm/pipes.d.ts",
|
|
56
|
+
"dist/browser/pipes.js",
|
|
57
|
+
"dist/pipes.cjs",
|
|
48
58
|
"dist/react/",
|
|
49
59
|
"dist/vue/",
|
|
50
60
|
"cli/init.js",
|