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.4 to 1.0.0

TODO

108

index.js
module.exports = chainit;
function chainit(Constructor) {
var instances = [];
var fns = [];
var Chain = function Chain() {
instances.push(this);
fns[instances.indexOf(this)] = {};
function Chain() {
Constructor.apply(this, arguments);
};
}

@@ -59,78 +55,66 @@ Chain.prototype = Object.create(Constructor.prototype);

var statics = Object.keys(Constructor).forEach(function(name) {
Chain[name] = new Function(Constructor[name]);
});
// static methods, not chained
Object.keys(Constructor)
.forEach(function(name) {
Chain[name] = new Function(Constructor[name]);
});
var methods = Object.keys(Constructor.prototype);
methods.forEach(function(name) {
var original = Constructor.prototype[name];
// prototype methods, chained
Object
.keys(Constructor.prototype)
.forEach(function(fnName) {
Chain.prototype[fnName] = makeChain(fnName, Constructor.prototype[fnName]);
});
var chained = makeChain();
function makeChain(fnName, fn) {
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();
}
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();
}
var ldepth = currentDepth;
var ldepth = currentDepth;
if (currentDepth > 0 && queues[currentDepth - 1].concurrency > 0) {
queues[currentDepth - 1].concurrency = 0;
}
if (currentDepth > 0 && queues[currentDepth - 1].concurrency > 0) {
queues[currentDepth - 1].concurrency = 0;
}
var task = function(cb) {
currentDepth = ldepth + 1;
var task = function(cb) {
currentDepth = ldepth + 1;
args.push(function() {
var cbArgs = arguments;
args.push(function() {
var cbArgs = arguments;
if (customCb) {
customCb.apply(ctx, cbArgs);
}
if (customCb) {
customCb.apply(ctx, cbArgs);
}
cb();
});
cb();
});
fn.apply(ctx, args);
}
if (typeof fn === 'function') {
fn.apply(ctx, args);
} else {
original.apply(ctx, args);
}
}
pushTo(currentDepth, task);
return this;
}
pushTo(currentDepth, task);
return this;
}
}
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];
}
}
});
Chain.prototype.__addToChain = function(fnName, fn) {
this[fnName] = makeChain(fnName, fn);
}
});
return Chain;
}
chainit.add = function add(to, fnName, fn) {
to.__addToChain(fnName, fn);
}
function hasPending(queue) {
return queue.length >= 1;
}
{
"name": "chainit",
"version": "0.0.4",
"version": "1.0.0",
"description": "Turn an asynchronous JavaScript api into an asynchronous chainable JavaScript api.",

@@ -5,0 +5,0 @@ "main": "index.js",

[![Build Status](https://travis-ci.org/vvo/chainit.png)](https://travis-ci.org/vvo/chainit)
[![Selenium Test Status](https://saucelabs.com/browser-matrix/chainitvvo.svg)](https://saucelabs.com/u/chainitvvo)
# chainit

@@ -27,14 +29,10 @@

## Overriding methods
## Adding or overriding methods
You can override methods:
* at the `.prototype` level
* at the instance level
Adding and overriding methods works at both prototype level and instance level.
And still benefits from the chain.
You must use `chainit.add(chain, methodName, method)`,
you can't do direct assignation (`chain.methodName = method`) because
`object.observe` is not yet ready.
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

@@ -49,3 +47,6 @@ function MyApi() {}

MyChainApi.prototype.method1 = function(cb) {cb()}
// override instance method
chainit.add(MyChainApi, 'method1', function(cb) {
cb()
});

@@ -58,17 +59,9 @@ var obj = new MyChainApi();

MyChainApi.prototype.method1 = original1;
// revert original method
chainit.add(MyChainApi, '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;
// override prototype method
chainit.add(MyChainApi.prototype, 'method1', function(cb) {
cb()
});
```

@@ -88,8 +81,5 @@

* supports methods redifinition
* fully tested! `npm test`
* supports adding new methods
* fully tested! local: `npm install -g mocha && mocha`, saucelabs: `npm test`
## examples
See [examples](examples/).
## tests

@@ -103,4 +93,8 @@

## async/sync apis
## examples
See [examples](examples/).
## mixing async/sync apis
There is no easy way to mix sync/async chainable

@@ -128,8 +122,7 @@ apis because there is no way to differenciate sync/async calls.

This module was done easily thanks to
[jessetane/queue](https://github.com/jessetane/queue).
This module is using [jessetane/queue](https://github.com/jessetane/queue).
A chainable api is just queueing methods and reordering calls.
A chainable api is queueing methods and reordering calls, so we use a queue.
This module was built to replace the chainable api from
[webdriverjs](https://github.com/camme/webdriverjs/tree/v0.8.0).
[webdriverjs](https://github.com/camme/webdriverjs).

@@ -218,6 +218,6 @@ describe('chaining an Api', function() {

ChainApi.prototype.concat = function concat(sub, cb) {
chainit.add(ChainApi.prototype, 'concat', function concat(sub, cb) {
this.s = this.s.concat(sub + '#');
setTimeout(cb, ChainApi.getRandomArbitrary(5, 20));
}
});

@@ -232,10 +232,10 @@ o2.concat('re');

assert.equal(this.s, 're#de#fi1-#fi2-#fi3-#nition#');
ChainApi.prototype.concat = original;
chainit.add(ChainApi.prototype, 'concat', original);
o.concat('BOUH-', function() {
ChainApi.prototype.concat = function (sub, cb) {
chainit.add(ChainApi.prototype, 'concat', function concat(sub, cb) {
this.s = this.s.concat(sub + '!!');
setTimeout(cb, ChainApi.getRandomArbitrary(5, 20));
};
});
o.concat('hello', function() {
ChainApi.prototype.concat = Api.prototype.concat;
chainit.add(ChainApi.prototype, 'concat', Api.prototype.concat);
o.concat('-ah', function() {

@@ -257,6 +257,6 @@ o2.concat('def', function() {

o.concat = function(sub, cb) {
chainit.add(o, 'concat', function concat(sub, cb) {
this.s += sub + '#'
setTimeout(cb, ChainApi.getRandomArbitrary(5, 20));
}
});

@@ -271,3 +271,3 @@ o

o2.concat('hey').concat('ho', function() {
o.concat = original;
chainit.add(o, 'concat',original);
o.concat('YO!', function() {

@@ -289,6 +289,22 @@ assert.equal(this.s, 'one#two#three#four1-#four2-#four3-#YO!');

xit('supports adding new methods', function() {
it('supports adding new methods', function(done) {
function newMethod(sub, cb) {
this.s += sub + 'NEW!-'
setTimeout(cb, ChainApi.getRandomArbitrary(5, 20));
}
assert.equal(typeof o.newMethod, 'undefined');
chainit.add(o, 'newMethod', newMethod);
assert.equal(typeof o.newMethod, 'function');
o
.newMethod('thiis')
.newMethod('amazing', function() {
this.concat('allo', function() {
assert.equal(this.s, 'thiisNEW!-amazingNEW!-allo');
done()
})
})
});
});

Sorry, the diff of this file is not supported yet

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