"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.useContextState = exports.StateProvider = exports.StateContext = void 0;
const hash_1 = require("@saulx/hash");
const react_1 = __importStar(require("react"));
exports.StateContext = (0, react_1.createContext)({ map: new Map() });
const StateProvider = ({ children, values, onChange }) => {
    const ctxValue = (0, react_1.useMemo)(() => {
        const ctxVal = {
            map: new Map(),
            notDefault: true,
            onChange,
        };
        return ctxVal;
    }, []);
    (0, react_1.useEffect)(() => {
        for (const key in values) {
            let v = ctxValue.map.get(key);
            if (!v) {
                v = {
                    version: 0,
                    listeners: new Set(),
                };
                ctxValue.map.set(key, v);
            }
            v.value = values[key];
            const n = (0, hash_1.hash)(v.value ?? 0);
            if (n !== v.version) {
                v.version = n;
                v.listeners.forEach((u) => u(n));
            }
        }
    }, [ctxValue, values ? (0, hash_1.hashObjectIgnoreKeyOrder)(values) : 0]);
    ctxValue.onChange = onChange;
    return (react_1.default.createElement(exports.StateContext.Provider, { value: ctxValue }, children));
};
exports.StateProvider = StateProvider;
const useContextState = (key, initialValue) => {
    const values = (0, react_1.useContext)(exports.StateContext);
    if (!values.map.has(key)) {
        values.map.set(key, {
            version: 0,
            listeners: new Set(),
        });
    }
    const v = values.map.get(key);
    const [, update] = (0, react_1.useState)(v.version);
    (0, react_1.useEffect)(() => {
        v.listeners.add(update);
        return () => {
            v.listeners.delete(update);
        };
    }, []);
    return [
        v.value ?? initialValue,
        (value) => {
            v.value = value;
            const n = (0, hash_1.hash)(v.value ?? 0);
            if (n !== v.version) {
                v.listeners.forEach((u) => u(n));
                if (values.onChange) {
                    values.onChange(key, value);
                }
            }
        },
    ];
};
exports.useContextState = useContextState;
//# sourceMappingURL=index.js.map