Comparing version 0.2.0 to 1.0.0-alpha-02
129
lib/index.js
@@ -1,15 +0,130 @@ | ||
// Generated by CoffeeScript 1.7.1 | ||
// Generated by CoffeeScript 1.9.1 | ||
(function() { | ||
var Channel, EventChannel; | ||
var Emitter, PatternSet, assert, first, is_function, is_object, is_string, map, ref, | ||
slice = [].slice; | ||
Channel = require("./channel"); | ||
ref = require("fairmont"), is_string = ref.is_string, is_object = ref.is_object, is_function = ref.is_function, first = ref.first; | ||
EventChannel = require("./event-channel"); | ||
PatternSet = require("evie-wildcards"); | ||
module.exports = EventChannel; | ||
assert = function(x) { | ||
if (!x) { | ||
throw new TypeError; | ||
} | ||
}; | ||
module.exports.Channel = Channel; | ||
map = function(fn) { | ||
return function() { | ||
var args, event, x; | ||
args = 1 <= arguments.length ? slice.call(arguments, 0) : []; | ||
if (args.length === 1 && is_object(first(args))) { | ||
map = args[0]; | ||
for (event in map) { | ||
x = map[event]; | ||
fn.call(this, event, x); | ||
} | ||
} else { | ||
fn.call.apply(fn, [this].concat(slice.call(args))); | ||
} | ||
return this; | ||
}; | ||
}; | ||
module.exports.EventChannel = EventChannel; | ||
Emitter = (function() { | ||
function Emitter(target) { | ||
this.handlers = {}; | ||
this.patterns = new PatternSet; | ||
if (target != null) { | ||
this.forward({ | ||
"*": target | ||
}); | ||
} | ||
} | ||
Emitter.prototype.emit = map(function() { | ||
var args, event; | ||
event = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; | ||
assert(is_string(event)); | ||
return this.patterns.match(event, (function(_this) { | ||
return function(event) { | ||
var base, handler, handlers, i, len, results; | ||
handlers = ((base = _this.handlers)[event] != null ? base[event] : base[event] = []); | ||
results = []; | ||
for (i = 0, len = handlers.length; i < len; i++) { | ||
handler = handlers[i]; | ||
results.push(handler.apply(null, args)); | ||
} | ||
return results; | ||
}; | ||
})(this)); | ||
}); | ||
Emitter.prototype.on = map(function(event, handler) { | ||
var base, handlers; | ||
assert(is_string(event)); | ||
assert(is_function(handler)); | ||
this.patterns.add(event); | ||
handlers = ((base = this.handlers)[event] != null ? base[event] : base[event] = []); | ||
return handlers.push(handler); | ||
}); | ||
Emitter.prototype.once = map(function(event, handler) { | ||
assert(is_string(event)); | ||
assert(is_function(handler)); | ||
return this.on(event, (function(_this) { | ||
return function() { | ||
var args; | ||
args = 1 <= arguments.length ? slice.call(arguments, 0) : []; | ||
handler.apply(null, args); | ||
return _this.remove(event, handler); | ||
}; | ||
})(this)); | ||
}); | ||
Emitter.prototype.remove = map(function(event, handler) { | ||
var _h, base, handlers; | ||
assert(is_string(event)); | ||
assert(is_function(handler)); | ||
handlers = ((base = this.handlers)[event] != null ? base[event] : base[event] = []); | ||
return this.handlers[event] = (function() { | ||
var i, len, results; | ||
results = []; | ||
for (i = 0, len = handlers.length; i < len; i++) { | ||
_h = handlers[i]; | ||
if (_h !== handler) { | ||
results.push(_h); | ||
} | ||
} | ||
return results; | ||
})(); | ||
}); | ||
Emitter.prototype.forward = map(function(event, emitter) { | ||
var emit; | ||
assert(is_string(event)); | ||
assert(emitter.emit != null); | ||
emit = function() { | ||
var args; | ||
args = 1 <= arguments.length ? slice.call(arguments, 0) : []; | ||
return emitter.emit.apply(emitter, [event].concat(slice.call(args))); | ||
}; | ||
return this.on(event, emit); | ||
}); | ||
Emitter.create = function() { | ||
var args; | ||
args = 1 <= arguments.length ? slice.call(arguments, 0) : []; | ||
return (function(func, args, ctor) { | ||
ctor.prototype = func.prototype; | ||
var child = new ctor, result = func.apply(child, args); | ||
return Object(result) === result ? result : child; | ||
})(Emitter, args, function(){}); | ||
}; | ||
return Emitter; | ||
})(); | ||
module.exports = Emitter; | ||
}).call(this); |
{ | ||
"name": "evie", | ||
"version": "0.2.0", | ||
"version": "1.0.0-alpha-02", | ||
"description": "EventEmitter-style events with event-bubbling", | ||
"main": "./lib/index.js", | ||
"scripts": { | ||
"prepublish": "coffee -o lib/ -c src/*.coffee", | ||
"test": "coffee test/event-channel.coffee" | ||
"prepublish": "coffee --nodejs --harmony --compile -o ./lib ./src", | ||
"watch": "coffee --nodejs --harmony --compile --watch -o lib/ ./src", | ||
"test": "coffee --nodejs --harmony test/index.litcoffee" | ||
}, | ||
"dependencies": { | ||
"fairmont": "^0.8.2", | ||
"typely": "0.0.0" | ||
"evie-wildcards": "^1.0.0-alpha-01", | ||
"fairmont": "^1.0.0-alpha-15" | ||
}, | ||
"devDependencies": { | ||
"testify": "^0.2.9" | ||
"amen": "^1.0.0-alpha-06" | ||
}, | ||
"repository": "git@github.com:pandastrike/evie.git", | ||
"author": "Matthew King <automatthew@gmail.com>", | ||
"repository": { | ||
"type": "git", | ||
"url": "git://github.com/dyoder/evie.git" | ||
}, | ||
"authors": [ | ||
"Matthew King <matthew@pandastrike.com>", | ||
"Dan Yoder <dan@pandastrike.com>" | ||
], | ||
"license": "MIT" | ||
} |
180
README.md
# Evie | ||
Evie provides an EventEmtter-style interface, but provides support for event-bubbling. | ||
Evie provides an EventEmtter-style interface, but provides support for event-bubbling, wild-card events, object-literal handler specs, and doesn't require a handler for an `error` event. | ||
```coffee-script | ||
parent = new Evie | ||
parent.on "bam", -> console.log "Bam!" | ||
Evie = require "evie" | ||
child = new Evie | ||
child.forward parent | ||
child.emit "bam" | ||
``` | ||
count = 0 | ||
parent = Evie.create() | ||
parent.on bam: -> count++ | ||
Evie also supports serial and concurrent execution of multiple asynchronous operations without the need for an external library, like [async][0]. You can also conveniently wrap Node-style callback functions for use with Evie. | ||
[0]:https://github.com/caolan/async | ||
```coffee-script | ||
events = new Evie | ||
events.on "error", (error) -> console.log error | ||
[read, write] = events.wrap fs.readFile, fs.writeFile | ||
do events.serially (go) -> | ||
go -> read "foo.txt", encoding: "utf8" | ||
go (text) -> write "bar.txt", text, encoding: "utf8" | ||
go -> read "bar.txt", encoding: "utf8" | ||
``` | ||
## Install | ||
npm install evie | ||
## Using Evie Directly | ||
```coffee | ||
{Evie} = require "evie" | ||
events = new Evie() | ||
``` | ||
## Inheriting From Evie | ||
```coffee | ||
{evie} = require "evie" | ||
class MyEvents | ||
evie(@) | ||
events = new MyEvents() | ||
``` | ||
## Evie Reference | ||
Evie can be used in a similar fashion to `EventEmitter`. There are a few differences: for example, Evie doesn't throw when an `error` event is emitted and there is no handler. | ||
Events are also emitted using `setImmediate`, instead of invoking handlers directly. This makes it easier to define consistent interfaces without leaking details about the implementation. You can still emit an event synchronously using the `fire` method instead of `emit`: | ||
```coffee-script | ||
# using emit: | ||
events.emit "success", result | ||
# using fire | ||
events.fire event: "success", content: result | ||
``` | ||
### `forward` and `source` | ||
Evie also supports event-bubbling, similar to the way DOM events work. To forward events to another Evie object, just use the `forward` method. | ||
```coffee-script | ||
parent = new Evie | ||
parent.on "bam", -> console.log "Bam!" | ||
child = new Evie | ||
child = Evie.create() | ||
child.forward parent | ||
child.emit "bam" | ||
``` | ||
You can also create new channels from existing channels using the `source` method. The new channel will forward its events to the original channel. | ||
```coffee-script | ||
parent = new Evie | ||
parent.on "bam", -> console.log "Bam!" | ||
child = parent.source() | ||
child.forward parent | ||
child.emit "bam" | ||
``` | ||
child.emit "*" | ||
The `source` method can also take a channel name, which will be prepended to the event originating from it. | ||
```coffee-script | ||
parent = new Evie | ||
parent.on "child.bam", -> console.log "Bam!" | ||
child = parent.source("child") | ||
child.forward parent | ||
child.emit "bam" | ||
assert count == 2 | ||
``` | ||
The `source` method can also take a function, which is useful when you want to return the child event channel. | ||
```coffee-script | ||
parent = new Evie | ||
parent.on "read.error", (error) -> console.log error | ||
read = (path) -> | ||
parent.source "read", (events) -> | ||
fs.readFile path, encoding: "utf8", (error, content) -> | ||
unless error? | ||
event.emit "success", content | ||
else | ||
event.emit "error", error | ||
read "foo.txt" | ||
.on "success", (content) -> | ||
console.log content | ||
``` | ||
In the example above, the errors are handled in the parent, away from the call to read. This makes it possible to separate your error handling logic from the call site, which is often useful. | ||
### `success` and `error` Events | ||
Some of Evie's most useful methods are based on the convention of emitting `success` or `error` events. These include `wrap`, `serially`, and `concurrently`. | ||
### `wrap` | ||
The `wrap` method takes a function that accepts a Node-style callback as its last argument and returns a function that returns an Evie event channel, emitting either a `success` or `error` event. | ||
```coffee-script | ||
events = new Evie | ||
parent.on "error", (error) -> console.log error | ||
read = parent.wrap fs.readFile | ||
read "foo.txt", encoding: "utf8" | ||
.on "success", (content) -> console.log content | ||
``` | ||
### `serially` | ||
The `serially` method allows you to queue up a sequence of asynchronous functions that follow the Evie convention of returning an Evie event channel that will emit either a `success` or `error` event. If a `success` event is emitted, `serially` will run the next function, passing it the result of the previous function (which you are free to ignore, of course). | ||
```coffee-script | ||
events = new Evie | ||
events.on "error", (error) -> console.log error | ||
[read, write] = events.wrap fs.readFile, fs.writeFile | ||
do events.serially (go) -> | ||
go -> read "foo.txt", encoding: "utf8" | ||
go (text) -> write "bar.txt", text, encoding: "utf8" | ||
go -> read "bar.txt", encoding: "utf8" | ||
``` | ||
### `concurrently` | ||
The `concurrently` method works similarly to the `serially` method, except that all functions are run concurrently. If a name is passed to the builder method (assigned to the argument `go` in these examples), the result of the function will be added to an object using that property name. This object will be emitted by `concurrently` when all the functions have returned successful. | ||
```coffee-script | ||
events = new Evie | ||
events.on "error", (error) -> console.log error | ||
[read] = events.wrap fs.readFile | ||
do events.concurrently (go) -> | ||
for file in files | ||
go (file) -> read file, encoding: "utf8" | ||
.on "success", (cache) -> | ||
for file, content in cache | ||
console.log "File: #{file}", "\nContent: #{content}" | ||
``` | ||
# `success` and `error` methods | ||
You can do promise-style coding by using the `success` and `error` shortcuts. | ||
```coffee-script | ||
events = new Evie | ||
events.error (error) -> console.log error | ||
[read] = events.wrap fs.readFile | ||
do events.concurrently (go) -> | ||
for file in files | ||
go (file) -> read file, encoding: "utf8" | ||
.success (cache) -> | ||
for file, content in cache | ||
console.log "File: #{file}", "\nContent: #{content}" | ||
``` |
Sorry, the diff of this file is not supported yet
No contributors or author data
MaintenancePackage does not specify a list of contributors or an author in package.json.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
628
0
0
25501
11
3
20
+ Addedbalanced-match@1.0.2(transitive)
+ Addedbase64-words@0.1.2(transitive)
+ Addedbrace-expansion@1.1.11(transitive)
+ Addedconcat-map@0.0.1(transitive)
+ Addedevie-wildcards@1.0.0-alpha-01(transitive)
+ Addedfairmont@1.1.6(transitive)
+ Addedfairmont-core@1.0.1(transitive)
+ Addedfairmont-filesystem@1.1.3(transitive)
+ Addedfairmont-helpers@1.1.21.2.2(transitive)
+ Addedfairmont-multimethods@1.0.1(transitive)
+ Addedfairmont-process@1.1.1(transitive)
+ Addedfairmont-reactive@1.1.2(transitive)
+ Addedminimatch@2.0.10(transitive)
- Removedtypely@0.0.0
- Removedfairmont@0.4.10.8.2(transitive)
- Removedtypely@0.0.0(transitive)
Updatedfairmont@^1.0.0-alpha-15