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 2907x 15x 11x 2907x 2907x   2x 2989x       2989x 2989x 2989x   2989x 14765x   14765x 15x 15x 15x 15x   14750x   14765x 1x 1x   14765x 14765x 713060x 713060x 701284x 701284x 713060x 713060x 713060x 14749x   2989x 2989x 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;
    }
}