writetrack 0.10.2 → 0.11.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 +88 -37
- package/dist/browser/index.js +1 -1
- package/dist/browser/pipes.js +1 -1
- package/dist/browser/viz.js +60 -44
- package/dist/browser/writetrack.wasm +0 -0
- package/dist/ckeditor/index.d.ts +2 -0
- package/dist/ckeditor/index.js +1 -1
- package/dist/esm/index.d.ts +75 -5
- 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/viz.d.ts +124 -30
- package/dist/esm/viz.js +60 -44
- package/dist/esm/writetrack.wasm +0 -0
- package/dist/index.cjs +1 -1
- package/dist/lexical/index.d.ts +2 -0
- package/dist/lexical/index.js +1 -1
- package/dist/pipes.cjs +1 -1
- package/dist/prosemirror/index.d.ts +4 -0
- package/dist/prosemirror/index.js +1 -1
- package/dist/quill/index.d.ts +4 -0
- package/dist/quill/index.js +1 -1
- package/dist/react/index.d.ts +18 -2
- package/dist/react/index.js +1 -1
- package/dist/slate/index.d.ts +4 -0
- 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 +8 -1
- package/dist/tiptap/index.js +1 -1
- package/dist/viz.cjs +60 -44
- package/dist/vue/index.d.ts +13 -1
- package/dist/vue/index.js +1 -1
- package/dist/writetrack.wasm +0 -0
- package/package.json +11 -2
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-Cg3hzXZX.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 u(e,c){let a={...e},i=c;for(let o of Object.keys(i)){let t=i[o],n=a[o];d(t)&&d(n)?a[o]=u(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:{}}}},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:[]}}},outputSignature:"mock-signature"}}function p(e){return e?u(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 c=(e==null?void 0:e.analysis)!==void 0?e.analysis:p(),a=e!=null&&e.data?u(l(),e.data):l(),i={},o={getData(){return a},getAnalysis(){return Promise.resolve(c)},async getSessionReport(){return{data:a,analysis:c}},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/viz.d.ts
CHANGED
|
@@ -52,7 +52,7 @@ declare abstract class BaseChart<T = unknown> extends HTMLElement {
|
|
|
52
52
|
/** Called on container resize. Override in subclasses that shouldn't full re-render. */
|
|
53
53
|
protected onResize(): void;
|
|
54
54
|
/** Wrap render() in try/catch so subclasses don't need individual error handling */
|
|
55
|
-
|
|
55
|
+
protected safeRender(): void;
|
|
56
56
|
/** Subclasses implement this to draw their visualization */
|
|
57
57
|
protected abstract render(): void;
|
|
58
58
|
/** Register the custom element if not already defined */
|
|
@@ -148,32 +148,6 @@ declare class PauseDistribution extends BaseChart<SessionAnalysis> {
|
|
|
148
148
|
protected render(): void;
|
|
149
149
|
}
|
|
150
150
|
|
|
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
151
|
/**
|
|
178
152
|
* EditBeeswarm — per-keystroke beeswarm visualization.
|
|
179
153
|
*
|
|
@@ -206,7 +180,7 @@ declare class EditBeeswarm extends BaseChart<WriteTrackDataSchema> {
|
|
|
206
180
|
/** Glyph marks: single text mark so everything dodges together.
|
|
207
181
|
* Typed chars as letters, deletes as ×, pastes as 📋, cuts as ✂. */
|
|
208
182
|
private buildGlyphMarks;
|
|
209
|
-
/** Crop the SVG viewBox
|
|
183
|
+
/** Crop the SVG viewBox bottom to fit content, preserving the top (axis). */
|
|
210
184
|
private cropViewBox;
|
|
211
185
|
}
|
|
212
186
|
|
|
@@ -276,12 +250,54 @@ interface OriginBarColors {
|
|
|
276
250
|
/** Extract origin proportions from analysis, filtering out 0% segments. */
|
|
277
251
|
declare function extractOriginData(analysis: SessionAnalysis): OriginDatum[];
|
|
278
252
|
/** Render a horizontal stacked bar showing content origin proportions. */
|
|
279
|
-
declare function renderOriginBar(data: OriginDatum[], width: number, colors?: OriginBarColors): SVGSVGElement | null;
|
|
253
|
+
declare function renderOriginBar(data: OriginDatum[], width: number, colors?: OriginBarColors, textColors?: Partial<OriginBarColors>): SVGSVGElement | null;
|
|
280
254
|
declare class WtOriginBar extends BaseChart<SessionAnalysis> {
|
|
281
255
|
static tagName: string;
|
|
282
256
|
protected render(): void;
|
|
283
257
|
}
|
|
284
258
|
|
|
259
|
+
/**
|
|
260
|
+
* Session scorecard web component.
|
|
261
|
+
*
|
|
262
|
+
* Renders a full-page analysis report with header, stat badges, narrative summary,
|
|
263
|
+
* origin bar, 6-cell analysis grid, and detail panels with embedded charts.
|
|
264
|
+
*
|
|
265
|
+
* @element wt-scorecard
|
|
266
|
+
*
|
|
267
|
+
* @attr {string} theme - Color theme: `"light"` or `"dark"`. Overrides ancestor `data-theme` and `prefers-color-scheme`.
|
|
268
|
+
* @attr {boolean} share - Show share button and make QR code clickable.
|
|
269
|
+
* @attr {boolean} download - Show download button.
|
|
270
|
+
* @attr {string} data - JSON-serialized `SessionReport`. Alternative to calling `setData()`.
|
|
271
|
+
* @attr {boolean} compact - Compact rendering mode (inherited from BaseChart).
|
|
272
|
+
* @attr {string} label - Custom `aria-label` for accessibility (inherited from BaseChart).
|
|
273
|
+
*
|
|
274
|
+
* @fires wt-share - When the share button or QR code is clicked. Detail: `{ report: SessionReport }`.
|
|
275
|
+
* @fires wt-download - When the download button is clicked. Detail: `{ report: SessionReport }`.
|
|
276
|
+
* @fires wt-render - When render completes (inherited from BaseChart).
|
|
277
|
+
*
|
|
278
|
+
* @csspart page - The root container element.
|
|
279
|
+
*
|
|
280
|
+
* @cssprop [--wt-scorecard-bg] - Main background color.
|
|
281
|
+
* @cssprop [--wt-scorecard-bg-card] - Cell card background color.
|
|
282
|
+
* @cssprop [--wt-scorecard-bg-card-hover] - Card hover state color.
|
|
283
|
+
* @cssprop [--wt-scorecard-bg-card-flagged] - Flagged cell background color.
|
|
284
|
+
* @cssprop [--wt-scorecard-bg-detail] - Detail panel background color.
|
|
285
|
+
* @cssprop [--wt-scorecard-text] - Primary text color.
|
|
286
|
+
* @cssprop [--wt-scorecard-text-secondary] - Secondary text color.
|
|
287
|
+
* @cssprop [--wt-scorecard-text-tertiary] - Tertiary/muted text color.
|
|
288
|
+
* @cssprop [--wt-scorecard-border] - Border color.
|
|
289
|
+
* @cssprop [--wt-scorecard-border-heavy] - Heavy border color.
|
|
290
|
+
* @cssprop [--wt-scorecard-status-clear] - Pass/clear status color.
|
|
291
|
+
* @cssprop [--wt-scorecard-status-flagged] - Flagged/fail status color.
|
|
292
|
+
* @cssprop [--wt-scorecard-chart-line] - Chart line color.
|
|
293
|
+
* @cssprop [--wt-scorecard-chart-accent] - Chart accent color.
|
|
294
|
+
* @cssprop [--wt-scorecard-chart-flagged] - Chart flagged color.
|
|
295
|
+
* @cssprop [--wt-scorecard-chart-tertiary] - Chart tertiary color.
|
|
296
|
+
* @cssprop [--wt-scorecard-chart-cyan] - Chart cyan (paste) color.
|
|
297
|
+
* @cssprop [--wt-scorecard-font-display] - Display font (titles, headers).
|
|
298
|
+
* @cssprop [--wt-scorecard-font-body] - Body text font.
|
|
299
|
+
* @cssprop [--wt-scorecard-font-data] - Data/code font.
|
|
300
|
+
*/
|
|
285
301
|
declare class WtScorecard extends BaseChart<SessionReport> {
|
|
286
302
|
static tagName: string;
|
|
287
303
|
static get observedAttributes(): string[];
|
|
@@ -418,4 +434,82 @@ declare class WtBadge extends BaseChart<BadgeData> {
|
|
|
418
434
|
*/
|
|
419
435
|
declare function generateWritingSummary(analysis: SessionAnalysis): string | null;
|
|
420
436
|
|
|
421
|
-
|
|
437
|
+
/**
|
|
438
|
+
* CompositionTimeline — session activity segments over time.
|
|
439
|
+
*
|
|
440
|
+
* Shows typing/paste/pause/tabAway segments as colored horizontal bars
|
|
441
|
+
* and paste events as dots scaled by character count.
|
|
442
|
+
*/
|
|
443
|
+
|
|
444
|
+
declare const SEGMENT_COLORS: Record<string, string>;
|
|
445
|
+
interface SegmentDatum {
|
|
446
|
+
start: number;
|
|
447
|
+
end: number;
|
|
448
|
+
type: string;
|
|
449
|
+
color: string;
|
|
450
|
+
}
|
|
451
|
+
interface PasteDatum {
|
|
452
|
+
time: number;
|
|
453
|
+
chars: number;
|
|
454
|
+
source: string;
|
|
455
|
+
}
|
|
456
|
+
/** Extract activity segments from analysis, converting ms to seconds. */
|
|
457
|
+
declare function extractSegments(analysis: SessionAnalysis): SegmentDatum[];
|
|
458
|
+
/** Extract paste event markers from analysis. */
|
|
459
|
+
declare function extractPasteMarkers(analysis: SessionAnalysis): PasteDatum[];
|
|
460
|
+
/** Extract only tab-away segments (for mode="focus" rendering). */
|
|
461
|
+
declare function extractFocusSegments(analysis: SessionAnalysis): SegmentDatum[];
|
|
462
|
+
declare class CompositionTimeline extends BaseChart<SessionAnalysis> {
|
|
463
|
+
static tagName: string;
|
|
464
|
+
static get observedAttributes(): string[];
|
|
465
|
+
get mode(): string;
|
|
466
|
+
protected render(): void;
|
|
467
|
+
private _renderFocus;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
/**
|
|
471
|
+
* DocumentGrowth — writing process chart.
|
|
472
|
+
*
|
|
473
|
+
* By default shows net document length (product) over time as a line + area fill.
|
|
474
|
+
* Opt-in attributes enable additional series:
|
|
475
|
+
* process — cumulative total input activity (always increasing)
|
|
476
|
+
* cursor — cursor position in the document over time
|
|
477
|
+
* pauses — orange dots sized by inter-keystroke gap duration
|
|
478
|
+
*
|
|
479
|
+
* Consumes raw WriteTrackDataSchema (not WASM analysis output).
|
|
480
|
+
*/
|
|
481
|
+
|
|
482
|
+
interface ProcessPoint {
|
|
483
|
+
time: number;
|
|
484
|
+
process: number;
|
|
485
|
+
product: number;
|
|
486
|
+
cursor: number;
|
|
487
|
+
}
|
|
488
|
+
interface PauseDot {
|
|
489
|
+
time: number;
|
|
490
|
+
product: number;
|
|
491
|
+
pauseMs: number;
|
|
492
|
+
}
|
|
493
|
+
interface ProcessGraphData {
|
|
494
|
+
points: ProcessPoint[];
|
|
495
|
+
pauses: PauseDot[];
|
|
496
|
+
}
|
|
497
|
+
/** Extract process/product data from raw keystroke events. */
|
|
498
|
+
declare function extractProcessData(data: WriteTrackDataSchema, minPauseMs?: number): ProcessGraphData;
|
|
499
|
+
declare class DocumentGrowth extends BaseChart<WriteTrackDataSchema> {
|
|
500
|
+
static tagName: string;
|
|
501
|
+
private _changePointTime;
|
|
502
|
+
/** Set a change point time (in seconds) to display as a vertical marker. */
|
|
503
|
+
setChangePoint(timeSec: number | null): void;
|
|
504
|
+
static get observedAttributes(): string[];
|
|
505
|
+
attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;
|
|
506
|
+
protected render(): void;
|
|
507
|
+
}
|
|
508
|
+
/** @deprecated Use DocumentGrowth */
|
|
509
|
+
declare const ProcessGraph: typeof DocumentGrowth;
|
|
510
|
+
/** @deprecated Use extractProcessData */
|
|
511
|
+
declare const extractGrowthData: typeof extractProcessData;
|
|
512
|
+
/** @deprecated Use ProcessPoint */
|
|
513
|
+
type GrowthPoint = ProcessPoint;
|
|
514
|
+
|
|
515
|
+
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 };
|