import { BREADCRUMB_PAGE_TYPE_PARENTS } from '#base_modules/WebManager/config/general' /** * Utility functions that identify candidate pages for buildBreadcrumbs database queries. * Breadcrumbs climb hierarchically from a target page to the home page. * To avoid querying all published pages in a locale, queries are filtered down to two * predictable sets of candidates: * 1. Path-based ancestors: The small chain of parent paths above the target page. * 2. Group-key ancestors: Static relationships where pages belong to a specific parent * type regardless of location (e.g., blog-item under blog). */ export const BREADCRUMB_PARENT_GROUP_KEYS = [ ...new Set(Object.values(BREADCRUMB_PAGE_TYPE_PARENTS)), ] /** * The paths a page can climb to, nearest parent first, ending at the home page (`''`). * * 'blog/post/hello' → ['blog/post', 'blog', ''] * 'about' → [''] * '' → [''] * * The page's own path is never included — a page cannot be its own parent. */ export function ancestorPaths(path: string) { const segments = path.split('/').filter(Boolean) const paths: string[] = [] for (let depth = segments.length - 1; depth >= 1; depth--) { paths.push(segments.slice(0, depth).join('/')) } paths.push('') return paths } /** * True when `path` is an already loaded path or an ancestor of one. Only false after a * group-key jump to another branch, never during a path climb. */ export function ancestorsAlreadyLoaded(path: string, loadedPaths: Iterable) { for (const loaded of loadedPaths) { // The trailing slash keeps 'blog' from matching 'blogging'; '' matches every path. if (loaded === path || loaded.startsWith(path === '' ? '' : `${path}/`)) return true } return false }