enh(utils) refactor emitter to use Map and Set; update logging mechanism

This commit is contained in:
Benjamin Wegener
2024-01-11 23:24:54 +00:00
parent c7ab75ecdb
commit 159e53137a
2 changed files with 36 additions and 58 deletions

View File

@@ -1,7 +1,7 @@
class Emitter { class Emitter {
#listeners; #listeners;
constructor() { 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. * @param {Function} callback - The callback function to be executed when the event is triggered.
*/ */
on(event, callback) { on(event, callback) {
if (!this.#listeners[event]) { if (!this.#listeners.has(event)) {
this.#listeners[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. * @param {Function} [callback] - The callback function to be removed.
*/ */
off(event, callback = undefined) { off(event, callback = undefined) {
if (typeof event != 'string') { if (typeof event != 'string') return;
throw new TypeError('event must be a string');
return; if (!this.#listeners.has(event)) return false;
if (!callback || this.#listeners.get(event).size === 0) {
return this.#listeners.delete(event);
} }
if ( this.#listeners.get(event).delete(callback);
!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
);
} }
/** /**
@@ -56,11 +43,11 @@ class Emitter {
* @param {...any} args - The arguments to pass to the event listeners. * @param {...any} args - The arguments to pass to the event listeners.
*/ */
emit(event, ...args) { emit(event, ...args) {
if (!this.#listeners[event]) { if (!this.#listeners.has(event)) {
return; return;
} }
for (const callback of this.#listeners[event]) { for (const callback of [...this.#listeners.get(event)]) {
callback(this, ...args); callback(this, ...args);
} }
} }

View File

@@ -55,13 +55,13 @@ class Logger {
/** /**
* Logs a message with the specified level and options. * 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 {string} level - The log level (e.g., 'info', 'warn', 'error').
* @param {object} [options] - The optional log options. * @param {object} [options] - The optional log options.
* @param {number} [options.spamThreshold] - The spam threshold for duplicate messages. * @param {number} [options.spamThreshold] - The spam threshold for duplicate messages.
* @param {string} [options.namespace] - The namespace for the log message. * @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; if (!Logger.#enabled) return;
const { const {
@@ -69,65 +69,56 @@ class Logger {
namespace, namespace,
} = options; } = options;
if (Logger.#lastMessage === message) { if (Logger.#lastMessage === data) {
if (spamThreshold <= Logger.#spamIndex) return; if (spamThreshold <= Logger.#spamIndex) return;
Logger.#spamIndex++; Logger.#spamIndex++;
} }
if (typeof console[level] === 'function') { if (typeof console[level] === 'function') {
console[level]( console[level](
`[${ `[${namespace ? namespace + ' - ' : ''}${level.toUpperCase()}]`,
namespace ? namespace + ' - ' : '' ...data
}${level.toUpperCase()}] ${message}`
); );
} else { } else {
console.log( console.log(`[${namespace ? namespace + ' - ' : ''}LOG]`, ...data);
`[${namespace ? namespace + ' - ' : ''}LOG] ${message}`
);
} }
if (Logger.#lastMessage !== message) _spamIndex = 0; if (Logger.#lastMessage !== data) this.#spamIndex = 0;
Logger.#lastMessage = message; Logger.#lastMessage = data;
} }
/** /**
* Logs an error message. * Logs an error.
* *
* @param {string} message - The error message to log. * @param {string} data - The error data to log.
* @param {object} options - The options for logging. Default is Logger.#defaultOptions.
*/ */
static error(message, options = Logger.#defaultOptions) { static error() {
Logger.log(message, 'error', options); Logger.#log([...arguments], 'error');
} }
/** /**
* Logs an informational message. * Logs an information.
* *
* @param {string} message - The message to be logged. * @param {string} data - The data to be logged.
* @param {object} options - The options for logging. (optional)
*/ */
static info(message, options = Logger.#defaultOptions) { static info() {
Logger.log(message, 'info', options); Logger.#log([...arguments], 'info');
} }
/** /**
* Logs a warning message. * Logs a warning.
* *
* @param {string} message - The warning message to be logged. * @param {string} data - The warning data to be logged.
* @param {object} options - The options for logging. Default is Logger.#defaultOptions.
*/ */
static warn(message, options = Logger.#defaultOptions) { static warn() {
Logger.log(message, 'warn', options); Logger.#log([...arguments], 'warn');
} }
/** /**
* Logs a warning message. * wrapper for logging warnings.
*
* @param {string} message - The warning message to be logged.
* @param {object} [options=Logger.#defaultOptions] - The options for the warning log.
*/ */
static warning(message, options = Logger.#defaultOptions) { static warning() {
Logger.warn(message, options); Logger.#log([...arguments], 'warn');
} }
} }