18b082def0
Foundation for the Flutter tile-provider pattern.
Adds CachedAlbumDao / CachedArtistDao / CachedTrackDao observeById(id)
Flow methods (query-only change; no schema migration).
MetadataProvider exposes observeAlbum(id) / observeArtist(id) /
observeTrack(id) as Flow<X?> that:
- emits the Room row immediately if present,
- fires a single background fetch when the cache emits null,
- re-emits the populated row once the fetch upserts.
Fetch dedup is per-ID via ConcurrentHashMap<String, Job> — five
tiles asking for the same missing album = one network call. Fetch
failures are swallowed (row stays null, tile keeps skeleton);
FreshnessSweeper (next slice) retries.
Also exposes refreshAlbum/Artist/Track(id) for the upcoming sweeper
to force-refresh stale-but-cached rows; same dedup applies.
Next slices:
2/3 - FreshnessSweeper periodic walk + EventsStream reconnect hook.
3/3 - Wire MetadataProvider into Home / Library / Search tiles
and remove the band-aid Home hydration from commit 040217ca.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>