aboutsummaryrefslogtreecommitdiffstats
path: root/packages/shared/utils/listUtils.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/shared/utils/listUtils.ts')
-rw-r--r--packages/shared/utils/listUtils.ts55
1 files changed, 55 insertions, 0 deletions
diff --git a/packages/shared/utils/listUtils.ts b/packages/shared/utils/listUtils.ts
new file mode 100644
index 00000000..1dd3d476
--- /dev/null
+++ b/packages/shared/utils/listUtils.ts
@@ -0,0 +1,55 @@
+import { ZBookmarkList } from "../types/lists";
+
+export interface ZBookmarkListTreeNode {
+ item: ZBookmarkList;
+ children: ZBookmarkListTreeNode[];
+}
+
+export type ZBookmarkListRoot = Record<string, ZBookmarkListTreeNode>;
+
+export function listsToTree(lists: ZBookmarkList[]) {
+ const idToList = lists.reduce<Record<string, ZBookmarkList>>((acc, list) => {
+ acc[list.id] = list;
+ return acc;
+ }, {});
+
+ const root: ZBookmarkListRoot = {};
+
+ // Prepare all refs
+ const refIdx = lists.reduce<Record<string, ZBookmarkListTreeNode>>(
+ (acc, l) => {
+ acc[l.id] = {
+ item: l,
+ children: [],
+ };
+ return acc;
+ },
+ {},
+ );
+
+ // Build the tree
+ lists.forEach((list) => {
+ const node = refIdx[list.id];
+ if (list.parentId) {
+ refIdx[list.parentId].children.push(node);
+ } else {
+ root[list.id] = node;
+ }
+ });
+
+ const allPaths: ZBookmarkList[][] = [];
+ const dfs = (node: ZBookmarkListTreeNode, path: ZBookmarkList[]) => {
+ const list = idToList[node.item.id];
+ const newPath = [...path, list];
+ allPaths.push(newPath);
+ node.children.forEach((child) => {
+ dfs(child, newPath);
+ });
+ };
+
+ Object.values(root).forEach((node) => {
+ dfs(node, []);
+ });
+
+ return { allPaths, root };
+}