mirror of
https://github.com/johndoe6345789/low-code-react-app-b.git
synced 2026-05-02 09:34:54 +00:00
Generated by Spark: Reduce reliance on spark database. Just use sqlite.
This commit is contained in:
101
src/hooks/use-indexed-db.ts
Normal file
101
src/hooks/use-indexed-db.ts
Normal file
@@ -0,0 +1,101 @@
|
||||
import { useState, useEffect, useCallback } from 'react'
|
||||
import { db, type DBSchema } from '@/lib/db'
|
||||
|
||||
type StoreName = keyof DBSchema
|
||||
|
||||
export function useIndexedDB<T extends StoreName, V = DBSchema[T]['value']>(
|
||||
storeName: T,
|
||||
key?: string,
|
||||
defaultValue?: V
|
||||
): [V | undefined, (value: V) => Promise<void>, () => Promise<void>, boolean] {
|
||||
const [value, setValue] = useState<V | undefined>(defaultValue)
|
||||
const [loading, setLoading] = useState(true)
|
||||
|
||||
useEffect(() => {
|
||||
if (!key) {
|
||||
setLoading(false)
|
||||
return
|
||||
}
|
||||
|
||||
let mounted = true
|
||||
|
||||
db.get(storeName, key)
|
||||
.then((result) => {
|
||||
if (mounted) {
|
||||
setValue((result as V) || defaultValue)
|
||||
setLoading(false)
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error(`Error loading ${storeName}/${key}:`, error)
|
||||
if (mounted) {
|
||||
setValue(defaultValue)
|
||||
setLoading(false)
|
||||
}
|
||||
})
|
||||
|
||||
return () => {
|
||||
mounted = false
|
||||
}
|
||||
}, [storeName, key, defaultValue])
|
||||
|
||||
const updateValue = useCallback(
|
||||
async (newValue: V) => {
|
||||
if (!key) {
|
||||
throw new Error('Cannot update value without a key')
|
||||
}
|
||||
|
||||
setValue(newValue)
|
||||
|
||||
try {
|
||||
await db.put(storeName, newValue as any)
|
||||
} catch (error) {
|
||||
console.error(`Error saving ${storeName}/${key}:`, error)
|
||||
throw error
|
||||
}
|
||||
},
|
||||
[storeName, key]
|
||||
)
|
||||
|
||||
const deleteValue = useCallback(async () => {
|
||||
if (!key) {
|
||||
throw new Error('Cannot delete value without a key')
|
||||
}
|
||||
|
||||
setValue(undefined)
|
||||
|
||||
try {
|
||||
await db.delete(storeName, key)
|
||||
} catch (error) {
|
||||
console.error(`Error deleting ${storeName}/${key}:`, error)
|
||||
throw error
|
||||
}
|
||||
}, [storeName, key])
|
||||
|
||||
return [value, updateValue, deleteValue, loading]
|
||||
}
|
||||
|
||||
export function useIndexedDBCollection<T extends StoreName>(
|
||||
storeName: T
|
||||
): [DBSchema[T]['value'][], () => Promise<void>, boolean] {
|
||||
const [items, setItems] = useState<DBSchema[T]['value'][]>([])
|
||||
const [loading, setLoading] = useState(true)
|
||||
|
||||
const refresh = useCallback(async () => {
|
||||
setLoading(true)
|
||||
try {
|
||||
const result = await db.getAll(storeName)
|
||||
setItems(result)
|
||||
} catch (error) {
|
||||
console.error(`Error loading ${storeName} collection:`, error)
|
||||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
}, [storeName])
|
||||
|
||||
useEffect(() => {
|
||||
refresh()
|
||||
}, [refresh])
|
||||
|
||||
return [items, refresh, loading]
|
||||
}
|
||||
67
src/hooks/use-storage.ts
Normal file
67
src/hooks/use-storage.ts
Normal file
@@ -0,0 +1,67 @@
|
||||
import { useState, useEffect, useCallback } from 'react'
|
||||
import { storage } from '@/lib/storage'
|
||||
|
||||
export function useStorage<T>(
|
||||
key: string,
|
||||
defaultValue: T
|
||||
): [T, (value: T | ((prev: T) => T)) => Promise<void>, () => Promise<void>] {
|
||||
const [value, setValue] = useState<T>(defaultValue)
|
||||
const [isInitialized, setIsInitialized] = useState(false)
|
||||
|
||||
useEffect(() => {
|
||||
let mounted = true
|
||||
|
||||
storage
|
||||
.get<T>(key)
|
||||
.then((storedValue) => {
|
||||
if (mounted) {
|
||||
if (storedValue !== undefined) {
|
||||
setValue(storedValue)
|
||||
}
|
||||
setIsInitialized(true)
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error(`Error loading ${key}:`, error)
|
||||
if (mounted) {
|
||||
setIsInitialized(true)
|
||||
}
|
||||
})
|
||||
|
||||
return () => {
|
||||
mounted = false
|
||||
}
|
||||
}, [key])
|
||||
|
||||
const updateValue = useCallback(
|
||||
async (newValueOrUpdater: T | ((prev: T) => T)) => {
|
||||
const newValue =
|
||||
typeof newValueOrUpdater === 'function'
|
||||
? (newValueOrUpdater as (prev: T) => T)(value)
|
||||
: newValueOrUpdater
|
||||
|
||||
setValue(newValue)
|
||||
|
||||
try {
|
||||
await storage.set(key, newValue)
|
||||
} catch (error) {
|
||||
console.error(`Error saving ${key}:`, error)
|
||||
throw error
|
||||
}
|
||||
},
|
||||
[key, value]
|
||||
)
|
||||
|
||||
const deleteValue = useCallback(async () => {
|
||||
setValue(defaultValue)
|
||||
|
||||
try {
|
||||
await storage.delete(key)
|
||||
} catch (error) {
|
||||
console.error(`Error deleting ${key}:`, error)
|
||||
throw error
|
||||
}
|
||||
}, [key, defaultValue])
|
||||
|
||||
return [isInitialized ? value : defaultValue, updateValue, deleteValue]
|
||||
}
|
||||
Reference in New Issue
Block a user