ziplayer 0.2.7 → 0.3.0

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.
Files changed (63) hide show
  1. package/AI-Guide.md +624 -956
  2. package/README.md +277 -10
  3. package/dist/extensions/BaseExtension.d.ts +1 -0
  4. package/dist/extensions/BaseExtension.d.ts.map +1 -1
  5. package/dist/extensions/BaseExtension.js.map +1 -1
  6. package/dist/extensions/index.d.ts +38 -3
  7. package/dist/extensions/index.d.ts.map +1 -1
  8. package/dist/extensions/index.js +259 -41
  9. package/dist/extensions/index.js.map +1 -1
  10. package/dist/persistence/PersistenceManager.d.ts +95 -0
  11. package/dist/persistence/PersistenceManager.d.ts.map +1 -0
  12. package/dist/persistence/PersistenceManager.js +975 -0
  13. package/dist/persistence/PersistenceManager.js.map +1 -0
  14. package/dist/plugins/BasePlugin.js +1 -1
  15. package/dist/plugins/BasePlugin.js.map +1 -1
  16. package/dist/plugins/index.d.ts +73 -8
  17. package/dist/plugins/index.d.ts.map +1 -1
  18. package/dist/plugins/index.js +647 -116
  19. package/dist/plugins/index.js.map +1 -1
  20. package/dist/structures/FilterManager.js +3 -3
  21. package/dist/structures/FilterManager.js.map +1 -1
  22. package/dist/structures/PersistenceManager.d.ts +96 -0
  23. package/dist/structures/PersistenceManager.d.ts.map +1 -0
  24. package/dist/structures/PersistenceManager.js +1008 -0
  25. package/dist/structures/PersistenceManager.js.map +1 -0
  26. package/dist/structures/Player.d.ts +157 -14
  27. package/dist/structures/Player.d.ts.map +1 -1
  28. package/dist/structures/Player.js +1163 -188
  29. package/dist/structures/Player.js.map +1 -1
  30. package/dist/structures/PlayerManager.d.ts +106 -91
  31. package/dist/structures/PlayerManager.d.ts.map +1 -1
  32. package/dist/structures/PlayerManager.js +365 -124
  33. package/dist/structures/PlayerManager.js.map +1 -1
  34. package/dist/structures/Queue.d.ts +136 -31
  35. package/dist/structures/Queue.d.ts.map +1 -1
  36. package/dist/structures/Queue.js +265 -46
  37. package/dist/structures/Queue.js.map +1 -1
  38. package/dist/structures/StreamManager.d.ts +137 -0
  39. package/dist/structures/StreamManager.d.ts.map +1 -0
  40. package/dist/structures/StreamManager.js +420 -0
  41. package/dist/structures/StreamManager.js.map +1 -0
  42. package/dist/types/index.d.ts +181 -8
  43. package/dist/types/index.d.ts.map +1 -1
  44. package/dist/types/index.js.map +1 -1
  45. package/dist/types/persistence.d.ts +77 -0
  46. package/dist/types/persistence.d.ts.map +1 -0
  47. package/dist/types/persistence.js +3 -0
  48. package/dist/types/persistence.js.map +1 -0
  49. package/package.json +3 -2
  50. package/src/extensions/BaseExtension.ts +1 -0
  51. package/src/extensions/index.ts +320 -37
  52. package/src/plugins/BasePlugin.ts +1 -1
  53. package/src/plugins/index.ts +801 -139
  54. package/src/structures/FilterManager.ts +3 -3
  55. package/src/structures/Player.ts +2797 -1693
  56. package/src/structures/PlayerManager.ts +438 -129
  57. package/src/structures/Queue.ts +300 -55
  58. package/src/structures/StreamManager.ts +524 -0
  59. package/src/types/extension.ts +129 -129
  60. package/src/types/fillter.ts +264 -264
  61. package/src/types/index.ts +187 -12
  62. package/src/types/plugin.ts +59 -59
  63. package/tsconfig.json +0 -1
package/README.md CHANGED
@@ -21,6 +21,16 @@ advanced music bots quickly.
21
21
  - 🗂️ **Per-guild player system** — Scales across multiple Discord servers
22
22
  - 📡 **Event-driven core** — Full lifecycle hooks for customization
23
23
  - 💾 **Custom userdata** — Attach context to each player
24
+ - ⚡ **Smart caching** — Search and stream caching for better performance
25
+ - 🎯 **Queue management** — Advanced queue operations (move, swap, batch remove)
26
+ - 💹 **Preload** - Auto Preload next Track
27
+ - 🔃 **Crossfade** - Suport crossfade for new/slip Track
28
+ - 🧠 **Transition Engine** - BPM/genre-aware crossfade (chill → long fade, EDM → short fade) with beat-aligned entry instead of
29
+ blind time-based fading
30
+ - 🔄 **Anti-Stuck Recovery 2.0** - Automatic stream failure recovery: reuse preload → fallback plugin → reduce quality →
31
+ controlled skip (no chaotic skipping)
32
+ - 🔊 **Loudness Normalization** - LUFS-based normalization prevents sudden volume jumps between tracks, with gentle limiter to
33
+ avoid distortion
24
34
 
25
35
  ---
26
36
 
@@ -78,16 +88,20 @@ client.login(process.env.DISCORD_TOKEN);
78
88
  ```
79
89
  PlayerManager (global)
80
90
  └── Player (per guild)
81
- ├── Queue
82
- ├── PluginManager
83
- ├── ExtensionManager
84
- └── FilterManager
91
+ ├── Queue (advanced operations)
92
+ ├── PluginManager (with caching & fallback)
93
+ ├── ExtensionManager (with priority & caching)
94
+ └── FilterManager (FFmpeg filters)
85
95
  ```
86
96
 
87
97
  ### Flow
88
98
 
89
99
  ```
90
100
  create → connect → play → stream → events → destroy
101
+
102
+ auto-save (periodic)
103
+
104
+ restore on restart
91
105
  ```
92
106
 
93
107
  ---
@@ -100,6 +114,8 @@ create → connect → play → stream → events → destroy
100
114
  await player.play("Never Gonna Give You Up", userId);
101
115
  await player.play("https://youtube.com/watch?v=...", userId);
102
116
  await player.play("tts: Hello world", userId);
117
+ await player.play(searchResult, userId); // Play from SearchResult
118
+ await player.play(null); // Resume from queue
103
119
  ```
104
120
 
105
121
  ### Controls
@@ -108,19 +124,47 @@ await player.play("tts: Hello world", userId);
108
124
  player.pause();
109
125
  player.resume();
110
126
  player.skip();
127
+ player.skip(2); // Skip to track at index 2
111
128
  player.stop();
112
129
  player.setVolume(100);
113
- player.loop("track");
130
+ player.loop("track"); // Loop current track
131
+ player.loop("queue"); // Loop entire queue
132
+ player.loop(1); // Number mode: 0=off, 1=track, 2=queue
114
133
  player.shuffle();
134
+ player.seek(30000); // Seek to 30 seconds
135
+ player.previous(); // Go back to previous track
115
136
  ```
116
137
 
117
- ### Queue
138
+ ### Queue Management
118
139
 
119
140
  ```ts
141
+ // Basic operations
120
142
  player.queue.add(track);
143
+ player.queue.addMultiple([track1, track2]);
121
144
  player.queue.remove(0);
122
- player.queue.shuffle();
145
+ player.queue.removeMultiple([0, 2, 5]); // Remove multiple indices
146
+ player.queue.removeWhere((t) => t.source === "youtube"); // Remove by condition
123
147
  player.queue.clear();
148
+
149
+ // Queue manipulation
150
+ player.queue.move(3, 0); // Move track at index 3 to front
151
+ player.queue.swap(1, 3); // Swap positions 1 and 3
152
+ player.queue.shuffle();
153
+
154
+ // Queue inspection
155
+ player.queue.size;
156
+ player.queue.isEmpty;
157
+ player.queue.currentTrack;
158
+ player.queue.nextTrack;
159
+ player.queue.lastTrack;
160
+ player.queue.previousTracks;
161
+ player.queue.getTrack(5);
162
+ player.queue.findTracks((t) => t.duration > 300000);
163
+ player.queue.indexOf(track);
164
+ player.queue.has(track);
165
+
166
+ // History navigation
167
+ player.queue.jumpToHistory(2); // Go back 2 tracks
124
168
  ```
125
169
 
126
170
  ---
@@ -145,6 +189,16 @@ new PlayerManager({
145
189
  });
146
190
  ```
147
191
 
192
+ ### Dynamic Plugin Registration
193
+
194
+ ```ts
195
+ // Register plugin after initialization
196
+ manager.registerPlugin(new YouTubePlugin());
197
+
198
+ // Get all registered plugins
199
+ const plugins = manager.getPlugins();
200
+ ```
201
+
148
202
  ---
149
203
 
150
204
  ## 🧩 Extensions
@@ -165,6 +219,14 @@ const manager = new PlayerManager({
165
219
  });
166
220
  ```
167
221
 
222
+ ### Extension Capabilities
223
+
224
+ Extensions can now provide:
225
+
226
+ - **Search** — Custom search handling
227
+ - **Stream** — Custom stream sources (Lavalink, etc.)
228
+ - **Before/After play hooks** — Modify playback behavior
229
+
168
230
  ---
169
231
 
170
232
  ## 🎛️ Audio Filters
@@ -174,6 +236,8 @@ Apply FFmpeg filters in real-time:
174
236
  ```ts
175
237
  await player.filter.applyFilter("bassboost");
176
238
  await player.filter.applyFilter("nightcore");
239
+ await player.filter.applyFilters(["bassboost", "trebleboost"]); // Multiple filters
240
+ await player.filter.getFilterString(); // "bassboost,trebleboost"
177
241
  await player.filter.clearAll();
178
242
  ```
179
243
 
@@ -194,6 +258,8 @@ const player = await manager.create(guildId, {
194
258
  tts: {
195
259
  createPlayer: true,
196
260
  interrupt: true,
261
+ volume: 100,
262
+ maxTimeTts: 60000,
197
263
  },
198
264
  });
199
265
 
@@ -208,8 +274,19 @@ Listen globally via manager:
208
274
 
209
275
  ```ts
210
276
  manager.on("trackStart", (player, track) => {});
277
+ manager.on("trackEnd", (player, track) => {});
211
278
  manager.on("queueEnd", (player) => {});
212
- manager.on("playerError", (player, error) => {});
279
+ manager.on("playerError", (player, error, track) => {});
280
+ manager.on("playerPause", (player, track) => {});
281
+ manager.on("playerResume", (player, track) => {});
282
+ manager.on("volumeChange", (player, oldVolume, newVolume) => {});
283
+ manager.on("queueAdd", (player, track) => {});
284
+ manager.on("queueAddList", (player, tracks) => {});
285
+ manager.on("queueRemove", (player, track, index) => {});
286
+ manager.on("playerDestroy", (player) => {});
287
+ manager.on("ttsStart", (player, payload) => {});
288
+ manager.on("ttsEnd", (player) => {});
289
+ manager.on("stats", (PlayerStats) => {});
213
290
  ```
214
291
 
215
292
  ---
@@ -225,14 +302,189 @@ player.queue.autoPlay(true);
225
302
  ### Insert next track
226
303
 
227
304
  ```ts
228
- await player.insert("song", 0);
305
+ await player.insert("song", 0); // Insert at position 0 (play next)
306
+ await player.insert([track1, track2], 2); // Insert multiple at index 2
229
307
  ```
230
308
 
231
- ### Save stream
309
+ ### Save stream to file
232
310
 
233
311
  ```ts
234
312
  const stream = await player.save(track);
235
313
  stream.pipe(fs.createWriteStream("song.mp3"));
314
+
315
+ // Save with filters
316
+ const filteredStream = await player.save(track, {
317
+ filter: ["bassboost"],
318
+ seek: 30000, // Start from 30 seconds
319
+ });
320
+ ```
321
+
322
+ ### Progress Bar
323
+
324
+ ```ts
325
+ // Default (compact time format)
326
+ console.log(player.getProgressBar());
327
+ // Output: "1:22:12 ▬▬▬▬▬▬▬▬▬▬🔘▬▬▬▬▬▬▬▬ 1:45:30"
328
+
329
+ // Custom options
330
+ console.log(
331
+ player.getProgressBar({
332
+ size: 30,
333
+ barChar: "─",
334
+ progressChar: "●",
335
+ timeFormat: "full", // "full" or "compact"
336
+ showPercentage: true,
337
+ }),
338
+ );
339
+ // Output: "01:22:12 ───────●───────────────────── 01:45:30 (47%)"
340
+ ```
341
+
342
+ ### Time Formatting
343
+
344
+ ```ts
345
+ const time = player.getTime();
346
+ console.log(time.formatted.current); // "1:22:12" (compact)
347
+ console.log(time.format); // "01:22:12" (full with leading zeros)
348
+ ```
349
+
350
+ ### Batch Operations
351
+
352
+ ```ts
353
+ // Broadcast action to all players
354
+ manager.broadcast("setVolume", 50);
355
+ manager.broadcast("pause");
356
+
357
+ // Get players by filter
358
+ const activePlayers = manager.getPlayersByFilter((p) => p.isPlaying);
359
+
360
+ // Delete multiple players
361
+ manager.deleteWhere((p) => p.queue.isEmpty && !p.isPlaying);
362
+ ```
363
+
364
+ ---
365
+
366
+ ## ⚙️ Advanced Configuration
367
+
368
+ ### PlayerManager Options
369
+
370
+ ```ts
371
+ const manager = new PlayerManager({
372
+ plugins: [...],
373
+ extensions: [...],
374
+ extractorTimeout: 30000, // Timeout for stream extraction
375
+ autoCleanup: true, // Auto cleanup inactive players
376
+ cleanupInterval: 120000, // Cleanup interval (ms)
377
+ enableSearchCache: true, // Cache search results
378
+ enableStatsCollection: true, // Enable stats events
379
+ persistence: {...} // Persistence configuration
380
+ });
381
+ ```
382
+
383
+ ### Player Options
384
+
385
+ ```ts
386
+ const player = await manager.create(guildId, {
387
+ volume: 100,
388
+ quality: "high",
389
+ leaveOnEnd: true,
390
+ leaveOnEmpty: true,
391
+ leaveTimeout: 100000,
392
+ selfDeaf: true,
393
+ selfMute: false,
394
+ extractorTimeout: 50000,
395
+ filters: ["bassboost", "nightcore"],
396
+ tts: {
397
+ createPlayer: false,
398
+ interrupt: true,
399
+ volume: 100,
400
+ maxTimeTts: 60000,
401
+ },
402
+ // Runtime profile
403
+ lowPerformance: false,
404
+ preload: {
405
+ enabled: true,
406
+ autoDisableInLowPerformance: true,
407
+ },
408
+ crossfade: {
409
+ enabled: undefined, // omit to let autoEnable decide
410
+ autoEnable: true,
411
+ autoDisableInLowPerformance: true,
412
+ durationMs: 5000,
413
+ },
414
+ smartTransition: {
415
+ enabled: true,
416
+ genreAware: true,
417
+ beatAlign: true,
418
+ baseDurationMs: 5000,
419
+ minDurationMs: 1200,
420
+ maxDurationMs: 8000,
421
+ genreDurations: { chill: 7000, edm: 2200 },
422
+ beatAlignMaxWaitMs: 1200,
423
+ },
424
+ antiStuck: {
425
+ enabled: true,
426
+ maxRetries: 2,
427
+ retryDelayMs: 900,
428
+ reusePreloadFirst: true,
429
+ reduceQualityOnRetry: true,
430
+ controlledSkipThreshold: 3,
431
+ },
432
+ loudnessNormalization: {
433
+ enabled: true,
434
+ targetLUFS: -14,
435
+ maxBoostDb: 8,
436
+ maxCutDb: 10,
437
+ limiterCeiling: 0.95,
438
+ },
439
+ userdata: { customField: "value" },
440
+ });
441
+ ```
442
+
443
+ ### Crossfade + Low Performance
444
+
445
+ ```ts
446
+ // Auto mode: crossfade/preload enabled unless lowPerformance is on
447
+ const player = await manager.create(guildId, {
448
+ lowPerformance: false,
449
+ preload: { enabled: true, autoDisableInLowPerformance: true },
450
+ crossfade: { autoEnable: true, autoDisableInLowPerformance: true, durationMs: 4000 },
451
+ });
452
+
453
+ // Low performance mode: auto disable preload and crossfade
454
+ const litePlayer = await manager.create(guildId, {
455
+ lowPerformance: true,
456
+ preload: { enabled: true, autoDisableInLowPerformance: true }, // resolved: disabled
457
+ crossfade: { autoEnable: true, autoDisableInLowPerformance: true }, // resolved: disabled
458
+ });
459
+ ```
460
+
461
+ > Crossfade is applied when switching to the next track and when calling `player.skip()`. Smart transition adapts fade by
462
+ > `metadata.genre` and can align to beat using `metadata.bpm`. Loudness normalization uses `metadata.lufs` when available and
463
+ > applies a limiter ceiling.
464
+
465
+ ---
466
+
467
+ ## 📊 Monitoring & Stats
468
+
469
+ ```ts
470
+ // Get manager statistics
471
+ const stats = manager.getStats();
472
+ console.log({
473
+ totalPlayers: stats.totalPlayers,
474
+ activePlayers: stats.activePlayers,
475
+ pausedPlayers: stats.pausedPlayers,
476
+ connectedPlayers: stats.connectedPlayers,
477
+ totalTracksInQueue: stats.totalTracksInQueue,
478
+ });
479
+
480
+ // Get plugin/extension stats
481
+ console.log(manager.getConfig());
482
+ console.log(player.pluginManager.getStats());
483
+ console.log(player.extensionManager.getStats());
484
+
485
+ // Clear caches
486
+ player.clearSearchCache();
487
+ player.extensionManager.clearCache("search");
236
488
  ```
237
489
 
238
490
  ---
@@ -243,6 +495,21 @@ stream.pipe(fs.createWriteStream("song.mp3"));
243
495
  - Always `await player.connect()` before playing
244
496
  - Handle `playerError` events
245
497
  - Do not reuse a destroyed player
498
+ - Enable **persistence** for production bots to survive restarts
499
+ - Use **autoCleanup** to prevent memory leaks
500
+ - Set appropriate **extractorTimeout** based on your network (default: 10-50 seconds)
501
+
502
+ ---
503
+
504
+ ## 🌟 Migration Guide
505
+
506
+ ### From v1.x to v2.x
507
+
508
+ - `player.getTime()` now returns `{ current, total, format, formatted }`
509
+ - `player.getProgressBar()` supports new options
510
+ - `player.queue.remove(index)` removed track is now returned
511
+ - New `queue.removeMultiple()`, `queue.move()`, `queue.swap()` methods
512
+ - Extension hooks now support async properly
246
513
 
247
514
  ---
248
515
 
@@ -3,6 +3,7 @@ import type { Player } from "../structures/Player";
3
3
  export declare abstract class BaseExtension implements SourceExtension {
4
4
  abstract name: string;
5
5
  abstract version: string;
6
+ priority?: number;
6
7
  abstract player: Player | null;
7
8
  abstract active(alas: any): boolean | Promise<boolean>;
8
9
  onRegister?(context: ExtensionContext): void | Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"BaseExtension.d.ts","sourceRoot":"","sources":["../../src/extensions/BaseExtension.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,eAAe,EACf,gBAAgB,EAChB,YAAY,EACZ,oBAAoB,EACpB,qBAAqB,EACrB,yBAAyB,EACzB,sBAAsB,EACtB,UAAU,EACV,sBAAsB,EACtB,MAAM,UAAU,CAAC;AAClB,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAEnD,8BAAsB,aAAc,YAAW,eAAe;IAC7D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,GAAG,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAEtD,UAAU,CAAC,CAAC,OAAO,EAAE,gBAAgB,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAC5D,SAAS,CAAC,CAAC,OAAO,EAAE,gBAAgB,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAC3D,UAAU,CAAC,CACV,OAAO,EAAE,gBAAgB,EACzB,OAAO,EAAE,oBAAoB,GAC3B,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC,GAAG,qBAAqB,GAAG,IAAI;IACvE,SAAS,CAAC,CAAC,OAAO,EAAE,gBAAgB,EAAE,OAAO,EAAE,yBAAyB,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;IAC/F,aAAa,CAAC,CACb,OAAO,EAAE,gBAAgB,EACzB,OAAO,EAAE,sBAAsB,GAC7B,OAAO,CAAC,YAAY,GAAG,IAAI,GAAG,SAAS,CAAC,GAAG,YAAY,GAAG,IAAI,GAAG,SAAS;IAC7E,aAAa,CAAC,CACb,OAAO,EAAE,gBAAgB,EACzB,OAAO,EAAE,sBAAsB,GAC7B,OAAO,CAAC,UAAU,GAAG,IAAI,GAAG,SAAS,CAAC,GAAG,UAAU,GAAG,IAAI,GAAG,SAAS;CACzE"}
1
+ {"version":3,"file":"BaseExtension.d.ts","sourceRoot":"","sources":["../../src/extensions/BaseExtension.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,eAAe,EACf,gBAAgB,EAChB,YAAY,EACZ,oBAAoB,EACpB,qBAAqB,EACrB,yBAAyB,EACzB,sBAAsB,EACtB,UAAU,EACV,sBAAsB,EACtB,MAAM,UAAU,CAAC;AAClB,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAEnD,8BAAsB,aAAc,YAAW,eAAe;IAC7D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,GAAG,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAEtD,UAAU,CAAC,CAAC,OAAO,EAAE,gBAAgB,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAC5D,SAAS,CAAC,CAAC,OAAO,EAAE,gBAAgB,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAC3D,UAAU,CAAC,CACV,OAAO,EAAE,gBAAgB,EACzB,OAAO,EAAE,oBAAoB,GAC3B,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC,GAAG,qBAAqB,GAAG,IAAI;IACvE,SAAS,CAAC,CAAC,OAAO,EAAE,gBAAgB,EAAE,OAAO,EAAE,yBAAyB,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;IAC/F,aAAa,CAAC,CACb,OAAO,EAAE,gBAAgB,EACzB,OAAO,EAAE,sBAAsB,GAC7B,OAAO,CAAC,YAAY,GAAG,IAAI,GAAG,SAAS,CAAC,GAAG,YAAY,GAAG,IAAI,GAAG,SAAS;IAC7E,aAAa,CAAC,CACb,OAAO,EAAE,gBAAgB,EACzB,OAAO,EAAE,sBAAsB,GAC7B,OAAO,CAAC,UAAU,GAAG,IAAI,GAAG,SAAS,CAAC,GAAG,UAAU,GAAG,IAAI,GAAG,SAAS;CACzE"}
@@ -1 +1 @@
1
- {"version":3,"file":"BaseExtension.js","sourceRoot":"","sources":["../../src/extensions/BaseExtension.ts"],"names":[],"mappings":";;;AAaA,MAAsB,aAAa;CAqBlC;AArBD,sCAqBC"}
1
+ {"version":3,"file":"BaseExtension.js","sourceRoot":"","sources":["../../src/extensions/BaseExtension.ts"],"names":[],"mappings":";;;AAaA,MAAsB,aAAa;CAsBlC;AAtBD,sCAsBC"}
@@ -3,11 +3,28 @@ import type { PlayerManager } from "../structures/PlayerManager";
3
3
  import type { SearchResult, StreamInfo, Track, ExtensionPlayRequest, ExtensionPlayResponse, ExtensionAfterPlayPayload } from "../types";
4
4
  import { BaseExtension } from "./BaseExtension";
5
5
  export { BaseExtension } from "./BaseExtension";
6
+ interface ExtensionMetadata {
7
+ name: string;
8
+ priority: number;
9
+ registeredAt: number;
10
+ hasSearch: boolean;
11
+ hasStream: boolean;
12
+ hasBeforePlay: boolean;
13
+ hasAfterPlay: boolean;
14
+ }
6
15
  export declare class ExtensionManager {
7
16
  private extensions;
17
+ private extensionMetadata;
8
18
  private player;
9
19
  private manager;
10
20
  private extensionContext;
21
+ private searchCache;
22
+ private streamCache;
23
+ private readonly SEARCH_CACHE_TTL;
24
+ private readonly STREAM_CACHE_TTL;
25
+ private readonly MAX_CACHE_SIZE;
26
+ private pendingSearches;
27
+ private pendingStreams;
11
28
  constructor(player: Player, manager: PlayerManager);
12
29
  debug(message?: any, ...optionalParams: any[]): void;
13
30
  register(extension: BaseExtension): void;
@@ -15,15 +32,33 @@ export declare class ExtensionManager {
15
32
  destroy(): void;
16
33
  get(name: string): BaseExtension | undefined;
17
34
  getAll(): BaseExtension[];
18
- findExtension(alas: any): BaseExtension | undefined;
35
+ getMetadata(name: string): ExtensionMetadata | undefined;
36
+ getAllMetadata(): ExtensionMetadata[];
37
+ findExtension(query: unknown): BaseExtension | undefined;
38
+ findExtensionsByCapability(capability: "search" | "stream" | "beforePlay" | "afterPlay"): BaseExtension[];
19
39
  clear(): void;
20
40
  private invokeExtensionLifecycle;
41
+ private getCacheKey;
42
+ private cleanupCaches;
43
+ private clearAllCaches;
44
+ private getCachedSearch;
45
+ private setCachedSearch;
46
+ private getCachedStream;
47
+ private setCachedStream;
21
48
  provideSearch(query: string, requestedBy: string): Promise<SearchResult | null>;
22
49
  provideStream(track: Track): Promise<StreamInfo | null>;
23
- BeforePlayHooks(initial: ExtensionPlayRequest): Promise<{
50
+ beforePlayHooks(initial: ExtensionPlayRequest): Promise<{
24
51
  request: ExtensionPlayRequest;
25
52
  response: ExtensionPlayResponse;
26
53
  }>;
27
- AfterPlayHooks(payload: ExtensionAfterPlayPayload): Promise<void>;
54
+ afterPlayHooks(payload: ExtensionAfterPlayPayload): Promise<void>;
55
+ /**
56
+ * Get extension statistics
57
+ */
58
+ getStats(): object;
59
+ /**
60
+ * Clear specific cache
61
+ */
62
+ clearCache(type?: "search" | "stream"): void;
28
63
  }
29
64
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/extensions/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,KAAK,EAEX,YAAY,EACZ,UAAU,EACV,KAAK,EAEL,oBAAoB,EACpB,qBAAqB,EACrB,yBAAyB,EAEzB,MAAM,UAAU,CAAC;AAElB,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAGhD,qBAAa,gBAAgB;IAC5B,OAAO,CAAC,UAAU,CAA6B;IAC/C,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,OAAO,CAAgB;IAC/B,OAAO,CAAC,gBAAgB,CAAmB;gBAE/B,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa;IAMlD,KAAK,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE,GAAG,cAAc,EAAE,GAAG,EAAE,GAAG,IAAI;IAMpD,QAAQ,CAAC,SAAS,EAAE,aAAa,GAAG,IAAI;IAUxC,UAAU,CAAC,SAAS,EAAE,aAAa,GAAG,OAAO;IAS7C,OAAO,IAAI,IAAI;IAQf,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS;IAI5C,MAAM,IAAI,aAAa,EAAE;IAIzB,aAAa,CAAC,IAAI,EAAE,GAAG,GAAG,aAAa,GAAG,SAAS;IAInD,KAAK,IAAI,IAAI;IAIb,OAAO,CAAC,wBAAwB;IAc1B,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;IAkB/E,aAAa,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAkBvD,eAAe,CACpB,OAAO,EAAE,oBAAoB,GAC3B,OAAO,CAAC;QAAE,OAAO,EAAE,oBAAoB,CAAC;QAAC,QAAQ,EAAE,qBAAqB,CAAA;KAAE,CAAC;IAwCxE,cAAc,CAAC,OAAO,EAAE,yBAAyB,GAAG,OAAO,CAAC,IAAI,CAAC;CAiBvE"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/extensions/index.ts"],"names":[],"mappings":"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"}