UNPKG

informed

Version:

A lightweight framework and utility for building powerful forms in React applications

140 lines (136 loc) 4.51 kB
import { createForOfIteratorHelper as _createForOfIteratorHelper, typeof as _typeof } from './_virtual/_rollupPluginBabelHelpers.js'; import { ObjectMap } from './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 _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.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 && _typeof(a) == 'object' && _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 = _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.get(origObj, parsedKey); var nextValue = 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; } export { createDeepProxy, createProxyHandler, isDeepChanged, unwrap };