TONL Navigation API Reference
November 16, 2025 ยท View on GitHub
Version: 2.0.6 Status: Stable & Production Ready Last Updated: 2025-11-16
Overview
The Navigation API provides iteration and tree traversal capabilities for TONL documents.
Iterators
entries()
Iterate over [key, value] pairs at the root level.
for (const [key, value] of doc.entries()) {
console.log(`${key}: ${JSON.stringify(value)}`);
}
keys()
Iterate over keys at the root level.
for (const key of doc.keys()) {
console.log(key);
}
values()
Iterate over values at the root level.
for (const value of doc.values()) {
console.log(value);
}
Deep Iterators
deepEntries()
Recursively iterate over all [path, value] pairs.
for (const [path, value] of doc.deepEntries()) {
console.log(`${path}: ${value}`);
}
// Output:
// user: { name: 'Alice', age: 30 }
// user.name: Alice
// user.age: 30
// users: [...]
// users[0]: { id: 1, name: 'Bob' }
// users[0].id: 1
// users[0].name: Bob
deepKeys()
Recursively iterate over all paths.
const allPaths = Array.from(doc.deepKeys());
// ['user', 'user.name', 'user.age', 'users', 'users[0]', ...]
deepValues()
Recursively iterate over all values.
for (const value of doc.deepValues()) {
if (typeof value === 'string') {
console.log(value);
}
}
Tree Walking
walk()
Walk the tree with a callback function.
doc.walk((path, value, depth) => {
console.log(`[Depth ${depth}] ${path}: ${value}`);
});
Callback Signature:
type WalkCallback = (
path: string,
value: any,
depth: number
) => void | boolean;
Return false to stop traversal early.
Options:
interface WalkOptions {
maxDepth?: number; // Default: 100
filter?: (value: any) => boolean;
strategy?: 'depth-first' | 'breadth-first';
order?: 'pre-order' | 'post-order';
includeRoot?: boolean;
}
Examples:
// Depth-first (default)
doc.walk((path, value) => {
console.log(path);
}, { strategy: 'depth-first' });
// Breadth-first
doc.walk((path, value) => {
console.log(path);
}, { strategy: 'breadth-first' });
// With filter
doc.walk((path, value) => {
console.log(path, value);
}, {
filter: (v) => typeof v === 'number'
});
// Early termination
doc.walk((path, value) => {
if (value === 'STOP') {
return false; // Stop walking
}
});
// Post-order traversal
doc.walk((path, value, depth) => {
console.log(`Visited ${path} after children`);
}, { order: 'post-order' });
Search Utilities
find()
Find the first value matching a predicate.
const user = doc.find((value, path) => {
return value.email === 'alice@example.com';
});
findAll()
Find all values matching a predicate.
const numbers = doc.findAll((value) => {
return typeof value === 'number';
});
some()
Check if any value matches a predicate.
const hasAdmins = doc.some((value) => {
return value.role === 'admin';
});
every()
Check if all values match a predicate.
const allActive = doc.every((value, path) => {
return path.includes('active') ? value === true : true;
});
countNodes()
Count total nodes in the document.
const nodeCount = doc.countNodes(); // e.g., 156
Advanced Examples
Find all email addresses
const emails = doc.findAll((value) => {
return typeof value === 'string' && value.includes('@');
});
Collect all IDs recursively
const ids: number[] = [];
doc.walk((path, value) => {
if (path.endsWith('.id') && typeof value === 'number') {
ids.push(value);
}
});
Build a path map
const pathMap = new Map();
for (const [path, value] of doc.deepEntries()) {
pathMap.set(path, value);
}
Count nodes by type
const typeCounts = { strings: 0, numbers: 0, booleans: 0 };
doc.walk((_, value) => {
const type = typeof value;
if (type === 'string') typeCounts.strings++;
if (type === 'number') typeCounts.numbers++;
if (type === 'boolean') typeCounts.booleans++;
});
Performance
- Iterators: Lazy evaluation, memory efficient
- Deep iteration: O(n) where n = total nodes
- Walk: O(n) with early termination support
- Search utilities: O(n), stops on first match for find()