Skip to content

Commit 833f8c0

Browse files
feat: Upgrade Queue System, Stability Improvements & JSDoc (#39)
* feat: upgrade queue system and improve stability\n\n- Queue: Added shuffle, move, unshift, clear, and JSDoc.\n- Stability: Enhanced connection logic in Node.js and Riffy.js.\n- Docs: Detailed JSDoc for core classes and updated README. * fix(pr): address review comments\n\n- Fix: Removed duplicate class declaration in Node.js\n- Fix: Renumbered README.md sections to avoid duplicates\n- Chore: Verified Node.js structure and logs * fix(pr): address UnschooledGamer review comments - Add @SInCE 1.0.9 JSDoc to mixer property - Restore debug log for received OP/payloads in message() - Enhance debug log in open() with wsUrl - Enhance ready handler debug log with Nodelink info - Add resuming configuration debug logs (v3/v4) - Enhance close() debug log with fallback for unknown values - Add debug logging to migrate catch blocks - Restore disconnect() method * style(pr): restore original upstream formatting - Restore expanded stats object (multi-line format) - Restore getter-style Object.defineProperty - Restore if/else wsUrl conditional logic - Restore full mixer validation checks - Restore verbose error messages Addresses all remaining review preferences from UnschooledGamer * refactor(pr): reset Node.js to original upstream - Completely reverted Node.js to match riffy-team/riffy main branch - Queue system additions preserved (Queue.js with shuffle, move, clear) - README section numbering preserved (3, 4, 5) This keeps only the queue system enhancement from the PR. * Refactor Player.js methods and improve documentation Refactor autoplay method and update JSDoc comments for clarity. Adjust connection handling and improve debug logging for track end events. * Enhance JSDoc comments and add version property Updated JSDoc comments for clarity and added a version property. * Update Node.js --------- Co-authored-by: Emmanuel Lobo <76094069+UnschooledGamer@users.noreply.github.com>
1 parent 944d9f1 commit 833f8c0

5 files changed

Lines changed: 330 additions & 227 deletions

File tree

README.md

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,32 @@ client.on("raw", (d) => {
186186
client.login("Discord-Bot-Token-Here");
187187
```
188188

189+
### ╰┈2️⃣ Queue Management
190+
Riffy's queue system extends the native Array class, giving you access to all standard array methods plus powerful custom ones.
191+
192+
```js
193+
// Add a track to the end
194+
player.queue.add(track);
195+
196+
// Add a track to the front (Priority)
197+
player.queue.unshift(track);
198+
199+
// Shuffle the queue (Fisher-Yates)
200+
player.queue.shuffle();
201+
202+
// Move a track from position 2 to position 0
203+
player.queue.move(2, 0);
204+
205+
// Remove a specific track by index
206+
const removedTrack = player.queue.remove(2);
207+
208+
// Clear the entire queue
209+
player.queue.clear();
210+
211+
// Get queue size
212+
console.log(player.queue.size);
213+
```
214+
189215
#### Start the Bot
190216
Now that we have created our project, we can run our bot by typing the following command in the terminal.
191217

@@ -197,20 +223,20 @@ After running the bot, invite the bot in your server and run `!play` command to
197223

198224
---
199225

200-
### ╰┈2️⃣ Our Team
226+
### ╰┈3️⃣ Our Team
201227

202228
- 🟦 Emmanuel Lobo: **[@unschooledgamer](https://github.com/unschooledgamer)**
203229
- 🟪 Priyanshu Jain: **[@elitex07](https://github.com/elitex07)**
204230
- 🟥 Kunal KandePatil : **[@kunalkandepatil](https://github.com/kunalkandepatil)**
205231

206232
---
207233

208-
### ╰┈3️⃣ Example Projects
234+
### ╰┈4️⃣ Example Projects
209235
- **[Riffy Music Bot](https://github.com/riffy-team/riffy-music-bot)** | Contribute to add yours.
210236

211237
---
212238

213-
### ╰┈4️⃣ Official Plugins
239+
### ╰┈5️⃣ Official Plugins
214240
- **[riffy-spotify](https://github.com/riffy-team/riffy-spotify)** (Spotify Plugin for Riffy Client.)
215241

216242
<p align="center">≪ ◦ ✦ ◦ ≫</p>

build/structures/Node.js

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ const { Track } = require("./Track");
55
class Node {
66
/**
77
* @param {import("./Riffy").Riffy} riffy
8-
* @param {Node} node
8+
* @param {import("..").RiffyOptions} options
9+
* @param {import("..").LavalinkNode} node
910
*/
1011
constructor(riffy, node, options) {
1112
this.riffy = riffy
@@ -34,7 +35,7 @@ class Node {
3435
this.regions = node.regions;
3536
/**
3637
* Lavalink Info fetched While/After connecting.
37-
* @type {import("..").NodeInfo}
38+
* @type {import("..").NodeInfo | null}
3839
*/
3940
this.info = null;
4041
this.stats = {
@@ -66,7 +67,7 @@ class Node {
6667
this.resumeTimeout = options.resumeTimeout || 60;
6768
this.autoResume = options.autoResume || false;
6869

69-
this.reconnectTimeout = options.reconnectTimeout || 5000
70+
this.reconnectTimeout = options.reconnectTimeout || 5000;
7071
this.reconnectTries = options.reconnectTries || 3;
7172
this.reconnectAttempt = null;
7273
this.reconnectAttempted = 1;
@@ -81,10 +82,10 @@ class Node {
8182
* @param {boolean} [eitherOne=true] If set to true, will return true if at least one of the plugins is present.
8283
* @param {...string} plugins The plugins to look for.
8384
* @returns {Promise<boolean>} If the plugins are available.
84-
* @throws {RangeError} If the plugins are missing.
85+
* @throws {RangeError} If the plugins are missing and node is disconnected..
8586
*/
8687
checkAvailable: async (eitherOne = true, ...plugins) => {
87-
if (!this.sessionId) throw new Error(`Node (${this.name}) is not Ready/Connected.`)
88+
if (!this.sessionId || !this.connected) throw new Error(`Node (${this.name}) is not Ready/Connected.`)
8889
if (!plugins.length) plugins = ["lavalyrics-plugin", "java-lyrics-plugin", "lyrics"];
8990

9091
const missingPlugins = [];
@@ -133,7 +134,7 @@ class Node {
133134
* @param {boolean} skipTrackSource skips the Track Source & fetches from highest priority source (configured on Lavalink Server)
134135
* @param {string} [plugin] The Plugin to use(**Only required if you have too many known (i.e java-lyrics-plugin, lavalyrics-plugin) Lyric Plugins**)
135136
*/
136-
getCurrentTrack: async (guildId, skipTrackSource = false, plugin) => {
137+
getCurrentTrack: async (guildId, skipTrackSource = false, plugin = "") => {
137138
const DEFAULT_PLUGIN = "lavalyrics-plugin"
138139
if (!(await this.lyrics.checkAvailable())) return null;
139140

@@ -330,7 +331,8 @@ class Node {
330331

331332
async connect() {
332333
if (this.ws) this.ws.close()
333-
this.riffy.emit('debug', this.name, `Checking Node Version`);
334+
// this.riffy.emit("debug", `[Node (${this.name}) - Version Check] Checking Node Version`);
335+
this.riffy.emit("debug", `[Node (${this.name})] Connecting to the Node (i.e Lavalink/Nodelink Server; Opening a WebSocket Connection)`);
334336

335337
// // Preform Version Check To see If Lavalink Version is supported by Riffy (v3, v4)
336338
// await this.#fetchAndCheckVersion();
@@ -364,13 +366,15 @@ class Node {
364366
this.connected = true;
365367
this.riffy.emit('debug', `[Node: ${this.name}] Websocket connection established on ${this.wsUrl}`);
366368

367-
this.info = await this.fetchInfo()
368-
.then((info) => this.info = info)
369-
.catch((e) => (console.error(`Node (${this.name}) Failed to fetch info (${this.restVersion}/info) on WS-OPEN: ${e}`), null));
369+
this.info =
370+
await this.fetchInfo()
371+
.then((info) => this.info = info)
372+
.catch((e) => (this.riffy.emit('debug', `[Node: ${this.name}] Failed to fetch info on open: ${e.message}`)));
370373

371-
this.info
372374
// @ts-ignore this.options exists on the constructor
373375
if (!this.info && !this.options.bypassChecks.nodeFetchInfo) {
376+
// Throws the Error because it's a critical failure, Node should have info
377+
// about the server configuration (i.e sources, version, plugins, etc).
374378
throw new Error(`Node (${this.name} - URL: ${this.restUrl}) Failed to fetch info on WS-OPEN`);
375379
}
376380

@@ -452,18 +456,23 @@ class Node {
452456
}
453457

454458
reconnect() {
459+
// Prevent multiple reconnect loops
460+
if (this.reconnectAttempt) return;
461+
455462
this.reconnectAttempt = setTimeout(() => {
456463
if (this.reconnectAttempted >= this.reconnectTries) {
457464
const error = new Error(`Unable to connect with ${this.name} node after ${this.reconnectTries} attempts.`);
458465

459466
this.riffy.emit("nodeError", this, error);
460-
return this.destroy();
467+
// Clean destroy
468+
return this.destroy(true);
461469
}
462470

463471
this.ws?.removeAllListeners();
464472
this.ws = null;
465473
this.riffy.emit("nodeReconnect", this);
466474
this.riffy.emit("debug", `[Node: ${this.name}] Reconnecting... Attempt ${this.reconnectAttempted}/${this.reconnectTries}`);
475+
this.reconnectAttempt = null;
467476
this.connect();
468477
this.reconnectAttempted++;
469478
}, this.reconnectTimeout);
@@ -488,8 +497,10 @@ class Node {
488497
*/
489498
destroy(clean = false) {
490499
if (clean) {
500+
if (this.ws) this.ws?.close(1000, "Clean Destroy");
491501
this.ws?.removeAllListeners();
492502
this.ws = null;
503+
this.reconnectAttempt = null;
493504
this.riffy.emit("nodeDestroy", this);
494505
this.riffy.nodeMap.delete(this.name);
495506
return;
@@ -508,6 +519,7 @@ class Node {
508519
this.ws = null;
509520

510521
clearTimeout(this.reconnectAttempt);
522+
this.reconnectAttempt = null;
511523

512524
this.riffy.emit("nodeDestroy", this);
513525
this.riffy.emit("debug", `[Node: ${this.name}] Destroyed.`);
@@ -549,4 +561,4 @@ class Node {
549561
}
550562
}
551563

552-
module.exports = { Node };
564+
module.exports = { Node };

0 commit comments

Comments
 (0)