Coder Social home page Coder Social logo

isaacs / treeverse Goto Github PK

View Code? Open in Web Editor NEW
128.0 13.0 12.0 224 KB

Walk any kind of tree structure depth- or breadth-first. Supports promises and advanced map-reduce operations with a very small API.

License: ISC License

JavaScript 100.00%
npm-cli

treeverse's Introduction

treeverse

Walk any kind of tree structure depth- or breadth-first. Supports promises and advanced map-reduce operations with a very small API.

Treeverse does not care what kind of tree it is, it will traverse it for you just fine. It does the right thing with functions that return Promises, and returns a non-Promise value if your functions don't return Promises.

Rather than imposing a specific structure, like requiring you to have child nodes stored in a children array, it calls the supplied getChildren() function, so the children can be anywhere (or not even exist yet!) This makes it suitable for creating an optimized tree from a set of dependency manifests, for example.

USAGE

const {depth, breadth} = require('treeverse')

// depth-first traversal
// returns a promise if any visit/leave function returns a promise
// otherwise returns the result of leave, or visit if no leave function
// provided.
depth({
  // the root node where we start the traversal
  tree: rootNode,

  visit (node) {
    // optional
    // called upon descent into the node.
    // return a promise, or a mapped value, or nothing to just leave it
    // as-is
  },
  leave (node, children) {
    // optional
    // called as we ascend back to the root of the tree.
    // return a promise, or a reduced value, or nothing to leave it as is
    // the children array is a list of the child nodes that have been
    // visited (and potentially left) already.  If the tree is acyclic,
    // then leave() will have been called on all of them.  If it has
    // cycles, then the children may not have been left yet.
  },
  getChildren (node, nodeResult) {
    // required
    // return an array of child nodes in the tree, if any exist
    // returning a promise is totally ok, of course.
    // the first argument is the original value of the node.  The second
    // argument is the result of visit(node).
  },
  filter (node) {
    // optional
    // return true if the node should be visited, false otherwise
    // initial tree is always visited, so this only filters children
    // note that filtering a node _also_ filters all of its children.
  },
})

// breadth first traversal
// returns a promise if any visit function returns a promise
// otherwise returns the result of the top-level node.
// note that only a visit() function is supported here, since a node's
// children are typically traversed much later in the process.
breadth({
  // the root node where we start the traversal
  tree: rootNode,

  visit (node) {
    // optional, but a no-op if not provided.
    // called when this node is encountered in the traversal.
    // return a promise, or a mapped value, or nothing to leave as-is.
  },
  getChildren (node, nodeResult) {
    // required, same as depth()
  },
  filter (node) {
    // optional, same as depth()
  },
})

API

Both functions take a single options object as an argument, and return either the result value, or a Promise to the result value if the methods in the options argument ever return a Promise.

  • treeverse.breadth - Perform a breadth-first traversal. That is, walk across node siblings before traversing node children.
  • treeverse.depth - Perform a depth-first traversal. That is, walk down into child nodes before traversing siblings.

OPTIONS

All function options can return a Promise or actual value.

The return value is the result of the top level visit function if no leave function is provided, or leave. If any method along the way returns a promise, then the top level function will return a promise which resolves to the result of visiting (and leaving) the top node in the tree.

  • tree - The initial node where the traversal begins.
  • visit(node) - Function to call upon visiting a node.
  • leave(node, children) - (Depth only) Function to call upon leaving a node, once all of its children have been visited, and potentially left. children is an array of child node visit results. If the graph is cyclic, then some children may have been visited but not left.
  • getChildren(node, nodeResult) - Get an array of child nodes to process.
  • filter - Filter out child nodes from the traversal. Note that this filters the entire branch of the tree, not just that one node. That is, children of filtered nodes are not traversed either.

STACK DEPTH WARNING

When a leave method is specified, then recursion is used, because maintaining state otherwise is challenging. This means that using leave with a synchronous depth first traversal of very deeply nested trees will result in stack overflow errors.

To avoid this, either make one or more of the functions async, or do all of the work in the visit method.

Breadth-first traversal always uses a loop, and is stack-safe.

It is possible to implement depth first traversal with a leave method using a loop rather than recursion, but maintaining the leave(node, [children]) API surface would be challenging, and is not implemented at this time.

treeverse's People

Contributors

dependabot[bot] avatar github-actions[bot] avatar isaacs avatar lukekarrys avatar papb avatar theniceangel avatar wraithgar avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

treeverse's Issues

Reporting a vulnerability

Hello!

I hope you are doing well!

We are a security research team. Our tool automatically detected a vulnerability in this repository. We want to disclose it responsibly. GitHub has a feature called Private vulnerability reporting, which enables security research to privately disclose a vulnerability. Unfortunately, it is not enabled for this repository.

Can you enable it, so that we can report it?

Thanks in advance!

PS: you can read about how to enable private vulnerability reporting here: https://docs.github.com/en/code-security/security-advisories/repository-security-advisories/configuring-private-vulnerability-reporting-for-a-repository

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.