tree-processor 0.8.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.
Files changed (2) hide show
  1. package/README.md +247 -123
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,30 +1,104 @@
1
1
  # tree-processor
2
2
 
3
- 一个轻量级的树结构数据处理工具库,使用 TypeScript 编写,支持 tree-shaking,每个格式打包体积约 **3-4 KB**(ESM: 3.25 KB,CJS: 3.42 KB,UMD: 3.56 KB)。
4
-
5
- 目前已支持 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 的属性名。
3
+ <div align="center">
4
+
5
+ ![npm version](https://img.shields.io/npm/v/tree-processor?style=flat-square)
6
+ ![npm downloads](https://img.shields.io/npm/dm/tree-processor?style=flat-square)
7
+ ![bundle size](https://img.shields.io/badge/bundle-6.6KB-blue?style=flat-square)
8
+ ![TypeScript](https://img.shields.io/badge/TypeScript-5.7-blue?style=flat-square)
9
+ ![License](https://img.shields.io/badge/license-MIT-green?style=flat-square)
10
+ ![test coverage](https://img.shields.io/badge/coverage-272%20tests-brightgreen?style=flat-square)
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
- - 🚀 **轻量级** - 每个格式约 3-4 KB(ESM: 3.25 KB,CJS: 3.42 KB,UMD: 3.56 KB
10
- - 📦 **支持 Tree-shaking** - 按需导入,只打包使用的代码
11
- - 🔧 **TypeScript 支持** - 完整的类型定义和类型提示
12
- - 🎯 **类似数组 API** - 提供 map、filter、find 等熟悉的数组方法
13
- - ⚙️ **自定义字段名** - 支持自定义 children 和 id 字段名
14
- - **零依赖** - 无外部依赖,开箱即用
15
- - 🧪 **完善的测试覆盖** - 包含 272 个测试用例,覆盖基础功能、边界情况、异常处理、复杂场景、npm 包导入等
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
- npm i tree-processor
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
- ### mapTree(遍历树结构数据的方法)
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(树结构数据的filter方法)
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
- ### findTree(树结构数据的find方法)
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
- ### pushTree(在指定节点下添加子节点到末尾)
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(根据父节点ID和子节点索引获取节点)
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
- ### dedupTree(树结构对象数组去重方法)
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
- ### removeTree(删除指定节点)
404
+ ---
335
405
 
336
- 删除树结构数据中指定ID的节点,包括根节点和子节点。
406
+ ## 判断方法
407
+
408
+ ### someTree
409
+
410
+ 检查树结构数据中是否存在满足条件的节点。只要有一个节点满足条件就返回 true。
337
411
 
338
412
  ```javascript
339
- const nodeIdToRemove = 2
340
- const removeSuccess = t.removeTree(treeData, nodeIdToRemove)
413
+ // 检查是否存在名称为 'node2' 的节点
414
+ const hasNode2 = t.someTree(treeData, node => node.name === 'node2')
415
+ console.log(hasNode2) // true
341
416
 
342
- console.log(removeSuccess) // true 表示删除成功,false 表示未找到节点
343
- console.log(treeData) // 删除后的树结构
417
+ // 检查是否存在ID大于10的节点
418
+ const hasLargeId = t.someTree(treeData, node => node.id > 10)
419
+ console.log(hasLargeId) // false
344
420
  ```
345
421
 
346
- ### getParentTree(获取节点的父节点)
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
- ### getNodeDepthMap(返回节点ID到深度的映射)
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,7 @@ console.log(depth) // 2
490
584
  - `getNodeDepthMap` - 批量获取所有节点的深度(一次性计算所有节点)
491
585
  - `getNodeDepth` - 只获取单个节点的深度(只计算目标节点,效率更高)
492
586
 
493
- ### isLeafNode(检查节点是否是叶子节点)
587
+ ### isLeafNode
494
588
 
495
589
  检查节点是否是叶子节点(没有子节点)。轻量级方法,只检查节点本身,不遍历树。
496
590
 
@@ -536,7 +630,7 @@ console.log(t.isLeafNode(customNode, fieldNames)) // true
536
630
  - `isLeafNode` - 只检查单个节点,轻量级(O(1)),适合在遍历时使用
537
631
  - `getChildrenTree` - 获取子节点数组,需要传入 tree 和 nodeId,需要查找节点(O(n))
538
632
 
539
- ### isRootNode(检查节点是否是根节点)
633
+ ### isRootNode
540
634
 
541
635
  检查节点是否是根节点(没有父节点)。根节点是树结构数据数组中的顶层节点。
542
636
 
@@ -590,7 +684,7 @@ console.log(t.isRootNode(treeData, 999)) // false
590
684
  - `getParentTree` - 返回父节点对象,需要判断是否为 null
591
685
  - `getNodeDepth` - 返回深度,需要判断是否等于 1
592
686
 
593
- ### isEmptyTreeData(检查树结构数据是否为空)
687
+ ### isEmptyTreeData
594
688
 
595
689
  检查树结构数据(数组)是否为空。空数组、null、undefined 都视为空。此函数支持 fieldNames 参数以保持 API 一致性,但该参数不生效(因为只检查数组是否为空,不访问 children 或 id 字段)。
596
690
 
@@ -613,7 +707,7 @@ const isEmptyWithFieldNames = t.isEmptyTreeData(treeData, fieldNames)
613
707
  console.log(isEmptyWithFieldNames) // false(结果与不传 fieldNames 相同)
614
708
  ```
615
709
 
616
- ### isEmptySingleTreeData(检查单个树结构数据是否为空)
710
+ ### isEmptySingleTreeData
617
711
 
618
712
  检查单个树结构数据是否为空。如果数据不是有效的单个树结构数据、没有 children 字段,或者 children 是空数组,则视为空。如果有子节点(children 数组不为空),即使子节点本身是空的,树也不为空。
619
713
 
@@ -666,7 +760,7 @@ const isEmptyCustom = t.isEmptySingleTreeData(customTree, fieldNames)
666
760
  console.log(isEmptyCustom) // true
667
761
  ```
668
762
 
669
- ### isTreeData(判断数据是否是树结构数据)
763
+ ### isTreeData
670
764
 
671
765
  判断数据是否是树结构数据(数组)。树结构数据必须是一个数组,数组中的每个元素都必须是有效的单个树结构数据。
672
766
 
@@ -715,7 +809,7 @@ const fieldNames = { children: 'subNodes', id: 'nodeId' };
715
809
  console.log(t.isTreeData(customForest, fieldNames)) // true
716
810
  ```
717
811
 
718
- ### isSingleTreeData(判断数据是否是单个树结构数据)
812
+ ### isSingleTreeData
719
813
 
720
814
  判断数据是否是单个树结构数据(单个对象)。树结构数据必须是一个对象(不能是数组、null、undefined 或基本类型),如果存在 children 字段,必须是数组类型,并且会递归检查所有子节点。
721
815
 
@@ -757,7 +851,7 @@ const fieldNames = { children: 'subNodes', id: 'nodeId' };
757
851
  console.log(t.isSingleTreeData(customTree, fieldNames)) // true
758
852
  ```
759
853
 
760
- ### isValidTreeNode(检查单个节点是否是有效的树节点结构)
854
+ ### isValidTreeNode
761
855
 
762
856
  检查单个节点是否是有效的树节点结构(轻量级,不递归检查子节点)。只检查节点本身的结构,不检查子节点。
763
857
 
@@ -794,7 +888,7 @@ console.log(t.isValidTreeNode(customNode, fieldNames)) // true
794
888
  - `isValidTreeNode` - 只检查单个节点的基本结构,不递归检查子节点(轻量级)
795
889
  - `isSingleTreeData` - 递归检查整个树结构,确保所有子节点都是有效的树结构
796
890
 
797
- ### isTreeNodeWithCircularCheck(检查节点结构并检测循环引用)
891
+ ### isTreeNodeWithCircularCheck
798
892
 
799
893
  检查节点是否是有效的树节点结构,并检测循环引用。使用 WeakSet 跟踪已访问的节点,如果发现循环引用则返回 false。
800
894
 
@@ -834,7 +928,7 @@ console.log(t.isTreeNodeWithCircularCheck(customNode, fieldNames)) // true
834
928
  - 数据验证,防止无限递归
835
929
  - 调试时检查数据结构是否正确
836
930
 
837
- ### isSafeTreeDepth(检查树深度是否安全)
931
+ ### isSafeTreeDepth
838
932
 
839
933
  检查树结构数据的深度是否安全(防止递归爆栈)。如果树的深度超过 `maxDepth`,返回 false。
840
934
 
@@ -937,6 +1031,36 @@ npm run build
937
1031
  - **Terser** - JavaScript 压缩工具
938
1032
  - **TypeScript** - 类型支持
939
1033
 
940
- ## License
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)
941
1065
 
942
- MIT
1066
+ </div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tree-processor",
3
- "version": "0.8.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",