diff --git a/rpc/src/utils/emitter.ts b/rpc/src/utils/emitter.ts index 9adca71..76a9882 100644 --- a/rpc/src/utils/emitter.ts +++ b/rpc/src/utils/emitter.ts @@ -1,23 +1,22 @@ import { RPCErrors } from './types' +/** + * Accepts any callback. Argument types are enforced by the typed `on*`/`emit*` + * methods that wrap the emitter, not here. + */ +type Handler = (...args: never[]) => unknown + +/** One handler per event: registering an event again replaces its handler. */ export class Emitter { - /** Map */ - private _storage: Map any, boolean]> + /** Map */ + private _storage = new Map() - constructor() { - this._storage = new Map() - } - - get _raw_storage() { - return this._storage - } - - public on(event: string, cb: (...args: any[]) => any): this { + public on(event: string, cb: Handler): this { this._storage.set(event, [cb, false]) return this } - public once(event: string, cb: (...args: any[]) => any): this { + public once(event: string, cb: Handler): this { this._storage.set(event, [cb, true]) return this } @@ -31,24 +30,17 @@ export class Emitter { return this._storage.has(event) } - public async emit(event: string, ...args: any[]): Promise { - return new Promise((res, rej) => { - if (!this._storage.has(event)) { - rej(RPCErrors.EVENT_NOT_REGISTERED) - } + public async emit(event: string, ...args: unknown[]): Promise { + const entry = this._storage.get(event) + if (!entry) { + throw new Error(RPCErrors.EVENT_NOT_REGISTERED) + } - const [cb, once] = this._storage.get(event) as [ - (...args: any[]) => any, - boolean, - ] + const [cb, once] = entry + if (once) { + this._storage.delete(event) + } - if (once) { - this._storage.delete(event) - } - - Promise.resolve(cb(...args)) - .then(res) - .catch(rej) - }) + return (await cb(...(args as never[]))) as R } }