Published on

树形结构转化成Fiber架构

树形结构转化成Fiber架构

type Fiber<T extends Record<string, unknown>> = T & {
    parent: Fiber<T> | null
    child: Fiber<T> | null
    sibling: Fiber<T> | null
}

type CommonNode<T extends Record<string, unknown>> = T & {
    children?: CommonNode<T>[]
}

export const treeToFiber = <T extends Record<string, unknown>>(node: CommonNode<T>[]): Fiber<T>[] => {
    const fibers: Fiber<T>[] = []

    const handle = (node: CommonNode<T>) => {
        const { children, ...rest } = node

        let fiber: Fiber<T> = {
            ...(rest as T),
            parent: null,
            sibling: null,
            child: null
        }

        function handleChildren(children: CommonNode<T>[], parent: Fiber<T> | null = null) {
            let prev: Fiber<T> | null = null

            children.forEach(child => {
                const { children, ...rest } = child

                const childFiber: Fiber<T> = {
                    ...(rest as T),
                    parent,
                    sibling: null,
                    child: null
                }

                if (parent && !parent.child) parent.child = childFiber

                if (prev) {
                    prev.sibling = childFiber
                }

                prev = childFiber

                children && handleChildren(children, childFiber)
            })
        }

        if (children) {
            handleChildren(children, fiber)
        }

        return fiber
    }

    node.forEach(n => fibers.push(handle(n)))

    return fibers
}