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

hookable-tree

v1.1.0

Published

Javascript librairy to build and manipulate hookable trees.

Downloads

1,194

Readme

Tree.js Build Status

Tree.js is a JavaScript library to build and manipulate hookable trees.

Installation

It is available with bower:

bower install tree.js

Then add the retrieved files to your HTML layout:

<script type="text/javascript" src="/path/to/bower_components/tree.js/tree.min.js"></script>
<!-- If you want to build hookable tree (see below) -->
<script type="text/javascript" src="/path/to/bower_components/q/q.js"></script>

You can also use it with RequireJS as an AMD module.

Usage

Simple tree

Create a tree


var myTree = Tree.tree({
    children: [
        {
            name: 'dupuis',
            children: [
                {
                    name: 'prunelle',
                    children: [
                        {
                            name: 'lebrac',
                            job: 'designer'
                        },
                        {
                            name: 'lagaffe',
                            firstname: 'gaston',
                            job: 'sleeper'
                        },
                    ]
                }
            ]
        }
    ]
});

Find a node

var lebrac = myTree.find('/dupuis/prunelle/lebrac');

// or

var lebrac = myTree.find('/dupuis').find('/prunelle/lebrac');

// or

var lebrac = myTree.find('/dupuis').find('/prunelle').find('/lebrac');

Get the raw data of a node

lebrac.data() // { name: 'lebrac', job: 'designer' }

Get an attribute

lebrac.attr('job'); // designer

Set an attribute

lebrac.attr('job', 'director');
lebrac
    .attr('location', 'here')
    .attr('hobby', 'design');

Get the path of a node

lebrac.path(); // /dupuis/prunelle/lebrac

Get the parent of a node

var dupuis = lebrac.parent();
dupuis.name(); // dupuis
dupuis.parent(); // undefined

Append a child node

lebrac.append(Tree.tree({
    name: 'paper',
    children: [{ name: 'pen' }]
}));

lebrac.find('/paper/pen');
lebrac.find('/paper').parent().parent().parent().name(); // dupuis

Remove a node

lebrac.remove();
myTree.find('/dupuis/prunelle/lebrac'); // undefined

Move a node

var lagaffe = myTree.find('/dupuis/prunelle/lagaffe').moveTo(myTree.find('/dupuis'));
lagaffe.path(); // /dupuis/lagaffe

Get the children of a node

var children = myTree.find('/dupuis').children();
children[0].name(); // prunelle

Get a node visitor

In order to execute a callback on each node of the tree, you can use a visitor:

var visitor = myTree.visitor();
visitor(function(node) {
    // you can now interact with each node
});

Stringify a node

On any node you can call stringify to serialize it. Internally it will use JSON.stringify with custom replacer to avoid circular references because of the _parent private property:

myTree.stringify()

Work with hooks

To work with hooks, you first need to add hook capacities to your tree:

var hookableTree = Tree.hookable(myTree);

Everything explained above is still true but the hookable operations will now return promises!

Because of that you need to include into your page Q library. Otherwise you can specify another promises library by calling: hookableTree.promiseFactory(YOUR_FACTORY). It must expose the same API than Q.

You can configure the timeout used for each listener by calling hookableTree.timeout(30000). Set it to 0 to disable it, default to 30000.

Register a hook listener

There are 12 hooks available:

| Hook | Description | | ----------------: |:-------------------------------------------------------------------| | HOOK_PRE_APPEND | Triggered when append is called and before applying it on the tree | | HOOK_POST_APPEND | Triggered when append is called and after applying it on the tree | | HOOK_ERROR_APPEND | Triggered when append is called and an error occured | | HOOK_PRE_REMOVE | Triggered when remove is called and before applying it on the tree | | HOOK_POST_REMOVE | Triggered when remove is called and after applying it on the tree | | HOOK_ERROR_REMOVE | Triggered when remove is called and an error occured | | HOOK_PRE_MOVE | Triggered when moveTo is called and before applying it on the tree | | HOOK_POST_MOVE | Triggered when moveTo is called and after applying it on the tree | | HOOK_ERROR_MOVE | Triggered when moveTo is called and an error occured | | HOOK_PRE_CLONE | Triggered when clone is called and before applying it on the tree | | HOOK_POST_CLONE | Triggered when clone is called and after applying it on the tree | | HOOK_ERROR_CLONE | Triggered when clone is called and an error occured |

To register a hook you need to call registerListener(string hook, function listener):

hookableTree.registerListener(hookableTree.HOOK_PRE_APPEND, function(newNode) {
    // I am a hook listener, I will be triggered before any append operation.

    // The arguments are not always the same depending on the hook.
    // Hook context is the tree.

    this; // will be our tree

    // If you need to perform asynchronous operation, just return a promise.
});

Because of hooks, append, remove, move, clone will return promise, as show in this example:

hookableTree.append(Tree.tree({ name: 'spirou'})).then(function(childNode) {
    // Everything is ok, it worked!
    // When you append a node, you can either give as argument a tree or hookable tree.
    // If it is a hookable tree, its hook listeners will added to the parent tree.
}, function(err) {
   // An error occured or a hook listener failed
});
hookableTree.find('/dupuis').remove().then(function(dupuisParent) {
    // Everything is ok, it worked!
}, function(err) {
    // An error occured or a hook listener failed
});
hookableTree.find('/dupuis/prunelle').moveTo(hookableTree).then(function(prunelle) {
    // Everything is ok, it worked!
}, function(err) {
    // An error occured or a hook listener failed
});
hookableTree.find('/dupuis/prunelle').clone().then(function(clonedPrunelle) {
    // Everything is ok, it worked!
}, function(err) {
    // An error occured or a hook listener failed
});

Build

To rebuild the minified JavaScript you must run: make build.

Tests

Install dependencies and run the unit tests:

make install
make test-spec

Contributing

All contributions are welcome and must pass the tests. If you add a new feature, please write tests for it.

License

This application is available under the MIT License, courtesy of marmelab.