wildemitter
Advanced tools
Comparing version 0.0.1 to 0.0.2
{ | ||
"name": "wildemitter", | ||
"version": "0.0.1", | ||
"version": "0.0.2", | ||
"author": "Henrik Joreteg <henrik@andyet.net>", | ||
"description": "A super lightweight EventEmitter similar to what comes in Node.js, but with a support for wildcard events '*'", | ||
"description": "A super lightweight EventEmitter similar to what comes in Node.js, but with a support for wildcard events '*' and grouped handlers", | ||
"repository": { | ||
@@ -7,0 +7,0 @@ "type": "git", |
@@ -1,15 +0,18 @@ | ||
#WildEmitter | ||
# WildEmitter - A lightweight event emitter that supports wildcard handlers | ||
##What is it? | ||
A super lightweight EventEmitter similar to what comes in Node.js, but with a few specific differences: | ||
## What's an event emitter? | ||
If you've ever listened for a click event in a browser you've used an emitter. But, user interaction isn't the only thing that can trigger an event worth listening to. You can also make other objects capable of emitting events. That's what wildemitter is for. You can extend your objects with it so that you can emit events from them and register handlers on them. This pattern helps you write more re-usable code becaause your objct doen't have to know how it's going to be used. It can simply emit events any time something happens that other code *may* be interested in. | ||
- works in the browser (using some type of CommonJS module adapter, like stitch or browserify) | ||
- support wildcard handlers: `emitter.on('*', doSomething)` or `emitter.on('myNamespace*', doSomething)` | ||
You'll see this type of pattern a lot in node.js. Where lots of things in the standard libraries inherit from EventEmitter and emit various events to indicate progress, errors, completion, etc. | ||
This is largely based on the emitter in @visionmedia's UIKit. So, much props there. I just wanted it as a standalone on npm and with support for `*` handlers. | ||
So, why make another one? Aren't there others already? | ||
Well, yes there are, but not quite what I wanted. This one is largely based on the emitter in @visionmedia's UIKit. So, much props to TJ for that. But there were a few more things I wanted. Specifically the following: | ||
- Super lightweight | ||
- Support for browser/node.js (browser use requires a CommonJS wrapper of some kind, like Stitch or Browserify) | ||
- Support for wildcard handlers (`*` or `something*`) | ||
- Support for grouping registered handlers and aun unbinding them all by their group name. This is really handy when, for example, you want unbind all handlers associated with a given "sub-page" within a single page app. | ||
##How do I use it? | ||
You can use it to add event capabilities to other objects you build like so: | ||
```js | ||
@@ -68,4 +71,19 @@ var Emitter = require('./wildemitter'); | ||
*/ | ||
// grouped handlers example, we'll create another fruit | ||
var orange = new Fruit('orange'); | ||
// In this case "today" is the name of the group. | ||
// here we'll bind some handlers that all pass 'today' | ||
// as the group name | ||
orange.on('test', 'today', someHandler); | ||
orange.on('someOtherEvent', 'today', someHandler); | ||
orange.on('*', 'today', someHandler); | ||
// we can now unbind all three of those handlers like this | ||
orange.releaseGroup('today'); | ||
``` | ||
## Testing | ||
You can run the tests with `nodeunit` by running: `nodeunit test.js` | ||
@@ -72,0 +90,0 @@ ##License |
62
test.js
@@ -1,3 +0,2 @@ | ||
var repl = require('repl'), | ||
Emitter = require('./wildemitter'); | ||
var Emitter = require('./wildemitter'); | ||
@@ -17,28 +16,51 @@ | ||
// set up some test fruits | ||
var fruit1 = new Fruit('apple'), | ||
fruit2 = new Fruit('orange'); | ||
var apple = new Fruit('apple'), | ||
orange = new Fruit('orange'); | ||
fruit1.on('*', function () { | ||
console.log('"*" handler called', arguments); | ||
}); | ||
exports['Make sure wildcard handlers work'] = function (test) { | ||
var count = 0, | ||
cb = function () { | ||
return function () {count++} | ||
}; | ||
apple.on('*', cb()); | ||
apple.on('te*', cb()); | ||
apple.on('test', cb()); | ||
apple.test(); | ||
fruit1.on('te*', function () { | ||
console.log('"te*" handler called', arguments); | ||
}); | ||
// sanity check to make sure we've got the emitter isolated to the instance | ||
orange.test(); | ||
fruit1.on('test', function () { | ||
console.log('"test" handler called', arguments); | ||
}); | ||
test.equal(count, 3); | ||
fruit1.test(); | ||
// just making sure we've got the emitter isolated to the instance | ||
fruit2.test(); | ||
apple.off('test'); | ||
// reset our counter | ||
count = 0; | ||
apple.test(); | ||
fruit1.off('test'); | ||
test.equal(count, 2); | ||
test.done(); | ||
}; | ||
console.log('should be 3 logs'); | ||
exports['Test group binding and unbinding'] = function (test) { | ||
var count = 0, | ||
cb = function () { | ||
return function () {count++} | ||
}; | ||
// test our groups | ||
orange.on('test', 'lumped', cb()); | ||
orange.on('test', 'lumped', cb()); | ||
orange.on('test', 'lumped', cb()); | ||
orange.on('test', cb()); | ||
orange.test(); | ||
test.equal(count, 4); | ||
fruit1.test(); | ||
console.log('should be 2 logs now'); | ||
count = 0; | ||
orange.releaseGroup('lumped'); | ||
orange.test(); | ||
test.equal(count, 1); | ||
test.done(); | ||
}; |
@@ -26,5 +26,9 @@ /* | ||
// Listen on the given `event` with `fn`. | ||
WildEmitter.prototype.on = function (event, fn) { | ||
(this.callbacks[event] = this.callbacks[event] || []).push(fn); | ||
// Listen on the given `event` with `fn`. Store a group name if present. | ||
WildEmitter.prototype.on = function (event, groupName, fn) { | ||
var hasGroup = (arguments.length === 3), | ||
group = hasGroup ? arguments[1] : undefined, | ||
func = hasGroup ? arguments[2] : arguments[1]; | ||
func._groupName = group; | ||
(this.callbacks[event] = this.callbacks[event] || []).push(func); | ||
return this; | ||
@@ -45,2 +49,20 @@ }; | ||
// Unbinds an entire group | ||
WildEmitter.prototype.releaseGroup = function (groupName) { | ||
var item, i, len, handlers; | ||
for (item in this.callbacks) { | ||
handlers = this.callbacks[item]; | ||
for (i = 0, len = handlers.length; i < len; i++) { | ||
if (handlers[i]._groupName === groupName) { | ||
//console.log('removing'); | ||
// remove it and shorten the array we're looping through | ||
handlers.splice(i, 1); | ||
i--; | ||
len--; | ||
} | ||
} | ||
} | ||
return this; | ||
}; | ||
// Remove the given callback for `event` or all | ||
@@ -91,3 +113,3 @@ // registered callbacks. | ||
// Helper for for finding special wildcard event handlers that match the event | ||
WildEmitter.prototype.getWildcardCallbacks = function (eventName) { | ||
@@ -94,0 +116,0 @@ var item, |
Debug access
Supply chain riskUses debug, reflection and dynamic code execution features.
Found 1 instance in 1 package
8599
5
148
92
0