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
JavaScript
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);
}