You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
selectors: resolveSelectorChainWithPolicy still double-scans the tree for disambiguate/fail-closed rows #1970
Found during adversarial review of #1690's implementation (find index-once).
packages/selectors/src/internal/resolve-with-policy.ts:66-89 runs listSelectorChainMatches (full scan per alternative) followed by resolveSelectorChain (another full scan per alternative) for the disambiguate and fail-closed rows — the same defect class #1690 removed from replay's resolveRecordedTarget. Measured: readText/readUnique rows pay 2 whole-tree passes; the comment at :61 ("One matching pass serves every row") is false for those rows.
The new resolveSelectorChainDomain primitive (added by #1690) could collapse them, but not mechanically: resolveSelectorChainWithPolicy deliberately reports the FIRST matching alternative's matchedNodes even when the winner comes from a later alternative (:79-81), whereas resolveSelectorChainDomain reports the winner's. Folding changes matchedNodes for chained selectors and needs an explicit semantic decision first.
Also related: analyzeSelectorMatches's lazy isVisible (packages/selectors/src/internal/resolve.ts:215-218) omits precomputedViewportRects, so each ambiguous candidate pays 2 extra whole-tree flatMap passes inside visibility resolution (4n scans per candidate measured). Passing the precomputed rects — or building them once next to the lazily-built byIndex — removes it.
Activity
perf(scroll-until): answer every candidate from one visibility index (#…