UNPKG

@graffy/common

Version:

Common libraries that used by various Graffy modules.

218 lines (173 loc) 7.92 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 _Symbol = require("@babel/runtime-corejs3/core-js-stable/symbol"); var _getIteratorMethod = require("@babel/runtime-corejs3/core-js/get-iterator-method"); var _Array$isArray = 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 = slice; exports.sliceRange = sliceRange; var _extends2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/extends")); var _node2 = require("../node"); var _step2 = require("./step"); var _path = require("../path"); var _merge = _interopRequireDefault(require("./merge")); var _add = _interopRequireDefault(require("./add")); var _testing = require("@graffy/testing"); function _createForOfIteratorHelperLoose(o, allowArrayLike) { var _context2; var it; if (typeof _Symbol === "undefined" || _getIteratorMethod(o) == null) { if (_Array$isArray(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 Result = /*#__PURE__*/function () { function Result(root) { // When linked queries are added, they are forwarded to the root. this.root = root || this; } var _proto = Result.prototype; _proto.addKnown = function addKnown(node) { this.known = this.known || []; (0, _merge.default)(this.known, [node]); }; _proto.addUnknown = function addUnknown(node) { this.unknown = this.unknown || []; this.unknown.push(node); }; _proto.addLinked = function addLinked(children) { if (this.root !== this) return this.root.addLinked(children); this.linked = this.linked || []; (0, _add.default)(this.linked, children); }; return Result; }(); function slice(graph, query, root) { var result = new Result(root); var currentQuery = query; while (currentQuery) { var index = 0; for (var _iterator = _createForOfIteratorHelperLoose(currentQuery), _step; !(_step = _iterator()).done;) { var queryNode = _step.value; if ((0, _node2.isRange)(queryNode)) { sliceRange(graph, queryNode, result); } else { var key = queryNode.key; index = (0, _node2.findFirst)(graph, key, index); // console.log('Index', graph, key, index); sliceNode(graph[index], queryNode, result); } } currentQuery = root ? undefined : result.linked; delete result.linked; } delete result.root; // console.log( // 'slice:\n' + format(graph) + format(query) + format(result.known), // ); return result; } function sliceNode(graph, query, result) { var key = query.key, version = query.version; var root = result.root; // console.log('Slicing', graph, query); if (!graph || graph.key > key || (0, _node2.isOlder)(graph, version)) { // The node found doesn't match the query or it's too old. result.addUnknown(query); } else if ((0, _node2.isRange)(graph)) { // The graph is indicating that this value was deleted. if ((0, _node2.isBranch)(query)) { var _slice = slice([{ key: '', end: "\uFFFF", version: graph.version }], query.children), known = _slice.known; result.addKnown({ key: key, version: graph.version, children: known }); } else { result.addKnown({ key: key, end: key, version: graph.version }); } } else if ((0, _node2.isBranch)(graph) && (0, _node2.isBranch)(query)) { // Both sides are branches; recurse into them. var _slice2 = slice(graph.children, query.children, root), _known = _slice2.known, unknown = _slice2.unknown; if (_known) result.addKnown((0, _extends2.default)({}, graph, { children: _known })); if (unknown) result.addUnknown((0, _extends2.default)({}, query, { children: unknown })); } else if ((0, _node2.isLink)(graph)) { result.addKnown(graph); result.addLinked((0, _node2.isBranch)(query) ? (0, _path.wrap)(query.children, graph.path, version) : (0, _path.wrapValue)(query.value, graph.path, version)); } else if ((0, _node2.isBranch)(graph) && query.options && query.options.subtree) { // This option allows a query to say "give me the subtree under this" // without knowing specifically what's available. If using this, the // value of "unknown" is no longer reliable. It is intended for use in // optimistic updates. result.addKnown(graph); } else if ((0, _node2.isBranch)(graph) || (0, _node2.isBranch)(query)) { // One side is a branch while the other is a leaf; throw error. throw new Error('slice.leaf_branch_mismatch:' + (0, _testing.format)(graph) + '\n' + (0, _testing.format)(query)); } else { result.addKnown(graph); } } function sliceRange(graph, query, result) { var key = query.key, end = query.end, _query$limit = query.limit, limit = _query$limit === void 0 ? Infinity : _query$limit, version = query.version; var step = key < end ? 1 : -1; 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 || (0, _node2.isOlder)(node, version)) break; if ((0, _node2.isRange)(node)) { result.addKnown(getOverlap(node, key, end)); } else { sliceNode(node, (0, _extends2.default)({}, query, { key: key }), result); limit--; } key = (0, _step2.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) || (0, _node2.isOlder)(_node, version)) break; if ((0, _node2.isRange)(_node)) { result.addKnown(getOverlap(_node, end, key)); } else { sliceNode(_node, (0, _extends2.default)({}, query, { key: key }), result); limit--; } key = (0, _step2.keyBefore)(_node.key); } } if (limit && (step < 0 ? key > end : key < end)) { var unknown = (0, _extends2.default)({}, query, { key: key, end: end, limit: limit }); result.addUnknown(unknown); } } function getOverlap(node, key, end) { if (node.key >= key && node.end <= end) return node; return (0, _extends2.default)({}, node, { key: node.key > key ? node.key : key, end: node.end < end ? node.end : end }); }