fast-tree-builder 1.0.0-alpha.2 → 1.0.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -24
- package/index.d.ts +21 -21
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -1,35 +1,36 @@
|
|
|
1
1
|
# fast-tree-builder
|
|
2
2
|
|
|
3
|
+
[](https://npmjs.org/package/fast-tree-builder)
|
|
4
|
+
[](https://npmjs.org/package/fast-tree-builder)
|
|
3
5
|
[](https://github.com/lionel87/fast-tree-builder/actions/workflows/build.yaml)
|
|
4
6
|
[](https://coveralls.io/github/lionel87/fast-tree-builder?branch=master)
|
|
5
|
-

|
|
7
|
+

|
|
7
8
|
|
|
8
|
-
`fast-tree-builder` is an npm package that allows you to
|
|
9
|
+
`fast-tree-builder` is an npm package that allows you to build trees quickly from iterable data structures. With its optimized algorithm, strong TypeScript typings, and customizable node structure it provides a convenient solution for working with hierarchical data.
|
|
9
10
|
|
|
10
11
|
## Prerequisites
|
|
11
12
|
|
|
12
13
|
- You have a list of items,
|
|
13
|
-
-
|
|
14
|
-
-
|
|
14
|
+
- each item is identifiable by a unique id,
|
|
15
|
+
- the items are connected via a *parent id* OR *children ids*.
|
|
15
16
|
|
|
16
17
|
## Features
|
|
17
18
|
|
|
18
|
-
- **Efficient Tree Building**:
|
|
19
|
+
- **Efficient Tree Building**: Using an optimized algorithm to construct trees in `O(n)` time.
|
|
19
20
|
|
|
20
|
-
- **Bi-Directional Tree Traversal**:
|
|
21
|
+
- **Bi-Directional Tree Traversal**: Pointers for parent and children both created for the nodes.
|
|
21
22
|
|
|
22
|
-
- **Robust TypeScript Type Definitions**:
|
|
23
|
+
- **Robust TypeScript Type Definitions**: Type safety through extensive TypeScript type definitions which helps code reliability and developer workflow.
|
|
23
24
|
|
|
24
|
-
- **Fully Customizable Node Structure**:
|
|
25
|
+
- **Fully Customizable Node Structure**: The structure of the nodes in the built tree is customizable to meet your specific requirements. You have the freedom to define `data`, `parent`, and `children` key names according to your application's needs. To avoid circular references, parent links can be turned off which helps generating JSON data.
|
|
25
26
|
|
|
26
|
-
- **Works on
|
|
27
|
+
- **Works on Iterables**: Designed to handle arrays, sets, and other iterable data structures out of the box ensuring broad applicability.
|
|
27
28
|
|
|
28
|
-
- **No Sorting Required**: The algorithm does not require your input data to be sorted, saving you preprocessing time and effort.
|
|
29
|
+
- **No Sorting Required**: The algorithm does not require your input data to be sorted (eg. parent must come before children), saving you preprocessing time and effort.
|
|
29
30
|
|
|
30
|
-
- **Flexible Key
|
|
31
|
+
- **Flexible Key Types**: You can use any JavaScript value for identifying items. Relations checked with strict (`childKey === parentKey`) comparison.
|
|
31
32
|
|
|
32
|
-
- **Multiple Root Nodes**: Can
|
|
33
|
+
- **Multiple Root Nodes**: Can construct multiple distinct trees. Handy when the intent is to handle the set as one tree, but a 'virtual' root item is not present among the items to couple them together. The 'roots' becomes your virtual root in this case.
|
|
33
34
|
|
|
34
35
|
- **Map of Nodes**: Beside the root nodes you can retrieve a `Map` object containing the nodes of the built tree, enabling easy entry on any point of the tree.
|
|
35
36
|
|
|
@@ -241,16 +242,16 @@ Builds a tree from the given iterable `items` using the specified `options`.
|
|
|
241
242
|
|
|
242
243
|
Parameters
|
|
243
244
|
|
|
244
|
-
- `items`: An iterable data structure containing the items
|
|
245
|
+
- `items`: An iterable data structure containing the items of the tree.
|
|
245
246
|
- `options`: An object specifying the build options. It has the following properties:
|
|
246
|
-
- `mode`: (Optional) Defines the item connection method. `children` means
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
247
|
+
- `mode`: (Optional) Defines the item connection method. `children` means items defines their children in an array, child nodes connects to these; `parent` means items defines their parent, parent nodes connects to these. Defaults to `parent`.
|
|
248
|
+
- `key`: (Optional) The key used to identify items. It can be a string, number, symbol, or a function that extracts the key from an item. Defaults to `'id'`.
|
|
249
|
+
- `parentKey`: (Optional) The key used to identify the parent of each item. It can be a `string`, `number`, `symbol`, or a `function` that extracts the parent key from an item. Defaults to `'parent'`.
|
|
250
|
+
- `nodeDataKey`: (Optional) The key used to store the item's data in each node. It can be a `string`, `number`, `symbol`, or `false` if the data should be merged directly into the node. Defaults to `'data'`.
|
|
251
|
+
- `nodeParentKey`: (Optional) The key used to store the parent node in each node. It can be a `string`, `number`, `symbol`, or `false` if the parent node should not be included. Defaults to `'parent'`.
|
|
252
|
+
- `nodeChildrenKey`: (Optional) The key used to store the children nodes in each node. It can be a `string`, `number`, `symbol`. Defaults to `'children'`.
|
|
253
|
+
- `mapNodeData`: (Optional) A function that maps an item to its corresponding node data. It allows transforming the item before assigning it to the node. Defaults to `undefined`.
|
|
254
|
+
- `validRootKeys`: (Optional) An iterable containing key values that can be accepted as root nodes. If provided, any item with a key not present in this iterable will cause an error to be thrown. Defaults to `undefined`.
|
|
254
255
|
- `validRootParentKeys`: (Optional) Only available when `mode` is set to `parent`. An iterable containing key values that can be accepted the parent field values of root nodes. If provided, any root node with a parent key not present in this iterable will cause an error to be thrown. Defaults to `undefined`.
|
|
255
256
|
- `validateTree`: (Optional) A boolean flag that determines whether to validate the resulting data structure. If the structure is a cyclic graph, an `Error` will be thrown. Requires additional `O(n)` time to compute. Defaults to `false`.
|
|
256
257
|
|
|
@@ -270,9 +271,9 @@ Throws `Error` when:
|
|
|
270
271
|
|
|
271
272
|
## Comparison with other tree building libraries
|
|
272
273
|
|
|
273
|
-
The package aims to be feature complete and highly customizable, which usually opposes with performance. There are other packages that may be more *performant* but lacks features that I really needed in my daily coding. In standard scenarios this package should perform more than enough and nearly as good as other
|
|
274
|
+
The package aims to be feature complete and highly customizable, which usually opposes with performance. There are other packages that may be more *performant* but lacks features that I really needed in my daily coding. In standard scenarios this package should perform more than enough and nearly as good as any other package.
|
|
274
275
|
|
|
275
|
-
For scenarios where performance is critical, consider
|
|
276
|
+
For scenarios where performance is critical and you start to benchmark tree building libraries, consider implementing your custom algorithm instead. It could be as simple as:
|
|
276
277
|
```js
|
|
277
278
|
const roots = [];
|
|
278
279
|
const nodes = new Map();
|
package/index.d.ts
CHANGED
|
@@ -1,37 +1,37 @@
|
|
|
1
|
-
type TreeNode<
|
|
2
|
-
[k in
|
|
3
|
-
} :
|
|
4
|
-
[k in Exclude<
|
|
1
|
+
type TreeNode<TInputData, TDataKey extends string | number | symbol | false, TParentKey extends string | number | symbol | false, TChildrenKey extends string | number | symbol> = (TDataKey extends false ? (TParentKey extends false ? Omit<TInputData, TChildrenKey> & {
|
|
2
|
+
[k in TChildrenKey]?: TreeNode<TInputData, TDataKey, TParentKey, TChildrenKey>[];
|
|
3
|
+
} : Omit<TInputData, Exclude<TParentKey, false> | TChildrenKey> & {
|
|
4
|
+
[k in Exclude<TParentKey, false>]?: TreeNode<TInputData, TDataKey, TParentKey, TChildrenKey>;
|
|
5
5
|
} & {
|
|
6
|
-
[k in
|
|
7
|
-
}) : (
|
|
8
|
-
[k in Exclude<
|
|
6
|
+
[k in TChildrenKey]?: TreeNode<TInputData, TDataKey, TParentKey, TChildrenKey>[];
|
|
7
|
+
}) : (TParentKey extends false ? {
|
|
8
|
+
[k in Exclude<TDataKey, false>]: TInputData;
|
|
9
9
|
} & {
|
|
10
|
-
[k in
|
|
10
|
+
[k in TChildrenKey]?: TreeNode<TInputData, TDataKey, TParentKey, TChildrenKey>[];
|
|
11
11
|
} : {
|
|
12
|
-
[k in Exclude<
|
|
12
|
+
[k in Exclude<TDataKey, false>]: TInputData;
|
|
13
13
|
} & {
|
|
14
|
-
[k in Exclude<
|
|
14
|
+
[k in Exclude<TParentKey, false>]?: TreeNode<TInputData, TDataKey, TParentKey, TChildrenKey>;
|
|
15
15
|
} & {
|
|
16
|
-
[k in
|
|
16
|
+
[k in TChildrenKey]?: TreeNode<TInputData, TDataKey, TParentKey, TChildrenKey>[];
|
|
17
17
|
}));
|
|
18
18
|
type KeyReturnType<T, P extends keyof T | ((item: T) => any)> = P extends ((item: T) => infer R) ? R : P extends keyof T ? T[P] : never;
|
|
19
|
-
declare function buildTree<
|
|
19
|
+
declare function buildTree<TInputData extends (TNodeDataKey extends false ? object : unknown), TKey extends keyof TInputData | ((item: TInputData) => any), TMappedData extends (TNodeDataKey extends false ? object : unknown) = TInputData, TNodeDataKey extends string | number | symbol | false = 'data', TNodeParentKey extends string | number | symbol | false = 'parent', TNodeChildrenKey extends string | number | symbol = 'children'>(items: Iterable<TInputData>, options?: {
|
|
20
20
|
mode?: 'parent' | 'children';
|
|
21
|
-
key?:
|
|
22
|
-
parentKey?: keyof
|
|
23
|
-
childrenKey?: keyof
|
|
24
|
-
nodeDataKey?:
|
|
25
|
-
nodeParentKey?:
|
|
26
|
-
nodeChildrenKey?:
|
|
21
|
+
key?: TKey;
|
|
22
|
+
parentKey?: keyof TInputData | ((item: TInputData) => any);
|
|
23
|
+
childrenKey?: keyof TInputData | ((item: TInputData) => any);
|
|
24
|
+
nodeDataKey?: TNodeDataKey;
|
|
25
|
+
nodeParentKey?: TNodeParentKey;
|
|
26
|
+
nodeChildrenKey?: TNodeChildrenKey;
|
|
27
27
|
mapNodeData?: {
|
|
28
|
-
(item:
|
|
28
|
+
(item: TInputData): TMappedData;
|
|
29
29
|
};
|
|
30
30
|
validRootKeys?: Iterable<unknown>;
|
|
31
31
|
validRootParentKeys?: Iterable<unknown>;
|
|
32
32
|
validateTree?: boolean;
|
|
33
33
|
}): {
|
|
34
|
-
roots: TreeNode<
|
|
35
|
-
nodes: Map<KeyReturnType<
|
|
34
|
+
roots: TreeNode<TMappedData extends undefined ? TInputData : TMappedData, TNodeDataKey, TNodeParentKey, TNodeChildrenKey>[];
|
|
35
|
+
nodes: Map<KeyReturnType<TInputData, TKey>, TreeNode<TMappedData extends undefined ? TInputData : TMappedData, TNodeDataKey, TNodeParentKey, TNodeChildrenKey>>;
|
|
36
36
|
};
|
|
37
37
|
export default buildTree;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fast-tree-builder",
|
|
3
|
-
"version": "1.0.0-
|
|
3
|
+
"version": "1.0.0-beta.0",
|
|
4
4
|
"description": "Efficiently construct highly customizable bi-directional tree structures from iterable data.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "./index.js",
|
|
@@ -23,9 +23,9 @@
|
|
|
23
23
|
"coverage": "c8 -r text -r text-summary -r lcov --include \"*.js\" npm test"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
|
-
"c8": "^
|
|
27
|
-
"chokidar": "^
|
|
28
|
-
"mocha": "^
|
|
26
|
+
"c8": "^10.1.3",
|
|
27
|
+
"chokidar": "^4.0.3",
|
|
28
|
+
"mocha": "^11.1.0",
|
|
29
29
|
"typescript": "^5.3.3"
|
|
30
30
|
},
|
|
31
31
|
"homepage": "https://github.com/lionel87/fast-tree-builder#readme",
|