Skip to content

Commit 53681ad

Browse files
authored
fix(listener): add and remove maximum listeners (#230)
BREAKING CHANGE: Listeners will now be automatically unloaded if no emitter is found
1 parent 8307313 commit 53681ad

File tree

1 file changed

+43
-7
lines changed

1 file changed

+43
-7
lines changed

src/lib/structures/Listener.ts

+43-7
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,24 @@ import { Events } from '../types/Events';
4343
* ```
4444
*/
4545
export abstract class Listener<E extends keyof ClientEvents | symbol = ''> extends Piece {
46+
/**
47+
* The emitter, if any.
48+
* @since 2.0.0
49+
*/
4650
public readonly emitter: EventEmitter | null;
51+
52+
/**
53+
* The name of the event the listener listens to.
54+
* @since 2.0.0
55+
*/
4756
public readonly event: string;
48-
public readonly once: boolean;
4957

50-
// eslint-disable-next-line @typescript-eslint/explicit-member-accessibility
51-
#listener: ((...args: any[]) => void) | null;
58+
/**
59+
* Whether or not the listener will be unloaded after the first run.
60+
* @since 2.0.0
61+
*/
62+
public readonly once: boolean;
63+
private _listener: ((...args: any[]) => void) | null;
5264

5365
public constructor(context: PieceContext, options: EventOptions = {}) {
5466
super(context, options);
@@ -61,22 +73,46 @@ export abstract class Listener<E extends keyof ClientEvents | symbol = ''> exten
6173
this.event = options.event ?? this.name;
6274
this.once = options.once ?? false;
6375

64-
this.#listener = this.emitter && this.event ? (this.once ? this._runOnce.bind(this) : this._run.bind(this)) : null;
76+
this._listener = this.emitter && this.event ? (this.once ? this._runOnce.bind(this) : this._run.bind(this)) : null;
77+
78+
// If there's no emitter or no listener, disable:
79+
if (this.emitter === null || this._listener === null) this.enabled = false;
6580
}
6681

6782
public abstract run(...args: E extends keyof ClientEvents ? ClientEvents[E] : unknown[]): unknown;
6883

6984
public onLoad() {
70-
if (this.#listener) this.emitter![this.once ? 'once' : 'on'](this.event, this.#listener);
85+
if (this._listener) {
86+
const emitter = this.emitter!;
87+
88+
// Increment the maximum amount of listeners by one:
89+
const maxListeners = emitter.getMaxListeners();
90+
if (maxListeners !== 0) emitter.setMaxListeners(maxListeners + 1);
91+
92+
emitter[this.once ? 'once' : 'on'](this.event, this._listener);
93+
}
94+
return super.onLoad();
7195
}
7296

7397
public onUnload() {
74-
if (!this.once && this.#listener) this.emitter!.off(this.event, this.#listener);
98+
if (!this.once && this._listener) {
99+
const emitter = this.emitter!;
100+
101+
// Increment the maximum amount of listeners by one:
102+
const maxListeners = emitter.getMaxListeners();
103+
if (maxListeners !== 0) emitter.setMaxListeners(maxListeners - 1);
104+
105+
emitter.off(this.event, this._listener);
106+
this._listener = null;
107+
}
108+
109+
return super.onUnload();
75110
}
76111

77112
public toJSON(): Record<PropertyKey, unknown> {
78113
return {
79114
...super.toJSON(),
115+
once: this.once,
80116
event: this.event
81117
};
82118
}
@@ -91,7 +127,7 @@ export abstract class Listener<E extends keyof ClientEvents | symbol = ''> exten
91127

92128
private async _runOnce(...args: unknown[]) {
93129
await this._run(...args);
94-
await this.store.unload(this);
130+
await this.unload();
95131
}
96132
}
97133

0 commit comments

Comments
 (0)