import { sort } from '@jsonjoy.com/util/lib/sort/insertion';
export var CONST;
(function (CONST) {
    CONST[CONST["START_STATE"] = 5381] = "START_STATE";
    CONST[CONST["NULL"] = 982452847] = "NULL";
    CONST[CONST["TRUE"] = 982453247] = "TRUE";
    CONST[CONST["FALSE"] = 982454243] = "FALSE";
    CONST[CONST["ARRAY"] = 982452259] = "ARRAY";
    CONST[CONST["STRING"] = 982453601] = "STRING";
    CONST[CONST["OBJECT"] = 982454533] = "OBJECT";
    CONST[CONST["BINARY"] = 982454837] = "BINARY";
})(CONST || (CONST = {}));
export const updateNum = (state, num) => {
    return (state << 5) + state + num;
};
export const updateStr = (state, str) => {
    const length = str.length;
    state = updateNum(state, CONST.STRING);
    state = updateNum(state, length);
    let i = length;
    while (i)
        state = (state << 5) + state + str.charCodeAt(--i);
    return state;
};
export const updateBin = (state, bin) => {
    const length = bin.length;
    state = updateNum(state, CONST.BINARY);
    state = updateNum(state, length);
    let i = length;
    while (i)
        state = (state << 5) + state + bin[--i];
    return state;
};
export const updateJson = (state, json) => {
    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 (Array.isArray(json)) {
                const length = json.length;
                state = updateNum(state, CONST.ARRAY);
                for (let i = 0; i < length; i++)
                    state = updateJson(state, json[i]);
                return state;
            }
            if (json instanceof Uint8Array)
                return updateBin(state, json);
            state = updateNum(state, CONST.OBJECT);
            const keys = sort(Object.keys(json));
            const length = keys.length;
            for (let i = 0; i < length; i++) {
                const key = keys[i];
                state = updateStr(state, key);
                state = updateJson(state, json[key]);
            }
            return state;
        }
        case 'boolean':
            return updateNum(state, json ? CONST.TRUE : CONST.FALSE);
    }
    return state;
};
export const hash = (json) => updateJson(CONST.START_STATE, json) >>> 0;
//# sourceMappingURL=hash.js.map