/** * @module api * Data Layer: Fetches metric data from the backend API. * Provides functions to retrieve and handle metrics related to exit analysis. */ const API_BASE_URL = '/metrics'; /** * Fetches exit metrics from the API. * * @async * @function fetchMetrics * @param {Object} [params={}] - Optional query parameters. * @param {('pinned'|'unpinned')} [params.filter] - Filters runs by pinned/unpinned status. * @param {string} [params.setup_fingerprint] - Restricts metrics to runs with identical setup_fingerprint. * @returns {Promise>} * Returns an array of metrics objects. */ export async function fetchMetrics(params = {}) { const url = new URL(API_BASE_URL, window.location.origin); if (params.filter) { url.searchParams.append('filter', params.filter); } if (params.setup_fingerprint) { url.searchParams.append('setup_fingerprint', params.setup_fingerprint); } try { const response = await fetch(url.toString(), { method: 'GET', headers: { 'Accept': 'application/json' } }); if (!response.ok) { console.error(`Fetch error: HTTP ${response.status}`); return []; } const data = await response.json(); if (!Array.isArray(data)) { console.error('Unexpected API response format (expected an array).'); return []; } return data.map(item => ({ run_id: item.run_id ?? '', setup_fingerprint: item.setup_fingerprint ?? '', warn_rate: Number(item.warn_rate ?? 0), unknown_rate: Number(item.unknown_rate ?? 0), delta_t_stats: item.delta_t_stats ?? {}, timestamp: item.timestamp ?? '' })); } catch (err) { console.error('Error fetching metrics:', err); return []; } }