vest-utils
Version:
218 lines (203 loc) • 5.91 kB
JavaScript
;
// The module is named "isArrayValue" since it
// is conflicting with a nested npm dependency.
// We may need to revisit this in the future.
function isArray(value) {
return Boolean(Array.isArray(value));
}
/**
* A safe hasOwnProperty access
*/
function hasOwnProperty(obj, key) {
return Object.prototype.hasOwnProperty.call(obj, key);
}
function isNumeric(value) {
const str = String(value);
const num = Number(value);
const result = !isNaN(parseFloat(str)) && !isNaN(Number(value)) && isFinite(num);
return Boolean(result);
}
function numberEquals(value, eq) {
return isNumeric(value) && isNumeric(eq) && Number(value) === Number(eq);
}
function lengthEquals(value, arg1) {
return numberEquals(value.length, arg1);
}
function isNull(value) {
return value === null;
}
function isUndefined(value) {
return value === undefined;
}
function isNullish(value) {
return isNull(value) || isUndefined(value);
}
function isObject(v) {
return typeof v === 'object' && !isNullish(v);
}
function isEmpty(value) {
if (!value) {
return true;
}
else if (hasOwnProperty(value, 'length')) {
return lengthEquals(value, 0);
}
else if (isObject(value)) {
return lengthEquals(Object.keys(value), 0);
}
return false;
}
function isFunction(value) {
return typeof value === 'function';
}
function isStringValue(v) {
return String(v) === v;
}
// Basic key generator that generates keys like a, b, c, ... aa, ab, ac, ...
function genMinifiedKey() {
const chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*';
let index = 0;
return function next() {
let code = '';
let x = index;
do {
code = code + chars[x % chars.length];
x = Math.floor(x / chars.length);
} while (x > 0);
index++;
return code;
};
}
function minifyObject(obj, replacer = v => v) {
const countMap = new Map();
countOccurrences(obj, countMap, replacer);
const maps = genMap(countMap);
const o = minifyObjectImpl(obj, maps.map, replacer);
// need to reverse the map so that the minified keys are the keys and the original keys are the values
// and turn it into an object
return [o, maps.reverseMap];
}
function genMap(countMap) {
const counts = [];
for (const [value, count] of countMap) {
if (count > 1) {
counts.push({ value, count });
}
}
const sorted = counts.sort((a, z) => z.count - a.count);
const getKey = genMinifiedKey();
return sorted.reduce((maps, { value }) => {
if (!shouldAddToMap(value, maps.keyLength)) {
return maps;
}
let key;
do {
key = getKey();
} while (countMap.has(key));
maps.map.set(value, key);
maps.reverseMap[key] = value;
maps.keyLength = key.length;
return maps;
}, {
map: new Map(),
reverseMap: {},
keyLength: 1,
});
}
// This avoids minification if the original key is shorter than or equals the minified key
function shouldAddToMap(value, keyLength) {
return value.toString().length >= keyLength;
}
function addCount(value, countMap) {
countMap.set(value, (countMap.get(value) || 0) + 1);
}
function countOccurrences(obj, countMap, replacer) {
for (const key in obj) {
const value = replacer(obj[key], key);
if (!shouldMinify(value))
continue;
if (!Array.isArray(obj)) {
addCount(key, countMap);
}
if (isObject(value)) {
countOccurrences(value, countMap, replacer);
}
else {
addCount(value, countMap);
}
}
}
function isNonSerializable(value) {
return isNullish(value) || isFunction(value) || typeof value === 'symbol';
}
// eslint-disable-next-line complexity
function shouldMinify(value) {
if (isObject(value) && isEmpty(value)) {
return false;
}
if (isNonSerializable(value)) {
return false;
}
if (isObject(value) && isEmpty(value)) {
return false;
}
return true;
}
function minifyObjectImpl(obj, map, replacer) {
const minifiedObject = getRootNode(obj);
for (const key in obj) {
const value = replacer(obj[key], key);
if (!shouldMinify(value))
continue;
let minifiedValue;
if (isObject(value)) {
minifiedValue = minifyObjectImpl(value, map, replacer);
}
else {
minifiedValue = minifyValue(value, map);
}
setValue(minifiedObject, minifiedValue, minifyValue(key, map));
}
return minifiedObject;
}
function minifyValue(value, map) {
var _a;
return (_a = map.get(value)) !== null && _a !== void 0 ? _a : value;
}
function expandSingle(value, map) {
var _a;
if (isStringValue(value)) {
return (_a = map[value]) !== null && _a !== void 0 ? _a : value;
}
return value;
}
function expandObject(minifiedObj, map) {
const expandedObject = getRootNode(minifiedObj);
for (const key in minifiedObj) {
let expandedValue;
const value = minifiedObj[key];
if (isObject(value)) {
expandedValue = expandObject(value, map);
}
else {
expandedValue = expandSingle(value, map);
}
const expandedKey = expandSingle(key, map);
setValue(expandedObject, expandedValue, expandedKey);
}
return expandedObject;
}
function setValue(container, value, key) {
if (isArray(container)) {
container.push(value);
}
else {
container[key] = value;
}
}
function getRootNode(node) {
return isArray(node) ? [] : {};
}
exports.expandObject = expandObject;
exports.minifyObject = minifyObject;
//# sourceMappingURL=minifyObject.development.js.map