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
}