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 2835545x     64x 7039x 57395x 7039x     64x 124098x   111400x   2505x 2505x   9679x 9430x 8737x 8737x 12359x 8737x   693x 693x 693x 693x 4534x 4534x 4534x   693x     514x         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;