Event Source/Handler helpers with optional frequency ratio limit

A few simple generic classes to create event sources and handlers. The handlers can optionally be set to receive events with a maximum frequency limit.

type EventHandlerCallback = (...args: any[]) => void;

export class EventHandler {
    private readonly source: EventSource;
    private readonly callback: EventHandlerCallback;
    private readonly maxFrequency: number = 0;
    private lastFired: number = 0;

    constructor(source: EventSource, callback: EventHandlerCallback, maxFrequency: number) {
        this.source = source;
        this.callback = callback;
        this.maxFrequency = maxFrequency;
    }

    fire(args: any[]): void {
        const now = performance.now() / 1000;
        if (this.maxFrequency > 0 && now - this.lastFired < this.maxFrequency) {
            return;
        }
        this.lastFired = now;
        this.callback.apply(null, args);
    }

    remove(): void {
        this.source.removeHandler(this);
    }
}

export class EventSource {
    private readonly handlers: EventHandler[] = [];

    addHandler(callback: EventHandlerCallback, maxFrequency: number = 0): EventHandler {
        const handler = new EventHandler(this, callback, maxFrequency);
        this.handlers.push(handler);
        return handler;
    }
    removeHandler(handler: EventHandler): void {
        const idx = this.handlers.indexOf(handler);
        if (idx == -1) {
            return;
        }
        this.handlers.splice(idx, 1);
    }

    fire(...args: any[]): void {
        for (const handler of this.handlers) {
            handler.fire(args);
        }
    }
}