/** * Baseline loading utilities * * Load and parse baseline JSON files for performance comparison. */ import type { BaselineData, ScenarioMetrics, BenchmarkScenario } from '../types'; /** * Validate baseline data structure */ export function validateBaseline(data: unknown): data is BaselineData { if (typeof data !== 'object' || data === null) { return false; } const baseline = data as Record; // Check required fields if (typeof baseline.version !== 'string') return false; if (typeof baseline.timestamp !== 'string') return false; if (typeof baseline.environment !== 'object' || baseline.environment === null) return false; if (typeof baseline.scenarios !== 'object' || baseline.scenarios === null) return false; // Validate environment const env = baseline.environment as Record; if (typeof env.platform !== 'string') return false; if (!['android', 'ios'].includes(env.platform)) return false; return true; } /** * Parse baseline JSON string * * @param jsonString - Raw JSON string from baseline file * @returns Parsed baseline data or null if invalid */ export function parseBaseline(jsonString: string): BaselineData | null { try { const data = JSON.parse(jsonString); if (validateBaseline(data)) { return data; } console.warn('[loadBaseline] Invalid baseline structure'); return null; } catch (error) { console.warn('[loadBaseline] Failed to parse baseline JSON:', error); return null; } } /** * Get metrics for a specific scenario and item count from baseline * * @param baseline - Loaded baseline data * @param scenario - Scenario name (e.g., 'scroll', 'drag') * @param itemCount - Number of items in the test * @returns Scenario metrics or null if not found */ export function getBaselineMetrics( baseline: BaselineData, scenario: BenchmarkScenario | string, itemCount: number, ): ScenarioMetrics | null { const scenarioData = baseline.scenarios[scenario]; if (!scenarioData) { console.warn(`[loadBaseline] Scenario '${scenario}' not found in baseline`); return null; } const itemCountStr = itemCount.toString(); const metrics = scenarioData[itemCountStr]; if (!metrics) { console.warn( `[loadBaseline] Item count '${itemCount}' not found for scenario '${scenario}'`, ); return null; } return metrics; } /** * Get vanilla FlashList comparison metrics from baseline * * @param baseline - Loaded baseline data * @param scenario - Scenario name * @param itemCount - Number of items * @returns Vanilla FlashList metrics or null if not available */ export function getVanillaMetrics( baseline: BaselineData, scenario: BenchmarkScenario | string, itemCount: number, ): ScenarioMetrics | null { if (!baseline.comparison?.vanillaFlashList) { return null; } const scenarioData = baseline.comparison.vanillaFlashList[scenario]; if (!scenarioData) { return null; } return scenarioData[itemCount.toString()] ?? null; } /** * Create an empty baseline template * * @param platform - Target platform * @param libraryVersion - Current library version * @returns Empty baseline structure */ export function createEmptyBaseline( platform: 'android' | 'ios', libraryVersion: string, ): BaselineData { return { version: '1.0', timestamp: new Date().toISOString(), environment: { platform, deviceModel: 'unknown', osVersion: 'unknown', libraryVersion, reactNativeVersion: 'unknown', reanimatedVersion: 'unknown', }, scenarios: {}, comparison: { vanillaFlashList: {}, }, }; } /** * Merge new scenario results into baseline * * @param baseline - Existing baseline data * @param scenario - Scenario name * @param itemCount - Number of items * @param metrics - New metrics to merge * @returns Updated baseline data */ export function mergeIntoBaseline( baseline: BaselineData, scenario: BenchmarkScenario | string, itemCount: number, metrics: ScenarioMetrics, ): BaselineData { const updated = { ...baseline }; if (!updated.scenarios[scenario]) { updated.scenarios[scenario] = {}; } updated.scenarios[scenario][itemCount.toString()] = metrics; updated.timestamp = new Date().toISOString(); return updated; } /** * Merge vanilla FlashList comparison results into baseline */ export function mergeVanillaIntoBaseline( baseline: BaselineData, scenario: BenchmarkScenario | string, itemCount: number, metrics: ScenarioMetrics, ): BaselineData { const updated = { ...baseline }; if (!updated.comparison) { updated.comparison = { vanillaFlashList: {} }; } if (!updated.comparison.vanillaFlashList[scenario]) { updated.comparison.vanillaFlashList[scenario] = {}; } updated.comparison.vanillaFlashList[scenario][itemCount.toString()] = metrics; updated.timestamp = new Date().toISOString(); return updated; } /** * Serialize baseline to JSON string */ export function serializeBaseline(baseline: BaselineData): string { return JSON.stringify(baseline, null, 2); }