Intelligent automatic routing system that creates conversion paths between color models that don't have direct conversions, enabling conversion between any two supported color spaces using breadth-first search algorithm.
Creates conversion functions with automatic routing for color models without direct conversion paths.
/**
* Creates conversion routes from a source color model to all reachable models
* @param fromModel - Source color model name
* @returns Object containing conversion functions to all reachable models
*/
function route(fromModel: string): RouteResult;
interface RouteResult {
[toModel: string]: RoutedConversionFunction;
}
interface RoutedConversionFunction {
(args: any[]): any[];
conversion: string[];
}Usage Examples:
import route from 'color-convert/route.js';
// Get all possible conversions from RGB
const rgbRoutes = route('rgb');
// Use routed conversion
const hslResult = rgbRoutes.hsl([255, 0, 0]); // [0, 100, 50]
// Check conversion path
console.log(rgbRoutes.hsl.conversion); // ['rgb', 'hsl'] (direct)
console.log(rgbRoutes.lch.conversion); // ['rgb', 'xyz', 'lab', 'lch'] (multi-step)The routing system automatically chains conversions to enable conversions between color models that don't have direct conversion functions.
/**
* Multi-step conversion chaining
* Automatically finds shortest path between color models
*/
interface MultiStepRouting {
/**
* Algorithm: Breadth-first search to find shortest conversion path
* Example: LCH → LAB → XYZ → RGB → HEX
*/
algorithm: 'breadth-first-search';
/**
* Path optimization: Always finds shortest path between models
* Minimizes precision loss from excessive conversions
*/
pathOptimization: 'shortest-path';
/**
* Conversion chaining: Links individual conversion functions
* Each step applies the output of previous step as input to next
*/
conversionChaining: 'function-composition';
}Usage Examples:
import convert from 'color-convert';
// Direct conversion (1 step)
convert.rgb.hsl([255, 0, 0]); // Direct conversion available
// Multi-step conversion (3 steps: RGB → XYZ → LAB → LCH)
convert.rgb.lch([255, 0, 0]); // [53, 104, 40]
// Check conversion path
console.log(convert.rgb.lch.conversion); // ['rgb', 'xyz', 'lab', 'lch']
// Very complex routing (4+ steps)
convert.keyword.apple('red'); // keyword → rgb → apple
console.log(convert.keyword.apple.conversion); // ['keyword', 'rgb', 'apple']Internal graph structure used for pathfinding between color models.
/**
* Graph building for conversion pathfinding
*/
interface ConversionGraph {
/**
* Graph node representing a color model
*/
GraphNode: {
distance: number; // Distance from source model (-1 = unreachable)
parent: string | null; // Parent model in shortest path
};
/**
* Graph structure mapping model names to nodes
*/
Graph: {
[modelName: string]: GraphNode;
};
/**
* Graph initialization: Sets all distances to -1, parents to null
* Source model gets distance 0
*/
initialization: {
allDistances: -1;
allParents: null;
sourceDistance: 0;
};
}The routing algorithm uses breadth-first search to find optimal conversion paths.
/**
* Breadth-first search implementation for shortest paths
*/
interface BreadthFirstSearch {
/**
* BFS algorithm steps:
* 1. Initialize graph with source model at distance 0
* 2. Process queue of models, starting with source
* 3. For each model, check all direct conversions (adjacents)
* 4. Update unvisited adjacent models with distance + 1
* 5. Continue until all reachable models are processed
*/
algorithmSteps: string[];
/**
* Queue management: FIFO queue for BFS processing
* - unshift() adds to front (enqueue)
* - pop() removes from back (dequeue)
*/
queueOperations: {
enqueue: 'unshift';
dequeue: 'pop';
};
/**
* Distance tracking: Tracks shortest distance from source
* Distance = number of conversion steps required
*/
distanceMetric: 'conversion-steps';
}How routing constructs the final conversion function from the shortest path.
/**
* Conversion path construction from BFS results
*/
interface PathConstruction {
/**
* Path reconstruction: Works backwards from target to source
* Uses parent pointers to build conversion path
*/
pathReconstruction: {
direction: 'target-to-source';
method: 'parent-pointers';
};
/**
* Function composition: Chains individual conversion functions
* Links functions using function composition pattern
*/
functionComposition: {
pattern: 'nested-function-calls';
implementation: '(args) => toFn(fromFn(args))';
};
/**
* Conversion property: Stores the conversion path for debugging
* Array of model names showing the conversion sequence
*/
conversionProperty: {
type: 'string[]';
content: 'conversion-path';
example: "['rgb', 'xyz', 'lab', 'lch']";
};
}Usage Examples:
import convert from 'color-convert';
// Examine conversion paths
const result = convert.hex.lab('FF0000');
console.log(convert.hex.lab.conversion); // ['hex', 'rgb', 'xyz', 'lab']
// Complex multi-step conversion
const result2 = convert.ansi16.lch(9); // ansi16 → rgb → xyz → lab → lch
console.log(convert.ansi16.lch.conversion); // ['ansi16', 'rgb', 'xyz', 'lab', 'lch']
// Direct conversions show simple paths
console.log(convert.rgb.hsl.conversion); // ['rgb', 'hsl']
console.log(convert.lab.xyz.conversion); // ['lab', 'xyz']Performance and precision considerations for the routing system.
/**
* Routing system performance and precision characteristics
*/
interface RoutingPerformance {
/**
* Path optimization: Always finds shortest available path
* Minimizes conversion steps to reduce cumulative precision loss
*/
pathOptimization: {
strategy: 'shortest-path';
benefit: 'minimal-precision-loss';
};
/**
* Precision considerations: Each conversion step may introduce rounding errors
* Raw conversions recommended for precision-critical applications
*/
precisionImpact: {
multipleSteps: 'cumulative-precision-loss';
recommendation: 'use-raw-conversions';
directConversions: 'highest-precision';
};
/**
* Caching: Routing results are generated once per color model
* Conversion functions are reused for all subsequent calls
*/
caching: {
level: 'per-color-model';
scope: 'function-generation';
benefit: 'consistent-performance';
};
}Coverage and completeness of the routing system.
/**
* Routing system completeness and coverage
*/
interface RoutingCompleteness {
/**
* Full connectivity: Every color model can convert to every other model
* No unreachable model combinations in the supported set
*/
connectivity: {
coverage: '100%';
unreachableModels: 0;
totalConversions: '17 × 16 = 272 unique conversions';
};
/**
* Direct conversions: 50 explicitly defined conversion functions
* Remaining conversions use automatic routing
*/
directConversions: {
count: 50;
coverage: 'common-use-cases';
optimization: 'performance-and-precision';
};
/**
* Routed conversions: All remaining conversion combinations
* Generated automatically using shortest available paths
*/
routedConversions: {
count: '272 - 50 = 222';
generation: 'automatic';
pathFinding: 'breadth-first-search';
};
}Usage Examples:
import convert from 'color-convert';
// All these conversions work, even without direct conversion functions:
convert.keyword.apple('red'); // keyword → rgb → apple
convert.hex.ansi256('#FF0000'); // hex → rgb → ansi256
convert.hcg.lch([0, 100, 50]); // hcg → rgb → xyz → lab → lch
convert.gray.hsv([50]); // gray → rgb → hsv
// Check if routing was used (conversion property exists)
console.log('conversion' in convert.rgb.hsl); // false (direct)
console.log('conversion' in convert.keyword.apple); // true (routed)
console.log(convert.keyword.apple.conversion); // ['keyword', 'rgb', 'apple']
// All 272 possible conversions between 17 models are available
const models = ['rgb', 'hsl', 'hsv', 'hwb', 'cmyk', 'xyz', 'lab', 'lch', 'oklab', 'oklch',
'hex', 'keyword', 'ansi16', 'ansi256', 'hcg', 'apple', 'gray'];
models.forEach(from => {
models.forEach(to => {
if (from !== to) {
console.log(`${from} → ${to}: Available`); // All will show "Available"
}
});
});How the routing system handles invalid inputs and edge cases.
/**
* Error handling and edge cases in routing system
*/
interface RoutingErrorHandling {
/**
* Invalid model names: Route function handles unknown color models
* Returns empty object for models not in the conversion system
*/
invalidModels: {
input: 'unknown-model-name';
output: 'empty-object';
behavior: 'graceful-degradation';
};
/**
* Unreachable conversions: Should not occur in current system
* All models are connected through RGB hub model
*/
unreachableConversions: {
frequency: 'never';
reason: 'full-connectivity-via-rgb';
fallback: 'not-applicable';
};
/**
* Conversion function errors: Individual conversion functions may fail
* Errors propagate from underlying conversion implementations
*/
conversionErrors: {
source: 'individual-conversion-functions';
propagation: 'error-bubbling';
handling: 'caller-responsibility';
};
}Usage Examples:
import route from 'color-convert/route.js';
// Invalid model name handling
const invalidRoutes = route('invalid-model');
console.log(Object.keys(invalidRoutes)); // [] (empty)
// All valid models have full routing
const validRoutes = route('rgb');
console.log(Object.keys(validRoutes).length); // 16 (all other models)
// Error handling in conversion functions
try {
convert.hex.rgb('invalid-hex'); // May throw or return null
} catch (error) {
console.log('Conversion error:', error);
}