All files / json-hash index.ts

97.87% Statements 46/47
100% Branches 10/10
100% Functions 5/5
97.29% Lines 36/37

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  64x   64x 64x   64x 64x 64x 64x 64x 64x     64x 2726863x     64x 7111x 57777x 7111x     64x 123804x   111203x   2501x 2501x   9561x 9298x 8587x 8587x 12139x 8587x   711x 711x 711x 711x 4610x 4610x 4610x   711x     539x         100215x  
import type {JsonValue} from '@jsonjoy.com/json-pack/lib/types';
import {sort} from '@jsonjoy.com/util/lib/sort/insertion';
 
export enum CONST {
  START_STATE = 5381,
 
  NULL = 982452847,
  TRUE = 982453247,
  FALSE = 982454243,
  ARRAY = 982452259,
  STRING = 982453601,
  OBJECT = 982454533,
}
 
export const updateNum = (state: number, num: number): number => {
  return (state << 5) + state + num;
};
 
export const updateStr = (state: number, str: string): number => {
  let i = str.length;
  while (i) state = (state << 5) + state + str.charCodeAt(--i);
  return state;
};
 
export const updateJson = (state: number, json: JsonValue): number => {
  switch (typeof json) {
    case 'number':
      return updateNum(state, json);
    case 'string':
      state = updateNum(state, CONST.STRING);
      return updateStr(state, json);
    case 'object': {
      if (json === null) return updateNum(state, CONST.NULL);
      if (json instanceof Array) {
        const length = json.length;
        state = updateNum(state, CONST.ARRAY);
        for (let i = 0; i < length; i++) state = updateJson(state, json[i]);
        return state;
      }
      state = updateNum(state, CONST.OBJECT);
      const keys = sort(Object.keys(json as object));
      const length = keys.length;
      for (let i = 0; i < length; i++) {
        const key = keys[i];
        state = updateStr(state, key);
        state = updateJson(state, (json as any)[key]);
      }
      return state;
    }
    case 'boolean':
      return updateNum(state, json ? CONST.TRUE : CONST.FALSE);
  }
  return state;
};
 
export const hash = (json: JsonValue) => updateJson(CONST.START_STATE, json) >>> 0;