eventemitter2
Advanced tools
Comparing version 6.4.0 to 6.4.1
@@ -9,2 +9,7 @@ # Change Log | ||
## [6.4.1] - 2020-05-10 | ||
### Fixed | ||
- increased emitter performance in wildcard mode | ||
## [6.4.0] - 2020-05-04 | ||
@@ -11,0 +16,0 @@ |
@@ -419,8 +419,36 @@ /*! | ||
// | ||
function searchListenerTree(handlers, type, tree, i) { | ||
function searchListenerTree(handlers, type, tree, i, typeLength) { | ||
if (!tree) { | ||
return []; | ||
return null; | ||
} | ||
var listeners=[], leaf, len, branch, xTree, xxTree, isolatedBranch, endReached, | ||
typeLength = type.length, currentType = type[i], nextType = type[i+1]; | ||
if (i === 0) { | ||
var kind = typeof type; | ||
if (kind === 'string') { | ||
var ns, n, l = 0, j = 0, delimiter = this.delimiter, dl = delimiter.length; | ||
if ((n = type.indexOf(delimiter)) !== -1) { | ||
ns = new Array(5); | ||
do { | ||
ns[l++] = type.slice(j, n); | ||
j = n + dl; | ||
} while ((n = type.indexOf(delimiter, j)) !== -1); | ||
ns[l++] = type.slice(j); | ||
type = ns; | ||
typeLength = l; | ||
} else { | ||
type = [type]; | ||
typeLength = 1; | ||
} | ||
} else if (kind === 'object') { | ||
typeLength = type.length; | ||
} else { | ||
type = [type]; | ||
typeLength = 1; | ||
} | ||
} | ||
var listeners= null, branch, xTree, xxTree, isolatedBranch, endReached, currentType = type[i], | ||
nextType = type[i + 1], branches, _listeners; | ||
if (i === typeLength && tree._listeners) { | ||
@@ -435,5 +463,3 @@ // | ||
} else { | ||
for (leaf = 0, len = tree._listeners.length; leaf < len; leaf++) { | ||
handlers && handlers.push(tree._listeners[leaf]); | ||
} | ||
handlers && handlers.push.apply(handlers, tree._listeners); | ||
return [tree]; | ||
@@ -443,3 +469,3 @@ } | ||
if ((currentType === '*' || currentType === '**') || tree[currentType]) { | ||
if (currentType === '*') { | ||
// | ||
@@ -449,38 +475,63 @@ // If the event emitted is '*' at this part | ||
// | ||
if (currentType === '*') { | ||
for (branch in tree) { | ||
if (branch !== '_listeners' && tree.hasOwnProperty(branch)) { | ||
listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], i+1)); | ||
branches= ownKeys(tree); | ||
n= branches.length; | ||
while(n-->0){ | ||
branch= branches[n]; | ||
if (branch !== '_listeners') { | ||
_listeners = searchListenerTree(handlers, type, tree[branch], i + 1, typeLength); | ||
if(_listeners){ | ||
if(listeners){ | ||
listeners.push.apply(listeners, _listeners); | ||
}else{ | ||
listeners = _listeners; | ||
} | ||
} | ||
} | ||
return listeners; | ||
} else if(currentType === '**') { | ||
endReached = (i+1 === typeLength || (i+2 === typeLength && nextType === '*')); | ||
if(endReached && tree._listeners) { | ||
// The next element has a _listeners, add it to the handlers. | ||
listeners = listeners.concat(searchListenerTree(handlers, type, tree, typeLength)); | ||
} | ||
} | ||
return listeners; | ||
} else if (currentType === '**') { | ||
endReached = (i + 1 === typeLength || (i + 2 === typeLength && nextType === '*')); | ||
if (endReached && tree._listeners) { | ||
// The next element has a _listeners, add it to the handlers. | ||
listeners = searchListenerTree(handlers, type, tree, typeLength, typeLength); | ||
} | ||
for (branch in tree) { | ||
if (branch !== '_listeners' && tree.hasOwnProperty(branch)) { | ||
if(branch === '*' || branch === '**') { | ||
if(tree[branch]._listeners && !endReached) { | ||
listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], typeLength)); | ||
branches= ownKeys(tree); | ||
n= branches.length; | ||
while(n-->0){ | ||
branch= branches[n]; | ||
if (branch !== '_listeners') { | ||
if (branch === '*' || branch === '**') { | ||
if (tree[branch]._listeners && !endReached) { | ||
_listeners = searchListenerTree(handlers, type, tree[branch], typeLength, typeLength); | ||
if(_listeners){ | ||
if(listeners){ | ||
listeners.push.apply(listeners, _listeners); | ||
}else{ | ||
listeners = _listeners; | ||
} | ||
} | ||
listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], i)); | ||
} else if(branch === nextType) { | ||
listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], i+2)); | ||
} else { | ||
// No match on this one, shift into the tree but not in the type array. | ||
listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], i)); | ||
} | ||
_listeners = searchListenerTree(handlers, type, tree[branch], i, typeLength); | ||
} else if (branch === nextType) { | ||
_listeners = searchListenerTree(handlers, type, tree[branch], i + 2, typeLength); | ||
} else { | ||
// No match on this one, shift into the tree but not in the type array. | ||
_listeners = searchListenerTree(handlers, type, tree[branch], i, typeLength); | ||
} | ||
if(_listeners){ | ||
if(listeners){ | ||
listeners.push.apply(listeners, _listeners); | ||
}else{ | ||
listeners = _listeners; | ||
} | ||
} | ||
} | ||
return listeners; | ||
} | ||
listeners = listeners.concat(searchListenerTree(handlers, type, tree[currentType], i+1)); | ||
return listeners; | ||
}else if (tree[currentType]) { | ||
listeners= searchListenerTree(handlers, type, tree[currentType], i + 1, typeLength); | ||
} | ||
xTree = tree['*']; | ||
xTree = tree['*']; | ||
if (xTree) { | ||
@@ -491,34 +542,37 @@ // | ||
// | ||
searchListenerTree(handlers, type, xTree, i+1); | ||
searchListenerTree(handlers, type, xTree, i + 1, typeLength); | ||
} | ||
xxTree = tree['**']; | ||
if(xxTree) { | ||
if(i < typeLength) { | ||
if(xxTree._listeners) { | ||
if (xxTree) { | ||
if (i < typeLength) { | ||
if (xxTree._listeners) { | ||
// If we have a listener on a '**', it will catch all, so add its handler. | ||
searchListenerTree(handlers, type, xxTree, typeLength); | ||
searchListenerTree(handlers, type, xxTree, typeLength, typeLength); | ||
} | ||
// Build arrays of matching next branches and others. | ||
for(branch in xxTree) { | ||
if(branch !== '_listeners' && xxTree.hasOwnProperty(branch)) { | ||
if(branch === nextType) { | ||
branches= ownKeys(xxTree); | ||
n= branches.length; | ||
while(n-->0){ | ||
branch= branches[n]; | ||
if (branch !== '_listeners') { | ||
if (branch === nextType) { | ||
// We know the next element will match, so jump twice. | ||
searchListenerTree(handlers, type, xxTree[branch], i+2); | ||
} else if(branch === currentType) { | ||
searchListenerTree(handlers, type, xxTree[branch], i + 2, typeLength); | ||
} else if (branch === currentType) { | ||
// Current node matches, move into the tree. | ||
searchListenerTree(handlers, type, xxTree[branch], i+1); | ||
searchListenerTree(handlers, type, xxTree[branch], i + 1, typeLength); | ||
} else { | ||
isolatedBranch = {}; | ||
isolatedBranch[branch] = xxTree[branch]; | ||
searchListenerTree(handlers, type, { '**': isolatedBranch }, i+1); | ||
searchListenerTree(handlers, type, {'**': isolatedBranch}, i + 1, typeLength); | ||
} | ||
} | ||
} | ||
} else if(xxTree._listeners) { | ||
} else if (xxTree._listeners) { | ||
// We have reached the end and still on a '**' | ||
searchListenerTree(handlers, type, xxTree, typeLength); | ||
} else if(xxTree['*'] && xxTree['*']._listeners) { | ||
searchListenerTree(handlers, type, xxTree['*'], typeLength); | ||
searchListenerTree(handlers, type, xxTree, typeLength, typeLength); | ||
} else if (xxTree['*'] && xxTree['*']._listeners) { | ||
searchListenerTree(handlers, type, xxTree['*'], typeLength, typeLength); | ||
} | ||
@@ -531,27 +585,43 @@ } | ||
function growListenerTree(type, listener) { | ||
var len = 0, j = 0, i, delimiter = this.delimiter, dl= delimiter.length, ns; | ||
type = typeof type === 'string' ? type.split(this.delimiter) : type.slice(); | ||
if(typeof type==='string') { | ||
if ((i = type.indexOf(delimiter)) !== -1) { | ||
ns = new Array(5); | ||
do { | ||
ns[len++] = type.slice(j, i); | ||
j = i + dl; | ||
} while ((i = type.indexOf(delimiter, j)) !== -1); | ||
ns[len++] = type.slice(j); | ||
}else{ | ||
ns= [type]; | ||
len= 1; | ||
} | ||
}else{ | ||
ns= type; | ||
len= type.length; | ||
} | ||
// | ||
// Looks for two consecutive '**', if so, don't add the event at all. | ||
// | ||
for (var i = 0, len = type.length; i + 1 < len; i++) { | ||
if (type[i] === '**' && type[i + 1] === '**') { | ||
return; | ||
if (len > 1) { | ||
for (i = 0; i + 1 < len; i++) { | ||
if (ns[i] === '**' && ns[i + 1] === '**') { | ||
return; | ||
} | ||
} | ||
} | ||
var tree = this.listenerTree; | ||
var name = type.shift(); | ||
while (name !== undefined) { | ||
if (!tree[name]) { | ||
tree[name] = {}; | ||
} | ||
var tree = this.listenerTree, name; | ||
tree = tree[name]; | ||
for (i = 0; i < len; i++) { | ||
name = ns[i]; | ||
if (type.length === 0) { | ||
tree = tree[name] || (tree[name] = {}); | ||
if (i === len - 1) { | ||
if (!tree._listeners) { | ||
@@ -577,4 +647,4 @@ tree._listeners = listener; | ||
} | ||
name = type.shift(); | ||
} | ||
return true; | ||
@@ -852,3 +922,3 @@ } | ||
var type = arguments[0], ns, wildcard= this.wildcard, kind; | ||
var type = arguments[0], ns, wildcard= this.wildcard; | ||
var args,l,i,j, containsSymbol; | ||
@@ -863,12 +933,7 @@ | ||
if (wildcard) { | ||
kind = typeof type; | ||
if (kind === 'string') { | ||
ns = type.split(this.delimiter); | ||
} else { | ||
if(kind==='symbol'){ | ||
ns= [type]; | ||
}else{ | ||
ns = type.slice(); | ||
l= type.length; | ||
if(symbolsSupported) { | ||
ns= type; | ||
if(type!=='newListener' && type!=='removeListener'){ | ||
if (typeof type === 'object') { | ||
l = type.length; | ||
if (symbolsSupported) { | ||
for (i = 0; i < l; i++) { | ||
@@ -881,3 +946,3 @@ if (typeof type[i] === 'symbol') { | ||
} | ||
if(!containsSymbol){ | ||
if (!containsSymbol) { | ||
type = type.join(this.delimiter); | ||
@@ -915,3 +980,3 @@ } | ||
handler = []; | ||
searchListenerTree.call(this, handler, ns, this.listenerTree, 0); | ||
searchListenerTree.call(this, handler, ns, this.listenerTree, 0, l); | ||
} else { | ||
@@ -984,3 +1049,3 @@ handler = this._events[type]; | ||
var type = arguments[0], wildcard= this.wildcard, ns, kind, containsSymbol; | ||
var type = arguments[0], wildcard= this.wildcard, ns, containsSymbol; | ||
var args,l,i,j; | ||
@@ -993,12 +1058,7 @@ | ||
if (wildcard) { | ||
kind = typeof type; | ||
if (kind === 'string') { | ||
ns = type.split(this.delimiter); | ||
} else { | ||
if(kind==='symbol'){ | ||
ns= [type]; | ||
}else{ | ||
ns = type.slice(); | ||
l= type.length; | ||
if(symbolsSupported) { | ||
ns= type; | ||
if(type!=='newListener' && type!=='removeListener'){ | ||
if (typeof type === 'object') { | ||
l = type.length; | ||
if (symbolsSupported) { | ||
for (i = 0; i < l; i++) { | ||
@@ -1011,3 +1071,3 @@ if (typeof type[i] === 'symbol') { | ||
} | ||
if(!containsSymbol){ | ||
if (!containsSymbol) { | ||
type = type.join(this.delimiter); | ||
@@ -1207,4 +1267,4 @@ } | ||
leafs = searchListenerTree.call(this, null, ns, this.listenerTree, 0); | ||
} | ||
else { | ||
if(!leafs) return this; | ||
} else { | ||
// does not use listeners(), so no side effect of creating _events[type] | ||
@@ -1307,7 +1367,6 @@ if (!this._events[type]) return this; | ||
if (this.wildcard) { | ||
var ns = typeof type === 'string' ? type.split(this.delimiter) : type.slice(); | ||
var leafs = searchListenerTree.call(this, null, ns, this.listenerTree, 0); | ||
for (var iLeaf = 0; iLeaf < leafs.length; iLeaf++) { | ||
var leaf = leafs[iLeaf]; | ||
var leafs = searchListenerTree.call(this, null, type, this.listenerTree, 0), leaf, i; | ||
if (!leafs) return this; | ||
for (i = 0; i < leafs.length; i++) { | ||
leaf = leafs[i]; | ||
leaf._listeners = null; | ||
@@ -1314,0 +1373,0 @@ } |
{ | ||
"name": "eventemitter2", | ||
"version": "6.4.0", | ||
"version": "6.4.1", | ||
"description": "A feature-rich Node.js event emitter implementation with namespaces, wildcards, TTL, async listeners and browser/worker support.", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
@@ -1,2 +0,2 @@ | ||
[![Build Status](https://travis-ci.com/EventEmitter2/EventEmitter2.svg?branch=master)](https://travis-ci.com/EventEmitter2/EventEmitter2) | ||
[![Build Status](https://travis-ci.org/EventEmitter2/EventEmitter2.svg?branch=master)](https://travis-ci.org/EventEmitter2/EventEmitter2) | ||
[![Coverage Status](https://coveralls.io/repos/github/EventEmitter2/EventEmitter2/badge.svg?branch=master)](https://coveralls.io/github/EventEmitter2/EventEmitter2?branch=master) | ||
@@ -38,7 +38,10 @@ [![NPM version](https://badge.fury.io/js/eventemitter2.svg)](http://badge.fury.io/js/eventemitter2) | ||
---------------------------------------------------------------- | ||
EventEmitterHeatUp x 3,167,076 ops/sec ±3.17% (59 runs sampled) | ||
EventEmitter x 3,190,460 ops/sec ±3.20% (66 runs sampled) | ||
EventEmitter2 x 11,278,456 ops/sec ±4.26% (60 runs sampled) | ||
EventEmitter2 (wild) x 4,620,369 ops/sec ±4.46% (61 runs sampled) | ||
EventEmitter3 x 10,309,717 ops/sec ±3.89% (64 runs sampled) | ||
EventEmitterHeatUp x 2,897,056 ops/sec ±3.86% (67 runs sampled) | ||
EventEmitter x 3,232,934 ops/sec ±3.50% (65 runs sampled) | ||
EventEmitter2 x 12,261,042 ops/sec ±4.72% (59 runs sampled) | ||
EventEmitter2 (wild) x 242,751 ops/sec ±5.15% (68 runs sampled) | ||
EventEmitter2 (wild) using plain events x 358,916 ops/sec ±2.58% (78 runs sampled) | ||
EventEmitter2 (wild) emitting ns x 1,837,323 ops/sec ±3.50% (72 runs sampled) | ||
EventEmitter2 (wild) emitting a plain event x 2,743,707 ops/sec ±4.08% (65 runs sampled) | ||
EventEmitter3 x 10,380,258 ops/sec ±3.93% (67 runs sampled) | ||
@@ -48,2 +51,6 @@ Fastest is EventEmitter2 | ||
### What's new | ||
To find out what's new see the project [CHANGELOG](https://github.com/EventEmitter2/EventEmitter2/blob/master/CHANGELOG.md) | ||
### Differences (Non-breaking, compatible with existing EventEmitter) | ||
@@ -90,3 +97,3 @@ | ||
emitter.emit(Symbol(), 5, 6); // Symbol() 5 6 | ||
emitter.emit(['foo', Symbol(), 7, 8]); // ['foo', Symbol()] 7 8 | ||
emitter.emit(['foo', Symbol()], 7, 8); // ['foo', Symbol()] 7 8 | ||
``` | ||
@@ -100,3 +107,3 @@ **Note**: Generally this.event is normalized to a string ('event', 'event.test'), | ||
```javascript | ||
server.many('foo', 4, function() { | ||
emitter.many('foo', 4, function() { | ||
console.log('hello'); | ||
@@ -109,3 +116,3 @@ }); | ||
```javascript | ||
server.many(['foo', 'bar', 'bazz'], 4, function() { | ||
emitter.many(['foo', 'bar', 'bazz'], 4, function() { | ||
console.log('hello'); | ||
@@ -240,3 +247,3 @@ }); | ||
emitter.emit('foo.bar.baz'); | ||
emitter.emit(['foo', Symbol(), 'baz'); | ||
emitter.emit(['foo', Symbol(), 'baz']); | ||
```` | ||
@@ -253,3 +260,3 @@ | ||
```javascript | ||
server.on('data', function(value1, value2, value3, ...) { | ||
emitter.on('data', function(value1, value2, value3, ...) { | ||
console.log('The event was raised!'); | ||
@@ -259,3 +266,3 @@ }); | ||
```javascript | ||
server.on('data', function(value) { | ||
emitter.on('data', function(value) { | ||
console.log('The event was raised!'); | ||
@@ -357,3 +364,3 @@ }); | ||
```javascript | ||
server.prependListener('data', function(value1, value2, value3, ...) { | ||
emitter.prependListener('data', function(value1, value2, value3, ...) { | ||
console.log('The event was raised!'); | ||
@@ -372,3 +379,3 @@ }); | ||
```javascript | ||
server.onAny(function(event, value) { | ||
emitter.onAny(function(event, value) { | ||
console.log('All events trigger this.'); | ||
@@ -383,3 +390,3 @@ }); | ||
```javascript | ||
server.prependAny(function(event, value) { | ||
emitter.prependAny(function(event, value) { | ||
console.log('All events trigger this.'); | ||
@@ -394,3 +401,3 @@ }); | ||
```javascript | ||
server.offAny(function(value) { | ||
emitter.offAny(function(value) { | ||
console.log('The event was raised!'); | ||
@@ -406,3 +413,3 @@ }); | ||
```javascript | ||
server.once('get', function (value) { | ||
emitter.once('get', function (value) { | ||
console.log('Ah, we have our first value!'); | ||
@@ -423,3 +430,3 @@ }); | ||
```javascript | ||
server.prependOnceListener('get', function (value) { | ||
emitter.prependOnceListener('get', function (value) { | ||
console.log('Ah, we have our first value!'); | ||
@@ -440,3 +447,3 @@ }); | ||
```javascript | ||
server.many('get', 4, function (value) { | ||
emitter.many('get', 4, function (value) { | ||
console.log('This event will be listened to exactly four times.'); | ||
@@ -458,3 +465,3 @@ }); | ||
```javascript | ||
server.many('get', 4, function (value) { | ||
emitter.many('get', 4, function (value) { | ||
console.log('This event will be listened to exactly four times.'); | ||
@@ -478,5 +485,5 @@ }); | ||
}; | ||
server.on('get', callback); | ||
emitter.on('get', callback); | ||
// ... | ||
server.removeListener('get', callback); | ||
emitter.removeListener('get', callback); | ||
``` | ||
@@ -509,6 +516,6 @@ | ||
```javascript | ||
server.on('get', function(value) { | ||
emitter.on('get', function(value) { | ||
console.log('someone connected!'); | ||
}); | ||
console.log(server.listeners('get')); // [ [Function] ] | ||
console.log(emitter.listeners('get')); // [ [Function] ] | ||
``` | ||
@@ -522,6 +529,6 @@ | ||
```javascript | ||
server.onAny(function(value) { | ||
emitter.onAny(function(value) { | ||
console.log('someone connected!'); | ||
}); | ||
console.log(server.listenersAny()[0]); // [ [Function] ] | ||
console.log(emitter.listenersAny()[0]); // [ [Function] ] | ||
``` | ||
@@ -621,3 +628,3 @@ | ||
Returns an array listing the events for which the emitter has registered listeners. The values in the array will be strings. | ||
Returns an array listing the events for which the emitter has registered listeners. | ||
```javascript | ||
@@ -627,6 +634,9 @@ var emitter= new EventEmitter2(); | ||
emitter.on('bar', () => {}); | ||
emitter.on(Symbol('test'), () => {}); | ||
emitter.on(['foo', Symbol('test2')], () => {}); | ||
console.log(emitter.eventNames()); | ||
// Prints: [ 'foo', 'bar' ] | ||
// Prints: [ 'bar', 'foo', [ 'foo', Symbol(test2) ], [ 'foo', Symbol(test2) ] ] | ||
``` | ||
**Note**: Listeners order not guaranteed | ||
### listenTo(targetEmitter, events: event | eventNS, options?) | ||
@@ -693,3 +703,23 @@ | ||
```` | ||
An example of using a wildcard emitter in a browser: | ||
````javascript | ||
const ee= new EventEmitter2({ | ||
wildcard: true | ||
}); | ||
ee.listenTo(document.querySelector('#test'), { | ||
'click': 'div.click', | ||
'mouseup': 'div.mouseup', | ||
'mousedown': 'div.mousedown' | ||
}); | ||
ee.on('div.*', function(evt){ | ||
console.log('listenTo: '+ evt.type); | ||
}); | ||
setTimeout(function(){ | ||
ee.stopListeningTo(document.querySelector('#test')); | ||
}, 30000); | ||
```` | ||
### stopListeningTo(target?: Object, event: event | eventNS): Boolean | ||
@@ -696,0 +726,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
83423
1512
810