listo carga de datos en localstorage
This commit is contained in:
@@ -29,6 +29,8 @@ export interface TableDataActions<T = Record<string, unknown>> {
|
||||
initialize(): Promise<void>
|
||||
getRecord(id: string | number): T | undefined
|
||||
filterRecords(predicate: (record: T) => boolean): T[]
|
||||
loadAllDataInBatches(onProgress?: (progress: number) => void): Promise<void>
|
||||
loadLatestDataInBatches(onProgress?: (progress: number) => void): Promise<void>
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -57,36 +59,46 @@ export function createTableDataStore<T = Record<string, unknown>>(
|
||||
/**
|
||||
* Get all records
|
||||
*/
|
||||
allRecords: (state): T[] => state.data,
|
||||
allRecords(): T[] {
|
||||
return this.data as T[]
|
||||
},
|
||||
|
||||
/**
|
||||
* Check if data is available
|
||||
*/
|
||||
hasData: (state): boolean => state.data.length > 0,
|
||||
hasData(): boolean {
|
||||
return this.data.length > 0
|
||||
},
|
||||
|
||||
/**
|
||||
* Check if data is currently loading
|
||||
*/
|
||||
isLoading: (state): boolean => state.loading,
|
||||
isLoading(): boolean {
|
||||
return this.loading
|
||||
},
|
||||
|
||||
/**
|
||||
* Check if there's an error
|
||||
*/
|
||||
hasError: (state): boolean => !!state.error,
|
||||
hasError(): boolean {
|
||||
return !!this.error
|
||||
},
|
||||
|
||||
/**
|
||||
* Get total number of records
|
||||
*/
|
||||
recordCount: (state): number => state.data.length,
|
||||
recordCount(): number {
|
||||
return this.data.length
|
||||
},
|
||||
|
||||
/**
|
||||
* Get formatted last updated time
|
||||
*/
|
||||
formattedLastUpdated: (state): string => {
|
||||
if (!state.lastUpdated) return 'Nunca'
|
||||
formattedLastUpdated(): string {
|
||||
if (!this.lastUpdated) return 'Nunca'
|
||||
|
||||
try {
|
||||
return new Date(state.lastUpdated).toLocaleString('es-ES', {
|
||||
return new Date(this.lastUpdated).toLocaleString('es-ES', {
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: 'numeric',
|
||||
@@ -101,10 +113,10 @@ export function createTableDataStore<T = Record<string, unknown>>(
|
||||
/**
|
||||
* Check if data is stale (older than 5 minutes)
|
||||
*/
|
||||
isStale: (state): boolean => {
|
||||
if (!state.lastUpdated) return true
|
||||
isStale(): boolean {
|
||||
if (!this.lastUpdated) return true
|
||||
|
||||
const lastUpdate = new Date(state.lastUpdated)
|
||||
const lastUpdate = new Date(this.lastUpdated)
|
||||
const now = new Date()
|
||||
const fiveMinutes = 5 * 60 * 1000
|
||||
|
||||
@@ -186,19 +198,27 @@ export function createTableDataStore<T = Record<string, unknown>>(
|
||||
* Load data from localStorage cache
|
||||
*/
|
||||
loadFromCache(): void {
|
||||
if (!process.client) return
|
||||
if (!process.client) {
|
||||
console.log(`[${tableName}] loadFromCache: Not on client, skipping`)
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
console.log(`[${tableName}] loadFromCache: Attempting to load from key: ${cacheKey}`)
|
||||
const cached = localStorage.getItem(cacheKey)
|
||||
if (cached) {
|
||||
const parsedCache = JSON.parse(cached)
|
||||
console.log(`[${tableName}] loadFromCache: Found ${parsedCache.data?.length || 0} records in cache`)
|
||||
this.data = parsedCache.data || []
|
||||
this.lastUpdated = parsedCache.lastUpdated || null
|
||||
this.limit = parsedCache.limit || defaultLimit
|
||||
this.initialized = true
|
||||
console.log(`[${tableName}] loadFromCache: Successfully loaded, data.length: ${this.data.length}`)
|
||||
} else {
|
||||
console.log(`[${tableName}] loadFromCache: No cached data found`)
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn(`Failed to load ${tableName} data from cache:`, error)
|
||||
console.error(`[${tableName}] loadFromCache: Failed to load data from cache:`, error)
|
||||
}
|
||||
},
|
||||
|
||||
@@ -259,7 +279,230 @@ export function createTableDataStore<T = Record<string, unknown>>(
|
||||
* Filter records by a predicate function
|
||||
*/
|
||||
filterRecords(predicate: (record: T) => boolean): T[] {
|
||||
return this.data.filter(predicate)
|
||||
return (this.data as T[]).filter(predicate)
|
||||
},
|
||||
|
||||
/**
|
||||
* Load all data in batches with progress callback
|
||||
*/
|
||||
async loadAllDataInBatches(onProgress?: (progress: number) => void): Promise<void> {
|
||||
console.log(`[${tableName}] loadAllDataInBatches: Starting...`)
|
||||
this.loading = true
|
||||
this.error = null
|
||||
|
||||
try {
|
||||
// Clear existing data
|
||||
console.log(`[${tableName}] loadAllDataInBatches: Clearing ${this.data.length} existing records`)
|
||||
this.data.splice(0, this.data.length)
|
||||
console.log(`[${tableName}] loadAllDataInBatches: Data cleared, length now: ${this.data.length}`)
|
||||
|
||||
let offset = 0
|
||||
const limit = 500
|
||||
let hasMore = true
|
||||
let totalFetched = 0
|
||||
let estimatedTotal = 0
|
||||
|
||||
while (hasMore) {
|
||||
console.log(`[${tableName}] loadAllDataInBatches: Fetching batch at offset ${offset}`)
|
||||
const response = await $fetch(`/api/data/${tableName}`, {
|
||||
params: { limit, offset }
|
||||
})
|
||||
|
||||
if (!response) {
|
||||
console.log(`[${tableName}] loadAllDataInBatches: No response, stopping`)
|
||||
hasMore = false
|
||||
break
|
||||
}
|
||||
|
||||
// Get total count from first response
|
||||
if (offset === 0 && response.count) {
|
||||
estimatedTotal = response.count
|
||||
console.log(`[${tableName}] loadAllDataInBatches: Estimated total: ${estimatedTotal}`)
|
||||
}
|
||||
|
||||
if (response.records && response.records.length > 0) {
|
||||
console.log(`[${tableName}] loadAllDataInBatches: Got ${response.records.length} records`)
|
||||
this.data.push(...(response.records as T[]))
|
||||
totalFetched += response.records.length
|
||||
console.log(`[${tableName}] loadAllDataInBatches: Total fetched so far: ${totalFetched}, data.length: ${this.data.length}`)
|
||||
|
||||
// Update progress
|
||||
if (onProgress) {
|
||||
if (estimatedTotal > 0) {
|
||||
onProgress(Math.min(95, (totalFetched / estimatedTotal) * 100))
|
||||
} else {
|
||||
onProgress(Math.min(95, (totalFetched / 10000) * 100))
|
||||
}
|
||||
}
|
||||
|
||||
// Check if we got fewer records than requested (means we're at the end)
|
||||
hasMore = response.records.length === limit
|
||||
offset += limit
|
||||
} else {
|
||||
console.log(`[${tableName}] loadAllDataInBatches: No records in response, stopping`)
|
||||
hasMore = false
|
||||
}
|
||||
}
|
||||
|
||||
this.lastUpdated = new Date().toISOString()
|
||||
this.initialized = true
|
||||
|
||||
console.log(`[${tableName}] loadAllDataInBatches: Finished loading ${this.data.length} records`)
|
||||
|
||||
// Persist to localStorage
|
||||
if (process.client) {
|
||||
try {
|
||||
console.log(`[${tableName}] loadAllDataInBatches: Persisting to localStorage with key: ${cacheKey}`)
|
||||
const dataToSave = {
|
||||
data: this.data,
|
||||
lastUpdated: this.lastUpdated,
|
||||
limit: this.limit
|
||||
}
|
||||
console.log(`[${tableName}] loadAllDataInBatches: Saving ${dataToSave.data.length} records`)
|
||||
localStorage.setItem(cacheKey, JSON.stringify(dataToSave))
|
||||
console.log(`[${tableName}] loadAllDataInBatches: Successfully saved to localStorage`)
|
||||
|
||||
// Verify it was saved
|
||||
const saved = localStorage.getItem(cacheKey)
|
||||
if (saved) {
|
||||
const parsed = JSON.parse(saved)
|
||||
console.log(`[${tableName}] loadAllDataInBatches: Verification - localStorage contains ${parsed.data?.length || 0} records`)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`[${tableName}] loadAllDataInBatches: Failed to persist data to localStorage:`, error)
|
||||
}
|
||||
} else {
|
||||
console.log(`[${tableName}] loadAllDataInBatches: Not on client, skipping localStorage`)
|
||||
}
|
||||
|
||||
if (onProgress) {
|
||||
onProgress(100)
|
||||
}
|
||||
} catch (error: any) {
|
||||
this.error = this.extractErrorMessage(error)
|
||||
console.error(`[${tableName}] loadAllDataInBatches: Error:`, error)
|
||||
throw error
|
||||
} finally {
|
||||
this.loading = false
|
||||
console.log(`[${tableName}] loadAllDataInBatches: Completed`)
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Load only latest data (incremental) in batches with progress callback
|
||||
*/
|
||||
async loadLatestDataInBatches(onProgress?: (progress: number) => void): Promise<void> {
|
||||
console.log(`[${tableName}] loadLatestDataInBatches: Starting...`)
|
||||
this.loading = true
|
||||
this.error = null
|
||||
|
||||
try {
|
||||
// Find the most recent created_at in memory
|
||||
let lastCreatedAt: string | null = null
|
||||
if (this.data.length > 0) {
|
||||
const sortedRecords = [...(this.data as any[])].sort((a, b) => {
|
||||
const dateA = new Date(a.created_at || 0).getTime()
|
||||
const dateB = new Date(b.created_at || 0).getTime()
|
||||
return dateB - dateA
|
||||
})
|
||||
lastCreatedAt = sortedRecords[0]?.created_at || null
|
||||
console.log(`[${tableName}] loadLatestDataInBatches: Most recent created_at in memory: ${lastCreatedAt}`)
|
||||
} else {
|
||||
console.log(`[${tableName}] loadLatestDataInBatches: No data in memory, will fetch all`)
|
||||
}
|
||||
|
||||
let offset = 0
|
||||
const limit = 500
|
||||
let hasMore = true
|
||||
let newRecordsCount = 0
|
||||
|
||||
while (hasMore) {
|
||||
console.log(`[${tableName}] loadLatestDataInBatches: Fetching batch at offset ${offset}`)
|
||||
const response = await $fetch(`/api/data/${tableName}`, {
|
||||
params: {
|
||||
limit,
|
||||
offset,
|
||||
orderBy: 'created_at',
|
||||
orderDirection: 'desc'
|
||||
}
|
||||
})
|
||||
|
||||
if (!response || !response.records || response.records.length === 0) {
|
||||
console.log(`[${tableName}] loadLatestDataInBatches: No response or records, stopping`)
|
||||
hasMore = false
|
||||
break
|
||||
}
|
||||
|
||||
console.log(`[${tableName}] loadLatestDataInBatches: Got ${response.records.length} records`)
|
||||
|
||||
// Filter only records newer than what we have
|
||||
const newRecords = lastCreatedAt
|
||||
? response.records.filter((r: any) => r.created_at > lastCreatedAt)
|
||||
: response.records
|
||||
|
||||
console.log(`[${tableName}] loadLatestDataInBatches: ${newRecords.length} new records after filtering`)
|
||||
|
||||
if (newRecords.length > 0) {
|
||||
this.data.unshift(...(newRecords as T[]))
|
||||
newRecordsCount += newRecords.length
|
||||
console.log(`[${tableName}] loadLatestDataInBatches: Total new records: ${newRecordsCount}, data.length: ${this.data.length}`)
|
||||
}
|
||||
|
||||
// Update progress
|
||||
if (onProgress) {
|
||||
onProgress(Math.min(95, (newRecordsCount / 500) * 100))
|
||||
}
|
||||
|
||||
// Stop if we found records older than our last one
|
||||
if (lastCreatedAt && response.records.some((r: any) => r.created_at <= lastCreatedAt)) {
|
||||
console.log(`[${tableName}] loadLatestDataInBatches: Found older records, stopping`)
|
||||
hasMore = false
|
||||
} else {
|
||||
hasMore = response.records.length === limit
|
||||
offset += limit
|
||||
}
|
||||
}
|
||||
|
||||
this.lastUpdated = new Date().toISOString()
|
||||
console.log(`[${tableName}] loadLatestDataInBatches: Added ${newRecordsCount} new records, total: ${this.data.length}`)
|
||||
|
||||
// Persist to localStorage
|
||||
if (process.client) {
|
||||
try {
|
||||
console.log(`[${tableName}] loadLatestDataInBatches: Persisting to localStorage with key: ${cacheKey}`)
|
||||
const dataToSave = {
|
||||
data: this.data,
|
||||
lastUpdated: this.lastUpdated,
|
||||
limit: this.limit
|
||||
}
|
||||
console.log(`[${tableName}] loadLatestDataInBatches: Saving ${dataToSave.data.length} records`)
|
||||
localStorage.setItem(cacheKey, JSON.stringify(dataToSave))
|
||||
console.log(`[${tableName}] loadLatestDataInBatches: Successfully saved to localStorage`)
|
||||
|
||||
// Verify it was saved
|
||||
const saved = localStorage.getItem(cacheKey)
|
||||
if (saved) {
|
||||
const parsed = JSON.parse(saved)
|
||||
console.log(`[${tableName}] loadLatestDataInBatches: Verification - localStorage contains ${parsed.data?.length || 0} records`)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`[${tableName}] loadLatestDataInBatches: Failed to persist data to localStorage:`, error)
|
||||
}
|
||||
} else {
|
||||
console.log(`[${tableName}] loadLatestDataInBatches: Not on client, skipping localStorage`)
|
||||
}
|
||||
|
||||
if (onProgress) {
|
||||
onProgress(100)
|
||||
}
|
||||
} catch (error: any) {
|
||||
this.error = this.extractErrorMessage(error)
|
||||
console.error(`[${tableName}] loadLatestDataInBatches: Error:`, error)
|
||||
throw error
|
||||
} finally {
|
||||
this.loading = false
|
||||
console.log(`[${tableName}] loadLatestDataInBatches: Completed`)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user