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;
}