diff --git a/src/decycle.ts b/src/decycle.ts index 83a8a26..4daca7f 100644 --- a/src/decycle.ts +++ b/src/decycle.ts @@ -3,39 +3,38 @@ import { pathToPointer } from './pathToPointer'; export function decycle(obj: unknown, replacer?: (value: any) => any) { const objs = new WeakMap(); + const processedObjs = new WeakSet(); function derez(value: any, path: (string | number)[]): any { if (replacer) { value = replacer(value); } - if (isPlainObject(value) || Array.isArray(value)) { // The path of an earlier occurance of value const oldPath = objs.get(value); - // If the value is an object or array, look to see if we have already // encountered it. If so, return a {"$ref":PATH} object. if (oldPath) { return { $ref: oldPath }; } - objs.set(value, pathToPointer(path)); // If it is an array, replicate the array. if (Array.isArray(value)) { return value.map((element, i) => derez(element, [...path, i])); } - const newObj: Record = {}; for (const name in value) { if (Object.prototype.hasOwnProperty.call(value, name)) { newObj[name] = derez(value[name], [...path, name]); } } - // deleteing object before returing - objs.delete(value); + // Only delete the object from the map if it has not been processed before + if (!processedObjs.has(value)) { + objs.delete(value); + } + processedObjs.add(value); return newObj; } return value; } - return derez(obj, []); }