Files
suaveplan/packages/commerce/contacts/api-plugin-contacts/src/tree/build-tree.ts
2026-05-27 23:29:53 +01:00

42 lines
1.4 KiB
TypeScript

/**
* 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<string, Group[]>();
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<string, Group[]>): GroupTreeNode {
const children = byParent.get(node.id) ?? [];
return {
group: node,
children: children.map((child) => walk(child, byParent)),
};
}