Pathfinding algorithm for multi-step file conversions
The TraversionGraph class implements a Dijkstra-based pathfinding algorithm to find optimal conversion paths between file formats, even when multi-step conversions are required.
The graph models file formats as nodes and possible conversions as weighted edges. The algorithm finds the lowest-cost path from a source format to a target format, considering:
Depth cost: Base cost for each conversion step
Category change cost: Additional cost when converting between format categories (e.g., image to video)
Lossiness penalty: Cost multiplier for lossy conversions (1.4x)
Handler priority: Small cost based on handler registration order
Format priority: Small cost based on format order within a handler
Adaptive costs: Dynamic penalties for specific category sequences
Optional handler name to specify that this cost only applies when using a specific handler for the category change. If not specified, the cost applies to all handlers.
Initializes the traversion graph based on supported formats and handlers.This should be called after all handlers have been registered and their supported formats have been cached. The graph is built by creating nodes for each unique file format and edges for each possible conversion.
If true, the algorithm will apply category change costs more strictly, even when formats share categories. This can lead to more accurate pathfinding at the cost of potentially longer paths and increased search time.If false, category change costs will only be applied when formats do not share any categories, allowing for more flexible pathfinding that may yield shorter paths but with less nuanced cost calculations.
Example:
const graph = new TraversionGraph();const formatCache = new Map<string, FileFormat[]>();// Populate format cache from handlersfor (const handler of handlers) { await handler.init(); if (handler.supportedFormats) { formatCache.set(handler.name, handler.supportedFormats); }}graph.init(formatCache, handlers, false);
(from: ConvertPathNode, to: ConvertPathNode, simpleMode: boolean) => AsyncGenerator<ConvertPathNode[]>
Searches for conversion paths from source to target format using Dijkstra’s algorithm.Returns an async generator that yields paths as they are found, ordered by cost (lowest cost first).
If true, accepts any path that reaches the target format, regardless of which handler is used for the final step.If false, only accepts paths where the final handler matches the target node’s handler.
Example:
const fromNode = new ConvertPathNode(imageHandler, pngFormat);const toNode = new ConvertPathNode(videoHandler, mp4Format);for await (const path of graph.searchPath(fromNode, toNode, true)) { console.log("Found path:", path.map(p => `${p.handler.name}(${p.format.mime})`)); // Use the first (lowest cost) path break;}
Adds a path fragment to the temporary dead ends list.Paths that start with this fragment will be assigned infinite cost during pathfinding, effectively blocking them.
Returns a deep copy of the graph data, including nodes, edges, category change costs, and category adaptive costs.This can be used for debugging, visualization, or analysis purposes. The returned data is a deep copy to prevent external modifications from affecting the internal state.