Source: controller/Utils/EventEmitter.js

/**
 * EventEmitter class to manage event-driven architecture.
 * @class
 */
class EventEmitter {
    /**
    * Creates an instance of EventEmitter.
    *
    * This constructor initializes the callbacks object, which is used to store event listeners.
    * The `base` namespace is initialized as an empty object to hold default event listeners.
    */
    constructor() {
        this.callbacks = {};
        this.callbacks.base = {};
    }
    /**
     * Registers an event listener for one or more events.
     * @param {string} _names - A string of event names separated by spaces.
     * @param {Function} callback - The function to be called when the event is triggered.
     * @returns {EventEmitter} The current instance of EventEmitter.
     */
    on(_names, callback) {
        if (typeof _names === 'undefined' || _names === '') {
            console.warn('wrong names');
            return false;
        }
        if (typeof callback === 'undefined') {
            console.warn('wrong callback');
            return false;
        }
        const names = this.resolveNames(_names);
        names.forEach((_name) => {
            const name = this.resolveName(_name);
            if (!(this.callbacks[name.namespace] instanceof Object))
                this.callbacks[name.namespace] = {};
            if (!(this.callbacks[name.namespace][name.value] instanceof Array))
                this.callbacks[name.namespace][name.value] = [];
            this.callbacks[name.namespace][name.value].push(callback);
        });
        return this;
    }
    /**
     * Removes event listeners for one or more events.
     * @param {string} _names - A string of event names separated by spaces.
     * @returns {EventEmitter} The current instance of EventEmitter.
     */
    off(_names) {
        if (typeof _names === 'undefined' || _names === '') {
            console.warn('wrong name');
            return false;
        }
        const names = this.resolveNames(_names);
        names.forEach((_name) => {
            const name = this.resolveName(_name);
            if (name.namespace !== 'base' && name.value === '') {
                delete this.callbacks[name.namespace];
            }
            else {
                if (name.namespace === 'base') {
                    for (const namespace in this.callbacks) {
                        if (this.callbacks[namespace] instanceof Object && this.callbacks[namespace][name.value] instanceof Array) {
                            delete this.callbacks[namespace][name.value];
                            if (Object.keys(this.callbacks[namespace]).length === 0)
                                delete this.callbacks[namespace];
                        }
                    }
                }
                else if (this.callbacks[name.namespace] instanceof Object && this.callbacks[name.namespace][name.value] instanceof Array) {
                    delete this.callbacks[name.namespace][name.value];
                    if (Object.keys(this.callbacks[name.namespace]).length === 0)
                        delete this.callbacks[name.namespace];
                }
            }
        });
        return this;
    }
    /**
     * Calls all event listeners for a given event.
     * @param {string} _name - The name of the event.
     * @param {any[]} [_args] - The arguments to pass to the event listeners.
     * @returns {any} The result of the event listeners.
     */
    trigger(_name, _args) {
        if (typeof _name === 'undefined' || _name === '') {
            console.warn('wrong name');
            return false;
        }
        let finalResult = null;
        let result = null;
        const args = !(_args instanceof Array) ? [] : _args;
        let nameArray = this.resolveNames(_name);
        let name = this.resolveName(nameArray[0]);
        if (name.namespace === 'base') {
            for (const namespace in this.callbacks) {
                if (this.callbacks[namespace] instanceof Object && this.callbacks[namespace][name.value] instanceof Array) {
                    this.callbacks[namespace][name.value].forEach((callback) => {
                        result = callback.apply(this, args);
                        if (typeof finalResult === 'undefined') {
                            finalResult = result;
                        }
                    });
                }
            }
        }
        else if (this.callbacks[name.namespace] instanceof Object) {
            if (name.value === '') {
                console.warn('wrong name');
                return this;
            }
            this.callbacks[name.namespace][name.value].forEach((callback) => {
                result = callback.apply(this, args);
                if (typeof finalResult === 'undefined')
                    finalResult = result;
            });
        }
        return finalResult;
    }
    /**
     * Resolves a string of event names into an array of individual names.
     * @param {string} _names - A string of event names separated by spaces.
     * @returns {string[]} An array of individual event names.
     */
    resolveNames(_names) {
        let names = _names;
        names = names.replace(/[^a-zA-Z0-9 ,/.]/g, '');
        names = names.replace(/[,/]+/g, ' ');
        names = names.split(' ');
        return names;
    }
    /**
     * Resolves a single event name into its components.
     * @param {string} name - The event name.
     * @returns {Name} An object containing the original name, the event value, and the namespace.
     */
    resolveName(name) {
        const newName = {};
        const parts = name.split('.');
        newName.original = name;
        newName.value = parts[0];
        newName.namespace = 'base';
        if (parts.length > 1 && parts[1] !== '') {
            newName.namespace = parts[1];
        }
        return newName;
    }
}
export default EventEmitter;