import { hasOwn } from "./has-own.js";
const SIZE_TAG = 1;
const SIZE_INT32 = 4;
const SIZE_SMI = 5;
const SIZE_DOUBLE = 8;
function getSizeOfValue(value) {
  switch (typeof value) {
    case "string":
      return SIZE_TAG + SIZE_INT32 + value.length;
    case "number":
      if (isSmi(value)) {
        if (value <= -1073741824 || value >= 2 ** 30 - 1) {
          return SIZE_TAG + SIZE_SMI;
        }
        return SIZE_TAG + SIZE_INT32;
      }
      return SIZE_TAG + SIZE_DOUBLE;
    case "boolean":
      return SIZE_TAG;
    case "object":
      if (value === null) {
        return SIZE_TAG;
      }
      if (Array.isArray(value)) {
        let sum = 2 * SIZE_TAG + SIZE_INT32;
        for (const element of value) {
          sum += getSizeOfValue(element);
        }
        return sum;
      }
      {
        const val = value;
        let sum = 2 * SIZE_TAG + SIZE_INT32;
        for (const k in val) {
          if (hasOwn(val, k)) {
            const propertyValue = val[k];
            if (propertyValue !== void 0) {
              sum += getSizeOfValue(k) + getSizeOfValue(propertyValue);
            }
          }
        }
        return sum;
      }
  }
  throw new Error(`Invalid value. type: ${typeof value}, value: ${value}`);
}
function isSmi(value) {
  return value === (value | 0);
}
const entryFixed = 2 * SIZE_TAG + SIZE_INT32 + SIZE_TAG + SIZE_INT32;
function getSizeOfEntry(key, value) {
  return entryFixed + getSizeOfValue(key) + getSizeOfValue(value);
}
export {
  getSizeOfEntry,
  getSizeOfValue
};
//# sourceMappingURL=size-of-value.js.map
