tree-processor 0.7.0 → 0.8.1
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 +501 -147
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/stats.html +1 -1
- package/dist/tree-processor.cjs.js +84 -72
- package/dist/tree-processor.esm.js +22 -10
- package/dist/tree-processor.umd.js +44 -32
- package/package.json +10 -1
package/README.md
CHANGED
|
@@ -1,30 +1,104 @@
|
|
|
1
1
|
# tree-processor
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
<div align="center">
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+

|
|
7
|
+

|
|
8
|
+

|
|
9
|
+

|
|
10
|
+

|
|
11
|
+
|
|
12
|
+
一个轻量级的树结构数据处理工具库,使用 TypeScript 编写,支持 tree-shaking,每个格式打包体积约 **6-7 KB**(ESM: 6.39 KB,CJS: 6.64 KB,UMD: 6.68 KB)。
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
</div>
|
|
16
|
+
|
|
17
|
+
## 📋 目录
|
|
18
|
+
|
|
19
|
+
- [特性](#-特性)
|
|
20
|
+
- [使用场景](#-使用场景)
|
|
21
|
+
- [安装](#-安装)
|
|
22
|
+
- [快速开始](#-快速开始)
|
|
23
|
+
- [API 文档](#-api-文档)
|
|
24
|
+
- [遍历方法](#遍历方法)
|
|
25
|
+
- [查找方法](#查找方法)
|
|
26
|
+
- [修改方法](#修改方法)
|
|
27
|
+
- [判断方法](#判断方法)
|
|
28
|
+
- [工具方法](#工具方法)
|
|
29
|
+
- [自定义字段名](#自定义字段名)
|
|
30
|
+
- [测试](#测试)
|
|
31
|
+
- [开发](#开发)
|
|
32
|
+
- [技术栈](#技术栈)
|
|
33
|
+
- [贡献](#-贡献)
|
|
34
|
+
- [更新日志](#-更新日志)
|
|
35
|
+
- [许可证](#-许可证)
|
|
36
|
+
- [相关链接](#-相关链接)
|
|
6
37
|
|
|
7
38
|
## ✨ 特性
|
|
8
39
|
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
40
|
+
- **轻量级** - 每个格式打包体积仅 6-7 KB(ESM: 6.39 KB,CJS: 6.64 KB,UMD: 6.68 KB),对项目体积影响极小
|
|
41
|
+
- **支持 Tree-shaking** - 支持按需导入,只打包实际使用的代码,进一步减小打包体积
|
|
42
|
+
- **完整的 TypeScript 支持** - 提供完整的类型定义和智能提示,提升开发体验
|
|
43
|
+
- **灵活的自定义字段名** - 支持自定义 children 和 id 字段名,适配各种数据结构
|
|
44
|
+
- **零依赖** - 无任何外部依赖,开箱即用,无需担心依赖冲突
|
|
45
|
+
- **完善的测试覆盖** - 包含 272 个测试用例,覆盖基础功能、边界情况、异常处理、复杂场景等
|
|
46
|
+
- **丰富的 API** - 提供 30+ 个方法,包含类似数组的 API(map、filter、find、some、every、includes、at、indexOf 等),以及树结构特有的操作(获取父子节点、深度计算、数据验证等),涵盖遍历、查找、修改、判断等完整场景
|
|
47
|
+
|
|
48
|
+
**已支持的方法:** mapTree、forEachTree、filterTree、findTree、pushTree、unshiftTree、popTree、shiftTree、someTree、everyTree、includesTree、atTree、indexOfTree、atIndexOfTree、dedupTree、removeTree、getParentTree、getChildrenTree、getSiblingsTree、getNodeDepthMap、getNodeDepth、isLeafNode、isRootNode、isEmptyTreeData、isEmptySingleTreeData、isTreeData、isSingleTreeData、isValidTreeNode、isTreeNodeWithCircularCheck、isSafeTreeDepth。每个方法的最后一个参数可以自定义 children 和 id 的属性名。
|
|
49
|
+
|
|
50
|
+
### 💡 使用场景
|
|
51
|
+
|
|
52
|
+
- **导航系统** - 多级菜单、路由配置的展开、折叠、搜索、过滤
|
|
53
|
+
- **文件系统** - 文件目录的遍历、查找、移动、删除
|
|
54
|
+
- **权限系统** - 组织架构、角色权限的树形结构管理和验证
|
|
55
|
+
- **框架开发** - 组件树、路由树等树形结构的构建和管理
|
|
56
|
+
- **数据管理** - 分类管理、评论系统、树形选择器等数据操作
|
|
16
57
|
|
|
17
58
|
## 📦 安装
|
|
18
59
|
|
|
19
60
|
```bash
|
|
61
|
+
npm install tree-processor
|
|
62
|
+
# 或
|
|
20
63
|
yarn add tree-processor
|
|
21
64
|
# 或
|
|
22
|
-
|
|
65
|
+
pnpm add tree-processor
|
|
23
66
|
```
|
|
24
67
|
|
|
25
|
-
##
|
|
68
|
+
## 🚀 快速开始
|
|
26
69
|
|
|
27
|
-
|
|
70
|
+
```javascript
|
|
71
|
+
import { mapTree, findTree, filterTree } from 'tree-processor'
|
|
72
|
+
|
|
73
|
+
const treeData = [
|
|
74
|
+
{
|
|
75
|
+
id: 1,
|
|
76
|
+
name: 'node1',
|
|
77
|
+
children: [
|
|
78
|
+
{ id: 2, name: 'node2' },
|
|
79
|
+
{ id: 3, name: 'node3' },
|
|
80
|
+
],
|
|
81
|
+
},
|
|
82
|
+
]
|
|
83
|
+
|
|
84
|
+
// 获取所有节点名称
|
|
85
|
+
const names = mapTree(treeData, (node) => node.name)
|
|
86
|
+
console.log(names) // ['node1', 'node2', 'node3']
|
|
87
|
+
|
|
88
|
+
// 查找节点
|
|
89
|
+
const node = findTree(treeData, (n) => n.id === 2)
|
|
90
|
+
console.log(node) // { id: 2, name: 'node2' }
|
|
91
|
+
|
|
92
|
+
// 过滤节点
|
|
93
|
+
const filtered = filterTree(treeData, (n) => n.id > 1)
|
|
94
|
+
console.log(filtered) // [{ id: 2, name: 'node2' }, { id: 3, name: 'node3' }]
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## 📖 API 文档
|
|
98
|
+
|
|
99
|
+
### 引入方式
|
|
100
|
+
|
|
101
|
+
#### 默认导入(推荐用于需要多个方法的场景)
|
|
28
102
|
|
|
29
103
|
#### 默认导入(推荐用于需要多个方法的场景)
|
|
30
104
|
|
|
@@ -59,7 +133,7 @@ const { mapTree, filterTree } = require('tree-processor')
|
|
|
59
133
|
- 只有在需要显式声明变量类型时才需要引入类型(如 `const treeData: TreeData = [...]`)
|
|
60
134
|
- 使用 `import type` 导入类型不会增加运行时体积(类型在编译时会被移除)
|
|
61
135
|
|
|
62
|
-
###
|
|
136
|
+
### 示例数据
|
|
63
137
|
|
|
64
138
|
以下示例数据将用于后续所有方法的演示:
|
|
65
139
|
|
|
@@ -87,7 +161,11 @@ const treeData = [
|
|
|
87
161
|
];
|
|
88
162
|
```
|
|
89
163
|
|
|
90
|
-
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
## 遍历方法
|
|
167
|
+
|
|
168
|
+
### mapTree
|
|
91
169
|
|
|
92
170
|
遍历树结构数据,对每个节点执行回调函数,返回映射后的数组。
|
|
93
171
|
|
|
@@ -108,7 +186,7 @@ const modifiedNodes = t.mapTree(treeData, (node) => ({
|
|
|
108
186
|
console.log(modifiedNodes) // 返回包含 label 字段的新数组
|
|
109
187
|
```
|
|
110
188
|
|
|
111
|
-
### forEachTree
|
|
189
|
+
### forEachTree
|
|
112
190
|
|
|
113
191
|
遍历树结构数据,对每个节点执行回调函数。与 mapTree 的区别是不返回值,性能更好,适合只需要遍历而不需要返回结果的场景。
|
|
114
192
|
|
|
@@ -132,7 +210,7 @@ t.forEachTree(treeData, () => {
|
|
|
132
210
|
console.log(nodeCount) // 节点总数
|
|
133
211
|
```
|
|
134
212
|
|
|
135
|
-
### filterTree
|
|
213
|
+
### filterTree
|
|
136
214
|
|
|
137
215
|
过滤树结构数据,返回满足条件的节点。
|
|
138
216
|
|
|
@@ -154,7 +232,11 @@ const leafNodes = t.filterTree(treeData, (node) => {
|
|
|
154
232
|
console.log(leafNodes) // 返回所有叶子节点
|
|
155
233
|
```
|
|
156
234
|
|
|
157
|
-
|
|
235
|
+
---
|
|
236
|
+
|
|
237
|
+
## 查找方法
|
|
238
|
+
|
|
239
|
+
### findTree
|
|
158
240
|
|
|
159
241
|
查找树结构数据中满足条件的第一个节点。如果未找到,返回 null。
|
|
160
242
|
|
|
@@ -172,85 +254,7 @@ const nodeNotFound = t.findTree(treeData, (node) => node.id === 999)
|
|
|
172
254
|
console.log(nodeNotFound) // null
|
|
173
255
|
```
|
|
174
256
|
|
|
175
|
-
###
|
|
176
|
-
|
|
177
|
-
在指定节点下添加子节点到末尾。返回 true 表示添加成功,false 表示未找到目标节点。
|
|
178
|
-
|
|
179
|
-
```javascript
|
|
180
|
-
// 在ID为1的节点下添加新子节点
|
|
181
|
-
const addSuccess = t.pushTree(treeData, 1, { id: 7, name: 'node7' })
|
|
182
|
-
console.log(addSuccess) // true
|
|
183
|
-
console.log(treeData) // 新节点已添加到 children 数组末尾
|
|
184
|
-
|
|
185
|
-
// 尝试在不存在的节点下添加
|
|
186
|
-
const addFailed = t.pushTree(treeData, 999, { id: 8, name: 'node8' })
|
|
187
|
-
console.log(addFailed) // false,未找到目标节点
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
### unshiftTree(在指定节点下添加子节点到开头)
|
|
191
|
-
|
|
192
|
-
在指定节点下添加子节点到开头。返回 true 表示添加成功,false 表示未找到目标节点。
|
|
193
|
-
|
|
194
|
-
```javascript
|
|
195
|
-
// 在ID为1的节点下添加新子节点到开头
|
|
196
|
-
const unshiftSuccess = t.unshiftTree(treeData, 1, { id: 7, name: 'node7' })
|
|
197
|
-
console.log(unshiftSuccess) // true
|
|
198
|
-
console.log(treeData) // 新节点已添加到 children 数组开头
|
|
199
|
-
```
|
|
200
|
-
|
|
201
|
-
### popTree(删除指定节点下的最后一个子节点)
|
|
202
|
-
|
|
203
|
-
删除指定节点下的最后一个子节点。返回被删除的节点,如果节点不存在或没有子节点则返回 false。
|
|
204
|
-
|
|
205
|
-
```javascript
|
|
206
|
-
// 删除ID为1的节点下的最后一个子节点
|
|
207
|
-
const removedNode = t.popTree(treeData, 1)
|
|
208
|
-
console.log(removedNode) // 返回被删除的节点对象,或 false
|
|
209
|
-
|
|
210
|
-
// 尝试删除不存在的节点下的子节点
|
|
211
|
-
const popFailed = t.popTree(treeData, 999)
|
|
212
|
-
console.log(popFailed) // false
|
|
213
|
-
```
|
|
214
|
-
|
|
215
|
-
### shiftTree(删除指定节点下的第一个子节点)
|
|
216
|
-
|
|
217
|
-
删除指定节点下的第一个子节点。返回被删除的节点,如果节点不存在或没有子节点则返回 false。
|
|
218
|
-
|
|
219
|
-
```javascript
|
|
220
|
-
// 删除ID为1的节点下的第一个子节点
|
|
221
|
-
const shiftedNode = t.shiftTree(treeData, 1)
|
|
222
|
-
console.log(shiftedNode) // 返回被删除的节点对象,或 false
|
|
223
|
-
```
|
|
224
|
-
|
|
225
|
-
### someTree(树结构数据的some方法)
|
|
226
|
-
|
|
227
|
-
检查树结构数据中是否存在满足条件的节点。只要有一个节点满足条件就返回 true。
|
|
228
|
-
|
|
229
|
-
```javascript
|
|
230
|
-
// 检查是否存在名称为 'node2' 的节点
|
|
231
|
-
const hasNode2 = t.someTree(treeData, node => node.name === 'node2')
|
|
232
|
-
console.log(hasNode2) // true
|
|
233
|
-
|
|
234
|
-
// 检查是否存在ID大于10的节点
|
|
235
|
-
const hasLargeId = t.someTree(treeData, node => node.id > 10)
|
|
236
|
-
console.log(hasLargeId) // false
|
|
237
|
-
```
|
|
238
|
-
|
|
239
|
-
### everyTree(树结构数据的every方法)
|
|
240
|
-
|
|
241
|
-
检查树结构数据中是否所有节点都满足条件。只有所有节点都满足条件才返回 true。
|
|
242
|
-
|
|
243
|
-
```javascript
|
|
244
|
-
// 检查所有节点的ID是否都大于0
|
|
245
|
-
const allIdsPositive = t.everyTree(treeData, node => node.id > 0)
|
|
246
|
-
console.log(allIdsPositive) // true
|
|
247
|
-
|
|
248
|
-
// 检查所有节点是否都有 name 属性
|
|
249
|
-
const allHaveName = t.everyTree(treeData, node => node.name)
|
|
250
|
-
console.log(allHaveName) // 根据实际数据返回 true 或 false
|
|
251
|
-
```
|
|
252
|
-
|
|
253
|
-
### includesTree(检查树中是否包含指定节点)
|
|
257
|
+
### includesTree
|
|
254
258
|
|
|
255
259
|
检查树结构数据中是否包含指定ID的节点。
|
|
256
260
|
|
|
@@ -261,7 +265,7 @@ const hasNode = t.includesTree(treeData, nodeId)
|
|
|
261
265
|
console.log(hasNode) // true 表示包含该节点,false 表示不包含
|
|
262
266
|
```
|
|
263
267
|
|
|
264
|
-
### atTree
|
|
268
|
+
### atTree
|
|
265
269
|
|
|
266
270
|
根据父节点ID和子节点索引获取节点。支持负数索引,和数组的 at 方法一样。未找到返回 null。
|
|
267
271
|
|
|
@@ -279,7 +283,7 @@ const nodeNotFound = t.atTree(treeData, 1, 10)
|
|
|
279
283
|
console.log(nodeNotFound) // null
|
|
280
284
|
```
|
|
281
285
|
|
|
282
|
-
### indexOfTree
|
|
286
|
+
### indexOfTree
|
|
283
287
|
|
|
284
288
|
返回一个数组,值为从根节点开始到 targetId 所在节点的索引路径。未找到返回 null。返回值可以传入 atIndexOfTree 的第二个参数进行取值。
|
|
285
289
|
|
|
@@ -298,7 +302,7 @@ const nodeByPath = t.atIndexOfTree(treeData, indexPath)
|
|
|
298
302
|
console.log(nodeByPath) // 获取到ID为4的节点
|
|
299
303
|
```
|
|
300
304
|
|
|
301
|
-
### atIndexOfTree
|
|
305
|
+
### atIndexOfTree
|
|
302
306
|
|
|
303
307
|
根据索引路径获取节点。路径无效或超出范围返回 null。
|
|
304
308
|
|
|
@@ -317,7 +321,73 @@ const invalidPath = t.atIndexOfTree(treeData, [999])
|
|
|
317
321
|
console.log(invalidPath) // null
|
|
318
322
|
```
|
|
319
323
|
|
|
320
|
-
|
|
324
|
+
---
|
|
325
|
+
|
|
326
|
+
## 修改方法
|
|
327
|
+
|
|
328
|
+
### pushTree
|
|
329
|
+
|
|
330
|
+
在指定节点下添加子节点到末尾。返回 true 表示添加成功,false 表示未找到目标节点。
|
|
331
|
+
|
|
332
|
+
```javascript
|
|
333
|
+
// 在ID为1的节点下添加新子节点
|
|
334
|
+
const addSuccess = t.pushTree(treeData, 1, { id: 7, name: 'node7' })
|
|
335
|
+
console.log(addSuccess) // true
|
|
336
|
+
console.log(treeData) // 新节点已添加到 children 数组末尾
|
|
337
|
+
|
|
338
|
+
// 尝试在不存在的节点下添加
|
|
339
|
+
const addFailed = t.pushTree(treeData, 999, { id: 8, name: 'node8' })
|
|
340
|
+
console.log(addFailed) // false,未找到目标节点
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
### unshiftTree
|
|
344
|
+
|
|
345
|
+
在指定节点下添加子节点到开头。返回 true 表示添加成功,false 表示未找到目标节点。
|
|
346
|
+
|
|
347
|
+
```javascript
|
|
348
|
+
// 在ID为1的节点下添加新子节点到开头
|
|
349
|
+
const unshiftSuccess = t.unshiftTree(treeData, 1, { id: 7, name: 'node7' })
|
|
350
|
+
console.log(unshiftSuccess) // true
|
|
351
|
+
console.log(treeData) // 新节点已添加到 children 数组开头
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
### popTree
|
|
355
|
+
|
|
356
|
+
删除指定节点下的最后一个子节点。返回被删除的节点,如果节点不存在或没有子节点则返回 false。
|
|
357
|
+
|
|
358
|
+
```javascript
|
|
359
|
+
// 删除ID为1的节点下的最后一个子节点
|
|
360
|
+
const removedNode = t.popTree(treeData, 1)
|
|
361
|
+
console.log(removedNode) // 返回被删除的节点对象,或 false
|
|
362
|
+
|
|
363
|
+
// 尝试删除不存在的节点下的子节点
|
|
364
|
+
const popFailed = t.popTree(treeData, 999)
|
|
365
|
+
console.log(popFailed) // false
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
### shiftTree
|
|
369
|
+
|
|
370
|
+
删除指定节点下的第一个子节点。返回被删除的节点,如果节点不存在或没有子节点则返回 false。
|
|
371
|
+
|
|
372
|
+
```javascript
|
|
373
|
+
// 删除ID为1的节点下的第一个子节点
|
|
374
|
+
const shiftedNode = t.shiftTree(treeData, 1)
|
|
375
|
+
console.log(shiftedNode) // 返回被删除的节点对象,或 false
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
### removeTree
|
|
379
|
+
|
|
380
|
+
删除树结构数据中指定ID的节点,包括根节点和子节点。
|
|
381
|
+
|
|
382
|
+
```javascript
|
|
383
|
+
const nodeIdToRemove = 2
|
|
384
|
+
const removeSuccess = t.removeTree(treeData, nodeIdToRemove)
|
|
385
|
+
|
|
386
|
+
console.log(removeSuccess) // true 表示删除成功,false 表示未找到节点
|
|
387
|
+
console.log(treeData) // 删除后的树结构
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
### dedupTree
|
|
321
391
|
|
|
322
392
|
树结构对象数组去重方法,根据指定的键去除重复节点。保留第一次出现的节点。
|
|
323
393
|
|
|
@@ -331,19 +401,39 @@ const uniqueByNameTree = t.dedupTree(treeData, 'name')
|
|
|
331
401
|
console.log(uniqueByNameTree) // 返回根据 name 去重后的数据
|
|
332
402
|
```
|
|
333
403
|
|
|
334
|
-
|
|
404
|
+
---
|
|
335
405
|
|
|
336
|
-
|
|
406
|
+
## 判断方法
|
|
407
|
+
|
|
408
|
+
### someTree
|
|
409
|
+
|
|
410
|
+
检查树结构数据中是否存在满足条件的节点。只要有一个节点满足条件就返回 true。
|
|
337
411
|
|
|
338
412
|
```javascript
|
|
339
|
-
|
|
340
|
-
const
|
|
413
|
+
// 检查是否存在名称为 'node2' 的节点
|
|
414
|
+
const hasNode2 = t.someTree(treeData, node => node.name === 'node2')
|
|
415
|
+
console.log(hasNode2) // true
|
|
341
416
|
|
|
342
|
-
|
|
343
|
-
|
|
417
|
+
// 检查是否存在ID大于10的节点
|
|
418
|
+
const hasLargeId = t.someTree(treeData, node => node.id > 10)
|
|
419
|
+
console.log(hasLargeId) // false
|
|
344
420
|
```
|
|
345
421
|
|
|
346
|
-
###
|
|
422
|
+
### everyTree
|
|
423
|
+
|
|
424
|
+
检查树结构数据中是否所有节点都满足条件。只有所有节点都满足条件才返回 true。
|
|
425
|
+
|
|
426
|
+
```javascript
|
|
427
|
+
// 检查所有节点的ID是否都大于0
|
|
428
|
+
const allIdsPositive = t.everyTree(treeData, node => node.id > 0)
|
|
429
|
+
console.log(allIdsPositive) // true
|
|
430
|
+
|
|
431
|
+
// 检查所有节点是否都有 name 属性
|
|
432
|
+
const allHaveName = t.everyTree(treeData, node => node.name)
|
|
433
|
+
console.log(allHaveName) // 根据实际数据返回 true 或 false
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
### getParentTree
|
|
347
437
|
|
|
348
438
|
获取指定节点的父节点。如果节点是根节点或未找到,返回 null。
|
|
349
439
|
|
|
@@ -361,7 +451,7 @@ const parentNotFound = t.getParentTree(treeData, 999)
|
|
|
361
451
|
console.log(parentNotFound) // null
|
|
362
452
|
```
|
|
363
453
|
|
|
364
|
-
### getChildrenTree
|
|
454
|
+
### getChildrenTree
|
|
365
455
|
|
|
366
456
|
获取指定节点的所有直接子节点。如果未找到节点或没有子节点,返回空数组。
|
|
367
457
|
|
|
@@ -394,7 +484,7 @@ const customChildren = t.getChildrenTree(customTree, 1, fieldNames)
|
|
|
394
484
|
console.log(customChildren) // 返回子节点数组
|
|
395
485
|
```
|
|
396
486
|
|
|
397
|
-
### getSiblingsTree
|
|
487
|
+
### getSiblingsTree
|
|
398
488
|
|
|
399
489
|
获取指定节点的所有兄弟节点(包括自己)。如果未找到节点,返回空数组。根节点的兄弟节点是其他根节点。
|
|
400
490
|
|
|
@@ -432,7 +522,11 @@ const customSiblings = t.getSiblingsTree(customTree, 2, fieldNames)
|
|
|
432
522
|
console.log(customSiblings) // 返回兄弟节点数组(包括自己)
|
|
433
523
|
```
|
|
434
524
|
|
|
435
|
-
|
|
525
|
+
---
|
|
526
|
+
|
|
527
|
+
## 工具方法
|
|
528
|
+
|
|
529
|
+
### getNodeDepthMap
|
|
436
530
|
|
|
437
531
|
返回一个字典,键代表节点的 id,值代表该节点在数据的第几层。深度从1开始,根节点深度为1。
|
|
438
532
|
|
|
@@ -450,7 +544,7 @@ const emptyDepthMap = t.getNodeDepthMap([])
|
|
|
450
544
|
console.log(emptyDepthMap) // {}
|
|
451
545
|
```
|
|
452
546
|
|
|
453
|
-
### getNodeDepth
|
|
547
|
+
### getNodeDepth
|
|
454
548
|
|
|
455
549
|
获取指定节点的深度。深度从1开始,根节点深度为1。
|
|
456
550
|
|
|
@@ -490,7 +584,107 @@ console.log(depth) // 2
|
|
|
490
584
|
- `getNodeDepthMap` - 批量获取所有节点的深度(一次性计算所有节点)
|
|
491
585
|
- `getNodeDepth` - 只获取单个节点的深度(只计算目标节点,效率更高)
|
|
492
586
|
|
|
493
|
-
###
|
|
587
|
+
### isLeafNode
|
|
588
|
+
|
|
589
|
+
检查节点是否是叶子节点(没有子节点)。轻量级方法,只检查节点本身,不遍历树。
|
|
590
|
+
|
|
591
|
+
```javascript
|
|
592
|
+
// 没有 children 字段的节点是叶子节点
|
|
593
|
+
const leafNode1 = { id: 1, name: 'node1' };
|
|
594
|
+
console.log(t.isLeafNode(leafNode1)) // true
|
|
595
|
+
|
|
596
|
+
// children 为空数组的节点是叶子节点
|
|
597
|
+
const leafNode2 = { id: 2, name: 'node2', children: [] };
|
|
598
|
+
console.log(t.isLeafNode(leafNode2)) // true
|
|
599
|
+
|
|
600
|
+
// 有子节点的节点不是叶子节点
|
|
601
|
+
const parentNode = {
|
|
602
|
+
id: 3,
|
|
603
|
+
name: 'node3',
|
|
604
|
+
children: [{ id: 4, name: 'node4' }],
|
|
605
|
+
};
|
|
606
|
+
console.log(t.isLeafNode(parentNode)) // false
|
|
607
|
+
|
|
608
|
+
// 在 filterTree 中使用(过滤出所有叶子节点)
|
|
609
|
+
const leafNodes = t.filterTree(treeData, (node) => t.isLeafNode(node))
|
|
610
|
+
console.log(leafNodes) // 返回所有叶子节点
|
|
611
|
+
|
|
612
|
+
// 在 forEachTree 中使用
|
|
613
|
+
t.forEachTree(treeData, (node) => {
|
|
614
|
+
if (t.isLeafNode(node)) {
|
|
615
|
+
console.log('叶子节点:', node.name)
|
|
616
|
+
}
|
|
617
|
+
})
|
|
618
|
+
|
|
619
|
+
// 支持自定义字段名
|
|
620
|
+
const customNode = {
|
|
621
|
+
nodeId: 1,
|
|
622
|
+
name: 'node1',
|
|
623
|
+
subNodes: [],
|
|
624
|
+
};
|
|
625
|
+
const fieldNames = { children: 'subNodes', id: 'nodeId' };
|
|
626
|
+
console.log(t.isLeafNode(customNode, fieldNames)) // true
|
|
627
|
+
```
|
|
628
|
+
|
|
629
|
+
**与现有方法的区别:**
|
|
630
|
+
- `isLeafNode` - 只检查单个节点,轻量级(O(1)),适合在遍历时使用
|
|
631
|
+
- `getChildrenTree` - 获取子节点数组,需要传入 tree 和 nodeId,需要查找节点(O(n))
|
|
632
|
+
|
|
633
|
+
### isRootNode
|
|
634
|
+
|
|
635
|
+
检查节点是否是根节点(没有父节点)。根节点是树结构数据数组中的顶层节点。
|
|
636
|
+
|
|
637
|
+
```javascript
|
|
638
|
+
// 检查根节点
|
|
639
|
+
const treeData = [
|
|
640
|
+
{
|
|
641
|
+
id: 1,
|
|
642
|
+
name: 'root1',
|
|
643
|
+
children: [{ id: 2, name: 'child1' }],
|
|
644
|
+
},
|
|
645
|
+
];
|
|
646
|
+
console.log(t.isRootNode(treeData, 1)) // true
|
|
647
|
+
console.log(t.isRootNode(treeData, 2)) // false
|
|
648
|
+
|
|
649
|
+
// 多个根节点的情况
|
|
650
|
+
const multiRoot = [
|
|
651
|
+
{ id: 1, name: 'root1' },
|
|
652
|
+
{ id: 2, name: 'root2' },
|
|
653
|
+
{ id: 3, name: 'root3' },
|
|
654
|
+
];
|
|
655
|
+
console.log(t.isRootNode(multiRoot, 1)) // true
|
|
656
|
+
console.log(t.isRootNode(multiRoot, 2)) // true
|
|
657
|
+
console.log(t.isRootNode(multiRoot, 3)) // true
|
|
658
|
+
|
|
659
|
+
// 在遍历时使用
|
|
660
|
+
t.forEachTree(treeData, (node) => {
|
|
661
|
+
if (t.isRootNode(treeData, node.id)) {
|
|
662
|
+
console.log('根节点:', node.name)
|
|
663
|
+
}
|
|
664
|
+
})
|
|
665
|
+
|
|
666
|
+
// 支持自定义字段名
|
|
667
|
+
const customTree = [
|
|
668
|
+
{
|
|
669
|
+
nodeId: 1,
|
|
670
|
+
name: 'root1',
|
|
671
|
+
subNodes: [{ nodeId: 2, name: 'child1' }],
|
|
672
|
+
},
|
|
673
|
+
];
|
|
674
|
+
const fieldNames = { children: 'subNodes', id: 'nodeId' };
|
|
675
|
+
console.log(t.isRootNode(customTree, 1, fieldNames)) // true
|
|
676
|
+
console.log(t.isRootNode(customTree, 2, fieldNames)) // false
|
|
677
|
+
|
|
678
|
+
// 节点不存在时返回 false
|
|
679
|
+
console.log(t.isRootNode(treeData, 999)) // false
|
|
680
|
+
```
|
|
681
|
+
|
|
682
|
+
**与现有方法的区别:**
|
|
683
|
+
- `isRootNode` - 语义化方法,直接返回布尔值
|
|
684
|
+
- `getParentTree` - 返回父节点对象,需要判断是否为 null
|
|
685
|
+
- `getNodeDepth` - 返回深度,需要判断是否等于 1
|
|
686
|
+
|
|
687
|
+
### isEmptyTreeData
|
|
494
688
|
|
|
495
689
|
检查树结构数据(数组)是否为空。空数组、null、undefined 都视为空。此函数支持 fieldNames 参数以保持 API 一致性,但该参数不生效(因为只检查数组是否为空,不访问 children 或 id 字段)。
|
|
496
690
|
|
|
@@ -513,7 +707,7 @@ const isEmptyWithFieldNames = t.isEmptyTreeData(treeData, fieldNames)
|
|
|
513
707
|
console.log(isEmptyWithFieldNames) // false(结果与不传 fieldNames 相同)
|
|
514
708
|
```
|
|
515
709
|
|
|
516
|
-
### isEmptySingleTreeData
|
|
710
|
+
### isEmptySingleTreeData
|
|
517
711
|
|
|
518
712
|
检查单个树结构数据是否为空。如果数据不是有效的单个树结构数据、没有 children 字段,或者 children 是空数组,则视为空。如果有子节点(children 数组不为空),即使子节点本身是空的,树也不为空。
|
|
519
713
|
|
|
@@ -566,7 +760,56 @@ const isEmptyCustom = t.isEmptySingleTreeData(customTree, fieldNames)
|
|
|
566
760
|
console.log(isEmptyCustom) // true
|
|
567
761
|
```
|
|
568
762
|
|
|
569
|
-
###
|
|
763
|
+
### isTreeData
|
|
764
|
+
|
|
765
|
+
判断数据是否是树结构数据(数组)。树结构数据必须是一个数组,数组中的每个元素都必须是有效的单个树结构数据。
|
|
766
|
+
|
|
767
|
+
```javascript
|
|
768
|
+
// 有效的树结构数据(森林)
|
|
769
|
+
const forest = [
|
|
770
|
+
{
|
|
771
|
+
id: 1,
|
|
772
|
+
name: 'node1',
|
|
773
|
+
children: [{ id: 2, name: 'node2' }],
|
|
774
|
+
},
|
|
775
|
+
{
|
|
776
|
+
id: 3,
|
|
777
|
+
name: 'node3',
|
|
778
|
+
children: [{ id: 4, name: 'node4' }],
|
|
779
|
+
},
|
|
780
|
+
];
|
|
781
|
+
console.log(t.isTreeData(forest)) // true
|
|
782
|
+
|
|
783
|
+
// 空数组也是有效的树结构数据(空森林)
|
|
784
|
+
console.log(t.isTreeData([])) // true
|
|
785
|
+
|
|
786
|
+
// 单个对象不是树结构数据(应该用 isSingleTreeData)
|
|
787
|
+
console.log(t.isTreeData({ id: 1 })) // false
|
|
788
|
+
|
|
789
|
+
// 数组包含非树结构元素,返回 false
|
|
790
|
+
const invalidForest = [
|
|
791
|
+
{ id: 1, children: [{ id: 2 }] },
|
|
792
|
+
'not a tree', // 无效元素
|
|
793
|
+
];
|
|
794
|
+
console.log(t.isTreeData(invalidForest)) // false
|
|
795
|
+
|
|
796
|
+
// null 或 undefined 不是有效的树结构数据
|
|
797
|
+
console.log(t.isTreeData(null)) // false
|
|
798
|
+
console.log(t.isTreeData(undefined)) // false
|
|
799
|
+
|
|
800
|
+
// 支持自定义字段名
|
|
801
|
+
const customForest = [
|
|
802
|
+
{
|
|
803
|
+
nodeId: 1,
|
|
804
|
+
name: 'node1',
|
|
805
|
+
subNodes: [{ nodeId: 2, name: 'node2' }],
|
|
806
|
+
},
|
|
807
|
+
];
|
|
808
|
+
const fieldNames = { children: 'subNodes', id: 'nodeId' };
|
|
809
|
+
console.log(t.isTreeData(customForest, fieldNames)) // true
|
|
810
|
+
```
|
|
811
|
+
|
|
812
|
+
### isSingleTreeData
|
|
570
813
|
|
|
571
814
|
判断数据是否是单个树结构数据(单个对象)。树结构数据必须是一个对象(不能是数组、null、undefined 或基本类型),如果存在 children 字段,必须是数组类型,并且会递归检查所有子节点。
|
|
572
815
|
|
|
@@ -608,55 +851,136 @@ const fieldNames = { children: 'subNodes', id: 'nodeId' };
|
|
|
608
851
|
console.log(t.isSingleTreeData(customTree, fieldNames)) // true
|
|
609
852
|
```
|
|
610
853
|
|
|
611
|
-
###
|
|
854
|
+
### isValidTreeNode
|
|
612
855
|
|
|
613
|
-
|
|
856
|
+
检查单个节点是否是有效的树节点结构(轻量级,不递归检查子节点)。只检查节点本身的结构,不检查子节点。
|
|
614
857
|
|
|
615
858
|
```javascript
|
|
616
|
-
//
|
|
617
|
-
const
|
|
859
|
+
// 有效的树节点(有 children 数组)
|
|
860
|
+
const node1 = {
|
|
861
|
+
id: 1,
|
|
862
|
+
name: 'node1',
|
|
863
|
+
children: [{ id: 2 }],
|
|
864
|
+
};
|
|
865
|
+
console.log(t.isValidTreeNode(node1)) // true
|
|
866
|
+
|
|
867
|
+
// 有效的树节点(没有 children 字段)
|
|
868
|
+
const node2 = { id: 1, name: 'node1' };
|
|
869
|
+
console.log(t.isValidTreeNode(node2)) // true
|
|
870
|
+
|
|
871
|
+
// 无效的树节点(children 不是数组)
|
|
872
|
+
const invalidNode = {
|
|
873
|
+
id: 1,
|
|
874
|
+
children: 'not an array',
|
|
875
|
+
};
|
|
876
|
+
console.log(t.isValidTreeNode(invalidNode)) // false
|
|
877
|
+
|
|
878
|
+
// 支持自定义字段名
|
|
879
|
+
const customNode = {
|
|
880
|
+
nodeId: 1,
|
|
881
|
+
subNodes: [{ nodeId: 2 }],
|
|
882
|
+
};
|
|
883
|
+
const fieldNames = { children: 'subNodes', id: 'nodeId' };
|
|
884
|
+
console.log(t.isValidTreeNode(customNode, fieldNames)) // true
|
|
885
|
+
```
|
|
886
|
+
|
|
887
|
+
**与 isSingleTreeData 的区别:**
|
|
888
|
+
- `isValidTreeNode` - 只检查单个节点的基本结构,不递归检查子节点(轻量级)
|
|
889
|
+
- `isSingleTreeData` - 递归检查整个树结构,确保所有子节点都是有效的树结构
|
|
890
|
+
|
|
891
|
+
### isTreeNodeWithCircularCheck
|
|
892
|
+
|
|
893
|
+
检查节点是否是有效的树节点结构,并检测循环引用。使用 WeakSet 跟踪已访问的节点,如果发现循环引用则返回 false。
|
|
894
|
+
|
|
895
|
+
```javascript
|
|
896
|
+
// 有效的树节点(无循环引用)
|
|
897
|
+
const validNode = {
|
|
898
|
+
id: 1,
|
|
899
|
+
children: [
|
|
900
|
+
{ id: 2, children: [{ id: 3 }] },
|
|
901
|
+
],
|
|
902
|
+
};
|
|
903
|
+
console.log(t.isTreeNodeWithCircularCheck(validNode)) // true
|
|
904
|
+
|
|
905
|
+
// 检测循环引用
|
|
906
|
+
const node1 = { id: 1, children: [] };
|
|
907
|
+
const node2 = { id: 2, children: [] };
|
|
908
|
+
node1.children.push(node2);
|
|
909
|
+
node2.children.push(node1); // 循环引用
|
|
910
|
+
console.log(t.isTreeNodeWithCircularCheck(node1)) // false
|
|
911
|
+
|
|
912
|
+
// 检测自引用
|
|
913
|
+
const selfRefNode = { id: 1, children: [] };
|
|
914
|
+
selfRefNode.children.push(selfRefNode); // 自引用
|
|
915
|
+
console.log(t.isTreeNodeWithCircularCheck(selfRefNode)) // false
|
|
916
|
+
|
|
917
|
+
// 支持自定义字段名
|
|
918
|
+
const customNode = {
|
|
919
|
+
nodeId: 1,
|
|
920
|
+
subNodes: [{ nodeId: 2 }],
|
|
921
|
+
};
|
|
922
|
+
const fieldNames = { children: 'subNodes', id: 'nodeId' };
|
|
923
|
+
console.log(t.isTreeNodeWithCircularCheck(customNode, fieldNames)) // true
|
|
924
|
+
```
|
|
925
|
+
|
|
926
|
+
**使用场景:**
|
|
927
|
+
- 在接收用户输入或外部数据时,检查是否有循环引用
|
|
928
|
+
- 数据验证,防止无限递归
|
|
929
|
+
- 调试时检查数据结构是否正确
|
|
930
|
+
|
|
931
|
+
### isSafeTreeDepth
|
|
932
|
+
|
|
933
|
+
检查树结构数据的深度是否安全(防止递归爆栈)。如果树的深度超过 `maxDepth`,返回 false。
|
|
934
|
+
|
|
935
|
+
```javascript
|
|
936
|
+
// 深度安全的树
|
|
937
|
+
const safeTree = [
|
|
618
938
|
{
|
|
619
939
|
id: 1,
|
|
620
|
-
|
|
621
|
-
|
|
940
|
+
children: [
|
|
941
|
+
{ id: 2, children: [{ id: 3 }] },
|
|
942
|
+
],
|
|
622
943
|
},
|
|
944
|
+
];
|
|
945
|
+
console.log(t.isSafeTreeDepth(safeTree, 10)) // true(深度为3,小于10)
|
|
946
|
+
|
|
947
|
+
// 深度超过最大深度
|
|
948
|
+
const deepTree = [
|
|
623
949
|
{
|
|
624
|
-
id:
|
|
625
|
-
|
|
626
|
-
|
|
950
|
+
id: 1,
|
|
951
|
+
children: [
|
|
952
|
+
{ id: 2, children: [{ id: 3 }] },
|
|
953
|
+
],
|
|
627
954
|
},
|
|
628
955
|
];
|
|
629
|
-
console.log(t.
|
|
956
|
+
console.log(t.isSafeTreeDepth(deepTree, 2)) // false(深度为3,超过2)
|
|
630
957
|
|
|
631
|
-
//
|
|
632
|
-
console.log(t.
|
|
958
|
+
// 空树总是安全的
|
|
959
|
+
console.log(t.isSafeTreeDepth([], 10)) // true
|
|
633
960
|
|
|
634
|
-
//
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
// 数组包含非树结构元素,返回 false
|
|
638
|
-
const invalidForest = [
|
|
639
|
-
{ id: 1, children: [{ id: 2 }] },
|
|
640
|
-
'not a tree', // 无效元素
|
|
641
|
-
];
|
|
642
|
-
console.log(t.isTreeData(invalidForest)) // false
|
|
643
|
-
|
|
644
|
-
// null 或 undefined 不是有效的树结构数据
|
|
645
|
-
console.log(t.isTreeData(null)) // false
|
|
646
|
-
console.log(t.isTreeData(undefined)) // false
|
|
961
|
+
// 单层树
|
|
962
|
+
const singleLayer = [{ id: 1 }, { id: 2 }];
|
|
963
|
+
console.log(t.isSafeTreeDepth(singleLayer, 1)) // true
|
|
647
964
|
|
|
648
965
|
// 支持自定义字段名
|
|
649
|
-
const
|
|
966
|
+
const customTree = [
|
|
650
967
|
{
|
|
651
968
|
nodeId: 1,
|
|
652
|
-
|
|
653
|
-
|
|
969
|
+
subNodes: [
|
|
970
|
+
{ nodeId: 2, subNodes: [{ nodeId: 3 }] },
|
|
971
|
+
],
|
|
654
972
|
},
|
|
655
973
|
];
|
|
656
974
|
const fieldNames = { children: 'subNodes', id: 'nodeId' };
|
|
657
|
-
console.log(t.
|
|
975
|
+
console.log(t.isSafeTreeDepth(customTree, 3, fieldNames)) // true
|
|
976
|
+
console.log(t.isSafeTreeDepth(customTree, 2, fieldNames)) // false
|
|
658
977
|
```
|
|
659
978
|
|
|
979
|
+
**使用场景:**
|
|
980
|
+
- 在处理大型树之前,先检查深度是否安全
|
|
981
|
+
- 防止递归调用栈溢出
|
|
982
|
+
- 性能优化,避免处理过深的树结构
|
|
983
|
+
|
|
660
984
|
## 自定义字段名
|
|
661
985
|
|
|
662
986
|
所有方法都支持自定义 children 和 id 的属性名,通过最后一个参数传入配置对象:
|
|
@@ -670,7 +994,7 @@ const fieldNames = { children: 'subNodes', id: 'nodeId' };
|
|
|
670
994
|
const foundNode2 = t.findTree(customTreeData, (node) => node.nodeId === 2, fieldNames);
|
|
671
995
|
```
|
|
672
996
|
|
|
673
|
-
**注意:** 所有
|
|
997
|
+
**注意:** 所有 30 个函数都支持 `fieldNames` 参数,保持 API 一致性。即使某些函数(如 `isEmptyTreeData`)中该参数不生效,也可以传入以保持代码风格一致。
|
|
674
998
|
|
|
675
999
|
## 测试
|
|
676
1000
|
|
|
@@ -707,6 +1031,36 @@ npm run build
|
|
|
707
1031
|
- **Terser** - JavaScript 压缩工具
|
|
708
1032
|
- **TypeScript** - 类型支持
|
|
709
1033
|
|
|
710
|
-
##
|
|
1034
|
+
## 🤝 贡献
|
|
1035
|
+
|
|
1036
|
+
欢迎贡献!如果你有任何想法或发现问题,请:
|
|
1037
|
+
|
|
1038
|
+
1. Fork 本仓库
|
|
1039
|
+
2. 创建你的特性分支 (`git checkout -b feature/AmazingFeature`)
|
|
1040
|
+
3. 提交你的更改 (`git commit -m 'Add some AmazingFeature'`)
|
|
1041
|
+
4. 推送到分支 (`git push origin feature/AmazingFeature`)
|
|
1042
|
+
5. 开启一个 Pull Request
|
|
1043
|
+
|
|
1044
|
+
## 📝 更新日志
|
|
1045
|
+
|
|
1046
|
+
查看 [CHANGELOG.md](./CHANGELOG.md) 了解详细的版本更新记录。
|
|
1047
|
+
|
|
1048
|
+
## 📄 许可证
|
|
1049
|
+
|
|
1050
|
+
本项目采用 [MIT](./LICENSE) 许可证。
|
|
1051
|
+
|
|
1052
|
+
## 🔗 相关链接
|
|
1053
|
+
|
|
1054
|
+
- [GitHub 仓库](https://github.com/knott11/tree-processor)
|
|
1055
|
+
- [npm 包](https://www.npmjs.com/package/tree-processor)
|
|
1056
|
+
- [问题反馈](https://github.com/knott11/tree-processor/issues)
|
|
1057
|
+
|
|
1058
|
+
---
|
|
1059
|
+
|
|
1060
|
+
<div align="center">
|
|
1061
|
+
|
|
1062
|
+
如果这个项目对你有帮助,请给它一个 ⭐️
|
|
1063
|
+
|
|
1064
|
+
Made with ❤️ by [knott11](https://github.com/knott11)
|
|
711
1065
|
|
|
712
|
-
|
|
1066
|
+
</div>
|
package/dist/index.d.ts
CHANGED
|
@@ -29,6 +29,11 @@ export declare function getParentTree(tree: TreeData, targetId: any, fieldNames?
|
|
|
29
29
|
export declare function includesTree(tree: TreeData, targetId: any, fieldNames?: FieldNames): boolean;
|
|
30
30
|
export declare function isSingleTreeData(data: any, fieldNames?: FieldNames): boolean;
|
|
31
31
|
export declare function isTreeData(data: any, fieldNames?: FieldNames): boolean;
|
|
32
|
+
export declare function isValidTreeNode(value: unknown, fieldNames?: FieldNames): value is TreeNode;
|
|
33
|
+
export declare function isTreeNodeWithCircularCheck(value: unknown, fieldNames?: FieldNames, visited?: WeakSet<object>): boolean;
|
|
34
|
+
export declare function isSafeTreeDepth(tree: TreeData, maxDepth: number, fieldNames?: FieldNames): boolean;
|
|
35
|
+
export declare function isLeafNode(node: TreeNode, fieldNames?: FieldNames): boolean;
|
|
36
|
+
export declare function isRootNode(tree: TreeData, nodeId: any, fieldNames?: FieldNames): boolean;
|
|
32
37
|
declare const treeProcessor: {
|
|
33
38
|
mapTree: typeof mapTree;
|
|
34
39
|
filterTree: typeof filterTree;
|
|
@@ -55,6 +60,11 @@ declare const treeProcessor: {
|
|
|
55
60
|
includesTree: typeof includesTree;
|
|
56
61
|
isSingleTreeData: typeof isSingleTreeData;
|
|
57
62
|
isTreeData: typeof isTreeData;
|
|
63
|
+
isValidTreeNode: typeof isValidTreeNode;
|
|
64
|
+
isTreeNodeWithCircularCheck: typeof isTreeNodeWithCircularCheck;
|
|
65
|
+
isSafeTreeDepth: typeof isSafeTreeDepth;
|
|
66
|
+
isLeafNode: typeof isLeafNode;
|
|
67
|
+
isRootNode: typeof isRootNode;
|
|
58
68
|
};
|
|
59
69
|
export default treeProcessor;
|
|
60
70
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;CACZ;AAaD,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAK3C,MAAM,MAAM,QAAQ,GAAG,QAAQ,EAAE,CAAC;AASlC,wBAAgB,OAAO,CACrB,IAAI,EAAE,QAAQ,EACd,QAAQ,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,GAAG,EACjC,UAAU,GAAE,UAAgC,GAC3C,GAAG,EAAE,CAeP;AASD,wBAAgB,UAAU,CACxB,IAAI,EAAE,QAAQ,EACd,QAAQ,EAAE,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,EACpD,UAAU,GAAE,UAAgC,GAC3C,QAAQ,CAiBV;AASD,wBAAgB,QAAQ,CACtB,IAAI,EAAE,QAAQ,EACd,WAAW,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,OAAO,EACxC,UAAU,GAAE,UAAgC,GAC3C,QAAQ,GAAG,IAAI,CAcjB;AAUD,wBAAgB,QAAQ,CACtB,IAAI,EAAE,QAAQ,EACd,cAAc,EAAE,GAAG,EACnB,OAAO,EAAE,QAAQ,EACjB,UAAU,GAAE,UAAgC,GAC3C,OAAO,CAqBT;AAUD,wBAAgB,WAAW,CACzB,IAAI,EAAE,QAAQ,EACd,cAAc,EAAE,GAAG,EACnB,OAAO,EAAE,QAAQ,EACjB,UAAU,GAAE,UAAgC,GAC3C,OAAO,CAqBT;AASD,wBAAgB,OAAO,CACrB,IAAI,EAAE,QAAQ,EACd,MAAM,EAAE,GAAG,EACX,UAAU,GAAE,UAAgC,GAC3C,OAAO,CAsBT;AASD,wBAAgB,SAAS,CACvB,IAAI,EAAE,QAAQ,EACd,MAAM,EAAE,GAAG,EACX,UAAU,GAAE,UAAgC,GAC3C,OAAO,CAsBT;AASD,wBAAgB,QAAQ,CACtB,IAAI,EAAE,QAAQ,EACd,QAAQ,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,OAAO,EACrC,UAAU,GAAE,UAAgC,GAC3C,OAAO,CAaT;AASD,wBAAgB,SAAS,CACvB,IAAI,EAAE,QAAQ,EACd,QAAQ,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,OAAO,EACrC,UAAU,GAAE,UAAgC,GAC3C,OAAO,CAaT;AAUD,wBAAgB,MAAM,CACpB,IAAI,EAAE,QAAQ,EACd,QAAQ,EAAE,GAAG,EACb,SAAS,EAAE,MAAM,EACjB,UAAU,GAAE,UAAgC,GAC3C,QAAQ,GAAG,IAAI,CAqCjB;AASD,wBAAgB,WAAW,CACzB,IAAI,EAAE,QAAQ,EACd,QAAQ,EAAE,GAAG,EACb,UAAU,GAAE,UAAgC,GAC3C,MAAM,EAAE,GAAG,IAAI,CAsBjB;AASD,wBAAgB,aAAa,CAC3B,IAAI,EAAE,QAAQ,EACd,IAAI,EAAE,MAAM,EAAE,EACd,UAAU,GAAE,UAAgC,GAC3C,QAAQ,GAAG,IAAI,CA4BjB;AAQD,wBAAgB,eAAe,CAC7B,IAAI,EAAE,QAAQ,EACd,UAAU,GAAE,UAAgC,GAC3C,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAexB;AASD,wBAAgB,YAAY,CAC1B,IAAI,EAAE,QAAQ,EACd,QAAQ,EAAE,GAAG,EACb,UAAU,GAAE,UAAgC,GAC3C,MAAM,GAAG,IAAI,CAqBf;AASD,wBAAgB,SAAS,CACvB,IAAI,EAAE,QAAQ,EACd,GAAG,EAAE,MAAM,EACX,UAAU,GAAE,UAAgC,GAC3C,QAAQ,CA+BV;AASD,wBAAgB,UAAU,CACxB,IAAI,EAAE,QAAQ,EACd,QAAQ,EAAE,GAAG,EACb,UAAU,GAAE,UAAgC,GAC3C,OAAO,CAuBT;AAQD,wBAAgB,WAAW,CACzB,IAAI,EAAE,QAAQ,EACd,QAAQ,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,IAAI,EAClC,UAAU,GAAE,UAAgC,GAC3C,IAAI,CAYN;AAQD,wBAAgB,eAAe,CAC7B,IAAI,EAAE,QAAQ,EACd,UAAU,CAAC,EAAE,UAAU,GACtB,OAAO,CAIT;AAQD,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,GAAG,EACT,UAAU,GAAE,UAAgC,GAC3C,OAAO,CAsBT;AASD,wBAAgB,eAAe,CAC7B,IAAI,EAAE,QAAQ,EACd,QAAQ,EAAE,GAAG,EACb,UAAU,GAAE,UAAgC,GAC3C,QAAQ,EAAE,CAwBZ;AASD,wBAAgB,eAAe,CAC7B,IAAI,EAAE,QAAQ,EACd,QAAQ,EAAE,GAAG,EACb,UAAU,GAAE,UAAgC,GAC3C,QAAQ,EAAE,CAiCZ;AASD,wBAAgB,aAAa,CAC3B,IAAI,EAAE,QAAQ,EACd,QAAQ,EAAE,GAAG,EACb,UAAU,GAAE,UAAgC,GAC3C,QAAQ,GAAG,IAAI,CAqBjB;AASD,wBAAgB,YAAY,CAC1B,IAAI,EAAE,QAAQ,EACd,QAAQ,EAAE,GAAG,EACb,UAAU,GAAE,UAAgC,GAC3C,OAAO,CAaT;AAQD,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,GAAG,EACT,UAAU,GAAE,UAAgC,GAC3C,OAAO,CA8BT;AAQD,wBAAgB,UAAU,CACxB,IAAI,EAAE,GAAG,EACT,UAAU,GAAE,UAAgC,GAC3C,OAAO,CAcT;AAKD,QAAA,MAAM,aAAa
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/stats.html
CHANGED
|
@@ -4929,7 +4929,7 @@ var drawChart = (function (exports) {
|
|
|
4929
4929
|
</script>
|
|
4930
4930
|
<script>
|
|
4931
4931
|
/*<!--*/
|
|
4932
|
-
const data = {"version":2,"tree":{"name":"root","children":[{"name":"tree-processor.
|
|
4932
|
+
const data = {"version":2,"tree":{"name":"root","children":[{"name":"tree-processor.cjs.js","children":[{"name":"src/index.ts","uid":"7eca4295-1"}]}],"isRoot":true},"nodeParts":{"7eca4295-1":{"renderedLength":17081,"gzipLength":2155,"brotliLength":1901,"metaUid":"7eca4295-0"}},"nodeMetas":{"7eca4295-0":{"id":"\\src\\index.ts","moduleParts":{"tree-processor.cjs.js":"7eca4295-1"},"imported":[],"importedBy":[],"isEntry":true}},"env":{"rollup":"4.56.0"},"options":{"gzip":true,"brotli":true,"sourcemap":false}};
|
|
4933
4933
|
|
|
4934
4934
|
const run = () => {
|
|
4935
4935
|
const width = window.innerWidth;
|
|
@@ -1,88 +1,100 @@
|
|
|
1
1
|
"use strict"
|
|
2
2
|
Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})
|
|
3
3
|
const r={children:"children",id:"id"}
|
|
4
|
-
function
|
|
5
|
-
return function r(
|
|
6
|
-
const
|
|
7
|
-
Array.isArray(
|
|
8
|
-
return function r(
|
|
9
|
-
const u=
|
|
10
|
-
Array.isArray(u)&&u.length>0&&r(u,o)})}(
|
|
11
|
-
const
|
|
12
|
-
if(Array.isArray(
|
|
13
|
-
if(r)return r}}return null}function i(n,
|
|
14
|
-
const
|
|
15
|
-
if(Array.isArray(
|
|
16
|
-
const
|
|
17
|
-
if(Array.isArray(
|
|
18
|
-
return!!(Array.isArray(r)&&r.length>0)&&(r.pop(),!0)}const
|
|
19
|
-
if(Array.isArray(
|
|
20
|
-
return!!(Array.isArray(r)&&r.length>0)&&(r.shift(),!0)}const
|
|
21
|
-
if(Array.isArray(
|
|
22
|
-
const
|
|
23
|
-
if(Array.isArray(
|
|
24
|
-
const
|
|
25
|
-
if(Array.isArray(
|
|
26
|
-
const
|
|
27
|
-
if(Array.isArray(
|
|
28
|
-
if(
|
|
4
|
+
function e(e,n,t=r){const i=[]
|
|
5
|
+
return function r(e){for(const o of e){i.push(n(o))
|
|
6
|
+
const e=o[t.children]
|
|
7
|
+
Array.isArray(e)&&e.length>0&&r(e)}}(e),i}function n(e,n,t=r){const i=[]
|
|
8
|
+
return function r(e){e.forEach((e,o)=>{n(e,o)&&i.push(e)
|
|
9
|
+
const u=e[t.children]
|
|
10
|
+
Array.isArray(u)&&u.length>0&&r(u,o)})}(e),i}function t(e,n,i=r){for(const r of e){if(n(r))return r
|
|
11
|
+
const e=r[i.children]
|
|
12
|
+
if(Array.isArray(e)&&e.length>0){const r=t(e,n,i)
|
|
13
|
+
if(r)return r}}return null}function i(e,n,t,i=r){return function r(e){for(const o of e){if(o[i.id]===n)return o[i.children]||(o[i.children]=[]),o[i.children].push(t),!0
|
|
14
|
+
const e=o[i.children]
|
|
15
|
+
if(Array.isArray(e)&&e.length>0&&r(e))return!0}return!1}(e)}function o(e,n,t,i=r){return function r(e){for(const o of e){if(o[i.id]===n)return o[i.children]||(o[i.children]=[]),o[i.children].unshift(t),!0
|
|
16
|
+
const e=o[i.children]
|
|
17
|
+
if(Array.isArray(e)&&e.length>0&&r(e))return!0}return!1}(e)}function u(e,n,t=r){return function r(e){for(const i of e){if(i[t.id]===n){const r=i[t.children]
|
|
18
|
+
return!!(Array.isArray(r)&&r.length>0)&&(r.pop(),!0)}const e=i[t.children]
|
|
19
|
+
if(Array.isArray(e)&&e.length>0&&r(e))return!0}return!1}(e)}function s(e,n,t=r){return function r(e){for(const i of e){if(i[t.id]===n){const r=i[t.children]
|
|
20
|
+
return!!(Array.isArray(r)&&r.length>0)&&(r.shift(),!0)}const e=i[t.children]
|
|
21
|
+
if(Array.isArray(e)&&e.length>0&&r(e))return!0}return!1}(e)}function f(e,n,t=r){for(const r of e){if(n(r))return!0
|
|
22
|
+
const e=r[t.children]
|
|
23
|
+
if(Array.isArray(e)&&e.length>0&&f(e,n,t))return!0}return!1}function c(e,n,t=r){for(const r of e){if(!n(r))return!1
|
|
24
|
+
const e=r[t.children]
|
|
25
|
+
if(Array.isArray(e)&&e.length>0&&!c(e,n,t))return!1}return!0}function l(e,n,t,i=r){const o=function r(e){for(const t of e){if(t[i.id]===n)return t
|
|
26
|
+
const e=t[i.children]
|
|
27
|
+
if(Array.isArray(e)&&e.length>0){const n=r(e)
|
|
28
|
+
if(n)return n}}return null}(e)
|
|
29
29
|
if(!o)return null
|
|
30
30
|
const u=o[i.children]
|
|
31
31
|
if(!Array.isArray(u)||0===u.length)return null
|
|
32
32
|
const s=t>=0?t:u.length+t
|
|
33
|
-
return s>=0&&s<u.length?u[s]:null}function a(n,
|
|
34
|
-
if(u[t.id]===
|
|
35
|
-
const
|
|
36
|
-
if(Array.isArray(
|
|
37
|
-
if(
|
|
38
|
-
let i=
|
|
39
|
-
for(let r=0;r<
|
|
40
|
-
if(!Array.isArray(i)||
|
|
41
|
-
const o=i[
|
|
42
|
-
if(r===
|
|
33
|
+
return s>=0&&s<u.length?u[s]:null}function a(e,n,t=r){return function r(e,i=[]){for(let o=0;o<e.length;o++){const u=e[o],s=[...i,o]
|
|
34
|
+
if(u[t.id]===n)return s
|
|
35
|
+
const f=u[t.children]
|
|
36
|
+
if(Array.isArray(f)&&f.length>0){const e=r(f,s)
|
|
37
|
+
if(e)return e}}return null}(e)}function h(e,n,t=r){if(!Array.isArray(n)||0===n.length)return null
|
|
38
|
+
let i=e
|
|
39
|
+
for(let r=0;r<n.length;r++){const e=n[r]
|
|
40
|
+
if(!Array.isArray(i)||e<0||e>=i.length)return null
|
|
41
|
+
const o=i[e]
|
|
42
|
+
if(r===n.length-1)return o
|
|
43
43
|
const u=o[t.children]
|
|
44
44
|
if(!Array.isArray(u))return null
|
|
45
|
-
i=u}return null}function d(n
|
|
46
|
-
return function r(
|
|
47
|
-
const
|
|
48
|
-
Array.isArray(
|
|
49
|
-
const
|
|
50
|
-
if(Array.isArray(
|
|
51
|
-
if(null!==
|
|
52
|
-
return function r(
|
|
53
|
-
for(const u of
|
|
54
|
-
if(null!=
|
|
55
|
-
i.add(
|
|
56
|
-
Array.isArray(
|
|
57
|
-
if(o[t.id]===
|
|
45
|
+
i=u}return null}function d(e,n=r){const t={}
|
|
46
|
+
return function r(e,i=1){for(const o of e){t[o[n.id]]=i
|
|
47
|
+
const e=o[n.children]
|
|
48
|
+
Array.isArray(e)&&e.length>0&&r(e,i+1)}}(e),t}function y(e,n,t=r){return function r(e,i=1){for(const o of e){if(o[t.id]===n)return i
|
|
49
|
+
const e=o[t.children]
|
|
50
|
+
if(Array.isArray(e)&&e.length>0){const n=r(e,i+1)
|
|
51
|
+
if(null!==n)return n}}return null}(e)}function A(e,n,t=r){const i=new Set
|
|
52
|
+
return function r(e){const o=[]
|
|
53
|
+
for(const u of e){const e=u[n]
|
|
54
|
+
if(null!=e){if(i.has(e))continue
|
|
55
|
+
i.add(e)}const s={...u},f=u[t.children]
|
|
56
|
+
Array.isArray(f)&&f.length>0&&(s[t.children]=r(f)),o.push(s)}return o}(e)}function p(e,n,t=r){return function r(e){for(let i=0;i<e.length;i++){const o=e[i]
|
|
57
|
+
if(o[t.id]===n)return e.splice(i,1),!0
|
|
58
58
|
const u=o[t.children]
|
|
59
|
-
if(Array.isArray(u)&&u.length>0&&r(u))return!0}return!1}(
|
|
60
|
-
const
|
|
61
|
-
Array.isArray(
|
|
62
|
-
const t=n
|
|
63
|
-
return void 0===t||(!Array.isArray(t)||0===t.length)}function D(n,
|
|
64
|
-
const
|
|
65
|
-
if(Array.isArray(
|
|
66
|
-
if(null!==
|
|
59
|
+
if(Array.isArray(u)&&u.length>0&&r(u))return!0}return!1}(e)}function g(e,n,t=r){!function r(e){for(const i of e){n(i)
|
|
60
|
+
const e=i[t.children]
|
|
61
|
+
Array.isArray(e)&&e.length>0&&r(e)}}(e)}function T(r){return!Array.isArray(r)||0===r.length}function x(e,n=r){if(!v(e,n))return!0
|
|
62
|
+
const t=e[n.children]
|
|
63
|
+
return void 0===t||(!Array.isArray(t)||0===t.length)}function D(e,n,t=r){const i=function r(e){for(const i of e){if(i[t.id]===n)return i
|
|
64
|
+
const e=i[t.children]
|
|
65
|
+
if(Array.isArray(e)&&e.length>0){const n=r(e)
|
|
66
|
+
if(null!==n)return n}}return null}(e)
|
|
67
67
|
if(!i)return[]
|
|
68
68
|
const o=i[t.children]
|
|
69
|
-
return Array.isArray(o)?o:[]}function
|
|
70
|
-
const
|
|
71
|
-
if(Array.isArray(
|
|
72
|
-
if(null!==
|
|
69
|
+
return Array.isArray(o)?o:[]}function N(e,n,t=r){const i=function r(e,i=null){for(const o of e){if(o[t.id]===n)return{node:o,parent:i}
|
|
70
|
+
const e=o[t.children]
|
|
71
|
+
if(Array.isArray(e)&&e.length>0){const n=r(e,o)
|
|
72
|
+
if(null!==n)return n}}return null}(e)
|
|
73
73
|
if(!i)return[]
|
|
74
|
-
if(null===i.parent)return
|
|
74
|
+
if(null===i.parent)return e
|
|
75
75
|
const o=i.parent[t.children]
|
|
76
|
-
return Array.isArray(o)?o:[]}function S(n,
|
|
77
|
-
const
|
|
78
|
-
if(Array.isArray(
|
|
79
|
-
if(null!==
|
|
80
|
-
const
|
|
81
|
-
if(Array.isArray(
|
|
82
|
-
const t=n
|
|
76
|
+
return Array.isArray(o)?o:[]}function S(e,n,t=r){return function r(e,i=null){for(const o of e){if(o[t.id]===n)return i
|
|
77
|
+
const e=o[t.children]
|
|
78
|
+
if(Array.isArray(e)&&e.length>0){const n=r(e,o)
|
|
79
|
+
if(null!==n)return n}}return null}(e)}function m(e,n,t=r){for(const r of e){if(r[t.id]===n)return!0
|
|
80
|
+
const e=r[t.children]
|
|
81
|
+
if(Array.isArray(e)&&e.length>0&&m(e,n,t))return!0}return!1}function v(e,n=r){if(!e||"object"!=typeof e||Array.isArray(e))return!1
|
|
82
|
+
const t=e[n.children]
|
|
83
83
|
if(void 0!==t){if(null===t)return!1
|
|
84
84
|
if(!Array.isArray(t))return!1
|
|
85
|
-
for(const r of t)if(!
|
|
86
|
-
for(const r of
|
|
87
|
-
return!0}
|
|
88
|
-
|
|
85
|
+
for(const r of t)if(!v(r,n))return!1}return!0}function b(e,n=r){if(!Array.isArray(e))return!1
|
|
86
|
+
for(const r of e)if(!v(r,n))return!1
|
|
87
|
+
return!0}function E(e,n=r){if(!e||"object"!=typeof e||Array.isArray(e))return!1
|
|
88
|
+
const t=e[n.children]
|
|
89
|
+
return void 0===t||Array.isArray(t)}function C(e,n=r,t=new WeakSet){if(!e||"object"!=typeof e||Array.isArray(e))return!1
|
|
90
|
+
if(t.has(e))return!1
|
|
91
|
+
t.add(e)
|
|
92
|
+
const i=e[n.children]
|
|
93
|
+
if(void 0!==i){if(null===i)return!1
|
|
94
|
+
if(!Array.isArray(i))return!1
|
|
95
|
+
for(const r of i)if(!C(r,n,t))return!1}return!0}function O(e,n,t=r){if(n<=0)return!1
|
|
96
|
+
return function r(e,i){if(i>n)return!1
|
|
97
|
+
for(const n of e){const e=n[t.children]
|
|
98
|
+
if(Array.isArray(e)&&e.length>0&&!r(e,i+1))return!1}return!0}(e,1)}function j(e,n=r){const t=e[n.children]
|
|
99
|
+
return void 0===t||!Array.isArray(t)||0===t.length}function M(e,n,t=r){return!!m(e,n,t)&&null===S(e,n,t)}const k={mapTree:e,filterTree:n,findTree:t,pushTree:i,unshiftTree:o,popTree:u,shiftTree:s,someTree:f,everyTree:c,atTree:l,indexOfTree:a,atIndexOfTree:h,getNodeDepthMap:d,getNodeDepth:y,dedupTree:A,removeTree:p,forEachTree:g,isEmptyTreeData:T,isEmptySingleTreeData:x,getParentTree:S,getChildrenTree:D,getSiblingsTree:N,includesTree:m,isSingleTreeData:v,isTreeData:b,isValidTreeNode:E,isTreeNodeWithCircularCheck:C,isSafeTreeDepth:O,isLeafNode:j,isRootNode:M}
|
|
100
|
+
exports.atIndexOfTree=h,exports.atTree=l,exports.dedupTree=A,exports.default=k,exports.everyTree=c,exports.filterTree=n,exports.findTree=t,exports.forEachTree=g,exports.getChildrenTree=D,exports.getNodeDepth=y,exports.getNodeDepthMap=d,exports.getParentTree=S,exports.getSiblingsTree=N,exports.includesTree=m,exports.indexOfTree=a,exports.isEmptySingleTreeData=x,exports.isEmptyTreeData=T,exports.isLeafNode=j,exports.isRootNode=M,exports.isSafeTreeDepth=O,exports.isSingleTreeData=v,exports.isTreeData=b,exports.isTreeNodeWithCircularCheck=C,exports.isValidTreeNode=E,exports.mapTree=e,exports.popTree=u,exports.pushTree=i,exports.removeTree=p,exports.shiftTree=s,exports.someTree=f,exports.unshiftTree=o
|
|
@@ -56,31 +56,43 @@ if(o[e.id]===t)return n.splice(i,1),!0
|
|
|
56
56
|
const u=o[e.children]
|
|
57
57
|
if(Array.isArray(u)&&u.length>0&&r(u))return!0}return!1}(n)}function T(n,t,e=r){!function r(n){for(const i of n){t(i)
|
|
58
58
|
const n=i[e.children]
|
|
59
|
-
Array.isArray(n)&&n.length>0&&r(n)}}(n)}function p(r){return!Array.isArray(r)||0===r.length}function
|
|
59
|
+
Array.isArray(n)&&n.length>0&&r(n)}}(n)}function p(r){return!Array.isArray(r)||0===r.length}function v(n,t=r){if(!b(n,t))return!0
|
|
60
60
|
const e=n[t.children]
|
|
61
|
-
return void 0===e||(!Array.isArray(e)||0===e.length)}function
|
|
61
|
+
return void 0===e||(!Array.isArray(e)||0===e.length)}function D(n,t,e=r){const i=function r(n){for(const i of n){if(i[e.id]===t)return i
|
|
62
62
|
const n=i[e.children]
|
|
63
63
|
if(Array.isArray(n)&&n.length>0){const t=r(n)
|
|
64
64
|
if(null!==t)return t}}return null}(n)
|
|
65
65
|
if(!i)return[]
|
|
66
66
|
const o=i[e.children]
|
|
67
|
-
return Array.isArray(o)?o:[]}function
|
|
67
|
+
return Array.isArray(o)?o:[]}function N(n,t,e=r){const i=function r(n,i=null){for(const o of n){if(o[e.id]===t)return{node:o,parent:i}
|
|
68
68
|
const n=o[e.children]
|
|
69
69
|
if(Array.isArray(n)&&n.length>0){const t=r(n,o)
|
|
70
70
|
if(null!==t)return t}}return null}(n)
|
|
71
71
|
if(!i)return[]
|
|
72
72
|
if(null===i.parent)return n
|
|
73
73
|
const o=i.parent[e.children]
|
|
74
|
-
return Array.isArray(o)?o:[]}function
|
|
74
|
+
return Array.isArray(o)?o:[]}function S(n,t,e=r){return function r(n,i=null){for(const o of n){if(o[e.id]===t)return i
|
|
75
75
|
const n=o[e.children]
|
|
76
76
|
if(Array.isArray(n)&&n.length>0){const t=r(n,o)
|
|
77
|
-
if(null!==t)return t}}return null}(n)}function
|
|
77
|
+
if(null!==t)return t}}return null}(n)}function m(n,t,e=r){for(const r of n){if(r[e.id]===t)return!0
|
|
78
78
|
const n=r[e.children]
|
|
79
|
-
if(Array.isArray(n)&&n.length>0&&
|
|
79
|
+
if(Array.isArray(n)&&n.length>0&&m(n,t,e))return!0}return!1}function b(n,t=r){if(!n||"object"!=typeof n||Array.isArray(n))return!1
|
|
80
80
|
const e=n[t.children]
|
|
81
81
|
if(void 0!==e){if(null===e)return!1
|
|
82
82
|
if(!Array.isArray(e))return!1
|
|
83
|
-
for(const r of e)if(!
|
|
84
|
-
for(const r of n)if(!
|
|
85
|
-
return!0}
|
|
86
|
-
|
|
83
|
+
for(const r of e)if(!b(r,t))return!1}return!0}function E(n,t=r){if(!Array.isArray(n))return!1
|
|
84
|
+
for(const r of n)if(!b(r,t))return!1
|
|
85
|
+
return!0}function j(n,t=r){if(!n||"object"!=typeof n||Array.isArray(n))return!1
|
|
86
|
+
const e=n[t.children]
|
|
87
|
+
return void 0===e||Array.isArray(e)}function x(n,t=r,e=new WeakSet){if(!n||"object"!=typeof n||Array.isArray(n))return!1
|
|
88
|
+
if(e.has(n))return!1
|
|
89
|
+
e.add(n)
|
|
90
|
+
const i=n[t.children]
|
|
91
|
+
if(void 0!==i){if(null===i)return!1
|
|
92
|
+
if(!Array.isArray(i))return!1
|
|
93
|
+
for(const r of i)if(!x(r,t,e))return!1}return!0}function C(n,t,e=r){if(t<=0)return!1
|
|
94
|
+
return function r(n,i){if(i>t)return!1
|
|
95
|
+
for(const t of n){const n=t[e.children]
|
|
96
|
+
if(Array.isArray(n)&&n.length>0&&!r(n,i+1))return!1}return!0}(n,1)}function k(n,t=r){const e=n[t.children]
|
|
97
|
+
return void 0===e||!Array.isArray(e)||0===e.length}function w(n,t,e=r){return!!m(n,t,e)&&null===S(n,t,e)}const O={mapTree:n,filterTree:t,findTree:e,pushTree:i,unshiftTree:o,popTree:u,shiftTree:c,someTree:f,everyTree:l,atTree:s,indexOfTree:a,atIndexOfTree:h,getNodeDepthMap:y,getNodeDepth:d,dedupTree:A,removeTree:g,forEachTree:T,isEmptyTreeData:p,isEmptySingleTreeData:v,getParentTree:S,getChildrenTree:D,getSiblingsTree:N,includesTree:m,isSingleTreeData:b,isTreeData:E,isValidTreeNode:j,isTreeNodeWithCircularCheck:x,isSafeTreeDepth:C,isLeafNode:k,isRootNode:w}
|
|
98
|
+
export{h as atIndexOfTree,s as atTree,A as dedupTree,O as default,l as everyTree,t as filterTree,e as findTree,T as forEachTree,D as getChildrenTree,d as getNodeDepth,y as getNodeDepthMap,S as getParentTree,N as getSiblingsTree,m as includesTree,a as indexOfTree,v as isEmptySingleTreeData,p as isEmptyTreeData,k as isLeafNode,w as isRootNode,C as isSafeTreeDepth,b as isSingleTreeData,E as isTreeData,x as isTreeNodeWithCircularCheck,j as isValidTreeNode,n as mapTree,u as popTree,i as pushTree,g as removeTree,c as shiftTree,f as someTree,o as unshiftTree}
|
|
@@ -5,67 +5,67 @@ return function r(n){for(const o of n){i.push(e(o))
|
|
|
5
5
|
const n=o[t.children]
|
|
6
6
|
Array.isArray(n)&&n.length>0&&r(n)}}(r),i}function t(r,e,t=n){const i=[]
|
|
7
7
|
return function r(n){n.forEach((n,o)=>{e(n,o)&&i.push(n)
|
|
8
|
-
const
|
|
9
|
-
Array.isArray(
|
|
8
|
+
const f=n[t.children]
|
|
9
|
+
Array.isArray(f)&&f.length>0&&r(f,o)})}(r),i}function i(r,e,t=n){for(const n of r){if(e(n))return n
|
|
10
10
|
const r=n[t.children]
|
|
11
11
|
if(Array.isArray(r)&&r.length>0){const n=i(r,e,t)
|
|
12
12
|
if(n)return n}}return null}function o(r,e,t,i=n){return function r(n){for(const o of n){if(o[i.id]===e)return o[i.children]||(o[i.children]=[]),o[i.children].push(t),!0
|
|
13
13
|
const n=o[i.children]
|
|
14
|
-
if(Array.isArray(n)&&n.length>0&&r(n))return!0}return!1}(r)}function
|
|
14
|
+
if(Array.isArray(n)&&n.length>0&&r(n))return!0}return!1}(r)}function f(r,e,t,i=n){return function r(n){for(const o of n){if(o[i.id]===e)return o[i.children]||(o[i.children]=[]),o[i.children].unshift(t),!0
|
|
15
15
|
const n=o[i.children]
|
|
16
|
-
if(Array.isArray(n)&&n.length>0&&r(n))return!0}return!1}(r)}function
|
|
16
|
+
if(Array.isArray(n)&&n.length>0&&r(n))return!0}return!1}(r)}function u(r,e,t=n){return function r(n){for(const i of n){if(i[t.id]===e){const r=i[t.children]
|
|
17
17
|
return!!(Array.isArray(r)&&r.length>0)&&(r.pop(),!0)}const n=i[t.children]
|
|
18
18
|
if(Array.isArray(n)&&n.length>0&&r(n))return!0}return!1}(r)}function c(r,e,t=n){return function r(n){for(const i of n){if(i[t.id]===e){const r=i[t.children]
|
|
19
19
|
return!!(Array.isArray(r)&&r.length>0)&&(r.shift(),!0)}const n=i[t.children]
|
|
20
|
-
if(Array.isArray(n)&&n.length>0&&r(n))return!0}return!1}(r)}function
|
|
20
|
+
if(Array.isArray(n)&&n.length>0&&r(n))return!0}return!1}(r)}function s(r,e,t=n){for(const n of r){if(e(n))return!0
|
|
21
21
|
const r=n[t.children]
|
|
22
|
-
if(Array.isArray(r)&&r.length>0&&
|
|
22
|
+
if(Array.isArray(r)&&r.length>0&&s(r,e,t))return!0}return!1}function l(r,e,t=n){for(const n of r){if(!e(n))return!1
|
|
23
23
|
const r=n[t.children]
|
|
24
|
-
if(Array.isArray(r)&&r.length>0&&!
|
|
24
|
+
if(Array.isArray(r)&&r.length>0&&!l(r,e,t))return!1}return!0}function a(r,e,t,i=n){const o=function r(n){for(const t of n){if(t[i.id]===e)return t
|
|
25
25
|
const n=t[i.children]
|
|
26
26
|
if(Array.isArray(n)&&n.length>0){const e=r(n)
|
|
27
27
|
if(e)return e}}return null}(r)
|
|
28
28
|
if(!o)return null
|
|
29
|
-
const
|
|
30
|
-
if(!Array.isArray(
|
|
31
|
-
const
|
|
32
|
-
return
|
|
33
|
-
if(
|
|
34
|
-
const c=
|
|
35
|
-
if(Array.isArray(c)&&c.length>0){const n=r(c,
|
|
29
|
+
const f=o[i.children]
|
|
30
|
+
if(!Array.isArray(f)||0===f.length)return null
|
|
31
|
+
const u=t>=0?t:f.length+t
|
|
32
|
+
return u>=0&&u<f.length?f[u]:null}function h(r,e,t=n){return function r(n,i=[]){for(let o=0;o<n.length;o++){const f=n[o],u=[...i,o]
|
|
33
|
+
if(f[t.id]===e)return u
|
|
34
|
+
const c=f[t.children]
|
|
35
|
+
if(Array.isArray(c)&&c.length>0){const n=r(c,u)
|
|
36
36
|
if(n)return n}}return null}(r)}function d(r,e,t=n){if(!Array.isArray(e)||0===e.length)return null
|
|
37
37
|
let i=r
|
|
38
38
|
for(let r=0;r<e.length;r++){const n=e[r]
|
|
39
39
|
if(!Array.isArray(i)||n<0||n>=i.length)return null
|
|
40
40
|
const o=i[n]
|
|
41
41
|
if(r===e.length-1)return o
|
|
42
|
-
const
|
|
43
|
-
if(!Array.isArray(
|
|
44
|
-
i=
|
|
42
|
+
const f=o[t.children]
|
|
43
|
+
if(!Array.isArray(f))return null
|
|
44
|
+
i=f}return null}function y(r,e=n){const t={}
|
|
45
45
|
return function r(n,i=1){for(const o of n){t[o[e.id]]=i
|
|
46
46
|
const n=o[e.children]
|
|
47
47
|
Array.isArray(n)&&n.length>0&&r(n,i+1)}}(r),t}function A(r,e,t=n){return function r(n,i=1){for(const o of n){if(o[t.id]===e)return i
|
|
48
48
|
const n=o[t.children]
|
|
49
49
|
if(Array.isArray(n)&&n.length>0){const e=r(n,i+1)
|
|
50
|
-
if(null!==e)return e}}return null}(r)}function
|
|
50
|
+
if(null!==e)return e}}return null}(r)}function T(r,e,t=n){const i=new Set
|
|
51
51
|
return function r(n){const o=[]
|
|
52
|
-
for(const
|
|
52
|
+
for(const f of n){const n=f[e]
|
|
53
53
|
if(null!=n){if(i.has(n))continue
|
|
54
|
-
i.add(n)}const
|
|
55
|
-
Array.isArray(c)&&c.length>0&&(
|
|
54
|
+
i.add(n)}const u={...f},c=f[t.children]
|
|
55
|
+
Array.isArray(c)&&c.length>0&&(u[t.children]=r(c)),o.push(u)}return o}(r)}function g(r,e,t=n){return function r(n){for(let i=0;i<n.length;i++){const o=n[i]
|
|
56
56
|
if(o[t.id]===e)return n.splice(i,1),!0
|
|
57
|
-
const
|
|
58
|
-
if(Array.isArray(
|
|
57
|
+
const f=o[t.children]
|
|
58
|
+
if(Array.isArray(f)&&f.length>0&&r(f))return!0}return!1}(r)}function p(r,e,t=n){!function r(n){for(const i of n){e(i)
|
|
59
59
|
const n=i[t.children]
|
|
60
|
-
Array.isArray(n)&&n.length>0&&r(n)}}(r)}function
|
|
60
|
+
Array.isArray(n)&&n.length>0&&r(n)}}(r)}function D(r){return!Array.isArray(r)||0===r.length}function m(r,e=n){if(!x(r,e))return!0
|
|
61
61
|
const t=r[e.children]
|
|
62
|
-
return void 0===t||(!Array.isArray(t)||0===t.length)}function
|
|
62
|
+
return void 0===t||(!Array.isArray(t)||0===t.length)}function N(r,e,t=n){const i=function r(n){for(const i of n){if(i[t.id]===e)return i
|
|
63
63
|
const n=i[t.children]
|
|
64
64
|
if(Array.isArray(n)&&n.length>0){const e=r(n)
|
|
65
65
|
if(null!==e)return e}}return null}(r)
|
|
66
66
|
if(!i)return[]
|
|
67
67
|
const o=i[t.children]
|
|
68
|
-
return Array.isArray(o)?o:[]}function
|
|
68
|
+
return Array.isArray(o)?o:[]}function S(r,e,t=n){const i=function r(n,i=null){for(const o of n){if(o[t.id]===e)return{node:o,parent:i}
|
|
69
69
|
const n=o[t.children]
|
|
70
70
|
if(Array.isArray(n)&&n.length>0){const e=r(n,o)
|
|
71
71
|
if(null!==e)return e}}return null}(r)
|
|
@@ -75,13 +75,25 @@ const o=i.parent[t.children]
|
|
|
75
75
|
return Array.isArray(o)?o:[]}function v(r,e,t=n){return function r(n,i=null){for(const o of n){if(o[t.id]===e)return i
|
|
76
76
|
const n=o[t.children]
|
|
77
77
|
if(Array.isArray(n)&&n.length>0){const e=r(n,o)
|
|
78
|
-
if(null!==e)return e}}return null}(r)}function
|
|
78
|
+
if(null!==e)return e}}return null}(r)}function b(r,e,t=n){for(const n of r){if(n[t.id]===e)return!0
|
|
79
79
|
const r=n[t.children]
|
|
80
|
-
if(Array.isArray(r)&&r.length>0&&
|
|
80
|
+
if(Array.isArray(r)&&r.length>0&&b(r,e,t))return!0}return!1}function x(r,e=n){if(!r||"object"!=typeof r||Array.isArray(r))return!1
|
|
81
81
|
const t=r[e.children]
|
|
82
82
|
if(void 0!==t){if(null===t)return!1
|
|
83
83
|
if(!Array.isArray(t))return!1
|
|
84
|
-
for(const r of t)if(!
|
|
85
|
-
for(const n of r)if(!
|
|
86
|
-
return!0}
|
|
87
|
-
|
|
84
|
+
for(const r of t)if(!x(r,e))return!1}return!0}function E(r,e=n){if(!Array.isArray(r))return!1
|
|
85
|
+
for(const n of r)if(!x(n,e))return!1
|
|
86
|
+
return!0}function C(r,e=n){if(!r||"object"!=typeof r||Array.isArray(r))return!1
|
|
87
|
+
const t=r[e.children]
|
|
88
|
+
return void 0===t||Array.isArray(t)}function j(r,e=n,t=new WeakSet){if(!r||"object"!=typeof r||Array.isArray(r))return!1
|
|
89
|
+
if(t.has(r))return!1
|
|
90
|
+
t.add(r)
|
|
91
|
+
const i=r[e.children]
|
|
92
|
+
if(void 0!==i){if(null===i)return!1
|
|
93
|
+
if(!Array.isArray(i))return!1
|
|
94
|
+
for(const r of i)if(!j(r,e,t))return!1}return!0}function O(r,e,t=n){if(e<=0)return!1
|
|
95
|
+
return function r(n,i){if(i>e)return!1
|
|
96
|
+
for(const e of n){const n=e[t.children]
|
|
97
|
+
if(Array.isArray(n)&&n.length>0&&!r(n,i+1))return!1}return!0}(r,1)}function M(r,e=n){const t=r[e.children]
|
|
98
|
+
return void 0===t||!Array.isArray(t)||0===t.length}function P(r,e,t=n){return!!b(r,e,t)&&null===v(r,e,t)}const k={mapTree:e,filterTree:t,findTree:i,pushTree:o,unshiftTree:f,popTree:u,shiftTree:c,someTree:s,everyTree:l,atTree:a,indexOfTree:h,atIndexOfTree:d,getNodeDepthMap:y,getNodeDepth:A,dedupTree:T,removeTree:g,forEachTree:p,isEmptyTreeData:D,isEmptySingleTreeData:m,getParentTree:v,getChildrenTree:N,getSiblingsTree:S,includesTree:b,isSingleTreeData:x,isTreeData:E,isValidTreeNode:C,isTreeNodeWithCircularCheck:j,isSafeTreeDepth:O,isLeafNode:M,isRootNode:P}
|
|
99
|
+
r.atIndexOfTree=d,r.atTree=a,r.dedupTree=T,r.default=k,r.everyTree=l,r.filterTree=t,r.findTree=i,r.forEachTree=p,r.getChildrenTree=N,r.getNodeDepth=A,r.getNodeDepthMap=y,r.getParentTree=v,r.getSiblingsTree=S,r.includesTree=b,r.indexOfTree=h,r.isEmptySingleTreeData=m,r.isEmptyTreeData=D,r.isLeafNode=M,r.isRootNode=P,r.isSafeTreeDepth=O,r.isSingleTreeData=x,r.isTreeData=E,r.isTreeNodeWithCircularCheck=j,r.isValidTreeNode=C,r.mapTree=e,r.popTree=u,r.pushTree=o,r.removeTree=g,r.shiftTree=c,r.someTree=s,r.unshiftTree=f,Object.defineProperties(r,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})})
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tree-processor",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.1",
|
|
4
4
|
"description": "A lightweight TypeScript library for processing tree-structured data with comprehensive methods (map, filter, find, push, pop, remove, getParent, includes, etc.), supporting tree-shaking and custom field names",
|
|
5
5
|
"main": "dist/tree-processor.cjs.js",
|
|
6
6
|
"module": "dist/tree-processor.esm.js",
|
|
@@ -42,7 +42,16 @@
|
|
|
42
42
|
"every",
|
|
43
43
|
"at",
|
|
44
44
|
"indexOf",
|
|
45
|
+
"depth",
|
|
45
46
|
"deduplicate",
|
|
47
|
+
"menu",
|
|
48
|
+
"navigation",
|
|
49
|
+
"file-tree",
|
|
50
|
+
"directory",
|
|
51
|
+
"category",
|
|
52
|
+
"comment",
|
|
53
|
+
"permission",
|
|
54
|
+
"tree-select",
|
|
46
55
|
"tree-processor"
|
|
47
56
|
],
|
|
48
57
|
"author": "",
|