magmastream 2.9.0-dev.10 → 2.9.0-dev.12

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
@@ -100,7 +100,7 @@
100
100
  | [HamBot](https://discord.com/oauth2/authorize?client_id=1049314312776335390) | yanishamburger|
101
101
  | [Miyu](https://discord.com/oauth2/authorize?client_id=1277180179273482280&permissions=572851999731703&response_type=code&redirect_uri=https%3A%2F%2Fdiscord.gg%2Ftn3nbFB8nX&integration_type=0&scope=identify+applications.commands+bot) | Kenver |
102
102
  | [Savage Bot](https://discord.com/oauth2/authorize?client_id=823703707522433054&permissions=8&scope=bot%20applications.commands) | Savage
103
- | [rive](https://discord.com/oauth2/authorize?client_id=1350601402325405806) | pomice
103
+ | [lost](https://discord.com/oauth2/authorize?client_id=1280681209604739204) | pomice
104
104
 
105
105
 
106
106
  Want to showcase your bot? Feel free to create a pull request and add it to our growing list of amazing bots powered by Magmastream!
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Queue = void 0;
4
4
  const Manager_1 = require("./Manager"); // Import Manager to access emit method
5
+ const logExecutionTime_1 = require("../utils/logExecutionTime");
5
6
  /**
6
7
  * The player's queue, the `current` property is the currently playing track, think of the rest as the up-coming tracks.
7
8
  */
@@ -27,32 +28,44 @@ class Queue extends Array {
27
28
  this.guildId = guildId;
28
29
  }
29
30
  async getCurrent() {
30
- return this.current;
31
+ return (0, logExecutionTime_1.logExecutionTime)("getCurrent (Collection)", async () => {
32
+ return this.current;
33
+ });
31
34
  }
32
35
  async setCurrent(track) {
33
- this.current = track;
36
+ return (0, logExecutionTime_1.logExecutionTime)("setCurrent (Collection)", async () => {
37
+ this.current = track;
38
+ });
34
39
  }
35
40
  async getPrevious() {
36
- return this.previous;
41
+ return (0, logExecutionTime_1.logExecutionTime)("getPrevious (Collection)", async () => {
42
+ return this.previous;
43
+ });
37
44
  }
38
45
  async addPrevious(track) {
39
- if (Array.isArray(track)) {
40
- this.previous.unshift(...track);
41
- }
42
- else {
43
- this.previous.unshift(track);
44
- }
46
+ return (0, logExecutionTime_1.logExecutionTime)("addPrevious (Collection)", async () => {
47
+ if (Array.isArray(track)) {
48
+ this.previous.unshift(...track);
49
+ }
50
+ else {
51
+ this.previous.unshift(track);
52
+ }
53
+ });
45
54
  }
46
55
  async clearPrevious() {
47
- this.previous = [];
56
+ return (0, logExecutionTime_1.logExecutionTime)("clearPrevious (Collection)", async () => {
57
+ this.previous = [];
58
+ });
48
59
  }
49
60
  /**
50
61
  * The total duration of the queue in milliseconds.
51
62
  * This includes the duration of the currently playing track.
52
63
  */
53
64
  async duration() {
54
- const current = this.current?.duration ?? 0;
55
- return this.reduce((acc, cur) => acc + (cur.duration || 0), current);
65
+ return (0, logExecutionTime_1.logExecutionTime)("duration (Collection)", async () => {
66
+ const current = this.current?.duration ?? 0;
67
+ return this.reduce((acc, cur) => acc + (cur.duration || 0), current);
68
+ });
56
69
  }
57
70
  /**
58
71
  * The total size of tracks in the queue including the current track.
@@ -60,7 +73,9 @@ class Queue extends Array {
60
73
  * @returns The total size of tracks in the queue including the current track.
61
74
  */
62
75
  async totalSize() {
63
- return this.length + (this.current ? 1 : 0);
76
+ return (0, logExecutionTime_1.logExecutionTime)("totalSize (Collection)", async () => {
77
+ return this.length + (this.current ? 1 : 0);
78
+ });
64
79
  }
65
80
  /**
66
81
  * The size of tracks in the queue.
@@ -68,7 +83,9 @@ class Queue extends Array {
68
83
  * @returns The size of tracks in the queue.
69
84
  */
70
85
  async size() {
71
- return this.length;
86
+ return (0, logExecutionTime_1.logExecutionTime)("size (Collection)", async () => {
87
+ return this.length;
88
+ });
72
89
  }
73
90
  /**
74
91
  * Adds a track to the queue.
@@ -76,274 +93,307 @@ class Queue extends Array {
76
93
  * @param [offset=null] The position to add the track(s) at. If not provided, the track(s) will be added at the end of the queue.
77
94
  */
78
95
  async add(track, offset) {
79
- // Get the track info as a string
80
- const trackInfo = Array.isArray(track) ? track.map((t) => JSON.stringify(t, null, 2)).join(", ") : JSON.stringify(track, null, 2);
81
- // Emit a debug message
82
- this.manager.emit(Manager_1.ManagerEventTypes.Debug, `[QUEUE] Added ${Array.isArray(track) ? track.length : 1} track(s) to queue: ${trackInfo}`);
83
- const oldPlayer = (await this.manager.players.get(this.guildId)) ? { ...(await this.manager.players.get(this.guildId)) } : null;
84
- // If the track is valid, add it to the queue
85
- // If the queue is empty, set the track as the current track
86
- if (!this.current) {
87
- if (Array.isArray(track)) {
88
- this.current = track.shift() || null;
89
- this.push(...track);
90
- }
91
- else {
92
- this.current = track;
93
- }
94
- }
95
- else {
96
- // If an offset is provided, add the track(s) at that position
97
- if (typeof offset !== "undefined" && typeof offset === "number") {
98
- // Validate the offset
99
- if (isNaN(offset)) {
100
- throw new RangeError("Offset must be a number.");
101
- }
102
- // Make sure the offset is between 0 and the length of the queue
103
- if (offset < 0 || offset > this.length) {
104
- throw new RangeError(`Offset must be between 0 and ${this.length}.`);
105
- }
106
- // Add the track(s) at the offset position
96
+ return (0, logExecutionTime_1.logExecutionTime)("add (Collection)", async () => {
97
+ // Get the track info as a string
98
+ const trackInfo = Array.isArray(track) ? track.map((t) => JSON.stringify(t, null, 2)).join(", ") : JSON.stringify(track, null, 2);
99
+ // Emit a debug message
100
+ this.manager.emit(Manager_1.ManagerEventTypes.Debug, `[QUEUE] Added ${Array.isArray(track) ? track.length : 1} track(s) to queue: ${trackInfo}`);
101
+ const oldPlayer = this.manager.players.get(this.guildId) ? { ...this.manager.players.get(this.guildId) } : null;
102
+ // If the queue is empty, set the track as the current track
103
+ if (!this.current) {
107
104
  if (Array.isArray(track)) {
108
- this.splice(offset, 0, ...track);
105
+ this.current = track.shift() || null;
106
+ this.push(...track);
109
107
  }
110
108
  else {
111
- this.splice(offset, 0, track);
109
+ this.current = track;
112
110
  }
113
111
  }
114
112
  else {
115
- // If no offset is provided, add the track(s) at the end of the queue
116
- if (Array.isArray(track)) {
117
- this.push(...track);
113
+ // If an offset is provided, add the track(s) at that position
114
+ if (typeof offset !== "undefined" && typeof offset === "number") {
115
+ // Validate the offset
116
+ if (isNaN(offset)) {
117
+ throw new RangeError("Offset must be a number.");
118
+ }
119
+ // Make sure the offset is between 0 and the length of the queue
120
+ if (offset < 0 || offset > this.length) {
121
+ throw new RangeError(`Offset must be between 0 and ${this.length}.`);
122
+ }
123
+ // Add the track(s) at the offset position
124
+ if (Array.isArray(track)) {
125
+ this.splice(offset, 0, ...track);
126
+ }
127
+ else {
128
+ this.splice(offset, 0, track);
129
+ }
118
130
  }
119
131
  else {
120
- this.push(track);
132
+ // If no offset is provided, add the track(s) at the end of the queue
133
+ if (Array.isArray(track)) {
134
+ this.push(...track);
135
+ }
136
+ else {
137
+ this.push(track);
138
+ }
121
139
  }
122
140
  }
123
- }
124
- if ((await this.manager.players.has(this.guildId)) && (await this.manager.players.get(this.guildId)).isAutoplay) {
125
- if (!Array.isArray(track)) {
126
- const botUser = (await (await this.manager.players.get(this.guildId)).get("Internal_BotUser"));
127
- if (botUser && botUser.id === track.requester.id) {
128
- this.manager.emit(Manager_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, await this.manager.players.get(this.guildId), {
129
- changeType: Manager_1.PlayerStateEventTypes.QueueChange,
130
- details: {
131
- changeType: "autoPlayAdd",
132
- tracks: Array.isArray(track) ? track : [track],
133
- },
134
- });
135
- return;
141
+ if (this.manager.players.has(this.guildId) && this.manager.players.get(this.guildId).isAutoplay) {
142
+ if (!Array.isArray(track)) {
143
+ const botUser = this.manager.players.get(this.guildId).get("Internal_BotUser");
144
+ if (botUser && botUser.id === track.requester.id) {
145
+ this.manager.emit(Manager_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this.manager.players.get(this.guildId), {
146
+ changeType: Manager_1.PlayerStateEventTypes.QueueChange,
147
+ details: {
148
+ changeType: "autoPlayAdd",
149
+ tracks: Array.isArray(track) ? track : [track],
150
+ },
151
+ });
152
+ return;
153
+ }
136
154
  }
137
155
  }
138
- }
139
- // Emit a player state update event with the added track(s)
140
- this.manager.emit(Manager_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, await this.manager.players.get(this.guildId), {
141
- changeType: Manager_1.PlayerStateEventTypes.QueueChange,
142
- details: {
143
- changeType: "add",
144
- tracks: Array.isArray(track) ? track : [track],
145
- },
156
+ // Emit a player state update event with the added track(s)
157
+ this.manager.emit(Manager_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this.manager.players.get(this.guildId), {
158
+ changeType: Manager_1.PlayerStateEventTypes.QueueChange,
159
+ details: {
160
+ changeType: "add",
161
+ tracks: Array.isArray(track) ? track : [track],
162
+ },
163
+ });
146
164
  });
147
165
  }
148
166
  async remove(startOrPosition = 0, end) {
149
- const oldPlayer = (await this.manager.players.get(this.guildId)) ? { ...(await this.manager.players.get(this.guildId)) } : null;
150
- if (typeof end !== "undefined") {
151
- // Validate input for `start` and `end`
152
- if (isNaN(Number(startOrPosition)) || isNaN(Number(end))) {
153
- throw new RangeError(`Invalid "start" or "end" parameter: start = ${startOrPosition}, end = ${end}`);
154
- }
155
- if (startOrPosition >= end || startOrPosition >= this.length) {
156
- throw new RangeError("Invalid range: start should be less than end and within queue length.");
167
+ return (0, logExecutionTime_1.logExecutionTime)("remove (Collection)", async () => {
168
+ const oldPlayer = this.manager.players.get(this.guildId) ? { ...this.manager.players.get(this.guildId) } : null;
169
+ if (typeof end !== "undefined") {
170
+ // Validate input for `start` and `end`
171
+ if (isNaN(Number(startOrPosition)) || isNaN(Number(end))) {
172
+ throw new RangeError(`Invalid "start" or "end" parameter: start = ${startOrPosition}, end = ${end}`);
173
+ }
174
+ if (startOrPosition >= end || startOrPosition >= this.length) {
175
+ throw new RangeError("Invalid range: start should be less than end and within queue length.");
176
+ }
177
+ const removedTracks = this.splice(startOrPosition, end - startOrPosition);
178
+ this.manager.emit(Manager_1.ManagerEventTypes.Debug, `[QUEUE] Removed ${removedTracks.length} track(s) from player: ${this.guildId} from position ${startOrPosition} to ${end}.`);
179
+ this.manager.emit(Manager_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this.manager.players.get(this.guildId), {
180
+ changeType: Manager_1.PlayerStateEventTypes.QueueChange,
181
+ details: {
182
+ changeType: "remove",
183
+ tracks: removedTracks,
184
+ },
185
+ });
186
+ return removedTracks;
157
187
  }
158
- const removedTracks = this.splice(startOrPosition, end - startOrPosition);
159
- this.manager.emit(Manager_1.ManagerEventTypes.Debug, `[QUEUE] Removed ${removedTracks.length} track(s) from player: ${this.guildId} from position ${startOrPosition} to ${end}.`);
160
- this.manager.emit(Manager_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, await this.manager.players.get(this.guildId), {
188
+ // Single item removal when no end specified
189
+ const removedTrack = this.splice(startOrPosition, 1);
190
+ this.manager.emit(Manager_1.ManagerEventTypes.Debug, `[QUEUE] Removed 1 track from player: ${this.guildId} from position ${startOrPosition}: ${JSON.stringify(removedTrack[0], null, 2)}`);
191
+ // Ensure removedTrack is an array for consistency
192
+ const tracksToEmit = removedTrack.length > 0 ? removedTrack : [];
193
+ this.manager.emit(Manager_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this.manager.players.get(this.guildId), {
161
194
  changeType: Manager_1.PlayerStateEventTypes.QueueChange,
162
195
  details: {
163
196
  changeType: "remove",
164
- tracks: removedTracks,
197
+ tracks: tracksToEmit,
165
198
  },
166
199
  });
167
- return removedTracks;
168
- }
169
- // Single item removal when no end specified
170
- const removedTrack = this.splice(startOrPosition, 1);
171
- this.manager.emit(Manager_1.ManagerEventTypes.Debug, `[QUEUE] Removed 1 track from player: ${this.guildId} from position ${startOrPosition}: ${JSON.stringify(removedTrack[0], null, 2)}`);
172
- // Ensure removedTrack is an array for consistency
173
- const tracksToEmit = removedTrack.length > 0 ? removedTrack : [];
174
- this.manager.emit(Manager_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, await this.manager.players.get(this.guildId), {
175
- changeType: Manager_1.PlayerStateEventTypes.QueueChange,
176
- details: {
177
- changeType: "remove",
178
- tracks: tracksToEmit,
179
- },
200
+ return removedTrack;
180
201
  });
181
- return removedTrack;
182
202
  }
183
203
  /**
184
204
  * Clears the queue.
185
205
  * This will remove all tracks from the queue and emit a state update event.
186
206
  */
187
207
  async clear() {
188
- // Capture the current state of the player for event emission.
189
- const oldPlayer = (await this.manager.players.get(this.guildId)) ? { ...(await this.manager.players.get(this.guildId)) } : null;
190
- // Remove all items from the queue.
191
- this.splice(0);
192
- // Emit an event to update the player state indicating the queue has been cleared.
193
- this.manager.emit(Manager_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, await this.manager.players.get(this.guildId), {
194
- changeType: Manager_1.PlayerStateEventTypes.QueueChange,
195
- details: {
196
- changeType: "clear",
197
- tracks: [], // No tracks are left after clearing
198
- },
208
+ return (0, logExecutionTime_1.logExecutionTime)("clear (Collection)", async () => {
209
+ // Capture the current state of the player for event emission.
210
+ const oldPlayer = this.manager.players.get(this.guildId) ? { ...this.manager.players.get(this.guildId) } : null;
211
+ // Remove all items from the queue.
212
+ this.splice(0);
213
+ // Emit an event to update the player state indicating the queue has been cleared.
214
+ this.manager.emit(Manager_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, await this.manager.players.get(this.guildId), {
215
+ changeType: Manager_1.PlayerStateEventTypes.QueueChange,
216
+ details: {
217
+ changeType: "clear",
218
+ tracks: [], // No tracks are left after clearing
219
+ },
220
+ });
221
+ // Emit a debug message indicating the queue has been cleared for a specific guild ID.
222
+ this.manager.emit(Manager_1.ManagerEventTypes.Debug, `[QUEUE] Cleared the queue for: ${this.guildId}`);
199
223
  });
200
- // Emit a debug message indicating the queue has been cleared for a specific guild ID.
201
- this.manager.emit(Manager_1.ManagerEventTypes.Debug, `[QUEUE] Cleared the queue for: ${this.guildId}`);
202
224
  }
203
225
  /**
204
226
  * Shuffles the queue.
205
227
  * This will randomize the order of the tracks in the queue and emit a state update event.
206
228
  */
207
229
  async shuffle() {
208
- // Capture the current state of the player for event emission.
209
- const oldPlayer = (await this.manager.players.get(this.guildId)) ? { ...(await this.manager.players.get(this.guildId)) } : null;
210
- // Shuffle the queue.
211
- for (let i = this.length - 1; i > 0; i--) {
212
- const j = Math.floor(Math.random() * (i + 1));
213
- [this[i], this[j]] = [this[j], this[i]];
214
- }
215
- // Emit an event to update the player state indicating the queue has been shuffled.
216
- this.manager.emit(Manager_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, await this.manager.players.get(this.guildId), {
217
- changeType: Manager_1.PlayerStateEventTypes.QueueChange,
218
- details: {
219
- changeType: "shuffle",
220
- },
230
+ return (0, logExecutionTime_1.logExecutionTime)("shuffle (Collection)", async () => {
231
+ // Capture the current state of the player for event emission.
232
+ const oldPlayer = this.manager.players.get(this.guildId) ? { ...this.manager.players.get(this.guildId) } : null;
233
+ // Shuffle the queue.
234
+ for (let i = this.length - 1; i > 0; i--) {
235
+ const j = Math.floor(Math.random() * (i + 1));
236
+ [this[i], this[j]] = [this[j], this[i]];
237
+ }
238
+ // Emit an event to update the player state indicating the queue has been shuffled.
239
+ this.manager.emit(Manager_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, await this.manager.players.get(this.guildId), {
240
+ changeType: Manager_1.PlayerStateEventTypes.QueueChange,
241
+ details: {
242
+ changeType: "shuffle",
243
+ },
244
+ });
245
+ // Emit a debug message indicating the queue has been shuffled for a specific guild ID.
246
+ this.manager.emit(Manager_1.ManagerEventTypes.Debug, `[QUEUE] Shuffled the queue for: ${this.guildId}`);
221
247
  });
222
- // Emit a debug message indicating the queue has been shuffled for a specific guild ID.
223
- this.manager.emit(Manager_1.ManagerEventTypes.Debug, `[QUEUE] Shuffled the queue for: ${this.guildId}`);
224
248
  }
225
249
  /**
226
250
  * Shuffles the queue to play tracks requested by each user one block at a time.
227
251
  */
228
252
  async userBlockShuffle() {
229
- // Capture the current state of the player for event emission.
230
- const oldPlayer = (await this.manager.players.get(this.guildId)) ? { ...(await this.manager.players.get(this.guildId)) } : null;
231
- // Group the tracks in the queue by the user that requested them.
232
- const userTracks = new Map();
233
- this.forEach((track) => {
234
- const user = track.requester.id;
235
- if (!userTracks.has(user)) {
236
- userTracks.set(user, []);
237
- }
238
- userTracks.get(user).push(track);
239
- });
240
- // Create a new array for the shuffled queue.
241
- const shuffledQueue = [];
242
- // Iterate over the user tracks and add one track from each user to the shuffled queue.
243
- // This will ensure that all the tracks requested by each user are played in a block order.
244
- while (shuffledQueue.length < this.length) {
245
- userTracks.forEach((tracks) => {
246
- const track = tracks.shift();
247
- if (track) {
248
- shuffledQueue.push(track);
253
+ return (0, logExecutionTime_1.logExecutionTime)("userBlockShuffle (Collection)", async () => {
254
+ // Capture the current state of the player for event emission.
255
+ const oldPlayer = this.manager.players.get(this.guildId) ? { ...this.manager.players.get(this.guildId) } : null;
256
+ // Group the tracks in the queue by the user that requested them.
257
+ const userTracks = new Map();
258
+ this.forEach((track) => {
259
+ const user = track.requester.id;
260
+ if (!userTracks.has(user)) {
261
+ userTracks.set(user, []);
249
262
  }
263
+ userTracks.get(user).push(track);
264
+ });
265
+ // Create a new array for the shuffled queue.
266
+ const shuffledQueue = [];
267
+ // Iterate over the user tracks and add one track from each user to the shuffled queue.
268
+ // This will ensure that all the tracks requested by each user are played in a block order.
269
+ while (shuffledQueue.length < this.length) {
270
+ userTracks.forEach((tracks) => {
271
+ const track = tracks.shift();
272
+ if (track) {
273
+ shuffledQueue.push(track);
274
+ }
275
+ });
276
+ }
277
+ // Clear the queue and add the shuffled tracks.
278
+ this.splice(0);
279
+ this.add(shuffledQueue);
280
+ // Emit an event to update the player state indicating the queue has been shuffled.
281
+ this.manager.emit(Manager_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, await this.manager.players.get(this.guildId), {
282
+ changeType: Manager_1.PlayerStateEventTypes.QueueChange,
283
+ details: {
284
+ changeType: "userBlock",
285
+ },
250
286
  });
251
- }
252
- // Clear the queue and add the shuffled tracks.
253
- this.splice(0);
254
- this.add(shuffledQueue);
255
- // Emit an event to update the player state indicating the queue has been shuffled.
256
- this.manager.emit(Manager_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, await this.manager.players.get(this.guildId), {
257
- changeType: Manager_1.PlayerStateEventTypes.QueueChange,
258
- details: {
259
- changeType: "userBlock",
260
- },
287
+ // Emit a debug message indicating the queue has been shuffled for a specific guild ID.
288
+ this.manager.emit(Manager_1.ManagerEventTypes.Debug, `[QUEUE] userBlockShuffled the queue for: ${this.guildId}`);
261
289
  });
262
- // Emit a debug message indicating the queue has been shuffled for a specific guild ID.
263
- this.manager.emit(Manager_1.ManagerEventTypes.Debug, `[QUEUE] userBlockShuffled the queue for: ${this.guildId}`);
264
290
  }
265
291
  /**
266
292
  * Shuffles the queue to play tracks requested by each user one by one.
267
293
  */
268
294
  async roundRobinShuffle() {
269
- const oldPlayer = (await this.manager.players.get(this.guildId)) ? { ...(await this.manager.players.get(this.guildId)) } : null;
270
- const userTracks = new Map();
271
- // Group the tracks in the queue by the user that requested them.
272
- this.forEach((track) => {
273
- const user = track.requester.id;
274
- if (!userTracks.has(user)) {
275
- userTracks.set(user, []);
276
- }
277
- userTracks.get(user).push(track);
278
- });
279
- // Shuffle the tracks of each user.
280
- userTracks.forEach((tracks) => {
281
- for (let i = tracks.length - 1; i > 0; i--) {
282
- const j = Math.floor(Math.random() * (i + 1));
283
- [tracks[i], tracks[j]] = [tracks[j], tracks[i]];
284
- }
285
- });
286
- // Create a new array for the shuffled queue.
287
- const shuffledQueue = [];
288
- // Add the shuffled tracks to the queue in a round-robin fashion.
289
- const users = Array.from(userTracks.keys());
290
- const userQueues = users.map((user) => userTracks.get(user));
291
- const userCount = users.length;
292
- while (userQueues.some((queue) => queue.length > 0)) {
293
- for (let i = 0; i < userCount; i++) {
294
- const queue = userQueues[i];
295
- if (queue.length > 0) {
296
- shuffledQueue.push(queue.shift());
295
+ return (0, logExecutionTime_1.logExecutionTime)("roundRobinShuffle (Collection)", async () => {
296
+ // Capture the current state of the player for event emission.
297
+ const oldPlayer = this.manager.players.get(this.guildId) ? { ...this.manager.players.get(this.guildId) } : null;
298
+ // Group the tracks in the queue by the user that requested them.
299
+ const userTracks = new Map();
300
+ // Group the tracks in the queue by the user that requested them.
301
+ this.forEach((track) => {
302
+ const user = track.requester.id;
303
+ if (!userTracks.has(user)) {
304
+ userTracks.set(user, []);
305
+ }
306
+ userTracks.get(user).push(track);
307
+ });
308
+ // Shuffle the tracks of each user.
309
+ userTracks.forEach((tracks) => {
310
+ for (let i = tracks.length - 1; i > 0; i--) {
311
+ const j = Math.floor(Math.random() * (i + 1));
312
+ [tracks[i], tracks[j]] = [tracks[j], tracks[i]];
313
+ }
314
+ });
315
+ // Create a new array for the shuffled queue.
316
+ const shuffledQueue = [];
317
+ // Add the shuffled tracks to the queue in a round-robin fashion.
318
+ const users = Array.from(userTracks.keys());
319
+ const userQueues = users.map((user) => userTracks.get(user));
320
+ const userCount = users.length;
321
+ while (userQueues.some((queue) => queue.length > 0)) {
322
+ for (let i = 0; i < userCount; i++) {
323
+ const queue = userQueues[i];
324
+ if (queue.length > 0) {
325
+ shuffledQueue.push(queue.shift());
326
+ }
297
327
  }
298
328
  }
299
- }
300
- // Clear the queue and add the shuffled tracks.
301
- this.splice(0);
302
- this.add(shuffledQueue);
303
- // Emit an event to update the player state indicating the queue has been shuffled.
304
- this.manager.emit(Manager_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, await this.manager.players.get(this.guildId), {
305
- changeType: Manager_1.PlayerStateEventTypes.QueueChange,
306
- details: {
307
- changeType: "roundRobin",
308
- },
329
+ // Clear the queue and add the shuffled tracks.
330
+ this.splice(0);
331
+ this.add(shuffledQueue);
332
+ // Emit an event to update the player state indicating the queue has been shuffled.
333
+ this.manager.emit(Manager_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, await this.manager.players.get(this.guildId), {
334
+ changeType: Manager_1.PlayerStateEventTypes.QueueChange,
335
+ details: {
336
+ changeType: "roundRobin",
337
+ },
338
+ });
339
+ // Emit a debug message indicating the queue has been shuffled for a specific guild ID.
340
+ this.manager.emit(Manager_1.ManagerEventTypes.Debug, `[QUEUE] roundRobinShuffled the queue for: ${this.guildId}`);
309
341
  });
310
- // Emit a debug message indicating the queue has been shuffled for a specific guild ID.
311
- this.manager.emit(Manager_1.ManagerEventTypes.Debug, `[QUEUE] roundRobinShuffled the queue for: ${this.guildId}`);
312
342
  }
313
343
  async dequeue() {
314
- return super.shift();
344
+ return (0, logExecutionTime_1.logExecutionTime)("dequeue (Collection)", async () => {
345
+ return super.shift();
346
+ });
315
347
  }
316
348
  async enqueueFront(track) {
317
- if (Array.isArray(track)) {
318
- this.unshift(...track);
319
- }
320
- else {
321
- this.unshift(track);
322
- }
349
+ return (0, logExecutionTime_1.logExecutionTime)("enqueueFront (Collection)", async () => {
350
+ if (Array.isArray(track)) {
351
+ this.unshift(...track);
352
+ }
353
+ else {
354
+ this.unshift(track);
355
+ }
356
+ });
323
357
  }
324
358
  async getTracks() {
325
- return [...this]; // clone to avoid direct mutation
359
+ return (0, logExecutionTime_1.logExecutionTime)("getTracks (Collection)", async () => {
360
+ return [...this]; // clone to avoid direct mutation
361
+ });
326
362
  }
327
363
  async getSlice(start, end) {
328
- return this.slice(start, end); // Native sync method, still wrapped in a Promise
364
+ return (0, logExecutionTime_1.logExecutionTime)("getSlice (Collection)", async () => {
365
+ return this.slice(start, end); // Native sync method, still wrapped in a Promise
366
+ });
329
367
  }
330
368
  async modifyAt(start, deleteCount = 0, ...items) {
331
- return super.splice(start, deleteCount, ...items);
369
+ return (0, logExecutionTime_1.logExecutionTime)("modifyAt (Collection)", async () => {
370
+ return super.splice(start, deleteCount, ...items);
371
+ });
332
372
  }
333
373
  async mapAsync(callback) {
334
- return this.map(callback);
374
+ return (0, logExecutionTime_1.logExecutionTime)("mapAsync (Collection)", async () => {
375
+ return this.map(callback);
376
+ });
335
377
  }
336
378
  async filterAsync(callback) {
337
- return this.filter(callback);
379
+ return (0, logExecutionTime_1.logExecutionTime)("filterAsync (Collection)", async () => {
380
+ return this.filter(callback);
381
+ });
338
382
  }
339
383
  async findAsync(callback) {
340
- return this.find(callback);
384
+ return (0, logExecutionTime_1.logExecutionTime)("findAsync (Collection)", async () => {
385
+ return this.find(callback);
386
+ });
341
387
  }
342
388
  async someAsync(callback) {
343
- return this.some(callback);
389
+ return (0, logExecutionTime_1.logExecutionTime)("someAsync (Collection)", async () => {
390
+ return this.some(callback);
391
+ });
344
392
  }
345
393
  async everyAsync(callback) {
346
- return this.every(callback);
394
+ return (0, logExecutionTime_1.logExecutionTime)("everyAsync (Collection)", async () => {
395
+ return this.every(callback);
396
+ });
347
397
  }
348
398
  }
349
399
  exports.Queue = Queue;
@@ -2,11 +2,10 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.RedisQueue = void 0;
4
4
  const Manager_1 = require("./Manager");
5
+ const logExecutionTime_1 = require("../utils/logExecutionTime");
5
6
  class RedisQueue {
6
7
  guildId;
7
8
  manager;
8
- current = null;
9
- previous = [];
10
9
  redis;
11
10
  redisPrefix;
12
11
  constructor(guildId, manager) {
@@ -34,268 +33,315 @@ class RedisQueue {
34
33
  return JSON.parse(data);
35
34
  }
36
35
  async getCurrent() {
37
- const raw = await this.redis.get(this.currentKey);
38
- return raw ? this.deserialize(raw) : null;
36
+ return (0, logExecutionTime_1.logExecutionTime)("getCurrent (RedisQueue)", async () => {
37
+ const raw = await this.redis.get(this.currentKey);
38
+ return raw ? this.deserialize(raw) : null;
39
+ });
39
40
  }
40
41
  async setCurrent(track) {
41
- if (track) {
42
- await this.redis.set(this.currentKey, this.serialize(track));
43
- }
44
- else {
45
- await this.redis.del(this.currentKey);
46
- }
42
+ return (0, logExecutionTime_1.logExecutionTime)("setCurrent (RedisQueue)", async () => {
43
+ if (track) {
44
+ await this.redis.set(this.currentKey, this.serialize(track));
45
+ }
46
+ else {
47
+ await this.redis.del(this.currentKey);
48
+ }
49
+ });
47
50
  }
48
51
  async getPrevious() {
49
- const raw = await this.redis.lrange(this.previousKey, 0, -1);
50
- return raw.map(this.deserialize);
52
+ return (0, logExecutionTime_1.logExecutionTime)("getPrevious (RedisQueue)", async () => {
53
+ const raw = await this.redis.lrange(this.previousKey, 0, -1);
54
+ return raw.map(this.deserialize);
55
+ });
51
56
  }
52
57
  async addPrevious(track) {
53
- const tracks = Array.isArray(track) ? track : [track];
54
- if (!tracks.length)
55
- return;
56
- const serialized = tracks.map(this.serialize);
57
- if (!serialized.length)
58
- return; // avoid lpush with no values
59
- await this.redis.lpush(this.previousKey, ...serialized.reverse());
58
+ return (0, logExecutionTime_1.logExecutionTime)("addPrevious (RedisQueue)", async () => {
59
+ const tracks = Array.isArray(track) ? track : [track];
60
+ if (!tracks.length)
61
+ return;
62
+ const serialized = tracks.map(this.serialize);
63
+ if (!serialized.length)
64
+ return; // avoid lpush with no values
65
+ await this.redis.lpush(this.previousKey, ...serialized.reverse());
66
+ });
60
67
  }
61
68
  async clearPrevious() {
62
- await this.redis.del(this.previousKey);
69
+ return (0, logExecutionTime_1.logExecutionTime)("clearPrevious (RedisQueue)", async () => {
70
+ await this.redis.del(this.previousKey);
71
+ });
63
72
  }
64
73
  async add(track, offset) {
65
- const isArray = Array.isArray(track);
66
- const tracks = isArray ? track : [track];
67
- const serialized = tracks.map((t) => this.serialize(t));
68
- const oldPlayer = this.manager.players.get(this.guildId) ? { ...this.manager.players.get(this.guildId) } : null;
69
- // If there's no current track, pop one from the list
70
- if (!this.current) {
71
- const current = serialized.shift();
72
- if (current) {
73
- await this.redis.set(this.currentKey, current);
74
- this.current = this.deserialize(current);
74
+ return (0, logExecutionTime_1.logExecutionTime)("add (RedisQueue)", async () => {
75
+ const isArray = Array.isArray(track);
76
+ const tracks = isArray ? track : [track];
77
+ const serialized = tracks.map((t) => this.serialize(t));
78
+ const oldPlayer = this.manager.players.get(this.guildId) ? { ...this.manager.players.get(this.guildId) } : null;
79
+ // If there's no current track, pop one from the list
80
+ if (!(await this.getCurrent())) {
81
+ const current = serialized.shift();
82
+ if (current) {
83
+ await this.setCurrent(this.deserialize(current));
84
+ }
75
85
  }
76
- }
77
- if (typeof offset === "number" && !isNaN(offset)) {
78
- const queue = await this.redis.lrange(this.queueKey, 0, -1);
79
- queue.splice(offset, 0, ...serialized);
80
- await this.redis.del(this.queueKey);
81
- if (queue.length > 0) {
82
- await this.redis.rpush(this.queueKey, ...queue);
86
+ if (typeof offset === "number" && !isNaN(offset)) {
87
+ const queue = await this.redis.lrange(this.queueKey, 0, -1);
88
+ queue.splice(offset, 0, ...serialized);
89
+ await this.redis.del(this.queueKey);
90
+ if (queue.length > 0) {
91
+ await this.redis.rpush(this.queueKey, ...queue);
92
+ }
93
+ }
94
+ else if (serialized.length > 0) {
95
+ await this.redis.rpush(this.queueKey, ...serialized);
83
96
  }
84
- }
85
- else if (serialized.length > 0) {
86
- await this.redis.rpush(this.queueKey, ...serialized);
87
- }
88
- this.manager.emit(Manager_1.ManagerEventTypes.Debug, `[QUEUE] Added ${tracks.length} track(s) to queue`);
89
- if (this.manager.players.has(this.guildId) && this.manager.players.get(this.guildId).isAutoplay) {
90
- if (!Array.isArray(track)) {
91
- const botUser = (await this.manager.players.get(this.guildId).get("Internal_BotUser"));
92
- if (botUser && botUser.id === track.requester.id) {
93
- this.manager.emit(Manager_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this.manager.players.get(this.guildId), {
94
- changeType: Manager_1.PlayerStateEventTypes.QueueChange,
95
- details: {
96
- changeType: "autoPlayAdd",
97
- tracks: Array.isArray(track) ? track : [track],
98
- },
99
- });
100
- return;
97
+ this.manager.emit(Manager_1.ManagerEventTypes.Debug, `[QUEUE] Added ${tracks.length} track(s) to queue`);
98
+ if (this.manager.players.has(this.guildId) && this.manager.players.get(this.guildId).isAutoplay) {
99
+ if (!Array.isArray(track)) {
100
+ const botUser = (await this.manager.players.get(this.guildId).get("Internal_BotUser"));
101
+ if (botUser && botUser.id === track.requester.id) {
102
+ this.manager.emit(Manager_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this.manager.players.get(this.guildId), {
103
+ changeType: Manager_1.PlayerStateEventTypes.QueueChange,
104
+ details: {
105
+ changeType: "autoPlayAdd",
106
+ tracks: Array.isArray(track) ? track : [track],
107
+ },
108
+ });
109
+ return;
110
+ }
101
111
  }
102
112
  }
103
- }
104
- this.manager.emit(Manager_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this.manager.players.get(this.guildId), {
105
- changeType: Manager_1.PlayerStateEventTypes.QueueChange,
106
- details: {
107
- changeType: "add",
108
- tracks,
109
- },
113
+ this.manager.emit(Manager_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this.manager.players.get(this.guildId), {
114
+ changeType: Manager_1.PlayerStateEventTypes.QueueChange,
115
+ details: {
116
+ changeType: "add",
117
+ tracks,
118
+ },
119
+ });
110
120
  });
111
121
  }
112
122
  async remove(startOrPos = 0, end) {
113
- const oldPlayer = this.manager.players.get(this.guildId) ? { ...this.manager.players.get(this.guildId) } : null;
114
- const queue = await this.redis.lrange(this.queueKey, 0, -1);
115
- let removed = [];
116
- if (typeof end === "number") {
117
- if (startOrPos >= end || startOrPos >= queue.length) {
118
- throw new RangeError("Invalid range.");
123
+ return (0, logExecutionTime_1.logExecutionTime)("remove (RedisQueue)", async () => {
124
+ const oldPlayer = this.manager.players.get(this.guildId) ? { ...this.manager.players.get(this.guildId) } : null;
125
+ const queue = await this.redis.lrange(this.queueKey, 0, -1);
126
+ let removed = [];
127
+ if (typeof end === "number") {
128
+ if (startOrPos >= end || startOrPos >= queue.length) {
129
+ throw new RangeError("Invalid range.");
130
+ }
131
+ removed = queue.slice(startOrPos, end);
132
+ queue.splice(startOrPos, end - startOrPos);
133
+ }
134
+ else {
135
+ removed = queue.splice(startOrPos, 1);
136
+ }
137
+ await this.redis.del(this.queueKey);
138
+ if (queue.length > 0) {
139
+ await this.redis.rpush(this.queueKey, ...queue);
119
140
  }
120
- removed = queue.slice(startOrPos, end);
121
- queue.splice(startOrPos, end - startOrPos);
122
- }
123
- else {
124
- removed = queue.splice(startOrPos, 1);
125
- }
126
- await this.redis.del(this.queueKey);
127
- if (queue.length > 0) {
128
- await this.redis.rpush(this.queueKey, ...queue);
129
- }
130
- const deserialized = removed.map(this.deserialize);
131
- this.manager.emit(Manager_1.ManagerEventTypes.Debug, `[QUEUE] Removed ${removed.length} track(s) from position ${startOrPos}${end ? ` to ${end}` : ""}`);
132
- this.manager.emit(Manager_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this.manager.players.get(this.guildId), {
133
- changeType: Manager_1.PlayerStateEventTypes.QueueChange,
134
- details: {
135
- changeType: "remove",
136
- tracks: deserialized,
137
- },
141
+ const deserialized = removed.map(this.deserialize);
142
+ this.manager.emit(Manager_1.ManagerEventTypes.Debug, `[QUEUE] Removed ${removed.length} track(s) from position ${startOrPos}${end ? ` to ${end}` : ""}`);
143
+ this.manager.emit(Manager_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this.manager.players.get(this.guildId), {
144
+ changeType: Manager_1.PlayerStateEventTypes.QueueChange,
145
+ details: {
146
+ changeType: "remove",
147
+ tracks: deserialized,
148
+ },
149
+ });
150
+ return deserialized;
138
151
  });
139
- return deserialized;
140
152
  }
141
153
  async clear() {
142
- const oldPlayer = this.manager.players.get(this.guildId) ? { ...this.manager.players.get(this.guildId) } : null;
143
- await this.redis.del(this.queueKey);
144
- this.manager.emit(Manager_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this.manager.players.get(this.guildId), {
145
- changeType: Manager_1.PlayerStateEventTypes.QueueChange,
146
- details: {
147
- changeType: "clear",
148
- tracks: [],
149
- },
154
+ return (0, logExecutionTime_1.logExecutionTime)("clear (RedisQueue)", async () => {
155
+ const oldPlayer = this.manager.players.get(this.guildId) ? { ...this.manager.players.get(this.guildId) } : null;
156
+ await this.redis.del(this.queueKey);
157
+ this.manager.emit(Manager_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this.manager.players.get(this.guildId), {
158
+ changeType: Manager_1.PlayerStateEventTypes.QueueChange,
159
+ details: {
160
+ changeType: "clear",
161
+ tracks: [],
162
+ },
163
+ });
164
+ this.manager.emit(Manager_1.ManagerEventTypes.Debug, `[QUEUE] Cleared the queue for: ${this.guildId}`);
150
165
  });
151
- this.manager.emit(Manager_1.ManagerEventTypes.Debug, `[QUEUE] Cleared the queue for: ${this.guildId}`);
152
166
  }
153
167
  async size() {
154
- return await this.redis.llen(this.queueKey);
168
+ return (0, logExecutionTime_1.logExecutionTime)("size (RedisQueue)", async () => {
169
+ return await this.redis.llen(this.queueKey);
170
+ });
155
171
  }
156
172
  async totalSize() {
157
- const size = await this.size();
158
- return this.current ? size + 1 : size;
173
+ return (0, logExecutionTime_1.logExecutionTime)("totalSize (RedisQueue)", async () => {
174
+ const size = await this.size();
175
+ return (await this.getCurrent()) ? size + 1 : size;
176
+ });
159
177
  }
160
178
  async duration() {
161
- const tracks = await this.redis.lrange(this.queueKey, 0, -1);
162
- const currentDuration = this.current?.duration || 0;
163
- const total = tracks.reduce((acc, raw) => {
164
- try {
165
- const parsed = this.deserialize(raw);
166
- return acc + (parsed.duration || 0);
167
- }
168
- catch {
169
- return acc;
170
- }
171
- }, currentDuration);
172
- return total;
179
+ return (0, logExecutionTime_1.logExecutionTime)("duration (RedisQueue)", async () => {
180
+ const tracks = await this.redis.lrange(this.queueKey, 0, -1);
181
+ const currentDuration = (await this.getCurrent())?.duration || 0;
182
+ const total = tracks.reduce((acc, raw) => {
183
+ try {
184
+ const parsed = this.deserialize(raw);
185
+ return acc + (parsed.duration || 0);
186
+ }
187
+ catch {
188
+ return acc;
189
+ }
190
+ }, currentDuration);
191
+ return total;
192
+ });
173
193
  }
174
194
  async shuffle() {
175
- const oldPlayer = this.manager.players.get(this.guildId) ? { ...this.manager.players.get(this.guildId) } : null;
176
- const queue = await this.redis.lrange(this.queueKey, 0, -1);
177
- for (let i = queue.length - 1; i > 0; i--) {
178
- const j = Math.floor(Math.random() * (i + 1));
179
- [queue[i], queue[j]] = [queue[j], queue[i]];
180
- }
181
- await this.redis.del(this.queueKey);
182
- if (queue.length > 0) {
183
- await this.redis.rpush(this.queueKey, ...queue);
184
- }
185
- this.manager.emit(Manager_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this.manager.players.get(this.guildId), {
186
- changeType: Manager_1.PlayerStateEventTypes.QueueChange,
187
- details: { changeType: "shuffle" },
195
+ return (0, logExecutionTime_1.logExecutionTime)("shuffle (RedisQueue)", async () => {
196
+ const oldPlayer = this.manager.players.get(this.guildId) ? { ...this.manager.players.get(this.guildId) } : null;
197
+ const queue = await this.redis.lrange(this.queueKey, 0, -1);
198
+ for (let i = queue.length - 1; i > 0; i--) {
199
+ const j = Math.floor(Math.random() * (i + 1));
200
+ [queue[i], queue[j]] = [queue[j], queue[i]];
201
+ }
202
+ await this.redis.del(this.queueKey);
203
+ if (queue.length > 0) {
204
+ await this.redis.rpush(this.queueKey, ...queue);
205
+ }
206
+ this.manager.emit(Manager_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this.manager.players.get(this.guildId), {
207
+ changeType: Manager_1.PlayerStateEventTypes.QueueChange,
208
+ details: { changeType: "shuffle" },
209
+ });
210
+ this.manager.emit(Manager_1.ManagerEventTypes.Debug, `[QUEUE] Shuffled the queue for: ${this.guildId}`);
188
211
  });
189
- this.manager.emit(Manager_1.ManagerEventTypes.Debug, `[QUEUE] Shuffled the queue for: ${this.guildId}`);
190
212
  }
191
213
  async userBlockShuffle() {
192
- const oldPlayer = this.manager.players.get(this.guildId) ? { ...this.manager.players.get(this.guildId) } : null;
193
- const rawTracks = await this.redis.lrange(this.queueKey, 0, -1);
194
- const deserialized = rawTracks.map(this.deserialize);
195
- const userMap = new Map();
196
- for (const track of deserialized) {
197
- const userId = track.requester.id;
198
- if (!userMap.has(userId))
199
- userMap.set(userId, []);
200
- userMap.get(userId).push(track);
201
- }
202
- const shuffledQueue = [];
203
- while (shuffledQueue.length < deserialized.length) {
204
- for (const [, tracks] of userMap) {
205
- const track = tracks.shift();
206
- if (track)
207
- shuffledQueue.push(track);
214
+ return (0, logExecutionTime_1.logExecutionTime)("userBlockShuffle (RedisQueue)", async () => {
215
+ const oldPlayer = this.manager.players.get(this.guildId) ? { ...this.manager.players.get(this.guildId) } : null;
216
+ const rawTracks = await this.redis.lrange(this.queueKey, 0, -1);
217
+ const deserialized = rawTracks.map(this.deserialize);
218
+ const userMap = new Map();
219
+ for (const track of deserialized) {
220
+ const userId = track.requester.id;
221
+ if (!userMap.has(userId))
222
+ userMap.set(userId, []);
223
+ userMap.get(userId).push(track);
224
+ }
225
+ const shuffledQueue = [];
226
+ while (shuffledQueue.length < deserialized.length) {
227
+ for (const [, tracks] of userMap) {
228
+ const track = tracks.shift();
229
+ if (track)
230
+ shuffledQueue.push(track);
231
+ }
208
232
  }
209
- }
210
- await this.redis.del(this.queueKey);
211
- await this.redis.rpush(this.queueKey, ...shuffledQueue.map(this.serialize));
212
- this.manager.emit(Manager_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this.manager.players.get(this.guildId), {
213
- changeType: Manager_1.PlayerStateEventTypes.QueueChange,
214
- details: { changeType: "userBlock" },
233
+ await this.redis.del(this.queueKey);
234
+ await this.redis.rpush(this.queueKey, ...shuffledQueue.map(this.serialize));
235
+ this.manager.emit(Manager_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this.manager.players.get(this.guildId), {
236
+ changeType: Manager_1.PlayerStateEventTypes.QueueChange,
237
+ details: { changeType: "userBlock" },
238
+ });
239
+ this.manager.emit(Manager_1.ManagerEventTypes.Debug, `[QUEUE] userBlockShuffled the queue for: ${this.guildId}`);
215
240
  });
216
- this.manager.emit(Manager_1.ManagerEventTypes.Debug, `[QUEUE] userBlockShuffled the queue for: ${this.guildId}`);
217
241
  }
218
242
  async roundRobinShuffle() {
219
- const oldPlayer = this.manager.players.get(this.guildId) ? { ...this.manager.players.get(this.guildId) } : null;
220
- const rawTracks = await this.redis.lrange(this.queueKey, 0, -1);
221
- const deserialized = rawTracks.map(this.deserialize);
222
- const userMap = new Map();
223
- for (const track of deserialized) {
224
- const userId = track.requester.id;
225
- if (!userMap.has(userId))
226
- userMap.set(userId, []);
227
- userMap.get(userId).push(track);
228
- }
229
- // Shuffle each user's tracks
230
- for (const tracks of userMap.values()) {
231
- for (let i = tracks.length - 1; i > 0; i--) {
232
- const j = Math.floor(Math.random() * (i + 1));
233
- [tracks[i], tracks[j]] = [tracks[j], tracks[i]];
243
+ return (0, logExecutionTime_1.logExecutionTime)("roundRobinShuffle (RedisQueue)", async () => {
244
+ const oldPlayer = this.manager.players.get(this.guildId) ? { ...this.manager.players.get(this.guildId) } : null;
245
+ const rawTracks = await this.redis.lrange(this.queueKey, 0, -1);
246
+ const deserialized = rawTracks.map(this.deserialize);
247
+ const userMap = new Map();
248
+ for (const track of deserialized) {
249
+ const userId = track.requester.id;
250
+ if (!userMap.has(userId))
251
+ userMap.set(userId, []);
252
+ userMap.get(userId).push(track);
234
253
  }
235
- }
236
- const users = [...userMap.keys()];
237
- const queues = users.map((id) => userMap.get(id));
238
- const shuffledQueue = [];
239
- while (queues.some((q) => q.length > 0)) {
240
- for (const q of queues) {
241
- const track = q.shift();
242
- if (track)
243
- shuffledQueue.push(track);
254
+ // Shuffle each user's tracks
255
+ for (const tracks of userMap.values()) {
256
+ for (let i = tracks.length - 1; i > 0; i--) {
257
+ const j = Math.floor(Math.random() * (i + 1));
258
+ [tracks[i], tracks[j]] = [tracks[j], tracks[i]];
259
+ }
244
260
  }
245
- }
246
- await this.redis.del(this.queueKey);
247
- await this.redis.rpush(this.queueKey, ...shuffledQueue.map(this.serialize));
248
- this.manager.emit(Manager_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this.manager.players.get(this.guildId), {
249
- changeType: Manager_1.PlayerStateEventTypes.QueueChange,
250
- details: { changeType: "roundRobin" },
261
+ const users = [...userMap.keys()];
262
+ const queues = users.map((id) => userMap.get(id));
263
+ const shuffledQueue = [];
264
+ while (queues.some((q) => q.length > 0)) {
265
+ for (const q of queues) {
266
+ const track = q.shift();
267
+ if (track)
268
+ shuffledQueue.push(track);
269
+ }
270
+ }
271
+ await this.redis.del(this.queueKey);
272
+ await this.redis.rpush(this.queueKey, ...shuffledQueue.map(this.serialize));
273
+ this.manager.emit(Manager_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this.manager.players.get(this.guildId), {
274
+ changeType: Manager_1.PlayerStateEventTypes.QueueChange,
275
+ details: { changeType: "roundRobin" },
276
+ });
277
+ this.manager.emit(Manager_1.ManagerEventTypes.Debug, `[QUEUE] roundRobinShuffled the queue for: ${this.guildId}`);
251
278
  });
252
- this.manager.emit(Manager_1.ManagerEventTypes.Debug, `[QUEUE] roundRobinShuffled the queue for: ${this.guildId}`);
253
279
  }
254
280
  async dequeue() {
255
- const raw = await this.redis.lpop(this.queueKey);
256
- return raw ? this.deserialize(raw) : undefined;
281
+ return (0, logExecutionTime_1.logExecutionTime)("dequeue (RedisQueue)", async () => {
282
+ const raw = await this.redis.lpop(this.queueKey);
283
+ return raw ? this.deserialize(raw) : undefined;
284
+ });
257
285
  }
258
286
  async enqueueFront(track) {
259
- const serialized = Array.isArray(track) ? track.map(this.serialize) : [this.serialize(track)];
260
- // Redis: LPUSH adds to front, reverse to maintain order if multiple tracks
261
- await this.redis.lpush(this.queueKey, ...serialized.reverse());
287
+ return (0, logExecutionTime_1.logExecutionTime)("enqueueFront (RedisQueue)", async () => {
288
+ const serialized = Array.isArray(track) ? track.map(this.serialize) : [this.serialize(track)];
289
+ // Redis: LPUSH adds to front, reverse to maintain order if multiple tracks
290
+ await this.redis.lpush(this.queueKey, ...serialized.reverse());
291
+ });
262
292
  }
263
293
  async getTracks() {
264
- const raw = await this.redis.lrange(this.queueKey, 0, -1);
265
- return raw.map(this.deserialize);
294
+ return (0, logExecutionTime_1.logExecutionTime)("getTracks (RedisQueue)", async () => {
295
+ const raw = await this.redis.lrange(this.queueKey, 0, -1);
296
+ return raw.map(this.deserialize);
297
+ });
266
298
  }
267
299
  async getSlice(start = 0, end = -1) {
268
- const raw = await this.redis.lrange(this.queueKey, start, end === -1 ? -1 : end - 1);
269
- return raw.map(this.deserialize);
300
+ return (0, logExecutionTime_1.logExecutionTime)("getSlice (RedisQueue)", async () => {
301
+ const raw = await this.redis.lrange(this.queueKey, start, end === -1 ? -1 : end - 1);
302
+ return raw.map(this.deserialize);
303
+ });
270
304
  }
271
305
  async modifyAt(start, deleteCount = 0, ...items) {
272
- const queue = await this.redis.lrange(this.queueKey, 0, -1);
273
- const removed = queue.splice(start, deleteCount, ...items.map(this.serialize));
274
- await this.redis.del(this.queueKey);
275
- if (queue.length > 0) {
276
- await this.redis.rpush(this.queueKey, ...queue);
277
- }
278
- return removed.map(this.deserialize);
306
+ return (0, logExecutionTime_1.logExecutionTime)("modifyAt (RedisQueue)", async () => {
307
+ const queue = await this.redis.lrange(this.queueKey, 0, -1);
308
+ const removed = queue.splice(start, deleteCount, ...items.map(this.serialize));
309
+ await this.redis.del(this.queueKey);
310
+ if (queue.length > 0) {
311
+ await this.redis.rpush(this.queueKey, ...queue);
312
+ }
313
+ return removed.map(this.deserialize);
314
+ });
279
315
  }
280
316
  async mapAsync(callback) {
281
- const tracks = await this.getTracks(); // same as lrange + deserialize
282
- return tracks.map(callback);
317
+ return (0, logExecutionTime_1.logExecutionTime)("mapAsync (RedisQueue)", async () => {
318
+ const tracks = await this.getTracks(); // same as lrange + deserialize
319
+ return tracks.map(callback);
320
+ });
283
321
  }
284
322
  async filterAsync(callback) {
285
- const tracks = await this.getTracks();
286
- return tracks.filter(callback);
323
+ return (0, logExecutionTime_1.logExecutionTime)("filterAsync (RedisQueue)", async () => {
324
+ const tracks = await this.getTracks();
325
+ return tracks.filter(callback);
326
+ });
287
327
  }
288
328
  async findAsync(callback) {
289
- const tracks = await this.getTracks();
290
- return tracks.find(callback);
329
+ return (0, logExecutionTime_1.logExecutionTime)("findAsync (RedisQueue)", async () => {
330
+ const tracks = await this.getTracks();
331
+ return tracks.find(callback);
332
+ });
291
333
  }
292
334
  async someAsync(callback) {
293
- const tracks = await this.getTracks();
294
- return tracks.some(callback);
335
+ return (0, logExecutionTime_1.logExecutionTime)("someAsync (RedisQueue)", async () => {
336
+ const tracks = await this.getTracks();
337
+ return tracks.some(callback);
338
+ });
295
339
  }
296
340
  async everyAsync(callback) {
297
- const tracks = await this.getTracks();
298
- return tracks.every(callback);
341
+ return (0, logExecutionTime_1.logExecutionTime)("everyAsync (RedisQueue)", async () => {
342
+ const tracks = await this.getTracks();
343
+ return tracks.every(callback);
344
+ });
299
345
  }
300
346
  }
301
347
  exports.RedisQueue = RedisQueue;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "magmastream",
3
- "version": "2.9.0-dev.10",
3
+ "version": "2.9.0-dev.12",
4
4
  "description": "A user-friendly Lavalink client designed for NodeJS.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -90,4 +90,4 @@
90
90
  "homepage": "https://docs.magmastream.com",
91
91
  "author": "Abel Purnwasy",
92
92
  "license": "Apache-2.0"
93
- }
93
+ }