chatgpt-web/src/lib/ImageStore.svelte

71 lines
2.3 KiB
Svelte

<script context="module" lang="ts">
import Dexie, { type Table } from 'dexie'
import type { ChatImage } from './Types.svelte'
import { v4 as uuidv4 } from 'uuid'
let _hasIndexedDb = !!window.indexedDB
const dbCheck = _hasIndexedDb && window.indexedDB.open('test')
if (_hasIndexedDb) dbCheck.onerror = () => { _hasIndexedDb = false }
const imageCache: Record<string, ChatImage> = {}
class ChatImageStore extends Dexie {
images!: Table<ChatImage>
constructor () {
super('chatImageStore')
this.version(1).stores({
images: 'id' // Primary key and indexed props
})
}
}
const imageDb = new ChatImageStore()
export const hasIndexedDb = () => _hasIndexedDb
export const getImage = async (uuid:string): Promise<ChatImage> => {
let image = imageCache[uuid]
if (image || !_hasIndexedDb) return image
image = await imageDb.images.get(uuid) as any
imageCache[uuid] = image
return image
}
export const deleteImage = async (chatId:number, uuid:string): Promise<void> => {
const cached = imageCache[uuid]
if (cached) cached.chats = cached.chats?.filter(c => c !== chatId)
if (!cached?.chats?.length) delete imageCache[uuid]
if (_hasIndexedDb) {
const stored:ChatImage = await imageDb.images.get({ id: uuid }) as any
if (stored) stored.chats = stored.chats?.filter(c => c !== chatId)
if (!stored?.chats?.length) {
imageDb.images.delete(uuid)
} else if (stored) {
await setImage(chatId, stored)
}
}
}
export const setImage = async (chatId:number, image:ChatImage): Promise<ChatImage> => {
image.id = image.id || uuidv4()
let current: ChatImage
if (_hasIndexedDb) {
current = await imageDb.images.get({ id: image.id }) as any
} else {
current = imageCache[image.id]
}
current = current || image
current.chats = current.chats || []
if (!(chatId in current.chats)) current.chats.push(chatId)
imageCache[current.id] = current
if (_hasIndexedDb) {
imageDb.images.put(current, current.id)
}
const clone = JSON.parse(JSON.stringify(current))
// Return a copy without the payload so local storage doesn't get clobbered
delete clone.b64image
delete clone.chats
return clone
}
</script>