{"version":3,"file":"useResourceCleanup.mjs","sources":["../../../src/lib/hooks/useResourceCleanup.ts"],"sourcesContent":["/**\n * @file Resource Cleanup Hook\n * @description React hooks for component lifecycle resource management,\n * automatic cleanup, and memory leak prevention\n */\n\nimport React, { useCallback, useEffect, useRef } from 'react';\nimport { DisposableRegistry, createDisposable, type Disposable } from '../utils/memoryManager';\nimport { useIsMounted, useMountedState } from './shared/useIsMounted';\n\n/**\n * Hook for managing disposable resources with automatic cleanup\n * Cleans up all registered resources when component unmounts\n */\nexport function useDisposable(): {\n  register: <T extends Disposable>(disposable: T) => T;\n  registerFn: (cleanup: () => void) => Disposable;\n  unregister: (disposable: Disposable) => void;\n  disposeAll: () => void;\n} {\n  const registryRef = useRef<DisposableRegistry | undefined>(undefined);\n\n  // Initialize registry lazily\n  registryRef.current ??= new DisposableRegistry();\n\n  // Cleanup on unmount\n  useEffect(() => {\n    const registry = registryRef.current;\n    return () => {\n      registry?.dispose();\n    };\n  }, []);\n\n  const register = useCallback(<T extends Disposable>(disposable: T): T => {\n    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n    return registryRef.current!.register(disposable);\n  }, []);\n\n  const registerFn = useCallback((cleanup: () => void): Disposable => {\n    const disposable = createDisposable(cleanup);\n    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n    return registryRef.current!.register(disposable);\n  }, []);\n\n  const unregister = useCallback((disposable: Disposable): void => {\n    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n    registryRef.current!.unregister(disposable);\n  }, []);\n\n  const disposeAll = useCallback((): void => {\n    registryRef.current?.dispose();\n    registryRef.current = new DisposableRegistry();\n  }, []);\n\n  return { register, registerFn, unregister, disposeAll };\n}\n\n/**\n * Hook for managing abort controllers with automatic cleanup\n */\nexport function useAbortController(): {\n  getSignal: () => AbortSignal;\n  abort: (reason?: string) => void;\n  reset: () => AbortController;\n} {\n  const controllerRef = useRef<AbortController>(new AbortController());\n\n  // Abort on unmount\n  useEffect(() => {\n    return () => {\n      controllerRef.current.abort('Component unmounted');\n    };\n  }, []);\n\n  const getSignal = useCallback((): AbortSignal => {\n    // Create new controller if current one is aborted\n    if (controllerRef.current.signal.aborted) {\n      controllerRef.current = new AbortController();\n    }\n    return controllerRef.current.signal;\n  }, []);\n\n  const abort = useCallback((reason?: string): void => {\n    controllerRef.current.abort(reason);\n  }, []);\n\n  const reset = useCallback((): AbortController => {\n    controllerRef.current = new AbortController();\n    return controllerRef.current;\n  }, []);\n\n  return { getSignal, abort, reset };\n}\n\n/**\n * Hook for managing timeouts with automatic cleanup\n */\nexport function useTimeout(): {\n  set: (callback: () => void, delay: number) => number;\n  clear: (id: number) => void;\n  clearAll: () => void;\n} {\n  const timeoutsRef = useRef<Set<number>>(new Set());\n\n  // Clear all on unmount\n  useEffect(() => {\n    const timeouts = timeoutsRef.current;\n    return () => {\n      timeouts.forEach((id) => clearTimeout(id));\n      timeouts.clear();\n    };\n  }, []);\n\n  const set = useCallback((callback: () => void, delay: number): number => {\n    const id = setTimeout(() => {\n      timeoutsRef.current.delete(id);\n      callback();\n    }, delay) as unknown as number;\n    timeoutsRef.current.add(id);\n    return id;\n  }, []);\n\n  const clear = useCallback((id: number): void => {\n    clearTimeout(id);\n    timeoutsRef.current.delete(id);\n  }, []);\n\n  const clearAll = useCallback((): void => {\n    timeoutsRef.current.forEach((id) => clearTimeout(id));\n    timeoutsRef.current.clear();\n  }, []);\n\n  return { set, clear, clearAll };\n}\n\n/**\n * Hook for managing intervals with automatic cleanup\n */\nexport function useInterval(): {\n  set: (callback: () => void, delay: number) => number;\n  clear: (id: number) => void;\n  clearAll: () => void;\n} {\n  const intervalsRef = useRef<Set<number>>(new Set());\n\n  // Clear all on unmount\n  useEffect(() => {\n    const intervals = intervalsRef.current;\n    return () => {\n      intervals.forEach((id) => clearInterval(id));\n      intervals.clear();\n    };\n  }, []);\n\n  const set = useCallback((callback: () => void, delay: number): number => {\n    const id = setInterval(callback, delay) as unknown as number;\n    intervalsRef.current.add(id);\n    return id;\n  }, []);\n\n  const clear = useCallback((id: number): void => {\n    clearInterval(id);\n    intervalsRef.current.delete(id);\n  }, []);\n\n  const clearAll = useCallback((): void => {\n    intervalsRef.current.forEach((id) => clearInterval(id));\n    intervalsRef.current.clear();\n  }, []);\n\n  return { set, clear, clearAll };\n}\n\n/**\n * Hook for managing event listeners with automatic cleanup\n */\nexport function useEventListener(): {\n  add: <K extends keyof WindowEventMap>(\n    target: EventTarget,\n    type: K,\n    listener: (event: WindowEventMap[K]) => void,\n    options?: boolean | AddEventListenerOptions\n  ) => () => void;\n  remove: (cleanup: () => void) => void;\n  removeAll: () => void;\n} {\n  const cleanupsRef = useRef<Set<() => void>>(new Set());\n\n  // Remove all on unmount\n  useEffect(() => {\n    const cleanups = cleanupsRef.current;\n    return () => {\n      cleanups.forEach((cleanup) => cleanup());\n      cleanups.clear();\n    };\n  }, []);\n\n  const add = useCallback(\n    <K extends keyof WindowEventMap>(\n      target: EventTarget,\n      type: K,\n      listener: (event: WindowEventMap[K]) => void,\n      options?: boolean | AddEventListenerOptions\n    ): (() => void) => {\n      target.addEventListener(type, listener as EventListener, options);\n\n      const cleanup = (): void => {\n        target.removeEventListener(type, listener as EventListener, options);\n        cleanupsRef.current.delete(cleanup);\n      };\n\n      cleanupsRef.current.add(cleanup);\n      return cleanup;\n    },\n    []\n  );\n\n  const remove = useCallback((cleanup: () => void): void => {\n    cleanup();\n    cleanupsRef.current.delete(cleanup);\n  }, []);\n\n  const removeAll = useCallback((): void => {\n    cleanupsRef.current.forEach((cleanup) => cleanup());\n    cleanupsRef.current.clear();\n  }, []);\n\n  return { add, remove, removeAll };\n}\n\n/**\n * Hook for managing subscriptions with automatic cleanup\n */\nexport function useSubscription(): {\n  subscribe: <T>(\n    subscribe: (callback: (value: T) => void) => () => void,\n    callback: (value: T) => void\n  ) => () => void;\n  unsubscribe: (cleanup: () => void) => void;\n  unsubscribeAll: () => void;\n} {\n  const subscriptionsRef = useRef<Set<() => void>>(new Set());\n\n  // Unsubscribe all on unmount\n  useEffect(() => {\n    const subscriptions = subscriptionsRef.current;\n    return () => {\n      subscriptions.forEach((unsubscribe) => unsubscribe());\n      subscriptions.clear();\n    };\n  }, []);\n\n  const subscribe = useCallback(\n    <T>(\n      subscribeFn: (callback: (value: T) => void) => () => void,\n      callback: (value: T) => void\n    ): (() => void) => {\n      const unsubscribe = subscribeFn(callback);\n      subscriptionsRef.current.add(unsubscribe);\n      return () => {\n        unsubscribe();\n        subscriptionsRef.current.delete(unsubscribe);\n      };\n    },\n    []\n  );\n\n  const unsubscribe = useCallback((cleanup: () => void): void => {\n    cleanup();\n    subscriptionsRef.current.delete(cleanup);\n  }, []);\n\n  const unsubscribeAll = useCallback((): void => {\n    subscriptionsRef.current.forEach((unsubscribe) => unsubscribe());\n    subscriptionsRef.current.clear();\n  }, []);\n\n  return { subscribe, unsubscribe, unsubscribeAll };\n}\n\n/**\n * Hook for running cleanup effect on unmount\n */\nexport function useUnmountEffect(effect: () => void): void {\n  const effectRef = useRef(effect);\n  // eslint-disable-next-line react-hooks/refs\n  effectRef.current = effect;\n\n  useEffect(() => {\n    return () => {\n      effectRef.current();\n    };\n  }, []);\n}\n\n/**\n * Hook for tracking mounted state\n * @deprecated Use useMountedState from shared utilities instead\n */\nexport { useMountedState as useMounted } from './shared/useIsMounted';\n\n/**\n * Hook for safe state updates that prevent updates after unmount\n */\nexport function useSafeState<T>(initialValue: T): [T, (value: T | ((prev: T) => T)) => void] {\n  const [state, setStateInternal] = React.useState(initialValue);\n  const isMounted = useIsMounted();\n\n  const setState = useCallback(\n    (value: T | ((prev: T) => T)): void => {\n      if (isMounted()) {\n        setStateInternal(value);\n      }\n    },\n    [isMounted, setStateInternal]\n  );\n\n  return [state, setState];\n}\n\n/**\n * Hook for ref-based cleanup that runs synchronously\n */\nexport function useRefCleanup<T>(\n  factory: () => T,\n  cleanup: (value: T) => void\n): React.RefObject<T> {\n  const ref = useRef<T | null>(null);\n  // Store cleanup function in a ref to avoid re-running effect when it changes\n  const cleanupRef = useRef(cleanup);\n  cleanupRef.current = cleanup;\n\n  // Initialize\n  ref.current ??= factory();\n\n  // Cleanup - uses ref to always call latest cleanup function\n  useEffect(() => {\n    return () => {\n      if (ref.current !== null) {\n        cleanupRef.current(ref.current);\n        ref.current = null;\n      }\n    };\n  }, []); // Empty deps - cleanup ref always has latest function\n\n  return ref as React.RefObject<T>;\n}\n\n/**\n * Hook for managing WebSocket connections with cleanup\n */\nexport function useWebSocketCleanup(\n  url: string | (() => string),\n  options?: {\n    protocols?: string | string[];\n    onOpen?: (event: Event) => void;\n    onMessage?: (event: MessageEvent) => void;\n    onError?: (event: Event) => void;\n    onClose?: (event: CloseEvent) => void;\n    reconnect?: boolean;\n    reconnectInterval?: number;\n    maxReconnectAttempts?: number;\n  }\n): {\n  ws: WebSocket | null;\n  send: (data: string | ArrayBuffer | Blob) => void;\n  close: (code?: number, reason?: string) => void;\n  reconnect: () => void;\n  readyState: number;\n} {\n  const wsRef = useRef<WebSocket | null>(null);\n  const reconnectAttemptsRef = useRef(0);\n  const reconnectTimeoutRef = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n\n  const connect = useCallback(() => {\n    const wsUrl = typeof url === 'function' ? url() : url;\n    const ws = new WebSocket(wsUrl, options?.protocols);\n\n    ws.onopen = (event) => {\n      reconnectAttemptsRef.current = 0;\n      options?.onOpen?.(event);\n    };\n\n    ws.onmessage = options?.onMessage ?? ((): void => {});\n    ws.onerror = options?.onError ?? ((): void => {});\n\n    ws.onclose = (event) => {\n      options?.onClose?.(event);\n\n      // Auto reconnect\n      if (\n        options?.reconnect === true &&\n        !event.wasClean &&\n        reconnectAttemptsRef.current < (options?.maxReconnectAttempts ?? 5)\n      ) {\n        reconnectAttemptsRef.current++;\n        reconnectTimeoutRef.current = setTimeout((): void => {\n          connect();\n        }, options?.reconnectInterval ?? 3000);\n      }\n    };\n\n    wsRef.current = ws;\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [url]);\n\n  // Connect on mount\n  useEffect(() => {\n    connect();\n\n    return () => {\n      if (reconnectTimeoutRef.current !== undefined && reconnectTimeoutRef.current !== null) {\n        clearTimeout(reconnectTimeoutRef.current);\n      }\n      if (wsRef.current !== null && wsRef.current !== undefined) {\n        wsRef.current.close(1000, 'Component unmounted');\n        wsRef.current = null;\n      }\n    };\n  }, [connect]);\n\n  const send = useCallback((data: string | ArrayBuffer | Blob): void => {\n    if (wsRef.current?.readyState === WebSocket.OPEN) {\n      wsRef.current.send(data);\n    }\n  }, []);\n\n  const close = useCallback((code?: number, reason?: string): void => {\n    reconnectAttemptsRef.current = Infinity; // Prevent reconnect\n    wsRef.current?.close(code, reason);\n  }, []);\n\n  const manualReconnect = useCallback((): void => {\n    reconnectAttemptsRef.current = 0;\n    if (wsRef.current != null) {\n      wsRef.current.close();\n    }\n    connect();\n  }, [connect]);\n\n  return {\n    ws: wsRef.current,\n    send,\n    close,\n    reconnect: manualReconnect,\n    readyState: wsRef.current?.readyState ?? WebSocket.CLOSED,\n  };\n}\n\n/**\n * Hook for managing all resources with unified interface\n */\nexport function useResourceManager(): {\n  disposable: ReturnType<typeof useDisposable>;\n  abort: ReturnType<typeof useAbortController>;\n  timeout: ReturnType<typeof useTimeout>;\n  interval: ReturnType<typeof useInterval>;\n  eventListener: ReturnType<typeof useEventListener>;\n  subscription: ReturnType<typeof useSubscription>;\n  mounted: ReturnType<typeof useMountedState>;\n  cleanupAll: () => void;\n} {\n  const disposable = useDisposable();\n  const abort = useAbortController();\n  const timeout = useTimeout();\n  const interval = useInterval();\n  const eventListener = useEventListener();\n  const subscription = useSubscription();\n  const mounted = useMountedState();\n\n  const cleanupAll = useCallback(() => {\n    disposable.disposeAll();\n    abort.abort('Manual cleanup');\n    timeout.clearAll();\n    interval.clearAll();\n    eventListener.removeAll();\n    subscription.unsubscribeAll();\n  }, [disposable, abort, timeout, interval, eventListener, subscription]);\n\n  return {\n    disposable,\n    abort,\n    timeout,\n    interval,\n    eventListener,\n    subscription,\n    mounted,\n    cleanupAll,\n  };\n}\n\n/**\n * Hook for async operations with automatic cancellation\n */\nexport function useAsync<T, Args extends unknown[]>(\n  asyncFn: (...args: Args) => Promise<T>,\n  deps: React.DependencyList = []\n): {\n  execute: (...args: Args) => Promise<T | undefined>;\n  cancel: () => void;\n  loading: boolean;\n  error: Error | null;\n  value: T | undefined;\n} {\n  const [state, setState] = useSafeState<{\n    loading: boolean;\n    error: Error | null;\n    value: T | undefined;\n  }>({\n    loading: false,\n    error: null,\n    value: undefined,\n  });\n\n  const abortControllerRef = useRef<AbortController | null>(null);\n  const isMounted = useIsMounted();\n\n  const execute = useCallback(async (...args: Args): Promise<T | undefined> => {\n    // Cancel previous request\n    abortControllerRef.current?.abort();\n    abortControllerRef.current = new AbortController();\n\n    setState((prev) => ({ ...prev, loading: true, error: null }));\n\n    try {\n      const result = await asyncFn(...args);\n\n      if (isMounted() && !abortControllerRef.current?.signal.aborted) {\n        setState({ loading: false, error: null, value: result });\n        return result;\n      }\n    } catch (error) {\n      if (isMounted() && !abortControllerRef.current?.signal.aborted) {\n        const errorObj = error instanceof Error ? error : new Error(String(error));\n        setState({ loading: false, error: errorObj, value: undefined });\n      }\n    }\n\n    return undefined;\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, deps);\n\n  const cancel = useCallback(() => {\n    abortControllerRef.current?.abort();\n    setState((prev) => ({ ...prev, loading: false }));\n  }, [setState]);\n\n  useEffect(() => {\n    return () => {\n      abortControllerRef.current?.abort();\n    };\n  }, []);\n\n  return {\n    execute,\n    cancel,\n    ...state,\n  };\n}\n"],"names":["useDisposable","registryRef","useRef","DisposableRegistry","useEffect","registry","register","useCallback","disposable","registerFn","cleanup","createDisposable","unregister","disposeAll","useAbortController","controllerRef","getSignal","abort","reason","reset","useTimeout","timeoutsRef","timeouts","id","set","callback","delay","clear","clearAll","useInterval","intervalsRef","intervals","useEventListener","cleanupsRef","cleanups","add","target","type","listener","options","remove","removeAll","useSubscription","subscriptionsRef","subscriptions","unsubscribe","subscribe","subscribeFn","unsubscribeAll","useUnmountEffect","effect","effectRef","useSafeState","initialValue","state","setStateInternal","React","isMounted","useIsMounted","setState","value","useRefCleanup","factory","ref","cleanupRef","useWebSocketCleanup","url","wsRef","reconnectAttemptsRef","reconnectTimeoutRef","connect","wsUrl","ws","event","send","data","close","code","manualReconnect","useAsync","asyncFn","deps","abortControllerRef","execute","args","prev","result","error","errorObj","cancel"],"mappings":"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"}