Files
yellowjacket/frontend/bindings/yellowjacket/backend/library/library.ts
T
logan 4bf59b45b7 feat(library): answer album completeness for a screenful in one query
A card grid has to know how much of an album is here — an album held 2
tracks of 10 wearing the same green tick as one held whole is the
complaint the badge-accuracy work was filed about — and
`GetAlbumCompleteness` is one query per album, which is fifty round
trips for a grid of fifty.

`GetAlbumsCompleteness` is the same question over a slice. It is two
grouping levels rather than the single-album form's correlated
subqueries, because a correlated subquery in the FROM clause is not
something SQLite will reliably do, and because the slice may only be
spelled once or sqlc expands it twice with independently numbered
placeholders.

An album with no files is absent from the result rather than zeroed:
"I have none of this" and "I have no idea" are the third state `Known`
exists to keep apart.

The test that matters is that the two spellings never disagree — they
are genuinely different SQL, so the risk is a drift in meaning (a
disc's total counted once per file, a duplicate counted twice) rather
than a typo.
2026-08-19 00:37:46 -04:00

348 lines
12 KiB
TypeScript

// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT
/**
* Library manages scanning and querying the music collection.
* @module
*/
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports
import { Call as $Call, CancellablePromise as $CancellablePromise } from "@wailsio/runtime";
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports
import * as sqlcgen$0 from "../database/sql/sqlcgen/models.js";
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports
import * as $models from "./models.js";
/**
* AddLibrary creates a new library from a directory path, emits a
* LibraryAdded event, and starts an asynchronous scan.
*/
export function AddLibrary(path: string): $CancellablePromise<sqlcgen$0.Library | null> {
return $Call.ByID(4258719739, path);
}
/**
* CancelAllScans cancels the current scan and clears the entire
* queue so no further libraries are scanned.
*/
export function CancelAllScans(): $CancellablePromise<void> {
return $Call.ByID(2826471660);
}
/**
* CancelCurrentScan cancels only the currently scanning library.
* The next queued library (if any) starts automatically when the
* current scan's goroutine completes.
*/
export function CancelCurrentScan(): $CancellablePromise<void> {
return $Call.ByID(2190880081);
}
/**
* CancelScan cancels an in-progress scan. Returns immediately;
* scan goroutines stop at their next checkpoint.
*
* Deprecated: Use CancelCurrentScan or CancelAllScans for
* queue-aware cancellation.
*/
export function CancelScan(): $CancellablePromise<void> {
return $Call.ByID(4160132270);
}
/**
* FullRescan clears the queue and player, wipes all library data
* (database records and cover art files), and performs a fresh
* scan of every library in the database. The returned ScanMetrics
* reflects the last library scanned; clear-phase durations are
* folded into its totals.
*/
export function FullRescan(): $CancellablePromise<$models.ScanMetrics | null> {
return $Call.ByID(378891236);
}
/**
* GetAlbumCompleteness answers "do I have all of this album" from the
* tags read at scan time, with no network.
*
* Complete is deliberately >= rather than ==: bonus and hidden tracks
* routinely put a folder over its declared total, and that is a
* complete album, not a broken one.
*/
export function GetAlbumCompleteness(albumID: number): $CancellablePromise<$models.AlbumCompleteness> {
return $Call.ByID(2895787150, albumID);
}
/**
* GetAlbumTracks returns one album's tracks in disc/track order.
*/
export function GetAlbumTracks(albumID: number, libraryID: number): $CancellablePromise<$models.Track[] | null> {
return $Call.ByID(300451334, albumID, libraryID);
}
/**
* GetAlbums returns every album, or those with a file in one library.
*/
export function GetAlbums(libraryID: number): $CancellablePromise<$models.Album[] | null> {
return $Call.ByID(2870789667, libraryID);
}
/**
* GetAlbumsByArtist returns the albums credited to an artist by name.
*/
export function GetAlbumsByArtist(artist: string, libraryID: number): $CancellablePromise<$models.Album[] | null> {
return $Call.ByID(1456840721, artist, libraryID);
}
/**
* GetAlbumsCompleteness answers the same question for a screenful of
* albums in one query, keyed by album id.
*
* A card grid asks this about every card that has a local album behind
* it, and one query per card is how a grid of fifty albums becomes
* fifty round trips. The answer matters there for the reason it
* matters on the album page: an album held 9 tracks of 12 has to show
* the count, and a bare tick saying "in your library" is the complaint
* this whole rule came from.
*
* An album with no row in the result is one with no files, and it is
* absent rather than zeroed — "I have none of this" and "I have no
* idea" are the same third state `Known` exists to keep apart, and a
* caller reading a missing key gets nothing rather than a confident 0.
*/
export function GetAlbumsCompleteness(albumIDs: number[] | null): $CancellablePromise<{ [_ in `${number}`]?: $models.AlbumCompleteness } | null> {
return $Call.ByID(531636827, albumIDs);
}
/**
* GetAllLibrariesWithTrackCounts lists the libraries and their sizes.
*/
export function GetAllLibrariesWithTrackCounts(): $CancellablePromise<$models.Info[] | null> {
return $Call.ByID(3420301148);
}
/**
* GetArtists returns the album artists in a library.
*/
export function GetArtists(libraryID: number): $CancellablePromise<$models.Artist[] | null> {
return $Call.ByID(2231116965, libraryID);
}
/**
* GetFilePathsByAlbums returns the file paths of every track in the
* given albums, grouped by album id.
*
* "Play this artist", "play these albums" and the album drag cache each
* resolved paths with one binding call per album, sequentially, and each
* asked for whole track rows to read one field off them (perf.m2). This
* is that question asked once. The result is grouped rather than
* flattened because the caller owns the ordering - an album list is
* sorted by name, not by id - and because the drag cache stores it per
* album.
*
* A library id of 0 means "every library", matching the caller's
* selected-library filter being unset.
*/
export function GetFilePathsByAlbums(albumIDs: number[] | null, libraryID: number): $CancellablePromise<{ [_ in `${number}`]?: string[] | null } | null> {
return $Call.ByID(1692993358, albumIDs, libraryID);
}
/**
* GetFilePathsByGenres returns file paths grouped by genre name.
*/
export function GetFilePathsByGenres(genreNames: string[] | null, libraryID: number): $CancellablePromise<{ [_ in string]?: string[] | null } | null> {
return $Call.ByID(1180707302, genreNames, libraryID);
}
/**
* GetFilePathsByRecordingMBIDs answers "which of these catalog
* recordings do I actually have a file for", grouped by MBID.
*
* It asks audio_files, which is the only table whose rows are files.
* The version of this question that asked the metadata tables said yes
* for 129 tracks in a real library that had no file at all - a
* retagged file left its old recording row behind, the catalog matched
* it, and every action on the row then failed.
*/
export function GetFilePathsByRecordingMBIDs(mbids: string[] | null, libraryID: number): $CancellablePromise<{ [_ in string]?: string[] | null } | null> {
return $Call.ByID(2789061644, mbids, libraryID);
}
/**
* GetGenres returns every genre with its track count.
*/
export function GetGenres(libraryID: number): $CancellablePromise<$models.GenreWithCount[] | null> {
return $Call.ByID(2817241511, libraryID);
}
/**
* GetRemovalImpact returns pre-removal counts for the confirmation
* dialog. All queries are read-only.
*/
export function GetRemovalImpact(libraryID: number): $CancellablePromise<$models.RemovalImpact | null> {
return $Call.ByID(2715588999, libraryID);
}
/**
* GetScanQueueLength returns the number of libraries waiting in the
* scan queue (excludes the currently scanning library).
*/
export function GetScanQueueLength(): $CancellablePromise<number> {
return $Call.ByID(2739382973);
}
/**
* GetTrackMBIDs returns the MusicBrainz ids for one file.
*/
export function GetTrackMBIDs(filePath: string): $CancellablePromise<$models.TrackMBIDs> {
return $Call.ByID(56752473, filePath);
}
/**
* GetTracks returns every track in a library, or in all of them when
* libraryID is 0.
*
* The library id is a parameter rather than a second method because the
* two used to be separate queries, separate bindings and a branch at
* every call site - and the scoped form costs nothing (measured: 23 ms
* against 21 ms over 26k rows).
*/
export function GetTracks(libraryID: number): $CancellablePromise<$models.Track[] | null> {
return $Call.ByID(933082923, libraryID);
}
/**
* GetTracksByGenre returns every track carrying a genre.
*/
export function GetTracksByGenre(genre: string, libraryID: number): $CancellablePromise<$models.Track[] | null> {
return $Call.ByID(1674220245, genre, libraryID);
}
/**
* IsScanActive returns whether a scan is currently running.
*/
export function IsScanActive(): $CancellablePromise<boolean> {
return $Call.ByID(1365062070);
}
/**
* IsScanPaused returns whether the scan is currently paused.
*/
export function IsScanPaused(): $CancellablePromise<boolean> {
return $Call.ByID(2930130958);
}
/**
* LibraryPath resolves a library's root directory by id.
*/
export function LibraryPath(id: number): $CancellablePromise<string> {
return $Call.ByID(1798172787, id);
}
/**
* PauseScan pauses an in-progress scan. Workers block at their
* next pause checkpoint until ResumeScan is called.
*/
export function PauseScan(): $CancellablePromise<void> {
return $Call.ByID(3522392788);
}
/**
* QueuedLibraryNames returns the display names of libraries waiting
* in the scan queue, in FIFO order.
*/
export function QueuedLibraryNames(): $CancellablePromise<string[] | null> {
return $Call.ByID(2036951097);
}
/**
* RemoveFromLibrary deletes the database rows for the given file paths
* and records each path as excluded, so the next scan does not import
* it again. **It does not touch the files on disk** — that is the
* promise the confirmation dialog makes, and the reason this operation
* is safe to put one keystroke from a focused row.
*
* The exclusion is not an enhancement. Without it the next scan finds
* the file, sees no row, and imports it again — a button that undoes
* itself, which is worse than no button.
*/
export function RemoveFromLibrary(filePaths: string[] | null): $CancellablePromise<$models.RemovalResult | null> {
return $Call.ByID(825509452, filePaths);
}
/**
* RemoveLibrary atomically removes a library and all its data,
* performing orphan cleanup, phantom metadata conversion, FTS5
* rebuild, and queue compaction. Returns a summary of what was removed.
*/
export function RemoveLibrary(id: number): $CancellablePromise<$models.RemovalSummary | null> {
return $Call.ByID(4110443412, id);
}
/**
* RenameLibrary validates and updates a library's display name.
*/
export function RenameLibrary(id: number, newName: string): $CancellablePromise<void> {
return $Call.ByID(3949052986, id, newName);
}
/**
* RestorePausedScans adopts scans that were paused when the app last
* shut down back into the job registry, still paused. Call during
* startup before SoftScanAllLibraries so the soft scan does not restart
* a library the user deliberately paused.
*/
export function RestorePausedScans(): $CancellablePromise<void> {
return $Call.ByID(4243712755);
}
/**
* ResumeScan unblocks a paused scan.
*/
export function ResumeScan(): $CancellablePromise<void> {
return $Call.ByID(3079702539);
}
/**
* ScanAllLibraries queries all libraries from the database and queues
* each one for scanning. Existing dedup logic ensures no duplicates.
*/
export function ScanAllLibraries(): $CancellablePromise<void> {
return $Call.ByID(266098306);
}
/**
* ScanLibrary queues a scan for the library with the given database ID.
* If no scan is active the library is scanned immediately; otherwise it
* is appended to the queue. Duplicate requests (same library already
* scanning or already queued) are silently ignored.
*/
export function ScanLibrary(id: number): $CancellablePromise<void> {
return $Call.ByID(2994459743, id);
}
/**
* SearchTracks runs the library's FTS index and returns whole tracks.
*/
export function SearchTracks(query: string, libraryID: number): $CancellablePromise<$models.Track[] | null> {
return $Call.ByID(3848515709, query, libraryID);
}
/**
* SoftScanAllLibraries performs a lightweight launch-time scan.
* First it claims any orphaned tracks (library_id=0) left over from
* the pre-multi-library schema. Then for each library it compares
* the number of audio files on disk against the track count in the
* database. Only libraries where the counts differ (files added or
* removed since last scan) are queued for a full scan. Libraries
* that are unchanged are silently skipped — no progress bar, no
* scan events.
*/
export function SoftScanAllLibraries(): $CancellablePromise<void> {
return $Call.ByID(1401473402);
}