All files / library/platform/default diff-node-data.ts

100% Statements 59/59
95% Branches 38/40
100% Functions 4/4
100% Lines 57/57

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 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125                      23x 4x 4x 4x 3x 3x   1x     4x 19x           4x         4x 4x 3x 3x   1x     4x 15x 6x 6x 6x   9x             18x 18x 18x 18x 18x 5x     13x 20x 20x 20x 20x 20x             20x 20x   13x 3x   10x             4x   4x 2x   2x 2x 3x 3x 3x 3x             3x 3x   2x 1x       1x   1x       14x 14x 5x   9x    
interface DiffResult {
  allChange: boolean;
  object?: Record<string, unknown>;
}
function _arrayOrObjectItemDiff(
  count: number,
  prefix: string,
  fromItem: unknown,
  toItem: unknown,
  changeObject: Record<string, unknown>
) {
  if (fromItem instanceof Array && toItem instanceof Array) {
    const result = diffDataArray(fromItem, toItem, prefix);
    Eif (result.allChange || result.object) {
      if (result.allChange) {
        count++;
        changeObject[prefix] = toItem;
      } else {
        changeObject = { ...changeObject, ...result.object };
      }
    }
    return { count: count, changeObject };
  } else if (
    typeof fromItem === 'object' &&
    fromItem !== null &&
    typeof toItem === 'object' &&
    toItem !== null
  ) {
    const result = diffDataObject(
      fromItem as Record<string, null>,
      toItem as Record<string, null>,
      prefix
    );
    Eif (result.allChange || result.object) {
      if (result.allChange) {
        count++;
        changeObject[prefix] = toItem;
      } else {
        changeObject = { ...changeObject, ...result.object };
      }
    }
    return { count: count, changeObject };
  } else if (fromItem !== toItem) {
    changeObject[prefix] = toItem;
    count++;
    return { count: count, changeObject };
  }
  return { count: count, changeObject };
}
function diffDataObject(
  from: Record<string, unknown>,
  to: Record<string, unknown>,
  prefix: string
): DiffResult {
  const toKeyList = Object.keys(to);
  let changeObject: Record<string, unknown> = {};
  const point = prefix ? '.' : '';
  let count = 0;
  if (Object.keys(from).length !== toKeyList.length) {
    return { allChange: true };
  }
 
  for (let index = 0; index < toKeyList.length; index++) {
    const key = toKeyList[index];
    const fromItem = from[key];
    const toItem = to[key];
    const currentPrefix = `${prefix}${point}${key}`;
    const result = _arrayOrObjectItemDiff(
      count,
      currentPrefix,
      fromItem,
      toItem,
      changeObject
    );
    count = result.count;
    changeObject = result.changeObject;
  }
  if (count === toKeyList.length && toKeyList.length !== 0) {
    return { allChange: true };
  }
  return { allChange: false, object: changeObject };
}
function diffDataArray(
  from: unknown[],
  to: unknown[],
  prefix: string
): DiffResult {
  let changeObject: Record<string, unknown> = {};
 
  if (from.length !== to.length) {
    return { allChange: true };
  }
  let count = 0;
  for (let i = 0; i < to.length; i++) {
    const fromItem = from[i];
    const toItem = to[i];
    const currentPrefix = `${prefix}[${i}]`;
    const result = _arrayOrObjectItemDiff(
      count,
      currentPrefix,
      fromItem,
      toItem,
      changeObject
    );
    count = result.count;
    changeObject = result.changeObject;
  }
  if (count === to.length && to.length !== 0) {
    return {
      allChange: true,
    };
  }
  return { allChange: false, object: changeObject };
}
export function diffNodeData(
  from: Record<string, unknown>,
  to: Record<string, unknown>
) {
  const result = diffDataObject(from, to, '');
  if (result.allChange) {
    return to;
  }
  return result.object!;
}