feat(11-01): per-library scan pipeline with queue coordinator
Task 1: Schema, events, and progress types - Add library_id to CreateAudioFile SQL INSERT and regenerate sqlc code - Add LibraryScanQueued and LibraryScanQueueDrained event constants - Regenerate TypeScript events via genevents - Add LibraryID, LibraryName, QueuedCount to ScanProgress - Add LibraryID, LibraryName to ScanMetrics - Add libraryID field to importResult for threading through pipeline Task 2: Scan queue coordinator and per-library scanning - Create scan_queue.go with ScanLibrary(id), ScanAllLibraries() - Add CancelCurrentScan(), CancelAllScans() for queue-aware cancellation - FIFO scan queue with silent dedup (same library already scanning or queued) - Refactor Scan() -> scanInternal(libraryID, libraryName, libraryPath) - Replace GetAllAudioFiles with GetAudioFilesByLibrary for per-library loading - Thread libraryID through DB writer to set CreateAudioFileParams.LibraryID - drainQueue auto-starts next queued library or emits LibraryScanQueueDrained - Pause freezes current scan AND queue - Add GetScanQueueLength() and QueuedLibraryNames() for UI - Mark CancelScan() and Scan() as deprecated
This commit is contained in:
@@ -38,6 +38,10 @@ export const Events = {
|
||||
LibraryScanCancelled: "LibraryScanCancelled",
|
||||
LibraryScanPaused: "LibraryScanPaused",
|
||||
LibraryScanResumed: "LibraryScanResumed",
|
||||
|
||||
// Scan queue events
|
||||
LibraryScanQueued: "LibraryScanQueued",
|
||||
LibraryScanQueueDrained: "LibraryScanQueueDrained",
|
||||
} as const;
|
||||
|
||||
export type EventName = (typeof Events)[keyof typeof Events];
|
||||
|
||||
+12
@@ -3,6 +3,10 @@
|
||||
import {library} from '../models';
|
||||
import {context} from '../models';
|
||||
|
||||
export function CancelAllScans():Promise<void>;
|
||||
|
||||
export function CancelCurrentScan():Promise<void>;
|
||||
|
||||
export function CancelScan():Promise<void>;
|
||||
|
||||
export function FullRescan():Promise<library.ScanMetrics>;
|
||||
@@ -19,6 +23,8 @@ export function GetAllGenresWithCounts():Promise<Array<library.GenreWithCount>>;
|
||||
|
||||
export function GetAllTracks():Promise<Array<library.Track>>;
|
||||
|
||||
export function GetScanQueueLength():Promise<number>;
|
||||
|
||||
export function GetTracksByGenre(arg1:string):Promise<Array<library.Track>>;
|
||||
|
||||
export function IsScanActive():Promise<boolean>;
|
||||
@@ -27,10 +33,16 @@ export function IsScanPaused():Promise<boolean>;
|
||||
|
||||
export function PauseScan():Promise<void>;
|
||||
|
||||
export function QueuedLibraryNames():Promise<Array<string>>;
|
||||
|
||||
export function ResumeScan():Promise<void>;
|
||||
|
||||
export function Scan():Promise<library.ScanMetrics>;
|
||||
|
||||
export function ScanAllLibraries():Promise<void>;
|
||||
|
||||
export function ScanLibrary(arg1:number):Promise<void>;
|
||||
|
||||
export function SearchTracks(arg1:string):Promise<Array<library.Track>>;
|
||||
|
||||
export function SetContext(arg1:context.Context):Promise<void>;
|
||||
|
||||
@@ -2,6 +2,14 @@
|
||||
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
||||
// This file is automatically generated. DO NOT EDIT
|
||||
|
||||
export function CancelAllScans() {
|
||||
return window['go']['library']['Library']['CancelAllScans']();
|
||||
}
|
||||
|
||||
export function CancelCurrentScan() {
|
||||
return window['go']['library']['Library']['CancelCurrentScan']();
|
||||
}
|
||||
|
||||
export function CancelScan() {
|
||||
return window['go']['library']['Library']['CancelScan']();
|
||||
}
|
||||
@@ -34,6 +42,10 @@ export function GetAllTracks() {
|
||||
return window['go']['library']['Library']['GetAllTracks']();
|
||||
}
|
||||
|
||||
export function GetScanQueueLength() {
|
||||
return window['go']['library']['Library']['GetScanQueueLength']();
|
||||
}
|
||||
|
||||
export function GetTracksByGenre(arg1) {
|
||||
return window['go']['library']['Library']['GetTracksByGenre'](arg1);
|
||||
}
|
||||
@@ -50,6 +62,10 @@ export function PauseScan() {
|
||||
return window['go']['library']['Library']['PauseScan']();
|
||||
}
|
||||
|
||||
export function QueuedLibraryNames() {
|
||||
return window['go']['library']['Library']['QueuedLibraryNames']();
|
||||
}
|
||||
|
||||
export function ResumeScan() {
|
||||
return window['go']['library']['Library']['ResumeScan']();
|
||||
}
|
||||
@@ -58,6 +74,14 @@ export function Scan() {
|
||||
return window['go']['library']['Library']['Scan']();
|
||||
}
|
||||
|
||||
export function ScanAllLibraries() {
|
||||
return window['go']['library']['Library']['ScanAllLibraries']();
|
||||
}
|
||||
|
||||
export function ScanLibrary(arg1) {
|
||||
return window['go']['library']['Library']['ScanLibrary'](arg1);
|
||||
}
|
||||
|
||||
export function SearchTracks(arg1) {
|
||||
return window['go']['library']['Library']['SearchTracks'](arg1);
|
||||
}
|
||||
|
||||
@@ -109,6 +109,8 @@ export namespace library {
|
||||
skipped: number;
|
||||
removed: number;
|
||||
cancelled: boolean;
|
||||
libraryId: number;
|
||||
libraryName: string;
|
||||
warnings: ScanWarning[];
|
||||
|
||||
static createFrom(source: any = {}) {
|
||||
@@ -143,6 +145,8 @@ export namespace library {
|
||||
this.skipped = source["skipped"];
|
||||
this.removed = source["removed"];
|
||||
this.cancelled = source["cancelled"];
|
||||
this.libraryId = source["libraryId"];
|
||||
this.libraryName = source["libraryName"];
|
||||
this.warnings = this.convertValues(source["warnings"], ScanWarning);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user