diff --git a/src/pages/Index.tsx b/src/pages/Index.tsx index dcdda17..2925804 100644 --- a/src/pages/Index.tsx +++ b/src/pages/Index.tsx @@ -20,19 +20,6 @@ const debugTiming = (operation: string, startTime: number) => { return duration; }; -// Enhanced fetch with timing -const fetchWithTiming = async (url: string, options: RequestInit, operation: string) => { - const startTime = Date.now(); - try { - const response = await fetch(url, options); - debugTiming(operation, startTime); - return response; - } catch (error) { - debugTiming(`${operation} (FAILED)`, startTime); - throw error; - } -}; - interface Note { id: string; epochTime: number; @@ -105,6 +92,29 @@ const Index = () => { setDebugInfo(prev => [...prev.slice(-19), debugMessage]); // Keep last 20 messages }; + // Enhanced fetch with timing + const fetchWithTiming = async (url: string, options: RequestInit, operation: string) => { + const startTime = Date.now(); + try { + addDebugInfo(`Starting ${operation}...`); + const response = await fetch(url, options); + const duration = Date.now() - startTime; + debugTiming(operation, startTime); + + // Add network diagnostics for slow requests + if (duration > 1000) { + addDebugInfo(`Slow request: ${operation} took ${duration}ms`); + } + + return response; + } catch (error) { + const duration = Date.now() - startTime; + debugTiming(`${operation} (FAILED)`, startTime); + addDebugInfo(`Network error: ${operation} failed after ${duration}ms`); + throw error; + } + }; + const previousNoteRef = useRef(null); const currentNoteRef = useRef(null); const scratchRef = useRef(null); @@ -447,7 +457,7 @@ const Index = () => { setIsLoading(true); if (offset === 0) { setCacheMode('global'); - addDebugInfo(`📝 Loading notes (offset: ${offset}, limit: ${limit})`); + addDebugInfo(`Loading notes (offset: ${offset}, limit: ${limit})`); } const response = await fetchWithTiming(`${MEILISEARCH_ENDPOINT}/indexes/${NOTE_INDEX}/search`, { method: 'POST', @@ -470,31 +480,31 @@ const Index = () => { const data = await response.json(); const notes: Note[] = data.hits.map((hit: any) => mapHitToNote(hit)); - if (offset === 0) { - setNoteCache(notes); - if (notes.length > 0) { - setPreviousNote(notes[0]); - setCurrentNoteIndex(0); + if (offset === 0) { + setNoteCache(notes); + if (notes.length > 0) { + setPreviousNote(notes[0]); + setCurrentNoteIndex(0); + } + const loadTime = Date.now() - loadStartTime; + addDebugInfo(`Loaded ${notes.length} notes in ${loadTime}ms`); + } else { + setNoteCache(prev => [...prev, ...notes]); + const loadTime = Date.now() - loadStartTime; + addDebugInfo(`Loaded ${notes.length} additional notes in ${loadTime}ms`); } + } catch (error) { + console.error('Error loading notes:', error); const loadTime = Date.now() - loadStartTime; - addDebugInfo(`✅ Loaded ${notes.length} notes in ${loadTime}ms`); - } else { - setNoteCache(prev => [...prev, ...notes]); - const loadTime = Date.now() - loadStartTime; - addDebugInfo(`✅ Loaded ${notes.length} additional notes in ${loadTime}ms`); + addDebugInfo(`Failed to load notes after ${loadTime}ms`); + toast({ + title: "Error", + description: "Failed to load notes. Please check your connection.", + variant: "destructive", + }); + } finally { + setIsLoading(false); } - } catch (error) { - console.error('Error loading notes:', error); - const loadTime = Date.now() - loadStartTime; - addDebugInfo(`❌ Failed to load notes after ${loadTime}ms`); - toast({ - title: "Error", - description: "Failed to load notes. Please check your connection.", - variant: "destructive", - }); - } finally { - setIsLoading(false); - } }; // Load notes around a specific note @@ -605,8 +615,8 @@ const Index = () => { } const searchStartTime = Date.now(); - console.log(`🔍 Starting search for: "${query}"`); - addDebugInfo(`🔍 Searching for: "${query}"`); + console.log(`Starting search for: "${query}"`); + addDebugInfo(`Searching for: "${query}"`); try { const response = await fetchWithTiming(`${MEILISEARCH_ENDPOINT}/indexes/${NOTE_INDEX}/search`, { @@ -640,13 +650,13 @@ const Index = () => { setSearchResults(results); const searchTime = Date.now() - searchStartTime; debugTiming(`Search Results (${results.length} found)`, searchStartTime); - addDebugInfo(`✅ Search complete: ${results.length} results in ${searchTime}ms`); - console.log(`✅ Search complete: ${results.length} results found`); + addDebugInfo(`Search complete: ${results.length} results in ${searchTime}ms`); + console.log(`Search complete: ${results.length} results found`); } catch (error) { console.error('Error searching notes:', error); const searchTime = Date.now() - searchStartTime; debugTiming('Search (FAILED)', searchStartTime); - addDebugInfo(`❌ Search failed after ${searchTime}ms`); + addDebugInfo(`Search failed after ${searchTime}ms`); toast({ title: "Error", description: "Failed to search notes. Please try again.", @@ -890,7 +900,7 @@ const Index = () => { // Only restore focus if no modal is open and the current note field exists if (!isSearchOpen && !isGotoOpen && !isCleanupOpen && currentNoteRef.current) { currentNoteRef.current.focus(); - console.log('🎯 Focus restored on window focus'); + console.log('Focus restored on window focus'); } }; @@ -1017,15 +1027,20 @@ const Index = () => { // Check if an index exists const indexExists = async (index: string): Promise => { + const checkStart = Date.now(); try { + addDebugInfo(`Checking if ${index} index exists...`); const response = await fetchWithTiming(`${MEILISEARCH_ENDPOINT}/indexes/${index}`, { headers: { 'Authorization': `Bearer ${MEILISEARCH_API_KEY}`, }, }, `Check Index ${index}`); - return response.status === 200; + const exists = response.status === 200; + addDebugInfo(`${index} index ${exists ? 'exists' : 'does not exist'}: ${Date.now() - checkStart}ms`); + return exists; } catch (error) { console.error(`Error checking if index ${index} exists:`, error); + addDebugInfo(`Failed to check ${index} index: ${Date.now() - checkStart}ms`); return false; } }; @@ -1034,12 +1049,13 @@ const Index = () => { const initializeIndexes = async () => { const initStartTime = Date.now(); try { - console.log('🚀 Starting initialization...'); - addDebugInfo('🚀 Starting initialization...'); + console.log('Starting initialization...'); + addDebugInfo('Starting initialization...'); // Initialize notes index if (!(await indexExists(NOTE_INDEX))) { const indexStart = Date.now(); + addDebugInfo('Creating notes index...'); await fetchWithTiming(`${MEILISEARCH_ENDPOINT}/indexes`, { method: 'POST', headers: { @@ -1051,10 +1067,14 @@ const Index = () => { primaryKey: 'id', }), }, 'Initialize Notes Index'); - addDebugInfo(`⏱️ Initialize Notes Index: ${Date.now() - indexStart}ms`); + addDebugInfo(`Notes index created: ${Date.now() - indexStart}ms`); + } else { + addDebugInfo('Notes index already exists'); } // Configure notes index settings + addDebugInfo('Configuring notes sortable attributes...'); + const sortableStart = Date.now(); await fetchWithTiming(`${MEILISEARCH_ENDPOINT}/indexes/${NOTE_INDEX}/settings/sortable-attributes`, { method: 'PUT', headers: { @@ -1063,8 +1083,11 @@ const Index = () => { }, body: JSON.stringify(['date']), }, 'Configure Notes Sortable Attributes'); + addDebugInfo(`Sortable attributes configured: ${Date.now() - sortableStart}ms`); // Set ranking rules to prioritize sorting + addDebugInfo('Configuring notes ranking rules...'); + const rankingStart = Date.now(); await fetchWithTiming(`${MEILISEARCH_ENDPOINT}/indexes/${NOTE_INDEX}/settings/ranking-rules`, { method: 'PUT', headers: { @@ -1073,7 +1096,10 @@ const Index = () => { }, body: JSON.stringify(['sort', 'words', 'typo', 'proximity', 'attribute', 'exactness']), }, 'Configure Notes Ranking Rules'); + addDebugInfo(`Ranking rules configured: ${Date.now() - rankingStart}ms`); + addDebugInfo('Configuring notes filterable attributes...'); + const filterableStart = Date.now(); await fetchWithTiming(`${MEILISEARCH_ENDPOINT}/indexes/${NOTE_INDEX}/settings/filterable-attributes`, { method: 'PUT', headers: { @@ -1082,9 +1108,12 @@ const Index = () => { }, body: JSON.stringify(['date', 'topLetter', 'letterCount', 'topLetterFrequency']), }, 'Configure Notes Filterable Attributes'); + addDebugInfo(`Filterable attributes configured: ${Date.now() - filterableStart}ms`); // Initialize scratch index if (!(await indexExists(SCRATCH_INDEX))) { + const scratchStart = Date.now(); + addDebugInfo('Creating scratch index...'); await fetchWithTiming(`${MEILISEARCH_ENDPOINT}/indexes`, { method: 'POST', headers: { @@ -1096,9 +1125,14 @@ const Index = () => { primaryKey: 'id', }), }, 'Initialize Scratch Index'); + addDebugInfo(`Scratch index created: ${Date.now() - scratchStart}ms`); + } else { + addDebugInfo('Scratch index already exists'); } // Configure scratch index settings + addDebugInfo('Configuring scratch sortable attributes...'); + const scratchSortableStart = Date.now(); await fetchWithTiming(`${MEILISEARCH_ENDPOINT}/indexes/${SCRATCH_INDEX}/settings/sortable-attributes`, { method: 'PUT', headers: { @@ -1107,7 +1141,10 @@ const Index = () => { }, body: JSON.stringify(['date']), }, 'Configure Scratch Sortable Attributes'); + addDebugInfo(`Scratch sortable attributes configured: ${Date.now() - scratchSortableStart}ms`); + addDebugInfo('Configuring scratch filterable attributes...'); + const scratchFilterableStart = Date.now(); await fetchWithTiming(`${MEILISEARCH_ENDPOINT}/indexes/${SCRATCH_INDEX}/settings/filterable-attributes`, { method: 'PUT', headers: { @@ -1116,9 +1153,12 @@ const Index = () => { }, body: JSON.stringify(['date']), }, 'Configure Scratch Filterable Attributes'); + addDebugInfo(`Scratch filterable attributes configured: ${Date.now() - scratchFilterableStart}ms`); // Initialize settings index if (!(await indexExists(SETTINGS_INDEX))) { + const settingsStart = Date.now(); + addDebugInfo('Creating settings index...'); await fetchWithTiming(`${MEILISEARCH_ENDPOINT}/indexes`, { method: 'POST', headers: { @@ -1130,9 +1170,14 @@ const Index = () => { primaryKey: 'key', }), }, 'Initialize Settings Index'); + addDebugInfo(`Settings index created: ${Date.now() - settingsStart}ms`); + } else { + addDebugInfo('Settings index already exists'); } // Configure settings index + addDebugInfo('Configuring settings filterable attributes...'); + const settingsFilterableStart = Date.now(); await fetchWithTiming(`${MEILISEARCH_ENDPOINT}/indexes/${SETTINGS_INDEX}/settings/filterable-attributes`, { method: 'PUT', headers: { @@ -1140,13 +1185,14 @@ const Index = () => { 'Authorization': `Bearer ${MEILISEARCH_API_KEY}`, }, body: JSON.stringify(['key', 'value']), - }, 'Configure Settings Filterable Attributes'); + }, 'Configure Settings Filterable Attributes'); + addDebugInfo(`Settings filterable attributes configured: ${Date.now() - settingsFilterableStart}ms`); setIsInitialized(true); const totalTime = Date.now() - initStartTime; debugTiming('Total Initialization', initStartTime); - addDebugInfo(`✅ Total Initialization: ${totalTime}ms`); - console.log('✅ Initialization complete'); + addDebugInfo(`Total Initialization: ${totalTime}ms`); + console.log('Initialization complete'); toast({ title: "Initialization complete", description: "All indexes have been configured successfully.", @@ -1155,7 +1201,7 @@ const Index = () => { console.error('Error initializing indexes:', error); const totalTime = Date.now() - initStartTime; debugTiming('Initialization (FAILED)', initStartTime); - addDebugInfo(`❌ Initialization FAILED: ${totalTime}ms`); + addDebugInfo(`Initialization FAILED: ${totalTime}ms`); toast({ title: "Initialization failed", description: "Failed to initialize indexes. Please check your connection.", @@ -1169,7 +1215,7 @@ const Index = () => { // Focus the current note field immediately with a small delay to ensure DOM is ready const focusTimer = setTimeout(() => { currentNoteRef.current?.focus(); - console.log('🎯 Focus set on current note field'); + console.log('Focus set on current note field'); }, 100); return () => clearTimeout(focusTimer); @@ -1186,8 +1232,8 @@ const Index = () => { const loadInitialData = async () => { if (isInitialized) { const dataLoadStartTime = Date.now(); - console.log('📊 Starting data loading...'); - addDebugInfo('📊 Starting data loading...'); + console.log('Starting data loading...'); + addDebugInfo('Starting data loading...'); await loadNotes(); await loadLatestScratch(); @@ -1195,8 +1241,8 @@ const Index = () => { const totalTime = Date.now() - dataLoadStartTime; debugTiming('Total Data Loading', dataLoadStartTime); - addDebugInfo(`✅ Total Data Loading: ${totalTime}ms`); - console.log('✅ Data loading complete'); + addDebugInfo(`Total Data Loading: ${totalTime}ms`); + console.log('Data loading complete'); // Re-focus after data loading to ensure focus is maintained currentNoteRef.current?.focus();