@scarlett-player/playlist 0.5.3 → 1.0.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.
- package/dist/index.cjs +24 -4
- package/dist/index.d.cts +8 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +24 -4
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -30,7 +30,9 @@ var DEFAULT_CONFIG = {
|
|
|
30
30
|
persist: false,
|
|
31
31
|
persistKey: "scarlett-playlist",
|
|
32
32
|
shuffle: false,
|
|
33
|
-
repeat: "none"
|
|
33
|
+
repeat: "none",
|
|
34
|
+
autoLoad: true,
|
|
35
|
+
advanceDelay: 0
|
|
34
36
|
};
|
|
35
37
|
function generateId() {
|
|
36
38
|
return `track-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
|
|
@@ -47,7 +49,10 @@ function createPlaylistPlugin(config) {
|
|
|
47
49
|
const mergedConfig = { ...DEFAULT_CONFIG, ...config };
|
|
48
50
|
let api = null;
|
|
49
51
|
let tracks = mergedConfig.tracks || [];
|
|
50
|
-
let currentIndex = -1;
|
|
52
|
+
let currentIndex = mergedConfig.initialIndex ?? -1;
|
|
53
|
+
if (currentIndex < -1 || currentIndex >= tracks.length) {
|
|
54
|
+
currentIndex = -1;
|
|
55
|
+
}
|
|
51
56
|
let shuffle = mergedConfig.shuffle || false;
|
|
52
57
|
let repeat = mergedConfig.repeat || "none";
|
|
53
58
|
let shuffleOrder = [];
|
|
@@ -174,6 +179,9 @@ function createPlaylistPlugin(config) {
|
|
|
174
179
|
}
|
|
175
180
|
api?.setState("mediaType", track.type || "audio");
|
|
176
181
|
emitChange();
|
|
182
|
+
if (mergedConfig.autoLoad !== false && track.src) {
|
|
183
|
+
api?.emit("media:load-request", { src: track.src, autoplay: true });
|
|
184
|
+
}
|
|
177
185
|
};
|
|
178
186
|
const plugin = {
|
|
179
187
|
id: "playlist",
|
|
@@ -188,12 +196,20 @@ function createPlaylistPlugin(config) {
|
|
|
188
196
|
if (shuffle && tracks.length > 0) {
|
|
189
197
|
generateShuffleOrder();
|
|
190
198
|
}
|
|
199
|
+
let advanceTimeout = null;
|
|
191
200
|
const unsubEnded = api.on("playback:ended", () => {
|
|
192
201
|
if (!mergedConfig.autoAdvance) return;
|
|
193
202
|
const nextIdx = getNextIndex();
|
|
194
203
|
if (nextIdx >= 0) {
|
|
195
|
-
|
|
196
|
-
|
|
204
|
+
const advance = () => {
|
|
205
|
+
api?.logger.debug("Auto-advancing to next track", { nextIdx });
|
|
206
|
+
setCurrentTrack(nextIdx);
|
|
207
|
+
};
|
|
208
|
+
if (mergedConfig.advanceDelay) {
|
|
209
|
+
advanceTimeout = setTimeout(advance, mergedConfig.advanceDelay);
|
|
210
|
+
} else {
|
|
211
|
+
advance();
|
|
212
|
+
}
|
|
197
213
|
} else {
|
|
198
214
|
api?.logger.info("Playlist ended");
|
|
199
215
|
api?.emit("playlist:ended", void 0);
|
|
@@ -201,6 +217,10 @@ function createPlaylistPlugin(config) {
|
|
|
201
217
|
});
|
|
202
218
|
api.onDestroy(() => {
|
|
203
219
|
unsubEnded();
|
|
220
|
+
if (advanceTimeout) {
|
|
221
|
+
clearTimeout(advanceTimeout);
|
|
222
|
+
advanceTimeout = null;
|
|
223
|
+
}
|
|
204
224
|
persistPlaylist();
|
|
205
225
|
});
|
|
206
226
|
},
|
package/dist/index.d.cts
CHANGED
|
@@ -28,6 +28,8 @@ interface PlaylistTrack {
|
|
|
28
28
|
mimeType?: string;
|
|
29
29
|
/** Additional metadata */
|
|
30
30
|
metadata?: Record<string, unknown>;
|
|
31
|
+
/** Allow additional properties for extensibility */
|
|
32
|
+
[key: string]: unknown;
|
|
31
33
|
}
|
|
32
34
|
/**
|
|
33
35
|
* Repeat mode
|
|
@@ -72,6 +74,12 @@ interface PlaylistPluginConfig {
|
|
|
72
74
|
shuffle?: boolean;
|
|
73
75
|
/** Initial repeat mode */
|
|
74
76
|
repeat?: RepeatMode;
|
|
77
|
+
/** Emit media:load-request on track change so core player loads automatically (default: true) */
|
|
78
|
+
autoLoad?: boolean;
|
|
79
|
+
/** Milliseconds to wait before auto-advancing to next track (default: 0) */
|
|
80
|
+
advanceDelay?: number;
|
|
81
|
+
/** Initial track index when tracks are provided and the player loads the first source via constructor (default: -1, meaning no track is active yet) */
|
|
82
|
+
initialIndex?: number;
|
|
75
83
|
/** Index signature for PluginConfig compatibility */
|
|
76
84
|
[key: string]: unknown;
|
|
77
85
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -28,6 +28,8 @@ interface PlaylistTrack {
|
|
|
28
28
|
mimeType?: string;
|
|
29
29
|
/** Additional metadata */
|
|
30
30
|
metadata?: Record<string, unknown>;
|
|
31
|
+
/** Allow additional properties for extensibility */
|
|
32
|
+
[key: string]: unknown;
|
|
31
33
|
}
|
|
32
34
|
/**
|
|
33
35
|
* Repeat mode
|
|
@@ -72,6 +74,12 @@ interface PlaylistPluginConfig {
|
|
|
72
74
|
shuffle?: boolean;
|
|
73
75
|
/** Initial repeat mode */
|
|
74
76
|
repeat?: RepeatMode;
|
|
77
|
+
/** Emit media:load-request on track change so core player loads automatically (default: true) */
|
|
78
|
+
autoLoad?: boolean;
|
|
79
|
+
/** Milliseconds to wait before auto-advancing to next track (default: 0) */
|
|
80
|
+
advanceDelay?: number;
|
|
81
|
+
/** Initial track index when tracks are provided and the player loads the first source via constructor (default: -1, meaning no track is active yet) */
|
|
82
|
+
initialIndex?: number;
|
|
75
83
|
/** Index signature for PluginConfig compatibility */
|
|
76
84
|
[key: string]: unknown;
|
|
77
85
|
}
|
package/dist/index.js
CHANGED
|
@@ -5,7 +5,9 @@ var DEFAULT_CONFIG = {
|
|
|
5
5
|
persist: false,
|
|
6
6
|
persistKey: "scarlett-playlist",
|
|
7
7
|
shuffle: false,
|
|
8
|
-
repeat: "none"
|
|
8
|
+
repeat: "none",
|
|
9
|
+
autoLoad: true,
|
|
10
|
+
advanceDelay: 0
|
|
9
11
|
};
|
|
10
12
|
function generateId() {
|
|
11
13
|
return `track-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
|
|
@@ -22,7 +24,10 @@ function createPlaylistPlugin(config) {
|
|
|
22
24
|
const mergedConfig = { ...DEFAULT_CONFIG, ...config };
|
|
23
25
|
let api = null;
|
|
24
26
|
let tracks = mergedConfig.tracks || [];
|
|
25
|
-
let currentIndex = -1;
|
|
27
|
+
let currentIndex = mergedConfig.initialIndex ?? -1;
|
|
28
|
+
if (currentIndex < -1 || currentIndex >= tracks.length) {
|
|
29
|
+
currentIndex = -1;
|
|
30
|
+
}
|
|
26
31
|
let shuffle = mergedConfig.shuffle || false;
|
|
27
32
|
let repeat = mergedConfig.repeat || "none";
|
|
28
33
|
let shuffleOrder = [];
|
|
@@ -149,6 +154,9 @@ function createPlaylistPlugin(config) {
|
|
|
149
154
|
}
|
|
150
155
|
api?.setState("mediaType", track.type || "audio");
|
|
151
156
|
emitChange();
|
|
157
|
+
if (mergedConfig.autoLoad !== false && track.src) {
|
|
158
|
+
api?.emit("media:load-request", { src: track.src, autoplay: true });
|
|
159
|
+
}
|
|
152
160
|
};
|
|
153
161
|
const plugin = {
|
|
154
162
|
id: "playlist",
|
|
@@ -163,12 +171,20 @@ function createPlaylistPlugin(config) {
|
|
|
163
171
|
if (shuffle && tracks.length > 0) {
|
|
164
172
|
generateShuffleOrder();
|
|
165
173
|
}
|
|
174
|
+
let advanceTimeout = null;
|
|
166
175
|
const unsubEnded = api.on("playback:ended", () => {
|
|
167
176
|
if (!mergedConfig.autoAdvance) return;
|
|
168
177
|
const nextIdx = getNextIndex();
|
|
169
178
|
if (nextIdx >= 0) {
|
|
170
|
-
|
|
171
|
-
|
|
179
|
+
const advance = () => {
|
|
180
|
+
api?.logger.debug("Auto-advancing to next track", { nextIdx });
|
|
181
|
+
setCurrentTrack(nextIdx);
|
|
182
|
+
};
|
|
183
|
+
if (mergedConfig.advanceDelay) {
|
|
184
|
+
advanceTimeout = setTimeout(advance, mergedConfig.advanceDelay);
|
|
185
|
+
} else {
|
|
186
|
+
advance();
|
|
187
|
+
}
|
|
172
188
|
} else {
|
|
173
189
|
api?.logger.info("Playlist ended");
|
|
174
190
|
api?.emit("playlist:ended", void 0);
|
|
@@ -176,6 +192,10 @@ function createPlaylistPlugin(config) {
|
|
|
176
192
|
});
|
|
177
193
|
api.onDestroy(() => {
|
|
178
194
|
unsubEnded();
|
|
195
|
+
if (advanceTimeout) {
|
|
196
|
+
clearTimeout(advanceTimeout);
|
|
197
|
+
advanceTimeout = null;
|
|
198
|
+
}
|
|
179
199
|
persistPlaylist();
|
|
180
200
|
});
|
|
181
201
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@scarlett-player/playlist",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "Playlist Plugin for Scarlett Player - Queue management, shuffle, repeat, and gapless playback",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.cjs",
|
|
@@ -22,14 +22,14 @@
|
|
|
22
22
|
"dist"
|
|
23
23
|
],
|
|
24
24
|
"peerDependencies": {
|
|
25
|
-
"@scarlett-player/core": "^0.
|
|
25
|
+
"@scarlett-player/core": "^1.0.1"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"tsup": "^8.0.0",
|
|
29
29
|
"typescript": "^5.3.0",
|
|
30
30
|
"vitest": "^1.6.0",
|
|
31
31
|
"jsdom": "^24.0.0",
|
|
32
|
-
"@scarlett-player/core": "0.
|
|
32
|
+
"@scarlett-player/core": "1.0.1"
|
|
33
33
|
},
|
|
34
34
|
"keywords": [
|
|
35
35
|
"video",
|