publishing v1 of action

This commit is contained in:
Paul Merlin 2019-09-21 16:11:55 +02:00
parent 91baa89272
commit 2d5ca45eab
569 changed files with 61688 additions and 2 deletions

1
node_modules/chainsaw/.npmignore generated vendored Normal file
View file

@ -0,0 +1 @@
node_modules

157
node_modules/chainsaw/README.markdown generated vendored Normal file
View file

@ -0,0 +1,157 @@
Chainsaw
========
Build chainable fluent interfaces the easy way in node.js.
With this meta-module you can write modules with chainable interfaces.
Chainsaw takes care of all of the boring details and makes nested flow control
super simple too.
Just call `Chainsaw` with a constructor function like in the examples below.
In your methods, just do `saw.next()` to move along to the next event and
`saw.nest()` to create a nested chain.
Examples
========
add_do.js
---------
This silly example adds values with a chainsaw.
var Chainsaw = require('chainsaw');
function AddDo (sum) {
return Chainsaw(function (saw) {
this.add = function (n) {
sum += n;
saw.next();
};
this.do = function (cb) {
saw.nest(cb, sum);
};
});
}
AddDo(0)
.add(5)
.add(10)
.do(function (sum) {
if (sum > 12) this.add(-10);
})
.do(function (sum) {
console.log('Sum: ' + sum);
})
;
Output:
Sum: 5
prompt.js
---------
This example provides a wrapper on top of stdin with the help of
[node-lazy](https://github.com/pkrumins/node-lazy) for line-processing.
var Chainsaw = require('chainsaw');
var Lazy = require('lazy');
module.exports = Prompt;
function Prompt (stream) {
var waiting = [];
var lines = [];
var lazy = Lazy(stream).lines.map(String)
.forEach(function (line) {
if (waiting.length) {
var w = waiting.shift();
w(line);
}
else lines.push(line);
})
;
var vars = {};
return Chainsaw(function (saw) {
this.getline = function (f) {
var g = function (line) {
saw.nest(f, line, vars);
};
if (lines.length) g(lines.shift());
else waiting.push(g);
};
this.do = function (cb) {
saw.nest(cb, vars);
};
});
}
And now for the new Prompt() module in action:
var util = require('util');
var stdin = process.openStdin();
Prompt(stdin)
.do(function () {
util.print('x = ');
})
.getline(function (line, vars) {
vars.x = parseInt(line, 10);
})
.do(function () {
util.print('y = ');
})
.getline(function (line, vars) {
vars.y = parseInt(line, 10);
})
.do(function (vars) {
if (vars.x + vars.y < 10) {
util.print('z = ');
this.getline(function (line) {
vars.z = parseInt(line, 10);
})
}
else {
vars.z = 0;
}
})
.do(function (vars) {
console.log('x + y + z = ' + (vars.x + vars.y + vars.z));
process.exit();
})
;
Installation
============
With [npm](http://github.com/isaacs/npm), just do:
npm install chainsaw
or clone this project on github:
git clone http://github.com/substack/node-chainsaw.git
To run the tests with [expresso](http://github.com/visionmedia/expresso),
just do:
expresso
Light Mode vs Full Mode
=======================
`node-chainsaw` supports two different modes. In full mode, every
action is recorded, which allows you to replay actions using the
`jump()`, `trap()` and `down()` methods.
However, if your chainsaws are long-lived, recording every action can
consume a tremendous amount of memory, so we also offer a "light" mode
where actions are not recorded and the aforementioned methods are
disabled.
To enable light mode simply use `Chainsaw.light()` to construct your
saw, instead of `Chainsaw()`.

25
node_modules/chainsaw/examples/add_do.js generated vendored Normal file
View file

@ -0,0 +1,25 @@
var Chainsaw = require('chainsaw');
function AddDo (sum) {
return Chainsaw(function (saw) {
this.add = function (n) {
sum += n;
saw.next();
};
this.do = function (cb) {
saw.nest(cb, sum);
};
});
}
AddDo(0)
.add(5)
.add(10)
.do(function (sum) {
if (sum > 12) this.add(-10);
})
.do(function (sum) {
console.log('Sum: ' + sum);
})
;

67
node_modules/chainsaw/examples/prompt.js generated vendored Normal file
View file

@ -0,0 +1,67 @@
var Chainsaw = require('chainsaw');
var Lazy = require('lazy');
module.exports = Prompt;
function Prompt (stream) {
var waiting = [];
var lines = [];
var lazy = Lazy(stream).lines.map(String)
.forEach(function (line) {
if (waiting.length) {
var w = waiting.shift();
w(line);
}
else lines.push(line);
})
;
var vars = {};
return Chainsaw(function (saw) {
this.getline = function (f) {
var g = function (line) {
saw.nest(f, line, vars);
};
if (lines.length) g(lines.shift());
else waiting.push(g);
};
this.do = function (cb) {
saw.nest(cb, vars);
};
});
}
var util = require('util');
if (__filename === process.argv[1]) {
var stdin = process.openStdin();
Prompt(stdin)
.do(function () {
util.print('x = ');
})
.getline(function (line, vars) {
vars.x = parseInt(line, 10);
})
.do(function () {
util.print('y = ');
})
.getline(function (line, vars) {
vars.y = parseInt(line, 10);
})
.do(function (vars) {
if (vars.x + vars.y < 10) {
util.print('z = ');
this.getline(function (line) {
vars.z = parseInt(line, 10);
})
}
else {
vars.z = 0;
}
})
.do(function (vars) {
console.log('x + y + z = ' + (vars.x + vars.y + vars.z));
process.exit();
})
;
}

145
node_modules/chainsaw/index.js generated vendored Executable file
View file

@ -0,0 +1,145 @@
var Traverse = require('traverse');
var EventEmitter = require('events').EventEmitter;
module.exports = Chainsaw;
function Chainsaw (builder) {
var saw = Chainsaw.saw(builder, {});
var r = builder.call(saw.handlers, saw);
if (r !== undefined) saw.handlers = r;
saw.record();
return saw.chain();
};
Chainsaw.light = function ChainsawLight (builder) {
var saw = Chainsaw.saw(builder, {});
var r = builder.call(saw.handlers, saw);
if (r !== undefined) saw.handlers = r;
return saw.chain();
};
Chainsaw.saw = function (builder, handlers) {
var saw = new EventEmitter;
saw.handlers = handlers;
saw.actions = [];
saw.chain = function () {
var ch = Traverse(saw.handlers).map(function (node) {
if (this.isRoot) return node;
var ps = this.path;
if (typeof node === 'function') {
this.update(function () {
saw.actions.push({
path : ps,
args : [].slice.call(arguments)
});
return ch;
});
}
});
process.nextTick(function () {
saw.emit('begin');
saw.next();
});
return ch;
};
saw.pop = function () {
return saw.actions.shift();
};
saw.next = function () {
var action = saw.pop();
if (!action) {
saw.emit('end');
}
else if (!action.trap) {
var node = saw.handlers;
action.path.forEach(function (key) { node = node[key] });
node.apply(saw.handlers, action.args);
}
};
saw.nest = function (cb) {
var args = [].slice.call(arguments, 1);
var autonext = true;
if (typeof cb === 'boolean') {
var autonext = cb;
cb = args.shift();
}
var s = Chainsaw.saw(builder, {});
var r = builder.call(s.handlers, s);
if (r !== undefined) s.handlers = r;
// If we are recording...
if ("undefined" !== typeof saw.step) {
// ... our children should, too
s.record();
}
cb.apply(s.chain(), args);
if (autonext !== false) s.on('end', saw.next);
};
saw.record = function () {
upgradeChainsaw(saw);
};
['trap', 'down', 'jump'].forEach(function (method) {
saw[method] = function () {
throw new Error("To use the trap, down and jump features, please "+
"call record() first to start recording actions.");
};
});
return saw;
};
function upgradeChainsaw(saw) {
saw.step = 0;
// override pop
saw.pop = function () {
return saw.actions[saw.step++];
};
saw.trap = function (name, cb) {
var ps = Array.isArray(name) ? name : [name];
saw.actions.push({
path : ps,
step : saw.step,
cb : cb,
trap : true
});
};
saw.down = function (name) {
var ps = (Array.isArray(name) ? name : [name]).join('/');
var i = saw.actions.slice(saw.step).map(function (x) {
if (x.trap && x.step <= saw.step) return false;
return x.path.join('/') == ps;
}).indexOf(true);
if (i >= 0) saw.step += i;
else saw.step = saw.actions.length;
var act = saw.actions[saw.step - 1];
if (act && act.trap) {
// It's a trap!
saw.step = act.step;
act.cb();
}
else saw.next();
};
saw.jump = function (step) {
saw.step = step;
saw.next();
};
};

61
node_modules/chainsaw/package.json generated vendored Normal file
View file

@ -0,0 +1,61 @@
{
"_args": [
[
"chainsaw@0.1.0",
"/Users/paul/src/codeartisans/gradle-command-action"
]
],
"_from": "chainsaw@0.1.0",
"_id": "chainsaw@0.1.0",
"_inBundle": false,
"_integrity": "sha1-XqtQsor+WAdNDVgpE4iCi15fvJg=",
"_location": "/chainsaw",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "chainsaw@0.1.0",
"name": "chainsaw",
"escapedName": "chainsaw",
"rawSpec": "0.1.0",
"saveSpec": null,
"fetchSpec": "0.1.0"
},
"_requiredBy": [
"/binary"
],
"_resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz",
"_spec": "0.1.0",
"_where": "/Users/paul/src/codeartisans/gradle-command-action",
"author": {
"name": "James Halliday",
"email": "mail@substack.net",
"url": "http://substack.net"
},
"bugs": {
"url": "https://github.com/substack/node-chainsaw/issues"
},
"dependencies": {
"traverse": ">=0.3.0 <0.4"
},
"description": "Build chainable fluent interfaces the easy way... with a freakin' chainsaw!",
"engine": {
"node": ">=0.4.0"
},
"homepage": "https://github.com/substack/node-chainsaw#readme",
"keywords": [
"chain",
"fluent",
"interface",
"monad",
"monadic"
],
"license": "MIT/X11",
"main": "./index.js",
"name": "chainsaw",
"repository": {
"type": "git",
"url": "git+ssh://git@github.com/substack/node-chainsaw.git"
},
"version": "0.1.0"
}

418
node_modules/chainsaw/test/chainsaw.js generated vendored Normal file
View file

@ -0,0 +1,418 @@
var assert = require('assert');
var Chainsaw = require('../index');
exports.getset = function () {
var to = setTimeout(function () {
assert.fail('builder never fired');
}, 1000);
var ch = Chainsaw(function (saw) {
clearTimeout(to);
var num = 0;
this.get = function (cb) {
cb(num);
saw.next();
};
this.set = function (n) {
num = n;
saw.next();
};
var ti = setTimeout(function () {
assert.fail('end event not emitted');
}, 50);
saw.on('end', function () {
clearTimeout(ti);
assert.equal(times, 3);
});
});
var times = 0;
ch
.get(function (x) {
assert.equal(x, 0);
times ++;
})
.set(10)
.get(function (x) {
assert.equal(x, 10);
times ++;
})
.set(20)
.get(function (x) {
assert.equal(x, 20);
times ++;
})
;
};
exports.nest = function () {
var ch = (function () {
var vars = {};
return Chainsaw(function (saw) {
this.do = function (cb) {
saw.nest(cb, vars);
};
});
})();
var order = [];
var to = setTimeout(function () {
assert.fail("Didn't get to the end");
}, 50);
ch
.do(function (vars) {
vars.x = 'y';
order.push(1);
this
.do(function (vs) {
order.push(2);
vs.x = 'x';
})
.do(function (vs) {
order.push(3);
vs.z = 'z';
})
;
})
.do(function (vars) {
vars.y = 'y';
order.push(4);
})
.do(function (vars) {
assert.eql(order, [1,2,3,4]);
assert.eql(vars, { x : 'x', y : 'y', z : 'z' });
clearTimeout(to);
})
;
};
exports.nestWait = function () {
var ch = (function () {
var vars = {};
return Chainsaw(function (saw) {
this.do = function (cb) {
saw.nest(cb, vars);
};
this.wait = function (n) {
setTimeout(function () {
saw.next();
}, n);
};
});
})();
var order = [];
var to = setTimeout(function () {
assert.fail("Didn't get to the end");
}, 1000);
var times = {};
ch
.do(function (vars) {
vars.x = 'y';
order.push(1);
this
.do(function (vs) {
order.push(2);
vs.x = 'x';
times.x = Date.now();
})
.wait(50)
.do(function (vs) {
order.push(3);
vs.z = 'z';
times.z = Date.now();
var dt = times.z - times.x;
assert.ok(dt >= 50 && dt < 75);
})
;
})
.do(function (vars) {
vars.y = 'y';
order.push(4);
times.y = Date.now();
})
.wait(100)
.do(function (vars) {
assert.eql(order, [1,2,3,4]);
assert.eql(vars, { x : 'x', y : 'y', z : 'z' });
clearTimeout(to);
times.end = Date.now();
var dt = times.end - times.y;
assert.ok(dt >= 100 && dt < 125)
})
;
};
exports.nestNext = function () {
var ch = (function () {
var vars = {};
return Chainsaw(function (saw) {
this.do = function (cb) {
saw.nest(false, function () {
var args = [].slice.call(arguments);
args.push(saw.next);
cb.apply(this, args);
}, vars);
};
});
})();
var order = [];
var to = setTimeout(function () {
assert.fail("Didn't get to the end");
}, 500);
var times = [];
ch
.do(function (vars, next_) {
vars.x = 'y';
order.push(1);
this
.do(function (vs, next) {
order.push(2);
vs.x = 'x';
setTimeout(next, 30);
})
.do(function (vs, next) {
order.push(3);
vs.z = 'z';
setTimeout(next, 10);
})
.do(function () {
setTimeout(next_, 20);
})
;
})
.do(function (vars, next) {
vars.y = 'y';
order.push(4);
setTimeout(next, 5);
})
.do(function (vars) {
assert.eql(order, [1,2,3,4]);
assert.eql(vars, { x : 'x', y : 'y', z : 'z' });
clearTimeout(to);
})
;
};
exports.builder = function () {
var cx = Chainsaw(function (saw) {
this.x = function () {};
});
assert.ok(cx.x);
var cy = Chainsaw(function (saw) {
return { y : function () {} };
});
assert.ok(cy.y);
var cz = Chainsaw(function (saw) {
return { z : function (cb) { saw.nest(cb) } };
});
assert.ok(cz.z);
var to = setTimeout(function () {
assert.fail("Nested z didn't run");
}, 50);
cz.z(function () {
clearTimeout(to);
assert.ok(this.z);
});
};
this.attr = function () {
var to = setTimeout(function () {
assert.fail("attr chain didn't finish");
}, 50);
var xy = [];
var ch = Chainsaw(function (saw) {
this.h = {
x : function () {
xy.push('x');
saw.next();
},
y : function () {
xy.push('y');
saw.next();
assert.eql(xy, ['x','y']);
clearTimeout(to);
}
};
});
assert.ok(ch.h);
assert.ok(ch.h.x);
assert.ok(ch.h.y);
ch.h.x().h.y();
};
exports.down = function () {
var error = null;
var s;
var ch = Chainsaw(function (saw) {
s = saw;
this.raise = function (err) {
error = err;
saw.down('catch');
};
this.do = function (cb) {
cb.call(this);
};
this.catch = function (cb) {
if (error) {
saw.nest(cb, error);
error = null;
}
else saw.next();
};
});
var to = setTimeout(function () {
assert.fail(".do() after .catch() didn't fire");
}, 50);
ch
.do(function () {
this.raise('pow');
})
.do(function () {
assert.fail("raise didn't skip over this do block");
})
.catch(function (err) {
assert.equal(err, 'pow');
})
.do(function () {
clearTimeout(to);
})
;
};
exports.trap = function () {
var error = null;
var ch = Chainsaw(function (saw) {
var pars = 0;
var stack = [];
var i = 0;
this.par = function (cb) {
pars ++;
var j = i ++;
cb.call(function () {
pars --;
stack[j] = [].slice.call(arguments);
saw.down('result');
});
saw.next();
};
this.join = function (cb) {
saw.trap('result', function () {
if (pars == 0) {
cb.apply(this, stack);
saw.next();
}
});
};
this.raise = function (err) {
error = err;
saw.down('catch');
};
this.do = function (cb) {
cb.call(this);
};
this.catch = function (cb) {
if (error) {
saw.nest(cb, error);
error = null;
}
else saw.next();
};
});
var to = setTimeout(function () {
assert.fail(".do() after .join() didn't fire");
}, 100);
var tj = setTimeout(function () {
assert.fail('.join() never fired');
}, 100);
var joined = false;
ch
.par(function () {
setTimeout(this.bind(null, 1), 50);
})
.par(function () {
setTimeout(this.bind(null, 2), 25);
})
.join(function (x, y) {
assert.equal(x[0], 1);
assert.equal(y[0], 2);
clearTimeout(tj);
joined = true;
})
.do(function () {
clearTimeout(to);
assert.ok(joined);
})
;
};
exports.jump = function () {
var to = setTimeout(function () {
assert.fail('builder never fired');
}, 50);
var xs = [ 4, 5, 6, -4, 8, 9, -1, 8 ];
var xs_ = [];
var ch = Chainsaw(function (saw) {
this.x = function (i) {
xs_.push(i);
saw.next();
};
this.y = function (step) {
var x = xs.shift();
if (x > 0) saw.jump(step);
else saw.next();
};
saw.on('end', function () {
clearTimeout(to);
assert.eql(xs, [ 8 ]);
assert.eql(xs_, [ 1, 1, 1, 1, 2, 3, 2, 3, 2, 3 ]);
});
});
ch
.x(1)
.y(0)
.x(2)
.x(3)
.y(2)
;
};