import Domain import Foundation public enum AlbumSort: String, CaseIterable, Sendable { case recentlyAdded, title, artist, year } public enum SearchHit: Identifiable, Hashable, Codable, Sendable { case artist(Artist) case album(Album) case track(Track) case playlist(Playlist) public var id: EntityID { switch self { case let .artist(artist): artist.id case let .album(album): album.id case let .track(track): track.id case let .playlist(playlist): playlist.id } } } public struct SearchResults: Sendable { public var top: [SearchHit] = [] public var artists: [Artist] = [] public var albums: [Album] = [] public var tracks: [Track] = [] public var playlists: [Playlist] = [] public init() {} public var isEmpty: Bool { artists.isEmpty && albums.isEmpty && tracks.isEmpty && playlists.isEmpty } } public protocol Library: Sendable { func apply(_ changes: [Change]) async func cursor(for source: SourceID) async -> Cursor? func setCursor(_ cursor: Cursor, for source: SourceID) async func updates() async -> AsyncStream func artists() async -> [Artist] func artist(_ id: EntityID) async -> Artist? func albums(sortedBy sort: AlbumSort) async -> [Album] func albums(byArtist id: EntityID) async -> [Album] func albums(inGenre genre: String) async -> [Album] func album(_ id: EntityID) async -> Album? func tracks() async -> [Track] func tracks(inAlbum id: EntityID) async -> [Track] func tracks(byArtist id: EntityID) async -> [Track] func tracks(inGenre genre: String) async -> [Track] func tracks(inPlaylist id: EntityID) async -> [Track] func playlists() async -> [Playlist] func stations() async -> [RadioStation] func genres() async -> [Genre] func recentlyPlayed(limit: Int) async -> [Album] func mostPlayed(limit: Int) async -> [Album] func favoriteTracks() async -> [Track] func favorites() async -> Set func setFavorite(_ isFavorite: Bool, for id: EntityID) async func recordPlay(of track: Track, at date: Date) async func search(_ query: String) async -> SearchResults }