Skip to content

Commit

Permalink
feat: added tree package (#38)
Browse files Browse the repository at this point in the history
  • Loading branch information
vtrbo authored Oct 26, 2023
1 parent c4b3258 commit c21af0b
Show file tree
Hide file tree
Showing 7 changed files with 184 additions and 1 deletion.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@
"@vtrbo/utils-log": "workspace:*",
"@vtrbo/utils-obj": "workspace:*",
"@vtrbo/utils-str": "workspace:*",
"@vtrbo/utils-tool": "workspace:*"
"@vtrbo/utils-tool": "workspace:*",
"@vtrbo/utils-tree": "workspace:*"
},
"devDependencies": {
"@antfu/eslint-config": "1.0.0-beta.26",
Expand Down
1 change: 1 addition & 0 deletions packages/core/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ export * from '@vtrbo/utils-obj'
export * from '@vtrbo/utils-arr'
export * from '@vtrbo/utils-str'
export * from '@vtrbo/utils-color'
export * from '@vtrbo/utils-tree'
1 change: 1 addition & 0 deletions packages/tree/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './src/tree'
56 changes: 56 additions & 0 deletions packages/tree/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
{
"name": "@vtrbo/utils-tree",
"type": "module",
"version": "0.4.0-beta.4",
"description": "Collection of common JavaScript or TypeScript utils.",
"author": {
"name": "Victor Bo",
"email": "hi@vtrbo.cn"
},
"license": "MIT",
"homepage": "https://github.com/vtrbo",
"bugs": "https://github.com/vtrbo/utils/issues",
"keywords": [
"typescript",
"javascript",
"utils",
"vue",
"react",
"svelte",
"vite"
],
"exports": {
".": {
"types": "./index.d.ts",
"import": "./index.js",
"require": "./index.cjs"
}
},
"main": "./index.js",
"module": "./index.js",
"types": "./index.d.ts",
"typesVersions": {
"*": {
"*": [
"./*",
"./index.d.ts"
]
}
},
"files": [
"README.md",
"index.cjs",
"index.d.cts",
"index.d.ts",
"index.js"
],
"scripts": {
"build": "tsup",
"clean": "pnpm clean:dist && pnpm clean:deps",
"clean:dist": "rimraf dist",
"clean:deps": "rimraf node_modules"
},
"dependencies": {
"@vtrbo/utils-tool": "workspace:*"
}
}
106 changes: 106 additions & 0 deletions packages/tree/src/tree.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
export function treeToList<T>(tree: T[], options?: {
children?: string
}): T[] {
const tOption = Object.assign({
children: 'children',
}, options || {})

const { children } = tOption

const list: T[] = [...tree]
for (let i = 0; i < list.length; i++) {
const node: T = list[i]
if (!(node as any)[children])
continue
list.splice(i + 1, 0, ...(treeToList((node as any)[children]) as any))
}

return list
}

export function treeFilter<T>(tree: T[], callback: (node: T) => boolean, options?: {
children?: string
}): T[] {
const tOption = Object.assign({
children: 'children',
}, options || {})

const { children } = tOption

return tree.map(node => ({ ...node })).filter((node) => {
if (callback(node))
return node

if ((node as any)[children] && Array.isArray((node as any)[children]) && (node as any)[children].length)
(node as any)[children] = treeFilter((node as any)[children], callback, tOption)
else
(node as any)[children] = []

return callback(node) || (node as any)[children].length
})
}

export function findPaths<T>(tree: T[], callback: (node: T) => boolean, options?: {
children?: string
findAll?: boolean
}): Array<T[]> {
const tOption = Object.assign({
children: 'children',
findAll: false,
}, options || {})

const { children, findAll } = tOption

const list: T[] = [...tree]
const path: T[] = []
const paths: Array<T[]> = []
const records: Set<T> = new Set()

while (list.length) {
const node: T = list[0]
if (records.has(node)) {
path.pop()
list.shift()
}
else {
records.add(node);
(node as any)[children] && list.unshift(...(node as any)[children])
path.push(node)
if (callback(node)) {
paths.push([...path])
if (!findAll)
break
}
}
}

return paths
}

export function findNodes<T>(tree: T[], callback: (node: T) => boolean, options?: {
children?: string
findAll?: boolean
}): T[] {
const tOption = Object.assign({
children: 'children',
findAll: false,
}, options || {})

const { children, findAll } = tOption

const list: T[] = [...tree]
const nodes: T[] = []

for (const node of list) {
if (callback(node)) {
nodes.push(node)
if (!findAll)
break
}

if ((node as any)[children] && Array.isArray((node as any)[children]) && (node as any)[children].length)
list.push(...(node as any)[children])
}

return nodes
}
9 changes: 9 additions & 0 deletions packages/tree/tsup.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { defineConfig } from 'tsup'

export default defineConfig({
entry: ['index.ts'],
format: ['cjs', 'esm'],
dts: true,
clean: true,
splitting: true,
})
9 changes: 9 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit c21af0b

Please sign in to comment.