"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.structHash = void 0;
const insertion_1 = require("@jsonjoy.com/util/lib/sort/insertion");
const hash_1 = require("./hash");
const json_crdt_patch_1 = require("../json-crdt-patch");
/**
 * Produces a *structural hash* of a JSON value.
 *
 * This is a hash that is not sensitive to the order of properties in object and
 * it preserves spatial information of the JSON nodes.
 *
 * The hash is guaranteed to contain only printable ASCII characters, excluding
 * the newline character.
 *
 * @param val A JSON value to hash.
 */
const structHash = (val) => {
    switch (typeof val) {
        case 'string':
            return (0, hash_1.hash)(val).toString(36);
        case 'number':
        case 'bigint':
            return val.toString(36);
        case 'boolean':
            return val ? 'T' : 'F';
        case 'object':
            if (val === null)
                return 'N';
            if (val instanceof json_crdt_patch_1.Timestamp)
                return (val.sid % 2000000).toString(36) + '.' + val.time.toString(36);
            if (Array.isArray(val)) {
                const length = val.length;
                let res = '[';
                for (let i = 0; i < length; i++)
                    res += (0, exports.structHash)(val[i]) + ';';
                return res + ']';
            }
            else if (val instanceof Uint8Array) {
                return (0, hash_1.hash)(val).toString(36);
            }
            else {
                const keys = Object.keys(val);
                (0, insertion_1.sort)(keys);
                let res = '{';
                const length = keys.length;
                for (let i = 0; i < length; i++) {
                    const key = keys[i];
                    res += (0, hash_1.hash)(key).toString(36) + ':' + (0, exports.structHash)(val[key]) + ',';
                }
                return res + '}';
            }
        default:
            return 'U';
    }
};
exports.structHash = structHash;
//# sourceMappingURL=structHash.js.map