import { defineStore } from 'pinia' import { ref } from 'vue' const cloneJson = (value: T): T => JSON.parse(JSON.stringify(value)) as T export const useKvStore = defineStore('kv', () => { const entries = ref>({}) const ready = ref(false) const loading = ref | null>(null) const ensureReady = async () => { if (ready.value) return if (loading.value) { await loading.value return } loading.value = (async () => { ready.value = true })() await loading.value loading.value = null } const getItem = async (keyRaw: string | number): Promise => { await ensureReady() const key = String(keyRaw || '').trim() if (!key) return null if (!Object.prototype.hasOwnProperty.call(entries.value, key)) return null return cloneJson(entries.value[key] as T) } const setItem = async (keyRaw: string | number, value: T): Promise => { await ensureReady() const key = String(keyRaw || '').trim() if (!key) return entries.value[key] = cloneJson(value) } const removeItem = async (keyRaw: string | number): Promise => { await ensureReady() const key = String(keyRaw || '').trim() if (!key) return delete entries.value[key] } const keys = async (): Promise => { await ensureReady() return Object.keys(entries.value) } const clear = async (): Promise => { await ensureReady() entries.value = {} } const exportEntries = async () => { await ensureReady() return Object.entries(entries.value).map(([key, value]) => ({ key, value: cloneJson(value) })) } const importEntries = async ( incoming: Array<{ key: string; value: unknown }>, options?: { replace?: boolean } ) => { await ensureReady() if (options?.replace !== false) { entries.value = {} } for (const item of incoming || []) { const key = String(item?.key || '').trim() if (!key) continue entries.value[key] = cloneJson(item.value) } } return { entries, ready, ensureReady, getItem, setItem, removeItem, keys, clear, exportEntries, importEntries } }, { persist: true })