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 🙏

© 2026 – Pkg Stats / Ryan Hefner

rblb-utils

v3.1.0

Published

Common utils and shims used by RBLB projects

Downloads

19

Readme

rblb-utils

Common utils and shims used by RBLB projects

Basically, this is just my lazy way of adding a few choice shims that I use regularly in certain projects. You might want to look at lodash instead as it's better for public use ;)

Install

$ yarn add rblb-utils

or

$ npm install --save rblb-utils

Usage

require("rblb-utils"); // No need toassign to an object as it's all shims

Included

Shims

Object.entries(Obj)

Object.entries({"a": 1, "b": 2}) 
// => [["a", 1], ["b", 2]]

Object.prototype.oentries()

{"a": 1, "b": 2}.oentries() 
// => [["a", 1], ["b", 2]]

Object.values(Obj)

Object.values({"a": 1, "b": 2})
// => [1, 2]

Object.prototype.ovalues()

{"a": 1, "b": 2}.ovalues() 
// => [1, 2]

Object.oreduce(Obj, fn)

const source = {"a": 1, "b": 2};
Object.oreduce(source, (acc, k, v) => {
    acc[k] = v;
    if (v%2 == 0) {
      acc.evens = (acc.evens || 0 ) + 1;
    } else {
      acc.odds = (acc.odds || 0) + 1;
    }
    return acc;
  }, {"c": 3})
// {"a": 1, "b": 2, "c": 3, "odds": 1, "evens": 1} 

Initial value is optional:

const source = {"a": 1, "b": 2};
Object.oreduce(source, (acc, k, v) => {
    acc[k] = v;
    if (v%2 == 0) {
      acc.evens = (acc.evens || 0 ) + 1;
    } else {
      acc.odds = (acc.odds || 0) + 1;
    }
    return acc;
  })
// {"a": 1, "b": 2, "odds": 1, "evens": 1} 

Object.prototype.oreduce(fn)

const source = {"a": 1, "b": 2};
source.oreduce((acc, k, v) => {
    acc[k] = v;
    if (v%2 == 0) {
      acc.evens = (acc.evens || 0 ) + 1;
    } else {
      acc.odds = (acc.odds || 0) + 1;
    }
    return acc;
  }, {"c": 3)
// {"a": 1, "b": 2, "odds": 1, "evens": 1, "c": 3} 

Initial value is optional:

const source = {"a": 1, "b": 2};
source.oreduce((acc, k, v) => {
    acc[k] = v;
    if (v%2 == 0) {
      acc.evens = (acc.evens || 0 ) + 1;
    } else {
      acc.odds = (acc.odds || 0) + 1;
    }
    return acc;
  })
// {"a": 1, "b": 2, "odds": 1, "evens": 1} 

Object.omap(Obj, fn)

const source = {"a": 1, "b": 2};
Object.omap(source, (k, v) => (k==="a") ? v*2 : 0);
// {"a": 2, "b": 0}

Object.prototype.omap(fn)

const source = {"a": 1, "b": 2};
source.omap((k, v) => (k==="a") ? v*2 : 0);
// {"a": 2, "b": 0}

Object.ofilter(Obj, fn)

const source = {"a": 1, "b": 2, "c": 3};
Object.ofilter(source, (k, v) => k === "a" || v%2 ==0);
// {"a": 1, "b": 2}

Object.prototype.ofilter(fn)

const source = {"a": 1, "b": 2, "c": 3};
source.ofilter((k, v) => k === "a" || v%2 ==0);
// {"a": 1, "b": 2}

Object.pickAndAssign(...sources)

const source1 = {"a": "nope"};
const source2 = {"c": "nope"}
const source3 = {"a": "yes", "b": "also", "c": "nope"};
{"a": 1, "b": 2}.pickAndAssign(source1, source2, source3);
// {"a": "yes", "b": "also"}

Useful if you have an object containing default config and want to extract the values from multiple hierarchical config sources with many entries:

const defaults = {
    "a": 1,
    "b": undefined,
    "c": "xyz"
}

const configSourceA = {
    "a": 2
    ...
}
const configSourceB = {
    "a": 3,
    "b": "x"
    ...
}

defaults.pickAndAssign(configSourceA, configSourceB);
// => {"a": 3, "b": "x", "c": "xyz"}

Array.seqAsync(fn)

Stands for "Sequential Async". It will run the async function on each value in the array in turn, waiting for the previous function to complete before stepping through to the next. If fn is not async then use Array.forEach(fn) or Array.map(fn) if you need the result.

The result returned by each function's promise is passed as a parameter to the next, so this is also effectively a reducer.

const fn = (x) => {
    return someAsyncFn(c)
        .then(console.log(x));
}
["a", "b", "c"].seqAsync(fn)
// => "a"
// => "b"
// => "c"

Array.toObjectKeys()

["a", "b", "c"].toObjectKeys()
// => {"a": undefined, "b": undefined, "c": undefined}

Handy in conjunction with pickAndAssign for setting up the initial object and then pulling out the values from other objects. e.g. for extracting a subset of config from multiple hierarchical config sources:

const desiredConfig = ["a", "b", "c"]
const configSourceA = {
    "a": 1 
    ...   
}
const configSourceB = {
    "a": 2,
    "b" "x"
    ...
}
desiredConfig.toObjectKeys().pickAndAssign(configSourceA, configSourceB);
// => {"a": 2, "b": "x", "c": undefined}

Testing

npm run mocha

License

MIT © [Alastair Brayne]