ziplayer 0.2.7-dev.0 → 0.2.7-dev.2

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 (54) hide show
  1. package/AI-Guide.md +407 -756
  2. package/README.md +275 -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 +968 -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 +19 -4
  17. package/dist/plugins/index.d.ts.map +1 -1
  18. package/dist/plugins/index.js +204 -113
  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/Player.d.ts +65 -14
  23. package/dist/structures/Player.d.ts.map +1 -1
  24. package/dist/structures/Player.js +330 -88
  25. package/dist/structures/Player.js.map +1 -1
  26. package/dist/structures/PlayerManager.d.ts +127 -91
  27. package/dist/structures/PlayerManager.d.ts.map +1 -1
  28. package/dist/structures/PlayerManager.js +437 -124
  29. package/dist/structures/PlayerManager.js.map +1 -1
  30. package/dist/structures/Queue.d.ts +136 -31
  31. package/dist/structures/Queue.d.ts.map +1 -1
  32. package/dist/structures/Queue.js +265 -46
  33. package/dist/structures/Queue.js.map +1 -1
  34. package/dist/types/index.d.ts +46 -6
  35. package/dist/types/index.d.ts.map +1 -1
  36. package/dist/types/index.js +1 -0
  37. package/dist/types/index.js.map +1 -1
  38. package/dist/types/persistence.d.ts +74 -0
  39. package/dist/types/persistence.d.ts.map +1 -0
  40. package/dist/types/persistence.js +3 -0
  41. package/dist/types/persistence.js.map +1 -0
  42. package/package.json +3 -2
  43. package/src/extensions/BaseExtension.ts +1 -0
  44. package/src/extensions/index.ts +320 -37
  45. package/src/persistence/PersistenceManager.ts +1073 -0
  46. package/src/plugins/BasePlugin.ts +1 -1
  47. package/src/plugins/index.ts +248 -133
  48. package/src/structures/FilterManager.ts +3 -3
  49. package/src/structures/Player.ts +358 -94
  50. package/src/structures/PlayerManager.ts +535 -129
  51. package/src/structures/Queue.ts +300 -55
  52. package/src/types/index.ts +52 -10
  53. package/src/types/persistence.ts +83 -0
  54. package/src/types/plugin.ts +1 -1
package/README.md CHANGED
@@ -21,6 +21,9 @@ 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
+ - 💿 **Persistence** — Auto-save and restore player state across restarts
25
+ - ⚡ **Smart caching** — Search and stream caching for better performance
26
+ - 🎯 **Queue management** — Advanced queue operations (move, swap, batch remove)
24
27
 
25
28
  ---
26
29
 
@@ -77,17 +80,22 @@ client.login(process.env.DISCORD_TOKEN);
77
80
 
78
81
  ```
79
82
  PlayerManager (global)
83
+ ├── PersistenceManager (auto-save/load)
80
84
  └── Player (per guild)
81
- ├── Queue
82
- ├── PluginManager
83
- ├── ExtensionManager
84
- └── FilterManager
85
+ ├── Queue (advanced operations)
86
+ ├── PluginManager (with caching & fallback)
87
+ ├── ExtensionManager (with priority & caching)
88
+ └── FilterManager (FFmpeg filters)
85
89
  ```
86
90
 
87
91
  ### Flow
88
92
 
89
93
  ```
90
94
  create → connect → play → stream → events → destroy
95
+
96
+ auto-save (periodic)
97
+
98
+ restore on restart
91
99
  ```
92
100
 
93
101
  ---
@@ -100,6 +108,8 @@ create → connect → play → stream → events → destroy
100
108
  await player.play("Never Gonna Give You Up", userId);
101
109
  await player.play("https://youtube.com/watch?v=...", userId);
102
110
  await player.play("tts: Hello world", userId);
111
+ await player.play(searchResult, userId); // Play from SearchResult
112
+ await player.play(null); // Resume from queue
103
113
  ```
104
114
 
105
115
  ### Controls
@@ -108,19 +118,101 @@ await player.play("tts: Hello world", userId);
108
118
  player.pause();
109
119
  player.resume();
110
120
  player.skip();
121
+ player.skip(2); // Skip to track at index 2
111
122
  player.stop();
112
123
  player.setVolume(100);
113
- player.loop("track");
124
+ player.loop("track"); // Loop current track
125
+ player.loop("queue"); // Loop entire queue
126
+ player.loop(1); // Number mode: 0=off, 1=track, 2=queue
114
127
  player.shuffle();
128
+ player.seek(30000); // Seek to 30 seconds
129
+ player.previous(); // Go back to previous track
115
130
  ```
116
131
 
117
- ### Queue
132
+ ### Queue Management
118
133
 
119
134
  ```ts
135
+ // Basic operations
120
136
  player.queue.add(track);
137
+ player.queue.addMultiple([track1, track2]);
121
138
  player.queue.remove(0);
122
- player.queue.shuffle();
139
+ player.queue.removeMultiple([0, 2, 5]); // Remove multiple indices
140
+ player.queue.removeWhere((t) => t.source === "youtube"); // Remove by condition
123
141
  player.queue.clear();
142
+
143
+ // Queue manipulation
144
+ player.queue.move(3, 0); // Move track at index 3 to front
145
+ player.queue.swap(1, 3); // Swap positions 1 and 3
146
+ player.queue.shuffle();
147
+
148
+ // Queue inspection
149
+ player.queue.size;
150
+ player.queue.isEmpty;
151
+ player.queue.currentTrack;
152
+ player.queue.nextTrack;
153
+ player.queue.lastTrack;
154
+ player.queue.previousTracks;
155
+ player.queue.getTrack(5);
156
+ player.queue.findTracks((t) => t.duration > 300000);
157
+ player.queue.indexOf(track);
158
+ player.queue.has(track);
159
+
160
+ // History navigation
161
+ player.queue.jumpToHistory(2); // Go back 2 tracks
162
+ ```
163
+
164
+ ---
165
+
166
+ ## 💾 Persistence (Auto-save & Restore)
167
+
168
+ Automatically save and restore player state across bot restarts.
169
+
170
+ ### Setup
171
+
172
+ ```ts
173
+ const manager = new PlayerManager({
174
+ plugins: [new YouTubePlugin()],
175
+ persistence: {
176
+ enabled: true,
177
+ filePath: "./player_data",
178
+
179
+ // Backup management
180
+ maxBackups: 3, // Keep only 3 backups per player
181
+ maxTotalBackups: 20, // Keep max 20 total backup files
182
+ autoCleanupBackupsOnStart: true, // Clean old backups on startup
183
+ backupRetentionDays: 3, // Delete backups older than 3 days
184
+
185
+ // Auto restore
186
+ autoRestoreOnRestart: true,
187
+ restoreDelay: 3000,
188
+
189
+ compress: true,
190
+ },
191
+ });
192
+
193
+ // Listen to persistence events
194
+ manager.on("playerSaved", (guildId) => console.log(`Saved ${guildId}`));
195
+ manager.on("playerLoaded", (guildId, data) => console.log(`Loaded ${guildId} from ${new Date(data.lastUpdate)}`));
196
+ ```
197
+
198
+ ### Manual Persistence
199
+
200
+ ```ts
201
+ // Save specific player
202
+ await manager.savePlayer(guildId);
203
+ await player.save(); // From player instance
204
+
205
+ // Save all players
206
+ await manager.saveAllPlayers();
207
+
208
+ // Load players
209
+ await manager.loadPlayer(guildId, true); // Restore playback position
210
+ await manager.loadAllPlayers();
211
+
212
+ // Delete saved data
213
+ const persistence = manager.getPersistence();
214
+ await persistence?.deletePlayer(guildId);
215
+ await persistence?.restoreBackup(guildId); // Restore from backup
124
216
  ```
125
217
 
126
218
  ---
@@ -145,6 +237,16 @@ new PlayerManager({
145
237
  });
146
238
  ```
147
239
 
240
+ ### Dynamic Plugin Registration
241
+
242
+ ```ts
243
+ // Register plugin after initialization
244
+ manager.registerPlugin(new YouTubePlugin());
245
+
246
+ // Get all registered plugins
247
+ const plugins = manager.getPlugins();
248
+ ```
249
+
148
250
  ---
149
251
 
150
252
  ## 🧩 Extensions
@@ -165,6 +267,14 @@ const manager = new PlayerManager({
165
267
  });
166
268
  ```
167
269
 
270
+ ### Extension Capabilities
271
+
272
+ Extensions can now provide:
273
+
274
+ - **Search** — Custom search handling
275
+ - **Stream** — Custom stream sources (Lavalink, etc.)
276
+ - **Before/After play hooks** — Modify playback behavior
277
+
168
278
  ---
169
279
 
170
280
  ## 🎛️ Audio Filters
@@ -174,6 +284,8 @@ Apply FFmpeg filters in real-time:
174
284
  ```ts
175
285
  await player.filter.applyFilter("bassboost");
176
286
  await player.filter.applyFilter("nightcore");
287
+ await player.filter.applyFilters(["bassboost", "trebleboost"]); // Multiple filters
288
+ await player.filter.getFilterString(); // "bassboost,trebleboost"
177
289
  await player.filter.clearAll();
178
290
  ```
179
291
 
@@ -194,6 +306,8 @@ const player = await manager.create(guildId, {
194
306
  tts: {
195
307
  createPlayer: true,
196
308
  interrupt: true,
309
+ volume: 100,
310
+ maxTimeTts: 60000,
197
311
  },
198
312
  });
199
313
 
@@ -208,8 +322,24 @@ Listen globally via manager:
208
322
 
209
323
  ```ts
210
324
  manager.on("trackStart", (player, track) => {});
325
+ manager.on("trackEnd", (player, track) => {});
211
326
  manager.on("queueEnd", (player) => {});
212
- manager.on("playerError", (player, error) => {});
327
+ manager.on("playerError", (player, error, track) => {});
328
+ manager.on("playerPause", (player, track) => {});
329
+ manager.on("playerResume", (player, track) => {});
330
+ manager.on("volumeChange", (player, oldVolume, newVolume) => {});
331
+ manager.on("queueAdd", (player, track) => {});
332
+ manager.on("queueAddList", (player, tracks) => {});
333
+ manager.on("queueRemove", (player, track, index) => {});
334
+ manager.on("playerDestroy", (player) => {});
335
+ manager.on("ttsStart", (player, payload) => {});
336
+ manager.on("ttsEnd", (player) => {});
337
+
338
+ // Persistence events
339
+ manager.on("playerSaved", (guildId) => {});
340
+ manager.on("playerLoaded", (guildId, data) => {});
341
+ manager.on("savedAll", (results) => {});
342
+ manager.on("loadedAll", (results) => {});
213
343
  ```
214
344
 
215
345
  ---
@@ -225,14 +355,130 @@ player.queue.autoPlay(true);
225
355
  ### Insert next track
226
356
 
227
357
  ```ts
228
- await player.insert("song", 0);
358
+ await player.insert("song", 0); // Insert at position 0 (play next)
359
+ await player.insert([track1, track2], 2); // Insert multiple at index 2
229
360
  ```
230
361
 
231
- ### Save stream
362
+ ### Save stream to file
232
363
 
233
364
  ```ts
234
365
  const stream = await player.save(track);
235
366
  stream.pipe(fs.createWriteStream("song.mp3"));
367
+
368
+ // Save with filters
369
+ const filteredStream = await player.save(track, {
370
+ filter: ["bassboost"],
371
+ seek: 30000, // Start from 30 seconds
372
+ });
373
+ ```
374
+
375
+ ### Progress Bar
376
+
377
+ ```ts
378
+ // Default (compact time format)
379
+ console.log(player.getProgressBar());
380
+ // Output: "1:22:12 ▬▬▬▬▬▬▬▬▬▬🔘▬▬▬▬▬▬▬▬ 1:45:30"
381
+
382
+ // Custom options
383
+ console.log(
384
+ player.getProgressBar({
385
+ size: 30,
386
+ barChar: "─",
387
+ progressChar: "●",
388
+ timeFormat: "full", // "full" or "compact"
389
+ showPercentage: true,
390
+ }),
391
+ );
392
+ // Output: "01:22:12 ───────●───────────────────── 01:45:30 (47%)"
393
+ ```
394
+
395
+ ### Time Formatting
396
+
397
+ ```ts
398
+ const time = player.getTime();
399
+ console.log(time.formatted.current); // "1:22:12" (compact)
400
+ console.log(time.format); // "01:22:12" (full with leading zeros)
401
+ ```
402
+
403
+ ### Batch Operations
404
+
405
+ ```ts
406
+ // Broadcast action to all players
407
+ manager.broadcast("setVolume", 50);
408
+ manager.broadcast("pause");
409
+
410
+ // Get players by filter
411
+ const activePlayers = manager.getPlayersByFilter((p) => p.isPlaying);
412
+
413
+ // Delete multiple players
414
+ manager.deleteWhere((p) => p.queue.isEmpty && !p.isPlaying);
415
+ ```
416
+
417
+ ---
418
+
419
+ ## ⚙️ Advanced Configuration
420
+
421
+ ### PlayerManager Options
422
+
423
+ ```ts
424
+ const manager = new PlayerManager({
425
+ plugins: [...],
426
+ extensions: [...],
427
+ extractorTimeout: 30000, // Timeout for stream extraction
428
+ autoCleanup: true, // Auto cleanup inactive players
429
+ cleanupInterval: 120000, // Cleanup interval (ms)
430
+ enableSearchCache: true, // Cache search results
431
+ enableStatsCollection: true, // Enable stats events
432
+ persistence: {...} // Persistence configuration
433
+ });
434
+ ```
435
+
436
+ ### Player Options
437
+
438
+ ```ts
439
+ const player = await manager.create(guildId, {
440
+ volume: 100,
441
+ quality: "high",
442
+ leaveOnEnd: true,
443
+ leaveOnEmpty: true,
444
+ leaveTimeout: 100000,
445
+ selfDeaf: true,
446
+ selfMute: false,
447
+ extractorTimeout: 50000,
448
+ filters: ["bassboost", "nightcore"],
449
+ tts: {
450
+ createPlayer: false,
451
+ interrupt: true,
452
+ volume: 100,
453
+ maxTimeTts: 60000,
454
+ },
455
+ userdata: { customField: "value" },
456
+ });
457
+ ```
458
+
459
+ ---
460
+
461
+ ## 📊 Monitoring & Stats
462
+
463
+ ```ts
464
+ // Get manager statistics
465
+ const stats = manager.getStats();
466
+ console.log({
467
+ totalPlayers: stats.totalPlayers,
468
+ activePlayers: stats.activePlayers,
469
+ pausedPlayers: stats.pausedPlayers,
470
+ connectedPlayers: stats.connectedPlayers,
471
+ totalTracksInQueue: stats.totalTracksInQueue,
472
+ });
473
+
474
+ // Get plugin/extension stats
475
+ console.log(manager.getConfig());
476
+ console.log(player.pluginManager.getStats());
477
+ console.log(player.extensionManager.getStats());
478
+
479
+ // Clear caches
480
+ player.clearSearchCache();
481
+ player.extensionManager.clearCache("search");
236
482
  ```
237
483
 
238
484
  ---
@@ -243,6 +489,21 @@ stream.pipe(fs.createWriteStream("song.mp3"));
243
489
  - Always `await player.connect()` before playing
244
490
  - Handle `playerError` events
245
491
  - Do not reuse a destroyed player
492
+ - Enable **persistence** for production bots to survive restarts
493
+ - Use **autoCleanup** to prevent memory leaks
494
+ - Set appropriate **extractorTimeout** based on your network (default: 10-50 seconds)
495
+
496
+ ---
497
+
498
+ ## 🌟 Migration Guide
499
+
500
+ ### From v1.x to v2.x
501
+
502
+ - `player.getTime()` now returns `{ current, total, format, formatted }`
503
+ - `player.getProgressBar()` supports new options
504
+ - `player.queue.remove(index)` removed track is now returned
505
+ - New `queue.removeMultiple()`, `queue.move()`, `queue.swap()` methods
506
+ - Extension hooks now support async properly
246
507
 
247
508
  ---
248
509
 
@@ -257,3 +518,7 @@ stream.pipe(fs.createWriteStream("song.mp3"));
257
518
  ## 📄 License
258
519
 
259
520
  MIT License
521
+
522
+ ```
523
+
524
+ ```
@@ -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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"}