Files
p2ns/plugin-sites/domain.consensus/www/js/api.js
T
2025-12-17 20:05:50 -05:00

171 lines
3.7 KiB
JavaScript

/**
* 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();