import type { Declaration, Diagnostic } from '@variance-authority/core/format'; import { type ConditionEnvironment } from './media.js'; import { type Specificity } from './specificity.js'; import { type IndexedFace } from './font-faces.js'; import { type LayerName } from './layers.js'; /** * The per-document half of the pruning: sheets flattened into a matchable index. * * Separated from the matcher next door by the rate each side runs at. An index * is built once per document per environment; matching runs once per element in * the subject. Everything that does not depend on *which element is asking* * belongs on this side — condition evaluation, declaration extraction, bucket * keys — and putting any of it on the other side multiplies a stylesheet-sized * cost by the node count, which is the rules × elements failure the rightmost-key * bucketing exists to avoid. Two files make that boundary visible; one file left * nothing to notice it being crossed. * * Nothing here reads an element. That is a property worth keeping: it is what * lets an index be a value a caller may hand back rather than a cache. */ export interface IndexedRule { readonly sheet: string; readonly selector: string; readonly branch: string; readonly specificity: Specificity; readonly order: number; readonly declarations: readonly Declaration[]; /** * What the originating element must match: the branch without its trailing * pseudo-element, or the branch itself when it styles an element. */ readonly host: string; /** The pseudo-element the rule styles, as `::before`; absent when it styles an element. */ readonly pseudo?: string; /** Rightmost simple selector, used to avoid testing every rule on every node. */ readonly key: string; /** Some condition around this rule could not be evaluated with certainty. */ readonly uncertain: boolean; } export interface StyleIndex { readonly byKey: ReadonlyMap; readonly universal: readonly IndexedRule[]; readonly diagnostics: readonly Diagnostic[]; /** Rules seen before applicability filtering. Reported to show what was pruned. */ readonly totalRules: number; /** * Every `@font-face` in force, in document order, under the same conditions * as the rules. A face matches no element, so it is kept here rather than in * a bucket, and `facesUsedBy` asks the subject which of them it is set in. */ readonly faces: readonly IndexedFace[]; /** Every cascade layer the sheets declare, in the order they declare them. */ readonly layers: readonly LayerName[]; /** The layer each layered rule sits in, by its `order`; an unlayered rule is absent. */ readonly layerOf: ReadonlyMap; /** * Which condition environment this index was flattened against, per * `conditionKey`. * * Carried so that an index handed back for reuse can be checked rather than * trusted. Conditions are *erased* during indexing — a rule inside a * non-matching `@media` never enters it — so an index is only meaningful for * the environment that erased them. Reusing one built at 480px to answer for * 1280px yields a capture whose declarations are the narrow layout's and whose * environment key says wide, which is a wrong answer that looks exactly like a * right one. Recording the key costs one string per index and makes that * mistake refusable. */ readonly conditions: string; /** * Outcomes of conditions that depend on an input the *semantic* key omits. * * Narrow on purpose. ADR-0003 flattens conditions out of the rule text and puts * them in the environment key, but the semantic key already carries viewport * width, height, and colour scheme — so the outcome of `@media (min-width: …)` * is *derivable* from the key and recording it would be redundant. Worse than * redundant: it made a rule that matches nothing invalidate every baseline, * because adding a never-true media block changed the key. The corpus caught * that immediately. * * The one input the semantic key drops is `deviceScaleFactor`, so resolution * queries are the only conditions whose outcome is not otherwise recoverable. * Those are recorded, and nothing else is. * * Slightly over-conservative: a resolution query gating rules that match no * subject still splits the key. That costs two baselines where one would do, * which is the safe direction, and resolution queries are rare enough that the * precise version — testing whether the gated rules would match — is not worth * its complexity yet. */ readonly evaluatedConditions: Readonly>; } /** * An index's condition environment, as a comparable string. * * Exists so reuse can be validated. Equality of two `ConditionEnvironment` * objects is not a question JavaScript answers — a fresh one is built per * collection — so the comparable form is derived instead. * * `supports` is recorded as present-or-absent rather than by identity, and that * is the honest limit of this check. Presence is what changes the *shape* of the * answer: without a probe every `@supports` block is included and marked * uncertain, with one the block is evaluated, and those are different rule sets. * Two probes from two different engines are not told apart here — the engine is * already part of the capture's environment key, and an index cannot outlive the * document it was built from, which has one view. */ export declare function conditionKey(environment: ConditionEnvironment): string; /** * The sheets this project reads, in cascade order: every readable kind of sheet * the document holds, less the one it injected itself, then the adopted ones. */ export declare function authoredSheets(document: Document): CSSStyleSheet[]; export declare function indexStyleSheets(document: Document, environment: ConditionEnvironment): StyleIndex; export declare function isGroupingRule(rule: CSSRule): rule is CSSGroupingRule; //# sourceMappingURL=css-index.d.ts.map