aqualink 2.7.0 → 2.7.1

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.
@@ -4,7 +4,7 @@ const Player = require("./Player");
4
4
  const Track = require("./Track");
5
5
  const { version: pkgVersion } = require("../../package.json");
6
6
  const { EventEmitter } = require('tseep');
7
- const fs = require('fs-extra');
7
+ const fs = require('fs/promises');
8
8
 
9
9
  const URL_REGEX = /^https?:\/\//;
10
10
  const DEFAULT_OPTIONS = Object.freeze({
@@ -57,11 +57,11 @@ class Aqua extends EventEmitter {
57
57
  this.send = this.options.send || this.defaultSendFunction.bind(this);
58
58
 
59
59
  this._leastUsedCache = { nodes: [], timestamp: 0 };
60
-
60
+
61
61
  this._nodeStates = new Map();
62
62
  this._failoverQueue = new Map();
63
63
  this._lastFailoverAttempt = new Map();
64
-
64
+
65
65
  this._boundCleanupPlayer = this.cleanupPlayer.bind(this);
66
66
  this._boundHandlePlayerDestroy = this._handlePlayerDestroy.bind(this);
67
67
  }
@@ -100,16 +100,16 @@ class Aqua extends EventEmitter {
100
100
  console.error(`Failed to create node ${node.name || node.host}:`, err);
101
101
  return null;
102
102
  }));
103
-
103
+
104
104
  const results = await Promise.allSettled(nodePromises);
105
105
  const successfulNodes = results.filter(r => r.status === 'fulfilled' && r.value).length;
106
-
106
+
107
107
  if (successfulNodes === 0) {
108
108
  throw new Error("No nodes could be connected");
109
109
  }
110
110
 
111
- await Promise.all(this.plugins.map(plugin =>
112
- Promise.resolve(plugin.load(this)).catch(err =>
111
+ await Promise.all(this.plugins.map(plugin =>
112
+ Promise.resolve(plugin.load(this)).catch(err =>
113
113
  console.error("Plugin load error:", err)
114
114
  )
115
115
  ));
@@ -166,10 +166,10 @@ class Aqua extends EventEmitter {
166
166
 
167
167
  async handleNodeFailover(failedNode) {
168
168
  if (!this.failoverOptions.enabled) return;
169
-
169
+
170
170
  const nodeId = failedNode.name || failedNode.host;
171
171
  const now = Date.now();
172
-
172
+
173
173
  const nodeState = this._nodeStates.get(nodeId);
174
174
  if (nodeState?.failoverInProgress) return;
175
175
 
@@ -182,10 +182,10 @@ class Aqua extends EventEmitter {
182
182
  this._nodeStates.set(nodeId, { connected: false, failoverInProgress: true });
183
183
  this._lastFailoverAttempt.set(nodeId, now);
184
184
  this._failoverQueue.set(nodeId, currentAttempts + 1);
185
-
185
+
186
186
  try {
187
187
  this.emit("nodeFailover", failedNode);
188
-
188
+
189
189
  const affectedPlayers = this._getPlayersForNode(failedNode);
190
190
  if (affectedPlayers.length === 0) {
191
191
  this._nodeStates.set(nodeId, { connected: false, failoverInProgress: false });
@@ -200,14 +200,14 @@ class Aqua extends EventEmitter {
200
200
  }
201
201
 
202
202
  const failoverResults = await this._migratePlayersWithRetry(affectedPlayers, availableNodes);
203
-
203
+
204
204
  const successful = failoverResults.filter(r => r.success).length;
205
205
  const failed = failoverResults.length - successful;
206
-
206
+
207
207
  if (successful > 0) {
208
208
  this.emit("nodeFailoverComplete", failedNode, successful, failed);
209
209
  }
210
-
210
+
211
211
  } catch (error) {
212
212
  this.emit("error", null, new Error(`Failover failed for node ${nodeId}: ${error.message}`));
213
213
  } finally {
@@ -226,14 +226,14 @@ class Aqua extends EventEmitter {
226
226
  }
227
227
 
228
228
  _getAvailableNodesForFailover(failedNode) {
229
- return this.leastUsedNodes.filter(node =>
229
+ return this.leastUsedNodes.filter(node =>
230
230
  node !== failedNode && node.name !== failedNode.name
231
231
  );
232
232
  }
233
233
 
234
234
  async _migratePlayersWithRetry(players, availableNodes) {
235
235
  const results = [];
236
-
236
+
237
237
  const concurrency = 3;
238
238
  for (let i = 0; i < players.length; i += concurrency) {
239
239
  const batch = players.slice(i, i + concurrency);
@@ -246,11 +246,11 @@ class Aqua extends EventEmitter {
246
246
  return { player, success: false, error };
247
247
  }
248
248
  });
249
-
249
+
250
250
  const batchResults = await Promise.allSettled(batchPromises);
251
251
  results.push(...batchResults.map(r => r.value || r.reason));
252
252
  }
253
-
253
+
254
254
  return results;
255
255
  }
256
256
 
@@ -261,7 +261,7 @@ class Aqua extends EventEmitter {
261
261
 
262
262
  const guildId = player.guildId;
263
263
  let retryCount = 0;
264
-
264
+
265
265
  while (retryCount < this.failoverOptions.maxRetries) {
266
266
  try {
267
267
  const targetNode = this._selectBestNode(availableNodes, player);
@@ -274,15 +274,15 @@ class Aqua extends EventEmitter {
274
274
  if (!newPlayer) throw new Error("Failed to create player on target node");
275
275
 
276
276
  await this._restorePlayerState(newPlayer, playerState);
277
-
277
+
278
278
  newPlayer.destroy();
279
279
  if (playerState.current) {
280
280
  newPlayer.queue.add(playerState.current);
281
281
  }
282
-
282
+
283
283
  this.emit("playerMigrated", player, newPlayer, targetNode);
284
284
  return newPlayer;
285
-
285
+
286
286
  } catch (error) {
287
287
  retryCount++;
288
288
  if (retryCount < this.failoverOptions.maxRetries) {
@@ -296,12 +296,12 @@ class Aqua extends EventEmitter {
296
296
 
297
297
  _selectBestNode(availableNodes, player) {
298
298
  if (player.region) {
299
- const regionNode = availableNodes.find(node =>
299
+ const regionNode = availableNodes.find(node =>
300
300
  node.regions?.includes(player.region.toLowerCase())
301
301
  );
302
302
  if (regionNode) return regionNode;
303
303
  }
304
-
304
+
305
305
  return availableNodes[0];
306
306
  }
307
307
 
@@ -349,7 +349,7 @@ class Aqua extends EventEmitter {
349
349
  try {
350
350
  // Batch operations where possible
351
351
  const operations = [];
352
-
352
+
353
353
  if (playerState.volume !== undefined) {
354
354
  operations.push(newPlayer.setVolume(playerState.volume));
355
355
  }
@@ -365,15 +365,15 @@ class Aqua extends EventEmitter {
365
365
  // Handle current track restoration
366
366
  if (playerState.current && this.failoverOptions.preservePosition) {
367
367
  newPlayer.queue.unshift(playerState.current);
368
-
368
+
369
369
  if (this.failoverOptions.resumePlayback) {
370
370
  await newPlayer.play();
371
-
371
+
372
372
  if (playerState.position > 0) {
373
373
  await this._delay(300); // Reduced delay
374
374
  await newPlayer.seek(playerState.position);
375
375
  }
376
-
376
+
377
377
  if (playerState.paused) {
378
378
  await newPlayer.pause();
379
379
  }
@@ -557,7 +557,7 @@ class Aqua extends EventEmitter {
557
557
  baseResponse.tracks.push(new Track(response.data, requester, requestNode));
558
558
  }
559
559
  break;
560
-
560
+
561
561
  case "playlist": {
562
562
  const info = response.data?.info;
563
563
  if (info) {
@@ -604,42 +604,50 @@ class Aqua extends EventEmitter {
604
604
  }
605
605
  }
606
606
 
607
- // Optimized save/load methods
608
607
  async savePlayer(filePath = "./AquaPlayers.json") {
609
- const data = Array.from(this.players.values(), player => ({
610
- g: player.guildId,
611
- t: player.textChannel,
612
- v: player.voiceChannel,
613
- u: player.current?.uri || null,
614
- p: player.position || 0,
615
- ts: player.timestamp || 0,
616
- q: player.queue?.tracks?.slice(0, 5).map(tr => tr.uri) || [],
617
- r: player.requester || player.current?.requester,
618
- vol: player.volume,
619
- pa: player.paused,
620
- n: player.nodes?.name || null
621
- }));
622
-
608
+ const data = Array.from(this.players.values()).map(player => {
609
+ const requester = player.requester || player.current?.requester;
610
+
611
+ return {
612
+ g: player.guildId,
613
+ t: player.textChannel,
614
+ v: player.voiceChannel,
615
+ u: player.current?.uri || null,
616
+ p: player.position || 0,
617
+ ts: player.timestamp || 0,
618
+ q: player.queue?.tracks?.map(tr => tr.uri).slice(0, 5) || [],
619
+ r: requester ? {
620
+ id: requester.id,
621
+ username: requester.username,
622
+ globalName: requester.globalName,
623
+ discriminator: requester.discriminator,
624
+ avatar: requester.avatar
625
+ } : null,
626
+ vol: player.volume,
627
+ pa: player.paused,
628
+ isPlaying: !!player.current && !player.paused
629
+ };
630
+ });
631
+
623
632
  await fs.writeFile(filePath, JSON.stringify(data), "utf8");
633
+ this.emit("debug", "Aqua", `Saved ${data.length} players to ${filePath}`);
624
634
  }
625
635
 
626
636
  async loadPlayers(filePath = "./AquaPlayers.json") {
627
637
  try {
628
638
  await fs.access(filePath);
629
639
  await this._waitForFirstNode();
630
-
640
+
631
641
  const data = JSON.parse(await fs.readFile(filePath, "utf8"));
632
-
633
- // Process in batches to avoid overwhelming
642
+
634
643
  const batchSize = 5;
635
644
  for (let i = 0; i < data.length; i += batchSize) {
636
645
  const batch = data.slice(i, i + batchSize);
637
646
  await Promise.all(batch.map(p => this._restorePlayer(p)));
638
647
  }
639
-
648
+
640
649
  await fs.writeFile(filePath, "[]", "utf8");
641
650
  } catch (error) {
642
- // Silent fail if file doesn't exist
643
651
  }
644
652
  }
645
653
 
@@ -647,11 +655,11 @@ class Aqua extends EventEmitter {
647
655
  try {
648
656
  let player = this.players.get(p.g);
649
657
  if (!player) {
650
- const targetNode = (p.n && this.nodeMap.get(p.n)?.connected) ?
658
+ const targetNode = (p.n && this.nodeMap.get(p.n)?.connected) ?
651
659
  this.nodeMap.get(p.n) : this.leastUsedNodes[0];
652
-
660
+
653
661
  if (!targetNode) return;
654
-
662
+
655
663
  player = await this.createConnection({
656
664
  guildId: p.g,
657
665
  textChannel: p.t,
@@ -661,7 +669,6 @@ class Aqua extends EventEmitter {
661
669
  });
662
670
  }
663
671
 
664
- // Restore current track
665
672
  if (p.u && player) {
666
673
  const resolved = await this.resolve({ query: p.u, requester: p.r });
667
674
  if (resolved.tracks?.[0]) {
@@ -670,13 +677,12 @@ class Aqua extends EventEmitter {
670
677
  if (typeof p.ts === "number") player.timestamp = p.ts;
671
678
  }
672
679
  }
673
-
674
- // Restore queue
680
+
675
681
  if (p.q?.length && player) {
676
682
  const queuePromises = p.q
677
683
  .filter(uri => uri !== p.u)
678
684
  .map(uri => this.resolve({ query: uri, requester: p.r }));
679
-
685
+
680
686
  const queueResults = await Promise.allSettled(queuePromises);
681
687
  queueResults.forEach(result => {
682
688
  if (result.status === 'fulfilled' && result.value.tracks?.[0]) {
@@ -684,21 +690,20 @@ class Aqua extends EventEmitter {
684
690
  }
685
691
  });
686
692
  }
687
-
693
+
688
694
  if (player) {
689
695
  player.paused = !!p.pa;
690
- if (!player.playing && !player.paused && player.queue.size > 0) {
696
+ if ((p.isPlaying || (p.pa && p.u)) && player.queue.size > 0) {
691
697
  player.play();
692
698
  }
693
699
  }
694
700
  } catch (error) {
695
- // Silent fail for individual player restoration
696
701
  }
697
702
  }
698
703
 
699
704
  async _waitForFirstNode() {
700
705
  if (this.leastUsedNodes.length > 0) return;
701
-
706
+
702
707
  return new Promise(resolve => {
703
708
  const checkInterval = setInterval(() => {
704
709
  if (this.leastUsedNodes.length > 0) {
@@ -747,15 +752,15 @@ class Aqua extends EventEmitter {
747
752
  }
748
753
  return stats;
749
754
  }
750
-
755
+
751
756
  async forceFailover(nodeIdentifier) {
752
757
  const node = this.nodeMap.get(nodeIdentifier);
753
758
  if (!node) return;
754
-
759
+
755
760
  if (node.connected) {
756
761
  await node.destroy();
757
762
  }
758
-
763
+
759
764
  this._cleanupNode(nodeIdentifier);
760
765
  }
761
766
  }
@@ -1,4 +1,5 @@
1
1
  "use strict";
2
+
2
3
  const WebSocket = require('ws');
3
4
  const Rest = require("./Rest");
4
5
 
@@ -29,9 +30,6 @@ class Node {
29
30
  this.sessionId = sessionId;
30
31
  this.regions = regions;
31
32
 
32
- this.wsUrl = `ws${this.secure ? "s" : ""}://${this.host}:${this.port}/v4/websocket`;
33
- this.rest = new Rest(aqua, this);
34
-
35
33
  const {
36
34
  resumeTimeout = 60,
37
35
  autoResume = false,
@@ -46,15 +44,24 @@ class Node {
46
44
  this.reconnectTries = reconnectTries;
47
45
  this.infiniteReconnects = infiniteReconnects;
48
46
 
47
+ this.wsUrl = `ws${this.secure ? "s" : ""}://${this.host}:${this.port}/v4/websocket`;
48
+ this.rest = new Rest(aqua, this);
49
+ this._headers = this._constructHeaders();
50
+
49
51
  this.connected = false;
52
+ this.isDestroyed = false;
50
53
  this.info = null;
51
54
  this.ws = null;
52
55
  this.reconnectAttempted = 0;
53
56
  this.reconnectTimeoutId = null;
54
- this.isDestroyed = false;
55
57
  this.lastHealthCheck = Date.now();
56
58
 
57
- this._headers = this._constructHeaders();
59
+ // Pre-bind event handlers for efficiency
60
+ this._onOpen = this._onOpen.bind(this);
61
+ this._onError = this._onError.bind(this);
62
+ this._onMessage = this._onMessage.bind(this);
63
+ this._onClose = this._onClose.bind(this);
64
+
58
65
  this.initializeStats();
59
66
  }
60
67
 
@@ -89,6 +96,9 @@ class Node {
89
96
  this.reconnectAttempted = 0;
90
97
  this.lastHealthCheck = Date.now();
91
98
  this.aqua.emit("debug", this.name, "WebSocket connection established");
99
+
100
+ clearTimeout(this.reconnectTimeoutId);
101
+ this.reconnectTimeoutId = null;
92
102
 
93
103
  if (this.aqua.bypassChecks?.nodeFetchInfo) return;
94
104
 
@@ -97,7 +107,7 @@ class Node {
97
107
  this.aqua.emit("nodeConnected", this);
98
108
 
99
109
  if (this.autoResume && this.sessionId) {
100
- await this.aqua.loadPlayers();
110
+ await this.resumePlayers();
101
111
  }
102
112
  } catch (err) {
103
113
  this.info = null;
@@ -118,30 +128,27 @@ class Node {
118
128
  return;
119
129
  }
120
130
 
121
- const op = payload?.op;
131
+ const { op, guildId } = payload;
122
132
  if (!op) return;
123
133
 
124
134
  this.lastHealthCheck = Date.now();
125
-
126
- if (op === "stats") {
127
- this._updateStats(payload);
128
- return;
129
- }
130
- if (op === "ready") {
131
- this._handleReadyOp(payload);
132
- return;
133
- }
134
-
135
- if (op.startsWith("Lyrics")) {
136
- const player = payload.guildId ? this.aqua.players.get(payload.guildId) : null;
137
- const track = payload.track || null;
138
- this.aqua.emit(op, player, track, payload);
139
- return;
140
- }
141
-
142
- if (payload.guildId) {
143
- const player = this.aqua.players.get(payload.guildId);
144
- if (player) player.emit(op, payload);
135
+
136
+ switch (op) {
137
+ case "stats":
138
+ this._updateStats(payload);
139
+ break;
140
+ case "ready":
141
+ this._handleReadyOp(payload);
142
+ break;
143
+ default:
144
+ if (op.startsWith("Lyrics")) {
145
+ const player = guildId ? this.aqua.players.get(guildId) : null;
146
+ this.aqua.emit(op, player, payload.track || null, payload);
147
+ } else if (guildId) {
148
+ const player = this.aqua.players.get(guildId);
149
+ player?.emit(op, payload);
150
+ }
151
+ break;
145
152
  }
146
153
  }
147
154
 
@@ -150,22 +157,20 @@ class Node {
150
157
  const reasonStr = reason?.toString() || "No reason provided";
151
158
 
152
159
  this.aqua.emit("nodeDisconnect", this, { code, reason: reasonStr });
153
-
154
160
  this.aqua.handleNodeFailover(this);
155
-
156
161
  this.scheduleReconnect(code);
157
162
  }
158
163
 
159
164
  scheduleReconnect(code) {
160
- this.clearReconnectTimeout();
161
-
162
165
  if (code === Node.WS_CLOSE_NORMAL || this.isDestroyed) {
163
- this.aqua.emit("debug", this.name, "WebSocket closed normally, not reconnecting");
166
+ this.aqua.emit("debug", this.name, "WebSocket closed normally, not reconnecting.");
164
167
  return;
165
168
  }
166
169
 
170
+ if (this.reconnectTimeoutId) return;
171
+
167
172
  if (this.infiniteReconnects) {
168
- this.aqua.emit("nodeReconnect", this, "Infinite reconnects enabled, trying again in 10 seconds");
173
+ this.aqua.emit("nodeReconnect", this, "Infinite reconnects enabled, trying again in 10 seconds.");
169
174
  this.reconnectTimeoutId = setTimeout(() => this.connect(), 10000);
170
175
  return;
171
176
  }
@@ -188,26 +193,19 @@ class Node {
188
193
  }
189
194
 
190
195
  calculateBackoff() {
191
- const baseBackoff = this.reconnectTimeout * Math.pow(Node.BACKOFF_MULTIPLIER, this.reconnectAttempted);
196
+ const baseBackoff = this.reconnectTimeout * Math.pow(Node.BACKOFF_MULTIPLIER, this.reconnectAttempted - 1);
192
197
  const jitter = Math.random() * Math.min(2000, baseBackoff * 0.2);
193
198
  return Math.min(baseBackoff + jitter, Node.MAX_BACKOFF);
194
199
  }
195
200
 
196
- clearReconnectTimeout() {
197
- if (this.reconnectTimeoutId) {
198
- clearTimeout(this.reconnectTimeoutId);
199
- this.reconnectTimeoutId = null;
200
- }
201
- }
202
-
203
- async connect() {
201
+ connect() {
204
202
  if (this.isDestroyed) return;
205
-
203
+
206
204
  if (this.ws && this.ws.readyState === Node.WS_OPEN) {
207
205
  this.aqua.emit("debug", this.name, "WebSocket already connected");
208
206
  return;
209
207
  }
210
-
208
+
211
209
  this.cleanupExistingConnection();
212
210
 
213
211
  this.ws = new WebSocket(this.wsUrl, {
@@ -215,31 +213,35 @@ class Node {
215
213
  perMessageDeflate: false
216
214
  });
217
215
 
218
- this.ws.once("open", this._onOpen.bind(this));
219
- this.ws.once("error", this._onError.bind(this));
220
- this.ws.on("message", this._onMessage.bind(this));
221
- this.ws.once("close", this._onClose.bind(this));
216
+ this.ws.once("open", this._onOpen);
217
+ this.ws.once("error", this._onError);
218
+ this.ws.on("message", this._onMessage);
219
+ this.ws.once("close", this._onClose);
222
220
  }
223
221
 
224
222
  cleanupExistingConnection() {
225
223
  if (!this.ws) return;
226
224
 
227
225
  this.ws.removeAllListeners();
228
-
229
- if (this.ws.readyState === Node.WS_OPEN) {
230
- try {
231
- this.ws.close();
232
- } catch (err) {
233
- this.emitError(`Failed to close WebSocket: ${err.message}`);
226
+ try {
227
+ if (this.ws.readyState === Node.WS_OPEN) {
228
+ this.ws.close(Node.WS_CLOSE_NORMAL, "Manual closure");
234
229
  }
230
+ } catch (err) {
231
+ this.emitError(`Failed to close WebSocket: ${err.message}`);
235
232
  }
236
-
237
233
  this.ws = null;
238
234
  }
239
235
 
240
236
  destroy(clean = false) {
237
+ if (this.isDestroyed) return;
241
238
  this.isDestroyed = true;
242
- this.clearReconnectTimeout();
239
+
240
+ if (this.reconnectTimeoutId) {
241
+ clearTimeout(this.reconnectTimeoutId);
242
+ this.reconnectTimeoutId = null;
243
+ }
244
+
243
245
  this.cleanupExistingConnection();
244
246
 
245
247
  if (!clean) {
@@ -251,61 +253,29 @@ class Node {
251
253
  this.aqua.emit("nodeDestroy", this);
252
254
  this.info = null;
253
255
  }
254
-
255
- async getStats() {
256
- if (this.connected && this.stats) {
257
- return this.stats;
258
- }
259
-
260
- try {
261
- const newStats = await this.rest.getStats();
262
- if (newStats && this.stats) {
263
- this.stats.players = newStats.players ?? this.stats.players;
264
- this.stats.playingPlayers = newStats.playingPlayers ?? this.stats.playingPlayers;
265
- this.stats.uptime = newStats.uptime ?? this.stats.uptime;
266
- this.stats.ping = newStats.ping ?? this.stats.ping;
267
-
268
- if (newStats.memory) {
269
- Object.assign(this.stats.memory, newStats.memory);
270
- this._calculateMemoryPercentages();
271
- }
272
-
273
- if (newStats.cpu) {
274
- Object.assign(this.stats.cpu, newStats.cpu);
275
- this._calculateCpuPercentages();
276
- }
277
-
278
- if (newStats.frameStats) {
279
- Object.assign(this.stats.frameStats, newStats.frameStats);
280
- }
281
- }
282
- return this.stats;
283
- } catch (err) {
284
- this.emitError(`Failed to fetch node stats: ${err.message}`);
285
- return this.stats;
286
- }
287
- }
288
-
256
+
289
257
  _updateStats(payload) {
290
258
  if (!payload) return;
259
+
260
+ const { players, playingPlayers, uptime, memory, cpu, frameStats, ping } = payload;
261
+
262
+ this.stats.players = players;
263
+ this.stats.playingPlayers = playingPlayers;
264
+ this.stats.uptime = uptime;
265
+ this.stats.ping = ping ?? this.stats.ping;
291
266
 
292
- this.stats.players = payload.players;
293
- this.stats.playingPlayers = payload.playingPlayers;
294
- this.stats.uptime = payload.uptime;
295
- this.stats.ping = payload.ping;
296
-
297
- if (payload.memory) {
298
- Object.assign(this.stats.memory, payload.memory);
267
+ if (memory) {
268
+ Object.assign(this.stats.memory, memory);
299
269
  this._calculateMemoryPercentages();
300
270
  }
301
271
 
302
- if (payload.cpu) {
303
- Object.assign(this.stats.cpu, payload.cpu);
272
+ if (cpu) {
273
+ Object.assign(this.stats.cpu, cpu);
304
274
  this._calculateCpuPercentages();
305
275
  }
306
276
 
307
- if (payload.frameStats) {
308
- Object.assign(this.stats.frameStats, payload.frameStats);
277
+ if (frameStats) {
278
+ Object.assign(this.stats.frameStats, frameStats);
309
279
  }
310
280
  }
311
281
 
@@ -324,16 +294,16 @@ class Node {
324
294
  }
325
295
  }
326
296
 
327
- _handleReadyOp(payload) {
328
- if (!payload.sessionId) {
297
+ _handleReadyOp({ sessionId }) {
298
+ if (!sessionId) {
329
299
  this.emitError("Ready payload missing sessionId");
330
300
  return;
331
301
  }
332
302
 
333
- this.sessionId = payload.sessionId;
334
- this.rest.setSessionId(payload.sessionId);
303
+ this.sessionId = sessionId;
304
+ this.rest.setSessionId(sessionId);
335
305
  this._headers = this._constructHeaders();
336
- this.aqua.emit("nodeConnect", this);
306
+ this.aqua.emit("nodeReady", this);
337
307
  }
338
308
 
339
309
  async resumePlayers() {
@@ -344,6 +314,7 @@ class Node {
344
314
  this.emitError(`Failed to resume session: ${err.message}`);
345
315
  }
346
316
  }
317
+
347
318
  emitError(error) {
348
319
  const errorObj = error instanceof Error ? error : new Error(error);
349
320
  console.error(`[Aqua] [${this.name}] Error:`, errorObj);
@@ -458,7 +458,7 @@ class Player extends EventEmitter {
458
458
  try {
459
459
  await this.nowPlayingMessage.delete();
460
460
  } catch (error) {
461
- console.error("Error deleting now playing message:", error);
461
+ // Ignore
462
462
  } finally {
463
463
  this.nowPlayingMessage = null;
464
464
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aqualink",
3
- "version": "2.7.0",
3
+ "version": "2.7.1",
4
4
  "description": "An Lavalink client, focused in pure performance and features",
5
5
  "main": "build/index.js",
6
6
  "types": "index.d.ts",
@@ -42,7 +42,6 @@
42
42
  },
43
43
  "dependencies": {
44
44
  "ws": "^8.18.3",
45
- "fs-extra": "^11.3.0",
46
45
  "tseep": "^1.3.1"
47
46
  },
48
47
  "maintainers": [