diff --git a/src/app/MainApp.tsx b/src/app/MainApp.tsx index cfc782bf..66c23a31 100644 --- a/src/app/MainApp.tsx +++ b/src/app/MainApp.tsx @@ -22,7 +22,7 @@ import { runLegacyOfflineFileMigration } from '@/features/offline'; import { reconcileLibraryTierForServer } from '@/features/offline'; import { initMiniPlayerBridgeOnMain } from '@/features/miniPlayer'; import { runAdvancedModeMigration } from '../utils/migrations/advancedModeMigration'; -import { bootstrapAllIndexedServers } from '../utils/library/librarySession'; +import { bootstrapAllIndexedServers } from '@/lib/library/librarySession'; import { hydrateQueueFromIndex } from '@/features/playback/store/queueRestore'; import { useLibraryAnalysisBackfill } from '../hooks/useLibraryAnalysisBackfill'; import { useCoverArtPrefetch } from '../cover/useCoverArtPrefetch'; diff --git a/src/components/GenreFilterBar.tsx b/src/components/GenreFilterBar.tsx index dbf567c9..a21f0920 100644 --- a/src/components/GenreFilterBar.tsx +++ b/src/components/GenreFilterBar.tsx @@ -1,5 +1,5 @@ import { getGenres } from '@/lib/api/subsonicGenres'; -import type { GenreFilterOption } from '../utils/library/albumBrowseLoad'; +import type { GenreFilterOption } from '@/lib/library/albumBrowseLoad'; import React, { useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react'; import { createPortal } from 'react-dom'; import { Check, Filter, X } from 'lucide-react'; diff --git a/src/components/SongInfoModal.tsx b/src/components/SongInfoModal.tsx index 2ab44a1e..968db189 100644 --- a/src/components/SongInfoModal.tsx +++ b/src/components/SongInfoModal.tsx @@ -14,13 +14,13 @@ import { copyTextToClipboard } from '../utils/server/serverMagicString'; import { showToast } from '../utils/ui/toast'; import { formatTrackTime } from '@/lib/format/formatDuration'; import { formatLastSeen } from '../utils/componentHelpers/userMgmtHelpers'; -import { libraryIsReady } from '../utils/library/libraryReady'; +import { libraryIsReady } from '@/lib/library/libraryReady'; import { formatQueueMoodLabels, parseTrackEnrichmentFacts, resolveQueueBpm, type ParsedTrackEnrichment, -} from '../utils/library/trackEnrichment'; +} from '@/lib/library/trackEnrichment'; import i18n from '@/lib/i18n'; function formatSize(bytes?: number): string | null { diff --git a/src/components/YearFilterButton.tsx b/src/components/YearFilterButton.tsx index 1c05b1d6..0ac11a36 100644 --- a/src/components/YearFilterButton.tsx +++ b/src/components/YearFilterButton.tsx @@ -12,7 +12,7 @@ import { normalizeAlbumYearToFieldChange, resolveAlbumYearBounds, stepAlbumYearField, -} from '../utils/library/albumYearFilter'; +} from '@/lib/library/albumYearFilter'; interface Props { from: string; diff --git a/src/cover/prefetchStrategy.ts b/src/cover/prefetchStrategy.ts index 28a85351..1cca617a 100644 --- a/src/cover/prefetchStrategy.ts +++ b/src/cover/prefetchStrategy.ts @@ -1,8 +1,8 @@ -import type { CoverCacheStrategy } from '../utils/library/coverStrategy'; +import type { CoverCacheStrategy } from '@/lib/library/coverStrategy'; import { coverStrategyAllowsLibraryBackfill, coverStrategyAllowsRoutePrefetch, -} from '../utils/library/coverStrategy'; +} from '@/lib/library/coverStrategy'; /** @deprecated Use `coverStrategyAllowsRoutePrefetch` */ export function coverPrefetchStrategyAllowsRoutePrefetch( diff --git a/src/cover/useCoverArtPrefetch.ts b/src/cover/useCoverArtPrefetch.ts index 6fef1ac5..1a697c25 100644 --- a/src/cover/useCoverArtPrefetch.ts +++ b/src/cover/useCoverArtPrefetch.ts @@ -1,6 +1,6 @@ import { useEffect } from 'react'; import { coverCacheStats } from '../api/coverCache'; -import { coverStrategyAllowsRoutePrefetch } from '../utils/library/coverStrategy'; +import { coverStrategyAllowsRoutePrefetch } from '@/lib/library/coverStrategy'; import { useCoverStrategyStore } from '../store/coverStrategyStore'; import { useAuthStore } from '../store/authStore'; import { coverPrefetchDrainBatch } from './prefetchRegistry'; diff --git a/src/features/album/components/AlbumHeader.tsx b/src/features/album/components/AlbumHeader.tsx index 23221d91..7d4a4c40 100644 --- a/src/features/album/components/AlbumHeader.tsx +++ b/src/features/album/components/AlbumHeader.tsx @@ -20,8 +20,8 @@ import { sanitizeHtml } from '@/lib/util/sanitizeHtml'; import { OpenArtistRefInline } from '@/features/artist'; import { tooltipAttrs } from '@/ui/tooltipAttrs'; import { offlineActionPolicy, type OfflineActionPolicy } from '@/features/offline'; -import { deriveAlbumGenreTags } from '@/utils/library/genreTags'; -import { genreColor } from '@/utils/library/genreColor'; +import { deriveAlbumGenreTags } from '@/lib/library/genreTags'; +import { genreColor } from '@/lib/library/genreColor'; /** True when the album artist label means "no single artist" — `getArtistInfo` * has nothing meaningful to return for these, so the Artist Bio entry is hidden. diff --git a/src/features/album/components/LosslessAlbumsRail.tsx b/src/features/album/components/LosslessAlbumsRail.tsx index 5d9813b1..ac96b594 100644 --- a/src/features/album/components/LosslessAlbumsRail.tsx +++ b/src/features/album/components/LosslessAlbumsRail.tsx @@ -5,8 +5,8 @@ import { ndListLosslessAlbumsPage } from '@/lib/api/navidromeBrowse'; import AlbumRow from '@/features/album/components/AlbumRow'; import { useAuthStore } from '@/store/authStore'; import { useLibraryIndexStore } from '@/store/libraryIndexStore'; -import { runLocalLosslessAlbums } from '@/utils/library/browseTextSearch'; -import { LOSSLESS_MODE_QUERY } from '@/utils/library/losslessMode'; +import { runLocalLosslessAlbums } from '@/lib/library/browseTextSearch'; +import { LOSSLESS_MODE_QUERY } from '@/lib/library/losslessMode'; interface Props { disableArtwork?: boolean; diff --git a/src/features/album/hooks/useAlbumBrowseData.ts b/src/features/album/hooks/useAlbumBrowseData.ts index 1b137b54..db5ece3b 100644 --- a/src/features/album/hooks/useAlbumBrowseData.ts +++ b/src/features/album/hooks/useAlbumBrowseData.ts @@ -13,8 +13,8 @@ import { } from '@/cover/coverTraffic'; import { coverEnsureQueueBacklog, coverEnsureResumePump, coverEnsureSubscribeBacklogDrain } from '@/cover/ensureQueue'; import { dedupeById } from '@/lib/util/dedupeById'; -import { albumBrowseCompScanComplete, albumBrowseCompFilterClientOnly } from '@/utils/library/albumCompilation'; -import type { AlbumCompFilter } from '@/utils/library/albumCompilation'; +import { albumBrowseCompScanComplete, albumBrowseCompFilterClientOnly } from '@/lib/library/albumCompilation'; +import type { AlbumCompFilter } from '@/lib/library/albumCompilation'; import { albumBrowseHasGenreFilter, albumBrowseHasServerFilters, @@ -24,12 +24,12 @@ import { fetchLocalAlbumCatalogChunk, type AlbumBrowseQuery, type GenreFilterOption, -} from '@/utils/library/albumBrowseLoad'; +} from '@/lib/library/albumBrowseLoad'; import { libraryScopeForServer } from '@/lib/api/subsonicClient'; import { ALBUM_YEAR_FILTER_DEBOUNCE_MS, resolveAlbumYearBounds, -} from '@/utils/library/albumYearFilter'; +} from '@/lib/library/albumYearFilter'; import { loadOfflineAlbumBrowseInitial } from '@/features/offline'; import { useOfflineBrowseReloadToken } from '@/features/offline'; import { diff --git a/src/features/album/hooks/useAlbumBrowseFilters.ts b/src/features/album/hooks/useAlbumBrowseFilters.ts index 3afb84d8..b799bd39 100644 --- a/src/features/album/hooks/useAlbumBrowseFilters.ts +++ b/src/features/album/hooks/useAlbumBrowseFilters.ts @@ -14,7 +14,7 @@ import { isAlbumDetailPath, useAlbumBrowseSessionStore, } from '@/features/album/store/albumBrowseSessionStore'; -import type { AlbumBrowseSort } from '@/utils/library/browseTextSearch'; +import type { AlbumBrowseSort } from '@/lib/library/browseTextSearch'; import { shouldRestoreAlbumBrowseSession } from '@/utils/navigation/albumDetailNavigation'; import { useLiveSearchScopeStore } from '@/store/liveSearchScopeStore'; diff --git a/src/features/album/hooks/useAlbumCatalogYearBounds.ts b/src/features/album/hooks/useAlbumCatalogYearBounds.ts index 7a80abb6..9f7148f9 100644 --- a/src/features/album/hooks/useAlbumCatalogYearBounds.ts +++ b/src/features/album/hooks/useAlbumCatalogYearBounds.ts @@ -3,8 +3,8 @@ import { ALBUM_YEAR_MAX, ALBUM_YEAR_MIN, type AlbumCatalogYearRange, -} from '@/utils/library/albumYearFilter'; -import { fetchAlbumCatalogYearBounds } from '@/utils/library/albumCatalogYearBounds'; +} from '@/lib/library/albumYearFilter'; +import { fetchAlbumCatalogYearBounds } from '@/lib/library/albumCatalogYearBounds'; const DEFAULT: AlbumCatalogYearRange = { min: ALBUM_YEAR_MIN, max: ALBUM_YEAR_MAX }; diff --git a/src/features/album/hooks/useAlbumDetailData.ts b/src/features/album/hooks/useAlbumDetailData.ts index 9398ac04..f2b24829 100644 --- a/src/features/album/hooks/useAlbumDetailData.ts +++ b/src/features/album/hooks/useAlbumDetailData.ts @@ -17,7 +17,7 @@ import { offlineLocalBrowseEnabled, } from '@/features/offline'; import { readDetailServerId } from '@/utils/navigation/detailServerScope'; -import { libraryIsReady } from '@/utils/library/libraryReady'; +import { libraryIsReady } from '@/lib/library/libraryReady'; import { shouldAttemptSubsonicForActiveServer, shouldAttemptSubsonicForServer, diff --git a/src/features/album/hooks/useBrowseAlbumTextSearch.ts b/src/features/album/hooks/useBrowseAlbumTextSearch.ts index 98e8d6b7..d8c20e4c 100644 --- a/src/features/album/hooks/useBrowseAlbumTextSearch.ts +++ b/src/features/album/hooks/useBrowseAlbumTextSearch.ts @@ -7,7 +7,7 @@ import { raceBrowseWithLocalFallback, runLocalBrowseAlbums, runNetworkBrowseAlbums, -} from '@/utils/library/browseTextSearch'; +} from '@/lib/library/browseTextSearch'; import { useOfflineBrowseContext } from '@/features/offline'; import { offlineLocalBrowseEnabled, searchOfflineLocalAlbums } from '@/features/offline'; diff --git a/src/features/album/hooks/useGenreAlbumBrowse.ts b/src/features/album/hooks/useGenreAlbumBrowse.ts index 8f6bbe7c..3c0b945e 100644 --- a/src/features/album/hooks/useGenreAlbumBrowse.ts +++ b/src/features/album/hooks/useGenreAlbumBrowse.ts @@ -1,12 +1,12 @@ import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import type { SubsonicAlbum } from '@/lib/api/subsonicTypes'; import { dedupeById } from '@/lib/util/dedupeById'; -import type { AlbumBrowseSort } from '@/utils/library/albumBrowseSort'; +import type { AlbumBrowseSort } from '@/lib/library/albumBrowseSort'; import { fetchGenreAlbumPage, GENRE_ALBUM_CATALOG_CHUNK, GENRE_ALBUM_FIRST_PAGE, -} from '@/utils/library/genreAlbumBrowse'; +} from '@/lib/library/genreAlbumBrowse'; import { useClientSliceInfiniteScroll } from '@/hooks/useClientSliceInfiniteScroll'; import { useInpageScrollSentinel } from '@/hooks/useInpageScrollSentinel'; diff --git a/src/features/album/index.ts b/src/features/album/index.ts index 86f6153c..89f641af 100644 --- a/src/features/album/index.ts +++ b/src/features/album/index.ts @@ -5,7 +5,7 @@ * the album session store, per-album offline status, and album export helpers. * * Stays OUT (library-core / cross-cutting, consumed by this feature, not owned): - * the `utils/library/album*` browse query engine (shared with offline + other + * the `lib/library/album*` browse query engine (shared with offline + other * browse surfaces → M4), `albumDetailNavigation` (cross-cutting nav → M4), * `playAlbum` (playback action → playback), `starredAlbumIndexSync` (index * sync, core), the album context-menu items (context-menu subsystem), the diff --git a/src/features/album/pages/AlbumDetail.tsx b/src/features/album/pages/AlbumDetail.tsx index 4c73a115..37f55d2c 100644 --- a/src/features/album/pages/AlbumDetail.tsx +++ b/src/features/album/pages/AlbumDetail.tsx @@ -43,8 +43,8 @@ import { usePerfProbeFlags } from '@/utils/perf/perfFlags'; import { albumGridWarmCovers } from '@/cover/layoutSizes'; import { VirtualCardGrid } from '@/components/VirtualCardGrid'; import LosslessModeBanner from '@/components/LosslessModeBanner'; -import { isLosslessSuffix } from '@/utils/library/losslessFormats'; -import { isLosslessMode } from '@/utils/library/losslessMode'; +import { isLosslessSuffix } from '@/lib/library/losslessFormats'; +import { isLosslessMode } from '@/lib/library/losslessMode'; import { readDetailServerId } from '@/utils/navigation/detailServerScope'; import { useOfflineBrowseContext } from '@/features/offline'; import { offlineActionPolicy } from '@/features/offline'; diff --git a/src/features/album/pages/Albums.tsx b/src/features/album/pages/Albums.tsx index eb59a887..2e648d97 100644 --- a/src/features/album/pages/Albums.tsx +++ b/src/features/album/pages/Albums.tsx @@ -43,15 +43,15 @@ import { peekAlbumBrowseScrollRestore } from '@/features/album/store/albumBrowse import { readAlbumBrowseRestore } from '@/utils/navigation/albumDetailNavigation'; import { albumArtistDisplayName } from '@/features/album/utils/deriveAlbumHeaderArtistRefs'; import { useAlbumCatalogYearBounds } from '@/features/album/hooks/useAlbumCatalogYearBounds'; -import type { AlbumBrowseSort } from '@/utils/library/albumBrowseSort'; -import { LOSSLESS_MODE_QUERY } from '@/utils/library/losslessMode'; -import { resolveAlbumYearBounds } from '@/utils/library/albumYearFilter'; +import type { AlbumBrowseSort } from '@/lib/library/albumBrowseSort'; +import { LOSSLESS_MODE_QUERY } from '@/lib/library/losslessMode'; +import { resolveAlbumYearBounds } from '@/lib/library/albumYearFilter'; import { filterAlbumsByCompilation, filterAlbumsByGenres, filterAlbumsByStarred, filterAlbumsByYearBounds, -} from '@/utils/library/albumBrowseFilters'; +} from '@/lib/library/albumBrowseFilters'; import { useScopedBrowseSearchQuery } from '@/store/liveSearchScopeStore'; type SortType = AlbumBrowseSort; diff --git a/src/features/album/pages/LosslessAlbums.tsx b/src/features/album/pages/LosslessAlbums.tsx index 2f4d9e63..ffef7b57 100644 --- a/src/features/album/pages/LosslessAlbums.tsx +++ b/src/features/album/pages/LosslessAlbums.tsx @@ -4,7 +4,7 @@ import type { SubsonicAlbum } from '@/lib/api/subsonicTypes'; import { songToTrack } from '@/features/playback/utils/playback/songToTrack'; import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import AlbumCard from '@/features/album/components/AlbumCard'; -import { LOSSLESS_MODE_QUERY } from '@/utils/library/losslessMode'; +import { LOSSLESS_MODE_QUERY } from '@/lib/library/losslessMode'; import { ndListLosslessAlbumsPage } from '@/lib/api/navidromeBrowse'; import { useTranslation } from 'react-i18next'; import { useAuthStore } from '@/store/authStore'; @@ -38,7 +38,7 @@ import { runLocalAlbumBrowsePage, sortSubsonicAlbums, type AlbumBrowseSort, -} from '@/utils/library/browseTextSearch'; +} from '@/lib/library/browseTextSearch'; /** Local index page size — SQLite is cheap; larger pages than the network walk. */ const LOCAL_PAGE_SIZE = 30; diff --git a/src/features/album/pages/RandomAlbums.tsx b/src/features/album/pages/RandomAlbums.tsx index 98940a3a..8344c488 100644 --- a/src/features/album/pages/RandomAlbums.tsx +++ b/src/features/album/pages/RandomAlbums.tsx @@ -15,7 +15,7 @@ import { useLocation, useNavigate } from 'react-router-dom'; import { useAuthStore } from '@/store/authStore'; import { useLibraryIndexStore } from '@/store/libraryIndexStore'; import { filterAlbumsByMixRatings, getMixMinRatingsConfigFromAuth } from '@/utils/mix/mixRatingFilter'; -import { runLocalRandomAlbums, runLocalAlbumsByGenres } from '@/utils/library/browseTextSearch'; +import { runLocalRandomAlbums, runLocalAlbumsByGenres } from '@/lib/library/browseTextSearch'; import { useOfflineStore } from '@/features/offline'; import { useDownloadModalStore } from '@/features/offline'; import { invoke } from '@tauri-apps/api/core'; diff --git a/src/features/album/store/albumBrowseSessionStore.ts b/src/features/album/store/albumBrowseSessionStore.ts index 4110f31d..9ba6e490 100644 --- a/src/features/album/store/albumBrowseSessionStore.ts +++ b/src/features/album/store/albumBrowseSessionStore.ts @@ -1,6 +1,6 @@ import { create } from 'zustand'; import type { SubsonicAlbum } from '@/lib/api/subsonicTypes'; -import type { AlbumBrowseSort } from '@/utils/library/browseTextSearch'; +import type { AlbumBrowseSort } from '@/lib/library/browseTextSearch'; export const DEFAULT_ALBUM_BROWSE_SORT: AlbumBrowseSort = 'alphabeticalByName'; diff --git a/src/features/album/utils/albumBrowseCatalogChunk.ts b/src/features/album/utils/albumBrowseCatalogChunk.ts index acc1fef6..7b745a2f 100644 --- a/src/features/album/utils/albumBrowseCatalogChunk.ts +++ b/src/features/album/utils/albumBrowseCatalogChunk.ts @@ -2,8 +2,8 @@ import type { SubsonicAlbum } from '@/lib/api/subsonicTypes'; import { dedupeById } from '@/lib/util/dedupeById'; import { isOfflineBrowseActive } from '@/features/offline'; import { loadOfflineAlbumCatalogChunk } from '@/features/offline'; -import type { AlbumBrowseQuery } from '@/utils/library/albumBrowseTypes'; -import { fetchLocalAlbumCatalogChunk } from '@/utils/library/albumBrowseLoad'; +import type { AlbumBrowseQuery } from '@/lib/library/albumBrowseTypes'; +import { fetchLocalAlbumCatalogChunk } from '@/lib/library/albumBrowseLoad'; export type AlbumCatalogChunk = { albums: SubsonicAlbum[]; diff --git a/src/features/artist/hooks/useArtistDetailData.ts b/src/features/artist/hooks/useArtistDetailData.ts index 91b2ceb5..9162023e 100644 --- a/src/features/artist/hooks/useArtistDetailData.ts +++ b/src/features/artist/hooks/useArtistDetailData.ts @@ -11,8 +11,8 @@ import { loadArtistFromLibraryIndex } from '@/features/offline'; import { useOfflineBrowseContext } from '@/features/offline'; import { loadArtistFromLocalPlayback, offlineLocalBrowseEnabled } from '@/features/offline'; import { readDetailServerId } from '@/utils/navigation/detailServerScope'; -import { runLocalArtistLosslessBrowse } from '@/utils/library/browseTextSearch'; -import { isLosslessSuffix } from '@/utils/library/losslessFormats'; +import { runLocalArtistLosslessBrowse } from '@/lib/library/browseTextSearch'; +import { isLosslessSuffix } from '@/lib/library/losslessFormats'; export interface UseArtistDetailDataOptions { /** When true, albums and top tracks are limited to lossless containers (local index preferred). */ diff --git a/src/features/artist/hooks/useArtistsBrowseCatalog.ts b/src/features/artist/hooks/useArtistsBrowseCatalog.ts index c24d1344..1ede8173 100644 --- a/src/features/artist/hooks/useArtistsBrowseCatalog.ts +++ b/src/features/artist/hooks/useArtistsBrowseCatalog.ts @@ -5,7 +5,7 @@ import { dedupeById } from '@/lib/util/dedupeById'; import { fetchLocalArtistCatalogChunk, fetchNetworkStarredArtists, -} from '@/utils/library/browseTextSearch'; +} from '@/lib/library/browseTextSearch'; import { useOfflineBrowseContext } from '@/features/offline'; import { useOfflineBrowseReloadToken } from '@/features/offline'; import { diff --git a/src/features/artist/hooks/useBrowseArtistTextSearch.ts b/src/features/artist/hooks/useBrowseArtistTextSearch.ts index da9e2a50..8f0d5f82 100644 --- a/src/features/artist/hooks/useBrowseArtistTextSearch.ts +++ b/src/features/artist/hooks/useBrowseArtistTextSearch.ts @@ -8,7 +8,7 @@ import { runLocalBrowseArtists, runNetworkBrowseArtists, type LibrarySearchSurface, -} from '@/utils/library/browseTextSearch'; +} from '@/lib/library/browseTextSearch'; import { useOfflineBrowseContext } from '@/features/offline'; import { offlineLocalBrowseEnabled, searchOfflineLocalArtists } from '@/features/offline'; diff --git a/src/features/artist/index.ts b/src/features/artist/index.ts index 4928cd58..5e1b28df 100644 --- a/src/features/artist/index.ts +++ b/src/features/artist/index.ts @@ -3,7 +3,7 @@ * `pages/*` paths, not re-exported), artist cards/rows/avatars, the detail hero + * similar-artists + top-tracks UI, the artist Subsonic API, browse catalog/ * filter/scroll hooks, per-artist offline status, and the open-artist-ref nav - * cluster. `sortArtistAlbums` moved in from `utils/library/` (artist-only sort, + * cluster. `sortArtistAlbums` moved in from `lib/library/` (artist-only sort, * not the shared index query engine). * * Stays OUT (other owners): `deriveAlbumHeaderArtistRefs` (album header), diff --git a/src/features/artist/pages/ArtistDetail.tsx b/src/features/artist/pages/ArtistDetail.tsx index 3baf8a64..1dde0a26 100644 --- a/src/features/artist/pages/ArtistDetail.tsx +++ b/src/features/artist/pages/ArtistDetail.tsx @@ -36,7 +36,7 @@ import { artistDetailCoverWarmAlbums } from '@/features/artist/components/topSon import { useLibraryCoverPrefetch } from '@/cover/useLibraryCoverPrefetch'; import { useWarmGridCovers } from '@/hooks/useWarmGridCovers'; import { VirtualCardGrid } from '@/components/VirtualCardGrid'; -import { LOSSLESS_MODE_QUERY } from '@/utils/library/losslessMode'; +import { LOSSLESS_MODE_QUERY } from '@/lib/library/losslessMode'; import { sortArtistAlbumsByYear } from '@/features/artist/utils/sortArtistAlbums'; import { readDetailServerId } from '@/utils/navigation/detailServerScope'; diff --git a/src/features/nowPlaying/utils/nowPlayingMetadataResolve.ts b/src/features/nowPlaying/utils/nowPlayingMetadataResolve.ts index 69c076a4..bbb6d4bf 100644 --- a/src/features/nowPlaying/utils/nowPlayingMetadataResolve.ts +++ b/src/features/nowPlaying/utils/nowPlayingMetadataResolve.ts @@ -22,8 +22,8 @@ import { getAlbumForServer, getSongForServer } from '@/lib/api/subsonicLibrary'; import type { SubsonicAlbum, SubsonicSong } from '@/lib/api/subsonicTypes'; import { shouldAttemptSubsonicForServer } from '@/utils/network/subsonicNetworkGuard'; import { loadAlbumFromLibraryIndex, loadArtistFromLibraryIndex } from '@/features/offline'; -import { trackToSong } from '@/utils/library/advancedSearchLocal'; -import { libraryIsReady } from '@/utils/library/libraryReady'; +import { trackToSong } from '@/lib/library/advancedSearchLocal'; +import { libraryIsReady } from '@/lib/library/libraryReady'; const TOP_SONGS_LIMIT = 5; diff --git a/src/features/offline/utils/offlineAlbumBrowseCatalog.ts b/src/features/offline/utils/offlineAlbumBrowseCatalog.ts index bb1f53b3..3d7a59be 100644 --- a/src/features/offline/utils/offlineAlbumBrowseCatalog.ts +++ b/src/features/offline/utils/offlineAlbumBrowseCatalog.ts @@ -1,5 +1,5 @@ import type { SubsonicAlbum } from '@/lib/api/subsonicTypes'; -import type { AlbumBrowseQuery } from '@/utils/library/albumBrowseTypes'; +import type { AlbumBrowseQuery } from '@/lib/library/albumBrowseTypes'; import { isOfflineBrowseActive } from '@/features/offline/utils/offlineBrowseMode'; import { fetchOfflineLocalAlbumCatalogChunk, diff --git a/src/features/offline/utils/offlineLibraryHelpers.ts b/src/features/offline/utils/offlineLibraryHelpers.ts index 7f0e4aea..d5d6f17e 100644 --- a/src/features/offline/utils/offlineLibraryHelpers.ts +++ b/src/features/offline/utils/offlineLibraryHelpers.ts @@ -7,7 +7,7 @@ import type { LocalPlaybackEntry, PinnedGroup, PinSource } from '@/store/localPl import { useLocalPlaybackStore } from '@/store/localPlaybackStore'; import { findLocalPlaybackEntry, hasLocalLibraryBytes } from '@/store/localPlaybackResolve'; import { useOfflineStore, type OfflineAlbumMeta } from '@/features/offline/store/offlineStore'; -import { resolveTrackCoverArtId, trackToSong } from '@/utils/library/advancedSearchLocal'; +import { resolveTrackCoverArtId, trackToSong } from '@/lib/library/advancedSearchLocal'; import { canonicalQueueServerKey, resolveIndexKey } from '@/utils/server/serverIndexKey'; import type { Track } from '@/features/playback/store/playerStoreTypes'; import { findServerByIdOrIndexKey, resolveServerIdForIndexKey } from '@/utils/server/serverLookup'; diff --git a/src/features/offline/utils/offlineLibraryIndexLoad.ts b/src/features/offline/utils/offlineLibraryIndexLoad.ts index 7aa1f55c..0a660be8 100644 --- a/src/features/offline/utils/offlineLibraryIndexLoad.ts +++ b/src/features/offline/utils/offlineLibraryIndexLoad.ts @@ -8,7 +8,7 @@ import { albumToAlbum, artistToArtist, trackToSong, -} from '@/utils/library/advancedSearchLocal'; +} from '@/lib/library/advancedSearchLocal'; export async function loadAlbumFromLibraryIndex( serverId: string, diff --git a/src/features/offline/utils/offlineLocalBrowse.ts b/src/features/offline/utils/offlineLocalBrowse.ts index ef810154..9214e269 100644 --- a/src/features/offline/utils/offlineLocalBrowse.ts +++ b/src/features/offline/utils/offlineLocalBrowse.ts @@ -9,17 +9,17 @@ import { artistToArtist, resolveTrackCoverArtId, trackToSong, -} from '@/utils/library/advancedSearchLocal'; -import { albumIsCompilationFromTrackDtos } from '@/utils/library/albumCompilation'; +} from '@/lib/library/advancedSearchLocal'; +import { albumIsCompilationFromTrackDtos } from '@/lib/library/albumCompilation'; import { filterAlbumsByCompilation, filterAlbumsByGenres, filterAlbumsByStarred, filterAlbumsByYearBounds, -} from '@/utils/library/albumBrowseFilters'; -import type { AlbumBrowseQuery } from '@/utils/library/albumBrowseTypes'; -import { sortSubsonicAlbums } from '@/utils/library/albumBrowseSort'; -import { isLosslessSuffix } from '@/utils/library/losslessFormats'; +} from '@/lib/library/albumBrowseFilters'; +import type { AlbumBrowseQuery } from '@/lib/library/albumBrowseTypes'; +import { sortSubsonicAlbums } from '@/lib/library/albumBrowseSort'; +import { isLosslessSuffix } from '@/lib/library/losslessFormats'; import { entryBelongsToServer } from '@/store/localPlaybackResolve'; function sortBrowsableSongs(songs: SubsonicSong[]): SubsonicSong[] { diff --git a/src/features/offline/utils/offlineMediaResolve.test.ts b/src/features/offline/utils/offlineMediaResolve.test.ts index fa3e8487..10841ae8 100644 --- a/src/features/offline/utils/offlineMediaResolve.test.ts +++ b/src/features/offline/utils/offlineMediaResolve.test.ts @@ -62,7 +62,7 @@ vi.mock('@/lib/api/subsonicPlaylists', () => ({ getPlaylistForServerMock(serverId, playlistId), })); -vi.mock('@/utils/library/libraryReady', () => ({ +vi.mock('@/lib/library/libraryReady', () => ({ libraryIsReady: (serverId: string) => libraryIsReadyMock(serverId), })); diff --git a/src/features/offline/utils/offlineMediaResolve.ts b/src/features/offline/utils/offlineMediaResolve.ts index 5e7a2722..76205c12 100644 --- a/src/features/offline/utils/offlineMediaResolve.ts +++ b/src/features/offline/utils/offlineMediaResolve.ts @@ -10,7 +10,7 @@ import type { import { useAuthStore } from '@/store/authStore'; import { shouldAttemptSubsonicForServer } from '@/utils/network/subsonicNetworkGuard'; import { isOfflineBrowseActive } from '@/features/offline/utils/offlineBrowseMode'; -import { libraryIsReady } from '@/utils/library/libraryReady'; +import { libraryIsReady } from '@/lib/library/libraryReady'; import { registerMediaResolver } from '@/store/mediaResolver'; import { loadAlbumFromLibraryIndex, diff --git a/src/features/offline/utils/offlinePlaylistBrowse.ts b/src/features/offline/utils/offlinePlaylistBrowse.ts index 98b12dd1..60f4dc7a 100644 --- a/src/features/offline/utils/offlinePlaylistBrowse.ts +++ b/src/features/offline/utils/offlinePlaylistBrowse.ts @@ -3,7 +3,7 @@ import type { SubsonicPlaylist, SubsonicSong } from '@/lib/api/subsonicTypes'; import { useLibraryIndexStore } from '@/store/libraryIndexStore'; import type { PinnedGroup } from '@/store/localPlaybackStore'; import { useLocalPlaybackStore } from '@/store/localPlaybackStore'; -import { trackToSong } from '@/utils/library/advancedSearchLocal'; +import { trackToSong } from '@/lib/library/advancedSearchLocal'; import { isManualOfflinePlaylist } from '@/features/offline/utils/pinnedOfflineSync'; import { hasLocalLibraryBytes, diff --git a/src/features/offline/utils/offlineStarredLoad.ts b/src/features/offline/utils/offlineStarredLoad.ts index 7abb10a4..d2f006b1 100644 --- a/src/features/offline/utils/offlineStarredLoad.ts +++ b/src/features/offline/utils/offlineStarredLoad.ts @@ -10,7 +10,7 @@ import { isActiveServerReachable } from '@/utils/network/activeServerReachabilit import { albumToAlbum, trackToSong, -} from '@/utils/library/advancedSearchLocal'; +} from '@/lib/library/advancedSearchLocal'; import { dedupeById } from '@/lib/util/dedupeById'; import { isOfflineBrowseActive } from '@/features/offline/utils/offlineBrowseMode'; import { favoritesServerIds } from '@/features/offline/utils/favoritesOfflineBrowse'; diff --git a/src/features/offline/utils/resumeIncompleteOfflinePins.ts b/src/features/offline/utils/resumeIncompleteOfflinePins.ts index 62d1d4ad..13c55ac0 100644 --- a/src/features/offline/utils/resumeIncompleteOfflinePins.ts +++ b/src/features/offline/utils/resumeIncompleteOfflinePins.ts @@ -4,7 +4,7 @@ import type { SubsonicSong } from '@/lib/api/subsonicTypes'; import { useAuthStore } from '@/store/authStore'; import type { OfflineAlbumMeta } from '@/features/offline/store/offlineStore'; import { useOfflineStore } from '@/features/offline/store/offlineStore'; -import { trackToSong } from '@/utils/library/advancedSearchLocal'; +import { trackToSong } from '@/lib/library/advancedSearchLocal'; import { isActiveServerReachable, onActiveServerBecameReachable } from '@/utils/network/activeServerReachability'; import { shouldAttemptSubsonicForServer } from '@/utils/network/subsonicNetworkGuard'; import { resolveServerIdForIndexKey } from '@/utils/server/serverLookup'; diff --git a/src/features/playback/store/playListenSession.test.ts b/src/features/playback/store/playListenSession.test.ts index 6973fd77..767aa252 100644 --- a/src/features/playback/store/playListenSession.test.ts +++ b/src/features/playback/store/playListenSession.test.ts @@ -14,7 +14,7 @@ import { } from '@/features/playback/store/playListenSession'; import { onPlaySessionRecorded } from '@/features/playback/store/playSessionRecorded'; -vi.mock('@/utils/library/libraryReady', () => ({ +vi.mock('@/lib/library/libraryReady', () => ({ libraryIsReady: vi.fn(async () => true), })); @@ -178,7 +178,7 @@ describe('playListenSession', () => { }); it('skips when library is not ready', async () => { - const { libraryIsReady } = await import('@/utils/library/libraryReady'); + const { libraryIsReady } = await import('@/lib/library/libraryReady'); vi.mocked(libraryIsReady).mockResolvedValueOnce(false); vi.useFakeTimers(); await playListenSessionOpen(testTrack, 'server-1'); diff --git a/src/features/playback/store/playListenSession.ts b/src/features/playback/store/playListenSession.ts index d775a908..7a3ffa84 100644 --- a/src/features/playback/store/playListenSession.ts +++ b/src/features/playback/store/playListenSession.ts @@ -5,7 +5,7 @@ import { libraryRecordPlaySession, type PlaySessionEndReason, } from '@/lib/api/library'; -import { libraryIsReady } from '@/utils/library/libraryReady'; +import { libraryIsReady } from '@/lib/library/libraryReady'; import { getPlaybackServerId } from '@/features/playback/utils/playback/playbackServer'; import { emitPlaySessionRecorded } from '@/features/playback/store/playSessionRecorded'; import { useLibraryIndexStore } from '@/store/libraryIndexStore'; diff --git a/src/features/playback/store/queueTrackResolver.ts b/src/features/playback/store/queueTrackResolver.ts index c03b2cd1..3560fbe6 100644 --- a/src/features/playback/store/queueTrackResolver.ts +++ b/src/features/playback/store/queueTrackResolver.ts @@ -5,8 +5,8 @@ import type { QueueItemRef, Track } from '@/features/playback/store/playerStoreT import { songToTrack } from '@/features/playback/utils/playback/songToTrack'; import { resolveServerIdForIndexKey } from '@/utils/server/serverLookup'; import { canonicalQueueServerKey } from '@/utils/server/serverIndexKey'; -import { trackToSong } from '@/utils/library/advancedSearchLocal'; -import { libraryIsReady } from '@/utils/library/libraryReady'; +import { trackToSong } from '@/lib/library/advancedSearchLocal'; +import { libraryIsReady } from '@/lib/library/libraryReady'; /** * Queue track resolver (thin-state phase 2). Resolves `QueueItemRef`s to full diff --git a/src/features/playback/utils/playback/genreBrowsePlayback.test.ts b/src/features/playback/utils/playback/genreBrowsePlayback.test.ts index a035c450..9305e8ab 100644 --- a/src/features/playback/utils/playback/genreBrowsePlayback.test.ts +++ b/src/features/playback/utils/playback/genreBrowsePlayback.test.ts @@ -22,23 +22,23 @@ vi.mock('@/lib/api/subsonicClient', () => ({ libraryScopeForServer: vi.fn(() => 'music'), })); -vi.mock('@/utils/library/libraryReady', () => ({ +vi.mock('@/lib/library/libraryReady', () => ({ libraryIsReady: vi.fn(), })); // Spread the real leaf module so other consumers pulled in transitively (the // album barrel reaches this via the artist↔album edge → useGenreAlbumBrowse needs // GENRE_ALBUM_FIRST_PAGE); only fetchGenreAlbumTotal is stubbed here. -vi.mock('@/utils/library/genreAlbumBrowse', async (importOriginal) => ({ - ...(await importOriginal()), +vi.mock('@/lib/library/genreAlbumBrowse', async (importOriginal) => ({ + ...(await importOriginal()), fetchGenreAlbumTotal: vi.fn(), })); import { libraryAdvancedSearch, libraryGetGenreAlbumCounts } from '@/lib/api/library'; import { fetchAllSongsByGenre, getGenres } from '@/lib/api/subsonicGenres'; -import { fetchGenreAlbumTotal } from '@/utils/library/genreAlbumBrowse'; -import { resetGenreCatalogCountsCacheForTests } from '@/utils/library/genreCatalogCountsCache'; -import { libraryIsReady } from '@/utils/library/libraryReady'; +import { fetchGenreAlbumTotal } from '@/lib/library/genreAlbumBrowse'; +import { resetGenreCatalogCountsCacheForTests } from '@/lib/library/genreCatalogCountsCache'; +import { libraryIsReady } from '@/lib/library/libraryReady'; describe('genreBrowsePlayback', () => { beforeEach(() => { diff --git a/src/features/playback/utils/playback/genreBrowsePlayback.ts b/src/features/playback/utils/playback/genreBrowsePlayback.ts index 0e1e6c97..a901c46f 100644 --- a/src/features/playback/utils/playback/genreBrowsePlayback.ts +++ b/src/features/playback/utils/playback/genreBrowsePlayback.ts @@ -8,8 +8,8 @@ import { libraryScopeForServer } from '@/lib/api/subsonicClient'; import type { Track } from '@/features/playback/store/playerStoreTypes'; import { songToTrack } from '@/features/playback/utils/playback/songToTrack'; import { shuffleArray } from '@/lib/util/shuffleArray'; -import { trackToSong } from '@/utils/library/advancedSearchLocal'; -import { type AlbumBrowseSort } from '@/utils/library/albumBrowseSort'; +import { trackToSong } from '@/lib/library/advancedSearchLocal'; +import { type AlbumBrowseSort } from '@/lib/library/albumBrowseSort'; import { genreCatalogCacheKey, getInflightGenreCatalog, @@ -17,9 +17,9 @@ import { peekGenreCatalogCache, trackInflightGenreCatalog, writeGenreCatalogCache, -} from '@/utils/library/genreCatalogCountsCache'; -import { fetchGenreAlbumTotal } from '@/utils/library/genreAlbumBrowse'; -import { libraryIsReady } from '@/utils/library/libraryReady'; +} from '@/lib/library/genreCatalogCountsCache'; +import { fetchGenreAlbumTotal } from '@/lib/library/genreAlbumBrowse'; +import { libraryIsReady } from '@/lib/library/libraryReady'; /** Drop genres with no indexed albums/tracks (stale server list or orphan rows). */ export function filterGenresWithContent(genres: SubsonicGenre[]): SubsonicGenre[] { diff --git a/src/features/queue/components/QueueCurrentTrack.tsx b/src/features/queue/components/QueueCurrentTrack.tsx index f5656b47..724667e0 100644 --- a/src/features/queue/components/QueueCurrentTrack.tsx +++ b/src/features/queue/components/QueueCurrentTrack.tsx @@ -10,7 +10,7 @@ import { } from '@/utils/componentHelpers/queuePanelHelpers'; import { loudnessGainPlaceholderUntilCacheDb } from '@/features/playback/utils/audio/loudnessPlaceholder'; import { effectiveLoudnessPreAnalysisAttenuationDb } from '@/utils/audio/loudnessPreAnalysisSlider'; -import { formatQueueBpmTech, formatQueueMoodLabels } from '@/utils/library/trackEnrichment'; +import { formatQueueBpmTech, formatQueueMoodLabels } from '@/lib/library/trackEnrichment'; import { useQueueTrackEnrichment } from '@/features/queue/hooks/useQueueTrackEnrichment'; import { QueueLufsTargetMenu } from '@/features/queue/components/QueueLufsTargetMenu'; import { PlaybackBufferingOverlay } from '@/components/playback/PlaybackBufferingOverlay'; diff --git a/src/features/queue/hooks/useQueueTrackEnrichment.ts b/src/features/queue/hooks/useQueueTrackEnrichment.ts index 6e3b25e2..38d8e655 100644 --- a/src/features/queue/hooks/useQueueTrackEnrichment.ts +++ b/src/features/queue/hooks/useQueueTrackEnrichment.ts @@ -8,8 +8,8 @@ import { OXIMEDIA_MOOD_UI_ENABLED, parseTrackEnrichmentFacts, type ParsedTrackEnrichment, -} from '@/utils/library/trackEnrichment'; -import { libraryIsReady } from '@/utils/library/libraryReady'; +} from '@/lib/library/trackEnrichment'; +import { libraryIsReady } from '@/lib/library/libraryReady'; import { normalizeAnalysisTrackId } from '@/features/playback/utils/playback/queueIdentity'; const EMPTY: ParsedTrackEnrichment = { diff --git a/src/features/search/components/LiveSearch.tsx b/src/features/search/components/LiveSearch.tsx index 626d0976..ad45b70c 100644 --- a/src/features/search/components/LiveSearch.tsx +++ b/src/features/search/components/LiveSearch.tsx @@ -9,17 +9,17 @@ import { mergeLiveSearchResults, runLocalLiveSearch, runNetworkLiveSearch, -} from '@/utils/library/liveSearchLocal'; -import { raceLiveSearch } from '@/utils/library/searchRace'; -import { libraryIsReady } from '@/utils/library/libraryReady'; +} from '@/lib/library/liveSearchLocal'; +import { raceLiveSearch } from '@/lib/library/searchRace'; +import { libraryIsReady } from '@/lib/library/libraryReady'; import { emitLiveSearchDebug, searchHitCounts, searchResultSamples, -} from '@/utils/library/liveSearchDebug'; +} from '@/lib/library/liveSearchDebug'; import { logLibrarySearch, -} from '@/utils/library/libraryDevLog'; +} from '@/lib/library/libraryDevLog'; import React, { useState, useEffect, useRef, useCallback } from 'react'; import { useNavigate, useLocation } from 'react-router-dom'; import { useNavigateToAlbum } from '@/features/album'; diff --git a/src/features/search/index.ts b/src/features/search/index.ts index 80b8ffb4..b76ad5e7 100644 --- a/src/features/search/index.ts +++ b/src/features/search/index.ts @@ -3,7 +3,7 @@ * search/browse page (lazy via the deep path `pages/SearchBrowsePage`), live * search scope UI/state, and the share-link search/queue-preview surfaces. * - * The local-index query engine (`utils/library/*search*`), the shared Subsonic + * The local-index query engine (`lib/library/*search*`), the shared Subsonic * search API, the cross-cutting `liveSearchScopeStore`, and the * `advancedSearch*` session/scroll state live outside this feature * (library-core / cross-cutting) — this feature consumes them. diff --git a/src/features/search/pages/SearchBrowsePage.tsx b/src/features/search/pages/SearchBrowsePage.tsx index b1f84d7a..50b2e864 100644 --- a/src/features/search/pages/SearchBrowsePage.tsx +++ b/src/features/search/pages/SearchBrowsePage.tsx @@ -42,19 +42,19 @@ import { runNetworkAdvancedTextSearch, runNetworkAdvancedYearAlbums, tryRunLocalAdvancedSearch, -} from '@/utils/library/advancedSearchLocal'; -import { isLosslessSuffix } from '@/utils/library/losslessFormats'; -import { LOSSLESS_MODE_QUERY } from '@/utils/library/losslessMode'; -import { OXIMEDIA_MOOD_SEARCH_ENABLED } from '@/utils/library/trackEnrichment'; -import { raceSearchSources } from '@/utils/library/searchRace'; -import { logLibrarySearch } from '@/utils/library/libraryDevLog'; +} from '@/lib/library/advancedSearchLocal'; +import { isLosslessSuffix } from '@/lib/library/losslessFormats'; +import { LOSSLESS_MODE_QUERY } from '@/lib/library/losslessMode'; +import { OXIMEDIA_MOOD_SEARCH_ENABLED } from '@/lib/library/trackEnrichment'; +import { raceSearchSources } from '@/lib/library/searchRace'; +import { logLibrarySearch } from '@/lib/library/libraryDevLog'; import { browseRaceCountsFullSearch, loadMoreLocalBrowseSongs, raceBrowseWithLocalFallback, runLocalBrowseFullSearch, runNetworkBrowseFullSearch, -} from '@/utils/library/browseTextSearch'; +} from '@/lib/library/browseTextSearch'; import { useLibraryIndexStore } from '@/store/libraryIndexStore'; import { MOOD_GROUP_IDS } from '@/config/moodGroups'; import { usePerfProbeFlags } from '@/utils/perf/perfFlags'; diff --git a/src/features/settings/components/AnalyticsStrategySection.tsx b/src/features/settings/components/AnalyticsStrategySection.tsx index d80ef28d..48db3573 100644 --- a/src/features/settings/components/AnalyticsStrategySection.tsx +++ b/src/features/settings/components/AnalyticsStrategySection.tsx @@ -29,7 +29,7 @@ import { ADVANCED_PARALLELISM_MAX, ADVANCED_PARALLELISM_MIN, type AnalyticsStrategy, -} from '@/utils/library/analysisStrategy'; +} from '@/lib/library/analysisStrategy'; type ClearTarget = { serverId: string; diff --git a/src/features/settings/components/CoverCacheStrategySection.tsx b/src/features/settings/components/CoverCacheStrategySection.tsx index b136d832..ee5d3e61 100644 --- a/src/features/settings/components/CoverCacheStrategySection.tsx +++ b/src/features/settings/components/CoverCacheStrategySection.tsx @@ -19,11 +19,11 @@ import { serverIndexKeyForProfile } from '@/utils/server/serverIndexKey'; import { showToast } from '@/utils/ui/toast'; import { formatBytes } from '@/lib/format/formatBytes'; import { clearImageCache, getImageCacheSize } from '@/utils/imageCache'; -import { wakeLibraryCoverBackfill } from '@/utils/library/coverBackfillWake'; +import { wakeLibraryCoverBackfill } from '@/lib/library/coverBackfillWake'; import { COVER_CACHE_STRATEGIES, type CoverCacheStrategy, -} from '@/utils/library/coverStrategy'; +} from '@/lib/library/coverStrategy'; type ClearTarget = | { kind: 'image' } diff --git a/src/features/settings/components/ServerLibraryIndexControls.tsx b/src/features/settings/components/ServerLibraryIndexControls.tsx index 81495e01..c3f0bf96 100644 --- a/src/features/settings/components/ServerLibraryIndexControls.tsx +++ b/src/features/settings/components/ServerLibraryIndexControls.tsx @@ -4,7 +4,7 @@ import type { SyncStateDto } from '@/lib/api/library'; import { libraryStatusDisplayTrackCount, libraryStatusIsReady, -} from '@/utils/library/libraryReady'; +} from '@/lib/library/libraryReady'; import type { LibraryServerConnection } from '@/hooks/useLibraryIndexSync'; interface ServerLibraryIndexControlsProps { diff --git a/src/features/settings/components/ServersTab.tsx b/src/features/settings/components/ServersTab.tsx index 2b8005fb..7490f2d8 100644 --- a/src/features/settings/components/ServersTab.tsx +++ b/src/features/settings/components/ServersTab.tsx @@ -8,7 +8,7 @@ import { formatServerSoftware, isNavidromeAudiomuseSoftwareEligible, type Instan import { buildCapabilityContext } from '@/serverCapabilities/context'; import { useLibraryIndexStore } from '@/store/libraryIndexStore'; import { libraryDeleteServerData, librarySyncClearSession } from '@/lib/api/library'; -import { bootstrapIndexedServer } from '@/utils/library/librarySession'; +import { bootstrapIndexedServer } from '@/lib/library/librarySession'; import { useLibraryIndexSync } from '@/hooks/useLibraryIndexSync'; import ServerLibraryIndexControls from '@/features/settings/components/ServerLibraryIndexControls'; import type { ServerProfile } from '@/store/authStoreTypes'; diff --git a/src/hooks/tauriBridge/useLibraryDevSyncLog.ts b/src/hooks/tauriBridge/useLibraryDevSyncLog.ts index 33906a6f..e481f9cd 100644 --- a/src/hooks/tauriBridge/useLibraryDevSyncLog.ts +++ b/src/hooks/tauriBridge/useLibraryDevSyncLog.ts @@ -15,7 +15,7 @@ import { logLibrarySync, normalizeIngestMetrics, timed, -} from '../../utils/library/libraryDevLog'; +} from '@/lib/library/libraryDevLog'; /** * DevTools: log library sync progress + idle with ingest strategy from status. diff --git a/src/hooks/useLibraryAnalysisBackfill.ts b/src/hooks/useLibraryAnalysisBackfill.ts index 848bb571..69b4f33e 100644 --- a/src/hooks/useLibraryAnalysisBackfill.ts +++ b/src/hooks/useLibraryAnalysisBackfill.ts @@ -6,7 +6,7 @@ import { import { librarySqlServerId } from '../api/coverCache'; import { useAuthStore } from '../store/authStore'; import { useAnalysisStrategyStore } from '../store/analysisStrategyStore'; -import { DEFAULT_ADVANCED_PARALLELISM } from '../utils/library/analysisStrategy'; +import { DEFAULT_ADVANCED_PARALLELISM } from '@/lib/library/analysisStrategy'; import { serverIndexKeyForProfile } from '../utils/server/serverIndexKey'; const DISABLED_CONFIGURE = { diff --git a/src/hooks/useLibraryCoverBackfill.ts b/src/hooks/useLibraryCoverBackfill.ts index eae2eb8f..8c8d3c10 100644 --- a/src/hooks/useLibraryCoverBackfill.ts +++ b/src/hooks/useLibraryCoverBackfill.ts @@ -7,10 +7,10 @@ import { libraryCoverBackfillSetBaseUrl, librarySqlServerId, } from '../api/coverCache'; -import { coverStrategyAllowsLibraryBackfill } from '../utils/library/coverStrategy'; +import { coverStrategyAllowsLibraryBackfill } from '@/lib/library/coverStrategy'; import { useAuthStore } from '../store/authStore'; import { useCoverStrategyStore } from '../store/coverStrategyStore'; -import { subscribeLibraryCoverBackfillWake } from '../utils/library/coverBackfillWake'; +import { subscribeLibraryCoverBackfillWake } from '@/lib/library/coverBackfillWake'; import { serverIndexKeyForProfile } from '../utils/server/serverIndexKey'; import { subscribeConnectCache } from '../utils/server/serverEndpoint'; diff --git a/src/hooks/useLibraryIndexSync.ts b/src/hooks/useLibraryIndexSync.ts index e519a6ef..37dfe185 100644 --- a/src/hooks/useLibraryIndexSync.ts +++ b/src/hooks/useLibraryIndexSync.ts @@ -15,9 +15,9 @@ import { bootstrapAllIndexedServers, bootstrapIndexedServer, type BindServerResult, -} from '../utils/library/librarySession'; -import { enqueueLibrarySync } from '../utils/library/librarySyncQueue'; -import { syncIngestDisplayCount } from '../utils/library/libraryReady'; +} from '@/lib/library/librarySession'; +import { enqueueLibrarySync } from '@/lib/library/librarySyncQueue'; +import { syncIngestDisplayCount } from '@/lib/library/libraryReady'; export type LibraryServerConnection = 'online' | 'offline' | 'unknown'; diff --git a/src/hooks/useSongBrowseList.test.ts b/src/hooks/useSongBrowseList.test.ts index 04e6e01d..886d6b65 100644 --- a/src/hooks/useSongBrowseList.test.ts +++ b/src/hooks/useSongBrowseList.test.ts @@ -14,7 +14,7 @@ vi.mock('@/lib/api/navidromeBrowse', () => ({ ndListSongs: vi.fn(async () => []), })); -vi.mock('../utils/library/advancedSearchLocal', () => ({ +vi.mock('@/lib/library/advancedSearchLocal', () => ({ runLocalSongBrowse: vi.fn(async () => []), })); @@ -25,7 +25,7 @@ vi.mock('@/features/offline/hooks/useOfflineBrowseReloadToken', () => ({ useOfflineBrowseReloadToken: () => undefined, })); -vi.mock('../utils/library/browseTextSearch', () => ({ +vi.mock('@/lib/library/browseTextSearch', () => ({ BROWSE_TEXT_DEBOUNCE_NETWORK_MS: 10, BROWSE_TEXT_DEBOUNCE_RACE_MS: 10, browseRaceCountsSongs: vi.fn(), diff --git a/src/hooks/useSongBrowseList.ts b/src/hooks/useSongBrowseList.ts index ca4cc9ae..dd93a555 100644 --- a/src/hooks/useSongBrowseList.ts +++ b/src/hooks/useSongBrowseList.ts @@ -2,7 +2,7 @@ import { searchSongsPaged } from '@/lib/api/subsonicSearch'; import type { SubsonicSong } from '@/lib/api/subsonicTypes'; import { useCallback, useEffect, useRef, useState } from 'react'; import { ndListSongs } from '@/lib/api/navidromeBrowse'; -import { runLocalSongBrowse } from '../utils/library/advancedSearchLocal'; +import { runLocalSongBrowse } from '@/lib/library/advancedSearchLocal'; import { BROWSE_TEXT_DEBOUNCE_NETWORK_MS, BROWSE_TEXT_DEBOUNCE_RACE_MS, @@ -11,7 +11,7 @@ import { raceBrowseWithLocalFallback, runLocalBrowseSongPage, runNetworkBrowseSongPage, -} from '../utils/library/browseTextSearch'; +} from '@/lib/library/browseTextSearch'; import { useAuthStore } from '../store/authStore'; import { useLibraryIndexStore } from '../store/libraryIndexStore'; import { useOfflineBrowseContext } from '@/features/offline'; diff --git a/src/lib/api/navidromeBrowse.ts b/src/lib/api/navidromeBrowse.ts index 897c64ae..a6788d4a 100644 --- a/src/lib/api/navidromeBrowse.ts +++ b/src/lib/api/navidromeBrowse.ts @@ -1,5 +1,5 @@ import type { SubsonicAlbum, SubsonicArtist, SubsonicSong } from '@/lib/api/subsonicTypes'; -import { parseItemGenres } from '@/utils/library/genreTags'; +import { parseItemGenres } from '@/lib/library/genreTags'; import { invoke } from '@tauri-apps/api/core'; import { useAuthStore } from '@/store/authStore'; import { ndLogin } from '@/lib/api/navidromeAdmin'; diff --git a/src/lib/api/subsonicScrobble.ts b/src/lib/api/subsonicScrobble.ts index 7b7c7b29..897ed8e8 100644 --- a/src/lib/api/subsonicScrobble.ts +++ b/src/lib/api/subsonicScrobble.ts @@ -1,6 +1,6 @@ import { api, apiForServer } from '@/lib/api/subsonicClient'; import type { PlaybackReportState, SubsonicNowPlaying } from '@/lib/api/subsonicTypes'; -import { patchLibraryTrackOnUse } from '@/utils/library/patchOnUse'; +import { patchLibraryTrackOnUse } from '@/lib/library/patchOnUse'; import { shouldAttemptSubsonicForServer } from '@/utils/network/subsonicNetworkGuard'; async function scrobbleOnServer( diff --git a/src/lib/api/subsonicSearch.ts b/src/lib/api/subsonicSearch.ts index 44d1dc97..45d0ad85 100644 --- a/src/lib/api/subsonicSearch.ts +++ b/src/lib/api/subsonicSearch.ts @@ -1,5 +1,5 @@ import { api, libraryFilterParams } from '@/lib/api/subsonicClient'; -import { searchQueryIsFtsSafe } from '@/utils/library/searchQueryFtsSafe'; +import { searchQueryIsFtsSafe } from '@/lib/library/searchQueryFtsSafe'; import type { SearchResults, SubsonicAlbum, diff --git a/src/lib/api/subsonicStarRating.ts b/src/lib/api/subsonicStarRating.ts index 5fa25152..acfd9192 100644 --- a/src/lib/api/subsonicStarRating.ts +++ b/src/lib/api/subsonicStarRating.ts @@ -1,12 +1,12 @@ import { api, apiForServer, libraryFilterParams, libraryFilterParamsForServer } from '@/lib/api/subsonicClient'; import { invalidateEntityUserRatingCaches } from '@/lib/api/subsonicRatings'; import { useAuthStore } from '@/store/authStore'; -import { patchLibraryTrackOnUse, type StarPatchMeta } from '@/utils/library/patchOnUse'; +import { patchLibraryTrackOnUse, type StarPatchMeta } from '@/lib/library/patchOnUse'; import { useLibraryIndexStore } from '@/store/libraryIndexStore'; import { invalidateStarredAlbumBrowse, refreshStarredAlbumIndexFromServer, -} from '@/utils/library/starredAlbumIndexSync'; +} from '@/lib/library/starredAlbumIndexSync'; import type { EntityRatingSupportLevel, StarredResults, diff --git a/src/lib/api/subsonicStatistics.ts b/src/lib/api/subsonicStatistics.ts index 47911926..77c9f45a 100644 --- a/src/lib/api/subsonicStatistics.ts +++ b/src/lib/api/subsonicStatistics.ts @@ -1,5 +1,5 @@ import { useAuthStore } from '@/store/authStore'; -import { genreTagsFor } from '@/utils/library/genreTags'; +import { genreTagsFor } from '@/lib/library/genreTags'; import { getArtists } from '@/lib/api/subsonicArtists'; import { getAlbumList, getRandomSongs } from '@/lib/api/subsonicLibrary'; import type { diff --git a/src/utils/library/advancedSearchLocal.test.ts b/src/lib/library/advancedSearchLocal.test.ts similarity index 100% rename from src/utils/library/advancedSearchLocal.test.ts rename to src/lib/library/advancedSearchLocal.test.ts diff --git a/src/utils/library/advancedSearchLocal.ts b/src/lib/library/advancedSearchLocal.ts similarity index 100% rename from src/utils/library/advancedSearchLocal.ts rename to src/lib/library/advancedSearchLocal.ts diff --git a/src/utils/library/albumBrowseCatalogChunk.test.ts b/src/lib/library/albumBrowseCatalogChunk.test.ts similarity index 100% rename from src/utils/library/albumBrowseCatalogChunk.test.ts rename to src/lib/library/albumBrowseCatalogChunk.test.ts diff --git a/src/utils/library/albumBrowseFilters.ts b/src/lib/library/albumBrowseFilters.ts similarity index 100% rename from src/utils/library/albumBrowseFilters.ts rename to src/lib/library/albumBrowseFilters.ts diff --git a/src/utils/library/albumBrowseGenreOptions.test.ts b/src/lib/library/albumBrowseGenreOptions.test.ts similarity index 100% rename from src/utils/library/albumBrowseGenreOptions.test.ts rename to src/lib/library/albumBrowseGenreOptions.test.ts diff --git a/src/utils/library/albumBrowseLoad.test.ts b/src/lib/library/albumBrowseLoad.test.ts similarity index 100% rename from src/utils/library/albumBrowseLoad.test.ts rename to src/lib/library/albumBrowseLoad.test.ts diff --git a/src/utils/library/albumBrowseLoad.ts b/src/lib/library/albumBrowseLoad.ts similarity index 100% rename from src/utils/library/albumBrowseLoad.ts rename to src/lib/library/albumBrowseLoad.ts diff --git a/src/utils/library/albumBrowseLocal.ts b/src/lib/library/albumBrowseLocal.ts similarity index 100% rename from src/utils/library/albumBrowseLocal.ts rename to src/lib/library/albumBrowseLocal.ts diff --git a/src/utils/library/albumBrowseNetwork.ts b/src/lib/library/albumBrowseNetwork.ts similarity index 100% rename from src/utils/library/albumBrowseNetwork.ts rename to src/lib/library/albumBrowseNetwork.ts diff --git a/src/utils/library/albumBrowseSort.test.ts b/src/lib/library/albumBrowseSort.test.ts similarity index 100% rename from src/utils/library/albumBrowseSort.test.ts rename to src/lib/library/albumBrowseSort.test.ts diff --git a/src/utils/library/albumBrowseSort.ts b/src/lib/library/albumBrowseSort.ts similarity index 100% rename from src/utils/library/albumBrowseSort.ts rename to src/lib/library/albumBrowseSort.ts diff --git a/src/utils/library/albumBrowseStarredCache.ts b/src/lib/library/albumBrowseStarredCache.ts similarity index 100% rename from src/utils/library/albumBrowseStarredCache.ts rename to src/lib/library/albumBrowseStarredCache.ts diff --git a/src/utils/library/albumBrowseStarredFetch.ts b/src/lib/library/albumBrowseStarredFetch.ts similarity index 100% rename from src/utils/library/albumBrowseStarredFetch.ts rename to src/lib/library/albumBrowseStarredFetch.ts diff --git a/src/utils/library/albumBrowseTypes.ts b/src/lib/library/albumBrowseTypes.ts similarity index 100% rename from src/utils/library/albumBrowseTypes.ts rename to src/lib/library/albumBrowseTypes.ts diff --git a/src/utils/library/albumCatalogYearBounds.ts b/src/lib/library/albumCatalogYearBounds.ts similarity index 100% rename from src/utils/library/albumCatalogYearBounds.ts rename to src/lib/library/albumCatalogYearBounds.ts diff --git a/src/utils/library/albumCompilation.test.ts b/src/lib/library/albumCompilation.test.ts similarity index 100% rename from src/utils/library/albumCompilation.test.ts rename to src/lib/library/albumCompilation.test.ts diff --git a/src/utils/library/albumCompilation.ts b/src/lib/library/albumCompilation.ts similarity index 100% rename from src/utils/library/albumCompilation.ts rename to src/lib/library/albumCompilation.ts diff --git a/src/utils/library/albumYearFilter.test.ts b/src/lib/library/albumYearFilter.test.ts similarity index 100% rename from src/utils/library/albumYearFilter.test.ts rename to src/lib/library/albumYearFilter.test.ts diff --git a/src/utils/library/albumYearFilter.ts b/src/lib/library/albumYearFilter.ts similarity index 100% rename from src/utils/library/albumYearFilter.ts rename to src/lib/library/albumYearFilter.ts diff --git a/src/utils/library/analysisStrategy.ts b/src/lib/library/analysisStrategy.ts similarity index 100% rename from src/utils/library/analysisStrategy.ts rename to src/lib/library/analysisStrategy.ts diff --git a/src/utils/library/browseTextSearch.test.ts b/src/lib/library/browseTextSearch.test.ts similarity index 100% rename from src/utils/library/browseTextSearch.test.ts rename to src/lib/library/browseTextSearch.test.ts diff --git a/src/utils/library/browseTextSearch.ts b/src/lib/library/browseTextSearch.ts similarity index 100% rename from src/utils/library/browseTextSearch.ts rename to src/lib/library/browseTextSearch.ts diff --git a/src/utils/library/composerBrowse.test.ts b/src/lib/library/composerBrowse.test.ts similarity index 100% rename from src/utils/library/composerBrowse.test.ts rename to src/lib/library/composerBrowse.test.ts diff --git a/src/utils/library/composerBrowse.ts b/src/lib/library/composerBrowse.ts similarity index 100% rename from src/utils/library/composerBrowse.ts rename to src/lib/library/composerBrowse.ts diff --git a/src/utils/library/coverBackfillWake.ts b/src/lib/library/coverBackfillWake.ts similarity index 100% rename from src/utils/library/coverBackfillWake.ts rename to src/lib/library/coverBackfillWake.ts diff --git a/src/utils/library/coverStrategy.ts b/src/lib/library/coverStrategy.ts similarity index 100% rename from src/utils/library/coverStrategy.ts rename to src/lib/library/coverStrategy.ts diff --git a/src/utils/library/genreAlbumBrowse.test.ts b/src/lib/library/genreAlbumBrowse.test.ts similarity index 100% rename from src/utils/library/genreAlbumBrowse.test.ts rename to src/lib/library/genreAlbumBrowse.test.ts diff --git a/src/utils/library/genreAlbumBrowse.ts b/src/lib/library/genreAlbumBrowse.ts similarity index 100% rename from src/utils/library/genreAlbumBrowse.ts rename to src/lib/library/genreAlbumBrowse.ts diff --git a/src/utils/library/genreCatalogCountsCache.test.ts b/src/lib/library/genreCatalogCountsCache.test.ts similarity index 100% rename from src/utils/library/genreCatalogCountsCache.test.ts rename to src/lib/library/genreCatalogCountsCache.test.ts diff --git a/src/utils/library/genreCatalogCountsCache.ts b/src/lib/library/genreCatalogCountsCache.ts similarity index 97% rename from src/utils/library/genreCatalogCountsCache.ts rename to src/lib/library/genreCatalogCountsCache.ts index 8b486567..2bdc0bd8 100644 --- a/src/utils/library/genreCatalogCountsCache.ts +++ b/src/lib/library/genreCatalogCountsCache.ts @@ -1,5 +1,5 @@ import type { SubsonicGenre } from '@/lib/api/subsonicTypes'; -import { resolveServerIdForIndexKey } from '../server/serverLookup'; +import { resolveServerIdForIndexKey } from '@/utils/server/serverLookup'; /** Fresh hits skip SQLite entirely. */ const FRESH_TTL_MS = 60 * 60 * 1000; diff --git a/src/utils/library/genreColor.ts b/src/lib/library/genreColor.ts similarity index 100% rename from src/utils/library/genreColor.ts rename to src/lib/library/genreColor.ts diff --git a/src/utils/library/genreTags.test.ts b/src/lib/library/genreTags.test.ts similarity index 100% rename from src/utils/library/genreTags.test.ts rename to src/lib/library/genreTags.test.ts diff --git a/src/utils/library/genreTags.ts b/src/lib/library/genreTags.ts similarity index 100% rename from src/utils/library/genreTags.ts rename to src/lib/library/genreTags.ts diff --git a/src/utils/library/libraryCoverBackfillPolicy.ts b/src/lib/library/libraryCoverBackfillPolicy.ts similarity index 93% rename from src/utils/library/libraryCoverBackfillPolicy.ts rename to src/lib/library/libraryCoverBackfillPolicy.ts index 8666c3e8..eec55e84 100644 --- a/src/utils/library/libraryCoverBackfillPolicy.ts +++ b/src/lib/library/libraryCoverBackfillPolicy.ts @@ -1,4 +1,4 @@ -import { coverEnsureQueueBacklog } from '../../cover/ensureQueue'; +import { coverEnsureQueueBacklog } from '@/cover/ensureQueue'; /** Target in-flight + queued ensures ≈ workers × multiplier (mirror analysis backfill). */ export const LIBRARY_COVER_BACKLOG_DEPTH_MULTIPLIER = 3; diff --git a/src/utils/library/libraryDevLog.test.ts b/src/lib/library/libraryDevLog.test.ts similarity index 100% rename from src/utils/library/libraryDevLog.test.ts rename to src/lib/library/libraryDevLog.test.ts diff --git a/src/utils/library/libraryDevLog.ts b/src/lib/library/libraryDevLog.ts similarity index 100% rename from src/utils/library/libraryDevLog.ts rename to src/lib/library/libraryDevLog.ts diff --git a/src/utils/library/libraryReady.test.ts b/src/lib/library/libraryReady.test.ts similarity index 100% rename from src/utils/library/libraryReady.test.ts rename to src/lib/library/libraryReady.test.ts diff --git a/src/utils/library/libraryReady.ts b/src/lib/library/libraryReady.ts similarity index 97% rename from src/utils/library/libraryReady.ts rename to src/lib/library/libraryReady.ts index a3cae8af..27f5431c 100644 --- a/src/utils/library/libraryReady.ts +++ b/src/lib/library/libraryReady.ts @@ -5,7 +5,7 @@ * index when it's enabled and synced enough for trustworthy results. */ import { libraryGetStatus, type SyncStateDto } from '@/lib/api/library'; -import { useLibraryIndexStore } from '../../store/libraryIndexStore'; +import { useLibraryIndexStore } from '@/store/libraryIndexStore'; /** Spec §9.3 — shared by Live Search, Advanced Search, browse, … */ export function libraryStatusIsReady(status: SyncStateDto): boolean { diff --git a/src/utils/library/librarySession.test.ts b/src/lib/library/librarySession.test.ts similarity index 100% rename from src/utils/library/librarySession.test.ts rename to src/lib/library/librarySession.test.ts diff --git a/src/utils/library/librarySession.ts b/src/lib/library/librarySession.ts similarity index 92% rename from src/utils/library/librarySession.ts rename to src/lib/library/librarySession.ts index 73defc14..9de4adc3 100644 --- a/src/utils/library/librarySession.ts +++ b/src/lib/library/librarySession.ts @@ -3,12 +3,12 @@ import { librarySyncBindSession, } from '@/lib/api/library'; import { enqueueLibrarySync, queueInitialSyncIfNeeded } from './librarySyncQueue'; -import type { ServerProfile } from '../../store/authStoreTypes'; -import { useAuthStore } from '../../store/authStore'; -import { useLibraryIndexStore } from '../../store/libraryIndexStore'; -import { ensureConnectUrlResolved } from '../server/serverEndpoint'; -import { serverIndexKeyForProfile } from '../server/serverIndexKey'; -import { syncServerHttpContextForProfile } from '../server/syncServerHttpContext'; +import type { ServerProfile } from '@/store/authStoreTypes'; +import { useAuthStore } from '@/store/authStore'; +import { useLibraryIndexStore } from '@/store/libraryIndexStore'; +import { ensureConnectUrlResolved } from '@/utils/server/serverEndpoint'; +import { serverIndexKeyForProfile } from '@/utils/server/serverIndexKey'; +import { syncServerHttpContextForProfile } from '@/utils/server/syncServerHttpContext'; import { libraryDevEnabled, logLibraryStatus, logLibrarySync, timed } from './libraryDevLog'; export type BindServerResult = 'bound' | 'offline' | 'error'; diff --git a/src/utils/library/librarySyncQueue.test.ts b/src/lib/library/librarySyncQueue.test.ts similarity index 100% rename from src/utils/library/librarySyncQueue.test.ts rename to src/lib/library/librarySyncQueue.test.ts diff --git a/src/utils/library/librarySyncQueue.ts b/src/lib/library/librarySyncQueue.ts similarity index 100% rename from src/utils/library/librarySyncQueue.ts rename to src/lib/library/librarySyncQueue.ts diff --git a/src/utils/library/liveSearchDebug.test.ts b/src/lib/library/liveSearchDebug.test.ts similarity index 100% rename from src/utils/library/liveSearchDebug.test.ts rename to src/lib/library/liveSearchDebug.test.ts diff --git a/src/utils/library/liveSearchDebug.ts b/src/lib/library/liveSearchDebug.ts similarity index 94% rename from src/utils/library/liveSearchDebug.ts rename to src/lib/library/liveSearchDebug.ts index 4ba9a932..b64f0293 100644 --- a/src/utils/library/liveSearchDebug.ts +++ b/src/lib/library/liveSearchDebug.ts @@ -1,6 +1,6 @@ import { invoke } from '@tauri-apps/api/core'; import type { SearchResults } from '@/lib/api/subsonicTypes'; -import { useAuthStore } from '../../store/authStore'; +import { useAuthStore } from '@/store/authStore'; export function searchHitCounts(result: SearchResults): string { return `${result.artists.length}/${result.albums.length}/${result.songs.length}`; diff --git a/src/utils/library/liveSearchLocal.test.ts b/src/lib/library/liveSearchLocal.test.ts similarity index 100% rename from src/utils/library/liveSearchLocal.test.ts rename to src/lib/library/liveSearchLocal.test.ts diff --git a/src/utils/library/liveSearchLocal.ts b/src/lib/library/liveSearchLocal.ts similarity index 100% rename from src/utils/library/liveSearchLocal.ts rename to src/lib/library/liveSearchLocal.ts diff --git a/src/utils/library/losslessFormats.ts b/src/lib/library/losslessFormats.ts similarity index 100% rename from src/utils/library/losslessFormats.ts rename to src/lib/library/losslessFormats.ts diff --git a/src/utils/library/losslessMode.ts b/src/lib/library/losslessMode.ts similarity index 100% rename from src/utils/library/losslessMode.ts rename to src/lib/library/losslessMode.ts diff --git a/src/utils/library/patchOnUse.test.ts b/src/lib/library/patchOnUse.test.ts similarity index 100% rename from src/utils/library/patchOnUse.test.ts rename to src/lib/library/patchOnUse.test.ts diff --git a/src/utils/library/patchOnUse.ts b/src/lib/library/patchOnUse.ts similarity index 94% rename from src/utils/library/patchOnUse.ts rename to src/lib/library/patchOnUse.ts index 375b613b..ef39dd16 100644 --- a/src/utils/library/patchOnUse.ts +++ b/src/lib/library/patchOnUse.ts @@ -1,5 +1,5 @@ import { libraryPatchTrack } from '@/lib/api/library'; -import { useLibraryIndexStore } from '../../store/libraryIndexStore'; +import { useLibraryIndexStore } from '@/store/libraryIndexStore'; type TrackPatch = { /** ms epoch when starred, or `null` to clear (unstar). */ diff --git a/src/utils/library/searchQueryFtsSafe.test.ts b/src/lib/library/searchQueryFtsSafe.test.ts similarity index 100% rename from src/utils/library/searchQueryFtsSafe.test.ts rename to src/lib/library/searchQueryFtsSafe.test.ts diff --git a/src/utils/library/searchQueryFtsSafe.ts b/src/lib/library/searchQueryFtsSafe.ts similarity index 100% rename from src/utils/library/searchQueryFtsSafe.ts rename to src/lib/library/searchQueryFtsSafe.ts diff --git a/src/utils/library/searchRace.live.test.ts b/src/lib/library/searchRace.live.test.ts similarity index 100% rename from src/utils/library/searchRace.live.test.ts rename to src/lib/library/searchRace.live.test.ts diff --git a/src/utils/library/searchRace.test.ts b/src/lib/library/searchRace.test.ts similarity index 100% rename from src/utils/library/searchRace.test.ts rename to src/lib/library/searchRace.test.ts diff --git a/src/utils/library/searchRace.ts b/src/lib/library/searchRace.ts similarity index 100% rename from src/utils/library/searchRace.ts rename to src/lib/library/searchRace.ts diff --git a/src/utils/library/starredAlbumIndexSync.ts b/src/lib/library/starredAlbumIndexSync.ts similarity index 100% rename from src/utils/library/starredAlbumIndexSync.ts rename to src/lib/library/starredAlbumIndexSync.ts diff --git a/src/utils/library/trackEnrichment.test.ts b/src/lib/library/trackEnrichment.test.ts similarity index 99% rename from src/utils/library/trackEnrichment.test.ts rename to src/lib/library/trackEnrichment.test.ts index bd9a8c40..abaf3e70 100644 --- a/src/utils/library/trackEnrichment.test.ts +++ b/src/lib/library/trackEnrichment.test.ts @@ -9,7 +9,7 @@ import { resolveDisplayBpm, topMoodLabelIds, } from './trackEnrichment'; -import { topDistinctOximediaMoodTagIds, topOximediaMoodTagIds } from '../../config/moodGroups'; +import { topDistinctOximediaMoodTagIds, topOximediaMoodTagIds } from '@/config/moodGroups'; const t = ((key: string, opts?: Record) => { if (key === 'queue.bpm') return `${opts?.bpm} BPM`; diff --git a/src/utils/library/trackEnrichment.ts b/src/lib/library/trackEnrichment.ts similarity index 97% rename from src/utils/library/trackEnrichment.ts rename to src/lib/library/trackEnrichment.ts index c8a3a938..2312d8a5 100644 --- a/src/utils/library/trackEnrichment.ts +++ b/src/lib/library/trackEnrichment.ts @@ -5,7 +5,7 @@ import { topDistinctOximediaMoodTagIds, topDistinctOximediaMoodTagIdsFromValenceArousal, moodScoresFromValenceArousal, -} from '../../config/moodGroups'; +} from '@/config/moodGroups'; /** Oximedia mood labels in queue/Song Info — off until a reliable model ships. */ export const OXIMEDIA_MOOD_UI_ENABLED = false; @@ -15,7 +15,7 @@ export const OXIMEDIA_ENRICHMENT_SOURCE_KIND = 'analysis'; export const OXIMEDIA_ENRICHMENT_SOURCE_ID = 'oximedia-60s-center'; /** Oximedia mood label ids — see `src/config/moodGroups.ts` and Rust `mood_groups`. */ -export type { OximediaMoodTagId } from '../../config/moodGroups'; +export type { OximediaMoodTagId } from '@/config/moodGroups'; export interface ParsedTrackEnrichment { serverBpm: number | null; @@ -115,7 +115,7 @@ export function deriveMoodScores(valence: number, arousal: number): Record { beforeEach(() => { diff --git a/src/store/analysisStrategyStore.ts b/src/store/analysisStrategyStore.ts index e07c4772..ef74aafe 100644 --- a/src/store/analysisStrategyStore.ts +++ b/src/store/analysisStrategyStore.ts @@ -5,7 +5,7 @@ import { DEFAULT_ADVANCED_PARALLELISM, DEFAULT_ANALYTICS_STRATEGY, type AnalyticsStrategy, -} from '../utils/library/analysisStrategy'; +} from '@/lib/library/analysisStrategy'; import { useAuthStore } from './authStore'; import { serverIndexKeyFromUrl } from '../utils/server/serverIndexKey'; import type { ServerProfile } from './authStoreTypes'; diff --git a/src/store/coverStrategyStore.ts b/src/store/coverStrategyStore.ts index 2eace02a..3faa594d 100644 --- a/src/store/coverStrategyStore.ts +++ b/src/store/coverStrategyStore.ts @@ -4,7 +4,7 @@ import { DEFAULT_COVER_CACHE_STRATEGY, coverStrategyFromLegacyPrefetch, type CoverCacheStrategy, -} from '../utils/library/coverStrategy'; +} from '@/lib/library/coverStrategy'; import { useAuthStore } from './authStore'; import { serverIndexKeyFromUrl } from '../utils/server/serverIndexKey'; import type { ServerProfile } from './authStoreTypes'; diff --git a/src/utils/queue/timelineBootstrapReady.test.ts b/src/utils/queue/timelineBootstrapReady.test.ts index 0b2531b2..5f527aec 100644 --- a/src/utils/queue/timelineBootstrapReady.test.ts +++ b/src/utils/queue/timelineBootstrapReady.test.ts @@ -3,11 +3,11 @@ import { useAuthStore } from '../../store/authStore'; import { useLibraryIndexStore } from '../../store/libraryIndexStore'; import { timelineBootstrapIndexReady } from './timelineBootstrapReady'; -vi.mock('../library/libraryReady', () => ({ +vi.mock('@/lib/library/libraryReady', () => ({ libraryIsReady: vi.fn(), })); -import { libraryIsReady } from '../library/libraryReady'; +import { libraryIsReady } from '@/lib/library/libraryReady'; describe('timelineBootstrapIndexReady', () => { beforeEach(() => { diff --git a/src/utils/queue/timelineBootstrapReady.ts b/src/utils/queue/timelineBootstrapReady.ts index 4d42deec..c1856846 100644 --- a/src/utils/queue/timelineBootstrapReady.ts +++ b/src/utils/queue/timelineBootstrapReady.ts @@ -1,6 +1,6 @@ import { useAuthStore } from '../../store/authStore'; import { useLibraryIndexStore } from '../../store/libraryIndexStore'; -import { libraryIsReady } from '../library/libraryReady'; +import { libraryIsReady } from '@/lib/library/libraryReady'; /** * Timeline cold bootstrap reads local `play_session` (cross-server). Gate on at