@@ -147,35 +147,79 @@ const unsub = dmn.keys.registerCustomTab({
147147
148148---
149149
150+ ## Stats API
151+
152+ Real-time key input statistics API. Provides KPS (Keys Per Second) and total key count for the current tab.
153+
154+ <Callout type = " info" >
155+ No performance overhead when there are no subscribers - statistics calculation
156+ is only performed when subscribed.
157+ </Callout >
158+
159+ ### ` dmn.stats.subscribe(callback): Unsubscribe `
160+
161+ Subscribes to real-time key input statistics.
162+
163+ - KPS values (kps, kpsAvg, kpsMax): Updated approximately every 50ms
164+ - total: Updated immediately when key counter changes
165+
166+ ``` typescript
167+ interface KeyStatsPayload {
168+ kps: number ; // Current KPS (keys per second)
169+ kpsAvg: number ; // Average KPS
170+ kpsMax: number ; // Maximum KPS
171+ total: number ; // Total key count for current tab
172+ }
173+
174+ const unsub = dmn .stats .subscribe (({ kps , kpsAvg , kpsMax , total }) => {
175+ console .log (` KPS: ${kps }, AVG: ${kpsAvg }, MAX: ${kpsMax }, TOTAL: ${total } ` );
176+ });
177+
178+ // Unsubscribe
179+ unsub ();
180+ ```
181+
182+ ### ` dmn.stats.get(): KeyStatsPayload `
183+
184+ Gets current statistics immediately.
185+
186+ ``` javascript
187+ const stats = dmn .stats .get ();
188+ console .log (` Current KPS: ${ stats .kps } ` );
189+ ```
190+
191+ ### ` dmn.stats.reset(): void `
192+
193+ Resets KPS-related statistics (kps, kpsAvg, kpsMax). ` total ` is not reset as it's based on key counters.
194+
195+ ``` javascript
196+ dmn .stats .reset ();
197+ ```
198+
199+ <Callout type = " warning" >
200+ To reset ` total ` , use ` dmn.keys.resetCounters() ` or
201+ ` dmn.keys.resetCountersMode(mode) ` .
202+ </Callout >
203+
204+ ---
205+
150206## Example Usage
151207
152208``` javascript
153- // KPS counter
209+ // KPS counter using stats API
154210dmn .plugin .defineElement ({
155211 name: " KPS Counter" ,
156212 maxInstances: 1 ,
157213
158214 template : (state , settings , { html }) => html `
159215 <div style =" font-size : 24px ; font-weight : bold ;" >
160- KPS: ${ ( state .kps ?? 0 ). toFixed ( 1 ) }
216+ KPS: ${ state .kps ?? 0 } | MAX : ${ state . kpsMax ?? 0 }
161217 < / div>
162218 ` ,
163219
164220 onMount: ({ setState }) => {
165- const keyTimes = [];
166-
167- const unsub = dmn.keys.onKeyState(({ state }) => {
168- if (state !== "DOWN") return;
169-
170- const now = Date.now();
171- keyTimes.push(now);
172-
173- // Keep only last 1 second
174- while (keyTimes.length && keyTimes[0] < now - 1000) {
175- keyTimes.shift();
176- }
177-
178- setState({ kps: keyTimes.length });
221+ const unsub = dmn.stats.subscribe(({ kps, kpsMax }) => {
222+ setState({ kps, kpsMax });
179223 });
180224
181225 return () => unsub();
0 commit comments