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

gnosis

v0.3.0

Published

A utility to traverse an object and execute a callback to transform the object, etc.

Downloads

91

Readme

#Gnosis v0.2.0

##What is it? Gnosis is a utility to traverse JavaScript objects, allowing you to pass a callback to do something with each member of the object, etc. You can transform the object in place, or do anything else you need.

##API It's pretty simple. The main method you're concerned with is: gnosis.traverse(targetObject, transformCallback [,path, options]);

The transformCallback argument is a function with the following signature:

var cb = function(instance, key, val, meta, root) {
  /*
    instance is the object that owns the member we're on
    key is the member name
    val is the current value of target[key]
    meta is an object containing the following:
      {
        source    : OBJECT - The source of the property descriptor. This could
                    be the instance for instance props OR a prototype for things
                    like Array.prototype.push, etc. USE THIS WITH CAUTION!
        name      : STRING - The member name,
        descriptor: OBJECT - Result of calling Object.getOwnPropertyDescriptor(source, name),
        path      : STRING - The dot-notation hierarchy of the path to the member.
                    For example, if you have an array containing address objects, you might
                    see a path like this: {ROOT}.addresses.0.street1. It's possible to use
                    the path to build a full reference to the target field from the root
        level     : INTEGER - The depth in the prototype chain. 0 = instance, 1 first prototype, etc.
        type      : STRING - The result of calling Object.prototype.toString.call(instance[key]);
      }
    root is the top level object that was originally passed to traverse as the target.
  */
}

##Example

In the example below, we take a simple object and traverse it, forcing getters and setters on the members, and writing a message to the DOM with information about properties being read or written to (or in the case of push on the array, we find out if it was invoked, etc.).


var me = {
    name: "Jim",
    city: "Signal Mountain",
    family: ["Stephanie"]
};

gnosis.traverse(
    me,
    function(target, key, val, meta, root) {
        var v = val;
        if (key === "push" && meta.type === "[object Function]" && Object.prototype.toString.call(target) === "[object Array]") {
            target[key] = function() {
                val.apply(target, arguments);
                writeToDom("The value '" + arguments[0] + "' was pushed into the array.");
            };
        } else if (key !== "length") {
            Object.defineProperty(target, key, {
                enumerable: true,
                configurable: true,
                get: function() {
                    var action = meta.type === "[object Function]" ? "invoked" : "read";
                    writeToDom("The '" + key + "' " + meta.type + " was " + action + ".");
                    return v;
                },
                set: function(x) {
                    v = x;
                    writeToDom("The '" + key + "' value was set.");
                }
            });
        }
    },
    "me", {
        nonEnumerable: true,
        walkPrototype: true
    }
);

me.name = "James";
me.city = "Chattanooga";
me.family.push("Ian");

/*
 The following output would be generated:
    The 'family' [object Array] was read.
    The 'name' value was set.
    The 'city' value was set.
    The 'family' [object Array] was read.
    The value 'Ian' was pushed into the array.
*/

For a live demo of usage, see this jsbin