{"version":3,"file":"minifyObject.cjs","names":["isObject","isNullish","isFunction","isEmpty","minifiedObject: any","isStringValue","expandedObject: any","isUnsafeKey","isArray"],"sources":["../../src/exports/minifyObject.ts"],"sourcesContent":["import isUnsafeKey from '../isUnsafeKey';\nimport { isArray } from '../isArrayValue';\nimport { isEmpty } from '../isEmpty';\nimport isFunction from '../isFunction';\nimport { isNullish } from '../isNullish';\nimport isStringValue from '../isStringValue';\nimport { isObject } from '../valueIsObject';\n\n// Basic key generator that generates keys like a, b, c, ... aa, ab, ac, ...\nfunction genMinifiedKey() {\n  const chars =\n    '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*';\n  let index = 0;\n\n  return function next(): string {\n    let code = '';\n    let x = index;\n\n    do {\n      code = code + chars[x % chars.length];\n      x = Math.floor(x / chars.length);\n    } while (x > 0);\n    index++;\n    return code;\n  };\n}\n\nexport function minifyObject(\n  obj: any,\n  replacer: MinifyObjectReplacer = v => v,\n): [any, any] {\n  const countMap = new Map<any, number>();\n  countOccurrences(obj, countMap, replacer);\n  const maps = genMap(countMap);\n  const o = minifyObjectImpl(obj, maps.map, replacer);\n  // need to reverse the map so that the minified keys are the keys and the original keys are the values\n  // and turn it into an object\n\n  return [o, maps.reverseMap];\n}\n\nfunction genMap(countMap: Map<any, number>) {\n  const counts = [];\n\n  for (const [value, count] of countMap) {\n    if (count > 1) {\n      counts.push({ value, count });\n    }\n  }\n\n  const sorted = counts.sort((a, z) => z.count - a.count);\n\n  const getKey = genMinifiedKey();\n  return sorted.reduce(\n    (maps, { value }) => {\n      if (!shouldAddToMap(value, maps.keyLength)) {\n        return maps;\n      }\n\n      let key;\n      do {\n        key = getKey();\n      } while (countMap.has(key));\n      maps.map.set(value, key);\n      maps.reverseMap[key] = value;\n      maps.keyLength = key.length;\n      return maps;\n    },\n    {\n      map: new Map(),\n      reverseMap: {},\n      keyLength: 1,\n    } as {\n      map: Map<any, string>;\n      reverseMap: Record<string, any>;\n      keyLength: number;\n    },\n  );\n}\n\n// This avoids minification if the original key is shorter than or equals the minified key\nfunction shouldAddToMap(value: any, keyLength: number) {\n  return value.toString().length >= keyLength;\n}\n\nfunction addCount(value: any, countMap: Map<any, number>) {\n  countMap.set(value, (countMap.get(value) || 0) + 1);\n}\n\nfunction countOccurrences(\n  obj: any,\n  countMap: Map<any, number>,\n  replacer: MinifyObjectReplacer,\n) {\n  for (const key in obj) {\n    const value = replacer(obj[key], key);\n    if (!shouldMinify(value)) continue;\n\n    if (!Array.isArray(obj)) {\n      addCount(key, countMap);\n    }\n\n    if (isObject(value)) {\n      countOccurrences(value, countMap, replacer);\n    } else {\n      addCount(value, countMap);\n    }\n  }\n}\n\nfunction isNonSerializable(value: any): boolean {\n  return isNullish(value) || isFunction(value) || typeof value === 'symbol';\n}\n\nfunction shouldMinify(value: any): boolean {\n  if (isObject(value) && isEmpty(value)) {\n    return false;\n  }\n\n  if (isNonSerializable(value)) {\n    return false;\n  }\n\n  return true;\n}\n\nfunction minifyObjectImpl(\n  obj: any,\n  map: Map<any, string>,\n  replacer: MinifyObjectReplacer,\n): any {\n  const minifiedObject: any = getRootNode(obj);\n\n  for (const key in obj) {\n    const value = replacer(obj[key], key);\n    if (!shouldMinify(value)) continue;\n\n    let minifiedValue;\n    if (isObject(value)) {\n      minifiedValue = minifyObjectImpl(value, map, replacer);\n    } else {\n      minifiedValue = minifyValue(value, map);\n    }\n\n    setValue(minifiedObject, minifiedValue, minifyValue(key, map));\n  }\n\n  return minifiedObject;\n}\n\nfunction minifyValue(value: any, map: Map<any, string>) {\n  return map.get(value) ?? value;\n}\n\nfunction expandSingle(value: any, map: Record<string, any>): any {\n  if (isStringValue(value)) {\n    return map[value] ?? value;\n  }\n\n  return value;\n}\n\nexport function expandObject(minifiedObj: any, map: Record<string, any>): any {\n  const expandedObject: any = getRootNode(minifiedObj);\n\n  for (const key in minifiedObj) {\n    let expandedValue;\n    const value = minifiedObj[key];\n    if (isObject(value)) {\n      expandedValue = expandObject(value, map);\n    } else {\n      expandedValue = expandSingle(value, map);\n    }\n\n    const expandedKey = expandSingle(key, map);\n    setValue(expandedObject, expandedValue, expandedKey);\n  }\n\n  return expandedObject;\n}\n\nfunction setValue(container: any, value: any, key: string) {\n  if (isUnsafeKey(key)) {\n    return;\n  }\n\n  if (isArray(container)) {\n    container.push(value);\n  } else {\n    container[key] = value;\n  }\n}\n\nfunction getRootNode(node: any) {\n  return isArray(node) ? [] : {};\n}\n\nexport type MinifyObjectReplacer = (value: any, key: string) => any;\n"],"mappings":"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"}