Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

tree-visit

Package Overview
Dependencies
Maintainers
1
Versions
20
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

tree-visit - npm Package Compare versions

Comparing version 0.3.0 to 0.4.0

lib/defineTree.d.ts

27

lib/__tests__/index.js

@@ -15,2 +15,3 @@ "use strict";

const access_1 = require("../access");
const defineTree_1 = require("../defineTree");
const diagram_1 = require("../diagram");

@@ -23,3 +24,2 @@ const find_1 = require("../find");

const reduce_1 = require("../reduce");
const withOptions_1 = require("../withOptions");
function getChildren(node) {

@@ -464,5 +464,3 @@ var _a;

var _a;
const _b = (0, withOptions_1.withOptions)({
getChildren,
}), { find, access, visit, reduce, flatMap, map } = _b, Tree = __rest(_b, ["find", "access", "visit", "reduce", "flatMap", "map"]);
const _b = (0, defineTree_1.defineTree)(getChildren), { find, access, visit, reduce, flatMap, map } = _b, Tree = __rest(_b, ["find", "access", "visit", "reduce", "flatMap", "map"]);
expect(Tree.getChildren(example, []).map((node) => node.name)).toEqual([

@@ -504,3 +502,3 @@ 'b',

var _a, _b;
const { find, findAll } = (0, withOptions_1.withOptions)({ getChildren: getTypedChildren });
const { find, findAll } = (0, defineTree_1.defineTree)(getTypedChildren);
expect(((_a = find(typedExample, {

@@ -515,5 +513,3 @@ predicate: (node) => node.type === 'a',

var _a;
const { find, findAllIndexPaths, visit, diagram, flat } = (0, withOptions_1.withOptions)({
getChildren,
});
const { find, findAllIndexPaths, visit, diagram, flat } = (0, defineTree_1.defineTree)(getChildren);
let enterNames = [];

@@ -540,2 +536,17 @@ visit(example, (child) => {

});
it('type checks', () => {
const Tree = (0, defineTree_1.defineTree)(getChildren);
const TreeWithOptions = Tree.withOptions({ getLabel: (node) => node.name });
expect(() => {
// @ts-expect-error
Tree.diagram(example);
}).toThrowError();
expect(() => {
// @ts-expect-error
Tree.diagram(example, {});
}).toThrowError();
TreeWithOptions.diagram(example);
TreeWithOptions.diagram(example, {});
TreeWithOptions.diagram(example, (node) => node.name);
});
});
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const node_1 = require("../__mocks__/node");
const defineTree_1 = require("../defineTree");
const diagram_1 = require("../diagram");

@@ -9,3 +10,2 @@ const insert_1 = require("../insert");

const replace_1 = require("../replace");
const withOptions_1 = require("../withOptions");
describe('insert', () => {

@@ -241,5 +241,24 @@ it('inserts node at start', () => {

});
describe('tree with no options', () => {
const Tree = (0, defineTree_1.defineTree)(node_1.getChildren);
it('inserts node', () => {
const result = Tree.insert(node_1.example, {
at: [1],
nodes: [{ name: 'x', indexPath: [] }],
create: node_1.createNode,
});
expect((0, diagram_1.diagram)(result, { getChildren: node_1.getChildren, getLabel: node_1.getLabel })).toMatchSnapshot();
});
it('type checks', () => {
expect(() => {
// @ts-expect-error
Tree.insert(node_1.example, {
at: [1],
nodes: [{ name: 'x', indexPath: [] }],
});
}).toThrowError();
});
});
describe('partially applied', () => {
const Tree = (0, withOptions_1.withOptions)({
getChildren: node_1.getChildren,
const Tree = (0, defineTree_1.defineTree)(node_1.getChildren).withOptions({
create: node_1.createNode,

@@ -246,0 +265,0 @@ });

export * from './access';
export * from './ancestors';
export * from './defineTree';
export * from './diagram';

@@ -4,0 +5,0 @@ export * from './find';

@@ -15,2 +15,3 @@ "use strict";

__exportStar(require("./ancestors"), exports);
__exportStar(require("./defineTree"), exports);
__exportStar(require("./diagram"), exports);

@@ -17,0 +18,0 @@ __exportStar(require("./find"), exports);

@@ -1,115 +0,7 @@

import { DiagramOptions } from './diagram';
import { FindOptions, FindOptionsTyped } from './find';
import { FlatMapOptions } from './flatMap';
import { IndexPath } from './indexPath';
import { InsertOptions } from './insert';
import { MapOptions } from './map';
import { MoveOptions } from './move';
import { BaseOptions, MutationBaseOptions } from './options';
import { ReduceOptions } from './reduce';
import { RemoveOptions } from './remove';
import { ReplaceOptions } from './replace';
import { VisitOptions } from './visit';
declare type WithoutBase<O> = Omit<O, keyof BaseOptions<unknown>>;
export declare type WithOptions<T> = {
/**
* Returns the node's children.
*
* This is the same as the `getChildren` option passed to `withOptions`, included here for convenience.
*/
getChildren: BaseOptions<T>['getChildren'];
/**
* Returns a node by its `IndexPath`.
*
* The first node is implicitly included in the `IndexPath` (i.e. no need to pass a `0` first in every `IndexPath`).
*/
access(node: T, indexPath: IndexPath): T;
/**
* Returns an array of each node in an `IndexPath`.
*
* The first node is implicitly included in the `IndexPath` (i.e. no need to pass a `0` first in every `IndexPath`).
*/
accessPath(node: T, indexPath: IndexPath): T[];
/**
* Generate a diagram of the tree, as a string.
*/
diagram(node: T, getLabel: DiagramOptions<T>['getLabel']): string;
diagram(node: T, options: WithoutBase<DiagramOptions<T>>): string;
/**
* Find a node matching a predicate function.
*/
find(node: T, predicate: FindOptions<T>['predicate']): T | undefined;
find(node: T, options: WithoutBase<FindOptions<T>>): T | undefined;
find<S extends T>(node: T, predicate: FindOptionsTyped<T, S>['predicate']): S | undefined;
find<S extends T>(node: T, options: WithoutBase<FindOptionsTyped<T, S>>): S | undefined;
/**
* Find all nodes matching a predicate function.
*/
findAll(node: T, predicate: FindOptions<T>['predicate']): T[];
findAll(node: T, options: WithoutBase<FindOptions<T>>): T[];
findAll<S extends T>(node: T, predicate: FindOptionsTyped<T, S>['predicate']): S[];
findAll<S extends T>(node: T, options: WithoutBase<FindOptionsTyped<T, S>>): S[];
/**
* Find the `IndexPath` of a node matching a predicate function.
*/
findIndexPath(node: T, predicate: FindOptions<T>['predicate']): IndexPath | undefined;
findIndexPath(node: T, options: WithoutBase<FindOptions<T>>): IndexPath | undefined;
/**
* Find the `IndexPath` of all nodes matching a predicate function.
*/
findAllIndexPaths(node: T, predicate: FindOptions<T>['predicate']): IndexPath[];
findAllIndexPaths(node: T, options: WithoutBase<FindOptions<T>>): IndexPath[];
/**
* Returns an array containing the root node and all of its descendants.
*
* This is analogous to `Array.prototype.flat` for flattening arrays.
*/
flat(node: T): T[];
/**
* Map each node into an array of values, which are then flattened into a single array.
*
* This is analogous to `Array.prototype.flatMap` for arrays.
*/
flatMap<R>(node: T, transform: FlatMapOptions<T, R>['transform']): R[];
reduce<R>(node: T, nextResult: ReduceOptions<T, R>['nextResult'], initialResult: R): R;
map<R>(node: T, transform: MapOptions<T, R>['transform']): R;
/**
* Visit each node using preorder DFS traversal.
*/
visit(node: T, onEnter: NonNullable<VisitOptions<T>>['onEnter']): void;
/**
* Visit each node using DFS traversal.
*/
visit(node: T, options: WithoutBase<VisitOptions<T>>): void;
/**
* Insert nodes at a given `IndexPath`.
*/
insert(node: T, options: WithoutBase<InsertOptions<T>>): T;
/**
* Remove nodes at the given `IndexPath`s.
*/
remove(node: T, options: WithoutBase<RemoveOptions<T>>): T;
/**
* Move nodes from one `IndexPath` to another.
*/
move(node: T, options: WithoutBase<MoveOptions<T>>): T;
/**
* Replace the node at the given `IndexPath` with another
*/
replace(node: T, options: WithoutBase<ReplaceOptions<T>>): T;
};
declare type WithoutMutationBase<O> = Omit<O, keyof MutationBaseOptions<unknown>>;
export declare type WithMutationOptions<T> = Omit<WithOptions<T>, 'insert' | 'remove' | 'move' | 'replace'> & {
insert: (node: T, options: WithoutMutationBase<InsertOptions<T>>) => T;
remove: (node: T, options: WithoutMutationBase<RemoveOptions<T>>) => T;
move: (node: T, options: WithoutMutationBase<MoveOptions<T>>) => T;
replace: (node: T, options: WithoutMutationBase<ReplaceOptions<T>>) => T;
};
import { defineTree } from './defineTree';
/**
* Return every tree utility function with options partially applied.
*
* @param baseOptions
* @deprecated Use `defineTree` instead
*/
export declare function withOptions<T>(baseOptions: BaseOptions<T>): WithOptions<T>;
export declare function withOptions<T>(baseOptions: MutationBaseOptions<T>): WithMutationOptions<T>;
export {};
export declare const withOptions: typeof defineTree;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.withOptions = void 0;
const access_1 = require("./access");
const diagram_1 = require("./diagram");
const find_1 = require("./find");
const flat_1 = require("./flat");
const flatMap_1 = require("./flatMap");
const insert_1 = require("./insert");
const map_1 = require("./map");
const move_1 = require("./move");
const reduce_1 = require("./reduce");
const remove_1 = require("./remove");
const replace_1 = require("./replace");
const visit_1 = require("./visit");
function withOptionsBase(baseOptions) {
return {
getChildren: baseOptions.getChildren,
access: (node, indexPath) => (0, access_1.access)(node, indexPath, baseOptions),
accessPath: (node, indexPath) => (0, access_1.accessPath)(node, indexPath, baseOptions),
diagram: (node, getLabelOrOptions) => typeof getLabelOrOptions === 'function'
? (0, diagram_1.diagram)(node, Object.assign(Object.assign({}, baseOptions), { getLabel: getLabelOrOptions }))
: (0, diagram_1.diagram)(node, Object.assign(Object.assign({}, baseOptions), getLabelOrOptions)),
find: (node, predicateOrOptions) => typeof predicateOrOptions === 'function'
? (0, find_1.find)(node, Object.assign(Object.assign({}, baseOptions), { predicate: predicateOrOptions }))
: (0, find_1.find)(node, Object.assign(Object.assign({}, baseOptions), predicateOrOptions)),
findAll: (node, predicateOrOptions) => typeof predicateOrOptions === 'function'
? (0, find_1.findAll)(node, Object.assign(Object.assign({}, baseOptions), { predicate: predicateOrOptions }))
: (0, find_1.findAll)(node, Object.assign(Object.assign({}, baseOptions), predicateOrOptions)),
findIndexPath: (node, predicateOrOptions) => typeof predicateOrOptions === 'function'
? (0, find_1.findIndexPath)(node, Object.assign(Object.assign({}, baseOptions), { predicate: predicateOrOptions }))
: (0, find_1.findIndexPath)(node, Object.assign(Object.assign({}, baseOptions), predicateOrOptions)),
flat: (node) => (0, flat_1.flat)(node, baseOptions),
flatMap: (node, transform) => (0, flatMap_1.flatMap)(node, Object.assign(Object.assign({}, baseOptions), { transform })),
reduce: (node, nextResult, initialResult) => (0, reduce_1.reduce)(node, Object.assign(Object.assign({}, baseOptions), { nextResult, initialResult })),
map: (node, transform) => (0, map_1.map)(node, Object.assign(Object.assign({}, baseOptions), { transform })),
findAllIndexPaths: (node, predicateOrOptions) => typeof predicateOrOptions === 'function'
? (0, find_1.findAllIndexPaths)(node, Object.assign(Object.assign({}, baseOptions), { predicate: predicateOrOptions }))
: (0, find_1.findAllIndexPaths)(node, Object.assign(Object.assign({}, baseOptions), predicateOrOptions)),
visit: (node, onEnterOrOptions) => typeof onEnterOrOptions === 'function'
? (0, visit_1.visit)(node, Object.assign(Object.assign({}, baseOptions), { onEnter: onEnterOrOptions }))
: (0, visit_1.visit)(node, Object.assign(Object.assign({}, baseOptions), onEnterOrOptions)),
insert: (node, options) => (0, insert_1.insert)(node, Object.assign(Object.assign({}, baseOptions), options)),
remove: (node, options) => (0, remove_1.remove)(node, Object.assign(Object.assign({}, baseOptions), options)),
move: (node, options) => (0, move_1.move)(node, Object.assign(Object.assign({}, baseOptions), options)),
replace: (node, options) => (0, replace_1.replace)(node, Object.assign(Object.assign({}, baseOptions), options)),
};
}
function withMutationOptions(baseOptions) {
const tree = withOptionsBase(baseOptions);
return Object.assign(Object.assign({}, tree), { insert: (node, options) => (0, insert_1.insert)(node, Object.assign(Object.assign({}, baseOptions), options)), remove: (node, options) => (0, remove_1.remove)(node, Object.assign(Object.assign({}, baseOptions), options)), move: (node, options) => (0, move_1.move)(node, Object.assign(Object.assign({}, baseOptions), options)), replace: (node, options) => (0, replace_1.replace)(node, Object.assign(Object.assign({}, baseOptions), options)) });
}
function withOptions(baseOptions) {
if ('create' in baseOptions) {
return withMutationOptions(baseOptions);
}
return withOptionsBase(baseOptions);
}
exports.withOptions = withOptions;
const defineTree_1 = require("./defineTree");
/**
* Return every tree utility function with options partially applied.
*
* @deprecated Use `defineTree` instead
*/
exports.withOptions = defineTree_1.defineTree;
{
"name": "tree-visit",
"version": "0.3.0",
"version": "0.4.0",
"description": "A tree traversal library.",

@@ -5,0 +5,0 @@ "main": "lib/index.js",

@@ -17,8 +17,11 @@ # tree-visit

All functions take an `options` parameter that must contain _at least_ a `getChildren` function which specifies how to find a node's children. The `withOptions` API returns a version of every function with the `getChildren` option already set. Using `withOptions` instead of the bare functions is recommended for convenience.
The recommended way to use `tree-visit` is by calling `defineTree(getChildren)`, where `getChildren` is a function which returns a node's children as an array. The `defineTree` API returns an object containing every library function with the `getChildren` option already set.
Most functions, such as `getChildren`, `predicate`, `onEnter`, and `onLeave`, are passed an `IndexPath` as the second argument, containing an array of integer indexes that identify that node. The root node is implicitly included in the `IndexPath` (i.e. there's no `0` first in every `IndexPath`).
You may alternately import individual functions, e.g. `visit`, and pass the `{ getChildren }` option when calling them. Importing individual functions can reduce your bundle size to the bear minimum (though the entire library is small and has 0 dependencies, so this may not be necessary).
Most callback functions, such as `getChildren`, `predicate`, `onEnter`, and `onLeave`, are passed an `IndexPath` as the second argument, containing an array of integer indexes that identify that node. The root node is implicitly included in the `IndexPath` (i.e. there's no `0` first in every `IndexPath`).
- [access](#access)
- [accessPath](#accessPath)
- [defineTree](#defineTree)
- [diagram](#diagram)

@@ -30,3 +33,2 @@ - [find](#find)

- [visit](#visit)
- [withOptions](#withOptions)

@@ -95,2 +97,41 @@ ---

### `defineTree`
Returns a version of every library function with the `getChildren` option already set.
This also allows for more concise calls to most functions.
**Type**: `function defineTree<T>(baseOptions: BaseOptions<T>): Tree<T>`
#### Example
```js
import { defineTree } from 'tree-visit'
const getChildren = (node) => node.children || []
const { visit, find } = defineTree({ getChildren })
const rootNode = {
name: 'a',
children: [
{ name: 'b' },
{
name: 'c',
children: [{ name: 'd' }],
},
],
}
visit(rootNode, (node) => {
console.log(node)
})
// #=> a, b, c, d
find(rootNode, (node) => node.name === 'd')
// #=> { name: 'd' }
```
---
### `diagram`

@@ -327,40 +368,1 @@

```
---
### `withOptions`
Returns a version of every function with the `getChildren` option already set.
This allows for more concise calls to most functions.
**Type**: `function withOptions<T>(baseOptions: BaseOptions<T>): WithOptions<T>`
#### Example
```js
import { withOptions } from 'tree-visit'
const getChildren = (node) => node.children || []
const { visit, find } = withOptions({ getChildren })
const rootNode = {
name: 'a',
children: [
{ name: 'b' },
{
name: 'c',
children: [{ name: 'd' }],
},
],
}
visit(rootNode, (node) => {
console.log(node)
})
// #=> a, b, c, d
find(rootNode, (node) => node.name === 'd')
// #=> { name: 'd' }
```
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc