"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. */ var _realm = require("../realm.js"); var _index = require("../values/index.js"); var _invariant = require("../invariant.js"); var _invariant2 = _interopRequireDefault(_invariant); var _utils = require("./utils"); var _index2 = require("../methods/index.js"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } // ReactElementSet keeps records around of the values // of ReactElement/JSX nodes so we can return the same immutable values // where possible, i.e.
===
// // Rather than uses hashes, this class uses linked Maps to track equality of objects. // It does this by recursively iterating through objects, by their properties/symbols and using // each property key as a map, and then from that map, each value as a map. The value // then links to the subsequent property/symbol in the object. This approach ensures insertion // is maintained through all objects. var ReactElementSet = function () { function ReactElementSet(realm, equivalenceSet) { _classCallCheck(this, ReactElementSet); this.realm = realm; this.equivalenceSet = equivalenceSet; this.reactElementRoot = new Map(); this.objectRoot = new Map(); this.arrayRoot = new Map(); this.emptyArray = new _index.ArrayValue(realm); this.emptyObject = new _index.ObjectValue(realm, realm.intrinsics.ObjectPrototype); } _createClass(ReactElementSet, [{ key: "_createNode", value: function _createNode() { return { map: new Map(), value: null }; } }, { key: "_getKey", value: function _getKey(key, map) { if (!map.has(key)) { map.set(key, new Map()); } return map.get(key); } }, { key: "_getValue", value: function _getValue(val, map) { if (val instanceof _index.StringValue || val instanceof _index.NumberValue) { val = val.value; } else if (val instanceof _index.AbstractValue) { val = this.equivalenceSet.add(val); } else if (val instanceof _index.ArrayValue) { val = this._getArrayValue(val); } else if (val instanceof _index.ObjectValue && !(val instanceof _index.FunctionValue)) { val = this._getObjectValue(val); } if (!map.has(val)) { map.set(val, this._createNode()); } return map.get(val); } // for objects: [key/symbol] -> [key/symbol]... as nodes }, { key: "_getObjectValue", value: function _getObjectValue(object) { if ((0, _utils.isReactElement)(object)) { return this.add(object); } var currentMap = this.objectRoot; var result = void 0; var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = object.properties[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var _ref = _step.value; var _ref2 = _slicedToArray(_ref, 1); var propName = _ref2[0]; currentMap = this._getKey(propName, currentMap); var prop = (0, _index2.Get)(this.realm, object, propName); result = this._getValue(prop, currentMap); currentMap = result.map; } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } var _iteratorNormalCompletion2 = true; var _didIteratorError2 = false; var _iteratorError2 = undefined; try { for (var _iterator2 = object.symbols[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { var _ref3 = _step2.value; var _ref4 = _slicedToArray(_ref3, 1); var symbol = _ref4[0]; currentMap = this._getKey(symbol, currentMap); var prop = (0, _index2.Get)(this.realm, object, symbol); result = this._getValue(prop, currentMap); currentMap = result.map; } } catch (err) { _didIteratorError2 = true; _iteratorError2 = err; } finally { try { if (!_iteratorNormalCompletion2 && _iterator2.return) { _iterator2.return(); } } finally { if (_didIteratorError2) { throw _iteratorError2; } } } if (result === undefined) { return this.emptyObject; } if (result.value === null) { result.value = object; } return result.value; } // for arrays: [0] -> [1] -> [2]... as nodes }, { key: "_getArrayValue", value: function _getArrayValue(array) { var lengthValue = (0, _index2.Get)(this.realm, array, "length"); (0, _invariant2.default)(lengthValue instanceof _index.NumberValue); var length = lengthValue.value; var currentMap = this.arrayRoot; var result = void 0; for (var i = 0; i < length; i++) { currentMap = this._getKey(i, currentMap); var element = (0, _index2.Get)(this.realm, array, "" + i); result = this._getValue(element, currentMap); currentMap = result.map; } if (result === undefined) { return this.emptyArray; } if (result.value === null) { result.value = array; } return result.value; } }, { key: "add", value: function add(reactElement) { var currentMap = this.reactElementRoot; // type currentMap = this._getKey("type", currentMap); var type = (0, _index2.Get)(this.realm, reactElement, "type"); var result = this._getValue(type, currentMap); currentMap = result.map; // key currentMap = this._getKey("key", currentMap); var key = (0, _index2.Get)(this.realm, reactElement, "key"); result = this._getValue(key, currentMap); currentMap = result.map; // ref currentMap = this._getKey("ref", currentMap); var ref = (0, _index2.Get)(this.realm, reactElement, "ref"); result = this._getValue(ref, currentMap); currentMap = result.map; // props currentMap = this._getKey("props", currentMap); var props = (0, _index2.Get)(this.realm, reactElement, "props"); result = this._getValue(props, currentMap); currentMap = result.map; if (result.value === null) { result.value = reactElement; } (0, _invariant2.default)(result.value instanceof _index.ObjectValue); return result.value; } }]); return ReactElementSet; }(); exports.default = ReactElementSet; //# sourceMappingURL=ReactElementSet.js.map