All files / src/PerfectWSAdvanced/transform TransformCircularObjects.ts

95.23% Statements 40/42
95.45% Branches 21/22
100% Functions 3/3
95.23% Lines 40/42

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 542x 2x   2x   2x 1284x   2x 2877x 15x 11x 2877x 2877x   2x 2959x       2959x 2959x 2959x   2959x 14673x   14673x 15x 15x 15x 15x   14658x   14673x 1x 1x   14673x 14673x 697487x 697487x 685773x 685773x 697487x 697487x 697487x 14657x   2959x 2959x 2x  
import { transformSendDeserializeType } from './utils/changeType.js';
import { getProperty } from 'dot-prop';
 
export class TransformCircularObjects {
 
    constructor(private _maxDepth: number = 100) {
    }
 
    deserialize(data: any) {
        return transformSendDeserializeType(data, 'circularRef', (found) => {
            if (found.refPath === '') return data;
            return getProperty(data, found.refPath);
        }, this._maxDepth);
    }
 
    serialize(obj: any) {
        if (typeof obj !== 'object' || !obj) {
            return obj;
        }
    
        const processed = new WeakMap();
        const parent = { root: obj };
        const stack: { obj: any; depth: number; parent: any, key: string | number; currentPath: string }[] = [{ obj, depth: 0, parent, key: 'root', currentPath: '' }];
    
        while (stack.length > 0) {
            const { obj: current, depth, parent, key, currentPath } = stack.pop()!;
 
            if (processed.has(current)) {
                const refPath = processed.get(current);
                parent[key] = { ___type: 'circularRef', refPath };
                continue;
            }
 
            processed.set(current, currentPath);
    
            if (depth >= this._maxDepth) {
                continue;
            }
    
            const currentKeys = Array.isArray(current) ? current.keys() : Object.keys(current);
            for (const key of currentKeys) {
                const value = current[key];
                if (typeof value !== 'object' || !value) {
                    continue;
                }
                const nextPath = currentPath ? `${currentPath}.${key}` : key.toString();
                stack.push({ obj: value, depth: depth + 1, key, parent: current, currentPath: nextPath });
            }
        }
    
        return parent.root;
    }
}