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.
Files changed (3) hide show
  1. package/README.md +25 -24
  2. package/index.d.ts +21 -21
  3. package/package.json +4 -4
package/README.md CHANGED
@@ -1,35 +1,36 @@
1
1
  # fast-tree-builder
2
2
 
3
+ [![NPM version](https://img.shields.io/npm/v/fast-tree-builder.svg)](https://npmjs.org/package/fast-tree-builder)
4
+ [![NPM downloads](https://img.shields.io/npm/dm/fast-tree-builder.svg)](https://npmjs.org/package/fast-tree-builder)
3
5
  [![Build Status](https://github.com/lionel87/fast-tree-builder/actions/workflows/build.yaml/badge.svg)](https://github.com/lionel87/fast-tree-builder/actions/workflows/build.yaml)
4
6
  [![Coverage Status](https://coveralls.io/repos/github/lionel87/fast-tree-builder/badge.svg?branch=master)](https://coveralls.io/github/lionel87/fast-tree-builder?branch=master)
5
- ![npms.io (quality)](https://img.shields.io/npms-io/quality-score/fast-tree-builder?label=quality)
6
- ![Maintenance](https://img.shields.io/maintenance/yes/2024)
7
+ ![Maintenance](https://img.shields.io/maintenance/yes/2025)
7
8
 
8
- `fast-tree-builder` is an npm package that allows you to efficiently build trees from iterable data structures. With its optimized algorithm, strong TypeScript typings, and customizable node structure, it provides a reliable solution for organizing and manipulating hierarchical data.
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
- - where each item is identifiable by a unique value,
14
- - and the items are connected via a *parent* OR a *childred* relation.
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**: The package utilizes an optimized algorithm to construct trees efficiently in `O(n)` time, while maintaining good performance.
19
+ - **Efficient Tree Building**: Using an optimized algorithm to construct trees in `O(n)` time.
19
20
 
20
- - **Bi-Directional Tree Traversal**: Traverse the built tree in both directions, enabling easy navigation between parent and child nodes.
21
+ - **Bi-Directional Tree Traversal**: Pointers for parent and children both created for the nodes.
21
22
 
22
- - **Robust TypeScript Type Definitions**: Leverage type safety through extensive TypeScript type definitions. The package includes precise type annotations to improve code reliability and developer workflow.
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**: Tailor the structure of the nodes in the built tree 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
+ - **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 Any Iterable Data**: Designed to handle arrays, sets, and other iterable data structures efficiently, ensuring broad applicability.
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 and Parent Key Types**: You can use any JavaScript value for identifying items. Relations checked with strict (`childKey === parentKey`) comparison.
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 efficiently construct trees with multiple root nodes, accommodating scenarios that necessitate distinct, separate tree structures within the same dataset.
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 to build the tree from.
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 an item defines its children in a list, and connects that way; `parent` means an item defines its parent, and connects to it that way. Defaults to `parent`.
247
- - `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'`.
248
- - `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'`.
249
- - `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'`.
250
- - `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'`.
251
- - `nodeChildrenKey`: (Optional) The key used to store the children nodes in each node. It can be a `string`, `number`, `symbol`. Defaults to `'children'`.
252
- - `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`.
253
- - `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`.
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 packages.
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 implementing a tailored, optimized algorithm. It could be as simple as:
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<T, D extends string | number | symbol | false, P extends string | number | symbol | false, C extends string | number | symbol> = (D extends false ? (P extends false ? T & {
2
- [k in C]?: TreeNode<T, D, P, C>[];
3
- } : T & {
4
- [k in Exclude<P, false>]?: TreeNode<T, D, P, C>;
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 C]?: TreeNode<T, D, P, C>[];
7
- }) : (P extends false ? {
8
- [k in Exclude<D, false>]: T;
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 C]?: TreeNode<T, D, P, C>[];
10
+ [k in TChildrenKey]?: TreeNode<TInputData, TDataKey, TParentKey, TChildrenKey>[];
11
11
  } : {
12
- [k in Exclude<D, false>]: T;
12
+ [k in Exclude<TDataKey, false>]: TInputData;
13
13
  } & {
14
- [k in Exclude<P, false>]?: TreeNode<T, D, P, C>;
14
+ [k in Exclude<TParentKey, false>]?: TreeNode<TInputData, TDataKey, TParentKey, TChildrenKey>;
15
15
  } & {
16
- [k in C]?: TreeNode<T, D, P, C>[];
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<T extends (D extends false ? object : unknown), K extends keyof T | ((item: T) => any), M extends (D extends false ? object : unknown) = T, D extends string | number | symbol | false = 'data', P extends string | number | symbol | false = 'parent', C extends string | number | symbol = 'children'>(items: Iterable<T>, options?: {
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?: K;
22
- parentKey?: keyof T | ((item: T) => KeyReturnType<T, K>);
23
- childrenKey?: keyof T | ((item: T) => KeyReturnType<T, K>);
24
- nodeDataKey?: D;
25
- nodeParentKey?: P;
26
- nodeChildrenKey?: C;
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: T): M;
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<M extends undefined ? T : M, D, P, C>[];
35
- nodes: Map<KeyReturnType<T, K>, TreeNode<M extends undefined ? T : M, D, P, C>>;
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-alpha.2",
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": "^9.1.0",
27
- "chokidar": "^3.5.3",
28
- "mocha": "^10.2.0",
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",