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 6263x 63x 63x 63x         63x 1017679x 1017679x 1017679x 1017679x     63x 122460x 122460x 122460x 122460x 122460x               63x 854466x 154857x 1932x 1932x 1932x   152925x 149885x 701281x   149885x   3040x 648x 2196x     3040x       63x 228x     63x 202x     63x      
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);
};