167) -> List[DalGroup]:
168 """Sort DalGroups by their depth in the configuration tree (BFS from Session root)."""
169 all_ids = {g.dals[0].id for g in groups}
170 tree_list = list(trees.values())
171 covered: Set[str] = set()
172 sorted_groups: List[DalGroup] = []
173 iteration = 0
174
175 while covered != all_ids:
176 iteration += 1
177
178 if iteration == 1:
179 sessions = tree_list[0].db.get_dals("Session")
180 if not sessions:
181 raise ValueError("Configuration must contain a Session object!")
182 root = sessions[0]
183 else:
184 remaining = all_ids - covered
185 root = next((g.dals[0] for g in groups if g.dals[0].id in remaining), None)
186 if root is None:
187 break
188
189
190 depth_map: Dict[str, int] = {}
191 queue = [(root, 0)]
192 visited: Set[int] = set()
193
194 while queue:
195 obj, depth = queue.pop(0)
196 if id(obj) in visited:
197 continue
198 visited.add(id(obj))
199 depth_map[obj.id] = depth
200 covered.add(obj.id)
201
202 seen_children: Set[int] = set()
203 for tree in tree_list:
204 for child in tree.graph.get(obj, []):
205 if id(child) not in visited and id(child) not in seen_children:
206 queue.append((child, depth + 1))
207 seen_children.add(id(child))
208
209 batch = [g for g in groups if g.dals[0].id in depth_map]
210 batch.sort(key=lambda g: (depth_map[g.dals[0].id], _natural_sort_key(g.dals[0].id)))
211 sorted_groups.extend(batch)
212
213 return sorted_groups
214
215
216
217