All files / json-crdt hash.ts

95.65% Statements 44/46
100% Branches 9/9
87.5% Functions 7/8
94.44% Lines 34/36

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 6260x 60x 60x 60x         60x 1008383x 1008383x 1008383x 1008383x     60x 121345x 121345x 121345x 121345x 121345x               60x 846988x 153186x 1926x 1926x 1926x   151260x 148116x 695602x   148116x   3144x 678x 2252x     3144x       60x 228x     60x 202x     60x      
import {CONST, updateNum} from '../json-hash';
import {ConNode, ValNode, ObjNode, VecNode, ArrNode} from './nodes';
import {AbstractRga} from './nodes/rga';
import {last2} from 'sonic-forest/lib/util2';
import type {JsonNode} from './nodes';
import type {ITimestampStruct} from '../json-crdt-patch/clock';
import type {Model} from './model';
 
export const updateId = (state: number, id: ITimestampStruct): number => {
  const time = id.time;
  state = updateNum(state, state ^ time);
  state = updateNum(state, id.sid ^ time);
  return state;
};
 
export const updateRga = (state: number, node: AbstractRga<unknown>): number => {
  state = updateNum(state, node.length());
  state = updateNum(state, node.size());
  const maxIdChunk = last2(node.ids);
  if (maxIdChunk) state = updateId(state, maxIdChunk.id);
  return updateId(state, node.id);
};
 
/**
 * Updates the hash state with the given JSON CRDT node.
 * @param state Current hash state.
 * @param node JSON CRDT node from which to compute the hash.
 */
export const updateNode = (state: number, node: JsonNode): number => {
  if (node instanceof ConNode) return updateId(state, node.id);
  if (node instanceof ValNode) {
    const child = node.child();
    if (child) state = updateNode(state, child);
    return updateId(state, node.id);
  }
  if (node instanceof ObjNode || node instanceof VecNode) {
    node.children((child) => {
      state = updateNode(state, child);
    });
    return updateId(state, node.id);
  }
  if (node instanceof ArrNode) {
    node.children((child) => {
      state = updateNode(state, child);
    });
  }
  if (node instanceof AbstractRga) return updateRga(state, node);
  throw new Error('UNKNOWN_NODE');
};
 
export const hashId = (id: ITimestampStruct): number => {
  return updateId(CONST.START_STATE, id);
};
 
export const hashNode = (node: JsonNode): number => {
  return updateNode(CONST.START_STATE, node) >>> 0;
};
 
export const hashModel = (model: Model): number => {
  return hashNode(model.root);
};