{"version":3,"file":"useExternalNav.cjs","sources":["../../../src/hooks/useExternalNav.ts"],"sourcesContent":["import { useEffect, useRef, useCallback } from 'react';\nimport { type NavElement } from '../types';\nimport type ResourceManager from \"../managers/ResourceManager\";\n\n// Define EventCallback type to match ResourceManager's definition\ntype EventCallback = EventListenerOrEventListenerObject;\n\n// Development environment check\nconst isDevelopment = import.meta.env?.MODE === 'development';\n\ninterface UseExternalNavProps {\n    externalNav: boolean;\n    navElement: NavElement;\n    handleNext: () => void;\n    handlePrev: () => void;\n    resourceManager?: ResourceManager | null;\n}\n\n/**\n * Hook to set up external navigation elements for the slider\n * Fully optimized with:\n * - Batch event listener registration\n * - Stable event handler references\n * - Comprehensive error handling\n * - Memory leak prevention\n * - Element reference caching\n * - Event propagation control\n * - Optimized dependency tracking\n * - Type safety improvements\n */\nconst useExternalNav = ({\n                            externalNav,\n                            navElement,\n                            handleNext,\n                            handlePrev,\n                            resourceManager\n                        }: UseExternalNavProps) => {\n    // Track found elements to avoid unnecessary DOM queries\n    const elementsRef = useRef<{\n        prevNav: Element | null;\n        nextNav: Element | null;\n    }>({ prevNav: null, nextNav: null });\n\n    // Define a stable interface for our event handlers\n    interface StableHandlers {\n        prevHandler: EventCallback;\n        nextHandler: EventCallback;\n        latestPrevFn: (() => void) | null;\n        latestNextFn: (() => void) | null;\n    }\n\n    // Create stable event handlers that internally reference the latest callback functions\n    const handlersRef = useRef<StableHandlers>({\n        prevHandler: (e: Event) => {\n            try {\n                e.preventDefault();\n                // Call the latest function reference\n                const latestHandler = handlersRef.current.latestPrevFn;\n                if (typeof latestHandler === 'function') {\n                    latestHandler();\n                }\n            } catch (error) {\n                if (isDevelopment) {\n                    console.error('Error in previous navigation handler:', error);\n                }\n            }\n        },\n        nextHandler: (e: Event) => {\n            try {\n                e.preventDefault();\n                // Call the latest function reference\n                const latestHandler = handlersRef.current.latestNextFn;\n                if (typeof latestHandler === 'function') {\n                    latestHandler();\n                }\n            } catch (error) {\n                if (isDevelopment) {\n                    console.error('Error in next navigation handler:', error);\n                }\n            }\n        },\n        latestPrevFn: null,\n        latestNextFn: null\n    });\n\n    // Keep the latest function references updated\n    useEffect(() => {\n        handlersRef.current.latestPrevFn = handlePrev;\n        handlersRef.current.latestNextFn = handleNext;\n    }, [handlePrev, handleNext]);\n\n    // Memoize the batch registration function for better performance\n    const setupBatchListeners = useCallback((\n        prevElement: Element,\n        nextElement: Element,\n        prevHandler: EventCallback,\n        nextHandler: EventCallback\n    ) => {\n        try {\n            if (!resourceManager) return false;\n\n            // Create listeners maps for each element\n            const prevListenersMap = new Map<string, EventCallback[]>();\n            prevListenersMap.set('click', [prevHandler]);\n\n            const nextListenersMap = new Map<string, EventCallback[]>();\n            nextListenersMap.set('click', [nextHandler]);\n\n            // Register event listeners in batch operations\n            resourceManager.addEventListenerBatch(prevElement, prevListenersMap);\n            resourceManager.addEventListenerBatch(nextElement, nextListenersMap);\n\n            return true;\n        } catch (error) {\n            if (isDevelopment) {\n                console.error('Error setting up batch listeners:', error);\n            }\n            return false;\n        }\n    }, [resourceManager]);\n\n    // Setup regular DOM event listeners\n    const setupDirectListeners = useCallback((\n        prevElement: Element,\n        nextElement: Element,\n        prevHandler: EventCallback,\n        nextHandler: EventCallback\n    ) => {\n        try {\n            prevElement.addEventListener('click', prevHandler);\n            nextElement.addEventListener('click', nextHandler);\n            return true;\n        } catch (error) {\n            if (isDevelopment) {\n                console.error('Error setting up direct listeners:', error);\n            }\n            return false;\n        }\n    }, []);\n\n    // Main effect for setting up and cleaning up navigation\n    useEffect(() => {\n        // Skip during server-side rendering\n        if (typeof window === 'undefined') return;\n\n        // Skip if external navigation is not enabled\n        if (!externalNav) return;\n\n        // Track initialization status for cleanup\n        let isInitialized = false;\n\n        try {\n            // Find the navigation elements in the DOM\n            const prevNav = document.querySelector(navElement.prev);\n            const nextNav = document.querySelector(navElement.next);\n\n            // Store references to found elements\n            elementsRef.current = { prevNav, nextNav };\n\n            // Check if both elements are found\n            if (!prevNav || !nextNav) {\n                // Create helpful error message\n                const missingElements: string[] = [];\n                if (!prevNav) missingElements.push(`\"${navElement.prev}\"`);\n                if (!nextNav) missingElements.push(`\"${navElement.next}\"`);\n\n                // Log warning in development mode\n                if (isDevelopment) {\n                    console.warn(\n                        `KineticSlider: External navigation elements not found: ${missingElements.join(', ')}. ` +\n                        `Ensure these selectors exist in the DOM.`\n                    );\n                }\n                return;\n            }\n\n            // Get stable event handlers\n            const { prevHandler, nextHandler } = handlersRef.current;\n\n            // Try batch registration first, fall back to direct listeners if needed\n            let registrationSuccessful = false;\n\n            if (resourceManager) {\n                registrationSuccessful = setupBatchListeners(\n                    prevNav, nextNav, prevHandler, nextHandler\n                );\n            }\n\n            // Fall back to direct listeners if batch registration failed or unavailable\n            if (!registrationSuccessful) {\n                registrationSuccessful = setupDirectListeners(\n                    prevNav, nextNav, prevHandler, nextHandler\n                );\n            }\n\n            // Mark as successfully initialized\n            isInitialized = registrationSuccessful;\n\n        } catch (error) {\n            // Handle any unexpected errors during initialization\n            if (isDevelopment) {\n                console.error('Error initializing external navigation:', error);\n            }\n        }\n\n        // Cleanup on unmount or dependencies change\n        return () => {\n            try {\n                // Skip cleanup if not initialized\n                if (!isInitialized) return;\n\n                // Get current element references for cleanup\n                const { prevNav, nextNav } = elementsRef.current;\n                const { prevHandler, nextHandler } = handlersRef.current;\n\n                // ResourceManager handles its own cleanup\n                if (!resourceManager && prevNav && nextNav) {\n                    // Safely remove event listeners\n                    try {\n                        prevNav.removeEventListener('click', prevHandler);\n                    } catch (e) {\n                        if (isDevelopment) {\n                            console.warn('Error removing event listener from previous nav:', e);\n                        }\n                    }\n\n                    try {\n                        nextNav.removeEventListener('click', nextHandler);\n                    } catch (e) {\n                        if (isDevelopment) {\n                            console.warn('Error removing event listener from next nav:', e);\n                        }\n                    }\n                }\n\n                // Clear element references to help garbage collection\n                elementsRef.current = { prevNav: null, nextNav: null };\n            } catch (cleanupError) {\n                // Handle errors during cleanup\n                if (isDevelopment) {\n                    console.error('Error during navigation cleanup:', cleanupError);\n                }\n            }\n        };\n    }, [\n        externalNav,\n        navElement.prev,\n        navElement.next,\n        resourceManager,\n        setupBatchListeners,\n        setupDirectListeners\n    ]);\n\n    // Return current elements for potential external use\n    return {\n        elements: elementsRef.current\n    };\n};\n\nexport default useExternalNav;"],"names":["useRef","useEffect","useCallback"],"mappings":"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"}