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  61x   61x 61x   61x 61x 61x 61x 61x 61x     61x 2651434x     61x 7119x 58171x 7119x     61x 114000x   104961x   2459x 2459x   6059x 5811x 5066x 5066x 5066x 5066x   745x 745x 745x 745x 4660x 4660x 4660x   745x     521x         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;