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

treewise

v2.0.1

Published

'treewise' is a TypeScript utility library providing functions for deep copying objects and arrays, processing arrays in batches, and performing various operations on tree data structures.

Readme

Treewise

A TypeScript library for managing tree (or forest) data structures, providing advanced features like:

  • Multiple root support
  • Batch operations (add/remove children in bulk)
  • Event handling (onNodeAdded, onNodeRemoved, onNodeUpdated, onNodeMoved)
  • Depth-first and breadth-first traversals
  • Internal indexing for fast lookups (findById)
  • Serialization and deserialization (with version checks)
  • Cloning of individual nodes or the entire forest
  • Utility functions for deep copying and batch processing arrays

Table of Contents


Installation

Install via npm (or yarn) by adding it to your package.json:

npm install treewise

or:

yarn add treewise

Then import it in your TypeScript or JavaScript files:

import { Treewise, TTreeNode } from 'treewise';

Usage

Creating a Treewise Instance

import { Treewise } from 'treewise';

interface MyNode {
  id: number;
  name: string;
}

// Create a new tree with one optional root node
const tree = new Treewise<MyNode>({ id: 1, name: 'Root' });

By default, Treewise supports multiple roots. You can add more root nodes later:

const root2 = { value: { id: 2, name: 'Another Root' } };
tree.addRoot(root2);

Adding and Removing Nodes

Add a Child

// Add a child node to an existing root
const childNode = tree.addNodeAsChild(
  tree.roots[0], 
  { id: 3, name: 'Child Node' }
);

Batch Add Children

tree.addChildren(tree.roots[0], [
  { id: 4, name: 'Batch Child 1' },
  { id: 5, name: 'Batch Child 2' },
]);

Remove a Node

tree.removeNode(childNode); // Removes a specific node

Remove Children in Batch

const childNodes = [ /* ...some TTreeNode<MyNode>[] ... */ ];
tree.removeChildren(tree.roots[0], childNodes);

Remove All Roots

tree.removeAllRoots(); // Clears all roots (and the index)

Traversing the Tree

Depth-First with pre-order or post-order:

tree.traverse((node, depth) => {
  console.log('Visited node:', node.value, 'at depth', depth);
}, 'pre-order');

You can also limit the traversal depth:

tree.traverse(
  (node, depth) => console.log(node.value),
  'pre-order',
  2 // maxDepth
);

Breadth-First traversal:

tree.traverseBreadthFirst((node, depth) => {
  console.log('BFS node:', node.value, 'depth:', depth);
});

Events

You can listen for various events like onNodeAdded, onNodeRemoved, onNodeUpdated, onNodeMoved.

// Register an event handler
const onNodeAddedHandler = (node) => {
  console.log('Node added:', node.value.id);
};

tree.on('onNodeAdded', onNodeAddedHandler);

// Remove the event handler when no longer needed
tree.off('onNodeAdded', onNodeAddedHandler);

onNodeUpdated is called for nodes changed via batchUpdate.
onNodeMoved can be emitted if you implement custom re-parenting logic.


Searching

Find a node via a custom predicate:

const foundNode = tree.find((node) => node.value.id === 3);
if (foundNode) {
  console.log('Found node with ID 3');
}

Find by ID with internal indexing:

const nodeById = tree.findById(3);

Cloning

Clone a specific node’s subtree (ignoring its parent reference):

const clonedSubtree = tree.cloneNode(nodeById);
console.log('Cloned node:', clonedSubtree);

Clone the entire forest into a separate Treewise instance:

const clonedForest = tree.cloneForest();
console.log('Cloned forest node count:', clonedForest.countNodes());

Serialization/Deserialization

Serialize the forest to JSON:

const jsonString = tree.serialize();

Deserialize:

const newTree = new Treewise<MyNode>();
await newTree.deserialize(Promise.resolve(jsonString));

Version mismatches in the JSON data will throw an error, ensuring compatibility.


Utility Functions

deepCopy deeply copies objects or arrays (including Date, RegExp, Map, and Set):

import { deepCopy } from 'treewise';

const original = { a: 1, b: [2, 3], date: new Date() };
const copy = deepCopy(original);

processArrayInBatches yields slices of an array in specified batch sizes:

import { processArrayInBatches } from 'treewise';

const data = [1, 2, 3, 4, 5];
for (const batch of processArrayInBatches(data, 2)) {
  console.log('Batch:', batch);
}

Testing

This package includes an example Jest test suite. To run it:

  1. Install dependencies:
    npm install --save-dev jest ts-jest @types/jest
  2. Configure Jest in your package.json or jest.config.js.
  3. Place the test file (e.g., treewise.test.ts) in your test directory.
  4. Run tests:
    npm test

License

MIT Made with ❤️ @pooyanpm