writetrack 0.7.0 → 0.9.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 CHANGED
@@ -4,7 +4,7 @@ Detect AI-generated and pasted text through keystroke dynamics.
4
4
 
5
5
  WriteTrack analyzes _how_ text was entered, not what was written. Human typing has natural variation in timing, rhythm, and corrections. Pasted or AI-generated text arrives all at once with no behavioral fingerprint. WriteTrack captures the difference.
6
6
 
7
- - **~100KB** gzipped (15KB JS + 86KB WASM)
7
+ - **~115KB** gzipped (17KB JS + 94KB WASM)
8
8
  - **0** runtime dependencies
9
9
  - **<1ms** per keystroke
10
10
  - **100%** client-side
@@ -29,7 +29,7 @@ import { WriteTrack } from 'writetrack';
29
29
  const responseField = document.getElementById('response-field')!;
30
30
  const tracker = new WriteTrack({
31
31
  target: responseField,
32
- license: process.env.WRITETRACK_LICENSE_KEY, // omit for dev/demo mode
32
+ license: process.env.WRITETRACK_LICENSE_KEY, // omit for localhost evaluation
33
33
  });
34
34
 
35
35
  tracker.start();
@@ -56,6 +56,9 @@ import { WriteTrackExtension } from 'writetrack/tiptap';
56
56
  import { WriteTrackPlugin } from 'writetrack/ckeditor';
57
57
  import { WriteTrackPlugin } from 'writetrack/prosemirror';
58
58
  import { WriteTrackModule } from 'writetrack/quill';
59
+ import { createWriteTrackLexical } from 'writetrack/lexical';
60
+ import { createWriteTrackSlate } from 'writetrack/slate';
61
+ import { createWriteTrackTinyMCE } from 'writetrack/tinymce';
59
62
  ```
60
63
 
61
64
  ## Output Sinks
@@ -104,39 +107,41 @@ new WriteTrack(options: WriteTrackOptions | HTMLElement)
104
107
  ```typescript
105
108
  interface WriteTrackOptions {
106
109
  target: HTMLElement;
107
- license?: string; // Omit for development/demo mode
110
+ license?: string; // Omit for localhost evaluation
108
111
  userId?: string; // Opaque user identifier, included in output metadata
109
112
  contentId?: string; // Opaque document identifier, included in output metadata
110
113
  metadata?: Record<string, unknown>; // Arbitrary metadata, included in output
111
114
  wasmUrl?: string; // Custom URL for the WASM analysis binary
112
115
  persist?: boolean; // Enable IndexedDB persistence (requires contentId)
116
+ cursorPositionProvider?: () => number; // Custom cursor position for rich-text editors
113
117
  }
114
118
  ```
115
119
 
116
120
  ### Methods
117
121
 
118
- | Method | Returns | Description |
119
- | ---------------------------------- | -------------------------------- | -------------------------------------- |
120
- | `start()` | `void` | Begin capturing events |
121
- | `stop()` | `void` | Stop capturing and clean up |
122
- | `getData()` | `WriteTrackDataSchema` | Export full session data |
123
- | `getText()` | `string` | Current text content |
124
- | `getRawEvents()` | `KeystrokeEvent[]` | All captured keystroke events |
125
- | `getClipboardEvents()` | `ClipboardEvent[]` | Paste/copy/cut events |
126
- | `getSelectionEvents()` | `SelectionEvent[]` | Text selection events |
127
- | `getUndoRedoEvents()` | `UndoRedoEvent[]` | Undo/redo events |
128
- | `getCompositionEvents()` | `CompositionEvent[]` | IME composition events |
129
- | `getProgrammaticInsertionEvents()` | `ProgrammaticInsertionEvent[]` | Programmatic insertion events |
130
- | `getSessionDuration()` | `number` | Session duration in ms |
131
- | `getKeystrokeCount()` | `number` | Total keystrokes captured |
132
- | `getAnalysis()` | `Promise<SessionAnalysis\|null>` | WASM-powered session analysis |
133
- | `getSessionReport()` | `Promise<SessionReport>` | Combined data + analysis |
134
- | `pipe(sink)` | `this` | Register an output sink |
135
- | `on(event, handler)` | `this` | Register an event listener |
136
- | `isLicenseValid()` | `boolean` | Whether license is valid |
137
- | `isLicenseValidated()` | `boolean` | Whether license check has completed |
138
- | `isTargetDetached()` | `boolean` | Whether the target element was removed |
139
- | `clearPersistedData()` | `Promise<void>` | Clear IndexedDB persisted session |
122
+ | Method | Returns | Description |
123
+ | ---------------------------------- | -------------------------------- | ------------------------------------------------- |
124
+ | `start()` | `void` | Begin capturing events |
125
+ | `stop()` | `void` | Stop capturing and clean up |
126
+ | `getData()` | `WriteTrackDataSchema` | Export full session data |
127
+ | `getText()` | `string` | Current text content |
128
+ | `getRawEvents()` | `KeystrokeEvent[]` | All captured keystroke events |
129
+ | `getClipboardEvents()` | `ClipboardEvent[]` | Paste/copy/cut events |
130
+ | `getSelectionEvents()` | `SelectionEvent[]` | Text selection events |
131
+ | `getUndoRedoEvents()` | `UndoRedoEvent[]` | Undo/redo events |
132
+ | `getCompositionEvents()` | `CompositionEvent[]` | IME composition events |
133
+ | `getProgrammaticInsertionEvents()` | `ProgrammaticInsertionEvent[]` | Programmatic insertion events |
134
+ | `getSessionDuration()` | `number` | Session duration in ms |
135
+ | `getActiveTime()` | `number` | Active (visible) session time in ms |
136
+ | `getKeystrokeCount()` | `number` | Total keystrokes captured |
137
+ | `getAnalysis()` | `Promise<SessionAnalysis\|null>` | WASM-powered session analysis |
138
+ | `getSessionReport()` | `Promise<SessionReport>` | Combined data + analysis |
139
+ | `pipe(sink)` | `this` | Register an output sink |
140
+ | `on(event, handler)` | `this` | Register an event listener (`tick`, `pipe:error`) |
141
+ | `isLicenseValid()` | `boolean` | Whether license is valid |
142
+ | `isLicenseValidated()` | `boolean` | Whether license check has completed |
143
+ | `isTargetDetached()` | `boolean` | Whether the target element was removed |
144
+ | `clearPersistedData()` | `Promise<void>` | Clear IndexedDB persisted session |
140
145
 
141
146
  ### Properties
142
147
 
@@ -162,7 +167,7 @@ const analysis = await analyzeEvents(data, {
162
167
 
163
168
  Full type definitions are included in the package:
164
169
 
165
- **Functions:** `analyzeEvents`, `formatIndicator`, `getHighResolutionTime`
170
+ **Functions:** `analyzeEvents`, `createSessionReport`, `formatIndicator`, `getHighResolutionTime`
166
171
 
167
172
  **Types:** `KeystrokeEvent`, `ClipboardEvent`, `SelectionEvent`, `UndoRedoEvent`, `CompositionEvent`, `ProgrammaticInsertionEvent`, `ModifierState`, `WriteTrackDataSchema`, `DataQualityMetrics`, `SessionMetadata`, `SessionAnalysis`, `SessionReport`, `IndicatorOutput`, `AnalyzeEventsOptions`, `WriteTrackSink`
168
173