Giter Club home page Giter Club logo

hybridify's Introduction

Hybridify. Hybrids. Create sync or async function to support both promise and callback-style APIs in same time. Using the power of relike.

code climate standard code style travis build status coverage status dependency status

You might also be interested in letta, relike, relike-all, hybridify-all.

Wait, what?

Hybrids?! Yea, hybrids are just promises on steroids. The philosophy of hybrids are some edge use cases like when you want to use both promise-style api and callback-style api in same time.

Hybrids are perfect for these times of transition from old school callback hell to the new and modern, next-generation javascript world - Promises, Generators, Async Functions and Arrow functions.

If you have callback api, or even some synchronous libs, hybrids comes to the rescue - use hybridify and you are here - in Promises Land, with centralized error handling and no breaking changes.

You can use hybridify when you considered to deprecate the callback api and want to support it for next few versions. And all that, without breaking changes - users of your library or project will be able to decide what to use - promises or good old callbacks.

Highlights

A few features and main points.

  • "promisify" synchronous and asynchronous functions
  • no breaking changes between switching APIs - from callbacks to promises
  • thin wrapper around relike to add support for both promise and callback-style API
  • only using bluebird, if not other Promise constructor provided through .Promise property
  • bluebird or the custom constructor is used only on environments that don't have support for native Promise
  • works on any nodejs version - from v0.10.x to latest v6+ Node.js
  • accept and works with javascript internal functions like JSON.stringify and JSON.parse

Install

npm i hybridify --save

Usage

For more use-cases see the tests

const hybridify = require('hybridify')

Make sync or async fn to support promise and callback-style APIs in same time.

Params

  • <fn> {Function}: Some sync or asynchronous function.
  • [...args] {Mixed}: Any number of any type of arguments, they are passed to fn.
  • returns {Promise}: Always Promise, always native Promise if supported on environment.

Example

const fs = require('fs')
const hybridify = require('hybridify')

const promise = hybridify(fs.readFile, 'package.json', (err, buf) => {
  if (err) console.error('callback err:', err)
  console.log('callback res:', buf) // => '<Buffer 7b 0a 20 ...>'
})

promise.then(buf => {
  console.log('promise res:', buf) // => '<Buffer 7b 0a 20 ...>'
}, err => {
  console.error('promise err:', err.stack)
})

Wrapper function for hybridify(), but acts like .promisify thingy. Accepts fn function and returns a function, which when is called returns a Promise, but also can accept and calls final callback if given.

Params

  • <fn> {Function}: Some sync or asynchronous function.
  • [Promize] {Function}: Promise constructor to be used on environment where no support for native.
  • returns {Function}: Hybridified function, which always return a Promise.

Example

const fs = require('fs')
const hybridify = require('hybridify')
const readdir = hybridify.hybridify(fs.readdir)

const promise = readdir('./', (err, files) => {
  if (err) console.error('callback err:', err)
  console.log('callback res:', files) // => array with directory files
})

promise.then(files => {
  console.log('promise res:', files) // => array of files
}, err => {
  console.error('promise err:', err.stack)
})

Alias for relike's .promisify method. Almost the same as the .hybridify method, but can't accept callback. When returned function is called only returns a promise, not calls the final callback.

Params

  • <fn> {Function}: Some sync or asynchronous function.
  • [Promize] {Function}: Promise constructor to be used on environment where no support for native.
  • returns {Function}: Promisified function, which always return a Promise.

Example

const fs = require('fs')
const hybridify = require('hybridify')
const statPromised = hybridify.promisify(fs.statSync)

statPromised('./index.js').then(stats => {
  console.log(stats.mode) // => mode of file
}, err => {
  console.error(err.stack)
})

.Promise

While hybridify always trying to use native Promise if available in the environment, you can give a Promise constructor to be used on environment where there's no support - for example, old broswers or node's 0.10 version. By default, hybridify will use and include bluebird on old environments, as it is the fastest implementation of Promises. So, you are able to give Promise constructor, but it won't be used in modern environments - it always will use native Promise, you can't trick that. You can't give custom promise implementation to be used in any environment.

Example

const fs = require('fs')
const hybridify = require('hybridify')

hybridify.hybridify.Promise = require('q') // using `Q` promise on node 0.10
const readFile = hybridify.hybridify(fs.readFile)

readFile('package.json', 'utf8', (err, val) => {
  if (err) console.error(err)
  console.log(val)
})
.then(console.log, err => {
  console.error(err.stack)
})

One way to pass a custom Promise constructor is as shown above. But the other way is passing it to .Promise of the hybridified function, like that

const fs = require('fs')
const hybridify = require('hybridify')
const statFile = hybridify.hybridify(fs.stat)

statFile.Promise = require('when') // using `when` promise on node 0.10
statFile('package.json').then(console.log, console.error)

One more thing, is that you can access the used Promise and can detect what promise is used. It is easy, just as promise.Promise and you'll get it. Or look for promise.___bluebirdPromise and promise.___customPromise properties. .___bluebirdPromise (yea, with three underscores in front) will be true if environment is old and you didn't provide promise constructor to .Promise.
So, when you give constructor .__customPromise will be true and .___bluebirdPromise will be false.

const fs = require('fs')
const hybridify = require('hybridify')

const promise = hybridify(fs.readFile, 'package.json', 'utf8', (err, val) => {
  if (err) console.error(err)
  console.log(JSON.parse(val).name) // => 'hybridify'
})
promise.then(JSON.parse).then(val => {
  console.log(val.name) // => 'hybridify'
}, console.error)

console.log(promise.Promise) // => used Promise constructor
console.log(promise.___bluebirdPromise) // => `true` on old env, falsey otherwise
console.log(promise.___customPromise) // => `true` when pass `.Promise`, falsey otherwise

Or finally, you can pass Promise constructor as second argument to .promisify/.hybridify method. Like that

const fs = require('fs')
const hybridify = require('hybridify')
const readFile = hybridify.hybridify(fs.readFile, require('when'))

const promise = readFile('index.js')

console.log(promise.Promise) // => The `when` promise constructor, on old environments
console.log(promise.___customPromise) // => `true` on old environments

Related

Contributing

Pull requests and stars are always welcome. For bugs and feature requests, please create an issue.
But before doing anything, please read the CONTRIBUTING.md guidelines.

tunnckoCore.tk keybase tunnckoCore tunnckoCore npm tunnckoCore twitter tunnckoCore github

hybridify's People

Contributors

greenkeeper[bot] avatar tunnckocore avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

hybridify's Issues

An in-range update of mukla is breaking the build 🚨

Version 0.4.5 of mukla just got published.

Branch Build failing 🚨
Dependency mukla
Current Version 0.4.4
Type devDependency

This version is covered by your current version range and after updating it in your project the build failed.

As mukla is “only” a devDependency of this project it might not break production or downstream projects, but “only” your build or test tools – preventing new deploys or publishes.

I recommend you give this issue a high priority. I’m sure you can resolve this 💪


Status Details
  • continuous-integration/travis-ci/push The Travis CI build could not complete due to an error Details

  • coverage/coveralls First build on greenkeeper/mukla-0.4.5 at 100.0% Details

Commits

The new version differs by 2 commits .

  • 703d308 0.4.5
  • 3b7d301 switch to always-done, fix errors output (should externalize it)

See the full diff.

Not sure how things should work exactly?

There is a collection of frequently asked questions and of course you may always ask my humans.


Your Greenkeeper Bot 🌴

An in-range update of isarray is breaking the build 🚨

Version 2.0.2 of isarray just got published.

Branch Build failing 🚨
Dependency isarray
Current Version 2.0.1
Type devDependency

This version is covered by your current version range and after updating it in your project the build failed.

As isarray is “only” a devDependency of this project it might not break production or downstream projects, but “only” your build or test tools – preventing new deploys or publishes.

I recommend you give this issue a high priority. I’m sure you can resolve this 💪

Status Details
  • coverage/coveralls First build on greenkeeper/isarray-2.0.2 at 100.0% Details
  • continuous-integration/travis-ci/push The Travis CI build could not complete due to an error Details

Commits

The new version differs by 5 commits.

  • a4ea9e1 2.0.2
  • 399170f Merge pull request #18 from mcollina/patch-1
  • 4046d45 Removed deprecation from README
  • aa39e31 add deprecation notice
  • b0abed9 test more node versions. closes #5

See the full diff

Not sure how things should work exactly?

There is a collection of frequently asked questions and of course you may always ask my humans.


Your Greenkeeper Bot 🌴

An in-range update of is-buffer is breaking the build 🚨

Version 1.1.4 of is-buffer just got published.

Branch Build failing 🚨
Dependency is-buffer
Current Version 1.1.3
Type devDependency

This version is covered by your current version range and after updating it in your project the build failed.

As is-buffer is “only” a devDependency of this project it might not break production or downstream projects, but “only” your build or test tools – preventing new deploys or publishes.

I recommend you give this issue a high priority. I’m sure you can resolve this 💪


Status Details
  • coverage/coveralls First build on greenkeeper/is-buffer-1.1.4 at 100.0% Details

  • continuous-integration/travis-ci/push The Travis CI build could not complete due to an error Details

Commits

The new version differs by 13 commits .

  • fd1a429 1.1.4
  • e6a91ad test only latest node, for speed
  • 564ae0e Add node v0.10 support
  • b18b3e2 Test node 0.10, 0.12, 4, 6
  • 5ee68c0 comment
  • dac1435 zuul: disable flaky ios test
  • fadd5b1 Ensure that true/false is always returned, not just truthy/falsy
  • a11fd2a Merge pull request #10 from feross/greenkeeper-standard-7.0.0
  • 49f6048 chore(package): update standard to version 7.0.0
  • f74c4d7 zuul: add iphone test; remove opera
  • 0d86dca test latest node
  • f0cb436 Merge pull request #7 from paladox/patch-2
  • 07dcc2e Make tests run faster

See the full diff.

Not sure how things should work exactly?

There is a collection of frequently asked questions and of course you may always ask my humans.


Your Greenkeeper Bot 🌴

An in-range update of pre-commit is breaking the build 🚨

Version 1.2.2 of pre-commit just got published.

Branch Build failing 🚨
Dependency pre-commit
Current Version 1.2.1
Type devDependency

This version is covered by your current version range and after updating it in your project the build failed.

As pre-commit is “only” a devDependency of this project it might not break production or downstream projects, but “only” your build or test tools – preventing new deploys or publishes.

I recommend you give this issue a high priority. I’m sure you can resolve this 💪


Status Details
  • continuous-integration/travis-ci/push The Travis CI build could not complete due to an error Details

  • coverage/coveralls First build on greenkeeper/pre-commit-1.2.2 at 100.0% Details

Commits

The new version differs by 2 commits .

  • bf393ad [dist] 1.2.2
  • 675560c Use string instead of int 777 in fs.chmodSync so it gets correctly interpreted as octal (#90)

See the full diff.

Not sure how things should work exactly?

There is a collection of frequently asked questions and of course you may always ask my humans.


Your Greenkeeper Bot 🌴

An in-range update of mukla is breaking the build 🚨

Version 0.4.7 of mukla just got published.

Branch Build failing 🚨
Dependency mukla
Current Version 0.4.6
Type devDependency

This version is covered by your current version range and after updating it in your project the build failed.

As mukla is “only” a devDependency of this project it might not break production or downstream projects, but “only” your build or test tools – preventing new deploys or publishes.

I recommend you give this issue a high priority. I’m sure you can resolve this 💪


Status Details
  • continuous-integration/travis-ci/push The Travis CI build could not complete due to an error Details

  • coverage/coveralls First build on greenkeeper/mukla-0.4.7 at 100.0% Details

Commits

The new version differs by 2 commits .

  • 2e89f15 chore(release): 0.4.7
  • e3d0449 fix(dep): we uses clean-stacktrace instead of clean-stack

See the full diff.

Not sure how things should work exactly?

There is a collection of frequently asked questions and of course you may always ask my humans.


Your Greenkeeper Bot 🌴

An in-range update of pre-commit is breaking the build 🚨

Version 1.1.3 of pre-commit just got published.

Branch Build failing 🚨
Dependency pre-commit
Current Version 1.1.2
Type devDependency

This version is covered by your current version range and after updating it in your project the build failed.

As pre-commit is “only” a devDependency of this project it might not break production or downstream projects, but “only” your build or test tools – preventing new deploys or publishes.

I recommend you give this issue a high priority. I’m sure you can resolve this 💪


Status Details
  • continuous-integration/travis-ci/push The Travis CI build could not complete due to an error Details

  • coverage/coveralls First build on greenkeeper/pre-commit-1.1.3 at 100.0% Details

Commits

The new version differs by 11 commits .

  • 0f0833a [dist] 1.1.3
  • fa6119d Merge pull request #57 from blacksonic/master
  • 2abd42b Merge pull request #64 from kevinoid/relative-link
  • 1a04430 Make pre-commit hook symlink relative
  • 2ca2fb9 Merge pull request #60 from saiichihashimoto/patch-1
  • b6e63d7 Update README.md
  • 4510f45 [fix] add .bashrc to supported home files
  • 3f83f72 Merge pull request #54 from fhemberger/fix/dependencies
  • 683221f Merge pull request #53 from fhemberger/fix/travis
  • 53ec6e9 Update dependencies
  • eb7ac24 [travis] Add [email protected], use new container infrastructure

See the full diff.

Not sure how things should work exactly?

There is a collection of frequently asked questions and of course you may always ask my humans.


Your Greenkeeper Bot 🌴

An in-range update of is-buffer is breaking the build 🚨

Version 1.1.5 of is-buffer just got published.

Branch Build failing 🚨
Dependency is-buffer
Current Version 1.1.4
Type devDependency

This version is covered by your current version range and after updating it in your project the build failed.

As is-buffer is “only” a devDependency of this project it might not break production or downstream projects, but “only” your build or test tools – preventing new deploys or publishes.

I recommend you give this issue a high priority. I’m sure you can resolve this 💪


Status Details
  • coverage/coveralls First build on greenkeeper/is-buffer-1.1.5 at 100.0% Details

  • continuous-integration/travis-ci/push The Travis CI build could not complete due to an error Details

Commits

The new version differs by 5 commits .

See the full diff.

Not sure how things should work exactly?

There is a collection of frequently asked questions and of course you may always ask my humans.


Your Greenkeeper Bot 🌴

An in-range update of lazy-cache is breaking the build 🚨

Version 2.0.2 of lazy-cache just got published.

Branch Build failing 🚨
Dependency lazy-cache
Current Version 2.0.1
Type dependency

This version is covered by your current version range and after updating it in your project the build failed.

As lazy-cache is a direct dependency of this project this is very likely breaking your project right now. If other packages depend on you it’s very likely also breaking them.
I recommend you give this issue a very high priority. I’m sure you can resolve this 💪


Status Details
  • continuous-integration/travis-ci/push The Travis CI build could not complete due to an error Details

  • coverage/coveralls First build on greenkeeper/lazy-cache-2.0.2 at 100.0% Details

Commits

The new version differs by 3 commits .

See the full diff.

Not sure how things should work exactly?

There is a collection of frequently asked questions and of course you may always ask my humans.


Your Greenkeeper Bot 🌴

return `then-callback` promise

Like that on L48-49-50

promise = utils.normalizePromise(resolved, promise)
return utils.then(promise)

to be even able to pass callback to the returned promise's .then method.

const fs = require('fs')
const hybridify = require('hybridify')
const readdir = hybridify.hybridify(fs.readdir)

// called two times
function callback (err, files) {
  if (err) return console.error('callback err:', err)
  console.log('callback res:', files) // => array with directory files
}

const promise = readdir('./', callback)
promise.then(callback)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.