| | const conversions = require('./conversions'); |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | function buildGraph() { |
| | const graph = {}; |
| | |
| | const models = Object.keys(conversions); |
| |
|
| | for (let len = models.length, i = 0; i < len; i++) { |
| | graph[models[i]] = { |
| | |
| | |
| | distance: -1, |
| | parent: null |
| | }; |
| | } |
| |
|
| | return graph; |
| | } |
| |
|
| | |
| | function deriveBFS(fromModel) { |
| | const graph = buildGraph(); |
| | const queue = [fromModel]; |
| |
|
| | graph[fromModel].distance = 0; |
| |
|
| | while (queue.length) { |
| | const current = queue.pop(); |
| | const adjacents = Object.keys(conversions[current]); |
| |
|
| | for (let len = adjacents.length, i = 0; i < len; i++) { |
| | const adjacent = adjacents[i]; |
| | const node = graph[adjacent]; |
| |
|
| | if (node.distance === -1) { |
| | node.distance = graph[current].distance + 1; |
| | node.parent = current; |
| | queue.unshift(adjacent); |
| | } |
| | } |
| | } |
| |
|
| | return graph; |
| | } |
| |
|
| | function link(from, to) { |
| | return function (args) { |
| | return to(from(args)); |
| | }; |
| | } |
| |
|
| | function wrapConversion(toModel, graph) { |
| | const path = [graph[toModel].parent, toModel]; |
| | let fn = conversions[graph[toModel].parent][toModel]; |
| |
|
| | let cur = graph[toModel].parent; |
| | while (graph[cur].parent) { |
| | path.unshift(graph[cur].parent); |
| | fn = link(conversions[graph[cur].parent][cur], fn); |
| | cur = graph[cur].parent; |
| | } |
| |
|
| | fn.conversion = path; |
| | return fn; |
| | } |
| |
|
| | module.exports = function (fromModel) { |
| | const graph = deriveBFS(fromModel); |
| | const conversion = {}; |
| |
|
| | const models = Object.keys(graph); |
| | for (let len = models.length, i = 0; i < len; i++) { |
| | const toModel = models[i]; |
| | const node = graph[toModel]; |
| |
|
| | if (node.parent === null) { |
| | |
| | continue; |
| | } |
| |
|
| | conversion[toModel] = wrapConversion(toModel, graph); |
| | } |
| |
|
| | return conversion; |
| | }; |
| |
|
| |
|