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 treewiseor:
yarn add treewiseThen 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 nodeRemove 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:
- Install dependencies:
npm install --save-dev jest ts-jest @types/jest - Configure Jest in your
package.jsonorjest.config.js. - Place the test file (e.g.,
treewise.test.ts) in your test directory. - Run tests:
npm test
License
MIT Made with ❤️ @pooyanpm
