├── .eslintrc.js
├── .gitignore
├── .npmignore
├── .nvmrc
├── .prettierignore
├── .prettierrc.js
├── .travis.yml
├── .vscode
└── settings.json
├── LICENSE
├── assets
├── plain-tree.png
└── plain-tree.svg
├── jest.config.js
├── package-lock.json
├── package.json
├── readme.md
├── src
├── Node.ts
├── Tree.ts
├── create.ts
├── index.ts
├── types.ts
├── utils.ts
└── utilsNodeTree.ts
├── tests
├── Node.test.ts
├── Tree.test.ts
├── create.test.ts
├── data.ts
└── utils.test.ts
└── tsconfig.json
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | env: {
3 | browser: true,
4 | es6: true,
5 | node: true
6 | },
7 | parser: '@typescript-eslint/parser',
8 | extends: [
9 | 'plugin:@typescript-eslint/recommended',
10 | 'prettier/@typescript-eslint', // Uses eslint-config-prettier to disable ESLint rules from @typescript-eslint/eslint-plugin that would conflict with prettier
11 | 'plugin:prettier/recommended' // Enables eslint-plugin-prettier and eslint-config-prettier. This will display prettier errors as ESLint errors. Make sure this is always the last configuration in the extends array.
12 | ],
13 | globals: {
14 | Atomics: 'readonly',
15 | SharedArrayBuffer: 'readonly'
16 | },
17 | parserOptions: {
18 | ecmaVersion: 2018,
19 | sourceType: 'module'
20 | },
21 | rules: {
22 | '@typescript-eslint/no-explicit-any': 0
23 | }
24 | };
25 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | build/
3 | .rts2*
4 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .rts2*
3 | tests
4 |
--------------------------------------------------------------------------------
/.nvmrc:
--------------------------------------------------------------------------------
1 | 10
2 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | build/
2 | node_modules
3 |
--------------------------------------------------------------------------------
/.prettierrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | semi: true,
3 | trailingComma: 'none',
4 | singleQuote: true,
5 | printWidth: 80,
6 | tabWidth: 2
7 | };
8 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | cache:
3 | directories:
4 | - ~/.npm
5 | - node_modules
6 | notifications:
7 | email: false
8 | node_js:
9 | - '12'
10 | - '10'
11 | - '8'
12 | install: npm install
13 | matrix:
14 | fast_finish: true
15 | jobs:
16 | include:
17 | - stage: test
18 | script:
19 | - npm run lint
20 | - npm run test
21 | - stage: release
22 | node_js: '10'
23 | before_script:
24 | - npm run build
25 | on:
26 | branch: release
27 | script: npx semantic-release@15
28 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "eslint.autoFixOnSave": true,
3 | "eslint.validate": [
4 | "javascript",
5 | "javascriptreact",
6 | { "language": "typescript", "autoFix": true },
7 | { "language": "typescriptreact", "autoFix": true }
8 | ]
9 | }
10 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 | Copyright (c) 2018 Luke Scott
3 |
4 | Permission is hereby granted, free of charge, to any person obtaining a copy
5 | of this software and associated documentation files (the "Software"), to deal
6 | in the Software without restriction, including without limitation the rights
7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | copies of the Software, and to permit persons to whom the Software is
9 | furnished to do so, subject to the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be included in all
12 | copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 | SOFTWARE.
21 |
--------------------------------------------------------------------------------
/assets/plain-tree.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lukeaus/plain-tree/6c9254653e0fbce94b9f976b5ef6f868067e0024/assets/plain-tree.png
--------------------------------------------------------------------------------
/assets/plain-tree.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | roots: ['/src', '/tests'],
3 | transform: {
4 | '^.+\\.tsx?$': 'ts-jest'
5 | }
6 | };
7 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@lukeaus/plain-tree",
3 | "description": "A plain tree with a bunch of tree tools",
4 | "version": "0.0.0",
5 | "source": "src/index.ts",
6 | "main": "build/index.js",
7 | "module": "build/index.mjs",
8 | "unpkg": "build/index.umd.js",
9 | "publishConfig": {
10 | "access": "public"
11 | },
12 | "files": [
13 | "build",
14 | "README.md"
15 | ],
16 | "scripts": {
17 | "test": "jest",
18 | "test:watch": "jest --watchAll",
19 | "dev": "microbundle watch",
20 | "lint": "tsc --noEmit && eslint '*/**/*.{js,ts,tsx}' --quiet --fix",
21 | "commit": "git-cz",
22 | "prebuild": "rimraf build & rimraf .rts2_*",
23 | "build": "microbundle"
24 | },
25 | "repository": {
26 | "type": "git",
27 | "url": "git+https://github.com/lukeaus/plain-tree.git"
28 | },
29 | "keywords": [
30 | "tree",
31 | "trees",
32 | "simple",
33 | "javascript",
34 | "hierarchy",
35 | "hierarchies",
36 | "tool",
37 | "tools",
38 | "util",
39 | "utils",
40 | "utility",
41 | "utilities",
42 | "node",
43 | "nodes",
44 | "create",
45 | "array"
46 | ],
47 | "author": {
48 | "name": "Luke Scott",
49 | "email": "luke.m.scott@gmail.com",
50 | "url": "https://lukescott.co"
51 | },
52 | "license": "MIT",
53 | "bugs": {
54 | "url": "https://github.com/lukeaus/plain-tree/issues"
55 | },
56 | "homepage": "https://github.com/lukeaus/plain-tree#readme",
57 | "husky": {
58 | "hooks": {
59 | "pre-commit": "pretty-quick --staged"
60 | }
61 | },
62 | "config": {
63 | "commitizen": {
64 | "path": "node_modules/cz-conventional-changelog"
65 | }
66 | },
67 | "devDependencies": {
68 | "@types/jest": "24.0.17",
69 | "@typescript-eslint/eslint-plugin": "2.0.0",
70 | "@typescript-eslint/parser": "2.0.0",
71 | "commitizen": "4.0.3",
72 | "cz-conventional-changelog": "3.0.2",
73 | "eslint": "6.2.0",
74 | "eslint-config-prettier": "6.1.0",
75 | "eslint-plugin-prettier": "3.1.0",
76 | "husky": "3.0.4",
77 | "jest": "24.9.0",
78 | "microbundle": "0.11.0",
79 | "prettier": "1.18.2",
80 | "pretty-quick": "1.11.1",
81 | "rimraf": "3.0.0",
82 | "ts-jest": "24.0.2",
83 | "typescript": "3.5.3"
84 | },
85 | "dependencies": {}
86 | }
87 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # Plain Tree
4 |
5 |
6 |
7 | ---
8 |
9 | [](https://travis-ci.org/lukeaus/plain-tree)
10 | [](https://github.com/lukeaus/plain-tree/blob/master/LICENSE)
11 | [](https://www.npmjs.com/@lukeaus/plain-tree)
12 | [](http://npm-stat.com/charts.html?package=@lukeaus/plain-tree&from=2019-08-20)
13 | [](https://github.com/semantic-release/semantic-release)
14 | [](https://github.com/lukeaus/plain-tree/issues)
15 | [](https://twitter.com/captbaritone/status/999996177411133440)
16 |
17 | ## What
18 |
19 | Performant tree and node utility library.
20 |
21 | ## Features
22 |
23 | - Create trees
24 | - manually
25 | - from array
26 | - Create nodes
27 | - manually
28 | - from array
29 | - from object
30 | - Search
31 | - Find one
32 | - Find all
33 | - Some/Every
34 | - Traverse (breath first and depth first)
35 | - Nodes at height
36 | - Nodes count
37 | - all
38 | - by height
39 | - Width
40 | - Height
41 | - Depth
42 | - Manipulate trees and nodes
43 | - FlatMap
44 | - Into single array
45 | - Into array of arrays by height
46 | - Convert to JSON
47 | - ... and more (see below)
48 |
49 | ## Why
50 |
51 | Tree and node tools all in one handy, well tested package.
52 |
53 | ## Install
54 |
55 | ```
56 | npm i --save @lukeaus/plain-tree
57 | ```
58 |
59 | ## Usage
60 |
61 | ```javascript
62 | import { Node, Tree } from '@lukeaus/plain-tree';
63 |
64 | const rootNode = new Node('a');
65 | const tree = new Tree(rootNode);
66 | rootNode.addChild('b');
67 |
68 | console.log(tree);
69 | /*
70 | Tree {
71 | root:
72 | Node {
73 | children: [ [Node] ],
74 | id: 'twsychkc3gdj7o30o3s3z6cb7vfpzb2xfgjl',
75 | parent: null,
76 | data: 'a'
77 | }
78 | }
79 | */
80 | ```
81 |
82 | ## API
83 |
84 | ### Creating a Tree
85 |
86 | There are multiple ways to create a tree.
87 |
88 | #### Manually via Declared Nodes
89 |
90 | Assign nodes to variables then use `node.addChild`
91 |
92 | ```javascript
93 | import { Node, Tree } from '@lukeaus/plain-tree';
94 |
95 | const rootNode = new Node('a');
96 | const tree = new Tree(rootNode);
97 | const nodeB = rootNode.addChild('b');
98 | const nodeC = nodeB.addChild('c');
99 |
100 | /* Tree Outline:
101 | * a
102 | * - b
103 | * - c
104 | */
105 | ```
106 |
107 | #### Manually via Children
108 |
109 | Add nodes by accessing the root node's children (and their children, and their children's children etc.)
110 |
111 | ```javascript
112 | import { Node, Tree } from '@lukeaus/plain-tree';
113 |
114 | const rootNode = new Node('a');
115 | const tree = new Tree(rootNode);
116 | rootNode.addChild('b');
117 | rootNode.children[0].addChild('c');
118 |
119 | /* Tree Outline:
120 | * a
121 | * - b
122 | * - c
123 | */
124 | ```
125 |
126 | #### Create a Tree From a Flat Array of Objects
127 |
128 | **`createTreeFromFlatArray(arr, ?opts)`**
129 |
130 | Return: Tree instance
131 |
132 | ##### arr
133 |
134 | Type: Array