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.

115 lines (93 loc) 2.96 kB
var clone = require('./../support/clone'); var types = require('./../support/types'); var $ref = types.$ref; var iterateKeySet = require('falcor-path-utils').iterateKeySet; /** * merges pathValue into a cache */ module.exports = function pathValueMerge(cache, pathValue) { var refs = []; var values = []; var invalidations = []; var valueType = true; // The pathValue invalidation shape. if (pathValue.invalidated === true) { invalidations.push({path: pathValue.path}); valueType = false; } // References. Needed for evaluationg suffixes in all three types, get, // call and set. else if ((pathValue.value !== null) && (pathValue.value.$type === $ref)) { refs.push({ path: pathValue.path, value: pathValue.value.value }); } // Values. Needed for reporting for call. else { values.push(pathValue); } // If the type of pathValue is a valueType (reference or value) then merge // it into the jsonGraph cache. if (valueType) { innerPathValueMerge(cache, pathValue); } return { references: refs, values: values, invalidations: invalidations }; }; function innerPathValueMerge(cache, pathValue) { var path = pathValue.path; var curr = cache; var next, key, cloned, outerKey, iteratorNote; var i, len; for (i = 0, len = path.length - 1; i < len; ++i) { outerKey = path[i]; // Setup the memo and the key. if (outerKey && typeof outerKey === 'object') { iteratorNote = {}; key = iterateKeySet(outerKey, iteratorNote); } else { key = outerKey; iteratorNote = false; } do { next = curr[key]; if (!next) { next = curr[key] = {}; } if (iteratorNote) { innerPathValueMerge( next, { path: path.slice(i + 1), value: pathValue.value }); if (!iteratorNote.done) { key = iterateKeySet(outerKey, iteratorNote); } } else { curr = next; } } while (iteratorNote && !iteratorNote.done); // All memoized paths need to be stopped to avoid // extra key insertions. if (iteratorNote) { return; } } // TODO: This clearly needs a re-write. I am just unsure of how i want // this to look. Plus i want to measure performance. outerKey = path[i]; iteratorNote = {}; key = iterateKeySet(outerKey, iteratorNote); do { cloned = clone(pathValue.value); curr[key] = cloned; if (!iteratorNote.done) { key = iterateKeySet(outerKey, iteratorNote); } } while (!iteratorNote.done); }