import { ref, Ref } from 'vue' import type { PeerPigeonMeshInstance as PeerPigeonMesh } from 'peerpigeon' import type { StorageEntry } from '../types' export interface UsePeerStorageReturn { entries: Ref> loading: Ref error: Ref set: (mesh: PeerPigeonMesh, key: string, value: any, ttl?: number) => Promise get: (mesh: PeerPigeonMesh, key: string) => Promise has: (mesh: PeerPigeonMesh, key: string) => Promise delete: (mesh: PeerPigeonMesh, key: string) => Promise clear: (mesh: PeerPigeonMesh) => Promise list: (mesh: PeerPigeonMesh) => Promise refreshEntries: (mesh: PeerPigeonMesh) => Promise } export function usePeerStorage(): UsePeerStorageReturn { const entries = ref>(new Map()) const loading = ref(false) const error = ref(null) const set = async (mesh: PeerPigeonMesh, key: string, value: any, ttl?: number): Promise => { try { error.value = null loading.value = true if (!mesh.storage) { throw new Error('Storage not available on mesh') } await mesh.storage.set(key, value, ttl) // Update local entries entries.value.set(key, { key, value, timestamp: Date.now(), ttl }) // Trigger reactivity entries.value = new Map(entries.value) } catch (err) { error.value = err instanceof Error ? err : new Error(String(err)) throw err } finally { loading.value = false } } const get = async (mesh: PeerPigeonMesh, key: string): Promise => { try { error.value = null loading.value = true if (!mesh.storage) { throw new Error('Storage not available on mesh') } const value = await mesh.storage.get(key) if (value !== null && value !== undefined) { entries.value.set(key, { key, value, timestamp: Date.now() }) // Trigger reactivity entries.value = new Map(entries.value) } return value } catch (err) { error.value = err instanceof Error ? err : new Error(String(err)) throw err } finally { loading.value = false } } const has = async (mesh: PeerPigeonMesh, key: string): Promise => { try { error.value = null loading.value = true if (!mesh.storage) { throw new Error('Storage not available on mesh') } return await mesh.storage.has(key) } catch (err) { error.value = err instanceof Error ? err : new Error(String(err)) throw err } finally { loading.value = false } } const deleteKey = async (mesh: PeerPigeonMesh, key: string): Promise => { try { error.value = null loading.value = true if (!mesh.storage) { throw new Error('Storage not available on mesh') } await mesh.storage.delete(key) entries.value.delete(key) // Trigger reactivity entries.value = new Map(entries.value) } catch (err) { error.value = err instanceof Error ? err : new Error(String(err)) throw err } finally { loading.value = false } } const clear = async (mesh: PeerPigeonMesh): Promise => { try { error.value = null loading.value = true if (!mesh.storage) { throw new Error('Storage not available on mesh') } await mesh.storage.clear() entries.value.clear() // Trigger reactivity entries.value = new Map(entries.value) } catch (err) { error.value = err instanceof Error ? err : new Error(String(err)) throw err } finally { loading.value = false } } const list = async (mesh: PeerPigeonMesh): Promise => { try { error.value = null loading.value = true if (!mesh.storage) { throw new Error('Storage not available on mesh') } const keys = await mesh.storage.keys() return Array.isArray(keys) ? keys : [] } catch (err) { error.value = err instanceof Error ? err : new Error(String(err)) throw err } finally { loading.value = false } } const refreshEntries = async (mesh: PeerPigeonMesh): Promise => { try { error.value = null loading.value = true if (!mesh.storage) { throw new Error('Storage not available on mesh') } const keys = await mesh.storage.keys() const newEntries = new Map() for (const key of keys) { const value = await mesh.storage.get(key) newEntries.set(key, { key, value, timestamp: Date.now() }) } entries.value = newEntries } catch (err) { error.value = err instanceof Error ? err : new Error(String(err)) throw err } finally { loading.value = false } } return { entries, loading, error, set, get, has, delete: deleteKey, clear, list, refreshEntries } }