BIST Predictor Dev
Initial commit - Clean HF release
1802f47
/**
* BIST Predictor β€” API Δ°letişim ModΓΌlΓΌ
* Backend REST API ve SSE stream yΓΆnetimi.
*/
const API = {
BASE_URL: window.location.origin,
/** SSE event source instance */
_eventSource: null,
_sseListeners: [],
// ─── HTTP Δ°stekleri ─────────────────────────────────────────────────────
async _fetch(endpoint, options = {}) {
try {
const url = `${this.BASE_URL}/api${endpoint}`;
const response = await fetch(url, {
headers: { 'Content-Type': 'application/json' },
...options,
});
if (!response.ok) {
const error = await response.json().catch(() => ({ detail: response.statusText }));
throw new Error(error.detail || `HTTP ${response.status}`);
}
return await response.json();
} catch (error) {
console.error(`API Error [${endpoint}]:`, error);
throw error;
}
},
async get(endpoint) {
return this._fetch(endpoint);
},
async post(endpoint, data = null) {
const options = { method: 'POST' };
if (data) options.body = JSON.stringify(data);
return this._fetch(endpoint, options);
},
// ─── Dashboard ──────────────────────────────────────────────────────────
async getDashboard(horizon = 10) {
return this.get(`/dashboard?horizon=${horizon}`);
},
async getStocks() {
return this.get('/stocks');
},
async getStockDetail(symbol, horizon = 10) {
return this.get(`/stock/${symbol}?horizon=${horizon}`);
},
// ─── Tahminler ──────────────────────────────────────────────────────────
async getPredictions(symbol, horizon = 10) {
return this.get(`/predictions/${symbol}?horizon=${horizon}`);
},
async triggerPrediction(symbol, horizons = '10') {
return this.post(`/predict/${symbol}?horizons=${horizons}`);
},
async triggerAllPredictions() {
return this.post('/predict-all');
},
// ─── GΓΌven PuanΔ± ────────────────────────────────────────────────────────
async getConfidence(symbol, horizon = 10) {
return this.get(`/confidence/${symbol}?horizon=${horizon}`);
},
async getConfidenceRanking(horizon = 10) {
return this.get(`/confidence-ranking?horizon=${horizon}`);
},
// ─── KarşılaştΔ±rma ──────────────────────────────────────────────────────
async getComparison(symbol, horizon = 10) {
return this.get(`/comparison/${symbol}?horizon=${horizon}`);
},
// ─── Veri YΓΆnetimi ──────────────────────────────────────────────────────
async loadInitialData() {
return this.post('/data/load');
},
async updateStockData(symbol) {
return this.post(`/data/update/${symbol}`);
},
async triggerComparison() {
return this.post('/data/compare');
},
// ─── Sistem ─────────────────────────────────────────────────────────────
async getSystemStatus() {
return this.get('/system/status');
},
async getSystemLogs(limit = 50) {
return this.get(`/system/logs?limit=${limit}`);
},
// ─── SSE (Server-Sent Events) ────────────────────────────────────────────
connectSSE() {
if (this._eventSource) {
this._eventSource.close();
}
this._eventSource = new EventSource(`${this.BASE_URL}/api/stream`);
this._eventSource.onopen = () => {
console.log('SSE bağlantısı kuruldu');
this._notifyListeners('connected', {});
};
this._eventSource.onmessage = (event) => {
try {
const parsed = JSON.parse(event.data);
const { type, data, timestamp } = parsed;
this._notifyListeners(type, data, timestamp);
} catch (e) {
console.warn('SSE parse hatasΔ±:', e);
}
};
this._eventSource.onerror = (error) => {
console.warn('SSE bağlantı hatası, yeniden bağlanılıyor...');
this._notifyListeners('disconnected', {});
// Otomatik yeniden bağlanma (EventSource bunu otomatik yapar)
};
},
disconnectSSE() {
if (this._eventSource) {
this._eventSource.close();
this._eventSource = null;
}
},
onSSE(callback) {
this._sseListeners.push(callback);
},
offSSE(callback) {
this._sseListeners = this._sseListeners.filter(cb => cb !== callback);
},
_notifyListeners(type, data, timestamp) {
for (const listener of this._sseListeners) {
try {
listener(type, data, timestamp);
} catch (e) {
console.error('SSE listener hatasΔ±:', e);
}
}
},
};