UNPKG

falcor-router

Version:

A router DataSource constructor for falcor that allows you to model all your cloud data sources as a single JSON resource.

86 lines (71 loc) 2.66 kB
var iterateKeySet = require('falcor-path-utils').iterateKeySet; var cloneArray = require('./../support/cloneArray'); var catAndSlice = require('./../support/catAndSlice'); var $types = require('./../support/types'); var $ref = $types.$ref; var followReference = require('./followReference'); /** * The fastest possible optimize of paths. * * What it does: * - Any atom short-circuit / found value will be removed from the path. * - All paths will be exploded which means that collapse will need to be * ran afterwords. * - Any missing path will be optimized as much as possible. */ module.exports = function optimizePathSets(cache, paths, maxRefFollow) { var optimized = []; paths.forEach(function(p) { optimizePathSet(cache, cache, p, 0, optimized, [], maxRefFollow); }); return optimized; }; /** * optimizes one pathSet at a time. */ function optimizePathSet(cache, cacheRoot, pathSet, depth, out, optimizedPath, maxRefFollow) { // at missing, report optimized path. if (cache === undefined) { out[out.length] = catAndSlice(optimizedPath, pathSet, depth); return; } // all other sentinels are short circuited. // Or we found a primitive (which includes null) if (cache === null || (cache.$type && cache.$type !== $ref) || (typeof cache !== 'object')) { return; } // If the reference is the last item in the path then do not // continue to search it. if (cache.$type === $ref && depth === pathSet.length) { return; } var keySet = pathSet[depth]; var nextDepth = depth + 1; var iteratorNote = {}; var key, next, nextOptimized; key = iterateKeySet(keySet, iteratorNote); do { next = cache[key]; var optimizedPathLength = optimizedPath.length; if (key !== null) { optimizedPath[optimizedPathLength] = key; } if (next && next.$type === $ref && nextDepth < pathSet.length) { var refResults = followReference(cacheRoot, next.value, maxRefFollow); next = refResults[0]; // must clone to avoid the mutation from above destroying the cache. nextOptimized = cloneArray(refResults[1]); } else { nextOptimized = optimizedPath; } optimizePathSet(next, cacheRoot, pathSet, nextDepth, out, nextOptimized, maxRefFollow); optimizedPath.length = optimizedPathLength; if (!iteratorNote.done) { key = iterateKeySet(keySet, iteratorNote); } } while (!iteratorNote.done); }