import { defineStore } from 'pinia' import { ref, computed } from 'vue' import { useApi } from '../composables/useApi.js' export const useSourcesStore = defineStore('sources', () => { const api = useApi() // keyed cache: null => all sources, number => artist_id filtered const byArtist = ref(new Map()) const loading = ref(false) const error = ref(null) const allSources = computed(() => byArtist.value.get(null) ?? []) async function loadAll() { loading.value = true error.value = null try { const body = await api.get('/api/sources') byArtist.value.set(null, body) } catch (e) { error.value = e } finally { loading.value = false } } async function loadForArtist(artistId) { loading.value = true error.value = null try { const body = await api.get('/api/sources', { params: { artist_id: artistId } }) byArtist.value.set(artistId, body) } catch (e) { error.value = e } finally { loading.value = false } } function _invalidate(artistId) { byArtist.value.delete(null) if (artistId != null) byArtist.value.delete(artistId) } async function create(payload) { const body = await api.post('/api/sources', { body: payload }) _invalidate(payload.artist_id) return body } async function update(id, patch, artistIdHint = null) { const body = await api.patch(`/api/sources/${id}`, { body: patch }) _invalidate(artistIdHint ?? body.artist_id) return body } async function remove(id, artistIdHint = null) { await api.delete(`/api/sources/${id}`) _invalidate(artistIdHint) } async function findOrCreateArtist(name) { const body = await api.post('/api/artists', { body: { name } }) return { artist: { id: body.id, name: body.name, slug: body.slug }, created: body.created } } async function autocompleteArtist(query, limit = 20) { if (!query || !query.trim()) return [] return await api.get('/api/artists/autocomplete', { params: { q: query, limit } }) } // FC-3c: trigger a download for one source. Returns {download_event_id,status}. const checkingIds = ref(new Set()) async function checkNow(id) { checkingIds.value = new Set(checkingIds.value).add(id) try { return await api.post(`/api/sources/${id}/check`) } finally { const next = new Set(checkingIds.value) next.delete(id) checkingIds.value = next } } function sourcesByArtistGrouped() { // returns [{artist: {id,name,slug}, sources: [...]}, ...] const arr = byArtist.value.get(null) ?? [] const groups = new Map() for (const s of arr) { const key = s.artist_id if (!groups.has(key)) { groups.set(key, { artist: { id: s.artist_id, name: s.artist_name, slug: s.artist_slug }, sources: [], }) } groups.get(key).sources.push(s) } return Array.from(groups.values()).sort( (a, b) => a.artist.name.localeCompare(b.artist.name) ) } return { byArtist, loading, error, allSources, checkingIds, loadAll, loadForArtist, create, update, remove, checkNow, findOrCreateArtist, autocompleteArtist, sourcesByArtistGrouped, } })