informed
Version:
A lightweight framework and utility for building powerful forms in React applications
147 lines (141 loc) • 4.77 kB
JavaScript
;
Object.defineProperty(exports, '__esModule', { value: true });
var _rollupPluginBabelHelpers = require('./_virtual/_rollupPluginBabelHelpers.js');
var ObjectMap = require('./ObjectMap.js');
var OWN_KEYS_SYMBOL = Symbol('own keys');
var ORIG_SYMBOL = Symbol('original object');
var PROXY = 'p';
var AFFECTED = 'a';
var CACHE = 'c';
var getProto = Object.getPrototypeOf;
var objectsToTrack = new WeakMap();
function shouldTrack(obj) {
if (objectsToTrack.has(obj)) {
return objectsToTrack.get(obj);
}
return obj && (getProto(obj) === Object.prototype || getProto(obj) === Array.prototype);
}
function isObject(obj) {
return _rollupPluginBabelHelpers["typeof"](obj) === 'object' && obj !== null;
}
function isOwnKeysChanged(origObj, nextObj) {
var origKeys = Reflect.ownKeys(origObj);
var nextKeys = Reflect.ownKeys(nextObj);
return origKeys.length !== nextKeys.length || origKeys.some(function (k, i) {
return k !== nextKeys[i];
});
}
function createProxyHandler(origObj) {
function recordUsage(h, key) {
var used = h[AFFECTED].get(origObj);
if (!used) {
used = new Set();
h[AFFECTED].set(origObj, used);
}
used.add(key);
}
return {
get: function get(target, key) {
if (key === ORIG_SYMBOL) {
return origObj;
}
if (key === 'toJSON') {
return function toJSON() {
return target;
};
}
var usedKey = key;
var value = target[String(key)];
// special access for path keys
if (typeof key === 'string' && key.indexOf('.') !== -1 && !(key in target)) {
var _ObjectMap$get;
value = (_ObjectMap$get = ObjectMap.ObjectMap.get(target, key)) !== null && _ObjectMap$get !== void 0 ? _ObjectMap$get : value;
usedKey = "$key:".concat(key);
}
recordUsage(this, usedKey);
return createDeepProxy(value, this[AFFECTED], this[CACHE]);
},
has: function has(target, key) {
recordUsage(this, key);
return key in target;
},
ownKeys: function ownKeys(target) {
recordUsage(this, OWN_KEYS_SYMBOL);
return Reflect.ownKeys(target);
}
};
}
function createDeepProxy(target, affected, cache) {
if (!shouldTrack(target)) return target;
var proxyHandler = cache.get(target);
if (!proxyHandler) {
proxyHandler = createProxyHandler(target);
proxyHandler[PROXY] = new Proxy(target, proxyHandler);
cache.set(target, proxyHandler);
}
proxyHandler[AFFECTED] = affected;
proxyHandler[CACHE] = cache;
return proxyHandler[PROXY];
}
function equal(a, b) {
if (a === b) return true;
if (a && b && _rollupPluginBabelHelpers["typeof"](a) == 'object' && _rollupPluginBabelHelpers["typeof"](b) == 'object') {
if (a.constructor !== b.constructor) return false;
var length, i, keys;
if (Array.isArray(a)) {
length = a.length;
if (length != b.length) return false;
for (i = length; i-- !== 0;) if (!equal(a[i], b[i])) return false;
return true;
}
if (a.valueOf !== Object.prototype.valueOf) return a.valueOf() === b.valueOf();
if (a.toString !== Object.prototype.toString) return a.toString() === b.toString();
keys = Object.keys(a);
length = keys.length;
if (length !== Object.keys(b).length) return false;
for (i = length; i-- !== 0;) if (!Object.prototype.hasOwnProperty.call(b, keys[i])) return false;
}
return a !== a && b !== b;
}
function isDeepChanged(origObj, nextObj, affected) {
if (Object.is(origObj, nextObj) && !isObject(origObj)) {
return false;
}
if (!isObject(origObj) || !isObject(nextObj)) {
return true;
}
var used = affected.get(origObj);
if (!used) {
return true;
}
var _iterator = _rollupPluginBabelHelpers.createForOfIteratorHelper(used),
_step;
try {
for (_iterator.s(); !(_step = _iterator.n()).done;) {
var key = _step.value;
var isChanged = key === OWN_KEYS_SYMBOL ? isOwnKeysChanged(origObj, nextObj) : isDeepChanged(origObj[key], nextObj[key], affected);
if (typeof key === 'string' && /^\$key:/.test(key)) {
var parsedKey = key.replace(/^\$key:/, '');
var origValue = ObjectMap.ObjectMap.get(origObj, parsedKey);
var nextValue = ObjectMap.ObjectMap.get(nextObj, parsedKey);
isChanged = !equal(origValue, nextValue);
}
if (isChanged) {
return isChanged;
}
}
} catch (err) {
_iterator.e(err);
} finally {
_iterator.f();
}
return false;
}
function unwrap(obj) {
if (!shouldTrack(obj)) return obj;
return ORIG_SYMBOL in obj ? obj[ORIG_SYMBOL] : obj;
}
exports.createDeepProxy = createDeepProxy;
exports.createProxyHandler = createProxyHandler;
exports.isDeepChanged = isDeepChanged;
exports.unwrap = unwrap;