"use client";
function _define_property(obj, key, value) {
    if (key in obj) {
        Object.defineProperty(obj, key, {
            value: value,
            enumerable: true,
            configurable: true,
            writable: true
        });
    } else {
        obj[key] = value;
    }
    return obj;
}
import { useEffect } from "react";
import { useEnsuredRef } from "./useEnsuredRef.js";
/**
 * @internal
 * @remarks \@since 6.0.0 This was added to help with testing. The
 * `subscriptions` and `sharedObserver` used to be module-level variables but
 * moving to a class makes it easier to mock. Checkout the
 * `src/tests-utils/ResizeObserver.ts`
 */ export class ResizeObserverManager {
    constructor(){
        _define_property(this, "frame", void 0);
        _define_property(this, "subscriptions", void 0);
        /**
   * Why is there a single shared observer instead of multiple and a
   * "subscription" model?
   *
   * Note: Probably a bit of a premature optimization right now...
   *
   * @see https://github.com/WICG/resize-observer/issues/59
   * @internal
   */ _define_property(this, "sharedObserver", void 0);
        _define_property(this, "subscribe", (options)=>{
            const { element, onUpdate, disableHeight, disableWidth } = options;
            // lazy initialize the observer
            const observer = this.sharedObserver || new ResizeObserver((entries)=>{
                // this prevents the `ResizeObserver loop limit exceeded`
                window.cancelAnimationFrame(this.frame);
                this.frame = window.requestAnimationFrame(()=>{
                    this.handleResizeEntries(entries);
                });
            });
            this.sharedObserver = observer;
            const updates = this.subscriptions.get(element) || new Set();
            const subscription = {
                onUpdate,
                disableHeight,
                disableWidth
            };
            updates.add(subscription);
            if (!this.subscriptions.has(element)) {
                this.subscriptions.set(element, updates);
            }
            observer.observe(element);
            return ()=>{
                observer.unobserve(element);
                updates.delete(subscription);
            };
        });
        _define_property(this, "handleResizeEntries", (entries)=>{
            for (const entry of entries){
                const targetSubscriptions = this.subscriptions.get(entry.target);
                // shouldn't really happen
                /* c8 ignore start */ if (!targetSubscriptions) {
                    continue;
                }
                /* c8 ignore stop */ const entries = targetSubscriptions.values();
                for (const subscription of entries){
                    const { height, width } = entry.contentRect;
                    const { scrollHeight, scrollWidth } = entry.target;
                    const { onUpdate, size, disableHeight, disableWidth } = subscription;
                    const isHeightChange = !disableHeight && (!size || size.height !== height || size.scrollHeight !== scrollHeight);
                    const isWidthChange = !disableWidth && (!size || size.width !== width || size.scrollWidth !== scrollWidth);
                    subscription.size = {
                        height,
                        width,
                        scrollHeight,
                        scrollWidth
                    };
                    if (isHeightChange || isWidthChange) {
                        onUpdate(entry);
                    }
                }
            }
        });
        this.frame = 0;
        this.subscriptions = new Map();
    }
}
/**
 * @internal
 * @remarks \@since 6.0.0
 */ export const resizeObserverManager = new ResizeObserverManager();
/**
 * The resize observer is used to track the size changes of a specific element.
 * For most cases you can use the {@link useElementSize} instead, but this hook
 * can be used for more complex behavior with the {@link ResizeObserverEntry}.
 *
 * @remarks
 * \@since 2.3.0
 * \@since 6.0.0 The API was updated to match the `useIntersectionObserver`
 * implementation -- accepts only a single object parameter and returns a
 * {@link RefCallback} instead of `[nodeRef, refCallback]`
 */ export function useResizeObserver(options) {
    const { ref, onUpdate, disabled, disableHeight = false, disableWidth = false } = options;
    const [targetNodeRef, refCallback] = useEnsuredRef(ref);
    useEffect(()=>{
        const element = targetNodeRef.current;
        if (disabled || disableHeight && disableWidth || !element) {
            return;
        }
        const unsubscribe = resizeObserverManager.subscribe({
            element,
            onUpdate,
            disableHeight,
            disableWidth
        });
        return ()=>{
            unsubscribe();
        };
    }, [
        disableHeight,
        disableWidth,
        disabled,
        onUpdate,
        targetNodeRef
    ]);
    return refCallback;
}

//# sourceMappingURL=useResizeObserver.js.map