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/lexical/index.d.ts
CHANGED
|
@@ -1,23 +1,7 @@
|
|
|
1
1
|
import { WriteTrack } from 'writetrack';
|
|
2
|
+
import type { BaseBindingOptions } from 'writetrack';
|
|
2
3
|
|
|
3
|
-
export
|
|
4
|
-
/** WriteTrack license key */
|
|
5
|
-
license?: string;
|
|
6
|
-
/** User identifier for metadata */
|
|
7
|
-
userId?: string;
|
|
8
|
-
/** Content identifier for metadata */
|
|
9
|
-
contentId?: string;
|
|
10
|
-
/** Additional metadata */
|
|
11
|
-
metadata?: Record<string, unknown>;
|
|
12
|
-
/** Auto-start tracking when editor root is available (default: true) */
|
|
13
|
-
autoStart?: boolean;
|
|
14
|
-
/** URL to the WASM binary for analysis. If omitted, uses default loader path. */
|
|
15
|
-
wasmUrl?: string;
|
|
16
|
-
/** Enable IndexedDB session persistence and auto-resume. Requires contentId. */
|
|
17
|
-
persist?: boolean;
|
|
18
|
-
/** Callback fired every second with active session time. */
|
|
19
|
-
onTick?: (data: { activeTime: number; totalTime: number }) => void;
|
|
20
|
-
}
|
|
4
|
+
export type WriteTrackLexicalOptions = BaseBindingOptions;
|
|
21
5
|
|
|
22
6
|
export interface WriteTrackLexicalHandle {
|
|
23
7
|
/** The underlying WriteTrack instance (null until root element is available) */
|
package/dist/lexical/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{WriteTrack as
|
|
1
|
+
import{WriteTrack as u}from"writetrack";function f(i,s,r){let l=r.autoStart!==!1,a,o=i.registerUpdateListener(({tags:t})=>{t.has("paste")?a="paste":t.has("historic")?a="undo":a=void 0}),e={tracker:null,isTracking:!1,destroy(){e.tracker&&(e.tracker.stop(),e.tracker=null,e.isTracking=!1),o(),d()}};function k(t){e.tracker=new u({target:t,license:r.license,userId:r.userId,contentId:r.contentId,metadata:r.metadata,wasmUrl:r.wasmUrl,persist:r.persist,cursorPositionProvider:()=>{try{return i.getEditorState().read(()=>{let n=s();return n&&typeof n.anchor?.offset=="number"?n.anchor.offset:0})}catch{return 0}},inputSourceProvider:()=>a}),r.onTick&&e.tracker.on("tick",r.onTick),l?r.persist?e.tracker.ready.then(()=>{e.tracker&&(e.tracker.start(),e.isTracking=!0,r.onReady?.(e.tracker))}):(e.tracker.start(),e.isTracking=!0,r.onReady?.(e.tracker)):r.persist?e.tracker.ready.then(()=>{e.tracker&&r.onReady?.(e.tracker)}):r.onReady?.(e.tracker)}function c(){e.tracker&&(e.tracker.stop(),e.tracker=null,e.isTracking=!1)}let d=i.registerRootListener(t=>{t?(c(),k(t)):c()});return e}export{f as createWriteTrackLexical};
|
package/dist/pipes.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var f=Object.defineProperty;var h=Object.getOwnPropertyDescriptor;var y=Object.getOwnPropertyNames;var b=Object.prototype.hasOwnProperty;var w=(r,n)=>{for(var o in n)f(r,o,{get:n[o],enumerable:!0})},x=(r,n,o,t)=>{if(n&&typeof n=="object"||typeof n=="function")for(let e of y(n))!b.call(r,e)&&e!==o&&f(r,e,{get:()=>n[e],enumerable:!(t=h(n,e))||t.enumerable});return r};var S=r=>x(f({},"__esModule",{value:!0}),r);var T={};w(T,{datadog:()=>p,opentelemetry:()=>g,segment:()=>d,webhook:()=>l});module.exports=S(T);function l(r){let{url:n,headers:o={},retries:t=0,backoffMs:e=100,maxBackoffMs:a=3e4,keepalive:u=!1}=r;return{async send(v){let m=null;for(let s=0;s<=t;s++){if(s>0){let i=Math.min(e*Math.pow(2,s-1),a);await new Promise(k=>setTimeout(k,i))}try{let i=await fetch(n,{method:"POST",headers:{"Content-Type":"application/json",...o},body:JSON.stringify(v),keepalive:u});if(i.ok)return;m=new Error(`Webhook failed: ${i.status} ${i.statusText}`)}catch(i){m=i instanceof Error?i:new Error(String(i))}}throw m}}}function c(r){return r instanceof Error?r.message:String(r)}function p(r){let{client:n,actionName:o="writetrack_session",tags:t={}}=r;return{async send(e){let a={...t,duration:e.metadata.duration,keystrokeCount:e.session.events.length,qualityLevel:e.quality.qualityLevel,targetElement:e.metadata.targetElement,schemaVersion:e.version};e.metadata.userId&&(a.userId=e.metadata.userId),e.metadata.contentId&&(a.contentId=e.metadata.contentId),e.metadata.custom&&(a.custom=e.metadata.custom);try{n.addAction(o,a)}catch(u){throw new Error(`Datadog addAction failed: ${c(u)}`)}}}}function d(r){let{client:n,eventName:o="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{n.track(o,e)}catch(a){throw new Error(`Segment track failed: ${c(a)}`)}}}}function g(r){let{tracer:n,spanName:o="writetrack.session"}=r;return{async send(t){let e=n.startSpan(o);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()}}}}0&&(module.exports={datadog,opentelemetry,segment,webhook});
|
|
@@ -1,22 +1,8 @@
|
|
|
1
1
|
import { WriteTrack } from 'writetrack';
|
|
2
|
+
import type { BaseBindingOptions } from 'writetrack';
|
|
2
3
|
import { Plugin, PluginKey } from 'prosemirror-state';
|
|
3
4
|
|
|
4
|
-
export
|
|
5
|
-
/** WriteTrack license key */
|
|
6
|
-
license?: string;
|
|
7
|
-
/** User identifier for metadata */
|
|
8
|
-
userId?: string;
|
|
9
|
-
/** Content identifier for metadata */
|
|
10
|
-
contentId?: string;
|
|
11
|
-
/** Additional metadata */
|
|
12
|
-
metadata?: Record<string, unknown>;
|
|
13
|
-
/** Auto-start tracking when editor is ready (default: true) */
|
|
14
|
-
autoStart?: boolean;
|
|
15
|
-
/** URL to the WASM binary for analysis. If omitted, uses default loader path. */
|
|
16
|
-
wasmUrl?: string;
|
|
17
|
-
/** Enable IndexedDB session persistence and auto-resume. Requires contentId. */
|
|
18
|
-
persist?: boolean;
|
|
19
|
-
}
|
|
5
|
+
export type WriteTrackPluginOptions = BaseBindingOptions;
|
|
20
6
|
|
|
21
7
|
export interface WriteTrackPluginState {
|
|
22
8
|
tracker: WriteTrack | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Plugin as
|
|
1
|
+
import{Plugin as s,PluginKey as c}from"prosemirror-state";import{WriteTrack as o}from"writetrack";var u=new c("writetrack");function d(t={}){let l=t.autoStart!==!1,e=null,a=!1,i;return new s({key:u,state:{init(){return{tracker:null,isTracking:!1}},apply(){return{tracker:e,isTracking:e!==null&&a}}},filterTransaction(r){let n=r.getMeta("uiEvent");return n==="paste"?i="paste":n==="drop"?i="drop":n==="cut"?i="cut":r.getMeta("composition")?i="composition":i=void 0,!0},view(r){let n=r.dom;return e=new o({target:n,license:t.license,userId:t.userId,contentId:t.contentId,metadata:t.metadata,wasmUrl:t.wasmUrl,persist:t.persist,cursorPositionProvider:()=>r.state.selection.from,inputSourceProvider:()=>i}),t.onTick&&e.on("tick",t.onTick),l?t.persist?e.ready.then(()=>{e&&(e.start(),a=!0,t.onReady?.(e))}):(e.start(),a=!0,t.onReady?.(e)):t.persist?e.ready.then(()=>{e&&t.onReady?.(e)}):t.onReady?.(e),r.dispatch(r.state.tr),{destroy(){e&&(e.stop(),e=null,a=!1)}}}})}export{d as WriteTrackPlugin,u as WriteTrackPluginKey};
|
package/dist/quill/index.d.ts
CHANGED
|
@@ -1,21 +1,7 @@
|
|
|
1
1
|
import { WriteTrack } from 'writetrack';
|
|
2
|
+
import type { BaseBindingOptions } from 'writetrack';
|
|
2
3
|
|
|
3
|
-
export
|
|
4
|
-
/** WriteTrack license key */
|
|
5
|
-
license?: string;
|
|
6
|
-
/** User identifier for metadata */
|
|
7
|
-
userId?: string;
|
|
8
|
-
/** Content identifier for metadata */
|
|
9
|
-
contentId?: string;
|
|
10
|
-
/** Additional metadata */
|
|
11
|
-
metadata?: Record<string, unknown>;
|
|
12
|
-
/** Auto-start tracking when module is initialized (default: true) */
|
|
13
|
-
autoStart?: boolean;
|
|
14
|
-
/** URL to the WASM binary for analysis. If omitted, uses default loader path. */
|
|
15
|
-
wasmUrl?: string;
|
|
16
|
-
/** Enable IndexedDB session persistence and auto-resume. Requires contentId. */
|
|
17
|
-
persist?: boolean;
|
|
18
|
-
}
|
|
4
|
+
export type WriteTrackModuleOptions = BaseBindingOptions;
|
|
19
5
|
|
|
20
6
|
/**
|
|
21
7
|
* Quill module for WriteTrack keystroke analysis
|
package/dist/quill/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{WriteTrack as
|
|
1
|
+
import{WriteTrack as n}from"writetrack";var t=class{constructor(e,r){this._tracker=null;this._isTracking=!1;let i=r.autoStart!==!1;e.on("text-change",(c,o,a)=>{this._currentSource=a==="api"?"api":void 0}),this._tracker=new n({target:e.root,license:r.license,userId:r.userId,contentId:r.contentId,metadata:r.metadata,wasmUrl:r.wasmUrl,persist:r.persist,cursorPositionProvider:()=>e.getSelection()?.index??0,inputSourceProvider:()=>this._currentSource}),r.onTick&&this._tracker.on("tick",r.onTick),i?r.persist?this._tracker.ready.then(()=>{this._tracker&&(this._tracker.start(),this._isTracking=!0,r.onReady?.(this._tracker))}):(this._tracker.start(),this._isTracking=!0,r.onReady?.(this._tracker)):r.persist?this._tracker.ready.then(()=>{this._tracker&&r.onReady?.(this._tracker)}):r.onReady?.(this._tracker)}get tracker(){return this._tracker}get isTracking(){return this._isTracking}destroy(){this._tracker&&(this._tracker.stop(),this._tracker=null,this._isTracking=!1)}};export{t as WriteTrackModule};
|
package/dist/react/index.d.ts
CHANGED
|
@@ -1,21 +1,10 @@
|
|
|
1
|
-
import { WriteTrack } from 'writetrack';
|
|
1
|
+
import { WriteTrack, SessionAnalysis } from 'writetrack';
|
|
2
|
+
import type { BaseBindingOptions } from 'writetrack';
|
|
2
3
|
import { RefObject } from 'react';
|
|
3
4
|
|
|
4
|
-
export interface UseWriteTrackOptions {
|
|
5
|
-
/**
|
|
6
|
-
|
|
7
|
-
/** User identifier included in metadata */
|
|
8
|
-
userId?: string;
|
|
9
|
-
/** Content identifier included in metadata */
|
|
10
|
-
contentId?: string;
|
|
11
|
-
/** Additional metadata */
|
|
12
|
-
metadata?: Record<string, unknown>;
|
|
13
|
-
/** Auto-start tracking when element is available (default: true) */
|
|
14
|
-
autoStart?: boolean;
|
|
15
|
-
/** URL to the WASM binary for analysis. If omitted, uses default loader path. */
|
|
16
|
-
wasmUrl?: string;
|
|
17
|
-
/** Enable IndexedDB session persistence and auto-resume. Requires contentId. */
|
|
18
|
-
persist?: boolean;
|
|
5
|
+
export interface UseWriteTrackOptions extends BaseBindingOptions {
|
|
6
|
+
/** Subscribe to real-time analysis events. Requires wasmUrl or default WASM loader. */
|
|
7
|
+
analysis?: boolean;
|
|
19
8
|
}
|
|
20
9
|
|
|
21
10
|
export interface UseWriteTrackReturn {
|
|
@@ -27,8 +16,18 @@ export interface UseWriteTrackReturn {
|
|
|
27
16
|
stop: () => void;
|
|
28
17
|
/** Whether the tracker is currently active */
|
|
29
18
|
isTracking: boolean;
|
|
30
|
-
/**
|
|
19
|
+
/**
|
|
20
|
+
* Access to the underlying WriteTrack instance.
|
|
21
|
+
* When `autoStart` is false, this is `null` on the initial render and
|
|
22
|
+
* becomes available after the first re-render.
|
|
23
|
+
*/
|
|
31
24
|
tracker: WriteTrack | null;
|
|
25
|
+
/** Whether the tracker has initialised and is ready */
|
|
26
|
+
isReady: boolean;
|
|
27
|
+
/** Latest analysis result (when `analysis: true`) */
|
|
28
|
+
analysis: SessionAnalysis | null;
|
|
29
|
+
/** Latest error from WASM or tracker initialisation */
|
|
30
|
+
error: Error | null;
|
|
32
31
|
}
|
|
33
32
|
|
|
34
33
|
/**
|
package/dist/react/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{useEffect as
|
|
1
|
+
import{useEffect as A,useRef as y,useCallback as p,useState as l}from"react";import{WriteTrack as x}from"writetrack";var u=class{constructor(s){this._unsubs=[];this._opts=s,this._state={tracker:null,isReady:!1,isTracking:!1,analysis:null,error:null},this._init(s.target,s.writeTrackOptions)}_init(s,i){let t=new x({...i,target:s});if(this._state.tracker=t,this._unsubs=[],this._opts.onTick){let a=t.on("tick",this._opts.onTick);this._unsubs.push(a)}if(this._opts.analysis){let a=t.on("analysis",n=>{this._state.analysis=n,this._notify()});this._unsubs.push(a);let o=t.on("wasm:error",n=>{this._state.error=n,this._notify()});this._unsubs.push(o)}this._opts.autoStart!==!1?!!i.persist?t.ready.then(()=>{t.start(),this._state.isReady=!0,this._state.isTracking=!0,this._notify(),this._opts.onReady?.(t)}).catch(o=>{this._state.error=o,this._notify()}):(t.start(),this._state.isReady=!0,this._state.isTracking=!0,this._notify(),queueMicrotask(()=>{this._opts.onReady?.(t)})):(this._state.isReady=!0,this._notify())}_notify(){this._opts.onStateChange({tracker:this._state.tracker,isReady:this._state.isReady,isTracking:this._state.isTracking,analysis:this._state.analysis,error:this._state.error})}getState(){return{tracker:this._state.tracker,isReady:this._state.isReady,isTracking:this._state.isTracking,analysis:this._state.analysis,error:this._state.error}}start(){this._state.tracker&&!this._state.isTracking&&(this._state.tracker.start(),this._state.isTracking=!0,this._notify())}stop(){this._state.tracker&&this._state.isTracking&&(this._state.tracker.stop(),this._state.isTracking=!1,this._notify())}async destroy(){this._state.tracker&&await this._state.tracker.stopAndWait();for(let s of this._unsubs)s();this._unsubs=[],this._state.tracker=null,this._state.isReady=!1,this._state.isTracking=!1,this._state.analysis=null,this._state.error=null,this._notify()}async reset(s,i){await this.destroy(),this._init(s,i??this._opts.writeTrackOptions)}};function j(e,s={}){let{autoStart:i=!0,analysis:t,onTick:k,onReady:a,...o}=s,n=y(o);n.current=o;let h=y(k);h.current=k;let _=y(a);_.current=a;let c=y(null),[d,g]=l(null),[m,R]=l(!1),[O,b]=l(!1),[S,W]=l(null),[v,w]=l(null);A(()=>{if(!e.current)return;let f=!1,T=new u({target:e.current,writeTrackOptions:n.current,autoStart:i,analysis:t,onTick:h.current?r=>h.current?.(r):void 0,onReady:r=>_.current?.(r),onStateChange:r=>{f||(g(r.tracker),R(r.isTracking),b(r.isReady),W(r.analysis),w(r.error))}});return c.current=T,()=>{f=!0,c.current=null,T.destroy()}},[e,i,t]);let C=p(()=>{c.current?.start()},[]),E=p(()=>{c.current?.stop()},[]);return{reset:p(()=>{!e.current||!c.current||c.current.reset(e.current,n.current)},[e]),start:C,stop:E,isTracking:m,tracker:d,isReady:O,analysis:S,error:v}}export{j as useWriteTrack};
|
package/dist/slate/index.d.ts
CHANGED
|
@@ -1,21 +1,7 @@
|
|
|
1
1
|
import { WriteTrack } from 'writetrack';
|
|
2
|
+
import type { BaseBindingOptions } from 'writetrack';
|
|
2
3
|
|
|
3
|
-
export
|
|
4
|
-
/** WriteTrack license key */
|
|
5
|
-
license?: string;
|
|
6
|
-
/** User identifier for metadata */
|
|
7
|
-
userId?: string;
|
|
8
|
-
/** Content identifier for metadata */
|
|
9
|
-
contentId?: string;
|
|
10
|
-
/** Additional metadata */
|
|
11
|
-
metadata?: Record<string, unknown>;
|
|
12
|
-
/** Auto-start tracking when created (default: true) */
|
|
13
|
-
autoStart?: boolean;
|
|
14
|
-
/** URL to the WASM binary for analysis. If omitted, uses default loader path. */
|
|
15
|
-
wasmUrl?: string;
|
|
16
|
-
/** Enable IndexedDB session persistence and auto-resume. Requires contentId. */
|
|
17
|
-
persist?: boolean;
|
|
18
|
-
}
|
|
4
|
+
export type WriteTrackSlateOptions = BaseBindingOptions;
|
|
19
5
|
|
|
20
6
|
export interface WriteTrackSlateHandle {
|
|
21
7
|
/** The underlying WriteTrack instance */
|
package/dist/slate/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{WriteTrack as
|
|
1
|
+
import{WriteTrack as k}from"writetrack";function o(t,s,r){let l=r.autoStart!==!1,a,c=t.insertText;t.insertText=n=>{a="keyboard",c.call(t,n)};let i=t.insertData;t.insertData=n=>{a="paste",i.call(t,n)};let e={tracker:null,isTracking:!1,destroy(){e.tracker&&(e.tracker.stop(),e.tracker=null,e.isTracking=!1),t.insertText=c,t.insertData=i}};return e.tracker=new k({target:s,license:r.license,userId:r.userId,contentId:r.contentId,metadata:r.metadata,wasmUrl:r.wasmUrl,persist:r.persist,cursorPositionProvider:()=>t.selection?.anchor.offset??0,inputSourceProvider:()=>a}),r.onTick&&e.tracker.on("tick",r.onTick),l?r.persist?e.tracker.ready.then(()=>{e.tracker&&(e.tracker.start(),e.isTracking=!0,r.onReady?.(e.tracker))}):(e.tracker.start(),e.isTracking=!0,r.onReady?.(e.tracker)):r.persist?e.tracker.ready.then(()=>{e.tracker&&r.onReady?.(e.tracker)}):r.onReady?.(e.tracker),e}export{o as createWriteTrackSlate};
|
package/dist/tinymce/index.d.ts
CHANGED
|
@@ -1,71 +1,41 @@
|
|
|
1
|
-
import { WriteTrack } from 'writetrack';
|
|
2
|
-
|
|
3
|
-
export interface WriteTrackTinyMCEOptions {
|
|
4
|
-
/** WriteTrack license key */
|
|
5
|
-
license?: string;
|
|
6
|
-
/** User identifier for metadata */
|
|
7
|
-
userId?: string;
|
|
8
|
-
/** Content identifier for metadata */
|
|
9
|
-
contentId?: string;
|
|
10
|
-
/** Additional metadata */
|
|
11
|
-
metadata?: Record<string, unknown>;
|
|
12
|
-
/** Auto-start tracking when editor initializes (default: true) */
|
|
13
|
-
autoStart?: boolean;
|
|
14
|
-
/** URL to the WASM binary for analysis. If omitted, uses default loader path. */
|
|
15
|
-
wasmUrl?: string;
|
|
16
|
-
/** Enable IndexedDB session persistence and auto-resume. Requires contentId. */
|
|
17
|
-
persist?: boolean;
|
|
18
|
-
/** Callback fired every second with active session time. */
|
|
19
|
-
onTick?: (data: { activeTime: number; totalTime: number }) => void;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export interface WriteTrackTinyMCEHandle {
|
|
23
|
-
/** The underlying WriteTrack instance (null until editor init fires) */
|
|
24
|
-
tracker: WriteTrack | null;
|
|
25
|
-
/** Whether tracking is currently active */
|
|
26
|
-
isTracking: boolean;
|
|
27
|
-
/** Stop tracking and clean up resources */
|
|
28
|
-
destroy(): void;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
1
|
/**
|
|
32
|
-
*
|
|
2
|
+
* Native TinyMCE plugin for WriteTrack.
|
|
33
3
|
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
4
|
+
* Importing this module registers the `writetrack` plugin with TinyMCE's
|
|
5
|
+
* PluginManager. No function call required — import for side effect.
|
|
36
6
|
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
* host page rather than the iframe, resulting in degraded tracking.
|
|
7
|
+
* Supports both inline and iframe editor modes. In iframe mode, focus and
|
|
8
|
+
* selection listeners automatically attach to the iframe's document context.
|
|
40
9
|
*
|
|
41
10
|
* @example
|
|
42
11
|
* ```ts
|
|
43
|
-
* import
|
|
44
|
-
* import { createWriteTrackTinyMCE } from 'writetrack/tinymce';
|
|
12
|
+
* import 'writetrack/tinymce';
|
|
45
13
|
*
|
|
46
14
|
* tinymce.init({
|
|
47
15
|
* selector: '#editor',
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
16
|
+
* plugins: ['writetrack'],
|
|
17
|
+
* writetrack_license: 'your-license-key',
|
|
18
|
+
* });
|
|
19
|
+
*
|
|
20
|
+
* // Access plugin API after init:
|
|
21
|
+
* editor.on('init', () => {
|
|
22
|
+
* const wt = editor.plugins.writetrack;
|
|
23
|
+
* const data = wt.tracker?.getData();
|
|
54
24
|
* });
|
|
55
25
|
* ```
|
|
56
26
|
*
|
|
57
|
-
* @
|
|
58
|
-
* @param options - WriteTrack configuration options
|
|
59
|
-
* @returns A handle with the tracker instance and a destroy method
|
|
27
|
+
* @module writetrack/tinymce
|
|
60
28
|
*/
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
29
|
+
|
|
30
|
+
import { WriteTrack } from 'writetrack';
|
|
31
|
+
|
|
32
|
+
export interface WriteTrackTinyMCEPlugin {
|
|
33
|
+
/** The underlying WriteTrack instance (null until editor init fires) */
|
|
34
|
+
tracker: WriteTrack | null;
|
|
35
|
+
/** Whether tracking is currently active */
|
|
36
|
+
isTracking: boolean;
|
|
37
|
+
/** Stop tracking and clean up resources */
|
|
38
|
+
destroy(): void;
|
|
39
|
+
/** TinyMCE plugin metadata for the Help plugin */
|
|
40
|
+
getMetadata(): { name: string; url: string };
|
|
41
|
+
}
|
package/dist/tinymce/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{WriteTrack as
|
|
1
|
+
import{WriteTrack as E}from"writetrack";function d(){tinymce.PluginManager.add("writetrack",(t,M)=>{t.options.register("writetrack_license",{processor:"string",default:""}),t.options.register("writetrack_userId",{processor:"string",default:""}),t.options.register("writetrack_contentId",{processor:"string",default:""}),t.options.register("writetrack_metadata",{processor:"object",default:{}}),t.options.register("writetrack_autoStart",{processor:"boolean",default:!0}),t.options.register("writetrack_wasmUrl",{processor:"string",default:""}),t.options.register("writetrack_persist",{processor:"boolean",default:!1}),t.options.register("writetrack_onTick",{processor:"function",default:void 0}),t.options.register("writetrack_onReady",{processor:"function",default:void 0});let n,o=!1,e={tracker:null,isTracking:!1,destroy(){e.tracker&&(e.tracker.stop(),e.tracker=null,e.isTracking=!1),t.off("init",g),t.off("remove",l),t.off("PastePreProcess",s),t.off("AutocompleterStart",c),t.off("AutocompleterEnd",u)},getMetadata(){return{name:"WriteTrack",url:"https://writetrack.dev"}}};function s(){n="paste"}function c(){o=!0}function u(){o&&(n="autocomplete"),o=!1}function g(){let p=t.getBody(),m=t.options.get("writetrack_license")||void 0,w=t.options.get("writetrack_userId")||void 0,T=t.options.get("writetrack_contentId")||void 0,i=t.options.get("writetrack_metadata"),y=t.options.get("writetrack_wasmUrl")||void 0,a=t.options.get("writetrack_persist"),f=t.options.get("writetrack_onTick"),r=t.options.get("writetrack_onReady"),v=t.options.get("writetrack_autoStart"),k=!!t.iframeElement,P=k?t.getDoc():void 0,_=k?t.getWin():void 0;e.tracker=new E({target:p,license:m,userId:w,contentId:T,metadata:i&&Object.keys(i).length>0?i:void 0,wasmUrl:y,persist:a,documentOverride:P,windowOverride:_,cursorPositionProvider:()=>{try{return t.selection.getRng().startOffset}catch{return 0}},inputSourceProvider:()=>n}),f&&e.tracker.on("tick",f),v?a?e.tracker.ready.then(()=>{e.tracker&&(e.tracker.start(),e.isTracking=!0,r?.(e.tracker))}):(e.tracker.start(),e.isTracking=!0,r?.(e.tracker)):a?e.tracker.ready.then(()=>{e.tracker&&r?.(e.tracker)}):r?.(e.tracker)}function l(){e.destroy()}return t.on("init",g),t.on("remove",l),t.on("PastePreProcess",s),t.on("AutocompleterStart",c),t.on("AutocompleterEnd",u),e})}d();
|
package/dist/tiptap/index.d.ts
CHANGED
|
@@ -1,30 +1,18 @@
|
|
|
1
1
|
import { WriteTrack } from 'writetrack';
|
|
2
|
+
import type { InputSource, BaseBindingOptions } from 'writetrack';
|
|
2
3
|
import { Extension } from '@tiptap/core';
|
|
3
4
|
|
|
4
|
-
export
|
|
5
|
-
/** WriteTrack license key */
|
|
6
|
-
license?: string;
|
|
7
|
-
/** User identifier for metadata */
|
|
8
|
-
userId?: string;
|
|
9
|
-
/** Content identifier for metadata */
|
|
10
|
-
contentId?: string;
|
|
11
|
-
/** Additional metadata */
|
|
12
|
-
metadata?: Record<string, unknown>;
|
|
13
|
-
/** Auto-start tracking when editor is created (default: true) */
|
|
14
|
-
autoStart?: boolean;
|
|
15
|
-
/** URL to the WASM binary for analysis. If omitted, uses default loader path. */
|
|
16
|
-
wasmUrl?: string;
|
|
17
|
-
/** Enable IndexedDB session persistence and auto-resume. Requires contentId. */
|
|
18
|
-
persist?: boolean;
|
|
19
|
-
/** Callback fired every second with active session time. Wired up inside onCreate to avoid lifecycle race conditions. */
|
|
20
|
-
onTick?: (data: { activeTime: number; totalTime: number }) => void;
|
|
21
|
-
}
|
|
5
|
+
export type WriteTrackExtensionOptions = BaseBindingOptions;
|
|
22
6
|
|
|
23
7
|
export interface WriteTrackExtensionStorage {
|
|
24
8
|
/** The underlying WriteTrack instance */
|
|
25
9
|
tracker: WriteTrack | null;
|
|
10
|
+
/** Whether the tracker is ready (persistence loaded if applicable) */
|
|
11
|
+
isReady: boolean;
|
|
26
12
|
/** Whether tracking is currently active */
|
|
27
13
|
isTracking: boolean;
|
|
14
|
+
/** Current input source classification (instance-scoped via storage) */
|
|
15
|
+
currentSource: InputSource | undefined;
|
|
28
16
|
}
|
|
29
17
|
|
|
30
18
|
/**
|
|
@@ -53,3 +41,12 @@ export declare const WriteTrackExtension: Extension<
|
|
|
53
41
|
WriteTrackExtensionOptions,
|
|
54
42
|
WriteTrackExtensionStorage
|
|
55
43
|
>;
|
|
44
|
+
|
|
45
|
+
declare module '@tiptap/core' {
|
|
46
|
+
interface Storage {
|
|
47
|
+
writetrack: WriteTrackExtensionStorage;
|
|
48
|
+
}
|
|
49
|
+
interface EditorEvents {
|
|
50
|
+
'writetrack:ready': { tracker: WriteTrack };
|
|
51
|
+
}
|
|
52
|
+
}
|
package/dist/tiptap/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Extension as r}from"@tiptap/core";import{WriteTrack as i}from"writetrack";var
|
|
1
|
+
import{Extension as r}from"@tiptap/core";import{WriteTrack as i}from"writetrack";var s=r.create({name:"writetrack",addOptions(){return{license:void 0,userId:void 0,contentId:void 0,metadata:void 0,autoStart:!0,wasmUrl:void 0,persist:void 0,onTick:void 0,onReady:void 0}},addStorage(){return{tracker:null,isReady:!1,isTracking:!1,currentSource:void 0}},onTransaction({transaction:t}){let e=t.getMeta("uiEvent");e==="paste"?this.storage.currentSource="paste":e==="drop"?this.storage.currentSource="drop":e==="cut"?this.storage.currentSource="cut":this.storage.currentSource=void 0},onCreate(){let t=this.editor.view.dom;this.storage.tracker=new i({target:t,license:this.options.license,userId:this.options.userId,contentId:this.options.contentId,metadata:this.options.metadata,wasmUrl:this.options.wasmUrl,persist:this.options.persist,cursorPositionProvider:()=>this.editor.view.state.selection.from,inputSourceProvider:()=>this.storage.currentSource}),this.options.onTick&&this.storage.tracker.on("tick",this.options.onTick),this.options.autoStart?this.options.persist?this.storage.tracker.ready.then(()=>{this.storage.tracker&&(this.storage.tracker.start(),this.storage.isReady=!0,this.storage.isTracking=!0,this.editor.emit("writetrack:ready",{tracker:this.storage.tracker}),this.options.onReady?.(this.storage.tracker))}):(this.storage.tracker.start(),this.storage.isReady=!0,this.storage.isTracking=!0,this.editor.emit("writetrack:ready",{tracker:this.storage.tracker}),this.options.onReady?.(this.storage.tracker)):this.options.persist?this.storage.tracker.ready.then(()=>{this.storage.tracker&&(this.storage.isReady=!0,this.editor.emit("writetrack:ready",{tracker:this.storage.tracker}),this.options.onReady?.(this.storage.tracker))}):(this.storage.isReady=!0,this.editor.emit("writetrack:ready",{tracker:this.storage.tracker}),this.options.onReady?.(this.storage.tracker))},onDestroy(){this.storage.tracker&&(this.storage.tracker.stop(),this.storage.tracker=null,this.storage.isReady=!1,this.storage.isTracking=!1)}});export{s as WriteTrackExtension};
|