Repository navigation
refactor(bot): split queueManipulation.ts into focused modules - #807
Conversation
Extract four focused modules from the 961-line hotspot: - trackNormalization.ts: normalizeTrackKey, normalizeText, genre family utilities - queueEditOps.ts: clearQueue, shuffleQueue, smartShuffleQueue, removeTrackFromQueue, moveTrackInQueue, extractSpotifyTrackId, markAsAutoplayTrack, moveUserTrackToPriority, blendAutoplayTracks - candidateFallback.ts: collectBroadFallbackCandidates, collectGenreCandidates, enrichWithAudioFeatures, interleaveByArtist, CandidateContext - queueRescue.ts: rescueQueue, buildVcContributionWeights, getHistoryTracks, QueueRescueResult, RescueQueueOptions queueManipulation.ts becomes a thin barrel (~90 LOC) that re-exports everything plus retains getTrackAudioFeatures. All existing exports preserved for backward compatibility. 2865 tests pass, tsc --noEmit clean.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Warning Rate limit exceeded
To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (8)
📝 WalkthroughWalkthroughThis PR refactors and expands the music autoplay and queue-management system by introducing four new modular utilities—track normalization, queue operations, queue rescue, and candidate fallback collection—while converting the main ChangesMusic Autoplay & Queue System Reorganization
Sequence DiagramssequenceDiagram
participant Client
participant Queue as discord-player Queue
participant Spotify
participant LastFm as Last.fm
participant Cache as Audio Feature Cache
rect rgba(220, 100, 100, 0.5)
Note over Client,Cache: Broad Fallback Candidate Collection
Client->>Spotify: Search by current artist
Spotify-->>Client: Results filtered by duration & dislike threshold
Client->>Client: Compute recommendation score
Client->>Queue: Upsert candidates with "artist fallback" reason
end
rect rgba(100, 150, 220, 0.5)
Note over Client,Cache: Genre Candidate Collection
Client->>LastFm: Fetch top tags for seed tracks
LastFm-->>Client: Tag list (capped)
Client->>Spotify: Search top tracks per genre tag
Spotify-->>Client: Results
Client->>Queue: Add genre-derived candidates with boost
end
rect rgba(100, 220, 100, 0.5)
Note over Client,Cache: Audio Feature Enrichment
Client->>Spotify: Request access token
Spotify-->>Client: Token
Client->>Spotify: Batch fetch audio features by Spotify track ID
Spotify-->>Cache: Store energy, valence, popularity
Client->>Client: Adjust candidate scores by feature deltas & genre family penalty
Client->>Queue: Update candidates sorted by descending score
end
sequenceDiagram
participant Client
participant Queue as discord-player Queue
participant SearchEngine
participant Replenish
rect rgba(180, 140, 220, 0.5)
Note over Client,Replenish: Queue Rescue & Repair
Client->>Queue: Filter tracks with url, title, author
alt Optional Probing
Client->>SearchEngine: Probe resolvability with timeout
SearchEngine-->>Client: Success or timeout
end
Client->>Queue: Clear queue
Client->>Queue: Re-add kept tracks
alt Below Refill Threshold & Current Track Exists
Client->>Replenish: Call replenishQueue(queue)
Replenish->>Queue: Add candidates until full
end
Client-->>Client: Return removed/kept/added counts
end
sequenceDiagram
participant User
participant Queue as discord-player Queue
participant Autoplay as Autoplay System
rect rgba(220, 180, 100, 0.5)
Note over User,Autoplay: Autoplay Track Priority Management
User->>Queue: Append track to queue
Autoplay->>Queue: Mark track with metadata (isAutoplay, reason)
alt moveUserTrackToPriority Invoked
Autoplay->>Queue: Find user track by URL
Autoplay->>Queue: Determine first autoplay position
Autoplay->>Queue: Remove user track & re-insert at priority
end
Autoplay->>Queue: Query queue state
alt blendAutoplayTracks Invoked
Autoplay->>Queue: Filter autoplay tracks by blendRatio
Autoplay->>Queue: Remove excess autoplay tracks
Autoplay->>Queue: Replenish queue with new candidates
end
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~50 minutes Possibly related PRs
Suggested labels
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/bot/src/utils/music/candidateFallback.ts`:
- Around line 151-162: The genre fallback loop currently lets exceptions from
getTagTopTracks and searchLastFmQuery abort the whole pass; wrap the call to
getTagTopTracks(tag, ...) in a try/catch and, on error, log/debug the failure
and continue to the next tag, and likewise wrap each searchLastFmQuery(...) call
in its own try/catch so a failed search skips that seed and continues adding
other candidates via addGenreTrackCandidate(track, tag, ctx); ensure the catches
do not rethrow and preserve the existing flow that checks ctx.candidates size.
- Around line 94-142: The loop over fallbackQueries currently returns early when
any query yields candidates (the `if (candidates.size > 0) return`), which
prevents later queries like the "artist popular" fallback from running and
underfills the buffer; remove that early return and instead let the loop
continue collecting candidates from all fallback queries (or replace the return
with a proper cap check such as stopping only when candidates.size reaches the
intended buffer/capacity like SEARCH_RESULTS_LIMIT or your configured fallback
buffer size), so update the code around the `for (const query of
fallbackQueries)` loop and the `candidates` collection logic to accumulate
across queries rather than exiting on the first non-empty result.
In `@packages/bot/src/utils/music/queueEditOps.ts`:
- Around line 214-250: The code finds the queued item by URL (tracks and
trackIndex) but calls queue.node.remove(track) and later reinserts the caller's
track; replace uses of the caller's track with the actual queued item
(tracks[trackIndex]) for removal and when re-adding/ inserting (use the
matchedQueueItem / tracks[trackIndex] for remove, queue.addTrack and
queue.insertTrack) so instance identity matches the queue's stored Track; ensure
remaining/newFirstAutoplayIndex logic continues to operate on
queue.tracks.toArray() as shown.
In `@packages/bot/src/utils/music/trackNormalization.ts`:
- Around line 20-24: normalizeText() currently strips all non-ASCII chars which
collapses accented and non-Latin names into the same key; update normalizeText
(used by normalizeTrackKey) to preserve Unicode letters/numbers and normalize
Unicode form: first call value?.normalize('NFKC') (or 'NFC'), then use
toLowerCase(), and replace runs of characters that are not Unicode letters or
numbers using a Unicode-aware regex like /[^\p{L}\p{N}]+/gu to remove only
punctuation/whitespace while keeping accented and non-Latin scripts; keep the
final .trim() so dedupe/like/dislike and audio-feature caching work correctly.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 2c244ad4-110d-400f-84b6-054392c14a47
📒 Files selected for processing (5)
packages/bot/src/utils/music/candidateFallback.tspackages/bot/src/utils/music/queueEditOps.tspackages/bot/src/utils/music/queueManipulation.tspackages/bot/src/utils/music/queueRescue.tspackages/bot/src/utils/music/trackNormalization.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Quality Gates
- GitHub Check: SonarCloud Scan
Covers trackNormalization, queueEditOps, queueRescue, candidateFallback (84 new tests) to satisfy SonarCloud new-code coverage gate on PR #807.
…dates tests and enrichWithAudioFeatures branch coverage
…ks and continue paths Adds 5 new tests to reach full coverage on the uncovered lines: - line 115: continue in collectBroadFallbackCandidates when shouldIncludeCandidate=false - line 176: catch(() => null) when getValidAccessToken throws - line 201: catch(() => []) when getArtistGenres throws for currentArtistName - line 224: catch(() => []) when getArtistGenres throws per-track
…y, unicode normalization
- candidateFallback: remove early-return that prevented artist-popular fallback
from running; wrap getTagTopTracks/searchLastFmQuery in per-seed try/catch so
a single failed seed skips rather than aborting the whole genre pass
- queueEditOps: use tracks[trackIndex] (queue-resident instance) instead of the
caller's track reference for remove/addTrack/insertTrack in moveUserTrackToPriority
- trackNormalization: normalizeText now calls .normalize('NFKC') and uses
Unicode-aware /[^\p{L}\p{N}]+/gu so accented and non-Latin scripts are
preserved instead of collapsed; update spec accordingly
All 4 issues addressed in commit ad04343
|
* refactor(bot): split queueManipulation.ts (961 LOC) into focused modules Extract four focused modules from the 961-line hotspot: - trackNormalization.ts: normalizeTrackKey, normalizeText, genre family utilities - queueEditOps.ts: clearQueue, shuffleQueue, smartShuffleQueue, removeTrackFromQueue, moveTrackInQueue, extractSpotifyTrackId, markAsAutoplayTrack, moveUserTrackToPriority, blendAutoplayTracks - candidateFallback.ts: collectBroadFallbackCandidates, collectGenreCandidates, enrichWithAudioFeatures, interleaveByArtist, CandidateContext - queueRescue.ts: rescueQueue, buildVcContributionWeights, getHistoryTracks, QueueRescueResult, RescueQueueOptions queueManipulation.ts becomes a thin barrel (~90 LOC) that re-exports everything plus retains getTrackAudioFeatures. All existing exports preserved for backward compatibility. 2865 tests pass, tsc --noEmit clean. * test(bot): add specs for queueManipulation refactor modules Covers trackNormalization, queueEditOps, queueRescue, candidateFallback (84 new tests) to satisfy SonarCloud new-code coverage gate on PR #807. * test(bot): improve candidateFallback coverage — add collectGenreCandidates tests and enrichWithAudioFeatures branch coverage * test(bot): cover remaining candidateFallback branches — catch callbacks and continue paths Adds 5 new tests to reach full coverage on the uncovered lines: - line 115: continue in collectBroadFallbackCandidates when shouldIncludeCandidate=false - line 176: catch(() => null) when getValidAccessToken throws - line 201: catch(() => []) when getArtistGenres throws for currentArtistName - line 224: catch(() => []) when getArtistGenres throws per-track * test(bot): fix branch coverage gaps in queueEditOps and queueRescue specs * chore: exclude split queueManipulation files from CPD analysis * fix: address CodeRabbit review — genre error isolation, queue identity, unicode normalization - candidateFallback: remove early-return that prevented artist-popular fallback from running; wrap getTagTopTracks/searchLastFmQuery in per-seed try/catch so a single failed seed skips rather than aborting the whole genre pass - queueEditOps: use tracks[trackIndex] (queue-resident instance) instead of the caller's track reference for remove/addTrack/insertTrack in moveUserTrackToPriority - trackNormalization: normalizeText now calls .normalize('NFKC') and uses Unicode-aware /[^\p{L}\p{N}]+/gu so accented and non-Latin scripts are preserved instead of collapsed; update spec accordingly



Summary
trackNormalization.ts—normalizeTrackKey,normalizeText, genre family penalty utilitiesqueueEditOps.ts—clearQueue,shuffleQueue,smartShuffleQueue,removeTrackFromQueue,moveTrackInQueue,extractSpotifyTrackId,markAsAutoplayTrack,moveUserTrackToPriority,blendAutoplayTrackscandidateFallback.ts—collectBroadFallbackCandidates,collectGenreCandidates,enrichWithAudioFeatures,interleaveByArtist,CandidateContextqueueRescue.ts—rescueQueue,buildVcContributionWeights,getHistoryTracks,QueueRescueResult,RescueQueueOptionsqueueManipulation.tsis now a pure re-export barrel plusgetTrackAudioFeatures— all existing public exports preserved for backward compatibilityTest plan
tsc --noEmit— zero errorsSummary by CodeRabbit
New Features