ziplayer 0.1.2 → 0.1.4

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.
@@ -1,354 +1,354 @@
1
- import { Track, LoopMode } from "../types";
2
-
3
- /**
4
- * Manages the track queue for a player.
5
- *
6
- * @example
7
- * // Basic queue operations
8
- * const queue = player.queue;
9
- *
10
- * // Add single track
11
- * queue.add(track);
12
- *
13
- * // Add multiple tracks
14
- * queue.add([track1, track2, track3]);
15
- *
16
- * // Queue controls
17
- * queue.shuffle(); // Randomize order
18
- * queue.clear(); // Remove all tracks
19
- * queue.autoPlay(true); // Enable auto-play
20
- *
21
- * // Get queue information
22
- * console.log(`Queue length: ${queue.length}`);
23
- * console.log(`Current track: ${queue.current?.title}`);
24
- * console.log(`Is empty: ${queue.isEmpty}`);
25
- * console.log(`Is playing: ${queue.isPlaying}`);
26
- *
27
- * // Loop modes
28
- * queue.setLoopMode("track"); // Loop current track
29
- * queue.setLoopMode("queue"); // Loop entire queue
30
- * queue.setLoopMode("off"); // No loop
31
- *
32
- * // Remove specific track
33
- * const removed = queue.remove(0); // Remove first track
34
- * if (removed) {
35
- * console.log(`Removed: ${removed.title}`);
36
- * }
37
- */
38
- export class Queue {
39
- private tracks: Track[] = [];
40
- private current: Track | null = null;
41
- private history: Track[] = [];
42
- private related: Track[] = [];
43
- private _autoPlay = false;
44
- private _loop: LoopMode = "off";
45
- private willnext: Track | null = null;
46
-
47
- /**
48
- * Add track(s) to the queue
49
- *
50
- * @param {Track | Track[]} track - Track or array of tracks to add
51
- * @example
52
- * queue.add(track);
53
- * queue.add([track1, track2, track3]);
54
- */
55
- add(track: Track): void {
56
- this.tracks.push(track);
57
- }
58
-
59
- /**
60
- * Add multiple tracks to the queue
61
- *
62
- * @param {Track[]} tracks - Tracks to add
63
- * @example
64
- * queue.addMultiple([track1, track2, track3]);
65
- */
66
- addMultiple(tracks: Track[]): void {
67
- this.tracks.push(...tracks);
68
- }
69
-
70
- /**
71
- * Insert a track at a specific upcoming position (0 = next)
72
- *
73
- * @param {Track} track - Track to insert
74
- * @param {number} index - Index to insert the track at
75
- * @example
76
- * queue.insert(track, 0);
77
- */
78
- insert(track: Track, index: number): void {
79
- if (!Number.isFinite(index)) {
80
- this.tracks.push(track);
81
- return;
82
- }
83
- const i = Math.max(0, Math.min(Math.floor(index), this.tracks.length));
84
- if (i === this.tracks.length) {
85
- this.tracks.push(track);
86
- return;
87
- }
88
- if (i <= 0) {
89
- this.tracks.unshift(track);
90
- return;
91
- }
92
- this.tracks.splice(i, 0, track);
93
- }
94
-
95
- /**
96
- * Insert multiple tracks at a specific upcoming position, preserving order
97
- *
98
- * @param {Track[]} tracks - Tracks to insert
99
- * @param {number} index - Index to insert the tracks at
100
- * @example
101
- * queue.insertMultiple([track1, track2, track3], 0);
102
- */
103
- insertMultiple(tracks: Track[], index: number): void {
104
- if (!Array.isArray(tracks) || tracks.length === 0) return;
105
- if (!Number.isFinite(index)) {
106
- this.tracks.push(...tracks);
107
- return;
108
- }
109
- const i = Math.max(0, Math.min(Math.floor(index), this.tracks.length));
110
- if (i === 0) {
111
- this.tracks = [...tracks, ...this.tracks];
112
- return;
113
- }
114
- if (i === this.tracks.length) {
115
- this.tracks.push(...tracks);
116
- return;
117
- }
118
- this.tracks.splice(i, 0, ...tracks);
119
- }
120
-
121
- /**
122
- * Remove a track from the queue
123
- *
124
- * @param {number} index - Index of track to remove
125
- * @returns {Track | null} Removed track or null
126
- * @example
127
- * const removed = queue.remove(0);
128
- * console.log(`Removed: ${removed?.title}`);
129
- */
130
-
131
- remove(index: number): Track | null {
132
- if (index < 0 || index >= this.tracks.length) return null;
133
- return this.tracks.splice(index, 1)[0];
134
- }
135
-
136
- /**
137
- * Get the next track in the queue
138
- *
139
- * @param {boolean} ignoreLoop - Ignore the loop mode
140
- * @returns {Track | null} The next track or null
141
- * @example
142
- * const nextTrack = queue.next();
143
- * console.log(`Next track: ${nextTrack?.title}`);
144
- */
145
- next(ignoreLoop = false): Track | null {
146
- if (this.current) {
147
- if (this._loop === "track" && !ignoreLoop) {
148
- return this.current;
149
- }
150
- this.history.push(this.current);
151
- if (this.history.length > 200) {
152
- this.history.shift();
153
- }
154
- }
155
- this.current = this.tracks.shift() || null;
156
- if (!this.current && this._loop === "queue" && this.history.length > 0 && !ignoreLoop) {
157
- this.tracks = [...this.history];
158
- this.history = [];
159
- this.current = this.tracks.shift() || null;
160
- }
161
- return this.current;
162
- }
163
-
164
- /**
165
- * Clear all tracks from the queue
166
- *
167
- * @example
168
- * queue.clear();
169
- */
170
- clear(): void {
171
- this.tracks = [];
172
- }
173
-
174
- /**
175
- * Enable or disable auto-play
176
- *
177
- * @param {boolean} value - Enable/disable auto-play
178
- * @returns {boolean} Current auto-play state
179
- * @example
180
- * queue.autoPlay(true);
181
- * queue.autoPlay(); // Get current auto-play state
182
- */
183
-
184
- autoPlay(value?: boolean): boolean {
185
- if (typeof value !== "undefined") {
186
- this._autoPlay = value;
187
- }
188
- return this._autoPlay;
189
- }
190
-
191
- /**
192
- * Set the loop mode
193
- *
194
- * @param {LoopMode} mode - Loop mode to set
195
- * @returns {LoopMode} The loop mode
196
- * @example
197
- * queue.loop("track");
198
- */
199
- loop(mode?: LoopMode): LoopMode {
200
- if (mode) {
201
- this._loop = mode;
202
- }
203
- return this._loop;
204
- }
205
-
206
- /**
207
- * Shuffle the queue
208
- *
209
- * @example
210
- * queue.shuffle();
211
- */
212
-
213
- shuffle(): void {
214
- for (let i = this.tracks.length - 1; i > 0; i--) {
215
- const j = Math.floor(Math.random() * (i + 1));
216
- [this.tracks[i], this.tracks[j]] = [this.tracks[j], this.tracks[i]];
217
- }
218
- }
219
-
220
- /**
221
- * Get the size of the queue
222
- *
223
- * @returns {number} The size of the queue
224
- * @example
225
- * const size = queue.size;
226
- * console.log(`Queue size: ${size}`);
227
- */
228
- get size(): number {
229
- return this.tracks.length;
230
- }
231
-
232
- /**
233
- * Check if the queue is empty
234
- *
235
- * @returns {boolean} True if the queue is empty
236
- * @example
237
- * const empty = queue.isEmpty;
238
- * console.log(`Queue is empty: ${empty}`);
239
- */
240
- get isEmpty(): boolean {
241
- return this.tracks.length === 0;
242
- }
243
-
244
- /**
245
- * Get the current track
246
- *
247
- * @returns {Track | null} The current track or null
248
- * @example
249
- * const currentTrack = queue.currentTrack;
250
- * console.log(`Current track: ${currentTrack?.title}`);
251
- */
252
- get currentTrack(): Track | null {
253
- return this.current;
254
- }
255
-
256
- /**
257
- * Get the previous tracks
258
- *
259
- * @returns {Track[]} The previous tracks
260
- * @example
261
- * const previousTracks = queue.previousTracks;
262
- * console.log(`Previous tracks: ${previousTracks.length}`);
263
- */
264
- get previousTracks(): Track[] {
265
- return [...this.history];
266
- }
267
-
268
- /**
269
- * Get the next track
270
- *
271
- * @returns {Track | null} The next track or null
272
- * @example
273
- * const nextTrack = queue.nextTrack;
274
- * console.log(`Next track: ${nextTrack?.title}`);
275
- */
276
- get nextTrack(): Track | null {
277
- return this.tracks[0] || null;
278
- }
279
-
280
- /**
281
- * Move back to the previously played track.
282
- * Makes the current track the next upcoming track, then sets previous as current.
283
- *
284
- * @returns {Track | null} The previous track or null
285
- * @example
286
- * const previousTrack = queue.previous();
287
- * console.log(`Previous track: ${previousTrack?.title}`);
288
- */
289
- previous(): Track | null {
290
- if (this.history.length === 0) return null;
291
- if (this.current) {
292
- this.tracks.unshift(this.current);
293
- }
294
- this.current = this.history.pop() || null;
295
- return this.current;
296
- }
297
-
298
- /**
299
- * Get the next track
300
- *
301
- * @param {Track} track - The next track
302
- * @returns {Track | null} The next track or null
303
- * @example
304
- * const nextTrack = queue.willNextTrack();
305
- * console.log(`Next track: ${nextTrack?.title}`);
306
- */
307
- willNextTrack(track?: Track): Track | null {
308
- if (track) {
309
- this.willnext = track;
310
- }
311
- return this.willnext;
312
- }
313
-
314
- /**
315
- * Get the related tracks
316
- *
317
- * @param {Track[]} track - The related tracks
318
- * @returns {Track[] | null} The related tracks or null
319
- * @example
320
- * const relatedTracks = queue.relatedTracks();
321
- * console.log(`Related tracks: ${relatedTracks?.length}`);
322
- */
323
- relatedTracks(track?: Track[]): Track[] | null {
324
- if (track) {
325
- this.related = track;
326
- }
327
- return this.related;
328
- }
329
-
330
- /**
331
- * Get the tracks
332
- *
333
- * @returns {Track[]} The tracks
334
- * @example
335
- * const tracks = queue.getTracks();
336
- * console.log(`Tracks: ${tracks.length}`);
337
- */
338
- getTracks(): Track[] {
339
- return [...this.tracks];
340
- }
341
-
342
- /**
343
- * Get a track at a specific index
344
- *
345
- * @param {number} index - The index of the track
346
- * @returns {Track | null} The track or null
347
- * @example
348
- * const track = queue.getTrack(0);
349
- * console.log(`Track: ${track?.title}`);
350
- */
351
- getTrack(index: number): Track | null {
352
- return this.tracks[index] || null;
353
- }
354
- }
1
+ import { Track, LoopMode } from "../types";
2
+
3
+ /**
4
+ * Manages the track queue for a player.
5
+ *
6
+ * @example
7
+ * // Basic queue operations
8
+ * const queue = player.queue;
9
+ *
10
+ * // Add single track
11
+ * queue.add(track);
12
+ *
13
+ * // Add multiple tracks
14
+ * queue.add([track1, track2, track3]);
15
+ *
16
+ * // Queue controls
17
+ * queue.shuffle(); // Randomize order
18
+ * queue.clear(); // Remove all tracks
19
+ * queue.autoPlay(true); // Enable auto-play
20
+ *
21
+ * // Get queue information
22
+ * console.log(`Queue length: ${queue.length}`);
23
+ * console.log(`Current track: ${queue.current?.title}`);
24
+ * console.log(`Is empty: ${queue.isEmpty}`);
25
+ * console.log(`Is playing: ${queue.isPlaying}`);
26
+ *
27
+ * // Loop modes
28
+ * queue.setLoopMode("track"); // Loop current track
29
+ * queue.setLoopMode("queue"); // Loop entire queue
30
+ * queue.setLoopMode("off"); // No loop
31
+ *
32
+ * // Remove specific track
33
+ * const removed = queue.remove(0); // Remove first track
34
+ * if (removed) {
35
+ * console.log(`Removed: ${removed.title}`);
36
+ * }
37
+ */
38
+ export class Queue {
39
+ private tracks: Track[] = [];
40
+ private current: Track | null = null;
41
+ private history: Track[] = [];
42
+ private related: Track[] = [];
43
+ private _autoPlay = false;
44
+ private _loop: LoopMode = "off";
45
+ private willnext: Track | null = null;
46
+
47
+ /**
48
+ * Add track(s) to the queue
49
+ *
50
+ * @param {Track | Track[]} track - Track or array of tracks to add
51
+ * @example
52
+ * queue.add(track);
53
+ * queue.add([track1, track2, track3]);
54
+ */
55
+ add(track: Track): void {
56
+ this.tracks.push(track);
57
+ }
58
+
59
+ /**
60
+ * Add multiple tracks to the queue
61
+ *
62
+ * @param {Track[]} tracks - Tracks to add
63
+ * @example
64
+ * queue.addMultiple([track1, track2, track3]);
65
+ */
66
+ addMultiple(tracks: Track[]): void {
67
+ this.tracks.push(...tracks);
68
+ }
69
+
70
+ /**
71
+ * Insert a track at a specific upcoming position (0 = next)
72
+ *
73
+ * @param {Track} track - Track to insert
74
+ * @param {number} index - Index to insert the track at
75
+ * @example
76
+ * queue.insert(track, 0);
77
+ */
78
+ insert(track: Track, index: number): void {
79
+ if (!Number.isFinite(index)) {
80
+ this.tracks.push(track);
81
+ return;
82
+ }
83
+ const i = Math.max(0, Math.min(Math.floor(index), this.tracks.length));
84
+ if (i === this.tracks.length) {
85
+ this.tracks.push(track);
86
+ return;
87
+ }
88
+ if (i <= 0) {
89
+ this.tracks.unshift(track);
90
+ return;
91
+ }
92
+ this.tracks.splice(i, 0, track);
93
+ }
94
+
95
+ /**
96
+ * Insert multiple tracks at a specific upcoming position, preserving order
97
+ *
98
+ * @param {Track[]} tracks - Tracks to insert
99
+ * @param {number} index - Index to insert the tracks at
100
+ * @example
101
+ * queue.insertMultiple([track1, track2, track3], 0);
102
+ */
103
+ insertMultiple(tracks: Track[], index: number): void {
104
+ if (!Array.isArray(tracks) || tracks.length === 0) return;
105
+ if (!Number.isFinite(index)) {
106
+ this.tracks.push(...tracks);
107
+ return;
108
+ }
109
+ const i = Math.max(0, Math.min(Math.floor(index), this.tracks.length));
110
+ if (i === 0) {
111
+ this.tracks = [...tracks, ...this.tracks];
112
+ return;
113
+ }
114
+ if (i === this.tracks.length) {
115
+ this.tracks.push(...tracks);
116
+ return;
117
+ }
118
+ this.tracks.splice(i, 0, ...tracks);
119
+ }
120
+
121
+ /**
122
+ * Remove a track from the queue
123
+ *
124
+ * @param {number} index - Index of track to remove
125
+ * @returns {Track | null} Removed track or null
126
+ * @example
127
+ * const removed = queue.remove(0);
128
+ * console.log(`Removed: ${removed?.title}`);
129
+ */
130
+
131
+ remove(index: number): Track | null {
132
+ if (index < 0 || index >= this.tracks.length) return null;
133
+ return this.tracks.splice(index, 1)[0];
134
+ }
135
+
136
+ /**
137
+ * Get the next track in the queue
138
+ *
139
+ * @param {boolean} ignoreLoop - Ignore the loop mode
140
+ * @returns {Track | null} The next track or null
141
+ * @example
142
+ * const nextTrack = queue.next();
143
+ * console.log(`Next track: ${nextTrack?.title}`);
144
+ */
145
+ next(ignoreLoop = false): Track | null {
146
+ if (this.current) {
147
+ if (this._loop === "track" && !ignoreLoop) {
148
+ return this.current;
149
+ }
150
+ this.history.push(this.current);
151
+ if (this.history.length > 200) {
152
+ this.history.shift();
153
+ }
154
+ }
155
+ this.current = this.tracks.shift() || null;
156
+ if (!this.current && this._loop === "queue" && this.history.length > 0 && !ignoreLoop) {
157
+ this.tracks = [...this.history];
158
+ this.history = [];
159
+ this.current = this.tracks.shift() || null;
160
+ }
161
+ return this.current;
162
+ }
163
+
164
+ /**
165
+ * Clear all tracks from the queue
166
+ *
167
+ * @example
168
+ * queue.clear();
169
+ */
170
+ clear(): void {
171
+ this.tracks = [];
172
+ }
173
+
174
+ /**
175
+ * Enable or disable auto-play
176
+ *
177
+ * @param {boolean} value - Enable/disable auto-play
178
+ * @returns {boolean} Current auto-play state
179
+ * @example
180
+ * queue.autoPlay(true);
181
+ * queue.autoPlay(); // Get current auto-play state
182
+ */
183
+
184
+ autoPlay(value?: boolean): boolean {
185
+ if (typeof value !== "undefined") {
186
+ this._autoPlay = value;
187
+ }
188
+ return this._autoPlay;
189
+ }
190
+
191
+ /**
192
+ * Set the loop mode
193
+ *
194
+ * @param {LoopMode} mode - Loop mode to set
195
+ * @returns {LoopMode} The loop mode
196
+ * @example
197
+ * queue.loop("track");
198
+ */
199
+ loop(mode?: LoopMode): LoopMode {
200
+ if (mode) {
201
+ this._loop = mode;
202
+ }
203
+ return this._loop;
204
+ }
205
+
206
+ /**
207
+ * Shuffle the queue
208
+ *
209
+ * @example
210
+ * queue.shuffle();
211
+ */
212
+
213
+ shuffle(): void {
214
+ for (let i = this.tracks.length - 1; i > 0; i--) {
215
+ const j = Math.floor(Math.random() * (i + 1));
216
+ [this.tracks[i], this.tracks[j]] = [this.tracks[j], this.tracks[i]];
217
+ }
218
+ }
219
+
220
+ /**
221
+ * Get the size of the queue
222
+ *
223
+ * @returns {number} The size of the queue
224
+ * @example
225
+ * const size = queue.size;
226
+ * console.log(`Queue size: ${size}`);
227
+ */
228
+ get size(): number {
229
+ return this.tracks.length;
230
+ }
231
+
232
+ /**
233
+ * Check if the queue is empty
234
+ *
235
+ * @returns {boolean} True if the queue is empty
236
+ * @example
237
+ * const empty = queue.isEmpty;
238
+ * console.log(`Queue is empty: ${empty}`);
239
+ */
240
+ get isEmpty(): boolean {
241
+ return this.tracks.length === 0;
242
+ }
243
+
244
+ /**
245
+ * Get the current track
246
+ *
247
+ * @returns {Track | null} The current track or null
248
+ * @example
249
+ * const currentTrack = queue.currentTrack;
250
+ * console.log(`Current track: ${currentTrack?.title}`);
251
+ */
252
+ get currentTrack(): Track | null {
253
+ return this.current;
254
+ }
255
+
256
+ /**
257
+ * Get the previous tracks
258
+ *
259
+ * @returns {Track[]} The previous tracks
260
+ * @example
261
+ * const previousTracks = queue.previousTracks;
262
+ * console.log(`Previous tracks: ${previousTracks.length}`);
263
+ */
264
+ get previousTracks(): Track[] {
265
+ return [...this.history];
266
+ }
267
+
268
+ /**
269
+ * Get the next track
270
+ *
271
+ * @returns {Track | null} The next track or null
272
+ * @example
273
+ * const nextTrack = queue.nextTrack;
274
+ * console.log(`Next track: ${nextTrack?.title}`);
275
+ */
276
+ get nextTrack(): Track | null {
277
+ return this.tracks[0] || null;
278
+ }
279
+
280
+ /**
281
+ * Move back to the previously played track.
282
+ * Makes the current track the next upcoming track, then sets previous as current.
283
+ *
284
+ * @returns {Track | null} The previous track or null
285
+ * @example
286
+ * const previousTrack = queue.previous();
287
+ * console.log(`Previous track: ${previousTrack?.title}`);
288
+ */
289
+ previous(): Track | null {
290
+ if (this.history.length === 0) return null;
291
+ if (this.current) {
292
+ this.tracks.unshift(this.current);
293
+ }
294
+ this.current = this.history.pop() || null;
295
+ return this.current;
296
+ }
297
+
298
+ /**
299
+ * Get the next track
300
+ *
301
+ * @param {Track} track - The next track
302
+ * @returns {Track | null} The next track or null
303
+ * @example
304
+ * const nextTrack = queue.willNextTrack();
305
+ * console.log(`Next track: ${nextTrack?.title}`);
306
+ */
307
+ willNextTrack(track?: Track): Track | null {
308
+ if (track) {
309
+ this.willnext = track;
310
+ }
311
+ return this.willnext;
312
+ }
313
+
314
+ /**
315
+ * Get the related tracks
316
+ *
317
+ * @param {Track[]} track - The related tracks
318
+ * @returns {Track[] | null} The related tracks or null
319
+ * @example
320
+ * const relatedTracks = queue.relatedTracks();
321
+ * console.log(`Related tracks: ${relatedTracks?.length}`);
322
+ */
323
+ relatedTracks(track?: Track[]): Track[] | null {
324
+ if (track) {
325
+ this.related = track;
326
+ }
327
+ return this.related;
328
+ }
329
+
330
+ /**
331
+ * Get the tracks
332
+ *
333
+ * @returns {Track[]} The tracks
334
+ * @example
335
+ * const tracks = queue.getTracks();
336
+ * console.log(`Tracks: ${tracks.length}`);
337
+ */
338
+ getTracks(): Track[] {
339
+ return [...this.tracks];
340
+ }
341
+
342
+ /**
343
+ * Get a track at a specific index
344
+ *
345
+ * @param {number} index - The index of the track
346
+ * @returns {Track | null} The track or null
347
+ * @example
348
+ * const track = queue.getTrack(0);
349
+ * console.log(`Track: ${track?.title}`);
350
+ */
351
+ getTrack(index: number): Track | null {
352
+ return this.tracks[index] || null;
353
+ }
354
+ }