{"version":3,"file":"react.cjs","sources":["../src/lib/core/PlanetaryComputerControlReact.tsx","../src/lib/hooks/usePlanetaryComputer.ts"],"sourcesContent":["import { useEffect, useRef } from 'react';\nimport { PlanetaryComputerControl } from './PlanetaryComputerControl';\nimport type { PlanetaryComputerReactProps } from './types';\n\n/**\n * React wrapper component for PlanetaryComputerControl.\n * Manages lifecycle and provides React-friendly event handling.\n *\n * @example\n * ```tsx\n * function App() {\n *   const [map, setMap] = useState<Map | null>(null);\n *\n *   return (\n *     <>\n *       <div ref={mapRef} />\n *       {map && (\n *         <PlanetaryComputerControlReact\n *           map={map}\n *           title=\"Earth Data\"\n *           onLayerAdd={(layer) => console.log('Added:', layer)}\n *         />\n *       )}\n *     </>\n *   );\n * }\n * ```\n */\nexport function PlanetaryComputerControlReact({\n  map,\n  onStateChange,\n  onLayerAdd,\n  onLayerRemove,\n  onSearch,\n  onItemSelect,\n  onError,\n  position = 'top-right',\n  ...options\n}: PlanetaryComputerReactProps): null {\n  const controlRef = useRef<PlanetaryComputerControl | null>(null);\n\n  useEffect(() => {\n    if (!map) return;\n\n    // Create control instance\n    const control = new PlanetaryComputerControl(options);\n    controlRef.current = control;\n\n    // Register event handlers\n    if (onStateChange) {\n      control.on('statechange', (e) => onStateChange(e.state));\n    }\n\n    if (onLayerAdd) {\n      control.on('layer:add', (e) => {\n        const layers = e.state.activeLayers;\n        if (layers.length > 0) {\n          onLayerAdd(layers[layers.length - 1]);\n        }\n      });\n    }\n\n    if (onLayerRemove) {\n      control.on('layer:remove', (e) => {\n        onLayerRemove(e.data as string);\n      });\n    }\n\n    if (onSearch) {\n      control.on('search:complete', (e) => {\n        onSearch(e.state.searchParams, e.state.searchResults);\n      });\n    }\n\n    if (onItemSelect) {\n      control.on('item:select', (e) => {\n        if (e.state.selectedItem) {\n          onItemSelect(e.state.selectedItem);\n        }\n      });\n    }\n\n    if (onError) {\n      control.on('error', (e) => {\n        if (e.state.error) {\n          onError(new Error(e.state.error));\n        }\n      });\n    }\n\n    // Add control to map\n    map.addControl(control, position);\n\n    // Cleanup on unmount\n    return () => {\n      if (map.hasControl(control)) {\n        map.removeControl(control);\n      }\n      controlRef.current = null;\n    };\n  }, [map]);\n\n  // Handle collapsed prop changes\n  useEffect(() => {\n    if (controlRef.current && options.collapsed !== undefined) {\n      const state = controlRef.current.getState();\n      if (options.collapsed !== state.collapsed) {\n        controlRef.current.toggle();\n      }\n    }\n  }, [options.collapsed]);\n\n  // This component renders nothing - the control manages its own DOM\n  return null;\n}\n","import { useState, useCallback, useRef, useEffect } from 'react';\nimport { STACClient } from '../api/stac-client';\nimport { TiTilerClient } from '../api/titiler-client';\nimport { SASTokenManager } from '../api/sas-token';\nimport type {\n  STACCollection,\n  STACItem,\n  STACSearchParams,\n  TileParams,\n} from '../api/types';\n\ninterface UsePlanetaryComputerOptions {\n  /** STAC API base URL */\n  stacApiUrl?: string;\n  /** TiTiler API base URL */\n  tilerApiUrl?: string;\n  /** Auto-load collections on mount */\n  autoLoadCollections?: boolean;\n}\n\ninterface UsePlanetaryComputerReturn {\n  /** All available collections */\n  collections: STACCollection[];\n  /** Loading state */\n  loading: boolean;\n  /** Error state */\n  error: Error | null;\n  /** Load all collections */\n  loadCollections: () => Promise<STACCollection[]>;\n  /** Search for items */\n  search: (params: STACSearchParams) => Promise<STACItem[]>;\n  /** Get tile URL for an item */\n  getItemTileUrl: (collectionId: string, itemId: string, params?: TileParams) => string;\n  /** Get tile URL for a collection mosaic */\n  getCollectionTileUrl: (collectionId: string, params?: TileParams) => string;\n  /** Get signed download URL */\n  getDownloadUrl: (url: string, collectionId: string) => Promise<string>;\n  /** Get collection by ID */\n  getCollection: (collectionId: string) => Promise<STACCollection>;\n  /** Get item by ID */\n  getItem: (collectionId: string, itemId: string) => Promise<STACItem>;\n}\n\n/**\n * React hook for interacting with Planetary Computer APIs.\n * Provides methods for browsing collections, searching, and generating tile URLs.\n *\n * @param options - Hook configuration options.\n * @returns Object with data and methods for Planetary Computer interaction.\n *\n * @example\n * ```tsx\n * function App() {\n *   const { collections, search, getItemTileUrl } = usePlanetaryComputer();\n *\n *   const handleSearch = async () => {\n *     const items = await search({\n *       collections: ['sentinel-2-l2a'],\n *       bbox: [-122.5, 37.5, -122, 38],\n *       datetime: '2024-01-01/2024-12-31',\n *     });\n *     console.log('Found items:', items);\n *   };\n *\n *   return <button onClick={handleSearch}>Search</button>;\n * }\n * ```\n */\nexport function usePlanetaryComputer(\n  options: UsePlanetaryComputerOptions = {}\n): UsePlanetaryComputerReturn {\n  const { stacApiUrl, tilerApiUrl, autoLoadCollections = true } = options;\n\n  const [collections, setCollections] = useState<STACCollection[]>([]);\n  const [loading, setLoading] = useState(false);\n  const [error, setError] = useState<Error | null>(null);\n\n  // Initialize clients\n  const stacClient = useRef(new STACClient(stacApiUrl));\n  const tilerClient = useRef(new TiTilerClient(tilerApiUrl));\n  const sasManager = useRef(new SASTokenManager());\n\n  /**\n   * Loads all available collections.\n   */\n  const loadCollections = useCallback(async () => {\n    setLoading(true);\n    setError(null);\n\n    try {\n      const result = await stacClient.current.getCollections();\n      setCollections(result);\n      return result;\n    } catch (err) {\n      const error = err instanceof Error ? err : new Error('Failed to load collections');\n      setError(error);\n      throw error;\n    } finally {\n      setLoading(false);\n    }\n  }, []);\n\n  /**\n   * Searches for items matching parameters.\n   */\n  const search = useCallback(async (params: STACSearchParams) => {\n    setLoading(true);\n    setError(null);\n\n    try {\n      return await stacClient.current.search(params);\n    } catch (err) {\n      const error = err instanceof Error ? err : new Error('Search failed');\n      setError(error);\n      throw error;\n    } finally {\n      setLoading(false);\n    }\n  }, []);\n\n  /**\n   * Gets a tile URL for a STAC item.\n   */\n  const getItemTileUrl = useCallback(\n    (collectionId: string, itemId: string, params: TileParams = {}) => {\n      return tilerClient.current.getItemTileUrl(collectionId, itemId, params);\n    },\n    []\n  );\n\n  /**\n   * Gets a tile URL for a collection mosaic.\n   */\n  const getCollectionTileUrl = useCallback(\n    (collectionId: string, params: TileParams = {}) => {\n      return tilerClient.current.getCollectionTileUrl(collectionId, params);\n    },\n    []\n  );\n\n  /**\n   * Gets a signed download URL for an asset.\n   */\n  const getDownloadUrl = useCallback(async (url: string, collectionId: string) => {\n    return sasManager.current.signUrl(url, collectionId);\n  }, []);\n\n  /**\n   * Gets a collection by ID.\n   */\n  const getCollection = useCallback(async (collectionId: string) => {\n    setLoading(true);\n    setError(null);\n\n    try {\n      return await stacClient.current.getCollection(collectionId);\n    } catch (err) {\n      const error = err instanceof Error ? err : new Error('Failed to get collection');\n      setError(error);\n      throw error;\n    } finally {\n      setLoading(false);\n    }\n  }, []);\n\n  /**\n   * Gets an item by ID.\n   */\n  const getItem = useCallback(async (collectionId: string, itemId: string) => {\n    setLoading(true);\n    setError(null);\n\n    try {\n      return await stacClient.current.getItem(collectionId, itemId);\n    } catch (err) {\n      const error = err instanceof Error ? err : new Error('Failed to get item');\n      setError(error);\n      throw error;\n    } finally {\n      setLoading(false);\n    }\n  }, []);\n\n  // Auto-load collections on mount\n  useEffect(() => {\n    if (autoLoadCollections) {\n      loadCollections().catch(() => {\n        // Error is already set in state\n      });\n    }\n  }, [autoLoadCollections, loadCollections]);\n\n  return {\n    collections,\n    loading,\n    error,\n    loadCollections,\n    search,\n    getItemTileUrl,\n    getCollectionTileUrl,\n    getDownloadUrl,\n    getCollection,\n    getItem,\n  };\n}\n"],"names":["useRef","useEffect","PlanetaryComputerControl","useState","STACClient","TiTilerClient","SASTokenManager","useCallback","error"],"mappings":"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"}