writetrack 0.10.3 → 0.12.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 +163 -42
- package/dist/browser/index.js +1 -1
- package/dist/browser/pipes.js +1 -1
- package/dist/browser/viz.js +56 -42
- package/dist/browser/writetrack.wasm +0 -0
- package/dist/ckeditor/index.d.ts +2 -18
- package/dist/ckeditor/index.js +1 -1
- package/dist/esm/index.d.ts +141 -6
- package/dist/esm/index.js +1 -1
- package/dist/esm/pipes.d.ts +3 -10
- package/dist/esm/pipes.js +1 -1
- package/dist/esm/testing.d.ts +61 -0
- package/dist/esm/testing.js +1 -0
- package/dist/esm/verify.d.ts +1 -1
- package/dist/esm/viz.d.ts +157 -37
- package/dist/esm/viz.js +56 -42
- package/dist/esm/writetrack.wasm +0 -0
- package/dist/index.cjs +1 -1
- package/dist/lexical/index.d.ts +2 -18
- package/dist/lexical/index.js +1 -1
- package/dist/pipes.cjs +1 -1
- package/dist/prosemirror/index.d.ts +2 -16
- package/dist/prosemirror/index.js +1 -1
- package/dist/quill/index.d.ts +2 -16
- package/dist/quill/index.js +1 -1
- package/dist/react/index.d.ts +16 -17
- package/dist/react/index.js +1 -1
- package/dist/slate/index.d.ts +2 -16
- package/dist/slate/index.js +1 -1
- package/dist/tinymce/index.d.ts +28 -58
- package/dist/tinymce/index.js +1 -1
- package/dist/tiptap/index.d.ts +15 -18
- package/dist/tiptap/index.js +1 -1
- package/dist/viz.cjs +57 -43
- package/dist/vue/index.d.ts +11 -16
- package/dist/vue/index.js +1 -1
- package/dist/writetrack.wasm +0 -0
- package/package.json +12 -3
package/dist/esm/pipes.d.ts
CHANGED
|
@@ -1,12 +1,5 @@
|
|
|
1
|
-
import { W as
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* A WriteTrack output sink receives session data when a session ends.
|
|
5
|
-
*/
|
|
6
|
-
interface WriteTrackSink {
|
|
7
|
-
/** Send session data to the destination. */
|
|
8
|
-
send(data: WriteTrackDataSchema): Promise<void>;
|
|
9
|
-
}
|
|
1
|
+
import { W as WriteTrackSink } from './types-B8bNI9P5.js';
|
|
2
|
+
import './index-Cy91q_po.js';
|
|
10
3
|
|
|
11
4
|
interface WebhookOptions {
|
|
12
5
|
/** URL to POST session data to */
|
|
@@ -110,4 +103,4 @@ interface OpenTelemetryOptions {
|
|
|
110
103
|
*/
|
|
111
104
|
declare function opentelemetry(options: OpenTelemetryOptions): WriteTrackSink;
|
|
112
105
|
|
|
113
|
-
export { type DatadogClient, type DatadogOptions, type OTelSpan, type OTelTracer, type OpenTelemetryOptions, type SegmentClient, type SegmentOptions, type WebhookOptions,
|
|
106
|
+
export { type DatadogClient, type DatadogOptions, type OTelSpan, type OTelTracer, type OpenTelemetryOptions, type SegmentClient, type SegmentOptions, type WebhookOptions, WriteTrackSink, datadog, opentelemetry, segment, webhook };
|
package/dist/esm/pipes.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
function p(
|
|
1
|
+
function p(r){let{url:i,headers:a={},retries:t=0,backoffMs:e=100,maxBackoffMs:o=3e4,keepalive:u=!1}=r;return{async send(f){let m=null;for(let s=0;s<=t;s++){if(s>0){let n=Math.min(e*Math.pow(2,s-1),o);await new Promise(l=>setTimeout(l,n))}try{let n=await fetch(i,{method:"POST",headers:{"Content-Type":"application/json",...a},body:JSON.stringify(f),keepalive:u});if(n.ok)return;m=new Error(`Webhook failed: ${n.status} ${n.statusText}`)}catch(n){m=n instanceof Error?n:new Error(String(n))}}throw m}}}function c(r){return r instanceof Error?r.message:String(r)}function d(r){let{client:i,actionName:a="writetrack_session",tags:t={}}=r;return{async send(e){let o={...t,duration:e.metadata.duration,keystrokeCount:e.session.events.length,qualityLevel:e.quality.qualityLevel,targetElement:e.metadata.targetElement,schemaVersion:e.version};e.metadata.userId&&(o.userId=e.metadata.userId),e.metadata.contentId&&(o.contentId=e.metadata.contentId),e.metadata.custom&&(o.custom=e.metadata.custom);try{i.addAction(a,o)}catch(u){throw new Error(`Datadog addAction failed: ${c(u)}`)}}}}function g(r){let{client:i,eventName:a="WriteTrack Session"}=r;return{async send(t){let e={duration:t.metadata.duration,keystrokeCount:t.session.events.length,qualityLevel:t.quality.qualityLevel,targetElement:t.metadata.targetElement,schemaVersion:t.version};t.metadata.userId&&(e.userId=t.metadata.userId),t.metadata.contentId&&(e.contentId=t.metadata.contentId),t.metadata.custom&&(e.custom=t.metadata.custom);try{i.track(a,e)}catch(o){throw new Error(`Segment track failed: ${c(o)}`)}}}}function v(r){let{tracer:i,spanName:a="writetrack.session"}=r;return{async send(t){let e=i.startSpan(a);try{e.setAttribute("writetrack.duration",t.metadata.duration),e.setAttribute("writetrack.keystroke_count",t.session.events.length),e.setAttribute("writetrack.quality_level",t.quality.qualityLevel),e.setAttribute("writetrack.target_element",t.metadata.targetElement),e.setAttribute("writetrack.schema_version",t.version),t.metadata.userId&&e.setAttribute("writetrack.user_id",t.metadata.userId),t.metadata.contentId&&e.setAttribute("writetrack.content_id",t.metadata.contentId),t.metadata.custom&&e.setAttribute("writetrack.custom",JSON.stringify(t.metadata.custom)),e.setStatus({code:1})}finally{e.end()}}}}export{d as datadog,v as opentelemetry,g as segment,p as webhook};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { S as SessionAnalysis, a as SessionReport } from './analysis-types-CRB59-1F.js';
|
|
2
|
+
import { W as WriteTrackDataSchema } from './index-Cy91q_po.js';
|
|
3
|
+
import { W as WriteTrackSink } from './types-B8bNI9P5.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* WriteTrack Test Utilities
|
|
7
|
+
*
|
|
8
|
+
* Framework-agnostic factories for creating mock WriteTrack instances
|
|
9
|
+
* and SessionAnalysis objects in consumer tests.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* import { createMockAnalysis, createMockTracker } from 'writetrack/testing';
|
|
14
|
+
*
|
|
15
|
+
* const analysis = createMockAnalysis({ keydownCount: 500 });
|
|
16
|
+
* const tracker = createMockTracker({ analysis });
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
/** Recursively makes all properties of T optional. */
|
|
21
|
+
type DeepPartial<T> = T extends object ? {
|
|
22
|
+
[P in keyof T]?: DeepPartial<T[P]>;
|
|
23
|
+
} : T;
|
|
24
|
+
/**
|
|
25
|
+
* Create a complete SessionAnalysis with sensible defaults.
|
|
26
|
+
* Accepts deep partial overrides that are merged into the defaults.
|
|
27
|
+
*/
|
|
28
|
+
declare function createMockAnalysis(overrides?: DeepPartial<SessionAnalysis>): SessionAnalysis;
|
|
29
|
+
/** Options for configuring the mock tracker. */
|
|
30
|
+
interface MockTrackerOptions {
|
|
31
|
+
/** Analysis returned by getAnalysis(). Defaults to a mock analysis. */
|
|
32
|
+
analysis?: SessionAnalysis | null;
|
|
33
|
+
/** Partial data merged into the default getData() return value. */
|
|
34
|
+
data?: DeepPartial<WriteTrackDataSchema>;
|
|
35
|
+
}
|
|
36
|
+
/** The mock tracker interface returned by createMockTracker(). */
|
|
37
|
+
interface MockWriteTrack {
|
|
38
|
+
getData(): WriteTrackDataSchema;
|
|
39
|
+
getAnalysis(): Promise<SessionAnalysis | null>;
|
|
40
|
+
getSessionReport(): Promise<SessionReport>;
|
|
41
|
+
getText(): string;
|
|
42
|
+
on(event: string, handler: (...args: unknown[]) => void): () => void;
|
|
43
|
+
off(event: string, handler: (...args: unknown[]) => void): void;
|
|
44
|
+
removeAllListeners(event?: string): void;
|
|
45
|
+
pipe(sink: WriteTrackSink): MockWriteTrack;
|
|
46
|
+
start(): void;
|
|
47
|
+
stop(): void;
|
|
48
|
+
stopAndWait(): Promise<void>;
|
|
49
|
+
ready: Promise<void>;
|
|
50
|
+
/** Test-only: fire an event to all registered handlers. */
|
|
51
|
+
emit(event: string, ...args: unknown[]): void;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Create a mock object that satisfies the WriteTrack public interface.
|
|
55
|
+
*
|
|
56
|
+
* The mock is test-framework-agnostic (no vitest/jest spies).
|
|
57
|
+
* Use `emit(event, data)` to fire events to registered handlers.
|
|
58
|
+
*/
|
|
59
|
+
declare function createMockTracker(options?: MockTrackerOptions): MockWriteTrack;
|
|
60
|
+
|
|
61
|
+
export { type DeepPartial, type MockTrackerOptions, type MockWriteTrack, createMockAnalysis, createMockTracker };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function d(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function c(e,u){let a={...e},i=u;for(let o of Object.keys(i)){let t=i[o],n=a[o];d(t)&&d(n)?a[o]=c(n,t):t!==void 0&&(a[o]=t)}return a}function m(){return{version:"1.0.0",locale:"en",analyzedAt:17e11,sufficientData:!0,keydownCount:420,integrity:{algorithm:"SHA-256",checkpoints:[],finalDigest:"mock-digest-0000",eventCount:450},sessionTimeline:[],initialTextLength:0,initialTextHash:"",finalTextLength:350,finalTextHash:"mock-final-hash",contentOrigin:{indicator:{code:"WT-104",params:{}},pasteReworkIndicator:{code:"WT-104",params:{}},metrics:{charactersByOrigin:{typed:.92,pasted:.06,autocompleted:.02},pasteEvents:[],pasteClassification:{internalPasteRatio:0,externalPasteRatio:.06,unknownPasteRatio:0},pasteEditSummary:{pasteRetentionRate:0,meanModificationDelayMs:0,pasteToTypeRatio:.065,meanReworkRatio:0,pasteLengthMean:0,pasteLengthStd:0,pasteLengthMin:0,pasteLengthMax:0},contentTimeline:{timestamps:[],series:{}}}},timingAuthenticity:{indicator:{code:"WT-204",params:{}},metrics:{dwellTimeDistribution:{mean:85,cv:.35,histogram:[]},flightTimeDistribution:{mean:110,cv:.4,histogram:[]},periodicityScore:.08,entropy:3.8,timingOverTime:{timestamps:[],series:{}}}},sessionContinuity:{indicator:{code:"WT-302",params:{}},metrics:{changePoints:[],tabAwayEvents:[],segmentComparison:{timestamps:[],series:{}},activeTime:{activeDurationMs:3e5,idleDurationMs:0,activeWindows:[],thinkingPauseCount:0,idleBreakCount:0}}},physicalPlausibility:{indicator:{code:"WT-403",params:{}},metrics:{impossibleSequences:{count:0,timeline:{timestamps:[],values:[]},samples:[]},syntheticEventRatio:0,mouseActivityDuringTyping:{periodsWithMouseActivity:.3,longestGapWithoutMouse:12e3},zeroLatencyEventCount:0,unmatchedKeydownCount:2,bulkInsertCharCount:0,modifierEventCount:18,uncoveredCaseCount:0,modifierLateralBalance:.8,modifierCoverage:1,modifierSustainCount:4,nonStandardKeys:[]}},revisionBehavior:{indicator:{code:"WT-503",params:{}},metrics:{correctionRate:.04,correctionCount:17,navigationCount:8,undoRedoCount:2,editPatterns:[],correctionTimeline:{timestamps:[],values:[]},revisionDepth:{maxDepth:3,avgDepth:1.2,regionsRevisedMultipleTimes:2},proportionBehindFrontier:.12,substitutedWordsCount:3,jumpToEditFrequency:.4,jumpDistanceSd:25,revisionAtPriorRatio:.08,revisionAtFrontierRatio:.92,insertionDeletion:{insertionCount:12,totalInsertionChars:380,insertionLengthMean:31.7,insertionLengthMedian:18,deletionCount:8,totalDeletionChars:45,deletionLengthMean:5.6,appendToInsertionRatio:.75},productProcessRatio:.85,pauseLocation:{beforeSentence:{count:5,meanDuration:2800},beforeWord:{count:12,meanDuration:800},withinWord:{count:3,meanDuration:350},afterWord:{count:8,meanDuration:600},betweenWords:{count:15,meanDuration:450}},proportionEventsAfterLastChar:.78,proportionCharsInMultiWordInsert:.04}},temporalPatterns:{indicator:{code:"WT-603",params:{}},metrics:{sessionDurationMs:3e5,speedTimeline:{timestamps:[],values:[]},fatigueRatio:.88,warmupRatio:1.15,pauseDistribution:{histogram:[],count:14,meanDuration:1800},burstPattern:{avgBurstLength:6,avgBurstSpeed:65,burstToTotalRatio:.35,burstDurationSd:480,burstDurationCv:.45},pause200ms:{count:45,meanDuration:350,sdDuration:120,pauseRate:.15},pause2000ms:{count:8,meanDuration:3200,sdDuration:900,pauseRate:.027},shortToLongPauseRatio:5.6,fluencySd5seg:12.5,fluencySd10seg:18.3,burstClassification:{pBurstCount:22,pBurstMedianDuration:4500,rBurstCount:15,rBurstMedianDuration:1200,pToRRatio:1.47}}},writingProcess:{indicator:{code:"WT-700",params:{}},metrics:{segments:[],transitions:[],timeInPhase:{planning:.15,drafting:.7,revision:.15},phaseChangeCount:8,windowDurationMs:3e4,phaseTimeline:{timestamps:[],values:[]}}},activeTime:{activeDurationMs:3e5,idleDurationMs:0,activeWindows:[],thinkingPauseCount:0,idleBreakCount:0},outputSignature:"mock-signature"}}function p(e){return e?c(m(),e):m()}function l(){return{version:"2.0.0",metadata:{tool:{name:"writetrack",version:"0.0.0-mock"},targetElement:"div",timestamp:new Date().toISOString(),duration:0,sessionId:"mock-session-id"},session:{events:[],rawText:"",sessionStartTime:0,sessionEndTime:0},quality:{overallScore:1,completeness:1,sequenceValid:!0,timingValid:!0,sessionDuration:0,eventCount:0,qualityLevel:"GOOD",issues:[],validatedAt:new Date().toISOString()}}}function g(e){let u=(e==null?void 0:e.analysis)!==void 0?e.analysis:p(),a=e!=null&&e.data?c(l(),e.data):l(),i={},o={getData(){return a},getAnalysis(){return Promise.resolve(u)},async getSessionReport(){return{data:a,analysis:u}},getText(){return a.session.rawText??""},on(t,n){return i[t]||(i[t]=[]),i[t].push(n),()=>{let s=i[t];if(s){let r=s.indexOf(n);r!==-1&&s.splice(r,1)}}},off(t,n){let s=i[t];if(s){let r=s.indexOf(n);r!==-1&&s.splice(r,1)}},removeAllListeners(t){if(t)delete i[t];else for(let n of Object.keys(i))delete i[n]},pipe(t){return o},start(){},stop(){},async stopAndWait(){},ready:Promise.resolve(),emit(t,...n){let s=i[t];if(s)for(let r of[...s])r(...n)}};return o}export{p as createMockAnalysis,g as createMockTracker};
|
package/dist/esm/verify.d.ts
CHANGED
package/dist/esm/viz.d.ts
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import { W as WriteTrackDataSchema } from './index-Cy91q_po.js';
|
|
2
|
-
import { S as SessionAnalysis, a as SessionReport,
|
|
2
|
+
import { S as SessionAnalysis, a as SessionReport, h as IntegrityProof } from './analysis-types-CRB59-1F.js';
|
|
3
|
+
|
|
4
|
+
interface ActiveTimeWindow {
|
|
5
|
+
startMs: number;
|
|
6
|
+
endMs: number;
|
|
7
|
+
}
|
|
3
8
|
|
|
4
9
|
/**
|
|
5
10
|
* BaseChart — abstract web component base class for WriteTrack visualizations.
|
|
@@ -7,18 +12,21 @@ import { S as SessionAnalysis, a as SessionReport, g as IntegrityProof } from '.
|
|
|
7
12
|
* Handles Shadow DOM creation, CSS token injection, data management,
|
|
8
13
|
* resize observation, and provides an abstract render() hook for subclasses.
|
|
9
14
|
*/
|
|
15
|
+
|
|
10
16
|
declare abstract class BaseChart<T = unknown> extends HTMLElement {
|
|
11
17
|
/** Override in subclasses to set the custom element tag name */
|
|
12
18
|
static tagName: string;
|
|
13
19
|
protected shadow: ShadowRoot;
|
|
14
20
|
protected container: HTMLDivElement;
|
|
15
21
|
protected _data: T | null;
|
|
22
|
+
protected _activeWindows: ActiveTimeWindow[];
|
|
16
23
|
private _resizeObserver;
|
|
17
24
|
private _resizeRaf;
|
|
18
25
|
private _themeObserver;
|
|
19
26
|
private _lastWidth;
|
|
20
27
|
private _rendered;
|
|
21
28
|
private _internalTheme;
|
|
29
|
+
private _skipTransition;
|
|
22
30
|
static get observedAttributes(): string[];
|
|
23
31
|
/** Whether to render in compact/sparkline mode (no axes, tight margins). */
|
|
24
32
|
get compact(): boolean;
|
|
@@ -36,6 +44,8 @@ declare abstract class BaseChart<T = unknown> extends HTMLElement {
|
|
|
36
44
|
connectedCallback(): void;
|
|
37
45
|
disconnectedCallback(): void;
|
|
38
46
|
attributeChangedCallback(name: string, _oldValue: string | null, newValue: string | null): void;
|
|
47
|
+
/** Set active time windows for idle-gap collapse on the time axis. */
|
|
48
|
+
setActiveWindows(windows: ActiveTimeWindow[]): void;
|
|
39
49
|
/** Set session data and trigger a render */
|
|
40
50
|
setData(data: T): void;
|
|
41
51
|
/** Get the current data */
|
|
@@ -52,7 +62,7 @@ declare abstract class BaseChart<T = unknown> extends HTMLElement {
|
|
|
52
62
|
/** Called on container resize. Override in subclasses that shouldn't full re-render. */
|
|
53
63
|
protected onResize(): void;
|
|
54
64
|
/** Wrap render() in try/catch so subclasses don't need individual error handling */
|
|
55
|
-
|
|
65
|
+
protected safeRender(): void;
|
|
56
66
|
/** Subclasses implement this to draw their visualization */
|
|
57
67
|
protected abstract render(): void;
|
|
58
68
|
/** Register the custom element if not already defined */
|
|
@@ -104,8 +114,9 @@ interface SpeedPoint {
|
|
|
104
114
|
time: number;
|
|
105
115
|
speed: number;
|
|
106
116
|
}
|
|
107
|
-
/** Extract speed timeline data from analysis, converting ms to seconds.
|
|
108
|
-
|
|
117
|
+
/** Extract speed timeline data from analysis, converting ms to seconds.
|
|
118
|
+
* When activeWindows are provided, idle gaps are collapsed. */
|
|
119
|
+
declare function extractSpeedData(analysis: SessionAnalysis, activeWindows?: ActiveTimeWindow[]): SpeedPoint[];
|
|
109
120
|
declare class SpeedTimeline extends BaseChart<SessionAnalysis> {
|
|
110
121
|
static tagName: string;
|
|
111
122
|
protected render(): void;
|
|
@@ -148,32 +159,6 @@ declare class PauseDistribution extends BaseChart<SessionAnalysis> {
|
|
|
148
159
|
protected render(): void;
|
|
149
160
|
}
|
|
150
161
|
|
|
151
|
-
/**
|
|
152
|
-
* DocumentGrowth — cumulative character count over time.
|
|
153
|
-
*
|
|
154
|
-
* Vertical jumps indicate paste/cut events. Slope indicates typing speed.
|
|
155
|
-
* Consumes raw WriteTrackDataSchema (not WASM analysis output).
|
|
156
|
-
*/
|
|
157
|
-
|
|
158
|
-
interface GrowthPoint {
|
|
159
|
-
time: number;
|
|
160
|
-
chars: number;
|
|
161
|
-
isPaste: boolean;
|
|
162
|
-
isCut: boolean;
|
|
163
|
-
pasteLength?: number;
|
|
164
|
-
cutLength?: number;
|
|
165
|
-
}
|
|
166
|
-
/** Extract cumulative character growth from raw events. */
|
|
167
|
-
declare function extractGrowthData(data: WriteTrackDataSchema): GrowthPoint[];
|
|
168
|
-
declare class DocumentGrowth extends BaseChart<WriteTrackDataSchema> {
|
|
169
|
-
static tagName: string;
|
|
170
|
-
/** Optional change point time (seconds) — renders as a dashed vertical rule. */
|
|
171
|
-
private _changePointTime;
|
|
172
|
-
/** Set a change point time (in seconds) to display as a vertical marker. */
|
|
173
|
-
setChangePoint(timeSec: number | null): void;
|
|
174
|
-
protected render(): void;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
162
|
/**
|
|
178
163
|
* EditBeeswarm — per-keystroke beeswarm visualization.
|
|
179
164
|
*
|
|
@@ -190,7 +175,7 @@ interface BeeswarmDatum {
|
|
|
190
175
|
key: string;
|
|
191
176
|
}
|
|
192
177
|
/** Extract per-keystroke beeswarm data from raw session events. */
|
|
193
|
-
declare function extractBeeswarmData(data: WriteTrackDataSchema): BeeswarmDatum[];
|
|
178
|
+
declare function extractBeeswarmData(data: WriteTrackDataSchema, activeWindows?: ActiveTimeWindow[]): BeeswarmDatum[];
|
|
194
179
|
declare class EditBeeswarm extends BaseChart<WriteTrackDataSchema> {
|
|
195
180
|
static tagName: string;
|
|
196
181
|
static get observedAttributes(): string[];
|
|
@@ -206,7 +191,7 @@ declare class EditBeeswarm extends BaseChart<WriteTrackDataSchema> {
|
|
|
206
191
|
/** Glyph marks: single text mark so everything dodges together.
|
|
207
192
|
* Typed chars as letters, deletes as ×, pastes as 📋, cuts as ✂. */
|
|
208
193
|
private buildGlyphMarks;
|
|
209
|
-
/** Crop the SVG viewBox
|
|
194
|
+
/** Crop the SVG viewBox bottom to fit content, preserving the top (axis). */
|
|
210
195
|
private cropViewBox;
|
|
211
196
|
}
|
|
212
197
|
|
|
@@ -228,7 +213,7 @@ interface WaterfallData {
|
|
|
228
213
|
cuts: WaterfallPoint[];
|
|
229
214
|
}
|
|
230
215
|
/** Extract cursor position data from raw events. */
|
|
231
|
-
declare function extractWaterfallData(data: WriteTrackDataSchema): WaterfallData;
|
|
216
|
+
declare function extractWaterfallData(data: WriteTrackDataSchema, activeWindows?: ActiveTimeWindow[]): WaterfallData;
|
|
232
217
|
declare class EditWaterfall extends BaseChart<WriteTrackDataSchema> {
|
|
233
218
|
static tagName: string;
|
|
234
219
|
protected render(): void;
|
|
@@ -249,7 +234,7 @@ interface BubbleDatum {
|
|
|
249
234
|
type: EditType;
|
|
250
235
|
}
|
|
251
236
|
/** Group consecutive keystrokes into edit runs and add paste/cut events. */
|
|
252
|
-
declare function extractCorrectionBubbles(data: WriteTrackDataSchema): BubbleDatum[];
|
|
237
|
+
declare function extractCorrectionBubbles(data: WriteTrackDataSchema, activeWindows?: ActiveTimeWindow[]): BubbleDatum[];
|
|
253
238
|
declare class CorrectionsBubble extends BaseChart<WriteTrackDataSchema> {
|
|
254
239
|
static tagName: string;
|
|
255
240
|
protected render(): void;
|
|
@@ -276,12 +261,54 @@ interface OriginBarColors {
|
|
|
276
261
|
/** Extract origin proportions from analysis, filtering out 0% segments. */
|
|
277
262
|
declare function extractOriginData(analysis: SessionAnalysis): OriginDatum[];
|
|
278
263
|
/** Render a horizontal stacked bar showing content origin proportions. */
|
|
279
|
-
declare function renderOriginBar(data: OriginDatum[], width: number, colors?: OriginBarColors): SVGSVGElement | null;
|
|
264
|
+
declare function renderOriginBar(data: OriginDatum[], width: number, colors?: OriginBarColors, textColors?: Partial<OriginBarColors>): SVGSVGElement | null;
|
|
280
265
|
declare class WtOriginBar extends BaseChart<SessionAnalysis> {
|
|
281
266
|
static tagName: string;
|
|
282
267
|
protected render(): void;
|
|
283
268
|
}
|
|
284
269
|
|
|
270
|
+
/**
|
|
271
|
+
* Session scorecard web component.
|
|
272
|
+
*
|
|
273
|
+
* Renders a full-page analysis report with header, stat badges, narrative summary,
|
|
274
|
+
* origin bar, 6-cell analysis grid, and detail panels with embedded charts.
|
|
275
|
+
*
|
|
276
|
+
* @element wt-scorecard
|
|
277
|
+
*
|
|
278
|
+
* @attr {string} theme - Color theme: `"light"` or `"dark"`. Overrides ancestor `data-theme` and `prefers-color-scheme`.
|
|
279
|
+
* @attr {boolean} share - Show share button and make QR code clickable.
|
|
280
|
+
* @attr {boolean} download - Show download button.
|
|
281
|
+
* @attr {string} data - JSON-serialized `SessionReport`. Alternative to calling `setData()`.
|
|
282
|
+
* @attr {boolean} compact - Compact rendering mode (inherited from BaseChart).
|
|
283
|
+
* @attr {string} label - Custom `aria-label` for accessibility (inherited from BaseChart).
|
|
284
|
+
*
|
|
285
|
+
* @fires wt-share - When the share button or QR code is clicked. Detail: `{ report: SessionReport }`.
|
|
286
|
+
* @fires wt-download - When the download button is clicked. Detail: `{ report: SessionReport }`.
|
|
287
|
+
* @fires wt-render - When render completes (inherited from BaseChart).
|
|
288
|
+
*
|
|
289
|
+
* @csspart page - The root container element.
|
|
290
|
+
*
|
|
291
|
+
* @cssprop [--wt-scorecard-bg] - Main background color.
|
|
292
|
+
* @cssprop [--wt-scorecard-bg-card] - Cell card background color.
|
|
293
|
+
* @cssprop [--wt-scorecard-bg-card-hover] - Card hover state color.
|
|
294
|
+
* @cssprop [--wt-scorecard-bg-card-flagged] - Flagged cell background color.
|
|
295
|
+
* @cssprop [--wt-scorecard-bg-detail] - Detail panel background color.
|
|
296
|
+
* @cssprop [--wt-scorecard-text] - Primary text color.
|
|
297
|
+
* @cssprop [--wt-scorecard-text-secondary] - Secondary text color.
|
|
298
|
+
* @cssprop [--wt-scorecard-text-tertiary] - Tertiary/muted text color.
|
|
299
|
+
* @cssprop [--wt-scorecard-border] - Border color.
|
|
300
|
+
* @cssprop [--wt-scorecard-border-heavy] - Heavy border color.
|
|
301
|
+
* @cssprop [--wt-scorecard-status-clear] - Pass/clear status color.
|
|
302
|
+
* @cssprop [--wt-scorecard-status-flagged] - Flagged/fail status color.
|
|
303
|
+
* @cssprop [--wt-scorecard-chart-line] - Chart line color.
|
|
304
|
+
* @cssprop [--wt-scorecard-chart-accent] - Chart accent color.
|
|
305
|
+
* @cssprop [--wt-scorecard-chart-flagged] - Chart flagged color.
|
|
306
|
+
* @cssprop [--wt-scorecard-chart-tertiary] - Chart tertiary color.
|
|
307
|
+
* @cssprop [--wt-scorecard-chart-cyan] - Chart cyan (paste) color.
|
|
308
|
+
* @cssprop [--wt-scorecard-font-display] - Display font (titles, headers).
|
|
309
|
+
* @cssprop [--wt-scorecard-font-body] - Body text font.
|
|
310
|
+
* @cssprop [--wt-scorecard-font-data] - Data/code font.
|
|
311
|
+
*/
|
|
285
312
|
declare class WtScorecard extends BaseChart<SessionReport> {
|
|
286
313
|
static tagName: string;
|
|
287
314
|
static get observedAttributes(): string[];
|
|
@@ -295,7 +322,21 @@ declare class WtScorecard extends BaseChart<SessionReport> {
|
|
|
295
322
|
protected getStylesheet(): string;
|
|
296
323
|
/** Override to handle theme changes without full re-render. */
|
|
297
324
|
attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;
|
|
325
|
+
connectedCallback(): void;
|
|
298
326
|
protected render(): void;
|
|
327
|
+
/**
|
|
328
|
+
* Update existing DOM in place without tearing it down. Called on
|
|
329
|
+
* subsequent setData() calls after the initial render. Updates:
|
|
330
|
+
* badges, narrative, grid cell metrics/status, flags, charts, origin bar.
|
|
331
|
+
*/
|
|
332
|
+
private updateInPlace;
|
|
333
|
+
/**
|
|
334
|
+
* Update existing chart elements with new data instead of recreating them.
|
|
335
|
+
* Falls back to full re-render for charts that don't exist yet.
|
|
336
|
+
*/
|
|
337
|
+
private updateChartsInPlace;
|
|
338
|
+
/** Feed new data to an existing chart element based on its category. */
|
|
339
|
+
private feedChartData;
|
|
299
340
|
private buildHeader;
|
|
300
341
|
private buildFlags;
|
|
301
342
|
private buildIntegrityDetails;
|
|
@@ -369,7 +410,7 @@ interface ScorecardMetric {
|
|
|
369
410
|
* directly available and diagnostically meaningful for automation detection.
|
|
370
411
|
*/
|
|
371
412
|
declare function getMetrics(category: string, analysis: SessionAnalysis): ScorecardMetric[];
|
|
372
|
-
/** Format milliseconds to human-readable duration. */
|
|
413
|
+
/** Format milliseconds to human-readable duration (e.g. "2h 3m", "3d 2h"). */
|
|
373
414
|
declare function formatDuration(ms: number): string;
|
|
374
415
|
|
|
375
416
|
interface GlossaryEntry {
|
|
@@ -418,4 +459,83 @@ declare class WtBadge extends BaseChart<BadgeData> {
|
|
|
418
459
|
*/
|
|
419
460
|
declare function generateWritingSummary(analysis: SessionAnalysis): string | null;
|
|
420
461
|
|
|
421
|
-
|
|
462
|
+
/**
|
|
463
|
+
* CompositionTimeline — session activity segments over time.
|
|
464
|
+
*
|
|
465
|
+
* Shows typing/paste/pause/tabAway segments as colored horizontal bars
|
|
466
|
+
* and paste events as dots scaled by character count.
|
|
467
|
+
*/
|
|
468
|
+
|
|
469
|
+
declare const SEGMENT_COLORS: Record<string, string>;
|
|
470
|
+
interface SegmentDatum {
|
|
471
|
+
start: number;
|
|
472
|
+
end: number;
|
|
473
|
+
type: string;
|
|
474
|
+
color: string;
|
|
475
|
+
}
|
|
476
|
+
interface PasteDatum {
|
|
477
|
+
time: number;
|
|
478
|
+
chars: number;
|
|
479
|
+
source: string;
|
|
480
|
+
}
|
|
481
|
+
/** Extract activity segments from analysis, converting ms to seconds.
|
|
482
|
+
* When activeWindows are provided, idle gaps are collapsed. */
|
|
483
|
+
declare function extractSegments(analysis: SessionAnalysis, activeWindows?: ActiveTimeWindow[]): SegmentDatum[];
|
|
484
|
+
/** Extract paste event markers from analysis. */
|
|
485
|
+
declare function extractPasteMarkers(analysis: SessionAnalysis, activeWindows?: ActiveTimeWindow[]): PasteDatum[];
|
|
486
|
+
/** Extract only tab-away segments (for mode="focus" rendering). */
|
|
487
|
+
declare function extractFocusSegments(analysis: SessionAnalysis, activeWindows?: ActiveTimeWindow[]): SegmentDatum[];
|
|
488
|
+
declare class CompositionTimeline extends BaseChart<SessionAnalysis> {
|
|
489
|
+
static tagName: string;
|
|
490
|
+
static get observedAttributes(): string[];
|
|
491
|
+
get mode(): string;
|
|
492
|
+
protected render(): void;
|
|
493
|
+
private _renderFocus;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
/**
|
|
497
|
+
* DocumentGrowth — writing process chart.
|
|
498
|
+
*
|
|
499
|
+
* By default shows net document length (product) over time as a line + area fill.
|
|
500
|
+
* Opt-in attributes enable additional series:
|
|
501
|
+
* process — cumulative total input activity (always increasing)
|
|
502
|
+
* cursor — cursor position in the document over time
|
|
503
|
+
* pauses — orange dots sized by inter-keystroke gap duration
|
|
504
|
+
*
|
|
505
|
+
* Consumes raw WriteTrackDataSchema (not WASM analysis output).
|
|
506
|
+
*/
|
|
507
|
+
|
|
508
|
+
interface ProcessPoint {
|
|
509
|
+
time: number;
|
|
510
|
+
process: number;
|
|
511
|
+
product: number;
|
|
512
|
+
cursor: number;
|
|
513
|
+
}
|
|
514
|
+
interface PauseDot {
|
|
515
|
+
time: number;
|
|
516
|
+
product: number;
|
|
517
|
+
pauseMs: number;
|
|
518
|
+
}
|
|
519
|
+
interface ProcessGraphData {
|
|
520
|
+
points: ProcessPoint[];
|
|
521
|
+
pauses: PauseDot[];
|
|
522
|
+
}
|
|
523
|
+
/** Extract process/product data from raw keystroke events. */
|
|
524
|
+
declare function extractProcessData(data: WriteTrackDataSchema, minPauseMs?: number, activeWindows?: ActiveTimeWindow[]): ProcessGraphData;
|
|
525
|
+
declare class DocumentGrowth extends BaseChart<WriteTrackDataSchema> {
|
|
526
|
+
static tagName: string;
|
|
527
|
+
private _changePointTime;
|
|
528
|
+
/** Set a change point time (in seconds) to display as a vertical marker. */
|
|
529
|
+
setChangePoint(timeSec: number | null): void;
|
|
530
|
+
static get observedAttributes(): string[];
|
|
531
|
+
attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;
|
|
532
|
+
protected render(): void;
|
|
533
|
+
}
|
|
534
|
+
/** @deprecated Use DocumentGrowth */
|
|
535
|
+
declare const ProcessGraph: typeof DocumentGrowth;
|
|
536
|
+
/** @deprecated Use extractProcessData */
|
|
537
|
+
declare const extractGrowthData: typeof extractProcessData;
|
|
538
|
+
/** @deprecated Use ProcessPoint */
|
|
539
|
+
type GrowthPoint = ProcessPoint;
|
|
540
|
+
|
|
541
|
+
export { type BadgeData, type BadgeStatus, BaseChart, type BeeswarmDatum, type BeeswarmType, type BubbleDatum, CATEGORY_NAMES, type CategoryKey, CompositionTimeline, CorrectionsBubble, DocumentGrowth, EditBeeswarm, type EditType, EditWaterfall, GLOSSARY, type GlossaryEntry, type GrowthPoint, IntegrityFooter, type OriginBarColors, type OriginDatum, type PasteDatum, type PauseBin, PauseDistribution, type PauseDot, ProcessGraph, type ProcessGraphData, type ProcessPoint, RhythmHeatmap, type RhythmPoint, SEGMENT_COLORS, type ScorecardMetric, type SegmentDatum, Sparkline, type SpeedPoint, SpeedTimeline, type StatBadge, TIER1_CATEGORIES, TIER2_CATEGORIES, type WaterfallData, type WaterfallPoint, WtBadge, WtOriginBar, WtScorecard, extractBeeswarmData, extractCorrectionBubbles, extractFocusSegments, extractGrowthData, extractOriginData, extractPasteMarkers, extractPauseHistogram, extractProcessData, extractRhythmPairs, extractSegments, extractSeries, extractSpeedData, extractStatBadges, extractWaterfallData, formatDuration, generateCaption, generateSummary, generateWritingSummary, getMetrics, getStatus, isPass, renderOriginBar, renderStatBadges, wrapTerms };
|