eventyoshi
Advanced tools
Comparing version 0.1.9 to 0.2.0
436
lib/index.js
@@ -1,6 +0,6 @@ | ||
var Stream = require('stream').Stream; | ||
var EventEmitter = require('events').EventEmitter; | ||
var util = require('util'); | ||
'use strict'; | ||
const EventEmitter = require('events').EventEmitter; | ||
/** | ||
@@ -10,283 +10,255 @@ * @constructor | ||
*/ | ||
var EventYoshi = module.exports = function() { | ||
EventEmitter.call(this); | ||
this._events = {}; | ||
this.children = []; | ||
this.__listeners = []; | ||
this.__wrappers = {}; | ||
this.__lastEvent = null; | ||
}; | ||
module.exports = class EventYoshi extends EventEmitter { | ||
constructor() { | ||
super(); | ||
this.children = new Map(); | ||
this.__wrappers = {}; | ||
this.__lastEvent = null; | ||
} | ||
util.inherits(EventYoshi, Stream); | ||
/** | ||
* Keep a copy of old EventEmitter functions | ||
* when the new functions are called publicly they will | ||
* be proxied to the emitters. | ||
*/ | ||
var addListener = EventEmitter.prototype.addListener; | ||
var emit = EventEmitter.prototype.emit; | ||
var removeListener = EventEmitter.prototype.removeListener; | ||
var removeAllListeners = EventEmitter.prototype.removeAllListeners; | ||
var setMaxListeners = EventEmitter.prototype.setMaxListeners; | ||
/** | ||
* Adds an event emitter to eventyoshi. | ||
* | ||
* @param {EventEmitter} ee | ||
* @return {EventYoshi} | ||
*/ | ||
EventYoshi.prototype.add = function(ee) { | ||
if (this.children.indexOf(ee) === -1) { | ||
var self = this; | ||
// Iterate through list of already listened to events | ||
// and listen to them on the newly added emitter. | ||
Object.keys(self._events) | ||
.forEach(function(event) { | ||
var listener = self.__wrappers[event]; | ||
if (listener) { | ||
ee.on(event, listener); | ||
} | ||
/** | ||
* Adds an event emitter to eventyoshi. | ||
* | ||
* @param {EventEmitter} ee | ||
* @return {EventYoshi} | ||
*/ | ||
add(ee) { | ||
if (!this.children.has(ee)) { | ||
// Iterate through list of already listened to events | ||
// and listen to them on the newly added emitter. | ||
Object.keys(this.__wrappers).forEach((event) => { | ||
ee.on(event, this.__wrappers[event]); | ||
}); | ||
// Listen for new listeners after adding all previous event listeners. | ||
var listen = function(event, listener) { | ||
// Listen for new listeners after adding all previous event listeners. | ||
var listen = (event, listener) => { | ||
// Do not emit `newChildListener` event if this listener | ||
// was added by eventyoshi. | ||
if (self.__wrappers[event] === listener) return; | ||
// Do not emit `newChildListener` event if this listener | ||
// was added by eventyoshi. | ||
if (this.__wrappers[event] === listener) return; | ||
self.child = ee; | ||
emit.call(self, 'newChildListener', event, listener); | ||
self.child = null; | ||
}; | ||
this.child = ee; | ||
super.emit('newChildListener', event, listener); | ||
this.child = null; | ||
}; | ||
ee.on('newListener', listen); | ||
this.__listeners.push(listen); | ||
ee.on('newListener', listen); | ||
this.children.set(ee, listen); | ||
} | ||
this.children.push(ee); | ||
return this; | ||
} | ||
return this; | ||
}; | ||
/** | ||
* Remove an event emitter from eventyoshi | ||
* remove all of the listeners that were added by eventyoshi. | ||
* | ||
* @param {EventEmitter} ee | ||
* @return {EventYoshi} | ||
*/ | ||
EventYoshi.prototype.remove = function(ee) { | ||
var i; | ||
if ((i = this.children.indexOf(ee)) !== -1) { | ||
var self = this; | ||
Object.keys(self._events) | ||
.forEach(function(event) { | ||
var listener = self.__wrappers[event]; | ||
if (listener) { | ||
ee.removeListener(event, listener); | ||
} | ||
/** | ||
* Remove an event emitter from eventyoshi | ||
* remove all of the listeners that were added by eventyoshi. | ||
* | ||
* @param {EventEmitter} ee | ||
* @return {EventYoshi} | ||
*/ | ||
remove(ee) { | ||
if (this.children.has(ee)) { | ||
Object.keys(this.__wrappers).forEach((event) => { | ||
ee.removeListener(event, this.__wrappers[event]); | ||
}); | ||
// Remove newListener listener from event emitter. | ||
ee.removeListener('newListener', this.__listeners[i]); | ||
this.__listeners.splice(i, 1); | ||
// Remove newListener listener from event emitter. | ||
ee.removeListener('newListener', this.children.get(ee)); | ||
this.children.delete(ee); | ||
} | ||
this.children.splice(i, 1); | ||
return this; | ||
} | ||
return this; | ||
}; | ||
/** | ||
* Adds listener to event emitters | ||
* | ||
* All event handling functions deal with | ||
* the special `newListener` event | ||
* in that case, it's treated only on eventyoshi | ||
* and not the rest of the emitters | ||
* | ||
* @param {String} event | ||
* @param {Function} listener | ||
* @override | ||
*/ | ||
on(event, listener) { | ||
if (event === 'newListener' || event === 'newChildListener') { | ||
super.addListener(event, listener); | ||
return; | ||
} | ||
/** | ||
* Adds listener to event emitters | ||
* | ||
* All event handling functions deal with | ||
* the special `newListener` event | ||
* in that case, it's treated only on eventyoshi | ||
* and not the rest of the emitters | ||
* | ||
* @param {String} event | ||
* @param {Function} listener | ||
* @override | ||
*/ | ||
EventYoshi.prototype.on = function(event, listener) { | ||
if (event === 'newListener' || event === 'newChildListener') { | ||
addListener.call(this, event, listener); | ||
return; | ||
} | ||
if (!this.__wrappers[event]) { | ||
if (this.__wrappers[event] === undefined) { | ||
// Proxy events emitted from each emitter onto eventyoshi | ||
// with a wrapper function. | ||
var self = this; | ||
var emit = super.emit; | ||
var wrapper = this.__wrappers[event] = function() { | ||
// Proxy events emitted from each emitter onto eventyoshi | ||
// with a wrapper function. | ||
var self = this; | ||
var wrapper = this.__wrappers[event] = function() { | ||
// Skip events emitted to yoshi. | ||
if (self.__lastEvent === event) return; | ||
// Skip events emitted to yoshi. | ||
if (self.__lastEvent === event) return; | ||
self.child = this; | ||
emit.apply(self, | ||
[event].concat(Array.prototype.slice.call(arguments))); | ||
self.child = null; | ||
}; | ||
self.child = this; | ||
emit.apply(self, | ||
[event].concat(Array.prototype.slice.call(arguments))); | ||
self.child = null; | ||
}; | ||
this.children.forEach((listener, ee) => { | ||
ee.on(event, wrapper); | ||
}); | ||
} | ||
this.children.forEach(function(ee) { | ||
ee.on(event, wrapper); | ||
}); | ||
this.child = this; | ||
super.addListener(event, listener); | ||
this.child = null; | ||
} | ||
this.child = this; | ||
addListener.call(this, event, listener); | ||
this.child = null; | ||
}; | ||
/** | ||
* @alias EventYoshi.prototype.addListener | ||
*/ | ||
addListener(event, listener) { | ||
this.on(event, listener); | ||
} | ||
/** | ||
* @alias EventYoshi.prototype.addListener | ||
*/ | ||
EventYoshi.prototype.addListener = EventYoshi.prototype.on; | ||
/** | ||
* @param {String} event | ||
* @param {Function} listener | ||
* @override | ||
*/ | ||
once(event, listener) { | ||
var self = this; | ||
var wrapper = function() { | ||
self.removeListener(event, wrapper); | ||
listener.apply(self, arguments); | ||
}; | ||
/** | ||
* @param {String} event | ||
* @param {Function} listener | ||
* @override | ||
*/ | ||
EventYoshi.prototype.once = function(event, listener) { | ||
var self = this; | ||
var wrapper = function() { | ||
self.removeListener(event, wrapper); | ||
listener.apply(self, arguments); | ||
}; | ||
wrapper.listener = listener; | ||
wrapper.listener = listener; | ||
self.on(event, wrapper); | ||
} | ||
self.on(event, wrapper); | ||
}; | ||
/** | ||
* `removeListener` and `removeAllListeners` must iterate through | ||
* the list of previously added listeners, | ||
* remove the wrapper from the emitters | ||
* and remove the listener from eventyoshi. | ||
* | ||
* @param {String} event | ||
* @param {Function} listener | ||
* @override | ||
*/ | ||
removeListener(event, listener) { | ||
if (event === 'newListener' || event === 'newChildListener') { | ||
super.removeListener(event, listener); | ||
return; | ||
} | ||
/** | ||
* `removeListener` and `removeAllListeners` must iterate through | ||
* the list of previously added listeners, | ||
* remove the wrapper from the emitters | ||
* and remove the listener from eventyoshi. | ||
* | ||
* @param {String} event | ||
* @param {Function} listener | ||
* @override | ||
*/ | ||
EventYoshi.prototype.removeListener = function(event, listener) { | ||
if (event === 'newListener' || event === 'newChildListener') { | ||
removeListener.call(this, event, listener); | ||
return; | ||
super.removeListener(event, listener); | ||
// Check if wrapper needs to be removed | ||
// by checking if there are anymore listeners for this event. | ||
var wrapper = this.__wrappers[event]; | ||
if (!super.listeners(event).length && wrapper) { | ||
this.children.forEach((listener, ee) => { | ||
ee.removeListener(event, wrapper); | ||
}); | ||
delete this.__wrappers[event]; | ||
} | ||
} | ||
removeListener.call(this, event, listener); | ||
// Check if wrapper needs to be removed | ||
// by checking if there are anymore listeners for this event. | ||
var wrapper = this.__wrappers[event]; | ||
if (!EventEmitter.prototype.listeners.call(this, event).length && | ||
wrapper !== undefined) { | ||
this.children.forEach(function(ee) { | ||
ee.removeListener(event, wrapper); | ||
}); | ||
delete this.__wrappers[event]; | ||
} | ||
}; | ||
/** | ||
* @param {String} event Optional event. | ||
* If not given, removes all events in emitter. | ||
* | ||
* @override | ||
*/ | ||
removeAllListeners(event) { | ||
if (event != null) { | ||
if (event === 'newListener' || event === 'newChildListener') { | ||
super.removeAllListeners(event); | ||
return; | ||
} | ||
if (EventEmitter.prototype.listeners.call(this, event).length) { | ||
this.children.forEach((listener, ee) => { | ||
ee.removeAllListeners(event); | ||
}); | ||
super.removeAllListeners(event); | ||
} | ||
/** | ||
* @param {String} event Optional event. | ||
* If not given, removes all events in emitter. | ||
* | ||
* @override | ||
*/ | ||
EventYoshi.prototype.removeAllListeners = function(event) { | ||
if (event != null) { | ||
if (event === 'newListener' || event === 'newChildListener') { | ||
removeAllListeners.call(this, event); | ||
return; | ||
} | ||
if (EventEmitter.prototype.listeners.call(this, event).length) { | ||
this.children.forEach(function(ee) { | ||
ee.removeAllListeners(event); | ||
} else { | ||
this.children.forEach((listener, ee) => { | ||
ee.removeAllListeners(); | ||
}); | ||
removeAllListeners.call(this, event); | ||
super.removeAllListeners(); | ||
} | ||
} | ||
} else { | ||
this.children.forEach(function(ee) { | ||
ee.removeAllListeners(); | ||
/** | ||
* Proxy the rest of EventEmitter's functions from eventyoshi | ||
* to all of the emitters added. | ||
* Note that addListener/on cannot simply be proxied due to | ||
* once and the `addListener` event | ||
* | ||
* @param {Number} n | ||
*/ | ||
setMaxListeners(n) { | ||
super.setMaxListeners(n); | ||
this.children.forEach((listener, ee) => { | ||
ee.setMaxListeners(n); | ||
}); | ||
removeAllListeners.call(this); | ||
} | ||
}; | ||
/** | ||
* Proxy the rest of EventEmitter's functions from eventyoshi | ||
* to all of the emitters added. | ||
* Note that addListener/on cannot simply be proxied due to | ||
* once and the `addListener` event | ||
* | ||
* @param {Number} n | ||
*/ | ||
EventYoshi.prototype.setMaxListeners = function(n) { | ||
setMaxListeners.call(this, n); | ||
this.children.forEach(function(ee) { | ||
ee.setMaxListeners(n); | ||
}); | ||
}; | ||
/** | ||
* @param {String} event | ||
* @param {Object...} args | ||
*/ | ||
emit(event) { | ||
var args = arguments; | ||
super.emit.apply(this, args); | ||
if (event === 'newListener') return; | ||
this.__lastEvent = event; | ||
/** | ||
* @param {String} event | ||
* @param {Object...} args | ||
*/ | ||
EventYoshi.prototype.emit = function(event) { | ||
var args = arguments; | ||
emit.apply(this, args); | ||
if (event === 'newListener') return; | ||
this.children.forEach((listener, ee) => { | ||
ee.emit.apply(ee, args); | ||
}); | ||
this.__lastEvent = event; | ||
this.__lastEvent = null; | ||
} | ||
this.children.forEach(function(ee) { | ||
ee.emit.apply(ee, args); | ||
}); | ||
this.__lastEvent = null; | ||
}; | ||
/** | ||
* Proxy custom functions. | ||
* | ||
* @param {String...} funcs | ||
*/ | ||
proxy() { | ||
var self = this; | ||
Array.prototype.slice.call(arguments).forEach((fn) => { | ||
self[fn] = function() { | ||
var args = arguments; | ||
var rs = []; | ||
/** | ||
* Proxy custom functions. | ||
* | ||
* @param {String...} funcs | ||
*/ | ||
EventYoshi.prototype.proxy = function() { | ||
var self = this; | ||
self.children.forEach((listener, ee) => { | ||
if (typeof ee[fn] === 'function') { | ||
rs.push(ee[fn].apply(ee, args)); | ||
} | ||
}); | ||
Array.prototype.slice.call(arguments).forEach(function(fn) { | ||
self[fn] = function() { | ||
var args = arguments; | ||
var rs = []; | ||
self.children.forEach(function(ee) { | ||
if (typeof ee[fn] === 'function') { | ||
rs.push(ee[fn].apply(ee, args)); | ||
} | ||
}); | ||
return rs.length === 1 ? rs[0] : rs; | ||
}; | ||
}); | ||
return rs.length === 1 ? rs[0] : rs; | ||
}; | ||
}); | ||
} | ||
}; |
@@ -11,3 +11,3 @@ { | ||
], | ||
"version": "0.1.9", | ||
"version": "0.2.0", | ||
"repository": { | ||
@@ -29,9 +29,9 @@ "type": "git", | ||
"devDependencies": { | ||
"istanbul": "*", | ||
"mocha": "*" | ||
"istanbul": "^0.4.5", | ||
"mocha": "^4.0.1" | ||
}, | ||
"engines": { | ||
"node": ">=0.12" | ||
"node": ">=4" | ||
}, | ||
"license": "MIT" | ||
} |
@@ -14,4 +14,4 @@ # eventyoshi | ||
```js | ||
var EventEmtter = require('events').EventEmitter | ||
, EventYoshi = require('eventyoshi') | ||
const EventEmitter = require('events').EventEmitter; | ||
const EventYoshi = require('eventyoshi'); | ||
@@ -22,5 +22,5 @@ var ee1 = new EventEmitter(); | ||
.add(ee1) | ||
.add(ee2) | ||
.add(ee2); | ||
yoshi.on('foo', function() { | ||
yoshi.on('foo', () => { | ||
console.log('foo!'); | ||
@@ -47,3 +47,3 @@ }); | ||
var yoshi = new EventYoshi(); | ||
yoshi.on('a', function() { | ||
yoshi.on('a', () => { | ||
console.log('a emitted'); | ||
@@ -58,3 +58,3 @@ }); | ||
And as you remove emitters, all listeners that were added through event yoshi are removed too. | ||
And as you remove emitters, all listeners that were added through event yoshi are removed. | ||
@@ -95,3 +95,3 @@ ```js | ||
```js | ||
yoshi.on('event', function() { | ||
yoshi.on('event', () => { | ||
console.log('Event came from: ', this.child); | ||
@@ -98,0 +98,0 @@ }); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
11191
216