// Domain index query APIs for deterministic first-order logic enumeration (V1.1) // All returned arrays are owned by the index — no copies on read. import { GeometryWorld } from './world.js' // --------------------------------------------------------------------------- // Selector queries // --------------------------------------------------------------------------- /** * Return all element subject IDs that match the given CSS selector string. * Supported selector forms: * - tag name: "div", "button", "span" * - class: ".button", ".card" * Returns a sorted array owned by the world selectorIndex. * If the selector is not indexed, returns an empty array. */ export function getElementsBySelector(world: GeometryWorld, selector: string): number[] { const normalized = selector.trim() return world.selectorIndex.get(normalized) ?? [] } // --------------------------------------------------------------------------- // Ancestor / descendant queries // --------------------------------------------------------------------------- /** * Return all descendant element subject IDs of `parentId`. * If `selector` is provided, filter to those matching the selector. * Returns a sorted array owned by the world ancestorIndex (or a filtered copy). */ export function getDescendants(world: GeometryWorld, parentId: number, selector?: string): number[] { const all = world.ancestorIndex.get(parentId) ?? [] if (!selector) { return all } const matched = getElementsBySelector(world, selector) if (matched.length === 0) { return [] } // Intersect two sorted arrays without allocating intermediates. const out: number[] = [] let i = 0 let j = 0 while (i < all.length && j < matched.length) { const a = all[i] const b = matched[j] if (a === b) { out.push(a) i++ j++ } else if (a < b) { i++ } else { j++ } } return out } // --------------------------------------------------------------------------- // Text geometry queries // --------------------------------------------------------------------------- /** * Return line box fragment IDs for the given text node subject ID. * Returns a sorted array owned by the world lineBoxIndex. */ export function getLineBoxes(world: GeometryWorld, textNodeId: number): number[] { return world.lineBoxIndex.get(textNodeId) ?? [] } /** * Return text run IDs for the given text node subject ID. * Returns a sorted array owned by the world textRunIndex. */ export function getTextRuns(world: GeometryWorld, textNodeId: number): number[] { return world.textRunIndex.get(textNodeId) ?? [] }