export class Emitter {
    listeners = {};
    emit(type, val) {
        if (this.listeners[type]) {
            const lis = this.listeners[type];
            for (let i = 0, len = lis.length; i < lis.length; i++) {
                const fn = lis[i];
                // @ts-ignore
                fn(val);
                if (len > lis.length) {
                    if (lis[i] !== fn) {
                        i--;
                        len = lis.length;
                    }
                }
            }
        }
    }
    on(type, fn) {
        if (!this.listeners[type]) {
            this.listeners[type] = [];
        }
        this.listeners[type].push(fn);
    }
    removeAllListeners() {
        this.listeners = {};
    }
    once(type, fn) {
        if (!fn) {
            return new Promise((resolve) => {
                const listener = (v) => {
                    resolve(v);
                    this.off(type, listener);
                };
                this.on(type, listener);
            });
        }
        // TODO: optmize this
        const listener = () => {
            this.off(type, listener);
            this.off(type, fn);
        };
        this.on(type, fn);
        this.on(type, listener);
    }
    off(type, fn) {
        const listeners = this.listeners[type];
        if (listeners) {
            if (!fn) {
                delete this.listeners[type];
            }
            else {
                for (let i = 0; i < listeners.length; i++) {
                    if (listeners[i] === fn) {
                        listeners.splice(i, 1);
                        break;
                    }
                }
                if (listeners.length === 0) {
                    delete this.listeners[type];
                }
            }
        }
    }
}
//# sourceMappingURL=Emitter.js.map