Skip to content

Commit

Permalink
update to use relike-all - now can accept everything
Browse files Browse the repository at this point in the history
  • Loading branch information
tunnckoCore committed Jan 15, 2016
1 parent d73c06a commit b2b50f5
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 55 deletions.
42 changes: 40 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,22 @@
# [redolent][author-www-url] [![npmjs.com][npmjs-img]][npmjs-url] [![The MIT License][license-img]][license-url]

> Simple promisify a callback-style function with sane defaults. Support promisify-ing sync functions.
> Simple promisify **everything** (string, array, stream, boolean, sync/async function, etc) with sane defaults.
[![code climate][codeclimate-img]][codeclimate-url] [![standard code style][standard-img]][standard-url] [![travis build status][travis-img]][travis-url] [![coverage status][coveralls-img]][coveralls-url] [![dependency status][david-img]][david-url]


## What's the difference?
> _What's the difference between me and you?!
> **–– Dr Dre feat. Eminem & X-Zibit - Whats the Difference, https://youtu.be/8y5MjguI-pM**_
What's the difference between this module, [relike](https://github.com/hybridables/relike) and [relike-all](https://github.com/hybridables/relike-all)?
–– Simply, almost nothing.

1. [redolent](https://github.com/hybridables/redolent) accepts **everything** and returns function, which when is executed it returns `Promise`. Above things applies here, because it is on top of `relike-all`.
2. [relike-all](https://github.com/hybridables/relike-all) accepts everything and returns `Promise`.
3. [relike](https://github.com/hybridables/relike) only accepts `sync` or `async` function which is executed immediately with next arguments, after that it returns `Promise`.


## Install
```
npm i redolent --save
Expand All @@ -22,7 +34,7 @@ const redolent = require('redolent')
> Will try to promisify `fn` with native Promise, otherwise will use `Bluebird`
or you can give different promise module as `Prome`, for example `pinkie`.

- `<fn>` **{Function}** callback-style function to promisify
- `[val]` **{Anything}** any type from string to function (number, stream, array, boolean, etc)
- `[Prome]` **{Function}** custom Promise module to use, e.g. `Q`
- `return` **{Function}** promisified function

Expand Down Expand Up @@ -116,13 +128,39 @@ promise
```


## Promise from any type
> Any number of any type of arguments can be given - String, Stream, Null, Boolean, Number and etc.
**Example**

```js
const redolent = require('redolent')

var fn = redolent('foo bar baz')

fn().then(function (str) {
console.log(str) // => 'foo bar baz'
}, console.error)

redolent(false)().then(function (bool) {
console.log(bool) // => false
}, console.error)

redolent({a: 'b'})().then(function (arr) {
console.log(arr) // => {a: 'b'}
}, console.error)
```


## Related
- [always-done](https://github.com/hybridables/always-done): Handles completion and errors of anything!
- [always-promise](https://github.com/hybridables/always-promise): Promisify, basically, **everything**. Generator function, callback-style or synchronous function; sync function that returns child process, stream or observable; directly passed promise, stream or child process.
- [always-thunk](https://github.com/hybridables/always-thunk): Thunkify, basically, **everything**. Generator function, callback-style or synchronous function; sync function that returns child process, stream or observable; directly passed promise, stream or child process.
- [always-generator](https://github.com/hybridables/always-generator): Generatorify, basically, **everything**. Async, callback-style or synchronous function; sync function that returns child process, stream or observable; directly passed promise, stream or child process.
- [native-or-another](https://github.com/tunnckoCore/native-or-another): Always will expose native `Promise` if available, otherwise `Bluebird` but only if you don't give another promise module like `q` or `promise` or what you want.
- [native-promise](https://github.com/tunnckoCore/native-promise): Get native `Promise` or falsey value if not available.
- [relike](https://github.com/hybridables/relike): Simple promisify a callback-style function with sane defaults. Support promisify-ing sync functions.
- [relike-all](https://github.com/hybridables/relike-all): Create promise from sync, async, string, number, array and so on. Handle completion (results) and errors gracefully! Built on top of `relike`, used by `redolent` to build robust (hybrid) APIs.


## Contributing
Expand Down
42 changes: 8 additions & 34 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

'use strict'

var utils = require('./utils')

/**
* Will try to promisify `fn` with native Promise,
* otherwise will use `Bluebird` or you can give
Expand All @@ -30,45 +32,17 @@
* ```
*
* @name redolent
* @param {Function} `<fn>` callback-style function to promisify
* @param {Anything} `[val]` any type from string to function (number, stream, array, boolean, etc)
* @param {Function} `[Prome]` custom Promise module to use, e.g. `Q`
* @return {Function} promisified function
* @api public
*/
module.exports = function redolent (fn, Prome) {
if (typeof fn !== 'function') {
throw new TypeError('redolent expect a function')
}

module.exports = function redolent (val, Prome) {
var self = this
return function promisify () {
var utils = require('./utils')
var argz = utils.handleArguments(arguments)
return function promisifyFn () {
var ctx = self || this

if (argz.callback && !utils.isAsyncFunction(argz.callback)) {
argz.args = argz.args.concat(argz.callback)
}

Prome = utils.nativeOrAnother(Prome || redolent.promise || promisify.promise)
var promise = new Prome(function prome (resolve, reject) {
var isAsync = utils.isAsyncFunction(fn)
if (isAsync) {
argz.args = argz.args.concat(function cb (err, res) {
if (err) return reject(err)
if (arguments.length > 2) res = utils.sliced(arguments, 1)
resolve(res)
})
}
var syncResult = fn.apply(ctx, argz.args)
if (!isAsync) {
resolve(syncResult)
}
})

promise.Prome = Prome
promise.___customPromise = Prome.___customPromise
promise.___bluebirdPromise = Prome.___bluebirdPromise
return promise
var args = utils.sliced(arguments)
utils.relikeAll.promise = Prome || redolent.promise || promisifyFn.promise
return utils.relikeAll.apply(ctx, [val].concat(args))
}
}
6 changes: 2 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "redolent",
"version": "1.0.7",
"description": "Simple promisify a callback-style function with sane defaults. Support promisify-ing sync functions.",
"description": "Simple promisify **everything** (string, array, stream, boolean, sync/async function, etc) with sane defaults.",
"repository": "hybridables/redolent",
"author": "Charlike Mike Reagent <@tunnckoCore> (http://www.tunnckocore.tk)",
"main": "index.js",
Expand All @@ -10,10 +10,8 @@
"test": "standard && node test.js"
},
"dependencies": {
"handle-arguments": "^3.0.4",
"is-async-function": "^1.1.0",
"lazy-cache": "^1.0.3",
"native-or-another": "^3.0.1",
"relike-all": "^1.0.0",
"sliced": "^1.0.1"
},
"devDependencies": {
Expand Down
31 changes: 24 additions & 7 deletions test.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,30 @@ function multipleArgs (one, two, three, cb) {
cb(null, one, two, three)
}

test('should throw TypeError if not function given', function (done) {
function fixture () {
redolent(123)
}
test.throws(fixture, TypeError)
test.throws(fixture, /redolent expect a function/)
done()
test('should not throw TypeError if falsey value given', function (done) {
redolent(false)().then(function (bool) {
test.strictEqual(bool, false)
return redolent(null)().then(function (empty) {
test.strictEqual(empty, null)
done()
})
}, done)
})

test('should promisify a given string (only one argument)', function (done) {
var fn = redolent('foo bar baz')
fn().then(function (str) {
test.strictEqual(str, 'foo bar baz')
done()
}, done)
})

test('should flatten arguments from first and from promisified function', function (done) {
var func = redolent('foo')
func(123, [1, 2], {a: 'b'}).then(function (arr) {
test.deepEqual(arr, ['foo', 123, [1, 2], {a: 'b'}])
done()
}, done)
})

test('should promisify with native Promise or Bluebird', function (done) {
Expand Down
33 changes: 25 additions & 8 deletions utils.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,36 @@
/* jshint asi:true */

'use strict'

/**
* Lazily required module dependencies
* Module dependencies
*/

var utils = require('lazy-cache')(require) // eslint-disable-line no-undef, no-native-reassign
var fn = require
var utils = require('lazy-cache')(require)

/**
* Temporarily re-assign `require` to trick browserify and
* webpack into reconizing lazy dependencies.
*
* This tiny bit of ugliness has the huge dual advantage of
* only loading modules that are actually called at some
* point in the lifecycle of the application, whilst also
* allowing browserify and webpack to find modules that
* are depended on but never actually called.
*/

var fn = require
require = utils // eslint-disable-line no-undef, no-native-reassign
require('handle-arguments')
require('is-async-function')
require('native-or-another')

/**
* Lazily required module dependencies
*/

require('relike-all')
require('sliced')

/**
* Restore `require`
*/

require = fn // eslint-disable-line no-undef, no-native-reassign

/**
Expand Down

0 comments on commit b2b50f5

Please sign in to comment.