All files / json-hash structHashCrdt.ts

96.77% Statements 30/31
100% Branches 13/13
100% Functions 2/2
96% Lines 24/25

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 395x 5x 5x 5x                     5x 37125x 23277x 15185x 6452x 3705x 3705x 3705x 3705x 3705x 14247x 14247x 14247x   3705x 2747x 2729x 2729x 6085x   2729x 18x      
import {sort} from '@jsonjoy.com/util/lib/sort/insertion';
import {ArrNode, BinNode, ConNode, type JsonNode, ObjNode, StrNode, ValNode, VecNode} from '../json-crdt';
import {hash} from './hash';
import {structHash} from './structHash';
 
/**
 * Constructs a structural hash of the view of the node.
 *
 * Produces a *structural hash* of a JSON CRDT node. Works the same as
 * `structHash, but uses the `JsonNode` interface instead of a generic value.
 *
 * @todo PERF: instead of constructing a "str" and "bin" view, iterate over
 *     the RGA chunks and hash them directly.
 */
export const structHashCrdt = (node?: JsonNode): string => {
  if (node instanceof ConNode) return structHash(node.val);
  else if (node instanceof ValNode) return structHashCrdt(node.node());
  else if (node instanceof StrNode) return hash(node.view()).toString(36);
  else if (node instanceof ObjNode) {
    let res = '{';
    const keys = Array.from(node.keys.keys());
    sort(keys);
    const length = keys.length;
    for (let i = 0; i < length; i++) {
      const key = keys[i];
      const value = node.get(key);
      res += hash(key).toString(36) + ':' + structHashCrdt(value) + ',';
    }
    return res + '}';
  } else if (node instanceof ArrNode || node instanceof VecNode) {
    let res = '[';
    node.children((child) => {
      res += structHashCrdt(child) + ',';
    });
    return res + ']';
  } else if (node instanceof BinNode) return hash(node.view()).toString(36);
  return 'U';
};