Compilation Flow
Relevant source files
The following files were used as context for generating this wiki page:
The Compilation Flow in nth-check refers to the multi-stage process of transforming a CSS nth-child formula (a string like 2n+3) into a highly optimized JavaScript function. This process ensures that element index matching and sequence generation adhere to the CSS3 Selectors specification while maintaining maximum performance.
The flow begins with a string input, which is decomposed into a tuple representing the step (a) and offset (b). This tuple is then passed to the compiler, which evaluates the mathematical properties of the rule to return either a boolean checker function or an index generator.
Sources: README.md:9-15, src/index.ts:25-27
Data Transformation Pipeline
The compilation process is divided into two primary phases: Parsing and Compilation/Generation. The nthCheck default export acts as a wrapper that orchestrates these phases.
The diagram above illustrates the transformation from a raw CSS formula to functional outputs.
Sources: src/index.ts:25-63, src/compile.ts:25-115
Parsing Logic
The parser converts the formula into a standard mathematical representation $[a, b]$, where the formula follows the pattern $an + b$. The parser handles special keywords, signs, and whitespace.
Keywords and Special Cases
The parser identifies specific CSS keywords and maps them to their numerical equivalents:
even: Translated to[2, 0](matches 2, 4, 6...).odd: Translated to[2, 1](matches 1, 3, 5...).
Sources: src/parse.ts:16-24
Parser Internal State Machine
The parser manually iterates through the string using a pointer (index) and internal helper functions:
readSign(): Detects+or-characters.readNumber(): Parses continuous digits into an integer.skipWhitespace(): Ignores characters matching " \t\r\n\f".
Sources: src/parse.ts:55-88
Compiler Optimization
The compile function takes the [a, b] tuple and returns a function optimized for the specific mathematical properties of the rule. It first converts the 1-indexed CSS offset to a 0-indexed internal value by subtracting 1 from b.
Optimization Strategies
| Condition | Optimization Strategy | Resulting Function Behavior |
|---|---|---|
b < 0 and a <= 0 | boolbase.falseFunc | Always returns false. |
a === -1 | Linear Limit | Returns index <= b. |
a === 0 | Exact Match | Returns index === b. |
a === 1 | Linear Minimum | Returns true if b < 0, else index >= b. |
a > 1 | Positive Modulo | Returns index >= b && index % absA === bModulo. |
a < -1 | Negative Modulo | Returns index <= b && index % absA === bModulo. |
Sources: src/compile.ts:31-62
Modulo Calculation
For rules where $|a| > 1$, the compiler pre-calculates a bModulo value to avoid redundant calculations during runtime.
const absA = Math.abs(a);
const bModulo = ((b % absA) + absA) % absA;
Sources: src/compile.ts:55-57
Sequence Generation
The generate function provides a way to produce a monotonously increasing sequence of indices based on the [a, b] rule.
Generation Logic Flow
The generator ensures that even for negative step sizes (a < 0), the output sequence is increasing.
Sources: src/compile.ts:92-126
Negative Step Handling
When a is negative, the generator calculates the smallest possible valid index (minValue) and increments until it hits the ceiling defined by b.
Sources: src/compile.ts:97-104
Summary of API Entry Points
The Compilation Flow is exposed through four main functions in the index.ts file:
nthCheck(formula): Combinedparseandcompilefor index validation.sequence(formula): Combinedparseandgeneratefor index iteration.parse(formula): Low-level string-to-tuple parsing.compile(parsed): Low-level tuple-to-function optimization.
Sources: src/index.ts:25-66, README.md:27-100