/ apps / web / src / hooks / useCompatibleSRS.ts
useCompatibleSRS.ts
  1  import { useCallback } from 'react'
  2  import { usePGLiteSRS } from './usePGLiteSRS'
  3  import type { DueCard } from '../types/srs.types'
  4  
  5  /**
  6   * Compatibility hook that wraps PGLite SRS functionality
  7   * Provides the same interface as the old IDB implementation
  8   */
  9  export function useCompatibleSRS() {
 10    const pgLiteSRS = usePGLiteSRS()
 11  
 12    // Wrapper for getDueCards
 13    const getDueCards = useCallback(async (limit?: number, songId?: number): Promise<DueCard[]> => {
 14      const cards = await pgLiteSRS.getDueCards(limit, songId)
 15      // Convert PGLite format to IDB format for compatibility
 16      return cards.map(card => ({
 17        id: card.id!,
 18        songId: card.song_id,
 19        lineIndex: card.referent_id, // Map referent_id back to lineIndex
 20        lineText: card.fragment,
 21        songTitle: card.song_title,
 22        artistName: card.artist_name,
 23        difficulty: card.difficulty,
 24        stability: card.stability,
 25        elapsedDays: card.elapsed_days,
 26        scheduledDays: card.scheduled_days,
 27        reps: card.reps,
 28        lapses: card.lapses,
 29        state: card.state,
 30        lastReview: card.last_review,
 31        dueDate: card.due_date,
 32        createdAt: card.created_at,
 33        updatedAt: card.updated_at
 34      }))
 35    }, [pgLiteSRS])
 36  
 37    // Wrapper for updateCardReview
 38    const updateCardReview = useCallback(async (
 39      songId: number,
 40      lineIndex: number,
 41      wasCorrect: boolean
 42    ): Promise<boolean> => {
 43      return await pgLiteSRS.updateCardReview(songId, lineIndex, wasCorrect)
 44    }, [pgLiteSRS])
 45  
 46    // Wrapper for saveExerciseSession (saveStudySession in PGLite)
 47    const saveExerciseSession = useCallback(async (data: {
 48      cardsReviewed: number
 49      cardsCorrect: number
 50      accuracy?: number
 51    }): Promise<string | null> => {
 52      return await pgLiteSRS.saveStudySession({
 53        cardsReviewed: data.cardsReviewed,
 54        cardsCorrect: data.cardsCorrect,
 55        startedAt: Date.now() - 300000, // Default 5 minutes ago
 56        completedAt: Date.now()
 57      })
 58    }, [pgLiteSRS])
 59  
 60    // Wrapper for createExerciseCard
 61    const createExerciseCard = useCallback(async (params: {
 62      exerciseId: string
 63      exerciseType: string
 64      songId: number
 65      referentId: number
 66      question: string
 67      fragment: string
 68      songTitle?: string
 69      artistName?: string
 70    }): Promise<boolean> => {
 71      return await pgLiteSRS.createExerciseCard({
 72        songId: params.songId,
 73        referentId: params.referentId,
 74        fragment: params.fragment,
 75        songTitle: params.songTitle,
 76        artistName: params.artistName
 77      })
 78    }, [pgLiteSRS])
 79  
 80    // Wrapper for getUserStats
 81    const getUserStats = useCallback(async (songId?: number) => {
 82      const stats = await pgLiteSRS.getUserStats(songId)
 83      if (!stats) return null
 84      
 85      // Convert to IDB format
 86      return {
 87        newCards: stats.new_cards,
 88        learningCards: stats.learning_cards,
 89        dueCards: stats.review_cards, // Use review_cards instead of total_due_cards
 90        totalCards: stats.total_cards,
 91        averageScore: 0 // Not tracked in PGLite
 92      }
 93    }, [pgLiteSRS])
 94  
 95    return {
 96      // State
 97      isReady: pgLiteSRS.isReady,
 98      isInitialized: pgLiteSRS.isReady,
 99      isChecking: false,
100      usePGLite: true, // Always using PGLite now
101      
102      // Core SRS operations
103      getDueCards,
104      updateCardReview,
105      saveExerciseSession,
106      createExerciseCard,
107      getUserStats,
108      
109      // Pass through from PGLite
110      syncStatus: pgLiteSRS.syncStatus,
111      currentChainId: pgLiteSRS.currentChainId,
112      
113      // New method to check total cards (useful for migration status)
114      getTotalCardCount: useCallback(async () => {
115        const stats = await pgLiteSRS.getUserStats()
116        return stats?.total_cards || 0
117      }, [pgLiteSRS])
118    }
119  }