Kraft102's picture
fix: sql.js Docker/Alpine compatibility layer for PatternMemory and FailureMemory
5a81b95
/**
* useBackendData - Hook for fetching real data from backend endpoints
* Provides auto-refresh and caching capabilities
*/
import { useState, useEffect, useCallback } from 'react';
import { API_URL } from '@/config/api';
export interface BackendDataOptions {
endpoint: string;
refreshInterval?: number; // ms, 0 = no auto-refresh
enabled?: boolean;
}
export interface BackendDataResult<T> {
data: T | null;
isLoading: boolean;
error: Error | null;
refresh: () => Promise<void>;
lastUpdated: Date | null;
}
export function useBackendData<T = unknown>(
options: BackendDataOptions
): BackendDataResult<T> {
const { endpoint, refreshInterval = 30000, enabled = true } = options;
const [data, setData] = useState<T | null>(null);
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState<Error | null>(null);
const [lastUpdated, setLastUpdated] = useState<Date | null>(null);
const fetchData = useCallback(async () => {
if (!enabled) return;
setIsLoading(true);
setError(null);
try {
const response = await fetch(`${API_URL}${endpoint}`);
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
const result = await response.json();
setData(result);
setLastUpdated(new Date());
} catch (err) {
setError(err instanceof Error ? err : new Error(String(err)));
} finally {
setIsLoading(false);
}
}, [endpoint, enabled]);
useEffect(() => {
fetchData();
if (refreshInterval > 0 && enabled) {
const interval = setInterval(fetchData, refreshInterval);
return () => clearInterval(interval);
}
}, [fetchData, refreshInterval, enabled]);
return {
data,
isLoading,
error,
refresh: fetchData,
lastUpdated
};
}
// Specific hooks for common data types
export interface HealthData {
status: string;
timestamp: string;
services: Record<string, { healthy: boolean; latency?: number }>;
}
export function useHealthData(refreshInterval = 10000) {
return useBackendData<HealthData>({
endpoint: '/health',
refreshInterval
});
}
export interface GraphStats {
nodes: number;
relationships: number;
labels: string[];
}
export function useGraphStats(refreshInterval = 30000) {
return useBackendData<GraphStats>({
endpoint: '/api/graph/stats',
refreshInterval
});
}
export interface MCPTool {
name: string;
description: string;
inputSchema: Record<string, unknown>;
}
export function useMCPTools(refreshInterval = 60000) {
return useBackendData<{ tools: MCPTool[] }>({
endpoint: '/api/mcp/tools',
refreshInterval
});
}
export interface HyperEvent {
id: string;
timestamp: string;
level: string;
category: string;
message: string;
data?: Record<string, unknown>;
}
export function useHyperEvents(limit = 50, refreshInterval = 5000) {
return useBackendData<HyperEvent[]>({
endpoint: `/api/hyper/events?limit=${limit}`,
refreshInterval
});
}
export interface HealingStatus {
healthy: boolean;
services: Record<string, boolean>;
lastCheck: string;
}
export function useHealingStatus(refreshInterval = 15000) {
return useBackendData<HealingStatus>({
endpoint: '/api/healing/status',
refreshInterval
});
}
export interface KnowledgeStats {
totalPatterns: number;
categories: Record<string, number>;
sources: Record<string, number>;
}
export function useKnowledgeStats(refreshInterval = 60000) {
return useBackendData<KnowledgeStats>({
endpoint: '/api/healing/knowledge/stats',
refreshInterval
});
}
export interface IngestionStatus {
running: boolean;
lastRun: string;
stats: Record<string, number>;
}
export function useIngestionStatus(refreshInterval = 30000) {
return useBackendData<IngestionStatus>({
endpoint: '/api/ingestion/status',
refreshInterval
});
}
export default useBackendData;