/** * Typed subtree builder. Given a root `Group` and a flat list of its * descendants (in arbitrary order), produces a nested `GroupTreeNode` * forest rooted at the supplied group. Replaces the upstream port's * `function buildTree(root: any, descendants: any[]): any`. */ import type { Group, GroupTreeNode } from "@suaveplan/contacts"; /** * Build a typed tree rooted at `root` from a flat `descendants` list. * Children are derived by `parentId === root.id`; the result is * deterministic insofar as the input order is deterministic — the * caller is responsible for sorting descendants if a deterministic * traversal order is required. */ export function buildTree( root: Group, descendants: readonly Group[] ): GroupTreeNode { const childrenByParent = new Map(); for (const d of descendants) { const key = d.parentId !== null && d.parentId !== undefined ? d.parentId : ""; const bucket = childrenByParent.get(key); if (bucket === undefined) { childrenByParent.set(key, [d]); } else { bucket.push(d); } } return walk(root, childrenByParent); } function walk(node: Group, byParent: Map): GroupTreeNode { const children = byParent.get(node.id) ?? []; return { group: node, children: children.map((child) => walk(child, byParent)), }; }