mirror of
https://github.com/tiramisulabs/seyfert.git
synced 2025-07-03 21:46:08 +00:00

* fix: silly eslint bug * fix: Linter Errors (#105) * fix * revert linter bug Co-authored-by: Marcos Susaña <marcosjgs03@gmail.com>
71 lines
2.5 KiB
TypeScript
71 lines
2.5 KiB
TypeScript
import type { Session, Events } from '@biscuitland/core';
|
|
import { EventEmitter } from 'node:events';
|
|
|
|
|
|
export interface CollectorOptions<E extends keyof Events> {
|
|
event: E;
|
|
filter?(...args: Parameters<Events[E]>): unknown;
|
|
max?: number;
|
|
time?: number;
|
|
idle?: number;
|
|
}
|
|
|
|
export class Collector<E extends keyof Events> extends EventEmitter {
|
|
collected = new Set<Parameters<Events[E]>[0]>();
|
|
ended = false;
|
|
|
|
private timeout: NodeJS.Timeout;
|
|
|
|
constructor(readonly session: Session, public options: CollectorOptions<E>) {
|
|
super();
|
|
|
|
if (!('filter' in this.options)) { this.options.filter = (() => true); }
|
|
|
|
if (!('max' in this.options)) { this.options.max = -1; }
|
|
|
|
this.session.events.setMaxListeners(this.session.events.getMaxListeners() + 1);
|
|
|
|
this.session.events.on(this.options.event, (...args: unknown[]) => this.collect(...args as Parameters<Events[E]>));
|
|
|
|
this.timeout = setTimeout(() => this.stop('time'), this.options.idle ?? this.options.time);
|
|
}
|
|
|
|
private collect(...args: Parameters<Events[E]>) {
|
|
if (this.options.filter?.(...args)) {
|
|
this.collected.add(args[0]);
|
|
this.emit('collect', ...args);
|
|
}
|
|
|
|
if (this.options.idle) {
|
|
clearTimeout(this.timeout);
|
|
this.timeout = setTimeout(() => this.stop('time'), this.options.idle);
|
|
}
|
|
|
|
if (this.collected.size >= this.options.max!) { this.stop('max'); }
|
|
}
|
|
|
|
stop(reason?: string) {
|
|
if (this.ended) { return; }
|
|
|
|
clearTimeout(this.timeout);
|
|
|
|
this.session.events.removeListener(this.options.event, (...args: unknown[]) => this.collect(...args as Parameters<Events[E]>));
|
|
this.session.events.setMaxListeners(this.session.events.getMaxListeners() - 1);
|
|
|
|
this.ended = true;
|
|
this.emit('end', reason, this.collected);
|
|
}
|
|
|
|
on(event: 'collect', listener: (...args: Parameters<Events[E]>) => unknown): this;
|
|
on(event: 'end', listener: (reason: string | null | undefined, collected: Set<Parameters<Events[E]>[0]>) => void): this;
|
|
on(event: string, listener: unknown): this {
|
|
return super.on(event, listener as (() => unknown));
|
|
}
|
|
|
|
once(event: 'collect', listener: (...args: Parameters<Events[E]>) => unknown): this;
|
|
once(event: 'end', listener: (reason: string | null | undefined, collected: Set<Parameters<Events[E]>[0]>) => void): this;
|
|
once(event: string, listener: unknown): this {
|
|
return super.once(event, listener as (() => unknown));
|
|
}
|
|
}
|