Comparing version 0.0.1 to 0.0.3
@@ -6,36 +6,20 @@ var fs = require('fs'), | ||
var em = new EventEmitter(); | ||
em.on('result', function() { | ||
console.log('RESULT EM'); | ||
var onResult = outcome.error(function(err) { | ||
console.log(err); | ||
}).success(function(result) { | ||
console.log(result) | ||
}); | ||
outcome.on('unhandledError', function(err) { | ||
console.log("ERROR") | ||
console.error(err.message); | ||
}); | ||
var onOutcome3 = outcome(em); | ||
var onOutcome = outcome().result(function() { | ||
var onResult2 = onResult.copy().success(function(result) { | ||
console.log("RESULT") | ||
}).error(function() { | ||
console.log("ERROR"); | ||
}); | ||
var onOutcome2 = outcome().result(function() { | ||
console.log("RESULT"); | ||
}).done(function(err, result) { | ||
console.log('DONE') | ||
}) | ||
fs.stat(__filename, onResult); | ||
fs.stat(__filename, onResult2); | ||
fs.stat('s'+__filename, onResult2); | ||
fs.stat(__filename, onOutcome); | ||
fs.stat(__filename+'d', onOutcome2); | ||
fs.stat(__filename, onOutcome3); | ||
outcome.call(fs.stat, __filename).done(function() { | ||
console.log("DONE") | ||
}).result(function() { | ||
console.log("G") | ||
}) |
239
lib/index.js
@@ -6,224 +6,115 @@ var EventEmitter = require('events').EventEmitter, | ||
Structr = require('structr'); | ||
_ = require('underscore'); | ||
/** | ||
*/ | ||
var Chain = function(listeners, parent) { | ||
var wrapResultFn = function(em) { | ||
if(!listeners) listeners = { }; | ||
if(!em) em = new EventEmitter(); | ||
return function() { | ||
var args = Array.apply(null, arguments); | ||
var doneListeners = [], | ||
self = function() { | ||
//error should always be first args | ||
err = args.shift(); | ||
var args = Array.apply(null, arguments), orgArgs = arguments; | ||
//if there is an error, and a result is *not* present, then continue | ||
if(err && !args[0]) { | ||
em.emit('error', err); | ||
if(listeners.handle) { | ||
listeners.handle.apply(listeners, args); | ||
} else { | ||
//pass the result on | ||
em.emit.apply(em, ['result'].concat(args)); | ||
} | ||
} | ||
} | ||
//error should always be first args | ||
err = args.shift(); | ||
/** | ||
* Pipes one event emitter to another | ||
*/ | ||
//if there is an error, and a result is *not* present, then continue | ||
if(err && !args[0]) { | ||
listeners.error(err); | ||
var pipeEmit = function(from, type, to) { | ||
to.addListener(type, function() { | ||
to.emit.apply(to, [type].concat(arguments)); | ||
}); | ||
} | ||
var Chain = function(em, ret) { | ||
if(!em) em = new EventEmitter(); | ||
if(!ret) ret = {}; | ||
var self = { | ||
/** | ||
*/ | ||
'call': function(fn) { | ||
//pass the arguments onto the function we're wrapping around | ||
var args = Array.apply(null, arguments).slice(1), | ||
em = new EventEmitter(); | ||
//push the callback we're gonna pipe to | ||
args.push(wrapResultFn(em)); | ||
//need to do next tick incase the function is syncronous (must be async) | ||
process.nextTick(function() { | ||
} else { | ||
fn.apply(null, args); | ||
}); | ||
return Chain(em, ret); | ||
}, | ||
/** | ||
*/ | ||
on: function(type, callback) { | ||
if(typeof type == 'object') { | ||
for(var t in type) { | ||
self.on(t, type[t]); | ||
} | ||
return ret; | ||
listeners.success.apply(null, args); | ||
} | ||
} | ||
doneListeners.forEach(function(fn) { | ||
fn.apply(null, orgArgs); | ||
}); | ||
}; | ||
em.addListener(type, callback); | ||
return ret; | ||
}, | ||
self.listeners = listeners; | ||
/** | ||
* listens to target event emitter against listeners | ||
*/ | ||
self.done = function(fn) { | ||
listen: function(em, listeners) { | ||
var child = Chain(em, ret); | ||
doneListeners.push(fn); | ||
return self; | ||
if(listeners) child.on(listeners); | ||
} | ||
self.copy = function(childListeners) { | ||
return child; | ||
return Chain(_.extend({}, listeners, childListeners || {}), self); | ||
}, | ||
} | ||
/** | ||
*/ | ||
self.handle = function(fn) { | ||
'throw': function(err) { | ||
throw err; | ||
listeners.handle = fn; | ||
return self; | ||
} | ||
}, | ||
/** | ||
* listens for a result | ||
*/ | ||
'result': function(fn) { | ||
self.success = function(fn) { | ||
em.on('result', fn); | ||
return ret; | ||
listeners.success = fn || function(){}; | ||
}, | ||
return self; | ||
} | ||
/** | ||
* listens for an error | ||
*/ | ||
self.error = function(fn) { | ||
'error': function(fn) { | ||
em.on('error', fn); | ||
listeners.error = fn || function(err) { | ||
return ret; | ||
//no error callback? check of unhandled error is present, or throw | ||
if(!globalEmitter.emit('unhandledError', err)) throw err; | ||
}, | ||
/** | ||
* regular fn(err, result); | ||
*/ | ||
'done': function(fn) { | ||
} | ||
self.on({ | ||
result: function() { | ||
fn.apply(null, [null].concat(Array.apply(null, arguments))); | ||
}, | ||
error: function(err) { | ||
fn(err); | ||
} | ||
}); | ||
return self; | ||
}; | ||
return ret; | ||
self.error(listeners.error); | ||
}, | ||
return self; | ||
} | ||
/** | ||
* pipes emit to another event emitter | ||
*/ | ||
'emit': function(target) { | ||
for(var type in em._events) { | ||
module.exports = function(listeners) { | ||
return Chain(listeners); | ||
} | ||
pipeEmit(em, type, target); | ||
} | ||
//ability to listen for unhandledError | ||
module.exports.on = function() { | ||
return ret; | ||
} | ||
}; | ||
globalEmitter.on.apply(globalEmitter, arguments); | ||
em.addListener('error', function(err) { | ||
//no error callback? check of unhandled error is present, or throw | ||
if((em.listeners('error').length == 1) && !globalEmitter.emit('unhandledError', err)) { | ||
throw err; | ||
} | ||
}); | ||
Structr.copy(self, ret); | ||
return ret || self; | ||
} | ||
module.exports = function(listenersOrEm) { | ||
module.exports.chain = Chain; | ||
var isEm = listenersOrEm instanceof EventEmitter, | ||
em = isEm ? listenersOrEm : new EventEmitter(); | ||
var chain = Chain(); | ||
var ch = Chain(em, wrapResultFn(em)); | ||
Object.keys(chain).forEach(function(prop) { | ||
module.exports[prop] = function() { | ||
var child = Chain(); | ||
if(!isEm && typeof listeners == 'object') { | ||
ch.on(listeners); | ||
return child[prop].apply(child, arguments); | ||
} | ||
}) | ||
return ch; | ||
} | ||
Structr.copy(Chain(), module.exports); | ||
module.exports.chain = Chain; | ||
module.exports.on = function() { | ||
globalEmitter.on.apply(globalEmitter, arguments); | ||
} |
{ | ||
"name": "outcome", | ||
"description": "Better Result Handling", | ||
"version": "0.0.1", | ||
"repository": { | ||
}, | ||
"engines": { | ||
}, | ||
"dependencies": { | ||
"tq":"<=0.1.0", | ||
"structr":"*" | ||
}, | ||
"devDependencies": { | ||
}, | ||
"main":"./lib/index.js" | ||
} | ||
"name": "outcome", | ||
"description": "Better Result Handling", | ||
"version": "0.0.3", | ||
"repository": {}, | ||
"engines": {}, | ||
"dependencies": { | ||
"underscore": "*" | ||
}, | ||
"devDependencies": {}, | ||
"main": "./lib/index.js" | ||
} |
178
README.md
@@ -7,3 +7,3 @@ | ||
fs.stat('some/file.js', function(err, result) { | ||
fs.stat('some/file.js', function(err, data) { | ||
@@ -23,50 +23,31 @@ if(err) { | ||
There are two ways you can use outcome.js: | ||
### .outcome(listeners) | ||
- `listeners` - success, or error | ||
```javascript | ||
var onOutcome = outcome().result(function() { | ||
console.log('result'); | ||
}).error(function() { | ||
console.log('error'); | ||
var resultHandler = outcome.error(function(err) { | ||
console.log(err); | ||
}); | ||
//success | ||
fs.stat(__filename, resultHandler.copy().success(function(data) { | ||
//do stuff | ||
})); | ||
fs.stat(__filename, onOutcome); | ||
```` | ||
//success | ||
fs.stat(__filename, resultHandler.copy().success(function(data) { | ||
//do stuff | ||
})); | ||
Or | ||
//this fails - error is passed to above func | ||
fs.stat('s'+__filename, resultHandler.copy().success(function(data) { | ||
//do stuff | ||
})); | ||
```javascript | ||
outcome.call(fs.stat, __filename).result(function() { | ||
```` | ||
console.log("RESULT"); | ||
}).error(function() { | ||
console.log("ERROR"); | ||
}) | ||
``` | ||
### .outcome([listenersOrEm]) | ||
- `listenersOrEm` - listeners or eventEmitter | ||
```javascript | ||
var em = new EventEmitter(); | ||
em.on('result', function() { | ||
console.log("RESULT"); | ||
}); | ||
fs.stat(__filename, outcome(em)); | ||
``` | ||
Or | ||
@@ -76,4 +57,4 @@ | ||
var onOutcome = outcome({ | ||
result: function() { | ||
console.log("RESULT"); | ||
success: function() { | ||
console.log("SUCCESS"); | ||
}, | ||
@@ -86,4 +67,6 @@ error: function() { | ||
fs.stat(__filename, onOutcome); | ||
``` | ||
By default, any unhandled errors are thrown. To get around this, you'll need to listen for an `unhandledError`: | ||
@@ -97,123 +80,66 @@ | ||
fs.stat(outcome({ | ||
result: function(){} | ||
//fails | ||
fs.stat('s'+__filename, outcome({ | ||
success: function(){} | ||
})); | ||
``` | ||
### .copy() | ||
### CallChain .call(fn[, arg1][, arg2][, ...]) | ||
Copies the current call chain. Useful for using one error handler, and many result handlers. See first example. | ||
Calls the given function | ||
### .done() | ||
- `fn` - target function to be called | ||
- `target` - target scope - for `this` | ||
Called when on error/success. `Same as function(err, data) { }` | ||
```javascript | ||
outcome.call(fs.stat, null, fs).on({ | ||
error: function() { }, | ||
result: function() { } | ||
fs.stat(__filename, outcome.error(function(err) { | ||
//handle error | ||
}).success(function(data) { | ||
//handle result | ||
}.done(function(err, result) { | ||
//called on fn complete | ||
}); | ||
//or | ||
outcome.call(fs.stat, fs, { | ||
error: function() { }, | ||
result: function() { } | ||
}) | ||
``` | ||
### CallChain .on(typeOrEvents[, callback]) | ||
### .success(fn) | ||
Listens for any events emitted by outcome - primarily `unhandledError` | ||
Called on success | ||
- `typeOrEvent` - type of event (string), or object of events | ||
- `callback` - callback for the listener | ||
```javascript | ||
outcome.on('unhandledError', function() { | ||
//DO STUFF | ||
var onOutcome = outcome.success(function(data) { | ||
}); | ||
``` | ||
### CallChain .listen(EventEmitter[, events]) | ||
Listens to the given event emitter. | ||
```javascript | ||
outcome.listen(em).on({ | ||
someEvent: function(){} | ||
}); | ||
//or | ||
outcome.listen(em, { | ||
someEvent: function(){} | ||
}); | ||
onOutcome(null, "success!"); | ||
``` | ||
### CallChain .emit(EventEmitter) | ||
### .error(fn) | ||
Pipes events to target event emitter | ||
Called on error | ||
```javascript | ||
outcome.call(fs.stat).emit(em); | ||
``` | ||
### CallChain .done() | ||
Called when on error/result: | ||
```javascript | ||
outcome.call(fs.stat, { | ||
result: function() { | ||
} | ||
}).done(function(err, result) { | ||
var onOutcome = outcome.error(function(err) { | ||
}); | ||
``` | ||
### CallChain .result(fn) | ||
Called on success/result | ||
```javascript | ||
outcome.call(fs.stat).result(function(result) { | ||
}); | ||
onOutcome(new Error("ERR")); | ||
``` | ||
### CallChain .error(fn) | ||
### .handle(fn) | ||
Called on error | ||
Custom response handler | ||
```javascript | ||
outcome.call(fs.stat).error(function(err) { | ||
//handle error | ||
}); | ||
``` | ||
## CallChain API | ||
Same as as above | ||
### CallChain .on(typeOrEvents[, callback]) | ||
Listens for results - `error`, and `result` primarily. | ||
- `typeOrEvent` - type of event (string), or object of events | ||
- `callback` - callback for the listener | ||
```javascript | ||
outcome.call(fs.stat).on('error', function() { | ||
outcome.handle(function(response) { | ||
}).on('result', function() { | ||
if(response.errors) this.error(response); | ||
if(response.data) this.success(response); | ||
}); | ||
//or | ||
``` | ||
outcome.call(fs.stat).on({ | ||
error: function() {}, | ||
result: function() {} | ||
}) | ||
``` |
Sorry, the diff of this file is not supported yet
Wildcard dependency
QualityPackage has a dependency with a floating version range. This can cause issues if the dependency publishes a new major version.
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
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
Wildcard dependency
QualityPackage has a dependency with a floating version range. This can cause issues if the dependency publishes a new major version.
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
1
14471
82
141
1
+ Addedunderscore@*
+ Addedunderscore@1.13.7(transitive)
- Removedstructr@*
- Removedtq@<=0.1.0
- Removedstructr@0.3.2(transitive)
- Removedtq@0.1.0(transitive)