import { jsx } from "react/jsx-runtime";
import { createContext, useCallback, useContext, useEffect, useRef, useSyncExternalStore } from "react";
const EMPTY_SET = Object.freeze(new Set());
class ConnectedHandlesStore {
    map = new Map();
    listeners = new Map();
    subscribe(nodeId, listener) {
        let nodeListeners = this.listeners.get(nodeId);
        if (!nodeListeners) {
            nodeListeners = new Set();
            this.listeners.set(nodeId, nodeListeners);
        }
        nodeListeners.add(listener);
        return ()=>{
            nodeListeners.delete(listener);
            if (0 === nodeListeners.size) this.listeners.delete(nodeId);
        };
    }
    getSnapshot(nodeId) {
        return this.map.get(nodeId) ?? EMPTY_SET;
    }
    update(edges) {
        const nextMap = buildConnectedHandlesMap(edges);
        const prevMap = this.map;
        const finalMap = new Map();
        const changedNodeIds = new Set();
        for (const [nodeId, nextSet] of nextMap){
            const prevSet = prevMap.get(nodeId);
            if (setsEqual(prevSet, nextSet)) finalMap.set(nodeId, prevSet);
            else {
                finalMap.set(nodeId, nextSet);
                changedNodeIds.add(nodeId);
            }
        }
        for (const nodeId of prevMap.keys())if (!nextMap.has(nodeId)) changedNodeIds.add(nodeId);
        if (0 === changedNodeIds.size) return;
        this.map = finalMap;
        for (const nodeId of changedNodeIds){
            const nodeListeners = this.listeners.get(nodeId);
            if (nodeListeners) for (const listener of nodeListeners)listener();
        }
    }
}
function setsEqual(a, b) {
    if (a === b) return true;
    if (!a || !b) return false;
    if (a.size !== b.size) return false;
    for (const value of a)if (!b.has(value)) return false;
    return true;
}
function buildConnectedHandlesMap(edges) {
    const map = new Map();
    for (const edge of edges){
        if (edge.sourceHandle) {
            let set = map.get(edge.source);
            if (!set) {
                set = new Set();
                map.set(edge.source, set);
            }
            set.add(edge.sourceHandle);
        }
        if (edge.targetHandle) {
            let set = map.get(edge.target);
            if (!set) {
                set = new Set();
                map.set(edge.target, set);
            }
            set.add(edge.targetHandle);
        }
    }
    return map;
}
const ConnectedHandlesContext = /*#__PURE__*/ createContext(null);
function ConnectedHandlesProvider({ edges, children }) {
    const storeRef = useRef(void 0);
    if (!storeRef.current) storeRef.current = new ConnectedHandlesStore();
    useEffect(()=>{
        storeRef.current.update(edges);
    }, [
        edges
    ]);
    return /*#__PURE__*/ jsx(ConnectedHandlesContext.Provider, {
        value: storeRef.current,
        children: children
    });
}
function useConnectedHandles(nodeId) {
    const store = useContext(ConnectedHandlesContext);
    const subscribe = useCallback((onStoreChange)=>{
        if (!store) return ()=>{};
        return store.subscribe(nodeId, onStoreChange);
    }, [
        store,
        nodeId
    ]);
    const getSnapshot = useCallback(()=>store?.getSnapshot(nodeId) ?? EMPTY_SET, [
        store,
        nodeId
    ]);
    return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
}
export { ConnectedHandlesProvider, useConnectedHandles };
