function serialize()

in packages-ext/recoil-devtools/src/utils/Serialization.js [41:151]


function serialize(
  item: mixed,
  maxDepth: number = DefaultMaxDepth,
  maxItems: number = DefaultMaxItems,
  parents?: ?Set<mixed>,
  depth: number = 0,
): SerializedValue {
  if (parents == null) {
    parents = new Set();
  }

  if (depth > maxDepth) {
    return {t: SerializedValueType.primitive, v: '[Max Depth Reached]'};
  }
  if (item && typeof item === 'object') {
    if (parents.has(item)) {
      return {t: SerializedValueType.primitive, v: '[Circular Reference]'};
    }
    parents.add(item);
  }

  let serialized: ?SerializedValue = null;
  if (item === null) {
    serialized = {t: SerializedValueType.null};
  } else if (item === undefined) {
    serialized = {t: SerializedValueType.undefined};
  } else if (Array.isArray(item)) {
    const {iterable, exceeds} = getExceedingItems<mixed>(item, maxItems);
    serialized = maybeAddExceeds(
      {
        t: SerializedValueType.array,
        v: iterable.map(it =>
          serialize(it, maxDepth, maxItems, parents, depth + 1),
        ),
      },
      exceeds,
    );
  } else if (item instanceof Set) {
    const {iterable, exceeds} = getExceedingItems<mixed>(
      Array.from(item),
      maxItems,
    );
    serialized = maybeAddExceeds(
      {
        t: SerializedValueType.set,
        v: iterable.map(it =>
          serialize(it, maxDepth, maxItems, parents, depth + 1),
        ),
      },
      exceeds,
    );
  } else if (item instanceof Map) {
    const {iterable, exceeds} = getExceedingItems<[mixed, mixed]>(
      Array.from(item.entries()),
      maxItems,
    );
    serialized = maybeAddExceeds(
      {
        t: SerializedValueType.map,
        v: iterable.map(entry =>
          entry.map(it =>
            serialize(it, maxDepth, maxItems, parents, depth + 1),
          ),
        ),
      },
      exceeds,
    );
  } else if (item instanceof Promise || typeof item?.then === 'function') {
    serialized = {t: SerializedValueType.promise, v: 'Promise<Pending>'};
  } else if (item instanceof Error) {
    serialized = {
      t: SerializedValueType.error,
      v: capStringLength(item.toString(), 150),
    };
  } else if (item instanceof Date) {
    serialized = {t: SerializedValueType.date, v: item.getTime()};
  } else if (typeof item === 'symbol') {
    serialized = {
      t: SerializedValueType.symbol,
      v: item.description,
    };
  } else if (typeof item === 'function') {
    serialized = {
      t: SerializedValueType.function,
      v: capStringLength(String(item), 150),
    };
  } else if (typeof item === 'object') {
    const {iterable, exceeds} = getExceedingItems<[string, mixed]>(
      Object.entries(item),
      maxItems,
    );
    serialized = maybeAddExceeds(
      {
        t: SerializedValueType.object,
        v: iterable.map(entry =>
          entry.map(it =>
            serialize(it, maxDepth, maxItems, parents, depth + 1),
          ),
        ),
      },
      exceeds,
    );
  } else {
    serialized = {t: SerializedValueType.primitive, v: item};
  }

  if (item && typeof item === 'object') {
    parents.delete(item);
  }
  return serialized;
}