import type { SpotifyTrack } from '../types'; import { resolveSpotifyAssetsDeep } from './assets'; export type CategoryDataMap = Record; export type PlaylistTracksMap = Record; // ─── 离线 iTunes 数据类型 ───────────────────────────────────────────────────── export interface ArtistTrackEntry extends SpotifyTrack { album?: string; } export type ArtistTracksMap = Record; // key: lowercase artist name export interface SearchResultEntry { songs: SpotifyTrack[]; artists: { artistId: string; artistName: string; artworkUrl100: string }[]; albums: { collectionId: string; collectionName: string; artistName: string; artworkUrl100: string }[]; } export type SearchResultsMap = Record; // key: lowercase search term export interface AlbumCacheEntry { playlist: { id: string; title: string; subtitle: string; cover: string; type: string }; tracks: SpotifyTrack[]; albumInfo: { title: string; trackCount: number; year: string }; } export type AlbumTracksMap = Record; // key: iTunes collectionId string let categoryCache: CategoryDataMap | null = null; let categoryInflight: Promise | null = null; let playlistTracksCache: PlaylistTracksMap | null = null; let playlistTracksInflight: Promise | null = null; export async function loadCategories(): Promise { if (categoryCache) return categoryCache; if (categoryInflight) return categoryInflight; categoryInflight = (async () => { const url = new URL('./categories.json', import.meta.url).href; const res = await fetch(url); if (!res.ok) throw new Error(`[Spotify] 加载 categories.json 失败:${res.status} ${res.statusText}`); const json = resolveSpotifyAssetsDeep((await res.json()) as CategoryDataMap); categoryCache = json; return json; })().catch(err => { categoryInflight = null; throw err; }); return categoryInflight; } export function getCategoriesSync(): CategoryDataMap | null { return categoryCache; } export async function loadPlaylistTracks(): Promise { if (playlistTracksCache) return playlistTracksCache; if (playlistTracksInflight) return playlistTracksInflight; playlistTracksInflight = (async () => { const url = new URL('./playlistTracks.json', import.meta.url).href; const res = await fetch(url); if (!res.ok) throw new Error(`[Spotify] 加载 playlistTracks.json 失败:${res.status} ${res.statusText}`); const json = resolveSpotifyAssetsDeep((await res.json()) as PlaylistTracksMap); playlistTracksCache = json; return json; })().catch(err => { playlistTracksInflight = null; throw err; }); return playlistTracksInflight; } export function getPlaylistTracksSync(): PlaylistTracksMap | null { return playlistTracksCache; } export function clearCache() { categoryCache = null; categoryInflight = null; playlistTracksCache = null; playlistTracksInflight = null; artistTracksCache = null; artistTracksInflight = null; searchResultsCache = null; searchResultsInflight = null; albumTracksCache = null; albumTracksInflight = null; } // ─── 离线 iTunes 数据加载 ───────────────────────────────────────────────────── let artistTracksCache: ArtistTracksMap | null = null; let artistTracksInflight: Promise | null = null; export async function loadArtistTracks(): Promise { if (artistTracksCache) return artistTracksCache; if (artistTracksInflight) return artistTracksInflight; artistTracksInflight = (async () => { const url = new URL('./artistTracks.json', import.meta.url).href; const res = await fetch(url); if (!res.ok) throw new Error(`[Spotify] 加载 artistTracks.json 失败:${res.status}`); artistTracksCache = resolveSpotifyAssetsDeep(await res.json() as ArtistTracksMap); return artistTracksCache; })().catch(err => { artistTracksInflight = null; throw err; }); return artistTracksInflight; } let searchResultsCache: SearchResultsMap | null = null; let searchResultsInflight: Promise | null = null; export async function loadSearchResults(): Promise { if (searchResultsCache) return searchResultsCache; if (searchResultsInflight) return searchResultsInflight; searchResultsInflight = (async () => { const url = new URL('./searchResults.json', import.meta.url).href; const res = await fetch(url); if (!res.ok) throw new Error(`[Spotify] 加载 searchResults.json 失败:${res.status}`); searchResultsCache = resolveSpotifyAssetsDeep(await res.json() as SearchResultsMap); return searchResultsCache; })().catch(err => { searchResultsInflight = null; throw err; }); return searchResultsInflight; } let albumTracksCache: AlbumTracksMap | null = null; let albumTracksInflight: Promise | null = null; export async function loadAlbumTracks(): Promise { if (albumTracksCache) return albumTracksCache; if (albumTracksInflight) return albumTracksInflight; albumTracksInflight = (async () => { const url = new URL('./albumTracks.json', import.meta.url).href; const res = await fetch(url); if (!res.ok) throw new Error(`[Spotify] 加载 albumTracks.json 失败:${res.status}`); albumTracksCache = resolveSpotifyAssetsDeep(await res.json() as AlbumTracksMap); return albumTracksCache; })().catch(err => { albumTracksInflight = null; throw err; }); return albumTracksInflight; } export async function preload(): Promise { await Promise.all([loadCategories(), loadPlaylistTracks()]); }