magmastream 2.9.0-dev.46 → 2.9.0-dev.48

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.
@@ -11,6 +11,9 @@ const fs_1 = require("fs");
11
11
  class JsonQueue {
12
12
  guildId;
13
13
  manager;
14
+ /**
15
+ * The base path for the queue files.
16
+ */
14
17
  basePath;
15
18
  /**
16
19
  * @param guildId The guild ID.
@@ -22,136 +25,7 @@ class JsonQueue {
22
25
  const base = manager.options.stateStorage?.jsonConfig?.path ?? path_1.default.join(process.cwd(), "magmastream", "sessionData", "players");
23
26
  this.basePath = path_1.default.join(base, this.guildId);
24
27
  }
25
- /**
26
- * @returns The queue path.
27
- */
28
- get queuePath() {
29
- return path_1.default.join(this.basePath, "queue.json");
30
- }
31
- /**
32
- * @returns The current path.
33
- */
34
- get currentPath() {
35
- return path_1.default.join(this.basePath, "current.json");
36
- }
37
- /**
38
- * @returns The previous path.
39
- */
40
- get previousPath() {
41
- return path_1.default.join(this.basePath, "previous.json");
42
- }
43
- /**
44
- * Ensures the directory exists.
45
- */
46
- async ensureDir() {
47
- await fs_1.promises.mkdir(this.basePath, { recursive: true });
48
- }
49
- /**
50
- * @returns The queue.
51
- */
52
- async getQueue() {
53
- const data = await this.readJSON(this.queuePath);
54
- return Array.isArray(data) ? data : [];
55
- }
56
- /**
57
- * @param queue The queue.
58
- */
59
- async setQueue(queue) {
60
- await this.deleteFile(this.queuePath);
61
- await this.writeJSON(this.queuePath, queue);
62
- }
63
- /**
64
- * @param filePath The file path.
65
- * @returns The JSON data.
66
- */
67
- async readJSON(filePath) {
68
- try {
69
- const raw = await fs_1.promises.readFile(filePath, "utf-8");
70
- return JSON.parse(raw);
71
- }
72
- catch {
73
- return null;
74
- }
75
- }
76
- /**
77
- * @param filePath The file path.
78
- * @param data The data to write.
79
- */
80
- async writeJSON(filePath, data) {
81
- await this.ensureDir();
82
- await fs_1.promises.writeFile(filePath, JSON.stringify(data, null, 2), "utf-8");
83
- }
84
- /**
85
- * @param filePath The file path.
86
- */
87
- async deleteFile(filePath) {
88
- try {
89
- await fs_1.promises.unlink(filePath);
90
- }
91
- catch {
92
- this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[JSONQUEUE] Failed to delete file: ${filePath}`);
93
- }
94
- }
95
- /**
96
- * @returns The current track.
97
- */
98
- async getCurrent() {
99
- return await this.readJSON(this.currentPath);
100
- }
101
- /**
102
- * @param track The track to set.
103
- */
104
- async setCurrent(track) {
105
- if (track) {
106
- await this.writeJSON(this.currentPath, track);
107
- }
108
- else {
109
- await this.deleteFile(this.currentPath);
110
- }
111
- }
112
- /**
113
- * @returns The previous tracks.
114
- */
115
- async getPrevious() {
116
- const data = await this.readJSON(this.previousPath);
117
- return Array.isArray(data) ? data : [];
118
- }
119
- /**
120
- * @param track The track to add.
121
- */
122
- async addPrevious(track) {
123
- const tracks = Array.isArray(track) ? track : [track];
124
- if (!tracks.length)
125
- return;
126
- const current = await this.getPrevious();
127
- await this.writeJSON(this.previousPath, [...tracks.reverse(), ...current]);
128
- }
129
- /**
130
- * @param track The track to set.
131
- */
132
- async setPrevious(track) {
133
- const tracks = Array.isArray(track) ? track : [track];
134
- if (!tracks.length)
135
- return;
136
- await this.writeJSON(this.previousPath, tracks);
137
- }
138
- /**
139
- * @returns The newest track.
140
- */
141
- async popPrevious() {
142
- const current = await this.getPrevious();
143
- if (!current.length)
144
- return null;
145
- const popped = current.shift();
146
- await this.writeJSON(this.previousPath, current);
147
- return popped;
148
- }
149
- /**
150
- * Clears the previous tracks.
151
- */
152
- async clearPrevious() {
153
- await this.deleteFile(this.previousPath);
154
- }
28
+ // #region Public
155
29
  /**
156
30
  * @param track The track or tracks to add. Can be a single `Track` or an array of `Track`s.
157
31
  * @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.
@@ -202,29 +76,15 @@ class JsonQueue {
202
76
  },
203
77
  });
204
78
  }
205
- async remove(startOrPos = 0, end) {
206
- const oldPlayer = this.manager.players.get(this.guildId) ? { ...this.manager.players.get(this.guildId) } : null;
207
- const queue = await this.getQueue();
208
- let removed = [];
209
- if (typeof end === "number") {
210
- if (startOrPos >= end || startOrPos >= queue.length)
211
- throw new RangeError("Invalid range.");
212
- removed = queue.splice(startOrPos, end - startOrPos);
213
- }
214
- else {
215
- removed = queue.splice(startOrPos, 1);
216
- }
217
- await this.setQueue(queue);
218
- this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[JSONQUEUE] Removed ${removed.length} track(s) from position ${startOrPos}${end ? ` to ${end}` : ""}`);
219
- this.manager.emit(Enums_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this.manager.players.get(this.guildId), {
220
- changeType: Enums_1.PlayerStateEventTypes.QueueChange,
221
- details: {
222
- type: "queue",
223
- action: "remove",
224
- tracks: removed,
225
- },
226
- });
227
- return removed;
79
+ /**
80
+ * @param track The track to add.
81
+ */
82
+ async addPrevious(track) {
83
+ const tracks = Array.isArray(track) ? track : [track];
84
+ if (!tracks.length)
85
+ return;
86
+ const current = await this.getPrevious();
87
+ await this.writeJSON(this.previousPath, [...tracks.reverse(), ...current]);
228
88
  }
229
89
  /**
230
90
  * Clears the queue.
@@ -243,18 +103,19 @@ class JsonQueue {
243
103
  this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[JSONQUEUE] Cleared the queue for: ${this.guildId}`);
244
104
  }
245
105
  /**
246
- * @returns The size of the queue.
106
+ * Clears the previous tracks.
247
107
  */
248
- async size() {
249
- const queue = await this.getQueue();
250
- return queue.length;
108
+ async clearPrevious() {
109
+ await this.deleteFile(this.previousPath);
251
110
  }
252
111
  /**
253
- * @returns The total size of the queue.
112
+ * Removes the first track from the queue.
254
113
  */
255
- async totalSize() {
256
- const size = await this.size();
257
- return (await this.getCurrent()) ? size + 1 : size;
114
+ async dequeue() {
115
+ const queue = await this.getQueue();
116
+ const track = queue.shift();
117
+ await this.setQueue(queue);
118
+ return track;
258
119
  }
259
120
  /**
260
121
  * @returns The total duration of the queue.
@@ -267,55 +128,112 @@ class JsonQueue {
267
128
  return total;
268
129
  }
269
130
  /**
270
- * Shuffles the queue.
131
+ * Adds a track to the front of the queue.
271
132
  */
272
- async shuffle() {
273
- const oldPlayer = this.manager.players.get(this.guildId) ? { ...this.manager.players.get(this.guildId) } : null;
133
+ async enqueueFront(track) {
134
+ const tracks = Array.isArray(track) ? track : [track];
274
135
  const queue = await this.getQueue();
275
- for (let i = queue.length - 1; i > 0; i--) {
276
- const j = Math.floor(Math.random() * (i + 1));
277
- [queue[i], queue[j]] = [queue[j], queue[i]];
278
- }
136
+ await this.setQueue([...tracks.reverse(), ...queue]);
137
+ }
138
+ /**
139
+ * Tests whether all elements in the queue pass the test implemented by the provided function.
140
+ */
141
+ async everyAsync(callback) {
142
+ const queue = await this.getQueue();
143
+ return queue.every(callback);
144
+ }
145
+ /**
146
+ * Filters the queue.
147
+ */
148
+ async filterAsync(callback) {
149
+ const queue = await this.getQueue();
150
+ return queue.filter(callback);
151
+ }
152
+ /**
153
+ * Finds the first track in the queue that satisfies the provided testing function.
154
+ */
155
+ async findAsync(callback) {
156
+ const queue = await this.getQueue();
157
+ return queue.find(callback);
158
+ }
159
+ /**
160
+ * @returns The current track.
161
+ */
162
+ async getCurrent() {
163
+ return await this.readJSON(this.currentPath);
164
+ }
165
+ /**
166
+ * @returns The previous tracks.
167
+ */
168
+ async getPrevious() {
169
+ const data = await this.readJSON(this.previousPath);
170
+ return Array.isArray(data) ? data : [];
171
+ }
172
+ /**
173
+ * @returns The tracks in the queue from start to end.
174
+ */
175
+ async getSlice(start = 0, end = -1) {
176
+ const queue = await this.getQueue();
177
+ if (end === -1)
178
+ return queue.slice(start);
179
+ return queue.slice(start, end);
180
+ }
181
+ /**
182
+ * @returns The tracks in the queue.
183
+ */
184
+ async getTracks() {
185
+ return await this.getQueue();
186
+ }
187
+ /**
188
+ * Maps the queue to a new array.
189
+ */
190
+ async mapAsync(callback) {
191
+ const queue = await this.getQueue();
192
+ return queue.map(callback);
193
+ }
194
+ /**
195
+ * Modifies the queue at the specified index.
196
+ */
197
+ async modifyAt(start, deleteCount = 0, ...items) {
198
+ const queue = await this.getQueue();
199
+ const removed = queue.splice(start, deleteCount, ...items);
279
200
  await this.setQueue(queue);
280
- this.manager.emit(Enums_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this.manager.players.get(this.guildId), {
281
- changeType: Enums_1.PlayerStateEventTypes.QueueChange,
282
- details: {
283
- type: "queue",
284
- action: "shuffle",
285
- },
286
- });
287
- this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[JSONQUEUE] Shuffled the queue for: ${this.guildId}`);
201
+ return removed;
288
202
  }
289
203
  /**
290
- * Shuffles the queue by user.
204
+ * @returns The newest track.
291
205
  */
292
- async userBlockShuffle() {
206
+ async popPrevious() {
207
+ const current = await this.getPrevious();
208
+ if (!current.length)
209
+ return null;
210
+ const popped = current.shift();
211
+ await this.writeJSON(this.previousPath, current);
212
+ return popped;
213
+ }
214
+ async remove(startOrPos = 0, end) {
293
215
  const oldPlayer = this.manager.players.get(this.guildId) ? { ...this.manager.players.get(this.guildId) } : null;
294
216
  const queue = await this.getQueue();
295
- const userMap = new Map();
296
- for (const track of queue) {
297
- const userId = track.requester.id;
298
- if (!userMap.has(userId))
299
- userMap.set(userId, []);
300
- userMap.get(userId).push(track);
217
+ let removed = [];
218
+ if (typeof end === "number") {
219
+ if (startOrPos >= end || startOrPos >= queue.length)
220
+ throw new RangeError("Invalid range.");
221
+ removed = queue.splice(startOrPos, end - startOrPos);
301
222
  }
302
- const shuffledQueue = [];
303
- while (shuffledQueue.length < queue.length) {
304
- for (const [, tracks] of userMap) {
305
- const track = tracks.shift();
306
- if (track)
307
- shuffledQueue.push(track);
308
- }
223
+ else {
224
+ removed = queue.splice(startOrPos, 1);
309
225
  }
310
- await this.setQueue(shuffledQueue);
226
+ await this.setQueue(queue);
227
+ this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[JSONQUEUE] Removed ${removed.length} track(s) from position ${startOrPos}${end ? ` to ${end}` : ""}`);
311
228
  this.manager.emit(Enums_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this.manager.players.get(this.guildId), {
312
229
  changeType: Enums_1.PlayerStateEventTypes.QueueChange,
313
230
  details: {
314
231
  type: "queue",
315
- action: "userBlock",
232
+ action: "remove",
233
+ tracks: removed,
316
234
  },
317
235
  });
318
- this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[JSONQUEUE] userBlockShuffled the queue for: ${this.guildId}`);
236
+ return removed;
319
237
  }
320
238
  /**
321
239
  * Shuffles the queue by round-robin.
@@ -358,80 +276,168 @@ class JsonQueue {
358
276
  this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[JSONQUEUE] roundRobinShuffled the queue for: ${this.guildId}`);
359
277
  }
360
278
  /**
361
- * Removes the first track from the queue.
279
+ * @param track The track to set.
362
280
  */
363
- async dequeue() {
364
- const queue = await this.getQueue();
365
- const track = queue.shift();
366
- await this.setQueue(queue);
367
- return track;
281
+ async setCurrent(track) {
282
+ if (track) {
283
+ await this.writeJSON(this.currentPath, track);
284
+ }
285
+ else {
286
+ await this.deleteFile(this.currentPath);
287
+ }
368
288
  }
369
289
  /**
370
- * Adds a track to the front of the queue.
290
+ * @param track The track to set.
371
291
  */
372
- async enqueueFront(track) {
292
+ async setPrevious(track) {
373
293
  const tracks = Array.isArray(track) ? track : [track];
374
- const queue = await this.getQueue();
375
- await this.setQueue([...tracks.reverse(), ...queue]);
294
+ if (!tracks.length)
295
+ return;
296
+ await this.writeJSON(this.previousPath, tracks);
376
297
  }
377
298
  /**
378
- * @returns The tracks in the queue.
299
+ * Shuffles the queue.
379
300
  */
380
- async getTracks() {
381
- return await this.getQueue();
301
+ async shuffle() {
302
+ const oldPlayer = this.manager.players.get(this.guildId) ? { ...this.manager.players.get(this.guildId) } : null;
303
+ const queue = await this.getQueue();
304
+ for (let i = queue.length - 1; i > 0; i--) {
305
+ const j = Math.floor(Math.random() * (i + 1));
306
+ [queue[i], queue[j]] = [queue[j], queue[i]];
307
+ }
308
+ await this.setQueue(queue);
309
+ this.manager.emit(Enums_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this.manager.players.get(this.guildId), {
310
+ changeType: Enums_1.PlayerStateEventTypes.QueueChange,
311
+ details: {
312
+ type: "queue",
313
+ action: "shuffle",
314
+ },
315
+ });
316
+ this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[JSONQUEUE] Shuffled the queue for: ${this.guildId}`);
382
317
  }
383
318
  /**
384
- * @returns The tracks in the queue from start to end.
319
+ * @returns The size of the queue.
385
320
  */
386
- async getSlice(start = 0, end = -1) {
321
+ async size() {
387
322
  const queue = await this.getQueue();
388
- if (end === -1)
389
- return queue.slice(start);
390
- return queue.slice(start, end);
323
+ return queue.length;
391
324
  }
392
325
  /**
393
- * Modifies the queue at the specified index.
326
+ * Tests whether at least one element in the queue passes the test implemented by the provided function.
394
327
  */
395
- async modifyAt(start, deleteCount = 0, ...items) {
328
+ async someAsync(callback) {
396
329
  const queue = await this.getQueue();
397
- const removed = queue.splice(start, deleteCount, ...items);
398
- await this.setQueue(queue);
399
- return removed;
330
+ return queue.some(callback);
400
331
  }
401
332
  /**
402
- * Maps the queue to a new array.
333
+ * @returns The total size of the queue.
403
334
  */
404
- async mapAsync(callback) {
405
- const queue = await this.getQueue();
406
- return queue.map(callback);
335
+ async totalSize() {
336
+ const size = await this.size();
337
+ return (await this.getCurrent()) ? size + 1 : size;
407
338
  }
408
339
  /**
409
- * Filters the queue.
340
+ * Shuffles the queue by user.
410
341
  */
411
- async filterAsync(callback) {
342
+ async userBlockShuffle() {
343
+ const oldPlayer = this.manager.players.get(this.guildId) ? { ...this.manager.players.get(this.guildId) } : null;
412
344
  const queue = await this.getQueue();
413
- return queue.filter(callback);
345
+ const userMap = new Map();
346
+ for (const track of queue) {
347
+ const userId = track.requester.id;
348
+ if (!userMap.has(userId))
349
+ userMap.set(userId, []);
350
+ userMap.get(userId).push(track);
351
+ }
352
+ const shuffledQueue = [];
353
+ while (shuffledQueue.length < queue.length) {
354
+ for (const [, tracks] of userMap) {
355
+ const track = tracks.shift();
356
+ if (track)
357
+ shuffledQueue.push(track);
358
+ }
359
+ }
360
+ await this.setQueue(shuffledQueue);
361
+ this.manager.emit(Enums_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this.manager.players.get(this.guildId), {
362
+ changeType: Enums_1.PlayerStateEventTypes.QueueChange,
363
+ details: {
364
+ type: "queue",
365
+ action: "userBlock",
366
+ },
367
+ });
368
+ this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[JSONQUEUE] userBlockShuffled the queue for: ${this.guildId}`);
414
369
  }
370
+ // #endregion Public
371
+ // #region Private
415
372
  /**
416
- * Finds the first track in the queue that satisfies the provided testing function.
373
+ * @returns The current path.
417
374
  */
418
- async findAsync(callback) {
419
- const queue = await this.getQueue();
420
- return queue.find(callback);
375
+ get currentPath() {
376
+ return path_1.default.join(this.basePath, "current.json");
421
377
  }
422
378
  /**
423
- * Tests whether at least one element in the queue passes the test implemented by the provided function.
379
+ * @param filePath The file path.
424
380
  */
425
- async someAsync(callback) {
426
- const queue = await this.getQueue();
427
- return queue.some(callback);
381
+ async deleteFile(filePath) {
382
+ try {
383
+ await fs_1.promises.unlink(filePath);
384
+ }
385
+ catch {
386
+ this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[JSONQUEUE] Failed to delete file: ${filePath}`);
387
+ }
428
388
  }
429
389
  /**
430
- * Tests whether all elements in the queue pass the test implemented by the provided function.
390
+ * Ensures the directory exists.
431
391
  */
432
- async everyAsync(callback) {
433
- const queue = await this.getQueue();
434
- return queue.every(callback);
392
+ async ensureDir() {
393
+ await fs_1.promises.mkdir(this.basePath, { recursive: true });
394
+ }
395
+ /**
396
+ * @returns The queue.
397
+ */
398
+ async getQueue() {
399
+ const data = await this.readJSON(this.queuePath);
400
+ return Array.isArray(data) ? data : [];
401
+ }
402
+ /**
403
+ * @returns The previous path.
404
+ */
405
+ get previousPath() {
406
+ return path_1.default.join(this.basePath, "previous.json");
407
+ }
408
+ /**
409
+ * @returns The queue path.
410
+ */
411
+ get queuePath() {
412
+ return path_1.default.join(this.basePath, "queue.json");
413
+ }
414
+ /**
415
+ * @param filePath The file path.
416
+ * @returns The JSON data.
417
+ */
418
+ async readJSON(filePath) {
419
+ try {
420
+ const raw = await fs_1.promises.readFile(filePath, "utf-8");
421
+ return JSON.parse(raw);
422
+ }
423
+ catch {
424
+ return null;
425
+ }
426
+ }
427
+ /**
428
+ * @param queue The queue.
429
+ */
430
+ async setQueue(queue) {
431
+ await this.deleteFile(this.queuePath);
432
+ await this.writeJSON(this.queuePath, queue);
433
+ }
434
+ /**
435
+ * @param filePath The file path.
436
+ * @param data The data to write.
437
+ */
438
+ async writeJSON(filePath, data) {
439
+ await this.ensureDir();
440
+ await fs_1.promises.writeFile(filePath, JSON.stringify(data, null, 2), "utf-8");
435
441
  }
436
442
  }
437
443
  exports.JsonQueue = JsonQueue;