Moves the download pipeline into the crate and removes its Tauri coupling:
- event: new CacheEvent enum (Started/Progress/Completed/Processed/Failed/
UnlockStart/UnlockEnd) + CacheFormat + the CacheEventSink callback type.
- downloader: StreamFetcher + try_cmaf_offline_download + spawn_track_cache_download
now report through a &CacheEventSink instead of tauri AppHandle::emit. The
CoreBridge param is gone — both the CMAF raw download, metadata fetch, and the
legacy stream-url fallback unify on a single core qbz_qobuz::QobuzClient handle.
TLS uses the workspace rustls (same backend qbz-qobuz uses for all CDN traffic).
- playback: adds load_cmaf_bundle_with_ui_events that emits UnlockStart/UnlockEnd
through the sink (the pure load_cmaf_bundle is unchanged).
Crate compiles headless; 5 unit tests pass. Remaining for Slice 0:
OfflineCacheState + purge, then re-wire the Tauri commands with an
app.emit-backed sink and delete the old src-tauri module.
cc