Skip to content

Instantly share code, notes, and snippets.

@Hi7cl4w
Last active December 12, 2022 08:02
Show Gist options
  • Select an option

  • Save Hi7cl4w/817b3a5854dfbf2eabfa16b7bb007cbd to your computer and use it in GitHub Desktop.

Select an option

Save Hi7cl4w/817b3a5854dfbf2eabfa16b7bb007cbd to your computer and use it in GitHub Desktop.
EventEmitter.js
/* Util Class for handling user defined event listeners */
export default class EventEmitter {
/**
* The constructor function creates an object called callbacks, which has a property called base.
*/
constructor() {
this.callbacks = {};
this.callbacks.base = {};
}
/**
* It takes a string of names and a callback function and adds the callback function to an array of
* callbacks for each name
* @param {String} _names - The name of the event you want to listen to.
* @param {() => void} callback - The function to be called when the event is triggered.
* @returns {EventEmitter} The object itself.
*/
on(_names, callback) {
// Errors
if (typeof _names === "undefined" || _names === "") {
console.warn("wrong names");
return false;
}
if (typeof callback === "undefined") {
console.warn("wrong callback");
return false;
}
// Resolve names
const names = this.resolveNames(_names);
// Each name
names.forEach((_name) => {
// Resolve name
const name = this.resolveName(_name);
// Create namespace if not exist
if (!(this.callbacks[name.namespace] instanceof Object))
this.callbacks[name.namespace] = {};
// Create callback if not exist
if (!(this.callbacks[name.namespace][name.value] instanceof Array))
this.callbacks[name.namespace][name.value] = [];
// Add callback
this.callbacks[name.namespace][name.value].push(callback);
});
return this;
}
/**
* It removes a callback from the callbacks object
* @param {String} _names - The name of the event to remove.
* @returns {EventEmitter} The object itself.
*/
off(_names) {
// Errors
if (typeof _names === "undefined" || _names === "") {
console.warn("wrong name");
return false;
}
// Resolve names
const names = this.resolveNames(_names);
// Each name
names.forEach((_name) => {
// Resolve name
const name = this.resolveName(_name);
// Remove namespace
if (name.namespace !== "base" && name.value === "") {
delete this.callbacks[name.namespace];
}
// Remove specific callback in namespace
else {
// Default
if (name.namespace === "base") {
// Try to remove from each namespace
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];
// Remove namespace if empty
if (Object.keys(this.callbacks[namespace]).length === 0)
delete this.callbacks[namespace];
}
}
}
// Specified namespace
else if (
this.callbacks[name.namespace] instanceof Object &&
this.callbacks[name.namespace][name.value] instanceof Array
) {
delete this.callbacks[name.namespace][name.value];
// Remove namespace if empty
if (Object.keys(this.callbacks[name.namespace]).length === 0)
delete this.callbacks[name.namespace];
}
}
});
return this;
}
/**
* Triggers the Event
* @param {String} _name - The name of the event you want to trigger.
* @param _args - Array of arguments to pass to the callback
* @returns The finalResult variable is being returned.
*/
trigger(_name, _args) {
// Errors
if (typeof _name === "undefined" || _name === "") {
console.warn("wrong name");
return false;
}
let finalResult = null;
let result = null;
// Default args
const args = !(_args instanceof Array) ? [] : _args;
// Resolve names (should on have one event)
let name = this.resolveNames(_name);
// Resolve name
name = this.resolveName(name[0]);
// Default namespace
if (name.namespace === "base") {
// Try to find callback in each namespace
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(function (callback) {
result = callback.apply(this, args);
if (typeof finalResult === "undefined") {
finalResult = result;
}
});
}
}
}
// Specified namespace
else if (this.callbacks[name.namespace] instanceof Object) {
if (name.value === "") {
console.warn("wrong name");
return this;
}
this.callbacks[name.namespace][name.value].forEach(function (callback) {
result = callback.apply(this, args);
if (typeof finalResult === "undefined") finalResult = result;
});
}
return finalResult;
}
/**
* It takes a string of names, removes all non-alphanumeric characters, replaces all commas and
* slashes with spaces, and then splits the string into an array of names.
* @param {String} _name - The string of names to be resolved.
* @returns An array of names.
*/
resolveNames(_names) {
let names = _names;
names = names.replace(/[^a-zA-Z0-9 ,/.]/g, "");
names = names.replace(/[,/]+/g, " ");
names = names.split(" ");
return names;
}
/**
* It takes a string and returns an object with the string split into two parts
* @param name - The name of the variable to be resolved.
* @returns An object with the following properties:
*/
resolveName(name) {
const newName = {};
const parts = name.split(".");
newName.original = name;
newName.value = parts[0];
newName.namespace = "base"; // Base namespace
// Specified namespace
if (parts.length > 1 && parts[1] !== "") {
newName.namespace = parts[1];
}
return newName;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment