npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

whif

v1.2.0

Published

Promises A+ implementation

Downloads

3

Readme

whif

this is a Promises A+ implementation compliant with version 1.1 passing the tests. many thanks to this lib's originator Rhys Brett-Bowen and his great article on Promises/A+ - understanding the spec through implementation.

quick reference

signature | description --- | --- [new] whif([init]) | constructor/factory with optional init = function(res, rej){/*...*/} whif.resolve(value) | perform the resolve procedure on value whif.reject(reason) | wrap reason in a rejected promise whif.join(thenables) | returns promise that resolves when all child promises resolve or proxies the earliest rejection. whif.nextTick(callback) | shim for process.nextTick promise._resolve(value) | resolve a yet pending deferred promise._reject(value) | reject a yet pending deferred promise.then(res, rej) | returns the succeeding promise promise.fail(rej) | promise.then(id, rej) promise.sync() | make promise's resolution synchronous

usage

(use whif as a factory method || prepend the new operator) && pass a function to it for scoped behaviour, isolated from the surrounding code.

var promise = whif(function(resolve, reject){
  if(condition) resolve(value);
  else reject(reason);
})

the above's equivalent using whif's private deferred api:

var promise = (function(){
  var deferred = whif();
  if(condition) deferred._resolve(value);
  else deferred._reject(reason);
  return deferred;
}())

the usual suspect (chained to the above)

.then(function(value){
  // success
}, function(reason){
  // failure
});

convenience shortcuts

promise.fail(function(reason){/*...*/});
var resolvedPromise = whif.resolve(value); // not necessarily fulfilled!
var rejectedPromise = whif.reject(reason);

grouping promises/concurrent processes

whif.join([p, q, true])
  .then(function(values){
    var p_value = values[0];
    var q_value = values[1];
    var boolean = values[2];
    throw new Error();
  })
  .fail(function(reason){
    // handler for whichever was rejected first,
    // not necessarily the error thrown above!
  });

whif ships with a shim for cross-platform/-browser process.nextTick which falls back to (vendor specific) requestAnimationFrame, setImmediate or setTimeout.

whif.nextTick(function(){
  // executed in the next run-loop-cycle
});

promises usually resolve/reject their successors asynchronously to ensure consistent behaviour/order of execution since code wrapped in promises may or may not involve asynchronous actions.

var promise = whif.resolve('foo');
promise.then(console.log);
console.log('bar');

the above logs bar first and then foo because the then-handler is wrapped by process.nextTick internally. however, if a promise wraps an asynchronous action anyway it's actually not necessary to defer the resolution until the next tick and thereby twice. for this and other edge cases you may call whif's sync method on the promise before you bind successors.

var promise = whif
  .resolve($.ajax(request_settings))
  .sync().then( /* ... */ )
  .sync().fail( /* ... */ );

be careful with this option since success may be yielded asynchronously but failure synchronously depending on your implementation. remember that promises were normalized by prolonging the resolution because of these potential differences in the first place.

tests & docs

prerequisites

  • python pygments for generating the annotated source
  • grunt-cli for use of grunt build commands
  • gzip for further compression of minified version

setup

$ git clone <this-repo> <target-folder>
$ cd path/to/<target-folder>
$ npm install

generate docs

generates the annotated source to the ./docs folder

$ grunt docs

build

jshint checks, uglifys source to ./dist/whif.min.js for production environments (~2.4 kb) and browserifys test bundle to ./test/whif.test.bundle.js

$ grunt

for convenience there is a ready-made gzip command to further compress the minified version to ./dist/whif.min.js.gz (~1.1 kb)

$ npm run-script gzip

run tests

in nodejs

$ npm test

in your browser (requires grunt build)

$ python -m SimpleHTTPServer

then fire up your favorite browser and point it to localhost:8000/test to run the tests or localhost:8000/docs to read whif's story - the annotated source.

licence

MIT