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

dangit

v0.3.1

Published

A utility library for JavaScript quirks.

Downloads

15

Readme

dangit Build status for dangit on Codeship.

A utility library for JavaScript quirks.

Why?

  • Validate user input.
  • Get the global object in any environment.
  • Create namespaces non-destructively.
  • See if native APIs have been modified.

Install

npm install dangit --save

Usage

Get it into your program.

const dangit = require('dangit');

In a browser, use an AMD loader like Alameda.

define(['dangit'], (dangit) => {

});

Retrieve the true type of any input, as a lowercase string.

const input = null;
dangit.whatis(input);  // => "null"

But why type all that and still have to do a strict equality check? Fuggedaboutit.

const input = null;
dangit.isNull(input);  // => true

Congrate, you saved 3 characters over typeof and you weren't lied to.

Another benefit is more intuitive operator precedence.

Next let's get the ever present global object.

dangit.getTheGlobalObject();  // => window in browsers, global in Node.js, etc.

It's a smarty pants function and won't get tricked as easily as you may think.

// Anywhere in Node.js.
const window = {};
dangit.getTheGlobalObject() === window;  // => false

or...

// Anywhere in a browser.
const global = {};
dangit.getTheGlobalObject() === global;  // => false

Isn't that warm and cozy? Just look at it.

Another common task is to construct an API namespace. Let's do that.

const ns = dangit.namespace('superb.llamas');  // => returns a namespaced global object

or if you already have something to extend...

const
    x = { y:{} },
    z = x.y,
    ns = dangit.namespace(z, 'pirates.forever');  // => returns a new object, which is only global if z was

Notes:

  • It is destructive by default in that if any part of the chain is not a truthy object or function, it has to overwrite that property with a new object to keep going. But...
  • If you pass false as the last argument, it will turn off force mode, throwing an error instead. And...
  • It will never destroy anything it doesn't have to.
  • To protect you from yourself, it only ever considers an object's own properties. An API without this restriction would be easy, file an issue if you want it.

Once you've got a namespace, you could really use some ninjas to help solve that issue where you want everything to be coerced to an easy-to-process list. Or a unicorn - that would do nicely, too.

function dream() {
    const args = dangit.flatten(arguments);
    console.log(args.join(' ') + ', whatever');
}
dream(['people', ['pass'], ['weird']], 'stuff')  // => "people pass weird stuff, whatever"

Yeah that's basically a real actual, magical unicorn for your APIs.

Who cares if they used querySelector or querySelectorAll, just flatten and process whatever you get the same way, 100% of the time.

So then you've got your cool new 3rd party JavaScript library and you find out your logger doesn't work on some website because they decided to prevent developers from accidentally being noisy in production.

dangit.isNative(console.log);  // => true only if it hasn't been overwritten
console.log = function () {};
dangit.isNative(console.log);  // => false

Note: This only works for functions and does not guarantee their properties are intact, file an issue if you want more.

And if you really flippin' want the console back, we've got some hacks up our sleeve.

dangit.resetConsole()

So now you want to figure out if it makes sense to loop over some input. It could be a NodeList, HTMLCollection, a plain old array, or something far more devious.

let input = 'abc';
dangit.isArrayish(input);  // => false, even though it has a length of 3
input = function (a, b) {};
dangit.isArrayish(input);  // => false, even though it has a length of 2
input = document.querySelectorAll('a');
dangit.isArrayish(input);  // => true, even though it is not a typical array

After tooling up to process input, you'll come across situations where you need to provide defaults or keep track of state during asynchronous tasks. Do this by stamping a new object with a bunch of properties.

const
    keys   = ['a', 'b', 'c', 'd'],
    values = false;
dangit.stampObject(keys, values);  // => {a: false, b: false, c: false, d: false}

You can provide either argument as a simple value or an array-like object, they will be flattened. Values will be used until there's no more left, at which point the last one will become sticky.

const
    keys   = ['a', ['b', 'c'], 'd'],
    values = [false, true];
dangit.stampObject(keys, values);  // => {a: false, b: true, c: true, d: true}

And also...

const
    keys   = ['a', 'b', 'c', 'd'],
    values = [false, 1, 1, true, 6, 'moo' ];  // it is safe to over-provide
dangit.stampObject(keys, values);  // => {a: false, b: 1, c: 1, d: true}

Do some stuff with that stamp, then when the time is right, make sure the results were what you expected.

const
    keys   = ['a', 'b', 'c', 'd'],
    values = false,
    stamp  = dangit.stampObject(keys, values);  // => {a: false, b: false, c: false, d: false}
// ... do async stuff with each, set to true when complete ...
// ... then, later...
dangit.checkStamp(stamp, true);  // => true

Note: Due to the non-guaranteed order of enumerating objects, this is not quite like .stampObject() - it can only take a simple value to check for an entire object. To compensate a bit, it does non-strict equality checking by default, with a third boolean argument for making it strict. File an issue if you want more.

Another task that could be simpler is processing a bunch of configuration just to ignore certain parts of it. We've got that covered, too.

function makeUrl(customer, mediaType, file) {
    return dangit.joinTruthy(
        { separator : '/' },
        '//mysite.com',
        customer,
        mediaType,
        file
    );
}
makeUrl('steve', 'img', 'funny.jpg');  // => '//mysite.com/steve/img/funny.jpg'
makeUrl('jane', false, 'config.js');  // => '//mysite.com/jane/config.js'

Contributing

See our contributing guidelines for more details.

  1. Fork it.
  2. Make a feature branch: git checkout -b my-new-feature
  3. Commit your changes: git commit -am 'Add some feature'
  4. Push to the branch: git push origin my-new-feature
  5. Submit a pull request.

License

MPL-2.0 © Seth Holladay

Go make something, dang it.