New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

chainit

Package Overview
Dependencies
Maintainers
1
Versions
17
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

chainit - npm Package Compare versions

Comparing version 0.0.3 to 0.0.4

.travis.yml

92

index.js
module.exports = chainit;
function chainit(Constructor) {
var instances = [];
var fns = [];
var Chain = function Chain() {
instances.push(this);
fns[instances.indexOf(this)] = {};
Constructor.apply(this, arguments);
};
Chain.prototype = Object.create(Constructor.prototype);
var Queue = require('queue');

@@ -48,2 +59,6 @@ var queues = [];

var statics = Object.keys(Constructor).forEach(function(name) {
Chain[name] = new Function(Constructor[name]);
});
var methods = Object.keys(Constructor.prototype);

@@ -53,41 +68,66 @@ methods.forEach(function(name) {

var chained = function() {
var ctx = this;
var args = Array.prototype.slice.call(arguments);
var customCb;
if (typeof args[args.length - 1] === 'function') {
customCb = args.pop();
}
var chained = makeChain();
var ldepth = currentDepth;
function makeChain(fn) {
return function chained() {
var ctx = this;
var args = Array.prototype.slice.call(arguments);
var customCb;
if (typeof args[args.length - 1] === 'function') {
customCb = args.pop();
}
if (currentDepth > 0 && queues[currentDepth - 1].concurrency > 0) {
queues[currentDepth - 1].concurrency = 0;
}
var ldepth = currentDepth;
var task = function(cb) {
currentDepth = ldepth + 1;
args.push(function() {
var cbArgs = arguments;
if (currentDepth > 0 && queues[currentDepth - 1].concurrency > 0) {
queues[currentDepth - 1].concurrency = 0;
}
if (customCb) {
customCb.apply(ctx, cbArgs);
var task = function(cb) {
currentDepth = ldepth + 1;
args.push(function() {
var cbArgs = arguments;
if (customCb) {
customCb.apply(ctx, cbArgs);
}
cb();
});
if (typeof fn === 'function') {
fn.apply(ctx, args);
} else {
original.apply(ctx, args);
}
}
cb();
});
pushTo(currentDepth, task);
return this;
}
}
original.apply(ctx, args);
Object.defineProperty(Chain.prototype, name, {
set: function(func) {
if (this === Chain.prototype) {
original = func;
} else {
fns[instances.indexOf(this)][name] = makeChain(func);
}
},
get: function() {
if (this === Chain.prototype || !fns[instances.indexOf(this)][name]) {
return chained;
} else {
return fns[instances.indexOf(this)][name];
}
}
});
pushTo(currentDepth, task);
return this;
}
Constructor.prototype[name] = chained;
});
return Constructor;
return Chain;
}

@@ -94,0 +134,0 @@

{
"name": "chainit",
"version": "0.0.3",
"version": "0.0.4",
"description": "Turn an asynchronous JavaScript api into an asynchronous chainable JavaScript api.",
"main": "index.js",
"directories": {
"example": "examples",
"test": "test"
"example": "examples"
},
"scripts": {
"test": "mocha"
"test": "zuul -- test/chain.js"
},

@@ -16,6 +15,7 @@ "author": "Vincent Voyer <vincent@zeroload.net>",

"devDependencies": {
"mocha": "~1.13.0"
"mocha": "~1.14.0",
"zuul": "~1.0.2"
},
"dependencies": {
"queue": "~1.0.1"
"queue": "~1.0.2"
},

@@ -31,3 +31,7 @@ "keywords": [

"chain api"
]
],
"repository": {
"type": "git",
"url": "git://github.com/vvo/chainit.git"
}
}

@@ -0,1 +1,3 @@

[![Build Status](https://travis-ci.org/vvo/chainit.png)](https://travis-ci.org/vvo/chainit)
# chainit

@@ -9,14 +11,6 @@

```js
function MyApi() {
// ...
}
function MyApi() {}
MyApi.prototype.method1 = function(cb) {cb()}
MyApi.prototype.method2 = function(cb) {cb()}
MyApi.prototype.method1 = function(cb) {
// ...
}
MyApi.prototype.method2 = function(cb) {
// ...
}
var chainit = require('chainit');

@@ -34,2 +28,48 @@ var MyChainApi = chainit(MyApi);

## Overriding methods
You can override methods:
* at the `.prototype` level
* at the instance level
And still benefits from the chain.
You can also keep references to the original methods to set them back later.
This is possible because we do not touch the
`MyApi` original `constructor` nor `prototype`.
```js
function MyApi() {}
MyApi.prototype.method1 = function(cb) {cb()}
MyApi.prototype.method2 = function(cb) {cb()}
var chainit = require('chainit');
var MyChainApi = chainit(MyApi);
var original1 = MyChainApi.prototype.method1;
MyChainApi.prototype.method1 = function(cb) {cb()}
var obj = new MyChainApi();
obj
.method1() // calls the newly added method1
.method2();
MyChainApi.prototype.method1 = original1;
obj
.method1() // calls the original method
.method2();
original1 = obj.method1;
obj.method1 = function(cb) {cb()}
obj
.method1() // calls the newly added method1
.method2();
obj.method1 = original1;
```
## features

@@ -46,2 +86,3 @@

* supports setTimeout(cb)
* supports methods redifinition
* fully tested! `npm test`

@@ -48,0 +89,0 @@

@@ -16,2 +16,14 @@ describe('chaining an Api', function() {

it('has the same instance type as an original object', function() {
var originalO = new Api();
assert.ok(originalO instanceof Api);
assert.ok(o instanceof Api);
assert.ok(o instanceof ChainApi);
assert.ok(o.constructor === originalO.constructor);
});
it('does not modify original prototype', function() {
assert.ok(Api.prototype !== ChainApi.prototype);
});
it('supports individuals calls', function(done) {

@@ -30,3 +42,3 @@ o.concat('he');

assert.equal(o.s, 'hola');
done(null);
done();
});

@@ -183,2 +195,98 @@ });

it('handles multiple objects', function(done) {
var o2 = new ChainApi();
var o3 = new ChainApi();
o.tripleConcat('one');
o2.tripleConcat('two');
o3.tripleConcat('three');
o
.concat('-and-', function() {
o2.concat('-or-')
})
.tripleConcat('four')
o3.concat('bon', function() {
assert.equal(o.s, 'one1-one2-one3--and-four1-four2-four3-');
assert.equal(o2.s, 'two1-two2-two3--or-');
assert.equal(this.s, 'three1-three2-three3-bon');
done(null)
})
});
it('supports methods redifinitions at the prototype level', function(done) {
var o2 = new ChainApi();
var original = Api.prototype.concat;
ChainApi.prototype.concat = function concat(sub, cb) {
this.s = this.s.concat(sub + '#');
setTimeout(cb, ChainApi.getRandomArbitrary(5, 20));
}
o2.concat('re');
o.concat('re');
o.concat('de', function() {
o.tripleConcat('fi')
})
.concat('nition', function() {
assert.equal(this.s, 're#de#fi1-#fi2-#fi3-#nition#');
ChainApi.prototype.concat = original;
o.concat('BOUH-', function() {
ChainApi.prototype.concat = function (sub, cb) {
this.s = this.s.concat(sub + '!!');
setTimeout(cb, ChainApi.getRandomArbitrary(5, 20));
};
o.concat('hello', function() {
ChainApi.prototype.concat = Api.prototype.concat;
o.concat('-ah', function() {
o2.concat('def', function() {
assert.equal(this.s, 're#def');
assert.equal(o.s, 're#de#fi1-#fi2-#fi3-#nition#BOUH-hello!!-ah');
done();
})
})
})
});
});
});
it('supports methods redifinitions at the instance level', function(done) {
var o2 = new ChainApi();
var original = o.concat;
o.concat = function(sub, cb) {
this.s += sub + '#'
setTimeout(cb, ChainApi.getRandomArbitrary(5, 20));
}
o
.concat('one')
.concat('two', function() {
this.concat('three');
})
.tripleConcat('four');
o2.concat('hey').concat('ho', function() {
o.concat = original;
o.concat('YO!', function() {
assert.equal(this.s, 'one#two#three#four1-#four2-#four3-#YO!');
assert.equal(o2.s, 'heyho');
done();
})
});
});
it('supports constructor arguments', function(done) {
var o2 = new ChainApi('allo');
o2.concat(' maman', function() {
assert.equal(this.s, 'allo maman');
done();
})
});
xit('supports adding new methods', function() {
});
});
module.exports = Api;
function Api() {
this.s = '';
function Api(s) {
this.s = s || '';
}

@@ -59,4 +59,6 @@

Api.getRandomArbitrary = getRandomArbitrary;
function getRandomArbitrary(min, max) {
return Math.random() * (max - min) + min;
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc