lavalink-client 2.4.3 → 2.4.5

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
@@ -790,10 +790,21 @@ if(previousTrack) {
790
790
 
791
791
  - Added the new events and configuration to the docs
792
792
 
793
+ ## **Version 2.4.1**
794
+
795
+ - Did some cleanup and comment removal + removed the playerVoiceEmptyStart because it would mean i'd need to add voice-state tracking, which wasn't the plan of doing by the client.
796
+
797
+ ## **Verison 2.4.2**
798
+
799
+ - Merged [PR#78](https://github.com/Tomato6966/lavalink-client/pull/78) from @hwangsihu - Added the configs to eslint ignore
800
+ - Merged [PR#80](https://github.com/Tomato6966/lavalink-client/pull/80) from @EvilG-MC - Argument Typo fix in resume event type declaration
801
+ - Merged [PR#83](https://github.com/Tomato6966/lavalink-client/pull/83) from @EvilG-MC - Fix if statement in Node#syncPlayerData() to allow syncing of "single entry objects"
802
+ - Some minor improvements by removing unnecessary spreading
803
+
793
804
  ## **Version 2.4.3**
794
805
  - `managerOptions#playerOptions.onDisconnect.autoReconnect`:
795
806
  - Added the option `managerOptions#playerOptions.onDisconnect.autoReconnectOnlyWithTracks` to control wether to try reconnecting only when there are tracks in the queue / current track or not
796
807
  - Added a new debug log for that
797
808
  - Added the try to play the next track if there is no current track
798
- - *There was a problem trying to auto-reconnect on "empty-queue" events, 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`"*
799
- - *Now you have to handle that case manually if you want to or set autoReconnectOnlyWithTracks to false (default)*
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
+ - *Now you have to handle that case manually if you want to or set autoReconnectOnlyWithTracks to false (default)*
@@ -142,12 +142,11 @@ class LavalinkNode {
142
142
  const url = new URL(`${this.restAddress}${options.path}`);
143
143
  url.searchParams.append("trace", "true");
144
144
  const urlToUse = this.getRequestingUrl(url, options?.extraQueryUrlParams);
145
- const originalOptions = structuredClone(options);
146
- delete options.path;
147
- delete options.extraQueryUrlParams;
148
- const response = await fetch(urlToUse, options);
145
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
146
+ const { path, extraQueryUrlParams, ...fetchOptions } = options; // destructure fetch only options
147
+ const response = await fetch(urlToUse, fetchOptions);
149
148
  this.calls++;
150
- return { response, options: originalOptions };
149
+ return { response, options: options };
151
150
  }
152
151
  async request(endpoint, modify, parseAsText) {
153
152
  if (!this.connected)
@@ -1160,6 +1159,8 @@ class LavalinkNode {
1160
1159
  }
1161
1160
  /** @private util function for handling trackEnd event */
1162
1161
  async trackEnd(player, track, payload) {
1162
+ if (player.get('internal_nodeChanging') === true)
1163
+ return; // Check if nodeChange is in Progress than stop the trackEnd Event from being triggered.
1163
1164
  const trackToUse = track || this.getTrackOfPayload(payload);
1164
1165
  // If a track was forcibly played
1165
1166
  if (payload.reason === "replaced") {
@@ -1375,6 +1376,8 @@ class LavalinkNode {
1375
1376
  }
1376
1377
  /** private util function for handling the queue end event */
1377
1378
  async queueEnd(player, track, payload) {
1379
+ if (player.get('internal_nodeChanging') === true)
1380
+ return; // Check if nodeChange is in Progress than stop the queueEnd Event from being triggered.
1378
1381
  // add previous track to the queue!
1379
1382
  player.queue.current = null;
1380
1383
  player.playing = false;
@@ -1425,7 +1428,7 @@ class LavalinkNode {
1425
1428
  }
1426
1429
  }
1427
1430
  player.set("internal_skipped", false);
1428
- player.set("internal_autoplayStopPlaying", Date.now());
1431
+ player.set("internal_autoplayStopPlaying", undefined);
1429
1432
  if (track && !track?.pluginInfo?.clientData?.previousTrack) { // If there was a current Track already and repeatmode === true, add it to the queue.
1430
1433
  player.queue.previous.unshift(track);
1431
1434
  if (player.queue.previous.length > player.queue.options.maxPreviousTracks)
@@ -217,8 +217,9 @@ export declare class Player {
217
217
  /**
218
218
  * Move the player on a different Audio-Node
219
219
  * @param newNode New Node / New Node Id
220
+ * @param checkSources If it should check if the sources are supported by the new node
220
221
  */
221
- changeNode(newNode: LavalinkNode | string): Promise<string>;
222
+ changeNode(newNode: LavalinkNode | string, checkSources?: boolean): Promise<string>;
222
223
  /** Converts the Player including Queue to a Json state */
223
224
  toJSON(): PlayerJson;
224
225
  }
@@ -459,11 +459,11 @@ class Player {
459
459
  throw new RangeError("Can't skip more than the queue size");
460
460
  await this.queue.splice(0, skipTo - 1);
461
461
  }
462
- if (!this.playing)
462
+ if (!this.playing && !this.queue.current)
463
463
  return (this.play(), this);
464
464
  const now = performance.now();
465
465
  this.set("internal_skipped", true);
466
- await this.node.updatePlayer({ guildId: this.guildId, playerOptions: { track: { encoded: null } } });
466
+ await this.node.updatePlayer({ guildId: this.guildId, playerOptions: { track: { encoded: null }, paused: false } });
467
467
  this.ping.lavalink = Math.round((performance.now() - now) / 10) / 100;
468
468
  return this;
469
469
  }
@@ -639,11 +639,37 @@ class Player {
639
639
  /**
640
640
  * Move the player on a different Audio-Node
641
641
  * @param newNode New Node / New Node Id
642
+ * @param checkSources If it should check if the sources are supported by the new node
642
643
  */
643
- async changeNode(newNode) {
644
+ async changeNode(newNode, checkSources = true) {
644
645
  const updateNode = typeof newNode === "string" ? this.LavalinkManager.nodeManager.nodes.get(newNode) : newNode;
645
646
  if (!updateNode)
646
647
  throw new Error("Could not find the new Node");
648
+ if (!updateNode.connected)
649
+ throw new Error("The provided Node is not active or disconnected");
650
+ if (this.node.id === updateNode.id)
651
+ throw new Error("Player is already on the provided Node");
652
+ if (this.get("internal_nodeChanging") === true)
653
+ throw new Error("Player is already changing the node please wait");
654
+ if (checkSources) {
655
+ const isDefaultSource = () => {
656
+ try {
657
+ this.LavalinkManager.utils.validateSourceString(updateNode, this.LavalinkManager.options.playerOptions.defaultSearchPlatform);
658
+ return true;
659
+ }
660
+ catch {
661
+ return false;
662
+ }
663
+ };
664
+ if (!isDefaultSource())
665
+ throw new RangeError(`defaultSearchPlatform "${this.LavalinkManager.options.playerOptions.defaultSearchPlatform}" is not supported by the newNode`);
666
+ if (this.queue.current || this.queue.tracks.length) { // Check if all queued track sources are supported by the new node
667
+ const trackSources = new Set([this.queue.current, ...this.queue.tracks].map(track => track.info.sourceName));
668
+ const missingSources = [...trackSources].filter(source => !updateNode.info.sourceManagers.includes(source));
669
+ if (missingSources.length)
670
+ throw new RangeError(`Sources missing for Node ${updateNode.id}: ${missingSources.join(', ')}`);
671
+ }
672
+ }
647
673
  if (this.LavalinkManager.options?.advancedOptions?.enableDebugEvents) {
648
674
  this.LavalinkManager.emit("debug", Constants_1.DebugEvents.PlayerChangeNode, {
649
675
  state: "log",
@@ -653,23 +679,60 @@ class Player {
653
679
  }
654
680
  const data = this.toJSON();
655
681
  const currentTrack = this.queue.current;
656
- await this.node.destroyPlayer(this.guildId);
682
+ const voiceData = this.voice;
683
+ if (!voiceData.endpoint ||
684
+ !voiceData.sessionId ||
685
+ !voiceData.token)
686
+ throw new Error("Voice Data is missing, can't change the node");
687
+ this.set("internal_nodeChanging", true); // This will stop execution of trackEnd or queueEnd event while changing the node
688
+ if (this.node.connected)
689
+ await this.node.destroyPlayer(this.guildId); // destroy the player on the currentNode if it's connected
657
690
  this.node = updateNode;
658
691
  const now = performance.now();
659
- await this.connect();
660
- await this.node.updatePlayer({
661
- guildId: this.guildId,
662
- noReplace: false,
663
- playerOptions: {
664
- position: data.position,
665
- volume: Math.round(Math.max(Math.min(data.volume, 1000), 0)),
666
- paused: data.paused,
667
- filters: { ...data.filters, equalizer: data.equalizer },
668
- track: currentTrack ?? undefined
669
- },
670
- });
671
- this.ping.lavalink = Math.round((performance.now() - now) / 10) / 100;
672
- return this.node.id;
692
+ try {
693
+ await this.connect();
694
+ const endpoint = `/sessions/${this.node.sessionId}/players/${this.guildId}`; //Send the VoiceData to the newly connected node.
695
+ await this.node.request(endpoint, r => {
696
+ r.method = "PATCH";
697
+ r.headers["Content-Type"] = "application/json";
698
+ r.body = JSON.stringify({
699
+ voice: {
700
+ token: voiceData.token,
701
+ endpoint: voiceData.endpoint,
702
+ sessionId: voiceData.sessionId
703
+ }
704
+ });
705
+ });
706
+ if (currentTrack) { // If there is a current track, send it to the new node.
707
+ await this.node.updatePlayer({
708
+ guildId: this.guildId,
709
+ noReplace: false,
710
+ playerOptions: {
711
+ track: currentTrack ?? null,
712
+ position: currentTrack ? data.position : 0,
713
+ volume: data.lavalinkVolume,
714
+ paused: data.paused,
715
+ //filters: { ...data.filters, equalizer: data.equalizer }, Sending filters on nodeChange causes issues (player gets dicsonnected)
716
+ }
717
+ });
718
+ }
719
+ this.ping.lavalink = Math.round((performance.now() - now) / 10) / 100;
720
+ return this.node.id;
721
+ }
722
+ catch (error) {
723
+ if (this.LavalinkManager.options?.advancedOptions?.enableDebugEvents) {
724
+ this.LavalinkManager.emit("debug", Constants_1.DebugEvents.PlayerChangeNode, {
725
+ state: "error",
726
+ error: error,
727
+ message: `Player.changeNode() execution failed`,
728
+ functionLayer: "Player > changeNode()",
729
+ });
730
+ }
731
+ throw new Error(`Failed to change the node: ${error}`);
732
+ }
733
+ finally {
734
+ this.set("internal_nodeChanging", undefined);
735
+ }
673
736
  }
674
737
  /** Converts the Player including Queue to a Json state */
675
738
  toJSON() {
@@ -217,7 +217,7 @@ class Queue {
217
217
  try {
218
218
  this.queueChanges.tracksAdd(this.guildId, (Array.isArray(TrackOrTracks) ? TrackOrTracks : [TrackOrTracks]).filter(v => this.managerUtils.isTrack(v) || this.managerUtils.isUnresolvedTrack(v)), this.tracks.length, oldStored, this.utils.toJSON());
219
219
  }
220
- catch (e) { /* */ }
220
+ catch { /* */ }
221
221
  // save the queue
222
222
  await this.utils.save();
223
223
  // return the amount of the tracks
@@ -243,7 +243,7 @@ class Queue {
243
243
  try {
244
244
  this.queueChanges.tracksAdd(this.guildId, (Array.isArray(TrackOrTracks) ? TrackOrTracks : [TrackOrTracks]).filter(v => this.managerUtils.isTrack(v) || this.managerUtils.isUnresolvedTrack(v)), index, oldStored, this.utils.toJSON());
245
245
  }
246
- catch (e) { /* */ }
246
+ catch { /* */ }
247
247
  // remove the tracks (and add the new ones)
248
248
  let spliced = TrackOrTracks ? this.tracks.splice(index, amount, ...(Array.isArray(TrackOrTracks) ? TrackOrTracks : [TrackOrTracks]).filter(v => this.managerUtils.isTrack(v) || this.managerUtils.isUnresolvedTrack(v))) : this.tracks.splice(index, amount);
249
249
  // get the spliced array
@@ -253,7 +253,7 @@ class Queue {
253
253
  try {
254
254
  this.queueChanges.tracksRemoved(this.guildId, spliced, index, oldStored, this.utils.toJSON());
255
255
  }
256
- catch (e) { /* */ }
256
+ catch { /* */ }
257
257
  // save the queue
258
258
  await this.utils.save();
259
259
  // return the things
@@ -302,7 +302,7 @@ class Queue {
302
302
  try {
303
303
  this.queueChanges.tracksRemoved(this.guildId, removed, removeQueryTrack, oldStored, this.utils.toJSON());
304
304
  }
305
- catch (e) { /* */ }
305
+ catch { /* */ }
306
306
  await this.utils.save();
307
307
  return { removed };
308
308
  }
@@ -321,7 +321,7 @@ class Queue {
321
321
  try {
322
322
  this.queueChanges.tracksRemoved(this.guildId, removed, removeQueryTrack, oldStored, this.utils.toJSON());
323
323
  }
324
- catch (e) { /* */ }
324
+ catch { /* */ }
325
325
  await this.utils.save();
326
326
  return { removed };
327
327
  }
@@ -345,7 +345,7 @@ class Queue {
345
345
  try {
346
346
  this.queueChanges.tracksRemoved(this.guildId, removed, tracksToRemove.map(v => v.i), oldStored, this.utils.toJSON());
347
347
  }
348
- catch (e) { /* */ }
348
+ catch { /* */ }
349
349
  await this.utils.save();
350
350
  return { removed };
351
351
  }
@@ -363,7 +363,7 @@ class Queue {
363
363
  try {
364
364
  this.queueChanges.tracksRemoved(this.guildId, removed, toRemove, oldStored, this.utils.toJSON());
365
365
  }
366
- catch (e) { /* */ }
366
+ catch { /* */ }
367
367
  await this.utils.save();
368
368
  return { removed };
369
369
  }
@@ -138,12 +138,11 @@ export class LavalinkNode {
138
138
  const url = new URL(`${this.restAddress}${options.path}`);
139
139
  url.searchParams.append("trace", "true");
140
140
  const urlToUse = this.getRequestingUrl(url, options?.extraQueryUrlParams);
141
- const originalOptions = structuredClone(options);
142
- delete options.path;
143
- delete options.extraQueryUrlParams;
144
- const response = await fetch(urlToUse, options);
141
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
142
+ const { path, extraQueryUrlParams, ...fetchOptions } = options; // destructure fetch only options
143
+ const response = await fetch(urlToUse, fetchOptions);
145
144
  this.calls++;
146
- return { response, options: originalOptions };
145
+ return { response, options: options };
147
146
  }
148
147
  async request(endpoint, modify, parseAsText) {
149
148
  if (!this.connected)
@@ -1156,6 +1155,8 @@ export class LavalinkNode {
1156
1155
  }
1157
1156
  /** @private util function for handling trackEnd event */
1158
1157
  async trackEnd(player, track, payload) {
1158
+ if (player.get('internal_nodeChanging') === true)
1159
+ return; // Check if nodeChange is in Progress than stop the trackEnd Event from being triggered.
1159
1160
  const trackToUse = track || this.getTrackOfPayload(payload);
1160
1161
  // If a track was forcibly played
1161
1162
  if (payload.reason === "replaced") {
@@ -1371,6 +1372,8 @@ export class LavalinkNode {
1371
1372
  }
1372
1373
  /** private util function for handling the queue end event */
1373
1374
  async queueEnd(player, track, payload) {
1375
+ if (player.get('internal_nodeChanging') === true)
1376
+ return; // Check if nodeChange is in Progress than stop the queueEnd Event from being triggered.
1374
1377
  // add previous track to the queue!
1375
1378
  player.queue.current = null;
1376
1379
  player.playing = false;
@@ -1421,7 +1424,7 @@ export class LavalinkNode {
1421
1424
  }
1422
1425
  }
1423
1426
  player.set("internal_skipped", false);
1424
- player.set("internal_autoplayStopPlaying", Date.now());
1427
+ player.set("internal_autoplayStopPlaying", undefined);
1425
1428
  if (track && !track?.pluginInfo?.clientData?.previousTrack) { // If there was a current Track already and repeatmode === true, add it to the queue.
1426
1429
  player.queue.previous.unshift(track);
1427
1430
  if (player.queue.previous.length > player.queue.options.maxPreviousTracks)
@@ -217,8 +217,9 @@ export declare class Player {
217
217
  /**
218
218
  * Move the player on a different Audio-Node
219
219
  * @param newNode New Node / New Node Id
220
+ * @param checkSources If it should check if the sources are supported by the new node
220
221
  */
221
- changeNode(newNode: LavalinkNode | string): Promise<string>;
222
+ changeNode(newNode: LavalinkNode | string, checkSources?: boolean): Promise<string>;
222
223
  /** Converts the Player including Queue to a Json state */
223
224
  toJSON(): PlayerJson;
224
225
  }
@@ -456,11 +456,11 @@ export class Player {
456
456
  throw new RangeError("Can't skip more than the queue size");
457
457
  await this.queue.splice(0, skipTo - 1);
458
458
  }
459
- if (!this.playing)
459
+ if (!this.playing && !this.queue.current)
460
460
  return (this.play(), this);
461
461
  const now = performance.now();
462
462
  this.set("internal_skipped", true);
463
- await this.node.updatePlayer({ guildId: this.guildId, playerOptions: { track: { encoded: null } } });
463
+ await this.node.updatePlayer({ guildId: this.guildId, playerOptions: { track: { encoded: null }, paused: false } });
464
464
  this.ping.lavalink = Math.round((performance.now() - now) / 10) / 100;
465
465
  return this;
466
466
  }
@@ -636,11 +636,37 @@ export class Player {
636
636
  /**
637
637
  * Move the player on a different Audio-Node
638
638
  * @param newNode New Node / New Node Id
639
+ * @param checkSources If it should check if the sources are supported by the new node
639
640
  */
640
- async changeNode(newNode) {
641
+ async changeNode(newNode, checkSources = true) {
641
642
  const updateNode = typeof newNode === "string" ? this.LavalinkManager.nodeManager.nodes.get(newNode) : newNode;
642
643
  if (!updateNode)
643
644
  throw new Error("Could not find the new Node");
645
+ if (!updateNode.connected)
646
+ throw new Error("The provided Node is not active or disconnected");
647
+ if (this.node.id === updateNode.id)
648
+ throw new Error("Player is already on the provided Node");
649
+ if (this.get("internal_nodeChanging") === true)
650
+ throw new Error("Player is already changing the node please wait");
651
+ if (checkSources) {
652
+ const isDefaultSource = () => {
653
+ try {
654
+ this.LavalinkManager.utils.validateSourceString(updateNode, this.LavalinkManager.options.playerOptions.defaultSearchPlatform);
655
+ return true;
656
+ }
657
+ catch {
658
+ return false;
659
+ }
660
+ };
661
+ if (!isDefaultSource())
662
+ throw new RangeError(`defaultSearchPlatform "${this.LavalinkManager.options.playerOptions.defaultSearchPlatform}" is not supported by the newNode`);
663
+ if (this.queue.current || this.queue.tracks.length) { // Check if all queued track sources are supported by the new node
664
+ const trackSources = new Set([this.queue.current, ...this.queue.tracks].map(track => track.info.sourceName));
665
+ const missingSources = [...trackSources].filter(source => !updateNode.info.sourceManagers.includes(source));
666
+ if (missingSources.length)
667
+ throw new RangeError(`Sources missing for Node ${updateNode.id}: ${missingSources.join(', ')}`);
668
+ }
669
+ }
644
670
  if (this.LavalinkManager.options?.advancedOptions?.enableDebugEvents) {
645
671
  this.LavalinkManager.emit("debug", DebugEvents.PlayerChangeNode, {
646
672
  state: "log",
@@ -650,23 +676,60 @@ export class Player {
650
676
  }
651
677
  const data = this.toJSON();
652
678
  const currentTrack = this.queue.current;
653
- await this.node.destroyPlayer(this.guildId);
679
+ const voiceData = this.voice;
680
+ if (!voiceData.endpoint ||
681
+ !voiceData.sessionId ||
682
+ !voiceData.token)
683
+ throw new Error("Voice Data is missing, can't change the node");
684
+ this.set("internal_nodeChanging", true); // This will stop execution of trackEnd or queueEnd event while changing the node
685
+ if (this.node.connected)
686
+ await this.node.destroyPlayer(this.guildId); // destroy the player on the currentNode if it's connected
654
687
  this.node = updateNode;
655
688
  const now = performance.now();
656
- await this.connect();
657
- await this.node.updatePlayer({
658
- guildId: this.guildId,
659
- noReplace: false,
660
- playerOptions: {
661
- position: data.position,
662
- volume: Math.round(Math.max(Math.min(data.volume, 1000), 0)),
663
- paused: data.paused,
664
- filters: { ...data.filters, equalizer: data.equalizer },
665
- track: currentTrack ?? undefined
666
- },
667
- });
668
- this.ping.lavalink = Math.round((performance.now() - now) / 10) / 100;
669
- return this.node.id;
689
+ try {
690
+ await this.connect();
691
+ const endpoint = `/sessions/${this.node.sessionId}/players/${this.guildId}`; //Send the VoiceData to the newly connected node.
692
+ await this.node.request(endpoint, r => {
693
+ r.method = "PATCH";
694
+ r.headers["Content-Type"] = "application/json";
695
+ r.body = JSON.stringify({
696
+ voice: {
697
+ token: voiceData.token,
698
+ endpoint: voiceData.endpoint,
699
+ sessionId: voiceData.sessionId
700
+ }
701
+ });
702
+ });
703
+ if (currentTrack) { // If there is a current track, send it to the new node.
704
+ await this.node.updatePlayer({
705
+ guildId: this.guildId,
706
+ noReplace: false,
707
+ playerOptions: {
708
+ track: currentTrack ?? null,
709
+ position: currentTrack ? data.position : 0,
710
+ volume: data.lavalinkVolume,
711
+ paused: data.paused,
712
+ //filters: { ...data.filters, equalizer: data.equalizer }, Sending filters on nodeChange causes issues (player gets dicsonnected)
713
+ }
714
+ });
715
+ }
716
+ this.ping.lavalink = Math.round((performance.now() - now) / 10) / 100;
717
+ return this.node.id;
718
+ }
719
+ catch (error) {
720
+ if (this.LavalinkManager.options?.advancedOptions?.enableDebugEvents) {
721
+ this.LavalinkManager.emit("debug", DebugEvents.PlayerChangeNode, {
722
+ state: "error",
723
+ error: error,
724
+ message: `Player.changeNode() execution failed`,
725
+ functionLayer: "Player > changeNode()",
726
+ });
727
+ }
728
+ throw new Error(`Failed to change the node: ${error}`);
729
+ }
730
+ finally {
731
+ this.set("internal_nodeChanging", undefined);
732
+ }
670
733
  }
671
734
  /** Converts the Player including Queue to a Json state */
672
735
  toJSON() {
@@ -212,7 +212,7 @@ export class Queue {
212
212
  try {
213
213
  this.queueChanges.tracksAdd(this.guildId, (Array.isArray(TrackOrTracks) ? TrackOrTracks : [TrackOrTracks]).filter(v => this.managerUtils.isTrack(v) || this.managerUtils.isUnresolvedTrack(v)), this.tracks.length, oldStored, this.utils.toJSON());
214
214
  }
215
- catch (e) { /* */ }
215
+ catch { /* */ }
216
216
  // save the queue
217
217
  await this.utils.save();
218
218
  // return the amount of the tracks
@@ -238,7 +238,7 @@ export class Queue {
238
238
  try {
239
239
  this.queueChanges.tracksAdd(this.guildId, (Array.isArray(TrackOrTracks) ? TrackOrTracks : [TrackOrTracks]).filter(v => this.managerUtils.isTrack(v) || this.managerUtils.isUnresolvedTrack(v)), index, oldStored, this.utils.toJSON());
240
240
  }
241
- catch (e) { /* */ }
241
+ catch { /* */ }
242
242
  // remove the tracks (and add the new ones)
243
243
  let spliced = TrackOrTracks ? this.tracks.splice(index, amount, ...(Array.isArray(TrackOrTracks) ? TrackOrTracks : [TrackOrTracks]).filter(v => this.managerUtils.isTrack(v) || this.managerUtils.isUnresolvedTrack(v))) : this.tracks.splice(index, amount);
244
244
  // get the spliced array
@@ -248,7 +248,7 @@ export class Queue {
248
248
  try {
249
249
  this.queueChanges.tracksRemoved(this.guildId, spliced, index, oldStored, this.utils.toJSON());
250
250
  }
251
- catch (e) { /* */ }
251
+ catch { /* */ }
252
252
  // save the queue
253
253
  await this.utils.save();
254
254
  // return the things
@@ -297,7 +297,7 @@ export class Queue {
297
297
  try {
298
298
  this.queueChanges.tracksRemoved(this.guildId, removed, removeQueryTrack, oldStored, this.utils.toJSON());
299
299
  }
300
- catch (e) { /* */ }
300
+ catch { /* */ }
301
301
  await this.utils.save();
302
302
  return { removed };
303
303
  }
@@ -316,7 +316,7 @@ export class Queue {
316
316
  try {
317
317
  this.queueChanges.tracksRemoved(this.guildId, removed, removeQueryTrack, oldStored, this.utils.toJSON());
318
318
  }
319
- catch (e) { /* */ }
319
+ catch { /* */ }
320
320
  await this.utils.save();
321
321
  return { removed };
322
322
  }
@@ -340,7 +340,7 @@ export class Queue {
340
340
  try {
341
341
  this.queueChanges.tracksRemoved(this.guildId, removed, tracksToRemove.map(v => v.i), oldStored, this.utils.toJSON());
342
342
  }
343
- catch (e) { /* */ }
343
+ catch { /* */ }
344
344
  await this.utils.save();
345
345
  return { removed };
346
346
  }
@@ -358,7 +358,7 @@ export class Queue {
358
358
  try {
359
359
  this.queueChanges.tracksRemoved(this.guildId, removed, toRemove, oldStored, this.utils.toJSON());
360
360
  }
361
- catch (e) { /* */ }
361
+ catch { /* */ }
362
362
  await this.utils.save();
363
363
  return { removed };
364
364
  }
@@ -217,8 +217,9 @@ export declare class Player {
217
217
  /**
218
218
  * Move the player on a different Audio-Node
219
219
  * @param newNode New Node / New Node Id
220
+ * @param checkSources If it should check if the sources are supported by the new node
220
221
  */
221
- changeNode(newNode: LavalinkNode | string): Promise<string>;
222
+ changeNode(newNode: LavalinkNode | string, checkSources?: boolean): Promise<string>;
222
223
  /** Converts the Player including Queue to a Json state */
223
224
  toJSON(): PlayerJson;
224
225
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lavalink-client",
3
- "version": "2.4.3",
3
+ "version": "2.4.5",
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",
@@ -58,22 +58,22 @@
58
58
  },
59
59
  "homepage": "https://tomato6966.github.io/lavalink-client/",
60
60
  "devDependencies": {
61
- "@eslint/eslintrc": "^3.1.0",
62
- "@eslint/js": "^9.11.0",
63
- "@types/node": "^22.5.5",
64
- "@types/ws": "^8.5.12",
65
- "@typescript-eslint/eslint-plugin": "^8.6.0",
66
- "@typescript-eslint/parser": "^8.6.0",
67
- "eslint": "^9.11.0",
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",
68
68
  "tsc-alias": "^1.8.10",
69
- "typescript": "^5.6.2"
69
+ "typescript": "^5.7.3"
70
70
  },
71
71
  "dependencies": {
72
- "tslib": "^2.7.0",
72
+ "tslib": "^2.8.1",
73
73
  "ws": "^8.18.0"
74
74
  },
75
75
  "engines": {
76
76
  "node": ">=18.0.0",
77
- "bun": ">=1.0.0"
77
+ "bun": ">=1.1.27"
78
78
  }
79
79
  }