@stella_project/stellalib 1.0.21 → 1.1.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.
package/README.md CHANGED
@@ -28,6 +28,11 @@
28
28
  - [Filters](#filters)
29
29
  - [Multi-Version Support (v3 + v4)](#multi-version-support-v3--v4)
30
30
  - [Session Persistence](#session-persistence)
31
+ - [Player State Persistence](#player-state-persistence)
32
+ - [Auto-Failover](#auto-failover)
33
+ - [Inactivity Timeout](#inactivity-timeout)
34
+ - [Queue Limits & Deduplication](#queue-limits--deduplication)
35
+ - [Node Health Monitoring](#node-health-monitoring)
31
36
  - [Smart Autoplay](#smart-autoplay)
32
37
  - [Search with Fallback](#search-with-fallback)
33
38
  - [Audio Filters](#audio-filters)
@@ -47,9 +52,11 @@
47
52
  Unlike other Lavalink clients, StellaLib:
48
53
 
49
54
  - **Auto-detects** whether your Lavalink server is v3 or v4 and adapts automatically
50
- - **Persists sessions** across bot restarts so music keeps playing
55
+ - **Persists sessions and player state** across bot restarts so music keeps playing — autoplay, queue, filters, and history all survive
51
56
  - **Has a smart autoplay engine** that picks the best next track based on listening history
52
- - **Handles failures gracefully** with reconnect backoff, rate limit retries, and search fallback
57
+ - **Auto-failover** when a node dies, players move to healthy nodes automatically
58
+ - **Proactive health monitoring** — detects overloaded nodes and migrates players *before* they crash
59
+ - **Handles failures gracefully** with fast first reconnect, exponential backoff, rate limit retries, and search fallback
53
60
 
54
61
  ## How it Works
55
62
 
@@ -97,7 +104,7 @@ StellaLib is composed of several core classes that work together:
97
104
  | **`StellaRest`** | HTTP client for Lavalink's REST API. Version-aware (v3 vs v4 endpoints), with rate limit retry, request deduplication, and timeout handling. |
98
105
  | **`StellaFilters`** | Manages audio filters and equalizer settings per player. Built-in presets for common effects. |
99
106
  | **`LRUCache`** | Bounded least-recently-used cache with TTL expiry for search results. Reduces redundant API calls. |
100
- | **`FileSessionStore`** | Persists Lavalink session IDs to a JSON file. Enables seamless resume after bot restarts. |
107
+ | **`FileSessionStore`** | Persists Lavalink session IDs **and full player states** to a JSON file. Enables seamless resume after bot restarts — including autoplay, queue, and filters. |
101
108
 
102
109
  ### Project Structure
103
110
 
@@ -410,7 +417,8 @@ const manager = new StellaManager({
410
417
  1. On connect, Node loads saved session ID from the store
411
418
  2. Sends it as `Session-Id` (v4) or `Resume-Key` (v3) header
412
419
  3. Lavalink resumes the session — players keep their state
413
- 4. On disconnect/shutdown, session ID is persisted to the store
420
+ 4. On disconnect/shutdown, session ID **and full player state** is persisted to the store
421
+ 5. On resume, autoplay state, queue, filters, history, and seed pool are all restored
414
422
 
415
423
  **Custom stores** (e.g., Redis, database):
416
424
 
@@ -425,6 +433,178 @@ const manager = new StellaManager({
425
433
  });
426
434
  ```
427
435
 
436
+ ## Player State Persistence
437
+
438
+ StellaLib v1.1.0+ persists **full player state** — not just session IDs — across bot restarts. This means autoplay, queue, filters, repeat modes, and listening history all survive a restart.
439
+
440
+ ```ts
441
+ import { FileSessionStore } from "@stella_project/stellalib";
442
+
443
+ // FileSessionStore automatically handles both session IDs and player states
444
+ const manager = new StellaManager({
445
+ sessionStore: new FileSessionStore("./sessions.json"),
446
+ // Player state store is auto-detected from FileSessionStore
447
+ // Or provide a custom one:
448
+ // playerStateStore: myCustomStore,
449
+ // ...
450
+ });
451
+ ```
452
+
453
+ **What is persisted per player:**
454
+ - Autoplay on/off state and bot user ID
455
+ - Autoplay history (last 50 tracks) and seed pool
456
+ - Queue (all tracks with encoded data)
457
+ - Filter configuration and active preset flags
458
+ - Repeat modes (track, queue, dynamic)
459
+ - Volume, voice channel, text channel
460
+
461
+ **Custom player state store** (e.g., Redis):
462
+
463
+ ```ts
464
+ const manager = new StellaManager({
465
+ playerStateStore: {
466
+ async getPlayerState(guildId) { return JSON.parse(await redis.get(`player:${guildId}`)); },
467
+ async setPlayerState(guildId, state) { await redis.set(`player:${guildId}`, JSON.stringify(state)); },
468
+ async deletePlayerState(guildId) { await redis.del(`player:${guildId}`); },
469
+ async getAllPlayerStates() { /* return all states */ },
470
+ },
471
+ // ...
472
+ });
473
+ ```
474
+
475
+ ## Auto-Failover
476
+
477
+ When a Lavalink node goes down **mid-playback**, StellaLib **immediately** moves all playing/paused players to a healthy node — audio continues at the exact same position with typically <150ms gap:
478
+
479
+ ```
480
+ Node A crashes! 💥
481
+
482
+ t=0ms WebSocket close fires
483
+ t=2ms attemptSeamlessFailover() starts
484
+ t=5ms Healthy nodes sorted by penalty score
485
+ t=50ms Voice state sent to Node B
486
+ t=100ms Track + position + filters sent
487
+ t=150ms Audio resumes on Node B ♪
488
+ ```
489
+
490
+ ```
491
+ Node A (dies) Node B (healthy) Node C (healthy)
492
+ Player 1 ──────────────► Player 1 ♪
493
+ Player 2 ──────────────► Player 2 ♪ (load balanced)
494
+ Player 3 ────────────────────────────────────► Player 3 ♪
495
+ ```
496
+
497
+ ### Three Layers of Protection
498
+
499
+ | Layer | Trigger | Speed |
500
+ |---|---|---|
501
+ | **Seamless failover** | Node unexpectedly disconnects | Immediate (<150ms) |
502
+ | **Health monitoring** | CPU/frame deficit exceeds threshold | Proactive (before crash) |
503
+ | **Destroy failover** | Node explicitly removed from pool | Immediate |
504
+
505
+ ### PlayerFailover Event
506
+
507
+ ```ts
508
+ manager.on("PlayerFailover", (player, oldNode, newNode) => {
509
+ console.log(`Player ${player.guild} moved: ${oldNode} → ${newNode}`);
510
+ // Optionally notify the guild
511
+ });
512
+ ```
513
+
514
+ - Players are distributed across healthy nodes by **penalty score** (not all dumped on one node)
515
+ - If no healthy nodes exist, players wait for reconnect (fast 2s retry on first attempt)
516
+ - See [docs/13-seamless-failover.md](docs/13-seamless-failover.md) for full architecture details
517
+
518
+ ## Inactivity Timeout
519
+
520
+ Auto-disconnect the bot when it's alone in a voice channel:
521
+
522
+ ```ts
523
+ const player = manager.create({
524
+ guild: guildId,
525
+ voiceChannel: voiceChannelId,
526
+ inactivityTimeout: 300000, // 5 minutes
527
+ });
528
+
529
+ // In your voiceStateUpdate handler:
530
+ client.on("voiceStateUpdate", (oldState, newState) => {
531
+ const player = manager.get(oldState.guild.id);
532
+ if (!player) return;
533
+
534
+ const channel = oldState.guild.channels.cache.get(player.voiceChannel!);
535
+ const members = channel?.members?.filter((m) => !m.user.bot).size ?? 0;
536
+
537
+ if (members === 0) {
538
+ player.startInactivityTimer(); // Start countdown
539
+ } else {
540
+ player.stopInactivityTimer(); // Cancel — someone joined
541
+ }
542
+ });
543
+ ```
544
+
545
+ ## Queue Limits & Deduplication
546
+
547
+ ### Max Queue Size
548
+
549
+ Prevent memory abuse by limiting the queue:
550
+
551
+ ```ts
552
+ const player = manager.create({
553
+ guild: guildId,
554
+ voiceChannel: voiceChannelId,
555
+ maxQueueSize: 500, // Max 500 tracks in queue
556
+ });
557
+
558
+ // Check before adding
559
+ if (!player.canAddToQueue(tracks.length)) {
560
+ return message.reply(`Queue is full! Only ${player.queueSpaceRemaining} slots left.`);
561
+ }
562
+ player.queue.add(tracks); // Excess tracks are automatically truncated
563
+ ```
564
+
565
+ ### Track Deduplication
566
+
567
+ Prevent the same song from being queued twice:
568
+
569
+ ```ts
570
+ player.queue.noDuplicates = true;
571
+
572
+ // Now queue.add() silently skips tracks that are already queued
573
+ player.queue.add(track); // Added
574
+ player.queue.add(track); // Silently skipped (same URI)
575
+
576
+ // Check manually:
577
+ if (player.queue.isDuplicate(track)) {
578
+ return message.reply("That track is already in the queue!");
579
+ }
580
+ ```
581
+
582
+ ## Node Health Monitoring
583
+
584
+ StellaLib can proactively monitor node health and migrate players **before** a node crashes:
585
+
586
+ ```ts
587
+ const manager = new StellaManager({
588
+ nodeHealthThresholds: {
589
+ maxCpuLoad: 0.85, // Migrate when CPU exceeds 85%
590
+ maxFrameDeficit: 300, // Migrate when frame deficit exceeds 300
591
+ checkInterval: 30000, // Check every 30 seconds
592
+ },
593
+ // ...
594
+ });
595
+ ```
596
+
597
+ ```
598
+ Health Check (every 30s)
599
+
600
+ Node A: CPU 92% ──► OVERLOADED
601
+ Node B: CPU 40% ──► healthy
602
+
603
+ Migrate players A → B (preemptive)
604
+ ```
605
+
606
+ This is **proactive** failover — it moves players before they experience audio issues, unlike the reactive auto-failover which only triggers when a node dies.
607
+
428
608
  ## Smart Autoplay
429
609
 
430
610
  When the queue ends and autoplay is enabled, StellaLib's auto-mix engine picks the best next track.
@@ -497,7 +677,8 @@ const result = await manager.search("natori セレナーデ", userId);
497
677
  | `PlayerMove` | `(player, oldChannel, newChannel)` | Bot moved to different voice channel |
498
678
  | `PlayerDisconnect` | `(player, oldChannel)` | Bot disconnected from voice |
499
679
  | `PlayerStateUpdate` | `(oldPlayer, newPlayer)` | Player state changed |
500
- | `SocketClosed` | `(player, payload)` | Lavalink WebSocket closed for player |
680
+ | `PlayerFailover` | `(player, oldNode, newNode)` | Player seamlessly moved to a new node |
681
+ | `SocketClosed` | `(player, payload)` | Discord voice WebSocket closed for player |
501
682
  | `Debug` | `(message)` | Debug log message |
502
683
 
503
684
  ## Configuration Reference
@@ -515,6 +696,12 @@ interface ManagerOptions {
515
696
  defaultSearchPlatform?: SearchPlatform;// Default search source
516
697
  searchFallback?: string[]; // Fallback platforms
517
698
  sessionStore?: SessionStore; // Session persistence store
699
+ playerStateStore?: PlayerStateStore; // Full player state persistence (auto-detected from sessionStore)
700
+ nodeHealthThresholds?: { // Proactive node health monitoring
701
+ maxCpuLoad?: number; // Max CPU load (0-1), default: 0.9
702
+ maxFrameDeficit?: number; // Max frame deficit, default: 500
703
+ checkInterval?: number; // Check interval (ms), default: 60000
704
+ };
518
705
  caches?: {
519
706
  enabled: boolean;
520
707
  time: number; // TTL in ms
@@ -542,6 +729,22 @@ interface NodeOptions {
542
729
  }
543
730
  ```
544
731
 
732
+ ### Player Options
733
+
734
+ ```ts
735
+ interface PlayerOptions {
736
+ guild: string; // Guild ID (required)
737
+ voiceChannel?: string; // Voice channel ID
738
+ textChannel?: string; // Text channel ID
739
+ node?: string; // Preferred node identifier
740
+ volume?: number; // Initial volume (default: 11)
741
+ selfMute?: boolean; // Self mute in voice
742
+ selfDeafen?: boolean; // Self deafen in voice
743
+ inactivityTimeout?: number; // Auto-disconnect when alone (ms, 0=disabled)
744
+ maxQueueSize?: number; // Max queue tracks (0=unlimited)
745
+ }
746
+ ```
747
+
545
748
  ## Requirements
546
749
 
547
750
  - **Node.js** >= 18.0.0
@@ -563,11 +766,25 @@ For detailed guides and API reference, see the [docs/](docs/) folder:
563
766
  - [Session Persistence](docs/09-session-persistence.md)
564
767
  - [Multi-Version Support](docs/10-multi-version.md)
565
768
  - [Autoplay Engine](docs/11-autoplay.md)
769
+ - [Player State Persistence](docs/12-player-state-persistence.md)
566
770
 
567
771
  ## Changelog
568
772
 
569
773
  See [CHANGELOG.md](CHANGELOG.md) for a detailed list of changes per version.
570
774
 
775
+ ## Credits
776
+
777
+ StellaLib stands on the shoulders of these amazing projects:
778
+
779
+ | Project | Description | Link |
780
+ |---|---|---|
781
+ | **Lavalink** | The audio server that powers everything | [GitHub](https://github.com/lavalink-devs/Lavalink) · [Website](https://lavalink.dev/) |
782
+ | **LithiumX** | Direct upstream — StellaLib is derived from LithiumX by Anantix Network (MIT) | [GitHub](https://github.com/anantix-network/LithiumX) |
783
+ | **Erela.js** | Pioneered the Lavalink client pattern in the JS ecosystem — many design patterns originated here | [GitHub](https://github.com/MenuDocs/erela.js) |
784
+ | **MagmaStream** | Inspiration for advanced features like improved node management and audio quality | [GitHub](https://github.com/Magmastream-NPM/magmastream) |
785
+
786
+ Thank you to all the maintainers and contributors of these projects for making music bots possible.
787
+
571
788
  ## License
572
789
 
573
790
  **StellaLib** is licensed under the [Open Software License v3.0 (OSL-3.0)](LICENSE).
@@ -73,6 +73,34 @@ SOFTWARE.
73
73
 
74
74
  ---
75
75
 
76
+ ## Erela.js
77
+
78
+ - **Project:** Erela.js
79
+ - **Repository:** https://github.com/MenuDocs/erela.js
80
+ - **License:** Apache-2.0
81
+ - **Note:** Erela.js pioneered the Lavalink client pattern in the JavaScript ecosystem. Many design patterns used in LithiumX (and by extension StellaLib) — such as the Manager/Node/Player/Queue class hierarchy, the plugin system, and the event-driven architecture — originated from Erela.js. StellaLib does not contain direct code from Erela.js, but acknowledges its foundational influence on the Lavalink client ecosystem.
82
+
83
+ ---
84
+
85
+ ## MagmaStream
86
+
87
+ - **Project:** MagmaStream
88
+ - **Repository:** https://github.com/Magmastream-NPM/magmastream
89
+ - **License:** ISC
90
+ - **Note:** MagmaStream provided inspiration for advanced features in StellaLib, including improved node management strategies, penalty-based load balancing, and audio quality optimizations. StellaLib does not contain direct code from MagmaStream, but acknowledges its contributions to the Lavalink client ecosystem.
91
+
92
+ ---
93
+
94
+ ## Lavalink
95
+
96
+ - **Project:** Lavalink
97
+ - **Repository:** https://github.com/lavalink-devs/Lavalink
98
+ - **Website:** https://lavalink.dev/
99
+ - **License:** MIT License
100
+ - **Note:** Lavalink is the audio server that StellaLib connects to. StellaLib implements the Lavalink client protocol (both v3 and v4) as documented in the Lavalink specification.
101
+
102
+ ---
103
+
76
104
  ## tiny-typed-emitter
77
105
 
78
106
  - **Repository:** https://github.com/binier/tiny-typed-emitter
@@ -91,6 +91,24 @@ declare class Filters {
91
91
  clearFilters(): Promise<this>;
92
92
  /** Returns the status of the specified filter. */
93
93
  getFilterStatus(filter: keyof AvailableFilters): boolean;
94
+ /** Returns a copy of all filter statuses (for persistence). */
95
+ getActiveFilters(): Record<string, boolean>;
96
+ /**
97
+ * Restores filter state from persisted data (used after bot restart).
98
+ * Re-applies all active filters without sending to Lavalink yet.
99
+ */
100
+ restoreState(state: {
101
+ distortion: object | null;
102
+ equalizer: object[];
103
+ karaoke: object | null;
104
+ rotation: object | null;
105
+ timescale: object | null;
106
+ vibrato: object | null;
107
+ volume: number;
108
+ activeFilters: Record<string, boolean>;
109
+ }): void;
110
+ /** Sends current filter state to Lavalink. Call after restoreState() to apply. */
111
+ applyFilters(): Promise<this>;
94
112
  }
95
113
  /** Options for adjusting the timescale of audio. */
96
114
  interface TimescaleOptions {
@@ -1 +1 @@
1
- {"version":3,"file":"Filters.d.ts","sourceRoot":"","sources":["../../src/Structures/Filters.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EACN,IAAI,EAMJ,MAAM,4BAA4B,CAAC;AACpC,cAAM,OAAO;IACL,UAAU,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACrC,SAAS,EAAE,IAAI,EAAE,CAAC;IAClB,OAAO,EAAE,cAAc,GAAG,IAAI,CAAC;IAC/B,MAAM,EAAE,GAAG,CAAC;IACZ,QAAQ,EAAE,eAAe,GAAG,IAAI,CAAC;IACjC,SAAS,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACnC,OAAO,EAAE,cAAc,GAAG,IAAI,CAAC;IAC/B,MAAM,EAAE,MAAM,CAAC;IAEtB,OAAO,CAAC,YAAY,CAA0B;gBAElC,MAAM,EAAE,GAAG;YAwBT,aAAa;IAqB3B,OAAO,CAAC,WAAW;IAWnB,OAAO,CAAC,eAAe;IAKvB;;;OAGG;IACI,YAAY,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,GAAG,IAAI;IAIzC,2CAA2C;IACpC,OAAO,IAAI,IAAI;IAatB,2DAA2D;IACpD,UAAU,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,IAAI;IAOlE,6DAA6D;IACtD,YAAY,CAAC,SAAS,CAAC,EAAE,gBAAgB,GAAG,IAAI,GAAG,IAAI;IAI9D,2DAA2D;IACpD,UAAU,CAAC,OAAO,CAAC,EAAE,cAAc,GAAG,IAAI,GAAG,IAAI;IAIxD,4DAA4D;IACrD,WAAW,CAAC,QAAQ,CAAC,EAAE,eAAe,GAAG,IAAI,GAAG,IAAI;IAI3D,8DAA8D;IACvD,aAAa,CAAC,UAAU,CAAC,EAAE,iBAAiB,GAAG,IAAI,GAAG,IAAI;IAIjE;;;OAGG;IACI,SAAS,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI;IAQvC;;;OAGG;IACI,YAAY,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI;IAY1C;;;OAGG;IACI,SAAS,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI;IAYvC;;;OAGG;IACI,OAAO,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI;IAQrC;;;OAGG;IACI,aAAa,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI;IAQ3C;;;OAGG;IACI,KAAK,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI;IAQnC;;;OAGG;IACI,YAAY,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI;IAY1C;;;OAGG;IACI,YAAY,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI;IAQ1C;;;OAGG;IACI,UAAU,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI;IAiBxC;;;;OAIG;IACU,SAAS,CAAC,MAAM,EAAE,MAAM,gBAAgB,GAAG,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAoB/F,8DAA8D;IACjD,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IA0B1C,kDAAkD;IAC3C,eAAe,CAAC,MAAM,EAAE,MAAM,gBAAgB,GAAG,OAAO;CAG/D;AAED,oDAAoD;AACpD,UAAU,gBAAgB;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;CACd;AAED,oDAAoD;AACpD,UAAU,cAAc;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;CACd;AAED,qDAAqD;AACrD,UAAU,eAAe;IACxB,UAAU,EAAE,MAAM,CAAC;CACnB;AAED,oDAAoD;AACpD,UAAU,cAAc;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,UAAU,iBAAiB;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED,UAAU,gBAAgB;IACzB,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC;IAChB,IAAI,EAAE,OAAO,CAAC;IACd,UAAU,EAAE,OAAO,CAAC;IACpB,EAAE,EAAE,OAAO,CAAC;IACZ,SAAS,EAAE,OAAO,CAAC;CACnB;AAED,OAAO,EACN,OAAO,EACP,gBAAgB,EAChB,cAAc,EACd,eAAe,EACf,cAAc,EACd,iBAAiB,EACjB,gBAAgB,GAChB,CAAC"}
1
+ {"version":3,"file":"Filters.d.ts","sourceRoot":"","sources":["../../src/Structures/Filters.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EACN,IAAI,EAMJ,MAAM,4BAA4B,CAAC;AACpC,cAAM,OAAO;IACL,UAAU,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACrC,SAAS,EAAE,IAAI,EAAE,CAAC;IAClB,OAAO,EAAE,cAAc,GAAG,IAAI,CAAC;IAC/B,MAAM,EAAE,GAAG,CAAC;IACZ,QAAQ,EAAE,eAAe,GAAG,IAAI,CAAC;IACjC,SAAS,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACnC,OAAO,EAAE,cAAc,GAAG,IAAI,CAAC;IAC/B,MAAM,EAAE,MAAM,CAAC;IAEtB,OAAO,CAAC,YAAY,CAA0B;gBAElC,MAAM,EAAE,GAAG;YAwBT,aAAa;IAqB3B,OAAO,CAAC,WAAW;IAWnB,OAAO,CAAC,eAAe;IAKvB;;;OAGG;IACI,YAAY,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,GAAG,IAAI;IAIzC,2CAA2C;IACpC,OAAO,IAAI,IAAI;IAatB,2DAA2D;IACpD,UAAU,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,IAAI;IAOlE,6DAA6D;IACtD,YAAY,CAAC,SAAS,CAAC,EAAE,gBAAgB,GAAG,IAAI,GAAG,IAAI;IAI9D,2DAA2D;IACpD,UAAU,CAAC,OAAO,CAAC,EAAE,cAAc,GAAG,IAAI,GAAG,IAAI;IAIxD,4DAA4D;IACrD,WAAW,CAAC,QAAQ,CAAC,EAAE,eAAe,GAAG,IAAI,GAAG,IAAI;IAI3D,8DAA8D;IACvD,aAAa,CAAC,UAAU,CAAC,EAAE,iBAAiB,GAAG,IAAI,GAAG,IAAI;IAIjE;;;OAGG;IACI,SAAS,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI;IAQvC;;;OAGG;IACI,YAAY,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI;IAY1C;;;OAGG;IACI,SAAS,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI;IAYvC;;;OAGG;IACI,OAAO,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI;IAQrC;;;OAGG;IACI,aAAa,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI;IAQ3C;;;OAGG;IACI,KAAK,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI;IAQnC;;;OAGG;IACI,YAAY,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI;IAY1C;;;OAGG;IACI,YAAY,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI;IAQ1C;;;OAGG;IACI,UAAU,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI;IAiBxC;;;;OAIG;IACU,SAAS,CAAC,MAAM,EAAE,MAAM,gBAAgB,GAAG,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAoB/F,8DAA8D;IACjD,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IA0B1C,kDAAkD;IAC3C,eAAe,CAAC,MAAM,EAAE,MAAM,gBAAgB,GAAG,OAAO;IAI/D,+DAA+D;IACxD,gBAAgB,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAIlD;;;OAGG;IACI,YAAY,CAAC,KAAK,EAAE;QAC1B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;QAC1B,SAAS,EAAE,MAAM,EAAE,CAAC;QACpB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;QACvB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;QACxB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;QACzB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;QACvB,MAAM,EAAE,MAAM,CAAC;QACf,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KACvC,GAAG,IAAI;IAaR,kFAAkF;IACrE,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;CAG1C;AAED,oDAAoD;AACpD,UAAU,gBAAgB;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;CACd;AAED,oDAAoD;AACpD,UAAU,cAAc;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;CACd;AAED,qDAAqD;AACrD,UAAU,eAAe;IACxB,UAAU,EAAE,MAAM,CAAC;CACnB;AAED,oDAAoD;AACpD,UAAU,cAAc;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,UAAU,iBAAiB;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED,UAAU,gBAAgB;IACzB,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC;IAChB,IAAI,EAAE,OAAO,CAAC;IACd,UAAU,EAAE,OAAO,CAAC;IACpB,EAAE,EAAE,OAAO,CAAC;IACZ,SAAS,EAAE,OAAO,CAAC;CACnB;AAED,OAAO,EACN,OAAO,EACP,gBAAgB,EAChB,cAAc,EACd,eAAe,EACf,cAAc,EACd,iBAAiB,EACjB,gBAAgB,GAChB,CAAC"}
@@ -310,6 +310,30 @@ class Filters {
310
310
  getFilterStatus(filter) {
311
311
  return this.filterStatus[filter];
312
312
  }
313
+ /** Returns a copy of all filter statuses (for persistence). */
314
+ getActiveFilters() {
315
+ return { ...this.filterStatus };
316
+ }
317
+ /**
318
+ * Restores filter state from persisted data (used after bot restart).
319
+ * Re-applies all active filters without sending to Lavalink yet.
320
+ */
321
+ restoreState(state) {
322
+ this.distortion = state.distortion;
323
+ this.equalizer = (state.equalizer ?? []);
324
+ this.karaoke = state.karaoke;
325
+ this.rotation = state.rotation;
326
+ this.timescale = state.timescale;
327
+ this.vibrato = state.vibrato;
328
+ this.volume = state.volume ?? 1.0;
329
+ if (state.activeFilters) {
330
+ this.filterStatus = { ...this.filterStatus, ...state.activeFilters };
331
+ }
332
+ }
333
+ /** Sends current filter state to Lavalink. Call after restoreState() to apply. */
334
+ async applyFilters() {
335
+ return this.updateFilters();
336
+ }
313
337
  }
314
338
  exports.Filters = Filters;
315
339
  //# sourceMappingURL=Filters.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Filters.js","sourceRoot":"","sources":["../../src/Structures/Filters.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Filters.js","sourceRoot":"","sources":["../../src/Structures/Filters.ts"],"names":[],"mappings":";;;AAAA;;;;;GAKG;AACH,kEAOoC;AACpC,MAAM,OAAO;IACL,UAAU,CAA2B;IACrC,SAAS,CAAS;IAClB,OAAO,CAAwB;IAC/B,MAAM,CAAM;IACZ,QAAQ,CAAyB;IACjC,SAAS,CAA0B;IACnC,OAAO,CAAwB;IAC/B,MAAM,CAAS;IAEd,YAAY,CAA0B;IAE9C,YAAY,MAAW;QACtB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACvB,IAAI,CAAC,SAAS,GAAG,EAAE,CAAC;QACpB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACpB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACtB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACpB,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC;QAElB,IAAI,CAAC,YAAY,GAAG;YACnB,SAAS,EAAE,KAAK;YAChB,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,KAAK;YACb,OAAO,EAAE,KAAK;YACd,SAAS,EAAE,KAAK;YAChB,MAAM,EAAE,KAAK;YACb,IAAI,EAAE,KAAK;YACX,UAAU,EAAE,KAAK;YACjB,EAAE,EAAE,KAAK;YACT,SAAS,EAAE,KAAK;SAChB,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,aAAa;QAC1B,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;QAEtF,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC;YACxC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK;YAC1B,IAAI,EAAE;gBACL,OAAO,EAAE;oBACR,UAAU;oBACV,SAAS;oBACT,OAAO;oBACP,QAAQ;oBACR,SAAS;oBACT,OAAO;oBACP,MAAM;iBACN;aACD;SACD,CAAC,CAAC;QAEH,OAAO,IAAI,CAAC;IACb,CAAC;IAEO,WAAW,CAClB,MAA0C,EAC1C,YAAY,GAAG,IAAI;QAEnB,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,MAAM,CAAC,KAAgB,CAAC;QAChD,IAAI,YAAY,EAAE,CAAC;YAClB,IAAI,CAAC,aAAa,EAAE,CAAC;QACtB,CAAC;QACD,OAAO,IAAI,CAAC;IACb,CAAC;IAEO,eAAe,CAAC,MAA8B,EAAE,MAAe;QACtE,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;QACnC,OAAO,IAAI,CAAC;IACb,CAAC;IAED;;;OAGG;IACI,YAAY,CAAC,KAAc;QACjC,OAAO,IAAI,CAAC,WAAW,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK,IAAI,EAAE,EAAE,CAAC,CAAC;IACxE,CAAC;IAED,2CAA2C;IACpC,OAAO;QACb,OAAO,IAAI,CAAC,aAAa,CAAC;YACzB,SAAS,EAAE,CAAC;YACZ,QAAQ,EAAE,GAAG;YACb,SAAS,EAAE,CAAC;YACZ,QAAQ,EAAE,GAAG;YACb,SAAS,EAAE,CAAC;YACZ,QAAQ,EAAE,GAAG;YACb,MAAM,EAAE,CAAC;YACT,KAAK,EAAE,GAAG;SACV,CAAC,CAAC,eAAe,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IACrC,CAAC;IAED,2DAA2D;IACpD,UAAU,CAAC,MAAe,EAAE,OAAwB;QAC1D,OAAO,IAAI,CAAC,WAAW,CAAC;YACvB,QAAQ,EAAE,SAAS;YACnB,KAAK,EAAE,OAAO,IAAI,IAAI;SACtB,CAAC,CAAC,eAAe,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IACvC,CAAC;IAED,6DAA6D;IACtD,YAAY,CAAC,SAAmC;QACtD,OAAO,IAAI,CAAC,WAAW,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE,KAAK,EAAE,SAAS,IAAI,IAAI,EAAE,CAAC,CAAC;IAC9E,CAAC;IAED,2DAA2D;IACpD,UAAU,CAAC,OAA+B;QAChD,OAAO,IAAI,CAAC,WAAW,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,IAAI,IAAI,EAAE,CAAC,CAAC;IAC1E,CAAC;IAED,4DAA4D;IACrD,WAAW,CAAC,QAAiC;QACnD,OAAO,IAAI,CAAC,WAAW,CAAC,EAAE,QAAQ,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,IAAI,IAAI,EAAE,CAAC,CAAC;IAC5E,CAAC;IAED,8DAA8D;IACvD,aAAa,CAAC,UAAqC;QACzD,OAAO,IAAI,CAAC,WAAW,CAAC,EAAE,QAAQ,EAAE,YAAY,EAAE,KAAK,EAAE,UAAU,IAAI,IAAI,EAAE,CAAC,CAAC;IAChF,CAAC;IAED;;;OAGG;IACI,SAAS,CAAC,MAAe;QAC/B,IAAI,MAAM,EAAE,CAAC;YACZ,OAAO,IAAI,CAAC,WAAW,CAAC,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC,eAAe,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAChF,CAAC;aAAM,CAAC;YACP,OAAO,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,eAAe,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QACjE,CAAC;IACF,CAAC;IAED;;;OAGG;IACI,YAAY,CAAC,MAAe;QAClC,IAAI,MAAM,EAAE,CAAC;YACZ,OAAO,IAAI,CAAC,YAAY,CAAC;gBACxB,KAAK,EAAE,GAAG;gBACV,KAAK,EAAE,KAAK;gBACZ,IAAI,EAAE,IAAI;aACV,CAAC,CAAC,eAAe,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QACzC,CAAC;aAAM,CAAC;YACP,OAAO,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,eAAe,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QACrE,CAAC;IACF,CAAC;IAED;;;OAGG;IACI,SAAS,CAAC,MAAe;QAC/B,IAAI,MAAM,EAAE,CAAC;YACZ,OAAO,IAAI,CAAC,YAAY,CAAC;gBACxB,KAAK,EAAE,GAAG;gBACV,KAAK,EAAE,GAAG;gBACV,IAAI,EAAE,GAAG;aACT,CAAC,CAAC,eAAe,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QACtC,CAAC;aAAM,CAAC;YACP,OAAO,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,eAAe,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAClE,CAAC;IACF,CAAC;IAED;;;OAGG;IACI,OAAO,CAAC,MAAe;QAC7B,IAAI,MAAM,EAAE,CAAC;YACZ,OAAO,IAAI,CAAC,YAAY,CAAC,iCAAa,CAAC,CAAC,eAAe,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACzE,CAAC;aAAM,CAAC;YACP,OAAO,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,eAAe,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC9D,CAAC;IACF,CAAC;IAED;;;OAGG;IACI,aAAa,CAAC,MAAe;QACnC,IAAI,MAAM,EAAE,CAAC;YACZ,OAAO,IAAI,CAAC,YAAY,CAAC,uCAAmB,CAAC,CAAC,eAAe,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;QACrF,CAAC;aAAM,CAAC;YACP,OAAO,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,eAAe,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;QACpE,CAAC;IACF,CAAC;IAED;;;OAGG;IACI,KAAK,CAAC,MAAe;QAC3B,IAAI,MAAM,EAAE,CAAC;YACZ,OAAO,IAAI,CAAC,YAAY,CAAC,+BAAW,CAAC,CAAC,eAAe,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACrE,CAAC;aAAM,CAAC;YACP,OAAO,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,eAAe,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAC5D,CAAC;IACF,CAAC;IAED;;;OAGG;IACI,YAAY,CAAC,MAAe;QAClC,IAAI,MAAM,EAAE,CAAC;YACZ,OAAO,IAAI,CAAC,YAAY,CAAC,sCAAkB,CAAC;iBAC1C,YAAY,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;iBAC7B,eAAe,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QACxC,CAAC;aAAM,CAAC;YACP,OAAO,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC;iBAC1B,YAAY,CAAC,IAAI,CAAC;iBAClB,eAAe,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QACxC,CAAC;IACF,CAAC;IAED;;;OAGG;IACI,YAAY,CAAC,MAAe;QAClC,IAAI,MAAM,EAAE,CAAC;YACZ,OAAO,IAAI,CAAC,YAAY,CAAC,sCAAkB,CAAC,CAAC,eAAe,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QACnF,CAAC;aAAM,CAAC;YACP,OAAO,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,eAAe,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QACnE,CAAC;IACF,CAAC;IAED;;;OAGG;IACI,UAAU,CAAC,MAAe;QAChC,IAAI,MAAM,EAAE,CAAC;YACZ,OAAO,IAAI,CAAC,aAAa,CAAC;gBACzB,SAAS,EAAE,CAAC;gBACZ,QAAQ,EAAE,GAAG;gBACb,SAAS,EAAE,CAAC;gBACZ,QAAQ,EAAE,GAAG;gBACb,SAAS,EAAE,CAAC;gBACZ,QAAQ,EAAE,GAAG;gBACb,MAAM,EAAE,CAAC;gBACT,KAAK,EAAE,GAAG;aACV,CAAC,CAAC,eAAe,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QACvC,CAAC;aAAM,CAAC;YACP,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,eAAe,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QACpE,CAAC;IACF,CAAC;IAED;;;;OAIG;IACI,KAAK,CAAC,SAAS,CAAC,MAAuC,EAAE,MAAe;QAC9E,IAAI,OAAO,MAAM,KAAK,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;QAE7E,QAAQ,MAAM,EAAE,CAAC;YAChB,KAAK,WAAW;gBAAE,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;gBAAC,MAAM;YACnD,KAAK,SAAS;gBAAE,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;gBAAC,MAAM;YAC/C,KAAK,QAAQ;gBAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;gBAAC,MAAM;YAC7C,KAAK,WAAW;gBAAE,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;gBAAC,MAAM;YACnD,KAAK,QAAQ;gBAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;gBAAC,MAAM;YAC7C,KAAK,MAAM;gBAAE,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;gBAAC,MAAM;YACzC,KAAK,YAAY;gBAAE,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;gBAAC,MAAM;YACrD,KAAK,IAAI;gBAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;gBAAC,MAAM;YACrC,KAAK,WAAW;gBAAE,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;gBAAC,MAAM;YACnD,OAAO,CAAC,CAAC,MAAM,IAAI,KAAK,CAAC,oBAAoB,MAAM,GAAG,CAAC,CAAC;QACzD,CAAC;QAED,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;QAC3B,OAAO,IAAI,CAAC;IACb,CAAC;IAED,8DAA8D;IACvD,KAAK,CAAC,YAAY;QACxB,IAAI,CAAC,YAAY,GAAG;YACnB,SAAS,EAAE,KAAK;YAChB,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,KAAK;YACb,OAAO,EAAE,KAAK;YACd,SAAS,EAAE,KAAK;YAChB,MAAM,EAAE,KAAK;YACb,IAAI,EAAE,KAAK;YACX,UAAU,EAAE,KAAK;YACjB,EAAE,EAAE,KAAK;YACT,SAAS,EAAE,KAAK;SAChB,CAAC;QAEF,IAAI,CAAC,MAAM,CAAC,OAAO,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC/C,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;QACtB,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;QACzB,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QACvB,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QACvB,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;QACxB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QAEtB,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;QAC3B,OAAO,IAAI,CAAC;IACb,CAAC;IAED,kDAAkD;IAC3C,eAAe,CAAC,MAA8B;QACpD,OAAO,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;IAClC,CAAC;IAED,+DAA+D;IACxD,gBAAgB;QACtB,OAAO,EAAE,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;IACjC,CAAC;IAED;;;OAGG;IACI,YAAY,CAAC,KASnB;QACA,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,UAAsC,CAAC;QAC/D,IAAI,CAAC,SAAS,GAAG,CAAC,KAAK,CAAC,SAAS,IAAI,EAAE,CAAW,CAAC;QACnD,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC,OAAgC,CAAC;QACtD,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC,QAAkC,CAAC;QACzD,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,SAAoC,CAAC;QAC5D,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC,OAAgC,CAAC;QACtD,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,IAAI,GAAG,CAAC;QAClC,IAAI,KAAK,CAAC,aAAa,EAAE,CAAC;YACzB,IAAI,CAAC,YAAY,GAAG,EAAE,GAAG,IAAI,CAAC,YAAY,EAAE,GAAG,KAAK,CAAC,aAAa,EAAE,CAAC;QACtE,CAAC;IACF,CAAC;IAED,kFAAkF;IAC3E,KAAK,CAAC,YAAY;QACxB,OAAO,IAAI,CAAC,aAAa,EAAE,CAAC;IAC7B,CAAC;CACD;AAqDA,0BAAO"}
@@ -4,7 +4,7 @@
4
4
  * Derived from LithiumX — Copyright (c) 2025 Anantix Network (MIT)
5
5
  * See LICENSE and THIRD-PARTY-NOTICES.md for full license details.
6
6
  */
7
- import type { NodeOptions, PlayerOptions, TrackData, VoicePacket, VoiceServer, VoiceStateUpdate, SearchPlatform, SearchQuery, SearchResult, ManagerOptions, ManagerEvents } from "./Types";
7
+ import type { NodeOptions, PlayerOptions, TrackData, VoicePacket, VoiceServer, VoiceStateUpdate, SearchPlatform, SearchQuery, SearchResult, ManagerOptions, ManagerEvents, PlayerStateStore } from "./Types";
8
8
  import type { StellaNode } from "./Node";
9
9
  import type { StellaPlayer } from "./Player";
10
10
  import { LRUCache } from "./LRUCache";
@@ -25,6 +25,10 @@ declare class StellaManager extends TypedEmitter<ManagerEvents> {
25
25
  caches: LRUCache<string, SearchResult>;
26
26
  /** Whether the manager is shutting down. */
27
27
  private shuttingDown;
28
+ /** Reference to cache prune interval for cleanup. */
29
+ private pruneInterval?;
30
+ /** Reference to node health check interval for cleanup. */
31
+ private healthCheckInterval?;
28
32
  /** Returns the nodes sorted by least CPU load. */
29
33
  get leastLoadNode(): Map<string, StellaNode>;
30
34
  /** Returns the nodes sorted by least amount of players. */
@@ -45,6 +49,11 @@ declare class StellaManager extends TypedEmitter<ManagerEvents> {
45
49
  * @param clientId
46
50
  */
47
51
  init(clientId?: string): this;
52
+ /**
53
+ * Checks node health and preemptively migrates players from overloaded nodes.
54
+ * Called periodically when `nodeHealthThresholds` is configured.
55
+ */
56
+ private checkNodeHealth;
48
57
  /**
49
58
  * Searches the enabled sources based off the URL or the `source` property.
50
59
  * @param query
@@ -94,9 +103,15 @@ declare class StellaManager extends TypedEmitter<ManagerEvents> {
94
103
  createNode(options: NodeOptions): StellaNode;
95
104
  /**
96
105
  * Destroys a node if it exists.
106
+ * Node.destroy() handles failover and cleanup, then removes itself from the map.
97
107
  * @param identifier
98
108
  */
99
109
  destroyNode(identifier: string): void;
110
+ /**
111
+ * Returns the player state store (explicit or auto-detected from sessionStore).
112
+ * Used internally by Node to restore player state after session resume.
113
+ */
114
+ getPlayerStateStore(): PlayerStateStore | null;
100
115
  /**
101
116
  * Sends voice data to the Lavalink server.
102
117
  * Handles both VOICE_STATE_UPDATE and VOICE_SERVER_UPDATE from Discord.
@@ -1 +1 @@
1
- {"version":3,"file":"Manager.d.ts","sourceRoot":"","sources":["../../src/Structures/Manager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Manager.d.ts","sourceRoot":"","sources":["../../src/Structures/Manager.ts"],"names":[],"mappings":"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"}
@@ -34,6 +34,10 @@ class StellaManager extends tiny_typed_emitter_1.TypedEmitter {
34
34
  caches;
35
35
  /** Whether the manager is shutting down. */
36
36
  shuttingDown = false;
37
+ /** Reference to cache prune interval for cleanup. */
38
+ pruneInterval;
39
+ /** Reference to node health check interval for cleanup. */
40
+ healthCheckInterval;
37
41
  /** Returns the nodes sorted by least CPU load. */
38
42
  get leastLoadNode() {
39
43
  const sorted = [...this.nodes.entries()]
@@ -145,7 +149,7 @@ class StellaManager extends tiny_typed_emitter_1.TypedEmitter {
145
149
  }
146
150
  // Periodic LRU cache pruning (removes expired entries)
147
151
  if (cacheOpts?.enabled && cacheOpts.time > 0) {
148
- setInterval(() => {
152
+ this.pruneInterval = setInterval(() => {
149
153
  const pruned = this.caches.prune();
150
154
  if (pruned > 0) {
151
155
  this.emit("Debug", `[Cache] Pruned ${pruned} expired entries (${this.caches.size} remaining)`);
@@ -172,9 +176,56 @@ class StellaManager extends tiny_typed_emitter_1.TypedEmitter {
172
176
  });
173
177
  }
174
178
  this.initiated = true;
179
+ // Start node health monitoring if thresholds are configured
180
+ const health = this.options.nodeHealthThresholds;
181
+ if (health) {
182
+ const interval = health.checkInterval ?? 60000;
183
+ this.healthCheckInterval = setInterval(() => this.checkNodeHealth(), interval);
184
+ this.emit("Debug", `[Manager] Node health monitor started (every ${interval}ms)`);
185
+ }
175
186
  this.emit("Debug", "[Manager] Initialized");
176
187
  return this;
177
188
  }
189
+ /**
190
+ * Checks node health and preemptively migrates players from overloaded nodes.
191
+ * Called periodically when `nodeHealthThresholds` is configured.
192
+ */
193
+ checkNodeHealth() {
194
+ const thresholds = this.options.nodeHealthThresholds;
195
+ if (!thresholds)
196
+ return;
197
+ const maxCpu = thresholds.maxCpuLoad ?? 0.9;
198
+ const maxDeficit = thresholds.maxFrameDeficit ?? 500;
199
+ for (const node of this.nodes.values()) {
200
+ if (!node.connected)
201
+ continue;
202
+ const cpuLoad = node.stats.cpu
203
+ ? node.stats.cpu.lavalinkLoad / node.stats.cpu.cores
204
+ : 0;
205
+ const frameDeficit = node.stats.frameStats?.deficit ?? 0;
206
+ const isOverloaded = cpuLoad > maxCpu || frameDeficit > maxDeficit;
207
+ if (!isOverloaded)
208
+ continue;
209
+ // Find a healthier node to migrate players to
210
+ const healthyTarget = [...this.nodes.values()].find((n) => {
211
+ if (n === node || !n.connected)
212
+ return false;
213
+ const nCpu = n.stats.cpu ? n.stats.cpu.lavalinkLoad / n.stats.cpu.cores : 0;
214
+ return nCpu < maxCpu * 0.7; // Only migrate to nodes well under threshold
215
+ });
216
+ if (!healthyTarget)
217
+ continue;
218
+ const playersOnNode = [...this.players.values()].filter((p) => p.node === node);
219
+ if (!playersOnNode.length)
220
+ continue;
221
+ this.emit("Debug", `[HealthCheck] Node ${node.options.identifier} overloaded (CPU: ${(cpuLoad * 100).toFixed(1)}%, deficit: ${frameDeficit}) — migrating ${playersOnNode.length} players to ${healthyTarget.options.identifier}`);
222
+ for (const player of playersOnNode) {
223
+ player.moveNode(healthyTarget.options.identifier).catch((err) => {
224
+ this.emit("Debug", `[HealthCheck] Failed to migrate player ${player.guild}: ${err instanceof Error ? err.message : String(err)}`);
225
+ });
226
+ }
227
+ }
228
+ }
178
229
  /**
179
230
  * Searches the enabled sources based off the URL or the `source` property.
180
231
  * @param query
@@ -185,7 +236,8 @@ class StellaManager extends tiny_typed_emitter_1.TypedEmitter {
185
236
  if (!node)
186
237
  throw new Error("No available nodes.");
187
238
  if (this.options.caches?.enabled && typeof query === "string") {
188
- const cached = this.caches.get(query);
239
+ const cacheKey = query.trim().toLowerCase();
240
+ const cached = this.caches.get(cacheKey);
189
241
  if (cached)
190
242
  return cached;
191
243
  }
@@ -266,7 +318,8 @@ class StellaManager extends tiny_typed_emitter_1.TypedEmitter {
266
318
  }
267
319
  }
268
320
  if (this.options.caches?.enabled) {
269
- this.caches.set(search, result);
321
+ const cacheKey = (typeof query === "string" ? query : rawQuery).trim().toLowerCase();
322
+ this.caches.set(cacheKey, result);
270
323
  }
271
324
  if (platform !== primarySource) {
272
325
  this.emit("Debug", `[Search] Found results via fallback "${platform}" for "${rawQuery}"`);
@@ -361,6 +414,7 @@ class StellaManager extends tiny_typed_emitter_1.TypedEmitter {
361
414
  }
362
415
  /**
363
416
  * Destroys a node if it exists.
417
+ * Node.destroy() handles failover and cleanup, then removes itself from the map.
364
418
  * @param identifier
365
419
  */
366
420
  destroyNode(identifier) {
@@ -368,7 +422,20 @@ class StellaManager extends tiny_typed_emitter_1.TypedEmitter {
368
422
  if (!node)
369
423
  return;
370
424
  node.destroy();
371
- this.nodes.delete(identifier);
425
+ }
426
+ /**
427
+ * Returns the player state store (explicit or auto-detected from sessionStore).
428
+ * Used internally by Node to restore player state after session resume.
429
+ */
430
+ getPlayerStateStore() {
431
+ if (this.options.playerStateStore)
432
+ return this.options.playerStateStore;
433
+ // Auto-detect: FileSessionStore implements PlayerStateStore
434
+ const ss = this.options.sessionStore;
435
+ if (ss && "getPlayerState" in ss && typeof ss.getPlayerState === "function") {
436
+ return ss;
437
+ }
438
+ return null;
372
439
  }
373
440
  /**
374
441
  * Sends voice data to the Lavalink server.
@@ -451,6 +518,20 @@ class StellaManager extends tiny_typed_emitter_1.TypedEmitter {
451
518
  return;
452
519
  this.shuttingDown = true;
453
520
  this.emit("Debug", "[Manager] Graceful shutdown initiated...");
521
+ // Persist all player states before closing (autoplay, queue, filters survive restart)
522
+ const playerStore = this.getPlayerStateStore();
523
+ if (playerStore) {
524
+ for (const [guildId, player] of this.players) {
525
+ try {
526
+ const state = player.getFullState();
527
+ await playerStore.setPlayerState(guildId, state);
528
+ this.emit("Debug", `[Manager] Persisted player state for guild ${guildId} (autoplay: ${state.isAutoplay}, queue: ${state.queue.length})`);
529
+ }
530
+ catch {
531
+ // Best effort
532
+ }
533
+ }
534
+ }
454
535
  // Gracefully close all nodes (persists session IDs for resume)
455
536
  const closePromises = [];
456
537
  for (const node of this.nodes.values()) {
@@ -467,9 +548,17 @@ class StellaManager extends tiny_typed_emitter_1.TypedEmitter {
467
548
  // Ignore
468
549
  }
469
550
  }
470
- // Clear caches
551
+ // Clear caches, prune interval, and health check interval
552
+ if (this.pruneInterval) {
553
+ clearInterval(this.pruneInterval);
554
+ this.pruneInterval = undefined;
555
+ }
556
+ if (this.healthCheckInterval) {
557
+ clearInterval(this.healthCheckInterval);
558
+ this.healthCheckInterval = undefined;
559
+ }
471
560
  this.caches.clear();
472
- this.emit("Debug", `[Manager] Shutdown complete. ${this.nodes.size} nodes closed, sessions persisted.`);
561
+ this.emit("Debug", `[Manager] Shutdown complete. ${this.nodes.size} nodes closed, sessions + player states persisted.`);
473
562
  }
474
563
  /**
475
564
  * Returns memory and performance statistics for monitoring.