{"version":3,"sources":["../src/lib/gloria.ts"],"names":["type"],"mappings":"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","file":"index.cjs","sourcesContent":["import { type } from 'arktype';\n\nexport const GloriaConfig = type({\n  \"apiKey?\": \"string\",\n  \"baseUrl?\": \"string\",\n  \"wsUrl?\": \"string\",\n  \"topics?\": \"string[]\",\n  \"defaultLimit?\": \"number\",\n  \"defaultTimeframe?\": \"string\"\n});\n\nexport type GloriaConfig = typeof GloriaConfig.infer;\n\nexport const NewsItem = type({\n  timestamp: \"number\",\n  signal: \"string\",\n  \"feed_category?\": \"string\",\n  \"[string]\": \"unknown\"\n});\n\nexport type NewsItem = typeof NewsItem.infer;\n\n// Enhanced RecapData with common properties while still allowing any additional properties\nexport const RecapData = type({\n  \"[string]\": \"unknown\"\n});\n\nexport type RecapData = typeof RecapData.infer;\n\nexport const WebSocketMessage = type({\n  type: \"'subscribe' | 'unsubscribe' | 'pong' | 'data' | 'error' | 'ping' | 'connected' | 'subscribed'\",\n  \"feed_category?\": \"string\",\n  \"content?\": \"unknown\",\n  \"action?\": \"string\",\n  \"error?\": \"string\", \n  \"details?\": \"string\",\n  \"timestamp?\": \"number\"\n});\n\nexport type WebSocketMessage = typeof WebSocketMessage.infer;\n\nexport class GloriaClient {\n  private apiKey: string;\n  private baseUrl: string;\n  private wsUrl: string;\n  private topics: string[];\n  private defaultLimit: number;\n  private defaultTimeframe: string;\n  private socket: WebSocket | null = null;\n  private reconnectAttempts = 0;\n  private maxReconnectAttempts = 5;\n  private reconnectDelay = 1000;\n  private pingInterval: Timer | null = null;\n  private messageHandlers: Map<string, (message: WebSocketMessage) => void> = new Map();\n  private subscribedTopics: Set<string> = new Set();\n\n  constructor(config?: GloriaConfig) {\n    // Validate config if provided\n    if (config) {\n      const validated = GloriaConfig(config);\n      if (validated instanceof type.errors) {\n        throw new Error(`Invalid config: ${validated.summary}`);\n      }\n    }\n    \n    this.apiKey = config?.apiKey || process.env.GLORIA_AI_API_KEY || '';\n    this.baseUrl = config?.baseUrl || 'https://ai-hub.cryptobriefing.com';\n    this.wsUrl = config?.wsUrl || 'wss://ai-hub.cryptobriefing.com/ws/feed';\n    this.topics = config?.topics || ['crypto', 'ai_agents', 'macro', 'rwa', 'tech'];\n    this.defaultLimit = config?.defaultLimit || 40;\n    this.defaultTimeframe = config?.defaultTimeframe || '12h';\n    \n    if (!this.apiKey) {\n      throw new Error('API key is required. Set GLORIA_AI_API_KEY env variable or pass it in config');\n    }\n  }\n\n  // WebSocket methods\n  connect(autoSubscribe: boolean = true): Promise<void> {\n    return new Promise((resolve, reject) => {\n      if (this.socket?.readyState === WebSocket.OPEN) {\n        resolve();\n        return;\n      }\n\n      this.socket = new WebSocket(`${this.wsUrl}?token=${this.apiKey}`);\n\n      this.socket.addEventListener('open', () => {\n        console.log('Connected to Gloria WebSocket');\n        this.reconnectAttempts = 0;\n        this.startPingPong();\n        \n        // Auto-subscribe to configured topics\n        if (autoSubscribe) {\n          this.subscribeToAllTopics();\n        }\n        \n        resolve();\n      });\n\n      this.socket.addEventListener('message', (event) => {\n        try {\n          const rawMessage = JSON.parse(event.data);\n          const validated = WebSocketMessage(rawMessage);\n          \n          if (validated instanceof type.errors) {\n            console.error('Invalid WebSocket message:', validated.summary);\n            return;\n          }\n          \n          this.handleMessage(validated);\n        } catch (error) {\n          console.error('Error parsing WebSocket message:', error);\n        }\n      });\n\n      this.socket.addEventListener('close', (event) => {\n        console.log('WebSocket connection closed:', event.code, event.reason);\n        this.stopPingPong();\n        this.subscribedTopics.clear();\n        this.attemptReconnect();\n      });\n\n      this.socket.addEventListener('error', (event) => {\n        console.error('WebSocket error:', event);\n        reject(event);\n      });\n    });\n  }\n\n  private handleMessage(message: WebSocketMessage) {\n    // Validate message with arktype\n    const validated = WebSocketMessage(message);\n    if (validated instanceof type.errors) {\n      console.error('Invalid WebSocket message:', validated.summary);\n      return;\n    }\n\n    switch (validated.type) {\n      case 'connected':\n        console.log('WebSocket connection confirmed');\n        break;\n      case 'subscribed':\n        console.log(`Successfully subscribed to ${validated.feed_category}`);\n        break;\n      case 'data':\n        if (validated.action === 'subscribed') {\n          console.log(`Successfully subscribed to ${validated.feed_category}`);\n        }\n        break;\n      case 'error':\n        console.error('Error:', validated.error, validated.details);\n        break;\n      case 'ping':\n        this.pong(validated.timestamp);\n        break;\n    }\n\n    // Call custom handlers\n    const handler = this.messageHandlers.get(validated.type);\n    if (handler) {\n      handler(validated);\n    }\n  }\n\n  private pong(timestamp?: number) {\n    if (this.socket?.readyState === WebSocket.OPEN) {\n      this.socket.send(JSON.stringify({\n        type: 'pong',\n        timestamp\n      }));\n    }\n  }\n\n  private startPingPong() {\n    this.pingInterval = setInterval(() => {\n      if (this.socket?.readyState === WebSocket.OPEN) {\n        this.socket.send(JSON.stringify({\n          type: 'ping',\n          timestamp: Date.now()\n        }));\n      }\n    }, 30000); // Ping every 30 seconds\n  }\n\n  private stopPingPong() {\n    if (this.pingInterval) {\n      clearInterval(this.pingInterval);\n      this.pingInterval = null;\n    }\n  }\n\n  private attemptReconnect() {\n    if (this.reconnectAttempts >= this.maxReconnectAttempts) {\n      console.error('Max reconnection attempts reached');\n      return;\n    }\n\n    this.reconnectAttempts++;\n    const delay = this.reconnectDelay * Math.pow(2, this.reconnectAttempts - 1);\n    \n    console.log(`Attempting to reconnect in ${delay}ms (attempt ${this.reconnectAttempts}/${this.maxReconnectAttempts})`);\n    \n    setTimeout(() => {\n      this.connect().catch(console.error);\n    }, delay);\n  }\n\n  private subscribeToAllTopics() {\n    for (const topic of this.topics) {\n      this.subscribe(topic);\n    }\n  }\n\n  subscribe(feedCategory: string) {\n    if (!this.socket || this.socket.readyState !== WebSocket.OPEN) {\n      throw new Error('WebSocket is not connected. Call connect() first');\n    }\n\n    this.socket.send(JSON.stringify({\n      type: 'subscribe',\n      feed_category: feedCategory\n    }));\n    this.subscribedTopics.add(feedCategory);\n  }\n\n  unsubscribe(feedCategory: string) {\n    if (!this.socket || this.socket.readyState !== WebSocket.OPEN) {\n      throw new Error('WebSocket is not connected');\n    }\n\n    this.socket.send(JSON.stringify({\n      type: 'unsubscribe',\n      feed_category: feedCategory\n    }));\n    this.subscribedTopics.delete(feedCategory);\n  }\n\n  onMessage(type: string, handler: (message: WebSocketMessage) => void) {\n    this.messageHandlers.set(type, handler);\n  }\n\n  disconnect() {\n    this.stopPingPong();\n    if (this.socket) {\n      this.socket.close();\n      this.socket = null;\n    }\n  }\n\n  // News API methods\n  async fetchNews(params?: {\n    page?: number;\n    limit?: number;\n    fromDate?: string;\n    toDate?: string;\n    topics?: string[];\n  }): Promise<NewsItem[]> {\n    const queryParams = new URLSearchParams({\n      token: this.apiKey,\n      feed_categories: (params?.topics || this.topics).join(','),\n      page: (params?.page || 1).toString(),\n      limit: (params?.limit || this.defaultLimit).toString()\n    });\n\n    if (params?.fromDate) {\n      queryParams.append('from_date', params.fromDate);\n    }\n    if (params?.toDate) {\n      queryParams.append('to_date', params.toDate);\n    }\n\n    const response = await fetch(`${this.baseUrl}/news?${queryParams}`);\n\n    if (!response.ok) {\n      throw new Error(`HTTP error! Status: ${response.status}`);\n    }\n\n    const data = await response.json();\n    \n    // Validate each news item\n    if (!Array.isArray(data)) {\n      throw new Error('Invalid response: expected array of news items');\n    }\n    \n    return data.map((item: unknown) => {\n      const validated = NewsItem(item);\n      if (validated instanceof type.errors) {\n        console.warn('Invalid news item:', validated.summary);\n        // Return a minimal valid object or skip\n        return { timestamp: Date.now(), signal: 'invalid' };\n      }\n      return validated;\n    });\n  }\n\n  // Recap API methods\n  async fetchRecap(category?: string, timeframe?: string): Promise<RecapData> {\n    // If no category specified, fetch for first configured topic\n    const feedCategory = category || this.topics[0];\n    const tf = timeframe || this.defaultTimeframe;\n    \n    const response = await fetch(\n      `${this.baseUrl}/recaps?token=${this.apiKey}&feed_category=${feedCategory}&timeframe=${tf}`\n    );\n\n    if (!response.ok) {\n      throw new Error(`HTTP error! Status: ${response.status} for ${feedCategory}`);\n    }\n\n    const data = await response.json();\n    const validated = RecapData(data);\n    \n    if (validated instanceof type.errors) {\n      throw new Error(`Invalid recap data: ${validated.summary}`);\n    }\n    \n    return validated;\n  }\n\n  // Fetch recaps for all configured topics\n  async fetchAllRecaps(timeframe?: string): Promise<Record<string, RecapData>> {\n    const tf = timeframe || this.defaultTimeframe;\n    const recaps: Record<string, RecapData> = {};\n    \n    await Promise.all(\n      this.topics.map(async (topic) => {\n        try {\n          recaps[topic] = await this.fetchRecap(topic, tf);\n        } catch (error) {\n          console.error(`Failed to fetch recap for ${topic}:`, error);\n          recaps[topic] = { error: `Failed to fetch: ${error}` };\n        }\n      })\n    );\n    \n    return recaps;\n  }\n\n  // Getters for configuration\n  getTopics(): string[] {\n    return [...this.topics];\n  }\n\n  getSubscribedTopics(): string[] {\n    return Array.from(this.subscribedTopics);\n  }\n\n  setTopics(topics: string[]) {\n    this.topics = topics;\n    // If connected, update subscriptions\n    if (this.socket?.readyState === WebSocket.OPEN) {\n      // Unsubscribe from topics not in the new list\n      for (const topic of this.subscribedTopics) {\n        if (!topics.includes(topic)) {\n          this.unsubscribe(topic);\n        }\n      }\n      // Subscribe to new topics\n      for (const topic of topics) {\n        if (!this.subscribedTopics.has(topic)) {\n          this.subscribe(topic);\n        }\n      }\n    }\n  }\n}\n\nexport default GloriaClient;"]}