/** * API client for domain consensus plugin */ class APIClient { constructor() { this.baseUrl = window.location.origin; this.cache = new Map(); this.cacheTimeout = 30000; // 30 seconds } /** * Make an API request */ async request(endpoint, options = {}) { const url = `${this.baseUrl}/${endpoint}`; try { const response = await fetch(url, { ...options, headers: { 'Content-Type': 'application/json', ...options.headers } }); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const data = await response.json(); return data; } catch (error) { console.error(`API request failed: ${endpoint}`, error); throw error; } } /** * Get overview data */ async getOverview() { const cacheKey = 'overview'; const cached = this.cache.get(cacheKey); if (cached && (Date.now() - cached.timestamp) < this.cacheTimeout) { return cached.data; } try { const data = await this.request('api/overview'); this.cache.set(cacheKey, { data, timestamp: Date.now() }); return data; } catch (error) { // Return cached data if available, even if expired if (cached) { return cached.data; } throw error; } } /** * Get all domains with consensus status */ async getDomains() { const cacheKey = 'domains'; const cached = this.cache.get(cacheKey); if (cached && (Date.now() - cached.timestamp) < this.cacheTimeout) { return cached.data; } try { const data = await this.request('api/domains'); this.cache.set(cacheKey, { data, timestamp: Date.now() }); return data; } catch (error) { if (cached) { return cached.data; } throw error; } } /** * Get detailed consensus state for a specific domain */ async getDomainDetail(domain) { const cacheKey = `domain:${domain}`; const cached = this.cache.get(cacheKey); if (cached && (Date.now() - cached.timestamp) < this.cacheTimeout) { return cached.data; } try { const encodedDomain = encodeURIComponent(domain); const data = await this.request(`api/domain/${encodedDomain}`); this.cache.set(cacheKey, { data, timestamp: Date.now() }); return data; } catch (error) { if (cached) { return cached.data; } throw error; } } /** * Get consensus metrics */ async getMetrics() { const cacheKey = 'metrics'; const cached = this.cache.get(cacheKey); if (cached && (Date.now() - cached.timestamp) < this.cacheTimeout) { return cached.data; } try { const data = await this.request('api/metrics'); this.cache.set(cacheKey, { data, timestamp: Date.now() }); return data; } catch (error) { if (cached) { return cached.data; } throw error; } } /** * Get peer information */ async getPeers() { const cacheKey = 'peers'; const cached = this.cache.get(cacheKey); if (cached && (Date.now() - cached.timestamp) < this.cacheTimeout) { return cached.data; } try { const data = await this.request('api/peers'); this.cache.set(cacheKey, { data, timestamp: Date.now() }); return data; } catch (error) { if (cached) { return cached.data; } throw error; } } /** * Invalidate cache for a specific key or all cache */ invalidateCache(key = null) { if (key) { this.cache.delete(key); } else { this.cache.clear(); } } } // Create singleton instance window.apiClient = new APIClient();