lavalink-client 2.4.5 → 2.4.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -808,3 +808,14 @@ if(previousTrack) {
808
808
  - Added the try to play the next track if there is no current track
809
809
  - *There was a problem trying to auto-reconnect on-Disconnect while the queue was empty, which caused the player to get destroyed by that and log the error in console "`There is no Track in the Queue, nor provided in the PlayOptions`"*
810
810
  - *Now you have to handle that case manually if you want to or set autoReconnectOnlyWithTracks to false (default)*
811
+
812
+
813
+ ## **Version 2.4.4 - Version 2.4.6**
814
+ - `player.changeNode()` is fixed and works - thanks to @PandaIN95
815
+ - The code got re-formatted and re-structured, no code-changes are needed to be made, but it's now cleaner & more readable in some areas
816
+ - The same for the testbot Folder(s), also it imports lavalink-client directly, so you can just copy it and move on from it.
817
+ - Some minor Fixess:
818
+ - Autoplay sometimes doesn't get called when previousAutoplay call failed.
819
+ - remove structuredClone so that it works in bun more stable
820
+ - Player Options Validation also allows single property objects
821
+ - Some typos were fixed
@@ -49,6 +49,8 @@ export declare enum DestroyReasons {
49
49
  NodeReconnectFail = "NodeReconnectFail",
50
50
  Disconnected = "Disconnected",
51
51
  PlayerReconnectFail = "PlayerReconnectFail",
52
+ PlayerChangeNodeFail = "PlayerChangeNodeFail",
53
+ PlayerChangeNodeFailNoEligibleNode = "PlayerChangeNodeFailNoEligibleNode",
52
54
  ChannelDeleted = "ChannelDeleted",
53
55
  DisconnectAllNodes = "DisconnectAllNodes",
54
56
  ReconnectAllNodes = "ReconnectAllNodes",
@@ -53,6 +53,8 @@ var DestroyReasons;
53
53
  DestroyReasons["NodeReconnectFail"] = "NodeReconnectFail";
54
54
  DestroyReasons["Disconnected"] = "Disconnected";
55
55
  DestroyReasons["PlayerReconnectFail"] = "PlayerReconnectFail";
56
+ DestroyReasons["PlayerChangeNodeFail"] = "PlayerChangeNodeFail";
57
+ DestroyReasons["PlayerChangeNodeFailNoEligibleNode"] = "PlayerChangeNodeFailNoEligibleNode";
56
58
  DestroyReasons["ChannelDeleted"] = "ChannelDeleted";
57
59
  DestroyReasons["DisconnectAllNodes"] = "DisconnectAllNodes";
58
60
  DestroyReasons["ReconnectAllNodes"] = "ReconnectAllNodes";
@@ -173,14 +173,20 @@ export declare class LavalinkNode {
173
173
  * Destroys the Node-Connection (Websocket) and all player's of the node
174
174
  * @param destroyReason Destroy Reason to use when destroying the players
175
175
  * @param deleteNode wether to delete the nodte from the nodes list too, if false it will emit a disconnect. @default true
176
+ * @param movePlayers whether to movePlayers to different eligible connected node. If false players won't be moved @default false
176
177
  * @returns void
177
178
  *
178
179
  * @example
180
+ * Destroys node and its players
179
181
  * ```ts
180
182
  * player.node.destroy("custom Player Destroy Reason", true);
181
183
  * ```
184
+ * destroys only the node and moves its players to different connected node.
185
+ * ```ts
186
+ * player.node.destroy("custom Player Destroy Reason", true, true);
187
+ * ```
182
188
  */
183
- destroy(destroyReason?: DestroyReasonsType, deleteNode?: boolean): void;
189
+ destroy(destroyReason?: DestroyReasonsType, deleteNode?: boolean, movePlayers?: boolean): void;
184
190
  /**
185
191
  * Disconnects the Node-Connection (Websocket)
186
192
  * @param disconnectReason Disconnect Reason to use when disconnecting Node
@@ -412,32 +412,94 @@ class LavalinkNode {
412
412
  * Destroys the Node-Connection (Websocket) and all player's of the node
413
413
  * @param destroyReason Destroy Reason to use when destroying the players
414
414
  * @param deleteNode wether to delete the nodte from the nodes list too, if false it will emit a disconnect. @default true
415
+ * @param movePlayers whether to movePlayers to different eligible connected node. If false players won't be moved @default false
415
416
  * @returns void
416
417
  *
417
418
  * @example
419
+ * Destroys node and its players
418
420
  * ```ts
419
421
  * player.node.destroy("custom Player Destroy Reason", true);
420
422
  * ```
423
+ * destroys only the node and moves its players to different connected node.
424
+ * ```ts
425
+ * player.node.destroy("custom Player Destroy Reason", true, true);
426
+ * ```
421
427
  */
422
- destroy(destroyReason, deleteNode = true) {
428
+ destroy(destroyReason, deleteNode = true, movePlayers = false) {
423
429
  if (!this.connected)
424
430
  return;
425
431
  const players = this.NodeManager.LavalinkManager.players.filter(p => p.node.id === this.id);
426
- if (players)
427
- players.forEach(p => {
428
- p.destroy(destroyReason || Constants_1.DestroyReasons.NodeDestroy);
432
+ if (players.size) {
433
+ const enableDebugEvents = this.NodeManager.LavalinkManager.options?.advancedOptions?.enableDebugEvents;
434
+ const handlePlayerOperations = () => {
435
+ if (movePlayers) {
436
+ const nodeToMove = Array.from(this.NodeManager.leastUsedNodes("playingPlayers"))
437
+ .find(n => n.connected && n.options.id !== this.id);
438
+ if (nodeToMove) {
439
+ return Promise.allSettled(Array.from(players.values()).map(player => player.changeNode(nodeToMove.options.id)
440
+ .catch(error => {
441
+ if (enableDebugEvents) {
442
+ console.error(`Node > destroy() Failed to move player ${player.guildId}: ${error.message}`);
443
+ }
444
+ return player.destroy(error.message ?? Constants_1.DestroyReasons.PlayerChangeNodeFail)
445
+ .catch(destroyError => {
446
+ if (enableDebugEvents) {
447
+ console.error(`Node > destroy() Failed to destroy player ${player.guildId} after move failure: ${destroyError.message}`);
448
+ }
449
+ });
450
+ })));
451
+ }
452
+ else {
453
+ return Promise.allSettled(Array.from(players.values()).map(player => player.destroy(Constants_1.DestroyReasons.PlayerChangeNodeFailNoEligibleNode)
454
+ .catch(error => {
455
+ if (enableDebugEvents) {
456
+ console.error(`Node > destroy() Failed to destroy player ${player.guildId}: ${error.message}`);
457
+ }
458
+ })));
459
+ }
460
+ }
461
+ else {
462
+ return Promise.allSettled(Array.from(players.values()).map(player => player.destroy(destroyReason || Constants_1.DestroyReasons.NodeDestroy)
463
+ .catch(error => {
464
+ if (enableDebugEvents) {
465
+ console.error(`Node > destroy() Failed to destroy player ${player.guildId}: ${error.message}`);
466
+ }
467
+ })));
468
+ }
469
+ };
470
+ // Handle all player operations first, then clean up the socket
471
+ handlePlayerOperations().finally(() => {
472
+ this.socket.close(1000, "Node-Destroy");
473
+ this.socket.removeAllListeners();
474
+ this.socket = null;
475
+ this.reconnectAttempts = 1;
476
+ clearTimeout(this.reconnectTimeout);
477
+ if (deleteNode) {
478
+ this.NodeManager.emit("destroy", this, destroyReason);
479
+ this.NodeManager.nodes.delete(this.id);
480
+ clearInterval(this.heartBeatInterval);
481
+ clearTimeout(this.pingTimeout);
482
+ }
483
+ else {
484
+ this.NodeManager.emit("disconnect", this, { code: 1000, reason: destroyReason });
485
+ }
429
486
  });
430
- this.socket.close(1000, "Node-Destroy");
431
- this.socket.removeAllListeners();
432
- this.socket = null;
433
- this.reconnectAttempts = 1;
434
- clearTimeout(this.reconnectTimeout);
435
- if (deleteNode) {
436
- this.NodeManager.emit("destroy", this, destroyReason);
437
- this.NodeManager.nodes.delete(this.id);
438
487
  }
439
- else {
440
- this.NodeManager.emit("disconnect", this, { code: 1000, reason: destroyReason });
488
+ else { // If no players, proceed with socket cleanup immediately
489
+ this.socket.close(1000, "Node-Destroy");
490
+ this.socket.removeAllListeners();
491
+ this.socket = null;
492
+ this.reconnectAttempts = 1;
493
+ clearTimeout(this.reconnectTimeout);
494
+ if (deleteNode) {
495
+ this.NodeManager.emit("destroy", this, destroyReason);
496
+ this.NodeManager.nodes.delete(this.id);
497
+ clearInterval(this.heartBeatInterval);
498
+ clearTimeout(this.pingTimeout);
499
+ }
500
+ else {
501
+ this.NodeManager.emit("disconnect", this, { code: 1000, reason: destroyReason });
502
+ }
441
503
  }
442
504
  return;
443
505
  }
@@ -692,9 +754,7 @@ class LavalinkNode {
692
754
  if (!this.info.plugins.find(v => v.name === "lavasrc-plugin") &&
693
755
  !this.info.plugins.find(v => v.name === "java-lyrics-plugin"))
694
756
  throw new RangeError(`there is no lyrics source (via lavasrc-plugin / java-lyrics-plugin) available in the lavalink node (required for lyrics): ${this.id}`);
695
- return await this.request(`/sessions/${this.sessionId}/players/${guildId}/lyrics/unsubscribe`, (options) => {
696
- options.method = "DELETE";
697
- });
757
+ return await this.request(`/sessions/${this.sessionId}/players/${guildId}/unsubscribe`);
698
758
  },
699
759
  };
700
760
  /**
@@ -966,8 +1026,11 @@ class LavalinkNode {
966
1026
  if (code === 1000 && reason === "Node-Disconnect")
967
1027
  return; // manually disconnected and already emitted the event.
968
1028
  this.NodeManager.emit("disconnect", this, { code, reason });
969
- if (code !== 1000 || reason !== "Node-Destroy")
970
- this.reconnect();
1029
+ if (code !== 1000 || reason !== "Node-Destroy") {
1030
+ if (this.NodeManager.nodes.has(this.id)) { // try to reconnect only when the node is still in the nodeManager.nodes list
1031
+ this.reconnect();
1032
+ }
1033
+ }
971
1034
  }
972
1035
  /** @private util function for handling error events from websocket */
973
1036
  error(error) {
@@ -83,7 +83,18 @@ export declare class NodeManager extends EventEmitter {
83
83
  /**
84
84
  * Delete a node from the nodeManager and destroy it
85
85
  * @param node The node to delete
86
+ * @param movePlayers whether to movePlayers to different connected node before deletion. @default false
86
87
  * @returns
88
+ *
89
+ * @example
90
+ * Deletes the node
91
+ * ```ts
92
+ * client.lavalink.nodeManager.deleteNode("nodeId to delete");
93
+ * ```
94
+ * Moves players to a different node before deleting
95
+ * ```ts
96
+ * client.lavalink.nodeManager.deleteNode("nodeId to delete", true);
97
+ * ```
87
98
  */
88
- deleteNode(node: LavalinkNodeIdentifier | LavalinkNode): void;
99
+ deleteNode(node: LavalinkNodeIdentifier | LavalinkNode, movePlayers?: boolean): void;
89
100
  }
@@ -196,13 +196,27 @@ class NodeManager extends events_1.EventEmitter {
196
196
  /**
197
197
  * Delete a node from the nodeManager and destroy it
198
198
  * @param node The node to delete
199
+ * @param movePlayers whether to movePlayers to different connected node before deletion. @default false
199
200
  * @returns
201
+ *
202
+ * @example
203
+ * Deletes the node
204
+ * ```ts
205
+ * client.lavalink.nodeManager.deleteNode("nodeId to delete");
206
+ * ```
207
+ * Moves players to a different node before deleting
208
+ * ```ts
209
+ * client.lavalink.nodeManager.deleteNode("nodeId to delete", true);
210
+ * ```
200
211
  */
201
- deleteNode(node) {
212
+ deleteNode(node, movePlayers = false) {
202
213
  const decodeNode = typeof node === "string" ? this.nodes.get(node) : node || this.leastUsedNodes()[0];
203
214
  if (!decodeNode)
204
215
  throw new Error("Node was not found");
205
- decodeNode.destroy(Constants_1.DestroyReasons.NodeDeleted);
216
+ if (movePlayers)
217
+ decodeNode.destroy(Constants_1.DestroyReasons.NodeDeleted, true, true);
218
+ else
219
+ decodeNode.destroy(Constants_1.DestroyReasons.NodeDeleted);
206
220
  this.nodes.delete(decodeNode.id);
207
221
  return;
208
222
  }
@@ -49,6 +49,8 @@ export declare enum DestroyReasons {
49
49
  NodeReconnectFail = "NodeReconnectFail",
50
50
  Disconnected = "Disconnected",
51
51
  PlayerReconnectFail = "PlayerReconnectFail",
52
+ PlayerChangeNodeFail = "PlayerChangeNodeFail",
53
+ PlayerChangeNodeFailNoEligibleNode = "PlayerChangeNodeFailNoEligibleNode",
52
54
  ChannelDeleted = "ChannelDeleted",
53
55
  DisconnectAllNodes = "DisconnectAllNodes",
54
56
  ReconnectAllNodes = "ReconnectAllNodes",
@@ -50,6 +50,8 @@ export var DestroyReasons;
50
50
  DestroyReasons["NodeReconnectFail"] = "NodeReconnectFail";
51
51
  DestroyReasons["Disconnected"] = "Disconnected";
52
52
  DestroyReasons["PlayerReconnectFail"] = "PlayerReconnectFail";
53
+ DestroyReasons["PlayerChangeNodeFail"] = "PlayerChangeNodeFail";
54
+ DestroyReasons["PlayerChangeNodeFailNoEligibleNode"] = "PlayerChangeNodeFailNoEligibleNode";
53
55
  DestroyReasons["ChannelDeleted"] = "ChannelDeleted";
54
56
  DestroyReasons["DisconnectAllNodes"] = "DisconnectAllNodes";
55
57
  DestroyReasons["ReconnectAllNodes"] = "ReconnectAllNodes";
@@ -173,14 +173,20 @@ export declare class LavalinkNode {
173
173
  * Destroys the Node-Connection (Websocket) and all player's of the node
174
174
  * @param destroyReason Destroy Reason to use when destroying the players
175
175
  * @param deleteNode wether to delete the nodte from the nodes list too, if false it will emit a disconnect. @default true
176
+ * @param movePlayers whether to movePlayers to different eligible connected node. If false players won't be moved @default false
176
177
  * @returns void
177
178
  *
178
179
  * @example
180
+ * Destroys node and its players
179
181
  * ```ts
180
182
  * player.node.destroy("custom Player Destroy Reason", true);
181
183
  * ```
184
+ * destroys only the node and moves its players to different connected node.
185
+ * ```ts
186
+ * player.node.destroy("custom Player Destroy Reason", true, true);
187
+ * ```
182
188
  */
183
- destroy(destroyReason?: DestroyReasonsType, deleteNode?: boolean): void;
189
+ destroy(destroyReason?: DestroyReasonsType, deleteNode?: boolean, movePlayers?: boolean): void;
184
190
  /**
185
191
  * Disconnects the Node-Connection (Websocket)
186
192
  * @param disconnectReason Disconnect Reason to use when disconnecting Node
@@ -408,32 +408,94 @@ export class LavalinkNode {
408
408
  * Destroys the Node-Connection (Websocket) and all player's of the node
409
409
  * @param destroyReason Destroy Reason to use when destroying the players
410
410
  * @param deleteNode wether to delete the nodte from the nodes list too, if false it will emit a disconnect. @default true
411
+ * @param movePlayers whether to movePlayers to different eligible connected node. If false players won't be moved @default false
411
412
  * @returns void
412
413
  *
413
414
  * @example
415
+ * Destroys node and its players
414
416
  * ```ts
415
417
  * player.node.destroy("custom Player Destroy Reason", true);
416
418
  * ```
419
+ * destroys only the node and moves its players to different connected node.
420
+ * ```ts
421
+ * player.node.destroy("custom Player Destroy Reason", true, true);
422
+ * ```
417
423
  */
418
- destroy(destroyReason, deleteNode = true) {
424
+ destroy(destroyReason, deleteNode = true, movePlayers = false) {
419
425
  if (!this.connected)
420
426
  return;
421
427
  const players = this.NodeManager.LavalinkManager.players.filter(p => p.node.id === this.id);
422
- if (players)
423
- players.forEach(p => {
424
- p.destroy(destroyReason || DestroyReasons.NodeDestroy);
428
+ if (players.size) {
429
+ const enableDebugEvents = this.NodeManager.LavalinkManager.options?.advancedOptions?.enableDebugEvents;
430
+ const handlePlayerOperations = () => {
431
+ if (movePlayers) {
432
+ const nodeToMove = Array.from(this.NodeManager.leastUsedNodes("playingPlayers"))
433
+ .find(n => n.connected && n.options.id !== this.id);
434
+ if (nodeToMove) {
435
+ return Promise.allSettled(Array.from(players.values()).map(player => player.changeNode(nodeToMove.options.id)
436
+ .catch(error => {
437
+ if (enableDebugEvents) {
438
+ console.error(`Node > destroy() Failed to move player ${player.guildId}: ${error.message}`);
439
+ }
440
+ return player.destroy(error.message ?? DestroyReasons.PlayerChangeNodeFail)
441
+ .catch(destroyError => {
442
+ if (enableDebugEvents) {
443
+ console.error(`Node > destroy() Failed to destroy player ${player.guildId} after move failure: ${destroyError.message}`);
444
+ }
445
+ });
446
+ })));
447
+ }
448
+ else {
449
+ return Promise.allSettled(Array.from(players.values()).map(player => player.destroy(DestroyReasons.PlayerChangeNodeFailNoEligibleNode)
450
+ .catch(error => {
451
+ if (enableDebugEvents) {
452
+ console.error(`Node > destroy() Failed to destroy player ${player.guildId}: ${error.message}`);
453
+ }
454
+ })));
455
+ }
456
+ }
457
+ else {
458
+ return Promise.allSettled(Array.from(players.values()).map(player => player.destroy(destroyReason || DestroyReasons.NodeDestroy)
459
+ .catch(error => {
460
+ if (enableDebugEvents) {
461
+ console.error(`Node > destroy() Failed to destroy player ${player.guildId}: ${error.message}`);
462
+ }
463
+ })));
464
+ }
465
+ };
466
+ // Handle all player operations first, then clean up the socket
467
+ handlePlayerOperations().finally(() => {
468
+ this.socket.close(1000, "Node-Destroy");
469
+ this.socket.removeAllListeners();
470
+ this.socket = null;
471
+ this.reconnectAttempts = 1;
472
+ clearTimeout(this.reconnectTimeout);
473
+ if (deleteNode) {
474
+ this.NodeManager.emit("destroy", this, destroyReason);
475
+ this.NodeManager.nodes.delete(this.id);
476
+ clearInterval(this.heartBeatInterval);
477
+ clearTimeout(this.pingTimeout);
478
+ }
479
+ else {
480
+ this.NodeManager.emit("disconnect", this, { code: 1000, reason: destroyReason });
481
+ }
425
482
  });
426
- this.socket.close(1000, "Node-Destroy");
427
- this.socket.removeAllListeners();
428
- this.socket = null;
429
- this.reconnectAttempts = 1;
430
- clearTimeout(this.reconnectTimeout);
431
- if (deleteNode) {
432
- this.NodeManager.emit("destroy", this, destroyReason);
433
- this.NodeManager.nodes.delete(this.id);
434
483
  }
435
- else {
436
- this.NodeManager.emit("disconnect", this, { code: 1000, reason: destroyReason });
484
+ else { // If no players, proceed with socket cleanup immediately
485
+ this.socket.close(1000, "Node-Destroy");
486
+ this.socket.removeAllListeners();
487
+ this.socket = null;
488
+ this.reconnectAttempts = 1;
489
+ clearTimeout(this.reconnectTimeout);
490
+ if (deleteNode) {
491
+ this.NodeManager.emit("destroy", this, destroyReason);
492
+ this.NodeManager.nodes.delete(this.id);
493
+ clearInterval(this.heartBeatInterval);
494
+ clearTimeout(this.pingTimeout);
495
+ }
496
+ else {
497
+ this.NodeManager.emit("disconnect", this, { code: 1000, reason: destroyReason });
498
+ }
437
499
  }
438
500
  return;
439
501
  }
@@ -688,9 +750,7 @@ export class LavalinkNode {
688
750
  if (!this.info.plugins.find(v => v.name === "lavasrc-plugin") &&
689
751
  !this.info.plugins.find(v => v.name === "java-lyrics-plugin"))
690
752
  throw new RangeError(`there is no lyrics source (via lavasrc-plugin / java-lyrics-plugin) available in the lavalink node (required for lyrics): ${this.id}`);
691
- return await this.request(`/sessions/${this.sessionId}/players/${guildId}/lyrics/unsubscribe`, (options) => {
692
- options.method = "DELETE";
693
- });
753
+ return await this.request(`/sessions/${this.sessionId}/players/${guildId}/unsubscribe`);
694
754
  },
695
755
  };
696
756
  /**
@@ -962,8 +1022,11 @@ export class LavalinkNode {
962
1022
  if (code === 1000 && reason === "Node-Disconnect")
963
1023
  return; // manually disconnected and already emitted the event.
964
1024
  this.NodeManager.emit("disconnect", this, { code, reason });
965
- if (code !== 1000 || reason !== "Node-Destroy")
966
- this.reconnect();
1025
+ if (code !== 1000 || reason !== "Node-Destroy") {
1026
+ if (this.NodeManager.nodes.has(this.id)) { // try to reconnect only when the node is still in the nodeManager.nodes list
1027
+ this.reconnect();
1028
+ }
1029
+ }
967
1030
  }
968
1031
  /** @private util function for handling error events from websocket */
969
1032
  error(error) {
@@ -83,7 +83,18 @@ export declare class NodeManager extends EventEmitter {
83
83
  /**
84
84
  * Delete a node from the nodeManager and destroy it
85
85
  * @param node The node to delete
86
+ * @param movePlayers whether to movePlayers to different connected node before deletion. @default false
86
87
  * @returns
88
+ *
89
+ * @example
90
+ * Deletes the node
91
+ * ```ts
92
+ * client.lavalink.nodeManager.deleteNode("nodeId to delete");
93
+ * ```
94
+ * Moves players to a different node before deleting
95
+ * ```ts
96
+ * client.lavalink.nodeManager.deleteNode("nodeId to delete", true);
97
+ * ```
87
98
  */
88
- deleteNode(node: LavalinkNodeIdentifier | LavalinkNode): void;
99
+ deleteNode(node: LavalinkNodeIdentifier | LavalinkNode, movePlayers?: boolean): void;
89
100
  }
@@ -193,13 +193,27 @@ export class NodeManager extends EventEmitter {
193
193
  /**
194
194
  * Delete a node from the nodeManager and destroy it
195
195
  * @param node The node to delete
196
+ * @param movePlayers whether to movePlayers to different connected node before deletion. @default false
196
197
  * @returns
198
+ *
199
+ * @example
200
+ * Deletes the node
201
+ * ```ts
202
+ * client.lavalink.nodeManager.deleteNode("nodeId to delete");
203
+ * ```
204
+ * Moves players to a different node before deleting
205
+ * ```ts
206
+ * client.lavalink.nodeManager.deleteNode("nodeId to delete", true);
207
+ * ```
197
208
  */
198
- deleteNode(node) {
209
+ deleteNode(node, movePlayers = false) {
199
210
  const decodeNode = typeof node === "string" ? this.nodes.get(node) : node || this.leastUsedNodes()[0];
200
211
  if (!decodeNode)
201
212
  throw new Error("Node was not found");
202
- decodeNode.destroy(DestroyReasons.NodeDeleted);
213
+ if (movePlayers)
214
+ decodeNode.destroy(DestroyReasons.NodeDeleted, true, true);
215
+ else
216
+ decodeNode.destroy(DestroyReasons.NodeDeleted);
203
217
  this.nodes.delete(decodeNode.id);
204
218
  return;
205
219
  }
@@ -49,6 +49,8 @@ export declare enum DestroyReasons {
49
49
  NodeReconnectFail = "NodeReconnectFail",
50
50
  Disconnected = "Disconnected",
51
51
  PlayerReconnectFail = "PlayerReconnectFail",
52
+ PlayerChangeNodeFail = "PlayerChangeNodeFail",
53
+ PlayerChangeNodeFailNoEligibleNode = "PlayerChangeNodeFailNoEligibleNode",
52
54
  ChannelDeleted = "ChannelDeleted",
53
55
  DisconnectAllNodes = "DisconnectAllNodes",
54
56
  ReconnectAllNodes = "ReconnectAllNodes",
@@ -173,14 +173,20 @@ export declare class LavalinkNode {
173
173
  * Destroys the Node-Connection (Websocket) and all player's of the node
174
174
  * @param destroyReason Destroy Reason to use when destroying the players
175
175
  * @param deleteNode wether to delete the nodte from the nodes list too, if false it will emit a disconnect. @default true
176
+ * @param movePlayers whether to movePlayers to different eligible connected node. If false players won't be moved @default false
176
177
  * @returns void
177
178
  *
178
179
  * @example
180
+ * Destroys node and its players
179
181
  * ```ts
180
182
  * player.node.destroy("custom Player Destroy Reason", true);
181
183
  * ```
184
+ * destroys only the node and moves its players to different connected node.
185
+ * ```ts
186
+ * player.node.destroy("custom Player Destroy Reason", true, true);
187
+ * ```
182
188
  */
183
- destroy(destroyReason?: DestroyReasonsType, deleteNode?: boolean): void;
189
+ destroy(destroyReason?: DestroyReasonsType, deleteNode?: boolean, movePlayers?: boolean): void;
184
190
  /**
185
191
  * Disconnects the Node-Connection (Websocket)
186
192
  * @param disconnectReason Disconnect Reason to use when disconnecting Node
@@ -83,7 +83,18 @@ export declare class NodeManager extends EventEmitter {
83
83
  /**
84
84
  * Delete a node from the nodeManager and destroy it
85
85
  * @param node The node to delete
86
+ * @param movePlayers whether to movePlayers to different connected node before deletion. @default false
86
87
  * @returns
88
+ *
89
+ * @example
90
+ * Deletes the node
91
+ * ```ts
92
+ * client.lavalink.nodeManager.deleteNode("nodeId to delete");
93
+ * ```
94
+ * Moves players to a different node before deleting
95
+ * ```ts
96
+ * client.lavalink.nodeManager.deleteNode("nodeId to delete", true);
97
+ * ```
87
98
  */
88
- deleteNode(node: LavalinkNodeIdentifier | LavalinkNode): void;
99
+ deleteNode(node: LavalinkNodeIdentifier | LavalinkNode, movePlayers?: boolean): void;
89
100
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lavalink-client",
3
- "version": "2.4.5",
3
+ "version": "2.4.7",
4
4
  "description": "Easy, flexible and feature-rich lavalink@v4 Client. Both for Beginners and Proficients.",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",
@@ -59,12 +59,12 @@
59
59
  "homepage": "https://tomato6966.github.io/lavalink-client/",
60
60
  "devDependencies": {
61
61
  "@eslint/eslintrc": "^3.2.0",
62
- "@eslint/js": "^9.18.0",
63
- "@types/node": "^22.10.5",
64
- "@types/ws": "^8.5.13",
65
- "@typescript-eslint/eslint-plugin": "^8.20.0",
66
- "@typescript-eslint/parser": "^8.20.0",
67
- "eslint": "^9.18.0",
62
+ "@eslint/js": "^9.19.0",
63
+ "@types/node": "^22.12.0",
64
+ "@types/ws": "^8.5.14",
65
+ "@typescript-eslint/eslint-plugin": "^8.22.0",
66
+ "@typescript-eslint/parser": "^8.22.0",
67
+ "eslint": "^9.19.0",
68
68
  "tsc-alias": "^1.8.10",
69
69
  "typescript": "^5.7.3"
70
70
  },