* feat(analysis): align index settings and per-server strategies
Rebuild the local index UX to live under Servers with per-server analytics
strategies, and scope analysis queue hints/pruning by playback server so
priorities stay isolated across profiles.
* feat(analysis): add progress tracking and server analysis deletion functionality
Introduce new interfaces for tracking library analysis progress and reporting on server analysis deletions. Implement functions to retrieve analysis progress for a server and to delete all analysis data for a specified server, enhancing the analytics strategy section with real-time progress updates and management capabilities. Update relevant components and localization files to support these features.
* feat(server): implement server index key migration and enhance server ID resolution
Add functionality to migrate server index keys from legacy IDs to new URL-based keys, improving server ID resolution across the application. Introduce new types and commands for handling server key migrations in both analysis and library contexts. Update relevant functions to utilize the new server ID resolution logic, ensuring consistency and accuracy in server-related operations.
* refactor(library): simplify server ID handling in sync progress and idle subscriptions
Refactor the library sync progress and idle subscription functions to directly use the payload's server ID without additional mapping. Update related components to resolve server IDs using a new utility function, ensuring consistent server ID resolution across the application. This change enhances code clarity and maintains functionality.
* refactor(analytics): rename advanced strategy to aggressive and update descriptions
Refactor the AnalyticsStrategySection component to rename the 'advanced' strategy to 'aggressive' for clarity. Update related localization strings to reflect this change, enhancing the user experience by providing clearer descriptions of the analytics strategies. Additionally, remove unused strategy description functions to streamline the code.
* fix(audio): update server ID handling in audio progress functions
Refactor the audio progress handling to utilize the new `getPlaybackIndexKey` function for server ID resolution. This change ensures that the correct analysis server ID is used when processing audio progress, enhancing the accuracy of playback operations. Additionally, a minor update was made to the analysis cache to include a checkpoint after seeding from bytes. Update the library path in live search to reflect the new database structure.
* refactor(analysis): update server ID handling and drop legacy keys
Refactor server ID handling across analysis components to utilize scheme-less keys (host + optional path) instead of legacy scheme-based keys. Introduce SQL migrations to drop legacy analysis rows and library entries keyed by scheme URLs. Update relevant functions and tests to ensure consistent server ID resolution and remove references to the legacy '' scope, enhancing clarity and maintainability.
* refactor(migration): switch to strategy C dual-db flow
Replace destructive server-key migration paths with a blocking inspect/run pipeline that imports into v2 sqlite files, verifies data, then switches active databases with backup safety. Add frontend migration orchestration and post-switch key rewrites while preserving existing user settings behavior.
* fix(migration): harden runtime db switch and startup gate
Switch database promotion through live runtime store/cache connection swaps so migration cannot leave writers on old sqlite inodes, and tighten startup gating to block initialization until migration completes. Also fix empty-bucket warning detection and set the done flag only after a post-run inspect confirms no pending legacy rows.
* feat(migration): enhance migration reporting with skipped server rows tracking
Add new fields to migration interfaces and reports to track skipped rows for removed servers. Update relevant components to display warnings and log messages when such rows are encountered during migration processes, improving visibility and user awareness of migration status.
* fix(migration): avoid startup blocking modal on no-op runs
Keep migration gate completed by default after successful runs and perform done-flag inspections without forcing a blocking phase, so normal app startup no longer flashes migration preparation when no migration is needed.
* fix(migration): enforce startup precheck and purge unknown rows
Prevent stale done-flag bypass by starting migration state in idle and gating completion on orchestrator precheck, and delete unknown removed-server rows from v2 databases before switch so skipped rows are not carried into the new active DB.
* fix(migration): block UI during done-flag precheck
Set inspecting phase before the first migration inspection and treat idle as blocking in the migration gate, so startup precheck cannot render the app before migration status is confirmed.
* fix(migration): hide precheck modal when no migration is needed
Keep startup precheck in a non-blocking idle phase and show the migration modal only after inspect confirms real migration work, removing the recurring half-second migration flash for already-migrated users.
* fix(migration): cleanup legacy db files after path migration
Always remove legacy analysis and library sqlite files (including wal/shm sidecars) when the new database paths are active, so old-path artifacts from previous builds do not linger after migration.
* docs(changelog): add PR #864 release notes and contributor credit
Document the full index-key rebuild scope for 1.47.0 and add the
corresponding settings credit entry for PR #864.
* test(analysis): raise hot-path coverage for analysis cache
Add focused unit tests for analysis cache compute/store hot paths and edge branches so coverage regressions are caught before CI. Make AppHandle entrypoints runtime-generic and enable tauri test utilities in dev dependencies to cover no-cache and registered-cache execute paths.
* fix(migration): make rebind pass resilient to foreign key ordering
Run library and analysis server_id rebind operations inside a foreign-key-disabled transaction and validate with PRAGMA foreign_key_check after commit, so migrations from older databases do not fail on transient FK ordering during bulk updates.
* feat(backup): add dual-database backup flow and blocking UX
Extend backup/export and restore flows to handle library databases with unified archive detection and asynchronous backend execution. Improve backup UI with a global blocking modal and clearer localized copy so long operations do not look like app hangs.
* docs(changelog): add PR #864 backup notes and contributor credit
Update 1.47.0 release notes with backup/restore UX and archive-flow entries for PR #864, and add the matching settings credits contribution line for cucadmuh.
* docs(changelog): sort 1.47.0 entries from old to new
Reorder Added, Changed, and Fixed subsections in the 1.47.0 changelog so entries follow chronological PR order inside each block.
* fix(playback): align offline/hot cache lookup with indexKey scope
Use a canonical playback cache key based on indexKey with legacy UUID fallback so migrated offline and hot-cache entries are still resolved on normal play, resume, queue-undo, and prefetch paths. Refresh PR #864 changelog/credits text to reflect the full migration and backup scope.
* fix(playback): pin queue streams, cover art, and library links to queue server
When the active server changes while a queue from another server is playing,
keep streams and UI on queueServerId; switch back for artist/album links and
queue or player-bar context menus.
* fix(playback): switch to queue server when opening Now Playing
Ensure active server matches queueServerId before Subsonic fetches on the
Now Playing page, mobile player route, and queue info panel; scope caches
by server id.
* docs(credits): mention Now Playing in PR #717 contribution line
* fix(playback): route scrobble and queue sync to queue server
Address PR review: apiForServer for scrobble/now-playing/savePlayQueue,
clear queueServerId on server removal, mini-player queueServerId sync,
block cross-server enqueue with toast, and regression tests.
111 of 122 top-level src/utils/ files move into 16 topic folders (audio,
cache, cover, share, server, playback, playlist, deviceSync, waveform,
mix, format, export, changelog, ui, perf, componentHelpers). True
singletons with no cluster stay at the utils/ root.
Pure file-move: a path-aware codemod rewrote 539 relative-import
specifiers across 275 files; no logic touched. The hot-path coverage
gate list (.github/frontend-hot-path-files.txt) is updated to the new
paths for the 11 gated utils files — a mechanical consequence of the
move, not a CI change. tsc is green.
The prefetch worker / replan orchestration and its shared module state
(pendingQueue, workerRunning, debounceTimer, graceEvictTimer) stay
entirely untouched in hotCachePrefetch.ts. Extracted only what does not
touch that state:
- hotCachePrefetch/helpers.ts pure helpers — entryKey, byte
estimators, debounceMs, frontend
debug log, PREFETCH_AHEAD, PrefetchJob
- hotCachePrefetch/analysisPrune.ts self-contained analysis-queue prune
cluster (its own analysisPruneTimer +
lastAnalysisPruneSig state, fully
encapsulated behind a
resetAnalysisPruneState wrapper)
Verbatim moves. The orchestration core diff is import-block + the three
analysis-cleanup lines collapsing to resetAnalysisPruneState() — nothing
else. The MainApp call site imports initHotCachePrefetch unchanged.
Seven domain-eng splits peel ~200 LOC of read endpoints out of
`api/subsonic.ts`:
- `subsonicStreamUrl.ts` — `buildStreamUrl`, `coverArtCacheKey`,
`buildCoverArtUrl`, `buildDownloadUrl` (token-signed URL builders
for the four /rest endpoints we hand to the browser).
- `subsonicStarRating.ts` — `getStarred`, `star`, `unstar`,
`setRating`, `probeEntityRatingSupport`. `setRating` still triggers
the lazy `navidromeBrowse` cache invalidation; the same-folder
lazy import path is preserved.
- `subsonicSearch.ts` — `search`, `searchSongsPaged`.
- `subsonicScrobble.ts` — `scrobbleSong`, `reportNowPlaying`,
`getNowPlaying`.
- `subsonicAlbumInfo.ts` — `getAlbumInfo2`.
- `subsonicLyrics.ts` — `getLyricsBySongId`.
- `subsonicGenres.ts` — `getGenres`, `getAlbumsByGenre`.
63 external call sites migrated to direct imports. Four `vi.mock`
targets in the store-level tests pointed at `../api/subsonic` and
were updated to the new module paths.
Pure code-move. subsonic.ts: 762 → 561 LOC (−201).
Migrates ~74 call sites away from the playerStore re-export shims that
were kept during M0–E.41 to avoid touching 30+ imports per PR. Now
that the bigger refactor work is done, each helper goes back to its
real home:
- `initAudioListeners`, `installQueueUndoHotkey`, `flushPlayQueuePosition`
→ from their own store modules
- `getPlaybackProgressSnapshot`, `subscribePlaybackProgress`,
`PlaybackProgressSnapshot` → from `playbackProgress`
- `resolveReplayGainDb`, `shuffleArray`, `songToTrack`
→ from `utils/*`
- `_resetQueueUndoStacksForTest`, `consumePendingQueueListScrollTop`,
`registerQueueListScrollTopReader` → from `queueUndo`
- `PlayerState`, `Track` types → from `playerStoreTypes`
Drops the corresponding 13 re-export stubs from `playerStore.ts` and
the now-unused imports. Also drops dead section banners + per-wrapper
comments above one-line action delegates. Trims one stale "(separate
PR)" note in `transportLightActions.ts` since that follow-up landed
in E.39.
`playerStore.ts`: 180 → 112 LOC (−68). Down from Phase E's starting
3732 LOC.
`bootstrap.test.ts` mock target updated from `../store/playerStore`
to `../store/queueUndoHotkey` to keep the spy reachable after the
import change.
* fix(analysis): prune stale backfill jobs and limit prefetch window
Drop pending backfill and cpu-seed jobs that are no longer in the active playback queue, and add debug counters for pruned work. Limit loudness backfill scheduling to the current track plus the next five tracks to prevent runaway queue growth in dev sessions.
* chore(analysis): remove unused loudness prefetch parameter
Drop the now-unused incoming-tracks parameter from the loudness prefetch helper and update internal call sites to match the current queue-window scheduling logic.
* docs(changelog): document analysis queue control fix (#480)
Add a short 1.46.0 Fixed entry describing stale backfill pruning, the current+5 loudness backfill window cap, and debug prune counters for diagnostics.
* docs(contributors): add cucadmuh entry for PR #480
Logs the analysis-queue prune + loudness backfill window cap in the
Settings → System → Contributors list.
Serialize heavy PCM seeding through a dedicated queue with optional priority
for the current track. Emit waveform-updated once per completed seed, fix
Lucky Mix waveform refresh tokens, redact Subsonic URLs in logs, and align
hot-cache prefetch with the queued path.
Small fix for hot playback cache: eviction keeps current and next only;
prefetch up to five tracks when under cap, always fetch the immediate next;
grace for the previous current until debounce; run evict immediately on
MB or folder changes; re-read cap after download; optional Track.size;
live disk usage on Audio settings.