From 159e53137a41424fa9e2dbb40f411656f1cfccc4 Mon Sep 17 00:00:00 2001 From: Benjamin Wegener Date: Thu, 11 Jan 2024 23:24:54 +0000 Subject: [PATCH] enh(utils) refactor emitter to use Map and Set; update logging mechanism --- lib/core/Emitter.js | 39 +++++++++++--------------------- lib/core/Logger.js | 55 +++++++++++++++++++-------------------------- 2 files changed, 36 insertions(+), 58 deletions(-) diff --git a/lib/core/Emitter.js b/lib/core/Emitter.js index 93f37ab..363cfc5 100644 --- a/lib/core/Emitter.js +++ b/lib/core/Emitter.js @@ -1,7 +1,7 @@ class Emitter { #listeners; constructor() { - this.#listeners = {}; + this.#listeners = new Map(); } /** @@ -11,10 +11,10 @@ class Emitter { * @param {Function} callback - The callback function to be executed when the event is triggered. */ on(event, callback) { - if (!this.#listeners[event]) { - this.#listeners[event] = []; + if (!this.#listeners.has(event)) { + this.#listeners.set(event, new Set()); } - this.#listeners[event].push(callback); + this.#listeners.get(event).push(callback); } /** @@ -25,28 +25,15 @@ class Emitter { * @param {Function} [callback] - The callback function to be removed. */ off(event, callback = undefined) { - if (typeof event != 'string') { - throw new TypeError('event must be a string'); - return; + if (typeof event != 'string') return; + + if (!this.#listeners.has(event)) return false; + + if (!callback || this.#listeners.get(event).size === 0) { + return this.#listeners.delete(event); } - if ( - !Array.isArray(this.#listeners[event]) || - this.#listeners[event].length === 0 - ) { - throw new TypeError( - `listener for \`${event}\` is not an array or empty` - ); - } - - if (!callback) { - this.#listeners[event] = undefined; - return; - } - - this.#listeners[event] = this.#listeners[event].filter( - (listener) => listener !== callback - ); + this.#listeners.get(event).delete(callback); } /** @@ -56,11 +43,11 @@ class Emitter { * @param {...any} args - The arguments to pass to the event listeners. */ emit(event, ...args) { - if (!this.#listeners[event]) { + if (!this.#listeners.has(event)) { return; } - for (const callback of this.#listeners[event]) { + for (const callback of [...this.#listeners.get(event)]) { callback(this, ...args); } } diff --git a/lib/core/Logger.js b/lib/core/Logger.js index 17217fd..b4b915e 100644 --- a/lib/core/Logger.js +++ b/lib/core/Logger.js @@ -55,13 +55,13 @@ class Logger { /** * Logs a message with the specified level and options. * - * @param {string} message - The message to be logged. + * @param {array} data - The message to be logged. * @param {string} level - The log level (e.g., 'info', 'warn', 'error'). * @param {object} [options] - The optional log options. * @param {number} [options.spamThreshold] - The spam threshold for duplicate messages. * @param {string} [options.namespace] - The namespace for the log message. */ - static log(message, level, options = Logger.#defaultOptions) { + static #log(data, level, options = Logger.#defaultOptions) { if (!Logger.#enabled) return; const { @@ -69,65 +69,56 @@ class Logger { namespace, } = options; - if (Logger.#lastMessage === message) { + if (Logger.#lastMessage === data) { if (spamThreshold <= Logger.#spamIndex) return; Logger.#spamIndex++; } if (typeof console[level] === 'function') { console[level]( - `[${ - namespace ? namespace + ' - ' : '' - }${level.toUpperCase()}] ${message}` + `[${namespace ? namespace + ' - ' : ''}${level.toUpperCase()}]`, + ...data ); } else { - console.log( - `[${namespace ? namespace + ' - ' : ''}LOG] ${message}` - ); + console.log(`[${namespace ? namespace + ' - ' : ''}LOG]`, ...data); } - if (Logger.#lastMessage !== message) _spamIndex = 0; - Logger.#lastMessage = message; + if (Logger.#lastMessage !== data) this.#spamIndex = 0; + Logger.#lastMessage = data; } /** - * Logs an error message. + * Logs an error. * - * @param {string} message - The error message to log. - * @param {object} options - The options for logging. Default is Logger.#defaultOptions. + * @param {string} data - The error data to log. */ - static error(message, options = Logger.#defaultOptions) { - Logger.log(message, 'error', options); + static error() { + Logger.#log([...arguments], 'error'); } /** - * Logs an informational message. + * Logs an information. * - * @param {string} message - The message to be logged. - * @param {object} options - The options for logging. (optional) + * @param {string} data - The data to be logged. */ - static info(message, options = Logger.#defaultOptions) { - Logger.log(message, 'info', options); + static info() { + Logger.#log([...arguments], 'info'); } /** - * Logs a warning message. + * Logs a warning. * - * @param {string} message - The warning message to be logged. - * @param {object} options - The options for logging. Default is Logger.#defaultOptions. + * @param {string} data - The warning data to be logged. */ - static warn(message, options = Logger.#defaultOptions) { - Logger.log(message, 'warn', options); + static warn() { + Logger.#log([...arguments], 'warn'); } /** - * Logs a warning message. - * - * @param {string} message - The warning message to be logged. - * @param {object} [options=Logger.#defaultOptions] - The options for the warning log. + * wrapper for logging warnings. */ - static warning(message, options = Logger.#defaultOptions) { - Logger.warn(message, options); + static warning() { + Logger.#log([...arguments], 'warn'); } }