Project Architecture
Relevant source files
The following files were used as context for generating this wiki page:
The nth-check project is a specialized utility designed to parse and compile CSS nth-child formulas into highly optimized JavaScript functions. It supports the standard CSS 3 Selector specification for pseudo-classes such as :nth-child() and :nth-last-of-type(). The architecture is split into two primary phases: a parsing phase that converts a string formula into a numeric tuple, and a compilation phase that transforms that tuple into an executable check function or an index generator.
The library is built as an ES module, targeting modern Node.js environments (>=20.19.0) and utilizing TypeScript for type safety and clarity. It prioritizes performance by returning specialized functions based on the input formula, ensuring that common cases (like even, odd, or constant offsets) are handled with minimal computational overhead.
Sources: package.json:2-10, README.md:3-12, src/index.ts:1-5
Core Modules and Data Flow
The architecture is divided into three main functional areas: parsing, compilation, and sequence generation. Users typically interact with the high-level API provided in the entry point, which orchestrates the flow between these modules.
Logical Data Flow
The following diagram illustrates how a CSS formula string is processed through the system to become either a boolean validator or a sequence generator.
The data flow starts with a string input (e.g., "2n+3") and results in optimized logic for index matching.
Sources: src/index.ts:25-50, src/parse.ts:15-30, src/compile.ts:21-40
Parsing Phase (parse.ts)
The parser transforms CSS nth-formula strings into a internal representation: a tuple [a, b], where a is the step size and b is the offset. It handles standard keywords, signed integers, and the n variable notation.
| Component | Description |
|---|---|
parse(formula) | Main entry point for string parsing. Trims, lowercases, and processes formula logic. |
readSign() | Internal helper to detect and consume + or - characters. |
readNumber() | Internal helper to consume sequences of digits and return them as integers. |
| Whitespace Handling | Follows W3C spec using a Set of character codes (9, 10, 12, 13, 32). |
The parser specifically recognizes keywords:
even: Returns[2, 0]odd: Returns[2, 1]
Sources: src/parse.ts:5-15, src/parse.ts:20-45, src/parse.ts:75-90
Compilation Phase (compile.ts)
The compiler takes the [a, b] tuple and generates an optimized function. A critical architectural detail is the conversion from CSS's 1-based indexing to JavaScript's 0-based indexing by subtracting 1 from the offset b at the start of the compilation.
Optimization Paths
The compiler returns different function implementations based on the values of a and b:
- Zero/Negative Match: If
b < 0(after adjustment) anda <= 0, it returnsboolbase.falseFunc. - Constant Match (
a === 0): Returns a simple equality checkindex === b. - Linear Match (
a === 1): Returns a range checkindex >= b. - Negative Step (
a === -1): Returns a range checkindex <= b. - Modulo Match: For
abs(a) > 1, it uses modulo arithmetic to determine if an index fits the sequence.
The system selects the most efficient comparison logic during compilation to minimize runtime overhead.
Sources: src/compile.ts:21-50, src/compile.ts:55-65
Sequence Generation
The library provides the ability to generate a monotonously increasing sequence of indices matching a formula. This is handled by the generate function, which manages internal state (n) to track the current position in the sequence.
- Negative Steps: Even if
ais negative, the generator ensures an increasing sequence by calculating the minimum valid value and moving upwards until the upper boundbis reached. - End State: When a sequence has a finite number of matches (e.g.,
-2n + 5), the generator returnsnullonce the limit is exceeded.
Sources: src/compile.ts:98-120, src/index.ts:58-65, src/compile.spec.ts:77-85
Exported API Summary
The project exports a clean functional API through src/index.ts.
| Function | Input | Returns | Source |
|---|---|---|---|
nthCheck (default) | string | (index: number) => boolean | src/index.ts:25 |
sequence | string | () => number | null | src/index.ts:65 |
parse | string | [number, number] | src/parse.ts:15 |
compile | [number, number] | (index: number) => boolean | src/compile.ts:21 |
generate | [number, number] | () => number | null | src/compile.ts:98 |
Sources: src/index.ts:25-78, README.md:20-80
Conclusion
The architecture of nth-check is a classic example of a specialized compiler. By separating the concerns of string parsing from the execution logic, and further specializing the execution logic based on the specific parameters of the CSS formula, it achieves high performance while maintaining strict adherence to the CSS Selector specification. Its stateless parsing and functional compilation make it suitable for high-frequency use in CSS engine implementations.