/* import {serializePrototypeChain} from "./serializePrototypeChain.js"; function Baz(){} let obj = serializePrototypeChain(Baz); let str = JSON.stringify(obj); debugger */ // serializePrototypeChain.js export function serializePrototypeChain(obj) { const serializedChain = []; let current = obj; // Keep track of seen objects to handle circular references const seenObjects = new WeakSet(); while (current) { if (seenObjects.has(current)) { // Handle circular reference: e.g., store a reference ID or skip serializedChain.push({ __circularRef: true }); break; } // add to weaklist seenObjects.add(current); // object const levelData = { // ctor is not part of properties, so it need to fix separately constructorName: current.constructor ? current.constructor.name : 'Object', properties: {}, }; // Get all own property names (enumerable and non-enumerable) const propertyNames = Object.getOwnPropertyNames(current); for (const name of propertyNames) { try { // receive descriptors const descriptor = Object.getOwnPropertyDescriptor(current, name); if (descriptor) { // Serialize value based on type (handle functions, objects, etc.) if (typeof descriptor.value === 'function') { // it returns out that if this is a property so we save it without calling recursion levelData.properties[name] = `[Function: ${name}]`; // Represent functions } else if (typeof descriptor.value === 'object' && descriptor.value !== null) { // Recursively serialize nested objects or store a reference levelData.properties[name] = serializePrototypeChain(descriptor.value); } else { // case if it is not an object or a function levelData.properties[name] = descriptor.value; } } } catch (e) { // Handle cases where property access might throw errors (e.g., security restrictions) levelData.properties[name] = `[Error: ${e.message}]`; } } serializedChain.push(levelData); // outer as regard to recursion current = Object.getPrototypeOf(current); } return serializedChain; }