This document contains information for developers working on the dancing-links library.
- Node.js 20 or higher
- npm 8 or higher
npm installnpm run build- Build the TypeScript code to JavaScriptnpm run build:dev- Build with development configuration (includes benchmarks and scripts)npm test- Run the test suitenpm run test-watch- Run tests in watch modenpm run coverage- Generate test coverage report
npm run lint- Run ESLint code quality checksnpm run lint:fix- Run ESLint with auto-fixnpm run format- Format code with Prettiernpm run format:check- Check code formatting
npm run benchmark- Run fast library-only benchmarks (CI mode)npm run benchmark:comparison- Run comprehensive benchmarks including external librariesnpm run benchmark:json- Generate JSON benchmark output for analysisnpm run update-benchmark-docs- Update README with current benchmark resultsnpm run update-benchmark-docs:dry-run- Preview benchmark documentation changesnpm run profile- Generate CPU performance profile
The benchmarks compare performance across different constraint formats and against other Dancing Links libraries using sudoku and pentomino problems.
# Fast library-only benchmarks
npm run benchmark
# Include external library comparisons
npm run benchmark:comparison
# Generate JSON output
npm run benchmark:json
# Custom options
node built/benchmark/index.js --external --json=results.json- Sparse constraints reduce parsing overhead compared to binary constraints
- Template reuse eliminates constraint preprocessing overhead, especially beneficial for binary constraints which require conversion to sparse format
- Batch operations reduce function call overhead when adding many constraints
Benchmarks consistently show this library outperforms other JavaScript Dancing Links implementations, with sparse constraints and templates providing additional optimizations.
The project includes automated benchmark documentation that runs during releases:
- Compares against other JS Dancing Links libraries (dlxlib, dance, dancing-links-algorithm)
- Generates objective performance comparison tables
- Updates README automatically during
npm run release - Can be run manually with
npm run update-benchmark-docs
Generate CPU profiles for performance analysis:
npm run profileThis creates profile.cpuprofile which can be loaded into Chrome DevTools for detailed performance analysis.
The algorithm uses a state machine pattern to avoid recursion and closely follows Knuth's reference implementation. The core algorithm is implemented using efficient data structures optimized for the Dancing Links technique.
lib/- Core library implementation with organized nested modulescore/- Core algorithm and data structuresconstraints/handlers/- Constraint handlers for different solver modessolvers/- Factory, solver, and template classestypes/- TypeScript interfaces and type definitions
benchmark/- Performance testing and example problems (n-queens, pentomino, sudoku)test/unit/- Unit test suitescripts/- Development and automation scriptsbuilt/- Compiled JavaScript output
The core algorithm (lib/core/algorithm.ts) uses a state machine pattern with these states:
- FORWARD: Select next column to cover
- ADVANCE: Try next option for selected column
- BACKUP: Backtrack when no options remain
- RECOVER: Restore previous state when backtracking
- DONE: Solution found or search complete
NodeStore<T>class: Struct-of-Arrays implementation with typed arrays for navigation fieldsColumnStoreclass: Column headers with length tracking and circular linking- Constraint types:
SimpleConstraint(single row) andComplexConstraint(primary + secondary rows)
This project follows Conventional Commits specification for automated releases and changelog generation. Please use the following commit message format:
<type>[optional scope]: <description>
[optional body]
[optional footer(s)]
Types:
feat:- A new feature (triggers minor version bump)fix:- A bug fix (triggers patch version bump)docs:- Documentation only changesstyle:- Changes that do not affect the meaning of the code (white-space, formatting, etc)refactor:- A code change that neither fixes a bug nor adds a featureperf:- A code change that improves performancetest:- Adding missing tests or correcting existing testschore:- Changes to the build process or auxiliary tools
Breaking Changes:
To trigger a major version release, include BREAKING CHANGE: in the commit footer or add ! after the type:
feat!: remove support for Node.js 16
BREAKING CHANGE: Node.js 18+ is now required
DO write detailed comments for:
- Complex algorithms with multiple steps
- Non-obvious business logic or domain-specific rules
- Areas where refactoring considerations are documented
- Code that cannot be easily simplified due to technical constraints
DON'T write comments for:
- Self-evident code (obvious function names, simple operations)
- Historical changes or what code "used to do"
- Anything that can be understood from reading the code itself
DO use for performance-critical code:
for...ofloops over.forEach()- Manual loops over
.map()and.reduce()for data transformation - Low-level iteration patterns in hot paths
DON'T use for performance-critical code:
- Array utility methods (
.map,.reduce,.forEach) - provably slower than loops - Functional programming patterns that create intermediate arrays
- Method chaining that allocates temporary objects
DO in tests:
- Test functionality and behavior
- Focus on input/output verification
- Test edge cases and error conditions
DON'T in tests:
- Test method existence with
.to.have.property- TypeScript ensures this - Test implementation details
- Duplicate type checking that TypeScript already provides
Before every commit, ALWAYS run:
npm run format- Format code with Prettiernpm run lint- Check for linting issuesnpm run test- Ensure all tests passnpm run build- Verify TypeScript compilation
Performance is critical - always run benchmarks before and after changes using npm run benchmark. The library maintains its position as the fastest Dancing Links implementation in JavaScript through systematic optimization.
See PERFORMANCE.md for detailed analysis of optimization work completed.
Releases are automated using release-it:
npm run releaseThis will:
- Run automated benchmark documentation updates
- Format code
- Generate changelog
- Create git tag
- Publish to npm
- Create GitHub release
The benchmark documentation is automatically updated during releases to ensure performance claims stay current.