# chainit

> Turn an asynchronous JavaScript api into an asynchronous chainable JavaScript api.

Latest version **2.1.1** (published 2014-08-11) · MIT/X11 license · 0 weekly downloads

> **Deprecated.** This package is deprecated.

## Install

```sh
npm install chainit
pnpm add chainit
yarn add chainit
bun add chainit
```

## Health

**Score 10/100 (F)** — status: deprecated.

Negative: deprecated.

## Facts

| | |
|---|---|
| Version | 2.1.1 |
| Published | 2014-08-11 |
| First published | 2013-10-20 |
| Weekly downloads | 0 |
| License | MIT/X11 |
| TypeScript types | none |
| Module format | CommonJS |
| Dependencies | 1 |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 13 |
| Author | Vincent Voyer |
| Maintainers | vvo, christian-bromann |
| Keywords | chain, async, queue, flow control, chainable, chainify, chainit, chain api |

## Links

- npm: https://www.npmjs.com/package/chainit
- Repository: https://github.com/vvo/chainit
- Issues: https://github.com/vvo/chainit/issues
- npm.io page: https://npm.io/package/chainit

## Dependencies (1)

- [queue](https://npm.io/package/queue.md) ~1.0.2

## Alternatives

- [cron](https://npm.io/package/cron.md) — 4.9M weekly downloads
- [@vercel/queue](https://npm.io/package/@vercel/queue.md) — 731.6K weekly downloads
- [create-sonicjs](https://npm.io/package/create-sonicjs.md) — 1.6K weekly downloads
- [@exellix/jobs-api](https://npm.io/package/@exellix/jobs-api.md) — 941 weekly downloads
- [@forwardimpact/libskill](https://npm.io/package/@forwardimpact/libskill.md) — 575 weekly downloads

## Recent versions

- 2.1.1 (latest) — 2014-08-11
- 2.1.0 — 2014-04-28
- 2.0.4 — 2014-04-25
- 2.0.3 — 2014-04-18
- 2.0.2-backcompat — 2014-03-18
- 2.0.1-backcompat — 2014-03-18
- 2.0.0-backcompat — 2014-03-18
- 1.3.1 — 2014-03-13
- 1.3.0 — 2014-03-13
- 1.2.0 — 2014-03-05
- 1.1.2 — 2013-12-29
- 1.1.1 — 2013-12-27
- 1.0.1 — 2013-12-01
- 1.0.0 — 2013-12-01
- 0.0.4 — 2013-11-13
- … 2 more at https://npm.io/package/chainit/versions

## README

# chainit [![Build Status](https://travis-ci.org/vvo/chainit.png)](https://travis-ci.org/vvo/chainit) [![Dependency Status](https://david-dm.org/vvo/chainit.svg?theme=shields.io)](https://david-dm.org/vvo/chainit) [![devDependency Status](https://david-dm.org/vvo/chainit/dev-status.svg?theme=shields.io)](https://david-dm.org/vvo/chainit#info=devDependencies)

[![Selenium Test Status](https://saucelabs.com/browser-matrix/chainitvvo.svg)](https://saucelabs.com/u/chainitvvo)

Turn an asynchronous JavaScript api into an asynchronous
[chainable](http://en.wikipedia.org/wiki/Method_chaining) JavaScript api.

## usage

```js
function MyApi() {}
MyApi.prototype.method1 = function(cb) {cb()}
MyApi.prototype.method2 = function(cb) {cb()}

var chainit = require('chainit');
var MyChainApi = chainit(MyApi);
var obj = new MyChainApi();
obj
  .method1()                      // 1st call
  .method2()                      // 2nd call
  .method1(function(/* args */) { // 3rd call
    this.method1();               // 4th call
  })
  .method2();                     // 5th call
```

## Adding or overriding methods

Adding and overriding methods works at both prototype level and instance level.

You must use `chainit.add(chain, methodName, method)`,
you can't do direct assignation (`chain.methodName = method`) because
`object.observe` is not yet ready.

```js
function MyApi() {}
MyApi.prototype.method1 = function(cb) {cb()}
MyApi.prototype.method2 = function(cb) {cb()}

var chainit = require('chainit');
var MyChainApi = chainit(MyApi);

var obj = new MyChainApi();

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

obj
  .method1() // calls the newly added method1
  .method2();

// revert original method
chainit.add(obj, 'method1', MyApi.prototype.method1);

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

var obj2 = new MyChainApi();

obj2.method1(); // calls the newly chained prototype `method1`
```

## features

Features:

* supports async apis
* supports (crazy) nested calls
* supports static and prototype methods
* preserve nested calls order
* preserve context in cb()
* preserve cb(args)
* supports process.nextTick(cb)
* supports setTimeout(cb)
* supports methods redifinition
* supports adding new methods
* fully tested! local: `npm install -g mocha && mocha`, saucelabs: `npm test`

## tests

See [tests](test/).

```shell
npm test
```

## examples

See [examples](examples/).

## mixing async/sync apis

There is no easy way to mix sync/async chainable
apis because there is no way to differenciate sync/async calls.

```js
obj
  .asyncMethod()
  .syncMethod()
```

We cannot know that syncMethod is synchronous and that
we do not
need to wait for a callback to be called to continue.

Either your api is fully asynchronous and every method
takes a callback.

Either your api is fully synchronous.
If you want synchronous support, make a pull request
adding `chainit.sync(Constructor)`.

## credits

This module is using [jessetane/queue](https://github.com/jessetane/queue).

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).

---
_Source: https://npm.io/package/chainit · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
