Efficient tree and linked list data structure using ES6 Symbols for DOM tree backing
—
Navigate between parents, children, and siblings with constant-time operations.
Determine if an object has any child objects.
/**
* Check if object has any children
* Time Complexity: O(1)
* @param {Object} object - Object to check
* @returns {boolean} True if object has children, false otherwise
*/
hasChildren(object: Object): boolean;Access first and last child objects.
/**
* Get the first child of an object
* Time Complexity: O(1)
* @param {Object} object - Parent object
* @returns {Object|null} First child object or null if no children
*/
firstChild(object: Object): Object | null;
/**
* Get the last child of an object
* Time Complexity: O(1)
* @param {Object} object - Parent object
* @returns {Object|null} Last child object or null if no children
*/
lastChild(object: Object): Object | null;Navigate between sibling objects.
/**
* Get the previous sibling of an object
* Time Complexity: O(1)
* @param {Object} object - Reference object
* @returns {Object|null} Previous sibling object or null if none
*/
previousSibling(object: Object): Object | null;
/**
* Get the next sibling of an object
* Time Complexity: O(1)
* @param {Object} object - Reference object
* @returns {Object|null} Next sibling object or null if none
*/
nextSibling(object: Object): Object | null;Access the parent of an object.
/**
* Get the parent of an object
* Time Complexity: O(1)
* @param {Object} object - Child object
* @returns {Object|null} Parent object or null if no parent
*/
parent(object: Object): Object | null;const SymbolTree = require("symbol-tree");
const tree = new SymbolTree();
// Create a tree structure
const parent = { name: "parent" };
const child1 = { name: "child1" };
const child2 = { name: "child2" };
const grandchild = { name: "grandchild" };
tree.appendChild(parent, child1);
tree.appendChild(parent, child2);
tree.appendChild(child1, grandchild);
// Navigate the tree
console.log(tree.hasChildren(parent)); // true
console.log(tree.hasChildren(child1)); // true
console.log(tree.hasChildren(child2)); // false
// Access children
console.log(tree.firstChild(parent) === child1); // true
console.log(tree.lastChild(parent) === child2); // true
// Navigate siblings
console.log(tree.nextSibling(child1) === child2); // true
console.log(tree.previousSibling(child2) === child1); // true
console.log(tree.nextSibling(child2)); // null (no next sibling)
// Access parents
console.log(tree.parent(child1) === parent); // true
console.log(tree.parent(grandchild) === child1); // true
console.log(tree.parent(parent)); // null (no parent)
// Traverse an entire branch
function printBranch(node, indent = 0) {
const spaces = " ".repeat(indent);
console.log(spaces + node.name);
for (let child = tree.firstChild(node); child; child = tree.nextSibling(child)) {
printBranch(child, indent + 2);
}
}
printBranch(parent);
// Output:
// parent
// child1
// grandchild
// child2const tree = new SymbolTree();
// Create a linked list
const nodeA = { value: "A" };
const nodeB = { value: "B" };
const nodeC = { value: "C" };
tree.insertBefore(nodeB, nodeA); // A -> B
tree.insertAfter(nodeB, nodeC); // A -> B -> C
// Navigate the linked list
let current = nodeA;
while (current) {
console.log(current.value);
current = tree.nextSibling(current);
}
// Output: A, B, C
// Navigate backwards
current = nodeC;
while (current) {
console.log(current.value);
current = tree.previousSibling(current);
}
// Output: C, B, AInstall with Tessl CLI
npx tessl i tessl/npm-symbol-tree