Comparing version 0.0.1 to 0.0.2
@@ -26,3 +26,4 @@ var Butler = require("./../lib/butler").Butler; | ||
console.log("%d + 1 = %d", values[0], values[0] + 1); | ||
return [ values[0] + 1 ]; | ||
butler.params.set(values[0] + 1); | ||
}) | ||
@@ -32,2 +33,11 @@ .add(asyncDouble) | ||
console.log("final=", values[0]); | ||
console.log("now going parallel"); | ||
}) | ||
.add(asyncDouble, 5) | ||
.add(asyncDouble, 10) | ||
.add(asyncDouble, 15) | ||
.add(asyncDouble, 20) | ||
.parallel(function (returns) { | ||
console.log(returns); | ||
}); | ||
@@ -34,0 +44,0 @@ |
// | ||
// A couple of dependencies | ||
// A simple asynchronous chaining butler | ||
// | ||
@@ -16,4 +16,6 @@ var util = require("util"), | ||
this.actions = []; | ||
this.storage = {}; | ||
this._working = false; | ||
this._last_wait = 0; | ||
this._scope = null; | ||
} | ||
@@ -27,2 +29,12 @@ | ||
// | ||
// Before adding a method from an object you must call | ||
// `.scope(object)` so the method is properly called with | ||
// the `this` correctly set. After that, if you want to | ||
// unset the scope for the next calls, just run `.scope()`. | ||
// | ||
Butler.prototype.scope = function (scope) { | ||
this._scope = scope || null; | ||
return this; | ||
}; | ||
// | ||
// Add an asynchronous call to the Butler. The first parameter is | ||
@@ -43,4 +55,5 @@ // a call reference and the other parameters are possible arguments | ||
this.actions.push({ | ||
"call": params[0], | ||
"args": params.slice(1) | ||
"call" : params[0], | ||
"scope": this._scope, | ||
"args" : params.slice(1) | ||
}); | ||
@@ -74,2 +87,28 @@ | ||
}; | ||
// | ||
// Instructs the butler that the previous calls are to be runned in | ||
// parallel, without arguments passing from one to another. | ||
// The callback is executed at the end of all the asynchronous calls | ||
// with the result of all the callbacks. | ||
// | ||
Butler.prototype.parallel = function (cb) { | ||
this.actions.push({ | ||
"parallel": cb | ||
}); | ||
this.resume(); | ||
return this; | ||
}; | ||
// | ||
// Returns `true` if an asynchronous call is runing and has | ||
// still not yet invoked the callback. This will always be | ||
// `false` inside the `.wait()` callbacks, unless you invoke | ||
// `.resume()`. | ||
// | ||
Butler.prototype.busy = function (cb) { | ||
return this._working; | ||
}; | ||
Butler.prototype.resume = function (params) { | ||
@@ -82,2 +121,65 @@ if (this._working || !this.actions.length) { | ||
var parallelResume = -1; | ||
for (var i = 0; i < this.actions.length; i++) { | ||
if (this.actions[i].hasOwnProperty("call")) continue; | ||
if (this.actions[i].hasOwnProperty("wait")) break; | ||
if (this.actions[i].hasOwnProperty("parallel")) { | ||
parallelResume = i; | ||
break; | ||
} | ||
} | ||
if (parallelResume == 0) { | ||
// ??? | ||
return console.log("parallel resume without anything to run in parallel"); | ||
} else if (parallelResume > 0) { | ||
var actions = this.actions.splice(0, parallelResume + 1), | ||
parallelCb = actions.pop(), | ||
missingActions = actions.length, | ||
errors = [], | ||
returns = []; | ||
this._last_wait = 0; | ||
for (var i = 0; i < actions.length; i++) { | ||
returns[i] = []; | ||
} | ||
for (var i = 0; i < actions.length; i++) { | ||
actions[i].args.push( | ||
(function (butler, n) { | ||
return function () { | ||
missingActions--; | ||
var params = Array.prototype.slice.apply(arguments); | ||
if (params.length == 0) { | ||
returns[n].push(null); | ||
} else { | ||
/* 1st argument must always be an error object */ | ||
if (params[0]) { | ||
params[0].callbackIndex = n + 1; | ||
errors.push(params[0]); | ||
} | ||
returns[n] = params.slice(1) || null; | ||
} | ||
if (missingActions == 0) { | ||
console.log("parallel done!"); | ||
butler._working = false; | ||
parallelCb.parallel.apply({ | ||
errors: errors, | ||
returns: returns | ||
}); | ||
} | ||
}; | ||
})(this, i) | ||
); | ||
actions[i].call.apply(actions[i].scope, actions[i].args); | ||
} | ||
return; | ||
} | ||
var action = this.actions.splice(0, 1).pop(); | ||
@@ -105,17 +207,7 @@ | ||
action.call.apply(action.call, action.args); | ||
action.call.apply(action.scope, action.args); | ||
return; | ||
} | ||
if (action.hasOwnProperty("wait")) { | ||
var butler = (function (butler) { | ||
return { | ||
"set": function () { | ||
butler._next_params = Array.prototype.slice.apply(arguments); | ||
return this; | ||
}, | ||
"resume": function () { | ||
butler.resume(); | ||
} | ||
}; | ||
})(this); | ||
var butler = this._getButlerCallbackObject(); | ||
@@ -126,3 +218,3 @@ this._next_params = params || []; | ||
var ret = action.wait.apply(action.wait, [ null, this._next_params, butler ]); | ||
var ret = action.wait.apply(butler, [ null, this._next_params ]); | ||
if (ret !== false) { | ||
@@ -143,13 +235,3 @@ this.resume(typeof ret == "object" ? ret : this._next_params); | ||
var action = this.actions.splice(0, i + 1).pop(), | ||
butler = (function (butler) { | ||
return { | ||
"set": function () { | ||
butler._next_params = Array.prototype.slice.apply(arguments); | ||
return this; | ||
}, | ||
"resume": function () { | ||
butler.resume(); | ||
} | ||
}; | ||
})(this); | ||
butler = this._getButlerCallbackObject(); | ||
@@ -173,3 +255,51 @@ params[0].callbackIndex = this._last_wait; | ||
}; | ||
Butler.prototype._getButlerCallbackObject = function () { | ||
return (function (butler) { | ||
return { | ||
"params": { | ||
"length": function () { | ||
return (butler._next_params || []).length; | ||
}, | ||
"set": function () { | ||
butler._next_params = Array.prototype.slice.apply(arguments); | ||
return this; | ||
}, | ||
"get": function (i) { | ||
if (typeof i == "number") { | ||
if (butler._next_params.length) { | ||
if (i >= 0 && i < butler._next_params.length) { | ||
return butler._next_params[i]; | ||
} | ||
} | ||
return null; | ||
} | ||
return butler._next_params || []; | ||
}, | ||
"first": function () { | ||
return this.get(0); | ||
}, | ||
"last": function () { | ||
return this.get(butler._next_params.length - 1); | ||
}, | ||
"clear": function () { | ||
butler._next_params = []; | ||
return this; | ||
}, | ||
"append": function () { | ||
butler._next_params = (butler._next_params || []).concat(Array.prototype.slice.apply(arguments)); | ||
return this; | ||
}, | ||
"prepend": function () { | ||
butler._next_params = Array.prototype.slice.apply(arguments).concat(butler._next_params || []); | ||
return this; | ||
} | ||
}, | ||
"storage": butler.storage, | ||
"resume": function () { | ||
butler.resume(); | ||
} | ||
}; | ||
})(this); | ||
}; | ||
exports.Butler = Butler; |
{ | ||
"name" : "butler", | ||
"version" : "0.0.1", | ||
"version" : "0.0.2", | ||
"description" : "NodeJS Butler", | ||
@@ -5,0 +5,0 @@ "keywords" : [ |
## Node Butler | ||
sdfsdf | ||
This module helps when you need to call several asynchronous calls one after each other. | ||
## Install | ||
npm install butler | ||
## Example | ||
// fs.readFile() implementation (check examples/fs.js) | ||
var fs = require("fs"), | ||
Butler = require("./../lib/butler").Butler, | ||
Alfred = new Butler(); | ||
// fs.readFile() | ||
function readFileAsync(filename, cb) { | ||
Alfred | ||
.add(fs.open, filename, "r") | ||
.wait(function (err) { | ||
if (err) { cb(err); return false; } | ||
this.storage.fd = this.params.first(); | ||
}) | ||
.add(fs.fstat) | ||
.wait(function (err) { | ||
if (err) { cb(err); return false; } | ||
var size = this.params.get(0).size; | ||
this.params.set(this.storage.fd, new Buffer(size), 0, size, 0); | ||
}) | ||
.add(fs.read) | ||
.wait(function (err) { | ||
if (err) { cb(err); return false; } | ||
this.storage.data = this.params.get(1); | ||
this.params.set(this.storage.fd); | ||
}) | ||
.add(fs.close) | ||
.wait(function (err) { | ||
if (err) { cb(err); return false; } | ||
cb(null, this.storage.data); | ||
}); | ||
} | ||
readFileAsync(__dirname + "/fs.js", function (err, data) { | ||
if (err) { | ||
return console.log("error reading file", err); | ||
} | ||
console.log("FILE\n-------------------------"); | ||
console.log(data); | ||
console.log("-------------------------"); | ||
}); |
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
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
53787
9
615
54
2
1