UNPKG

@graffy/common

Version:

Common libraries that used by various Graffy modules.

324 lines (254 loc) 10.7 kB
"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; }