| 3794 | ); |
| 3795 | |
| 3796 | const ensureFolder = (subpath: string): TreeNode => { |
| 3797 | const existing = byPath.get(subpath); |
| 3798 | if (existing) return existing; |
| 3799 | const segments = subpath.split("/"); |
| 3800 | let parent = root; |
| 3801 | let acc = ""; |
| 3802 | for (const seg of segments) { |
| 3803 | acc = acc ? `${acc}/${seg}` : seg; |
| 3804 | let node = byPath.get(acc); |
| 3805 | if (!node) { |
| 3806 | node = { |
| 3807 | name: seg, |
| 3808 | subpath: acc, |
| 3809 | siblingOrder: folderOrder.get(acc) ?? Number.MAX_SAFE_INTEGER, |
| 3810 | notes: [], |
| 3811 | assets: [], |
| 3812 | children: [], |
| 3813 | isSymlink: symlinkBySubpath.get(acc) ?? false, |
| 3814 | }; |
| 3815 | byPath.set(acc, node); |
| 3816 | parent.children.push(node); |
| 3817 | } |
| 3818 | parent = node; |
| 3819 | } |
| 3820 | return parent; |
| 3821 | }; |
| 3822 | |
| 3823 | // First pass: create nodes for every folder on disk (this is what |
| 3824 | // keeps empty folders visible in the tree). |