inventoresed
Version:
Z-Wave driver written entirely in JavaScript/TypeScript
62 lines (53 loc) • 1.66 kB
text/typescript
import { throttle } from "@zwave-js/shared";
import type EventEmitter from "events";
/** Mixin to provide statistics functionality. Requires the base class to extend EventEmitter. */
export abstract class StatisticsHost<T> {
protected abstract createEmpty(): T;
private _statistics: T | undefined;
public get statistics(): Readonly<T> {
if (!this._statistics) this.resetStatistics();
return Object.freeze(this._statistics!);
}
public resetStatistics(): void {
this.updateStatistics(() => this.createEmpty());
}
/** Can be overridden in derived classes to specify additional args to be included in the statistics event callback. */
protected getAdditionalEventArgs(): any[] {
return [];
}
private _emitUpdate: ((stat: T) => void) | undefined;
public updateStatistics(updater: (current: Readonly<T>) => T): void {
this._statistics = updater(this._statistics ?? this.createEmpty());
if (!this._emitUpdate) {
this._emitUpdate = throttle(
(this as unknown as EventEmitter).emit.bind(
this,
"statistics updated",
...this.getAdditionalEventArgs(),
),
250,
true,
);
}
this._emitUpdate(this._statistics);
}
public incrementStatistics(property: keyof T): void {
this.updateStatistics((s) => {
const value = s[property];
if (typeof value === "number") {
return {
...s,
[property]: value + 1,
};
} else {
return s;
}
});
}
}
export interface StatisticsEventCallbacks<T> {
"statistics updated": (statistics: T) => void;
}
export interface StatisticsEventCallbacksWithSelf<TSelf, TStats> {
"statistics updated": (self: TSelf, statistics: TStats) => void;
}