Last active
August 29, 2015 14:06
-
-
Save ysndr/813449af4a6c05b2cede to your computer and use it in GitHub Desktop.
EnhancedEventEmitter (E3) for Node.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Description: Slightly extended EventEmitter. Ported from Node.js/events.js | |
* Author: y4ng0 @ yangodev | |
* Licence: MIT | |
*/ | |
/** | |
* EventEmitter class | |
* Creates an object with event registering and firing methods | |
*/ | |
function E3(){/* costructor */} | |
module.exports = E3 | |
E3.create = function (options) { | |
var e3 = new E3() | |
e3.init(options) | |
//delete e3.init | |
return e3 | |
} | |
E3.emitter = E3.prototype | |
// helper variables | |
var isArray = Array.isArray, | |
keys = Object.keys | |
E3.prototype = {} | |
E3.prototype.constructor = E3 | |
E3.prototype.DEFAULT_MODIFIER = null | |
E3.prototype._initialized = false | |
E3.prototype._events = null | |
// TODO rename to "subscribe" | |
E3.prototype.init = function init() { | |
if (this._initialized) return this | |
this.config.apply(this, arguments) | |
this._events = {} | |
this._initialized = true | |
return this | |
} | |
E3.prototype.config = function config(options){ | |
options = options || {} | |
this.DEFAULT_MODIFIER = options.DEFAULT_MODIFIER || 'any' | |
return this | |
} | |
E3.prototype.receive = function receive(declaration) { | |
var event = null, | |
modifier = null, | |
receiver = null | |
event = declaration.event || event | |
modifier = declaration.mod || | |
declaration.modifier || | |
this.DEFAULT_MODIFIER | |
receiver = declaration.receiver || | |
declaration.listener || | |
receiver | |
if (!event) // Throw Error | |
throw new Error('receive needs an event to listen on.') | |
if ('function' !== typeof receiver) // Throw Error | |
throw new Error('receive only takes instances of Function as receiver / listener'); | |
// To avoid recursion in the case that event == "newReceiver"! | |
// before adding it to the listeners, first emit "newReceiver" | |
this.send({ | |
event: 'newReceiver', | |
data: { | |
event: event, | |
modifier: (modifier === this.DEFAULT_MODIFIER) ? modifier + '(Default)' : modifier, | |
receiver: receiver | |
} | |
}) | |
if (!this._events[event]) { | |
this._events[event] = {} | |
} | |
if (!this._events[event][modifier]) { | |
this._events[event][modifier] = [] | |
} | |
// at this point this._events[event][modifier] is an Array we can push to! | |
this._events[event][modifier].push(receiver) | |
return this | |
} | |
E3.prototype.send = function (declaration) { | |
var event = null, | |
modifier = null, | |
data = null, | |
args = null, | |
respond_data = false, | |
response = [], | |
final = function(){} | |
event = declaration.event || event | |
event = ('string' === typeof arguments[0]) ? arguments[0] : event | |
modifier = declaration.mod || declaration.modifier || [] | |
modifier = [this.DEFAULT_MODIFIER].concat(modifier) | |
data = declaration.data || data | |
args = declaration.args || [] // given Array will be parsed to CallBack / listener as arguments | |
if (!isArray(args)) args = [].concat(args) | |
respond_data = declaration.respond_data || respond_data | |
final = declaration.final || final | |
if (!event) { // Throw Error | |
throw new Error('You have to define the argument to fire on!') | |
} | |
// Setting up data Array | |
if (!data && arguments.length > 1) { | |
var l = arguments.length | |
for (var i = 1; i < l; i++) args.push(arguments[i]) | |
} | |
if (data) args.push(data) | |
if (!this._events[event]) return this | |
var handler = this._events[event] | |
for (var m = 0, l = modifier.length; m < l; m++) { | |
if (handler[modifier[m]]) { | |
handler[modifier[m]].forEach(function (listener) { | |
response.push(listener.apply(this, args)) | |
}) | |
} | |
} | |
final(response) | |
return (respond_data) ? response : this //just to be sure | |
} | |
E3.prototype.once = function (declaration) { | |
var event = null, | |
modifier = null, | |
listener = null, | |
self = this | |
event = declaration.event || null | |
modifier = declaration.mod || declaration.modifier || modifier | |
listener = declaration.listener || declaration.receiver || listener | |
if (!event || !listener) { | |
throw new Error("You have to define at least en event + listner function") } | |
var remover = function(){ | |
self.remove(rObj) | |
listener.apply(self, arguments) | |
} | |
var rObj = { | |
event: event, | |
mod : modifier, | |
listener : remover | |
} | |
this.receive(rObj) | |
return this | |
} | |
E3.prototype.remove = function remove(declaration) { | |
var event = null, | |
modifier = null, | |
receiver = null, | |
wipe = null | |
if(!declaration || !declaration.event){ | |
this._events = {} | |
return this } // performs a fulll reset (wipes ALL events) | |
event = declaration.event || event | |
modifier = declaration.mod || | |
declaration.modifier || | |
this.DEFAULT_MODIFIER | |
receiver = declaration.receiver || | |
declaration.listener || | |
receiver | |
wipe = declaration.wipe || wipe | |
if (receiver && 'function' !== typeof receiver) { // Throw Error | |
throw new Error('remove() only takes instances of Function' + | |
'as receiver / listener') | |
} | |
if (!this._events[event]) return this | |
if (modifier === this.DEFAULT_MODIFIER && wipe) { | |
this._events[event] = {} | |
} | |
if ('function' === typeof this._events[event]) { | |
delete this._events[event] | |
return this | |
} | |
if (receiver) { | |
var list = this._events[event][modifier], | |
position = -1 | |
for (var i = 0, l = list.length; i < l; i++) { | |
if (list[i] === receiver) { | |
position = i | |
break | |
} | |
} | |
if (position < 0) return this | |
list.splice(position, 1) | |
if (list.length == 0) { | |
delete this._events[event][modifier] | |
} | |
} else { | |
delete this._events[event][modifier] | |
} | |
return this | |
} | |
E3.prototype.list = function(event, modifier){ | |
event = event || null | |
modifier = [].concat(modifier) || null | |
var output = {} | |
if (!event) return this._events // returns all events by default | |
if ('string' === typeof event && // will search the event node on _events | |
this._events[event]){ | |
output = this._events[event] } | |
else if (isArray(event)){ | |
event.forEach(function(event){ | |
if(this._events[event]) output[event] = this._events[event] | |
}) | |
} // extract all searched events from _events | |
else { | |
throw new Error('You have to set either nothing, ' | |
+ ' a representing string' | |
+ 'or an array of strings as argument') } // throws an error when event not valid | |
// Deletes all modifier (sub)nodes on every output node | |
// that are not required | |
if (modifier){ | |
keys(output).forEach(function(key){ | |
keys(output[key])(function(mod){ | |
if (modifier.indexOf(mod) < 0 && modifier.length > 0){ | |
delete output[key][mod] | |
} | |
}) | |
if (keys(output[key]).length < 1) delete output[key] | |
}) | |
} | |
return output | |
} | |
/** | |
TODO: | |
Fallback to Node.js default functionality | |
*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"name": "E3", | |
"version": "0.0.3", | |
"description": "Enhanced EventEmitter (E3) for node.js", | |
"main": "E3.js", | |
"directories": { | |
"test": "tests" | |
}, | |
"repository": { | |
"type": "git", | |
"url": "git://gist.github.com/813449af4a6c05b2cede.git" | |
}, | |
"keywords": [ | |
"Enhanced", | |
"Event", | |
"Emitter", | |
"E3" | |
], | |
"author": "y4ng0 @ yangodev", | |
"license": "MIT", | |
"bugs": { | |
"url": "https://gist.github.com/yangodev/813449af4a6c05b2cede" | |
}, | |
"url": "git://gist.github.com/813449af4a6c05b2cede.git", | |
"homepage": "https://gist.github.com/yangodev/813449af4a6c05b2cede" | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Simple EventEmitter based on and extended from Node.js events.js / EventEmitter
Used a simplified version by ericz (https://github.com/ericz/EventEmitter/blob/master/EventEmitter.js)
How to use it: