@graphistry/falcor
Version:
A JavaScript library for efficient data fetching.
1,740 lines (1,426 loc) • 244 kB
JavaScript
/*!
*
* Copyright 2015 Netflix, Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define("falcor", [], factory);
else if(typeof exports === 'object')
exports["falcor"] = factory();
else
root["falcor"] = factory();
})(this, function() {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // identity function for calling harmony imports with the correct context
/******/ __webpack_require__.i = function(value) { return value; };
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
/******/ });
/******/ }
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 107);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports, __webpack_require__) {
var now = __webpack_require__(59);
var $now = __webpack_require__(34);
var $never = __webpack_require__(60);
module.exports = isExpired;
function isExpired(node, expireImmediate) {
var exp = node.$expires;
if (exp === undefined || exp === null || exp === $never) {
return false;
} else if (exp === $now) {
return expireImmediate;
}
return exp < now();
}
/***/ }),
/* 1 */
/***/ (function(module, exports, __webpack_require__) {
var isInternal = __webpack_require__(20);
module.exports = clone;
function clone(node) {
var key,
keys = Object.keys(node),
json = {},
index = -1,
length = keys.length;
while (++index < length) {
key = keys[index];
if (key !== '$size' && !isInternal(key)) {
json[key] = node[key];
}
}
return json;
}
/***/ }),
/* 2 */
/***/ (function(module, exports, __webpack_require__) {
var splice = __webpack_require__(54);
module.exports = expireNode;
function expireNode(node, expired, lru) {
if (!node["f_invalidated"]) {
node["f_invalidated"] = true;
expired.push(node);
splice(lru, node);
}
return node;
}
/***/ }),
/* 3 */
/***/ (function(module, exports, __webpack_require__) {
/* WEBPACK VAR INJECTION */(function(global) {function FalcorJSON(f_meta) {
if (!f_meta) {
this["f_meta"] = {};
} else if (!(this["f_meta"] = f_meta["f_meta"])) {
this["f_meta"] = f_meta;
}
}
var protoBlacklist = {
length: true,
toString: true,
constructor: true,
toLocaleString: true
};
var protoDescriptors = {
toJSON: { enumerable: false, value: toJSON },
toProps: { enumerable: false, value: toProps },
toString: { enumerable: false, value: toString },
toLocaleString: { enumerable: false, value: toString },
$__hash: {
enumerable: false,
get: function () {
var f_meta = this["f_meta"];
return f_meta && f_meta['$code'] || '';
}
},
$__path: {
enumerable: false,
get: function () {
var f_meta = this["f_meta"];
return f_meta && f_meta["abs_path"] || [];
}
},
$__status: {
enumerable: false,
get: function () {
var f_meta = this["f_meta"];
return f_meta && f_meta["status"] || 'resolved';
}
},
$__version: {
enumerable: false,
get: function () {
var f_meta = this["f_meta"];
return f_meta && f_meta["version"] || 0;
}
}
};
Object.defineProperties(FalcorJSON.prototype, Object.getOwnPropertyNames(Array.prototype).reduce(function (descriptors, name) {
if (!protoBlacklist.hasOwnProperty(name)) {
var fn = Array.prototype[name];
if (typeof fn === 'function') {
descriptors[name] = {
value: bindArrayMethod(fn),
writable: true, enumerable: false
};
}
}
return descriptors;
}, protoDescriptors));
function bindArrayMethod(fn) {
return function () {
var node = this,
json = node,
atom = node.length,
length = atom,
type;
// If length isn't a number, an $atom with a numeric `value`, or if the
// unboxed length isn't a valid Array length, bail early.
// If we're still waiting on pending updates, return an empty Array.
// Otherwise, throw a RangeError.
if ((type = typeof atom) !== 'number' && (!atom || type !== 'object' || atom.$type !== "atom" || typeof (length = atom.value) !== 'number') || length < 0 || length !== (length | 0)) {
if (node.$__status === 'resolved') {
throw new RangeError('Invalid FalcorJSON length');
}
return [];
}
// Temporarily set length to the unboxed length, call the bound Array
// method, then reset the length back to the boxed value. This is
// necessary because a few Array methods (like sort) operate on the
// Array in-place, so we can't pass a sliced copy of this instance to
// the bound Array method. Do this even when the length isn't boxed, so
// if calling the bound Array method writes to length, it's reset to the
// value in the cache.
node.length = length;
json = fn.apply(node, arguments);
node.length = atom;
return json;
};
}
var isArray = Array.isArray;
function getInst(x) {
var inst = x;
var typeofInst = typeof inst;
var argsLen = arguments.length;
if (argsLen === 0) {
inst = this;
} else if (typeofInst !== 'string') {
if (!inst || typeofInst !== 'object') {
return inst;
}
} else if (argsLen !== 1) {
return inst;
} else {
inst = this;
}
return inst === global ? undefined : inst;
}
function toJSON() {
return serialize(getInst.apply(this, arguments), toJSON);
}
function toString(includeMetadata, includeStatus) {
return JSON.stringify(serialize(getInst.call(this, this), serialize, includeMetadata === true, false, includeStatus === true));
}
function toProps(x) {
var inst = getInst.apply(this, arguments);
var f_meta_inst,
f_meta_json,
version = 0;
var json = serialize(inst, toProps, true, true);
if (inst && (f_meta_inst = inst["f_meta"])) {
version = f_meta_inst["version"];
}
if (!(!json || typeof json !== 'object')) {
if (f_meta_json = json["f_meta"]) {
f_meta_json["version"] = version;
}
}
return json;
}
function serialize(inst, serializer, includeMetadata, createWithProto, includeStatus) {
if (!inst || typeof inst !== 'object') {
return inst;
}
var count, total, f_meta, keys, key, xs, ys;
if (isArray(inst)) {
xs = inst;
} else {
count = -1;
keys = Object.keys(inst);
total = keys.length;
xs = {};
if (createWithProto) {
xs.__proto__ = FalcorJSON.prototype;
}
if (includeMetadata && (f_meta = inst["f_meta"])) {
var $code = f_meta['$code'];
var status = f_meta["status"];
var abs_path = f_meta["abs_path"];
var deref_to = f_meta["deref_to"];
var deref_from = f_meta["deref_from"];
f_meta = {};
$code && (f_meta['$code'] = $code);
abs_path && (f_meta["abs_path"] = abs_path);
deref_to && (f_meta["deref_to"] = deref_to);
deref_from && (f_meta["deref_from"] = deref_from);
includeStatus && status && (f_meta["status"] = status);
xs["f_meta"] = f_meta;
if (createWithProto) {
ys = {};
ys.__proto__ = xs;
xs = ys;
}
}
while (++count < total) {
if ((key = keys[count]) !== "f_meta") {
xs[key] = serializer(inst[key], serializer, includeMetadata, createWithProto, includeStatus);
}
}
}
return xs;
}
module.exports = FalcorJSON;
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(35)))
/***/ }),
/* 4 */
/***/ (function(module, exports, __webpack_require__) {
var createErrorClass = __webpack_require__(5);
var MESSAGE = '`null` is not allowed in branch key positions.';
/**
* Do not allow null in path.
*/
module.exports = createErrorClass('NullInPathError', function () {
this.message = MESSAGE;
});
/***/ }),
/* 5 */
/***/ (function(module, exports) {
module.exports = createErrorClass;
function createErrorClass(name, init) {
function E(message) {
this.message = message;
init && init.apply(this, arguments);
if (!Error.captureStackTrace) {
this.stack = new Error().stack;
} else {
Error.captureStackTrace(this, this.constructor);
}
}
E.prototype = Object.create(Error.prototype);
E.prototype.name = name;
E.prototype.constructor = E;
E.is = function (x) {
return x.name === name;
};
return E;
}
/***/ }),
/* 6 */
/***/ (function(module, exports) {
module.exports = isObject;
function isObject(value) {
return value !== null && typeof value === 'object';
}
/***/ }),
/* 7 */
/***/ (function(module, exports, __webpack_require__) {
module.exports = createHardlink;
function createHardlink(from, to) {
// create a back reference
var backRefs = to["f_refs_length"] || 0;
to["f_ref" + backRefs] = from;
to["f_refs_length"] = backRefs + 1;
// create a hard reference
from["f_ref_index"] = backRefs;
from["f_context"] = to;
}
/***/ }),
/* 8 */
/***/ (function(module, exports) {
module.exports = { $type: 'atom' };
/***/ }),
/* 9 */
/***/ (function(module, exports, __webpack_require__) {
var isObject = __webpack_require__(6);
module.exports = getSize;
function getSize(node) {
return isObject(node) && node.$size || 0;
}
/***/ }),
/* 10 */
/***/ (function(module, exports, __webpack_require__) {
/**
* getCachePosition makes a fast walk to the bound value since all bound
* paths are the most possible optimized path.
*
* @param {Model} model -
* @param {Array} path -
* @returns {Mixed} - undefined if there is nothing in this position.
* @private
*/
module.exports = getCachePosition;
function getCachePosition(cache, path) {
var node = cache;
var type,
depth = 0;
var maxDepth = path.length;
if (maxDepth > 0) {
do {
node = node[path[depth]];
while (node && (type = node.$type) === "ref") {
node = getCachePosition(cache, node.value);
}
} while (++depth < maxDepth && node && !type);
}
return node;
};
/***/ }),
/* 11 */
/***/ (function(module, exports, __webpack_require__) {
var removeNodeAndDescendants = __webpack_require__(29);
var updateBackReferenceVersions = __webpack_require__(31);
module.exports = updateNodeAncestors;
function updateNodeAncestors(node, offset, lru, version) {
var curr = node,
next;
do {
if ((curr.$size = (curr.$size || 0) - offset) > 0) {
if (!(next = curr["f_parent"])) {
curr["f_version"] = version;
} else if (curr["f_version"] !== version) {
updateBackReferenceVersions(curr, version);
}
} else if (next = curr["f_parent"]) {
removeNodeAndDescendants(curr, next, curr["f_key"], lru, version);
}
} while (curr = next);
return node;
}
/***/ }),
/* 12 */
/***/ (function(module, exports, __webpack_require__) {
var createErrorClass = __webpack_require__(5);
/**
* InvalidKeySetError happens when a dataSource syncronously throws
* an exception during a get/set/call operation.
*
* @param {Error} error - The error that was thrown.
* @private
*/
module.exports = createErrorClass('InvalidKeySetError', function (path, keysOrRanges) {
this.mesage = '' + 'The KeySet ' + JSON.stringify(keysOrRanges) + ' in path ' + JSON.stringify(path) + ' contains a KeySet. ' + 'Keysets can only contain Keys or Ranges';
});
/***/ }),
/* 13 */
/***/ (function(module, exports, __webpack_require__) {
var EXPIRES_NEVER = __webpack_require__(60);
module.exports = lruPromote;
// [H] -> Next -> ... -> [T]
// [T] -> Prev -> ... -> [H]
function lruPromote(lru, node) {
// Never promote node.$expires === 1. They cannot expire.
if (node.$expires === EXPIRES_NEVER) {
return;
}
var head = lru["f_head"];
// Nothing is in the cache.
if (!head) {
lru["f_head"] = lru["f_tail"] = node;
return;
}
if (head === node) {
return;
}
// The item always exist in the cache since to get anything in the
// cache it first must go through set.
var prev = node["f_prev"];
var next = node["f_next"];
if (next) {
next["f_prev"] = prev;
}
if (prev) {
prev["f_next"] = next;
}
node["f_prev"] = undefined;
// Insert into head position
lru["f_head"] = node;
node["f_next"] = head;
head["f_prev"] = node;
// If the item we promoted was the tail, then set prev to tail.
if (node === lru["f_tail"]) {
lru["f_tail"] = prev;
}
};
/***/ }),
/* 14 */
/***/ (function(module, exports, __webpack_require__) {
var Subscription = __webpack_require__(15);
module.exports = Subscriber;
function Subscriber(destination, parent, onCompleted) {
if (typeof destination === 'function' || typeof parent === 'function' || typeof onCompleted === 'function') {
Subscription.call(this, []);
this.destination = {
error: parent,
onError: parent,
next: destination,
onNext: destination,
complete: onCompleted,
onCompleted: onCompleted
};
} else {
Subscription.call(this, [], parent);
this.parent = parent;
this.destination = destination;
}
}
Subscriber.prototype = Object.create(Subscription.prototype);
Subscriber.prototype.next = Subscriber.prototype.onNext = function onNext(value) {
var dest = this.destination;
if (dest) {
if (dest.onNext) {
dest.onNext(value);
} else if (dest.next) {
dest.next(value);
}
}
};
Subscriber.prototype.error = Subscriber.prototype.onError = function onError(error) {
var signaled = false;
var dest = this.destination;
if (dest) {
if (dest.onError) {
signaled = true;
dest.onError(error);
} else if (dest.error) {
signaled = true;
dest.error(error);
}
this.dispose();
}
if (!signaled) {
throw error;
}
};
Subscriber.prototype.complete = Subscriber.prototype.onCompleted = function onCompleted() {
var dest = this.destination;
if (dest) {
if (dest.onCompleted) {
dest.onCompleted();
} else if (dest.complete) {
dest.complete();
}
this.dispose();
}
};
Subscriber.prototype.dispose = Subscriber.prototype.unsubscribe = function () {
this.destination = null;
Subscription.prototype.dispose.call(this);
};
/***/ }),
/* 15 */
/***/ (function(module, exports) {
module.exports = Subscription;
function Subscription(subscriptions, parent) {
this.parent = parent;
this.subscriptions = subscriptions || [];
}
Subscription.prototype.add = function (subscription) {
return this.subscriptions.push(subscription) && this || this;
};
Subscription.prototype.remove = function (subscription) {
var index = this.subscriptions.indexOf(subscription);
if (~index) {
this.subscriptions.splice(index, 1);
}
return this;
};
Subscription.prototype.dispose = Subscription.prototype.unsubscribe = function () {
var subscription,
subscriptions = this.subscriptions;
while (subscriptions.length) {
(subscription = subscriptions.pop()) && subscription.dispose && subscription.dispose();
}
var parent = this.parent;
if (parent) {
this.parent = null;
parent.remove && parent.remove(this);
}
};
/***/ }),
/* 16 */
/***/ (function(module, exports, __webpack_require__) {
var isExpired = __webpack_require__(0);
var expireNode = __webpack_require__(2);
var lruPromote = __webpack_require__(13);
module.exports = onValueType;
function onValueType(node, type, json, path, depth, seed, results, requestedPath, requestedLength, optimizedPath, optimizedLength, fromReference, modelRoot, expired, expireImmediate, branchSelector, boxValues, materialized, reportMissing, treatErrorsAsValues, onValue, onMissing, onMaterialize) {
var _reportMissing = reportMissing;
var reportMaterialized = reportMissing;
if (type) {
if (isExpired(node, expireImmediate)) {
if (!node["f_invalidated"]) {
expireNode(node, expired, modelRoot);
}
} else {
lruPromote(modelRoot, node);
if (node.value === undefined) {
_reportMissing = false;
reportMaterialized = materialized;
} else {
if (seed) {
if (fromReference) {
requestedPath[depth] = null;
}
return onValue(node, type, depth, seed, results, requestedPath, optimizedPath, optimizedLength, fromReference, boxValues, materialized, treatErrorsAsValues);
}
return undefined;
}
}
}
if (materialized) {
seed && (results.hasValue = true);
} else if (!reportMaterialized) {
return undefined;
}
return onMissing(path, depth, results, requestedPath, requestedLength, fromReference, optimizedPath, optimizedLength, _reportMissing, materialized, json, branchSelector, boxValues, onMaterialize, modelRoot);
}
/***/ }),
/* 17 */
/***/ (function(module, exports, __webpack_require__) {
var getCachePosition = __webpack_require__(10);
module.exports = getBoundCacheNode;
function getBoundCacheNode(model, path) {
path = path || model._path;
var node = model._node;
if (!node || node["f_parent"] === undefined || node["f_invalidated"]) {
model._node = null;
if (path.length === 0) {
node = model._root.cache;
} else {
node = getCachePosition(model._root.cache, path);
if (path === model._path) {
model._node = node;
}
}
}
return node;
}
/***/ }),
/* 18 */
/***/ (function(module, exports, __webpack_require__) {
var arr = new Array(5);
var isExpired = __webpack_require__(0);
var expireNode = __webpack_require__(2);
var createHardlink = __webpack_require__(7);
var mergeJSONGraphNode = __webpack_require__(81);
var NullInPathError = __webpack_require__(4);
var iterateKeySet = __webpack_require__(23);
/**
* Merges a list of {@link JSONGraphEnvelope}s into a {@link JSONGraph}.
* @function
* @param {Object} model - the Model for which to merge the {@link JSONGraphEnvelope}s.
* @param {Array.<PathValue>} jsonGraphEnvelopes - the {@link JSONGraphEnvelope}s to merge.
* @return {Array.<Array.<Path>>} - an Array of Arrays where each inner Array is a list of requested and optimized paths (respectively) for the successfully set values.
*/
module.exports = setJSONGraphs;
function setJSONGraphs(model, jsonGraphEnvelopes, errorSelector, comparator, expireImmediate) {
var modelRoot = model._root;
var lru = modelRoot;
var expired = modelRoot.expired;
var version = modelRoot.version + 1;
var cache = modelRoot.cache;
var requestedPath = [];
var optimizedPath = [];
var requestedPaths = [];
var optimizedPaths = [];
var jsonGraphEnvelopeIndex = -1;
var jsonGraphEnvelopeCount = jsonGraphEnvelopes.length;
while (++jsonGraphEnvelopeIndex < jsonGraphEnvelopeCount) {
var jsonGraphEnvelope = jsonGraphEnvelopes[jsonGraphEnvelopeIndex];
var paths = jsonGraphEnvelope.paths;
var jsonGraph = jsonGraphEnvelope.jsonGraph;
var pathIndex = -1;
var pathCount = paths.length;
while (++pathIndex < pathCount) {
var path = paths[pathIndex];
optimizedPath.index = 0;
setJSONGraphPathSet(path, 0, cache, cache, cache, jsonGraph, jsonGraph, jsonGraph, requestedPaths, optimizedPaths, requestedPath, optimizedPath, version, expired, lru, comparator, errorSelector, expireImmediate);
}
}
arr[0] = undefined;
arr[1] = undefined;
arr[2] = undefined;
arr[3] = undefined;
arr[4] = undefined;
if (cache["f_version"] === version) {
modelRoot.version = version;
return [requestedPaths, optimizedPaths, true];
}
return [requestedPaths, optimizedPaths, false];
}
/* eslint-disable no-constant-condition */
function setJSONGraphPathSet(path, depth, root, parent, node, messageRoot, messageParent, message, requestedPaths, optimizedPaths, requestedPath, optimizedPath, version, expired, lru, comparator, errorSelector, expireImmediate) {
var note = {};
var branch = depth < path.length - 1;
var keySet = path[depth];
var key = iterateKeySet(keySet, note);
var optimizedIndex = optimizedPath.index;
do {
requestedPath.depth = depth;
setNode(root, parent, node, messageRoot, messageParent, message, key, branch, false, requestedPath, optimizedPath, version, expired, lru, comparator, errorSelector, expireImmediate);
requestedPath[depth] = key;
requestedPath.index = depth;
var nextNode = arr[0];
var nextParent = arr[1];
var nextOptimizedPath = arr[4];
nextOptimizedPath[nextOptimizedPath.index++] = key;
if (nextNode) {
if (branch) {
setJSONGraphPathSet(path, depth + 1, root, nextParent, nextNode, messageRoot, arr[3], arr[2], requestedPaths, optimizedPaths, requestedPath, nextOptimizedPath, version, expired, lru, comparator, errorSelector, expireImmediate);
} else {
requestedPaths.push(requestedPath.slice(0, requestedPath.index + 1));
optimizedPaths.push(nextOptimizedPath.slice(0, nextOptimizedPath.index));
}
}
key = iterateKeySet(keySet, note);
if (note.done) {
break;
}
optimizedPath.index = optimizedIndex;
} while (true);
}
/* eslint-enable */
function setReference(root, nodeArg, messageRoot, message, requestedPath, optimizedPathArg, version, expired, lru, comparator, errorSelector, expireImmediate) {
var parent;
var messageParent;
var node = nodeArg;
var reference = node.value;
var optimizedPath = reference.slice(0);
if (isExpired(node, expireImmediate)) {
expireNode(node, expired, lru);
node = undefined;
parent = root;
messageParent = messageRoot;
optimizedPath.index = reference.length;
} else {
var index = 0;
var container = node;
var count = reference.length - 1;
parent = node = root;
messageParent = message = messageRoot;
do {
var key = reference[index];
var branch = index < count;
optimizedPath.index = index;
setNode(root, parent, node, messageRoot, messageParent, message, key, branch, true, requestedPath, optimizedPath, version, expired, lru, comparator, errorSelector, expireImmediate);
node = arr[0];
optimizedPath = arr[4];
if (!node || typeof node !== 'object') {
optimizedPath.index = index;
return;
}
parent = arr[1];
message = arr[2];
messageParent = arr[3];
} while (index++ < count);
optimizedPath.index = index;
if (container["f_context"] !== node) {
createHardlink(container, node);
}
}
arr[0] = node;
arr[1] = parent;
arr[2] = message;
arr[3] = messageParent;
arr[4] = optimizedPath;
}
function setNode(root, parentArg, nodeArg, messageRoot, messageParentArg, messageArg, key, branch, reference, requestedPath, optimizedPathArg, version, expired, lru, comparator, errorSelector, expireImmediate) {
var node = nodeArg;
var type = node.$type;
var parent = parentArg;
var message = messageArg;
var optimizedPath = optimizedPathArg;
var messageParent = messageParentArg;
while (type === "ref") {
setReference(root, node, messageRoot, message, requestedPath, optimizedPath, version, expired, lru, comparator, errorSelector, expireImmediate);
node = arr[0];
if (!node || typeof node !== 'object') {
return;
}
parent = arr[1];
message = arr[2];
messageParent = arr[3];
optimizedPath = arr[4];
type = node.$type;
}
if (type === undefined) {
if (key == null) {
if (branch) {
throw new NullInPathError();
} else if (node) {
key = node["f_key"];
}
} else {
parent = node;
messageParent = message;
node = parent[key];
message = messageParent && messageParent[key];
}
node = mergeJSONGraphNode(parent, node, message, key, requestedPath, optimizedPath, version, expired, lru, comparator, errorSelector, expireImmediate);
}
arr[0] = node;
arr[1] = parent;
arr[2] = message;
arr[3] = messageParent;
arr[4] = optimizedPath;
}
/***/ }),
/* 19 */
/***/ (function(module, exports, __webpack_require__) {
var arr = new Array(3);
var isArray = Array.isArray;
var isExpired = __webpack_require__(0);
var expireNode = __webpack_require__(2);
var createHardlink = __webpack_require__(7);
var getCachePosition = __webpack_require__(10);
var isInternalKey = __webpack_require__(33);
var NullInPathError = __webpack_require__(4);
var mergeValueOrInsertBranch = __webpack_require__(48);
/**
* Sets a list of {@link PathMapEnvelope}s into a {@link JSONGraph}.
* @function
* @param {Object} model - the Model for which to insert the PathMaps.
* @param {Array.<PathMapEnvelope>} pathMapEnvelopes - the a list of {@link PathMapEnvelope}s to set.
* @return {Array.<Array.<Path>>} - an Array of Arrays where each inner Array is a list of requested and optimized paths (respectively) for the successfully set values.
*/
module.exports = setPathMaps;
function setPathMaps(model, pathMapEnvelopes, errorSelector, comparator, expireImmediate) {
var modelRoot = model._root;
var expired = modelRoot.expired;
var version = modelRoot.version + 1;
var bound = model._path;
var cache = modelRoot.cache;
var node = getCachePosition(cache, bound);
if (!node) {
return [[], [], false];
}
var parent = node["f_parent"] || cache;
var requestedPath = [];
var requestedPaths = [];
var optimizedPaths = [];
var optimizedIndex = bound.length;
var pathMapIndex = -1;
var pathMapCount = pathMapEnvelopes.length;
while (++pathMapIndex < pathMapCount) {
var pathMapEnvelope = pathMapEnvelopes[pathMapIndex];
var optimizedPath = bound.slice(0);
optimizedPath.index = optimizedIndex;
setPathMap(pathMapEnvelope.json, 0, cache, parent, node, requestedPaths, optimizedPaths, requestedPath, optimizedPath, version, expired, modelRoot, comparator, errorSelector, expireImmediate);
}
arr[0] = undefined;
arr[1] = undefined;
arr[2] = undefined;
if (cache["f_version"] === version) {
modelRoot.version = version;
return [requestedPaths, optimizedPaths, true];
}
return [requestedPaths, optimizedPaths, false];
}
/* eslint-disable no-constant-condition */
function setPathMap(pathMap, depth, root, parent, node, requestedPaths, optimizedPaths, requestedPath, optimizedPath, version, expired, lru, comparator, errorSelector, expireImmediate) {
var keys = getKeys(pathMap);
if (keys && keys.length) {
var keyIndex = 0;
var keyCount = keys.length;
var optimizedIndex = optimizedPath.index;
do {
var key = keys[keyIndex];
var child = pathMap[key];
var branch = !(!child || typeof child !== 'object') && !child.$type;
requestedPath.depth = depth;
setNode(root, parent, node, key, child, branch, false, requestedPath, optimizedPath, version, expired, lru, comparator, errorSelector, expireImmediate);
requestedPath[depth] = key;
requestedPath.index = depth;
var nextNode = arr[0];
var nextParent = arr[1];
var nextOptimizedPath = arr[2];
nextOptimizedPath[nextOptimizedPath.index++] = key;
if (nextNode) {
if (branch) {
setPathMap(child, depth + 1, root, nextParent, nextNode, requestedPaths, optimizedPaths, requestedPath, nextOptimizedPath, version, expired, lru, comparator, errorSelector, expireImmediate);
} else {
requestedPaths.push(requestedPath.slice(0, requestedPath.index + 1));
optimizedPaths.push(nextOptimizedPath.slice(0, nextOptimizedPath.index));
}
}
if (++keyIndex >= keyCount) {
break;
}
optimizedPath.index = optimizedIndex;
} while (true);
}
}
/* eslint-enable */
function setReference(value, root, nodeArg, requestedPath, optimizedPathArg, version, expired, lru, comparator, errorSelector, expireImmediate) {
var parent;
var node = nodeArg;
var reference = node.value;
var optimizedPath = reference.slice(0);
if (isExpired(node, expireImmediate)) {
expireNode(node, expired, lru);
node = undefined;
parent = root;
optimizedPath.index = reference.length;
} else {
var container = node;
parent = root;
node = node["f_context"];
if (node != null) {
parent = node["f_parent"] || root;
optimizedPath.index = reference.length;
} else {
var index = 0;
var count = reference.length - 1;
optimizedPath.index = index;
parent = node = root;
do {
var key = reference[index];
var branch = index < count;
var results = setNode(root, parent, node, key, value, branch, true, requestedPath, optimizedPath, version, expired, lru, comparator, errorSelector, expireImmediate);
node = arr[0];
optimizedPath = arr[2];
if (!node || typeof node !== 'object') {
optimizedPath.index = index;
return;
}
parent = arr[1];
} while (index++ < count);
optimizedPath.index = index;
if (container["f_context"] !== node) {
createHardlink(container, node);
}
}
}
arr[0] = node;
arr[1] = parent;
arr[2] = optimizedPath;
}
function setNode(root, parentArg, nodeArg, key, value, branch, reference, requestedPath, optimizedPathArg, version, expired, lru, comparator, errorSelector, expireImmediate) {
var node = nodeArg;
var type = node.$type;
var parent = parentArg;
var optimizedPath = optimizedPathArg;
while (type === "ref") {
setReference(value, root, node, requestedPath, optimizedPath, version, expired, lru, comparator, errorSelector, expireImmediate);
node = arr[0];
if (!node || typeof node !== 'object') {
return;
}
parent = arr[1];
optimizedPath = arr[2];
type = node && node.$type;
}
if (!branch || type === undefined) {
if (key == null) {
if (branch) {
throw new NullInPathError();
} else if (node) {
key = node["f_key"];
}
} else {
parent = node;
node = parent[key];
}
node = mergeValueOrInsertBranch(parent, node, key, value, branch, reference, requestedPath, optimizedPath, version, expired, lru, comparator, errorSelector, expireImmediate);
}
arr[0] = node;
arr[1] = parent;
arr[2] = optimizedPath;
}
function getKeys(pathMap) {
if (!(!pathMap || typeof pathMap !== 'object') && !pathMap.$type) {
var keys = [];
var itr = 0;
if (isArray(pathMap)) {
keys[itr++] = 'length';
}
for (var key in pathMap) {
if (isInternalKey(key)) {
continue;
}
keys[itr++] = key;
}
return keys;
}
return undefined;
}
/***/ }),
/* 20 */
/***/ (function(module, exports, __webpack_require__) {
/**
* Determined if the key passed in is an f_ internal key.
*
* @param {String} x The key
* @private
* @returns {Boolean}
*/
var f_ = __webpack_require__(92);
var regexp = new RegExp('^' + f_, 'i', 'g');
module.exports = regexp.test.bind(regexp);
/***/ }),
/* 21 */
/***/ (function(module, exports) {
module.exports = flatBufferToPaths;
function flatBufferToPaths(seed, paths, path) {
path = path || [];
paths = paths || [];
if (!seed) {
return paths;
}
var leaf = [];
var keys = seed['$keys'];
var keysLen = keys.length;
var keysIndex = -1,
key,
len;
while (++keysIndex < keysLen) {
var next = seed[keysIndex];
var keyset = keys[keysIndex];
if (!next || typeof next !== 'object') {
leaf.push(keyset);
} else {
flatBufferToPaths(next, paths, path.concat([keyset]));
}
}
if (leaf.length === 1) {
paths.push(path.concat(leaf));
} else if (leaf.length > 1) {
paths.push(path.concat([leaf]));
}
return paths;
}
/***/ }),
/* 22 */
/***/ (function(module, exports) {
module.exports = getHashCode;
function getHashCode(str) {
var hash = 5381,
i = str.length;
while (i) {
hash = hash * 33 ^ str.charCodeAt(--i);
}
// JavaScript does bitwise operations (like XOR, above) on 32-bit signed
// integers. Since we want the results to be always positive, convert the
// signed int to an unsigned by doing an unsigned bitshift.
return hash >>> 0;
}
/***/ }),
/* 23 */
/***/ (function(module, exports) {
var isArray = Array.isArray;
/**
* Takes in a keySet and a note attempts to iterate over it.
* If the value is a primitive, the key will be returned and the note will
* be marked done
* If the value is an object, then each value of the range will be returned
* and when finished the note will be marked done.
* If the value is an array, each value will be iterated over, if any of the
* inner values are ranges, those will be iterated over. When fully done,
* the note will be marked done.
*
* @param {Object|Array|String|Number} keySet -
* @param {Object} note - The non filled note
* @returns {String|Number|undefined} - The current iteration value.
* If undefined, then the keySet is empty
* @public
*/
module.exports = function iterateKeySet(keySet, note) {
if (note.isArray === undefined) {
initializeNote(keySet, note);
}
// Array iteration
if (note.isArray) {
var nextValue;
// Cycle through the array and pluck out the next value.
do {
if (note.loaded && note.rangeOffset > note.to) {
++note.arrayOffset;
note.loaded = false;
}
var idx = note.arrayOffset,
length = keySet.length;
if (idx >= length) {
note.done = true;
break;
}
var el = keySet[note.arrayOffset];
var type = typeof el;
// Inner range iteration.
if (type === 'object') {
if (!note.loaded) {
initializeRange(el, note);
}
// Empty to/from
if (note.empty) {
continue;
}
nextValue = note.rangeOffset++;
}
// Primitive iteration in array.
else {
++note.arrayOffset;
nextValue = el;
}
} while (nextValue === undefined);
return nextValue;
}
// Range iteration
else if (note.isObject) {
if (!note.loaded) {
initializeRange(keySet, note);
}
if (note.rangeOffset > note.to) {
note.done = true;
return undefined;
}
return note.rangeOffset++;
}
// Primitive value
else {
note.done = true;
return keySet;
}
};
function initializeRange(key, memo) {
var from = memo.from = key.from || 0;
var to = memo.to = key.to || typeof key.length === 'number' && memo.from + key.length - 1 || 0;
memo.rangeOffset = memo.from;
memo.loaded = true;
if (from > to) {
memo.empty = true;
}
}
function initializeNote(key, note) {
note.done = false;
var isObject = note.isObject = !!(key && typeof key === 'object');
note.isArray = isObject && isArray(key);
note.arrayOffset = 0;
}
/***/ }),
/* 24 */
/***/ (function(module, exports, __webpack_require__) {
module.exports = __webpack_require__(40);
/***/ }),
/* 25 */
/***/ (function(module, exports, __webpack_require__) {
module.exports = __webpack_require__(43);
/***/ }),
/* 26 */
/***/ (function(module, exports) {
module.exports = inlineJSONGraphValue;
/* eslint-disable no-constant-condition */
function inlineJSONGraphValue(node, path, length, seed, branch) {
var key,
depth = 0,
prev,
curr = seed.jsonGraph;
if (!curr) {
seed.jsonGraph = curr = {};
}
do {
prev = curr;
key = path[depth++];
if (depth >= length) {
curr = prev[key] = branch !== true ? node : prev[key] || {};
break;
}
curr = prev[key] || (prev[key] = {});
} while (true);
return curr;
}
/* eslint-enable */
/***/ }),
/* 27 */
/***/ (function(module, exports) {
var isArray = Array.isArray;
module.exports = onMissing;
/* eslint-disable no-constant-condition */
function onMissing(path, depth, results, requestedPath, requestedLength, fromReference, optimizedPath, optimizedLength, reportMissing, reportMaterialized, json, branchSelector, boxValues, onMaterialize, modelRoot) {
if (!reportMissing && !reportMaterialized) {
return;
}
var keyset,
restPathIndex = -1,
restPathCount = requestedLength - depth,
restPath = restPathCount && new Array(restPathCount) || undefined;
while (++restPathIndex < restPathCount) {
keyset = path[restPathIndex + depth];
if (isEmptyKeySet(keyset)) {
return;
}
restPath[restPathIndex] = keyset;
}
var index, count, mPath;
var lastKeyIsNull = keyset === null;
var isRequestedPath = reportMissing;
var missDepth, missTotal, missingPath, missingPaths;
if (!reportMissing) {
missDepth = optimizedLength;
missingPath = optimizedPath;
missTotal = optimizedLength + restPathCount - Number(lastKeyIsNull);
} else {
missDepth = depth;
missTotal = requestedLength;
missingPath = requestedPath;
missingPaths = results.requested || (results.requested = []);
}
do {
if (restPathCount < requestedLength || !isRequestedPath) {
index = -1;
count = missDepth;
mPath = new Array(missTotal);
while (++index < count) {
mPath[index] = missingPath[index];
}
restPathIndex = -1;
while (index < missTotal) {
mPath[index++] = restPath[++restPathIndex];
}
}
// break after inserting both requested and optimized missing paths
if (isRequestedPath = !isRequestedPath) {
if (reportMissing) {
missingPaths[missingPaths.length] = mPath;
}
break;
}
missingPaths[missingPaths.length] = mPath || restPath;
missDepth = optimizedLength;
missingPath = optimizedPath;
missingPaths = results.missing || (results.missing = []);
missTotal = optimizedLength + restPathCount - Number(lastKeyIsNull);
} while (true);
if (reportMaterialized) {
return onMaterialize(json, mPath, missDepth, missTotal, branchSelector, boxValues, modelRoot, reportMissing);
}
}
/* eslint-enable */
function isEmptyKeySet(keyset) {
// false if the keyset is a primitive
if ('object' !== typeof keyset) {
return false;
} else if (keyset === null) {
return false;
}
if (isArray(keyset)) {
// return true if the keyset is an empty array
return keyset.length === 0;
}
var rangeEnd = keyset.to,
from = keyset.from || 0;
if ('number' !== typeof rangeEnd) {
rangeEnd = from + (keyset.length || 0);
}
// false if trying to request incorrect or empty ranges
// e.g. { from: 10, to: 0 } or { from: 5, length: 0 }
return from >= rangeEnd;
}
/***/ }),
/* 28 */
/***/ (function(module, exports, __webpack_require__) {
var arr = new Array(2);
var isExpired = __webpack_require__(0);
var expireNode = __webpack_require__(2);
var lruPromote = __webpack_require__(13);
var getSize = __webpack_require__(9);
var createHardlink = __webpack_require__(7);
var getBoundCacheNode = __webpack_require__(17);
var updateNodeAncestors = __webpack_require__(11);
var iterateKeySet = __webpack_require__(23);
/**
* Invalidates a list of Paths in a JSON Graph.
* @function
* @param {Object} model - the Model for which to insert the PathValues.
* @param {Array.<PathValue>} paths - the PathValues to set.
*/
module.exports = invalidatePathSets;
function invalidatePathSets(model, paths, expireImmediate) {
var modelRoot = model._root;
var lru = modelRoot;
var expired = modelRoot.expired;
var version = modelRoot.version + 1;
var cache = modelRoot.cache;
var node = getBoundCacheNode(model);
if (!node) {
return false;
}
var pathIndex = -1;
var pathCount = paths.length;
var parent = node["f_parent"] || cache;
while (++pathIndex < pathCount) {
var path = paths[pathIndex];
invalidatePathSet(path, 0, cache, parent, node, version, expired, lru, expireImmediate);
}
arr[0] = undefined;
arr[1] = undefined;
if (cache["f_version"] === version) {
modelRoot.version = version;
return true;
}
return false;
}
function invalidatePathSet(path, depth, root, parent, node, version, expired, lru, expireImmediate) {
var note = {};
var branch = depth < path.length - 1;
var keySet = path[depth];
var key = iterateKeySet(keySet, note);
do {
invalidateNode(root, parent, node, key, branch, false, version, expired, lru, expireImmediate);
var nextNode = arr[0];
var nextParent = arr[1];
if (nextNode) {
if (branch) {
invalidatePathSet(path, depth + 1, root, nextParent, nextNode, version, expired, lru, expireImmediate);
} else {
updateNodeAncestors(nextNode, getSize(nextNode), lru, version);
}
}
key = iterateKeySet(keySet, note);
} while (!note.done);
}
function invalidateReference(root, nodeArg, version, expired, lru, expireImmediate) {
var node = nodeArg;
if (isExpired(node, expireImmediate)) {
expireNode(node, expired, lru);
arr[0] = undefined;
arr[1] = root;
return;
}
lruPromote(lru, node);
var container = node;
var reference = node.value;
var parent = root;
node = node["f_context"];
if (node != null) {
parent = node["f_parent"] || root;
} else {
var index = 0;
var count = reference.length - 1;
parent = node = root;
do {
var key = reference[index];
var branch = index < count;
invalidateNode(root, parent, node, key, branch, true, version, expired, lru, expireImmediate);
node = arr[0];
if (!node && typeof node !== 'object') {
return;
}
parent = arr[1];
} while (index++ < count);
if (container["f_context"] !== node) {
createHardlink(container, node);
}
}
arr[0] = node;
arr[1] = parent;
}
function invalidateNode(root, parentArg, nodeArg, key, branch, reference, version, expired, lru, expireImmediate) {
var node = nodeArg;
var parent = parentArg;
var type = node.$type;
while (type === "ref") {
invalidateReference(root, node, version, expired, lru, expireImmediate);
node = arr[0];
if (!node && typeof node !== 'object') {
return;
}
parent = arr[1];
type = node.$type;
}
if (type === undefined) {
if (key == null) {
if (branch) {
throw new Error('`null` is not allowed in branch key positions.');
} else if (node) {
key = node["f_key"];
}
} else {
parent = node;
node = parent[key];
}
}
arr[0] = node;
arr[1] = parent;
}
/***/ }),
/* 29 */
/***/ (function(module, exports, __webpack_require__) {
var lruSplice = __webpack_require__(54);
var isInternalKey = __webpack_require__(33);
var unlinkBackReferences = __webpack_require__(84);
var unlinkForwardReference = __webpack_require__(85);
var updateBackReferenceVersions = __webpack_require__(31);
module.exports = removeNodeAndDescendants;
function removeNodeAndDescendants(node, parent, key, lru, version) {
if (!(!node || typeof node !== 'object')) {
var type = node.$type;
if (type === undefined) {
for (var key2 in node) {
if (!isInternalKey(key2)) {
removeNodeAndDescendants(node[key2], node, key2, lru, version);
}
}
} else {
if (type === "ref") {
unlinkForwardReference(node);
}
lruSplice(lru, node);
}
unlinkBackReferences(updateBackReferenceVersions(node, version));
parent[key] = node["f_parent"] = undefined;
return true;
}
return false;
}
/***/ }),
/* 30 */
/***/ (function(module, exports, __webpack_require__) {
var arr = new Array(3);
var isExpired = __webpack_require__(0);
var expireNode = __webpack_require__(2);
var createHardlin