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 6267x 67x 67x 67x         67x 971718x 971718x 971718x 971718x     67x 126064x 126064x 126064x 126064x 126064x               67x 803877x 148825x 3314x 3314x 3314x   145511x 139729x 654458x   139729x   5782x 3082x 8168x     5782x       67x 228x     67x 202x     67x      
import {CONST, updateNum} from '../json-hash/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);
};