var __rest = (this && this.__rest) || function (s, e) {
    var t = {};
    for (var p in s)
        if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
            t[p] = s[p];
    if (s != null && typeof Object.getOwnPropertySymbols === "function")
        for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
            if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
                t[p[i]] = s[p[i]];
        }
    return t;
};
import Ajv from "ajv";
import { isInteger } from "./validators";
const ajv = new Ajv({
    unknownFormats: 'ignore',
    allErrors: true,
    multipleOfPrecision: 2,
}).addFormat('integer', isInteger);
const validators = new Map();
/**
 * Returns a compiled JSON Schema validator, using a cached version
 * if the same schema content has been seen before.
 *
 * @param schema - the JSON Schema to compile
 */
export function getValidator(schema) {
    const key = hashSchema(schema);
    const cached = validators.get(key);
    if (cached) {
        return cached;
    }
    const { $id, id } = schema, schemaWithoutId = __rest(schema, ["$id", "id"]);
    const validator = ajv.compile(schemaWithoutId);
    validators.set(key, validator);
    return validator;
}
/**
 * Generates a deterministic ID from schema content, preserving any
 * existing `$id` as a prefix. Used to work around RJSF #1563 where
 * identical schemas need stable IDs to avoid validation cache collisions.
 *
 * @param schema - the JSON Schema to generate an ID for
 */
export function getSchemaId(schema) {
    const hash = hashSchema(schema);
    const prefix = schema.$id ? `${schema.$id}-` : '';
    return `${prefix}${hash}`;
}
function hashSchema(schema) {
    const { $id, id } = schema, schemaWithoutId = __rest(schema, ["$id", "id"]);
    return djb2Hash(JSON.stringify(schemaWithoutId, sortedReplacer));
}
function sortedReplacer(_, value) {
    if (value && typeof value === 'object' && !Array.isArray(value)) {
        return Object.fromEntries(Object.entries(value).sort(([a], [b]) => a.localeCompare(b)));
    }
    return value;
}
function djb2Hash(str) {
    let hash = 5381;
    for (let i = 0; i < str.length; i++) {
        hash = ((hash << 5) + hash + str.codePointAt(i)) & 4294967295;
    }
    return (hash >>> 0).toString(36);
}
