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

promitator

v0.1.0

Published

Promise helper for delayed initialization

Downloads

3

Readme

Promitator

Promitator is a small module that helps to work with promise-based API by providing generic mechanism for lazy initialization. It is based on ES6 Promise, so for now it will work with Node 4.x only in harmony mode. This is kind of experimental work for exploring JS metaprogramming.

Module concept is quite simple. Nowadays there is a lot of convenient promise-based APIs, or APIs, that we can promisify. But sometimes they do require extra initialization step, which is not that convenient. Everybody like to use get rid of unnecessary routines and boilerplate.

Promitator is a single function, that wraps any async function (or promise) into promise, that pretends to be a resulting object and imitates all of it's method (via ES6 proxy).

var db = promitator(function(callback) {
    someDbModule.connect('127.0.0.1:11211', opts, function(db) {
        callback(null, db);
    });
});

// You can start working with resulting object like
// you had already got result, not just a promise

db.get("some_key").then(function() {...})

Prerequisites

  • Node >= 4.0
  • --harmony --harmony_proxies flags (You can use harmonize module for that)

Installation

$ npm install promitator

Usage

Promitator simple returns a promsise, that imitates resulting object. It can be used in numerous ways.

var objProxy = promitator(Promise.resolve({
    test: function() {
        return Promise.resolve('This is test!');
    }
}));

objProxy.test().then((res) => {
    console.log(res); // Wow, this is realy test!
});

Every call on promitated object returns a new promise proxy, which imitates new object, which will be returned by result of imitated call. So you can easily chain proxies. This can be applied to sync methods as well.

var deep = function deep(level) {
    return Promise.resolve({
        deep: function() {
            return deep(level + 1);
        },
        level: level
    });
};

promitator(deep(0)).deep().deep().deep().deep().then((res) => {
    console.log(`${res.level} levels deep`); // 4 levels deep
});

If promise proxy stands in your way, you can easilly get access to original object just by resolving promise

objProxy.then((realObject) => {
    // whatever
});

The most prominent way of using promitated objects for me is passing them to module.exports. Since module system in Node.js is quite powerful, is has problems while dealing with async initialization. Of course you can pass just a promise, but it will force you to use .then() method each time you want to use object's method.

Finally here is real mongodb-native example, which is fully working and helps to understand this idea

// Usual flow requires pre initialization, like:
// MongoClient.connect(url).then(function(db) {
//     db.collection('samples')....
// })

// We can export working object, so any module can just
// require and use, no need to worry about initialization
// and syncing (since each promise is resolved only once)
var db = module.exports = promitator(function(callback) {
    return MongoClient.connect(url, callback);
});

// Promise as initializer works as well
// var db = promitator(MongoClient.connect(url));

db.collection('samples').insertOne({
    message: 'This is sample; Generated at ' + Date.now()
}).then((res) => {
    var id = res.ops[0]._id;
    console.log('Sample created with id: ' + id);
    return db.collection('samples').remove({_id: id});
}).then(() => {
    console.log('Sample deleted');
    return db.close();
}).catch((e) => {
    console.log('We got error, chief!', e.stack);
    process.exit(1);
});

Trade-offs

  • Requires promise or sync API for object to work properly. Does NOT promisifies callback methods, you have to do it yourself at first
  • Sync methods becomes promisified (In fact module just prepends init promise to any call, so sync calls are also resolved by a promise)
  • Depending on what promises you use, you could get conflict between promise api. Since proxy tries to be a promise at first, it can shadow some imitated object methods. I stuck into bluebirds's Promise#get method once.
  • As expected, it slows code a bit. But not that much if we speak about async network operations. (Maybe you'll help me to create good benchmark)

License

The MIT License (MIT)

Copyright (c) 2015 Anton Sidelnikov