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 🙏

© 2025 – Pkg Stats / Ryan Hefner

chainstyle

v0.0.2

Published

Easy to make strong chain style interface

Readme

Chainstyle

This tool helps to build chain style interface.

Chain style interface is popular, we like this kind of interface than big json interface, it looks like:

m.getUp(time).wash(time).eat(time).out(time)

There are two main problems for chain style interface:

  • calling order

In prev example, getUp, wash, eat and out have sequence relationship, we do not want user to call this chain like m.out(time).getUp(time).

  • lazy execution

We want to lazy our executation, we want to use those data at the last moment.

chainstyle can satisfy both.

Install

npm install chainstyle

example

var chainStyle = require("chainstyle");

let clz = chainStyle({
    getUp: null,
    wash: null
},{},{});

let inst = new clz();

inst.getUp("10:00", "bedroom").wash("10:30");

inst.end((queueInfo) => {
    let map = queueInfo.getMap();
    console.log(map["getUp"].args[0]); // 10:00
    console.log(map["getUp"].args[1]); // bedroom
    console.log(map["wash"].args[0]); // 10:30
});

Initial API

chainstyle( chainMap = { key:config }, otherMap = { key:config }, opts = {} )

  • chainMap

    Define chain style functions.

    Key is function name, value is a config for function, could be null or undefined.

    Function name defined in chainMap, can be used as chain function. Like the getup, wash, eat and out function.

// default config by using null
// chainMap
{
    a: null,
    b: null
}
// you can use function as the config
// chainMap
{
    a: function(){},
    b: function(){}
}

// you can use an object as the config
// chainMap
{
    a: {
        checkType: ["string & truthy"],
        method: function(){}
    },
    b: {
        checkType: ["string"]
    }
}

If the config is a function it will run when end function (what is end, see next more) called.

If the config is an object, contains two attributes at most, checkType and method. The meaning of method is that it will run when end function called.

CheckType used to check input of function. It's a function or an array of string, each string is a logic expression and used to check correspond input param.

  let clz = chainStyle({
      a: {
          checkType: ["string & truthy", "string"]
      },
      b: {
          checkType: function(str){ return typeof str === "string"; }
      }
  });
  let inst = new clz();
  inst.a("ok", [123]).b("456").end(); 
  // will throw exception, because the second param [123] is not a "string".

About checkType string expression, see typevalidator and logicer.

  • otherMap

OtherMap used to define function which is not a chain style function but normal function.

let clz = chainStyle({
    // chainMap
}, {
    // otherMap
    double: {
        method: function(v){ return 2 * v; }
    }
});

let inst = new clz();
console.log(inst.double(10)); // 20

Like chainMap's config, otherMap's config can use function and object two types just like chainMap.

  • opts.init

function default is undefined.

The init function will execute when constructor execute.

  • opts.chainRegular

RegExp defaul is undefined.

Used to validate chain style calling queue.

let clz = chainStyle({
    getUp: null,
    wash: null,
    eat: null
}, {}, {
    chainRegular: /^getUp\.wash\.eat$/
});

var inst = new clz();
inst.wash("10:00").eat("11:00").getUp("12:00").end();
// will throw exception, because calling queue "wash.eat.getUp" 
// fails to regular expression /^getUp\.wash\.eat$/

By using chainRegular option we can design strict calling order easily.

  • opts.typeMap

Used to create own types. See typevalidator.

// define type isA and isB
{
    "isA": function(x){},
    "isB": function(x){}
}
// use for checkType
checkType: ["isA | object" , "isB & truthy"]

end

By now, we know how to provide chain style interface to user, but how to get user's inputs in the calling queue.

The end function is a special function, used to indicate calling is end. And provide a callback to get all inputs through the calling chain.

  • when the end called, all chain functions will run.

  • end can be call multiple times, when you call end continuously, chain functions will run just once.

  • the callback for end will have a param queueInfo, which provide functions getMap and getArrMap.

getArrMap will return all inputs event a chain function was called multiple times, getMap just return the latest inputs for every chain functions. If a chain function was called multiple times, getMap will only return latest one.

// getArrMap

let clz = chainStyle({
    a: null
});

let inst = new clz();
inst.a("123", null).a("789", 6);

inst.end(function(queueInfo) {
    let map = queueInfo.getArrMap();
    console.log(map["a"][0].args[0]); // 123
    console.log(map["a"][1].args[1]); // 6
    done();
});
// getMap

let clz = chainStyle({
    a: null
});

let inst = new clz();
inst.a(null, 44).a("123", 12);

inst.end(function(queueInfo){
    let map = queueInfo.getMap();
    console.log(map["a"].args[0]); // 123
    console.log(map["a"].args[1]); // 12
    done();
});

License

MIT