@graffy/common
Version:
Common libraries that used by various Graffy modules.
324 lines (254 loc) • 10.7 kB
JavaScript
"use strict";
var _sliceInstanceProperty = require("@babel/runtime-corejs3/core-js-stable/instance/slice");
var _Array$from = require("@babel/runtime-corejs3/core-js-stable/array/from");
var _Symbol2 = require("@babel/runtime-corejs3/core-js-stable/symbol");
var _getIteratorMethod = require("@babel/runtime-corejs3/core-js/get-iterator-method");
var _Array$isArray2 = require("@babel/runtime-corejs3/core-js-stable/array/is-array");
var _getIterator = require("@babel/runtime-corejs3/core-js/get-iterator");
var _bindInstanceProperty = require("@babel/runtime-corejs3/core-js-stable/instance/bind");
var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault");
exports.__esModule = true;
exports.default = decodeGraph;
exports.getRangeNodes = getRangeNodes;
var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/objectWithoutPropertiesLoose"));
var _symbol = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/symbol"));
var _isArray = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/array/is-array"));
var _map = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/map"));
var _create = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/object/create"));
var _defineProperty = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/object/define-property"));
var _node2 = require("../../node");
var _util = require("../../util.js");
var _ops = require("../../ops");
var _index = require("../index.js");
function _createForOfIteratorHelperLoose(o, allowArrayLike) { var _context2; var it; if (typeof _Symbol2 === "undefined" || _getIteratorMethod(o) == null) { if (_Array$isArray2(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; return function () { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } it = _getIterator(o); return _bindInstanceProperty(_context2 = it.next).call(_context2, it); }
function _unsupportedIterableToArray(o, minLen) { var _context; if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = _sliceInstanceProperty(_context = Object.prototype.toString.call(o)).call(_context, 8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return _Array$from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
var LINK_PLACEHOLDER = (0, _symbol.default)();
function descend(tree, path) {
var node = tree;
for (var _iterator = _createForOfIteratorHelperLoose(path), _step; !(_step = _iterator()).done;) {
var key = _step.value;
if (!node) return;
if ((0, _isArray.default)(node)) node = node.props;
if (!(key in node)) return undefined;
node = node[key];
}
return node;
}
function decodeGraph(graph, query, links) {
if (links === void 0) {
links = [];
}
var result = graph && decodeChildren(graph, query, links);
var link;
while (link = links.shift()) {
var _link = link,
from = _link[0],
key = _link[1],
path = _link[2],
args = _link[3];
var node = descend(result, path); // console.log('resolving link', link, 'found', node, 'in', result);
if (node === LINK_PLACEHOLDER) {
// Try this link again later. This is to resolve multi-hop links.
// TODO: Cycle detection.
links.push(link);
} else {
// console.log('Replacing placeholder at', key, 'with', node);
from[key] = node;
if (typeof node === 'object' && node) {
node.$ref = path;
if (args) node.$key = args;
}
}
}
return result;
}
function decodeChildren(graph, query, links) {
var resObj = {};
var hasEncoded = false;
var hasRanges = false; // First, we construct the result object
for (var _iterator2 = _createForOfIteratorHelperLoose(graph), _step2; !(_step2 = _iterator2()).done;) {
var node = _step2.value;
var _key = node.key;
if (_key[0] === '\0') hasEncoded = true;
if ((0, _node2.isRange)(node)) {
if (_key === node.end) {
resObj[_key] = null;
} else {
hasRanges = true;
}
continue;
}
if ((0, _node2.isLink)(node)) {
links.push([resObj, _key, node.path]);
resObj[_key] = LINK_PLACEHOLDER;
continue;
}
if ((0, _node2.isBranch)(node)) {
resObj[_key] = decodeChildren(node.children, query == null ? void 0 : query[_key], links);
continue;
}
if (typeof node.value === 'object' && node.value) {
// The API must appear to return the value directly, but when
// JSON-stringified it returned object should be wrapped in a $val.
var child = (0, _create.default)(node.value);
child.$val = node.value;
resObj[_key] = child;
} else {
resObj[_key] = node.value;
}
}
if (hasRanges) {
var putRanges = [];
var last = null;
for (var _iterator3 = _createForOfIteratorHelperLoose(graph), _step3; !(_step3 = _iterator3()).done;) {
var _step3$value = _step3.value,
key = _step3$value.key,
end = _step3$value.end;
if (last) {
if (last.end) {
if (key === (0, _ops.keyAfter)(last.end)) {
last.end = end || key;
continue;
}
} else {
if (key === (0, _ops.keyAfter)(last.key)) key = last.key;
}
}
if (end && key !== end) {
last = {
key: key,
end: end
};
putRanges.push(last);
} else {
last = {
key: key
};
}
}
if (putRanges.length === 1 && putRanges[0].key === '' && putRanges[0].end === "\uFFFF") {
resObj.$put = true;
} else {
resObj.$put = (0, _map.default)(putRanges).call(putRanges, function (rNode) {
return (0, _index.decodeArgs)(rNode);
});
}
}
/*
We return an array, not an object, as the decoded value in three
situations:
1. The query had pagination parameters
2. The result had ranges of unknown
3. The result has encoded values, which must be decoded into an $key
*/
if (query) {
if ((0, _isArray.default)(query)) {
if (query.length !== 1) throw Error('decodeGraph.multi_page');
return makeArray(graph, query[0], links, resObj);
} else if (isPaginated(query)) {
return makeArray(graph, query, links, resObj);
}
}
if (hasEncoded) {
return makeArray(graph, null, links, resObj);
}
return resObj;
}
function isPaginated(_temp) {
var _ref = _temp === void 0 ? {} : _temp,
key = _ref.$key;
return key && (key.$first || key.$last || key.$after || key.$before || key.$since || key.$until || key.all);
}
function isMinKey(key) {
return key === '' || key[0] === '\0' && key[key.length - 1] === '.';
}
function isMaxKey(key) {
return key === "\uFFFF" || key[0] === '\0' && key[key.length - 2] === '.' && key[key.length - 1] === "\uFFFF";
}
function prefix(key) {
if (key[0] === '\0') {
var parts = key.split('.');
return parts[parts.length - 2] ? parts[parts.length - 2] + '.' : '';
}
return '';
}
function makeArray(graph, query, links, object) {
var _query$$key, _query$$key2;
var resArr = [];
if (query && isPaginated(query)) {
var queryNode = (0, _index.encodeQuery)(query)[0];
graph = getRangeNodes(graph, queryNode);
}
for (var _iterator4 = _createForOfIteratorHelperLoose(graph), _step4; !(_step4 = _iterator4()).done;) {
var node = _step4.value;
// console.log('node', node);
var key = node.key;
var child = object[key];
if (typeof child === 'undefined' || child === null) continue;
var args = (0, _index.decodeArgs)(node);
var _args = args,
cursor = _args.cursor,
rest = (0, _objectWithoutPropertiesLoose2.default)(_args, ["cursor"]);
if ((0, _util.isEmpty)(rest) && (0, _isArray.default)(cursor)) args = cursor;
if (child === LINK_PLACEHOLDER) {
links.push([resArr, resArr.length, node.path, args]);
resArr.push(LINK_PLACEHOLDER); // Placeholder that will be replaced.
continue;
}
if (typeof child === 'object' && child) child.$key = args;
resArr.push(child);
} // Add next and previous page links
var firstNode = graph[0];
var lastNode = graph[graph.length - 1];
var firstKey = firstNode.key;
var lastKey = lastNode.end || lastNode.key;
var limit = (query == null ? void 0 : (_query$$key = query.$key) == null ? void 0 : _query$$key.$first) || (query == null ? void 0 : (_query$$key2 = query.$key) == null ? void 0 : _query$$key2.$last) || resArr.length || 1;
if (!isMinKey(firstKey)) {
(0, _defineProperty.default)(resArr, 'prevPage', {
value: (0, _index.decodeArgs)({
key: (0, _ops.keyBefore)(firstKey),
end: prefix(firstKey),
limit: limit
})
});
}
if (!isMaxKey(lastKey)) {
(0, _defineProperty.default)(resArr, 'nextPage', {
value: (0, _index.decodeArgs)({
key: (0, _ops.keyAfter)(lastKey),
end: prefix(lastKey) + "\uFFFF",
limit: limit
})
});
} // Object.defineProperty(resArr, 'pageInfo', { value: pageInfo(graph) });
(0, _defineProperty.default)(resArr, 'props', {
value: object
});
return resArr;
}
function getRangeNodes(graph, _ref2) {
var key = _ref2.key,
end = _ref2.end,
_ref2$limit = _ref2.limit,
limit = _ref2$limit === void 0 ? Infinity : _ref2$limit;
var result = [];
if (key < end) {
for (var i = (0, _node2.findFirst)(graph, key); key <= end && limit > 0; i++) {
var node = graph[i];
if (!node || key < node.key) break;
result.push(node);
if (!(0, _node2.isRange)(node)) limit--;
key = (0, _ops.keyAfter)(node.end || node.key);
}
} else {
for (var _i = (0, _node2.findLast)(graph, key) - 1; key >= end && limit > 0; _i--) {
var _node = graph[_i];
if (!_node || key > (_node.end || _node.key)) break;
result.unshift(_node);
if (!(0, _node2.isRange)(_node)) limit--;
key = (0, _ops.keyBefore)(_node.key);
}
}
return result;
}