@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 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
- api?.logger.debug("Auto-advancing to next track", { nextIdx });
196
- setCurrentTrack(nextIdx);
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
- api?.logger.debug("Auto-advancing to next track", { nextIdx });
171
- setCurrentTrack(nextIdx);
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.5.3",
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.5.3"
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.5.3"
32
+ "@scarlett-player/core": "1.0.1"
33
33
  },
34
34
  "keywords": [
35
35
  "video",