The TypeScript rules compiler now uses the modern JSR-based @jk-com/adblock-compiler package as the primary compiler, with automatic fallback to the npm-based @adguard/hostlist-compiler if needed.
The compiler-adapter.ts module provides automatic fallback logic with lazy initialization:
- Lazy Loading: Compiler is loaded on first use, not at module import time
- Primary: Attempts to load
@jk-com/adblock-compilerfrom JSR - Fallback: Falls back to
@adguard/hostlist-compilerfrom npm if JSR fails - Logging: Logs which compiler is being used when initialized
import { compile, getFilterCompiler, getCompilerInfo } from './lib/compiler-adapter.ts';
// Check which compiler is active (triggers lazy initialization if not yet loaded)
const info = await getCompilerInfo();
console.log(`Using ${info.source} package: ${info.package}`);Key Design Decision: The adapter uses lazy initialization instead of top-level await to prevent blocking module imports. This ensures fast startup and deferred loading until the compiler is actually needed.
The @jk-com/adblock-compiler@^0.6.0 package includes:
✅ SOLID Principles: Refactored codebase following Single Responsibility, Open/Closed, etc. ✅ Dependency Injection: All components use DI for testability ✅ Modern TypeScript: Full type safety and modern patterns ✅ Comprehensive Error Handling: Descriptive errors with context ✅ Performance Optimizations: Improved pattern matching and processing ✅ Better Documentation: Full JSDoc coverage ✅ Trace Logging: Additional debug level for troubleshooting
- ✅ 100% API compatible with
@adguard/hostlist-compiler - ✅ Same
IConfigurationinterface - ✅ Same
compile()function signature - ✅ No breaking changes to existing code
import { compile } from './lib/compiler-adapter.ts';
import type { IConfiguration } from './lib/compiler-adapter.ts';
const config: IConfiguration = {
name: 'My Filter List',
sources: [
{
source: 'https://example.com/rules.txt',
type: 'adblock',
},
],
transformations: ['RemoveComments', 'Deduplicate'],
};
const rules = await compile(config);
console.log(`Compiled ${rules.length} rules`);import { getFilterCompiler } from './lib/compiler-adapter.ts';
// Get the FilterCompiler class (lazy loads on first call)
const FilterCompiler = await getFilterCompiler();
const compiler = new FilterCompiler(logger);
const result = await compiler.compile(config);import { getCompilerInfo } from './lib/compiler-adapter.ts';
// This will trigger lazy initialization if compiler not yet loaded
const { source, package: pkg } = await getCompilerInfo();
console.log(`Active compiler: ${pkg} (${source})`);No code changes required! The adapter handles everything automatically. Just import from ./lib/compiler-adapter.ts instead of directly from @adguard/hostlist-compiler.
Before:
import compile from '@adguard/hostlist-compiler';After:
import { compile } from './lib/compiler-adapter.ts';No changes needed. The fallback mechanism ensures compilation works even if JSR registry is unavailable.
If you see:
[Compiler] JSR package failed, falling back to npm
This is normal and automatic. The npm package will be used instead. Check:
- Network connectivity to jsr.io
- Deno cache status (
deno cache --reload)
If both fail:
Failed to load compiler from both sources:
JSR: <error>
npm: <error>
- Check internet connectivity
- Verify
deno.jsonhas both imports configured - Run
deno cache --reload src/compiler.ts
- v0.6.0 (2026-01-01): Initial JSR integration with Phase 1 SOLID refactoring
- SOLID-compliant interfaces
- 8 new classes following SRP
- Full dependency injection support
- Comprehensive error handling
- JSR Package: https://jsr.io/@jk-com/adblock-compiler
- Source Code: https://github.com/jaypatrick/hostlistcompiler
- Issue Tracker: https://github.com/jaypatrick/hostlistcompiler/issues
Phase 2 refactoring (planned):
- Factory pattern implementations
- Complete DI integration
- Remove duplicate code
- Enhanced testing infrastructure