import { keys } from '../../_common/utils/iterable.js';
const state = {
    skip: false,
    creating: false,
    derive: false,
};
export function setCreateState(creating, skipFieldInit) {
    state.skip = skipFieldInit;
    state.creating = creating;
}
function yDecorator(prototype, prop) {
    Object.defineProperty(prototype, prop, {
        get() {
            return (this.yMap.get(prop) ?? this._preserved.get(prop));
        },
        set(val) {
            if (state.skip) {
                return;
            }
            if (this.yMap) {
                this.yMap.set(prop, val);
            }
            if (!this.yMap.doc) {
                this._preserved.set(prop, val);
            }
            updateDerivedProp(prototype, prop, this);
        },
    });
}
export function yfield() {
    return yDecorator;
}
export function local() {
    return function localDecorator(target, prop) {
        Object.defineProperty(target, prop, {
            get() {
                return this._local.get(prop);
            },
            set(newVal) {
                const oldValue = this._local.get(prop);
                this._local.set(prop, newVal);
                if (state.creating)
                    return;
                this._onChange({
                    [prop]: {
                        oldValue,
                    },
                });
            },
        });
    };
}
const deriveSymbol = Symbol('derive');
function setDerivedMeta(target, prop, fn) {
    // @ts-ignore
    target[deriveSymbol] = target[deriveSymbol] ?? {};
    // @ts-ignore
    target[deriveSymbol][prop] = fn;
}
export function updateDerivedProp(target, prop, receiver) {
    if (state.derive || state.creating)
        return;
    const deriveFn = getDerivedMeta(target, prop);
    if (deriveFn) {
        state.derive = true;
        const derived = deriveFn(receiver);
        keys(derived).forEach(key => {
            // @ts-ignore
            receiver[key] = derived[key];
        });
        state.derive = false;
    }
}
export function getDerivedMeta(target, prop) {
    // @ts-ignore
    return target[deriveSymbol]?.[prop] ?? null;
}
export function derive(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
fn) {
    return function deriveDecorator(target, prop) {
        setDerivedMeta(target, prop, fn);
    };
}
//# sourceMappingURL=decorators.js.map