UNPKG

andrade-soulseek-downloader

Version:

Simple, safe Soulseek download library with built-in rate limiting to prevent bans

113 lines 4.38 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.TrackSelectionService = void 0; /** * Domain service for track selection and prioritization. * Implements quality-first download strategy with progressive fallback. */ class TrackSelectionService { /** * Groups tracks by bitrate for quality-tiered download attempts. * @param tracks - Array of available tracks * @returns Map of bitrate to tracks */ groupByBitrate(tracks) { const groups = new Map(); tracks.forEach(track => { const bitrate = track.getBitrate().getValue(); if (!groups.has(bitrate)) { groups.set(bitrate, []); } groups.get(bitrate).push(track); }); return groups; } /** * Sorts tracks by quality within a bitrate group. * Prioritizes slot availability, then quality score. * @param tracks - Tracks to sort * @returns Sorted tracks (best first) */ sortByQuality(tracks) { return [...tracks].sort((a, b) => { // First priority: available slots if (a.hasAvailableSlots() !== b.hasAvailableSlots()) { return a.hasAvailableSlots() ? -1 : 1; } // Second: quality score return b.calculateQualityScore() - a.calculateQualityScore(); }); } /** * @param groups - Bitrate groups map * @returns Bitrates sorted from highest to lowest */ getOrderedBitrates(groups) { return Array.from(groups.keys()).sort((a, b) => b - a); } /** * Selects best tracks using quality-first strategy. * @param tracks - All available tracks * @param maxPerBitrate - Max tracks to select per bitrate tier * @returns Ordered list of best tracks to attempt */ selectBestTracks(tracks, maxPerBitrate = 5) { const groups = this.groupByBitrate(tracks); const orderedBitrates = this.getOrderedBitrates(groups); const selected = []; for (const bitrate of orderedBitrates) { const tracksInGroup = groups.get(bitrate); const sorted = this.sortByQuality(tracksInGroup); selected.push(...sorted.slice(0, maxPerBitrate)); } return selected; } /** * Filters out tracks below minimum bitrate threshold. * @param tracks - Tracks to filter * @param minBitrate - Minimum acceptable bitrate * @returns Tracks meeting minimum quality */ filterByMinimumQuality(tracks, minBitrate) { return tracks.filter(track => track.getBitrate().getValue() >= minBitrate.getValue()); } /** * Filters out tracks above maximum bitrate threshold. * @param tracks - Tracks to filter * @param maxBitrate - Maximum acceptable bitrate * @returns Tracks not exceeding maximum quality */ filterByMaximumQuality(tracks, maxBitrate) { return tracks.filter(track => track.getBitrate().getValue() <= maxBitrate.getValue()); } /** * Filters tracks by bitrate range. * @param tracks - Tracks to filter * @param minBitrate - Minimum acceptable bitrate * @param maxBitrate - Maximum acceptable bitrate (optional) * @returns Tracks within quality range */ filterByQualityRange(tracks, minBitrate, maxBitrate) { let filtered = this.filterByMinimumQuality(tracks, minBitrate); if (maxBitrate) { filtered = this.filterByMaximumQuality(filtered, maxBitrate); } return filtered; } /** * Validates if track meets quality standards. * @param track - Track to validate * @param minBitrate - Minimum bitrate requirement * @param maxBitrate - Maximum bitrate requirement (optional) * @returns True if track meets all quality criteria */ meetsQualityStandards(track, minBitrate, maxBitrate) { const trackBitrate = track.getBitrate().getValue(); const meetsMinimum = trackBitrate >= minBitrate.getValue(); const meetsMaximum = !maxBitrate || trackBitrate <= maxBitrate.getValue(); const meetsMatchScore = track.getMatchScore() > 0.2; return meetsMinimum && meetsMaximum && meetsMatchScore; } } exports.TrackSelectionService = TrackSelectionService; //# sourceMappingURL=track-selection-service.js.map