Skip to content

Releases: Ecliptia/moonlink.js

v5.2.0

28 Feb 21:39
f87a0cc

Choose a tag to compare

What's Changed

Full Changelog: https://github.com/Ecliptia/moonlink.js/commits/v5.2.0

v5.0.0

10 Jan 18:57
47b6970

Choose a tag to compare

What's Changed

Full Changelog: v4.60.18...v5.0.0

v4.60.24

25 Dec 18:05

Choose a tag to compare

Full Changelog: v4.60.21...v4.60.24

v4.60.21

07 Dec 18:03

Choose a tag to compare

Full Changelog: v4.60.18...v4.60.21

v4.60.18

26 Sep 19:43
b3c974d

Choose a tag to compare

Full Changelog: v4.60.4...v4.60.18

Moonlink.js v4.60.18: Critical Bun.js Fix & Major Stability Upgrades (from v4.60.4)
The centerpiece of this update is a critical fix for an issue that affected users running their bots on
Bun.js. Thanks to detailed bug reports from our community, particularly from efekos
(https://github.com/efekos) and Duckie (aiden4419), we were able to resolve a Malformed_HTTP_Response
error caused by a keep-alive header conflict. To address this, the WebSocket service in
src/services/WebSocket.ts has been fundamentally re-engineered. It is now runtime-aware, featuring a new
connectBun() method that utilizes the native globalThis.WebSocket when Bun is detected. The previous
Node.js-based implementation remains in connectNode(), ensuring continued stability for Node.js users. As
part of this refactor, the non-standard addEventListener method was removed in favor of the standard on()
and once() from Node's EventEmitter for better code consistency.

Player reliability has been drastically improved with the introduction of a new Player Health Check
system. Previously, players could get "stuck" silently due to network or Lavalink issues. The Player class
in src/entities/Player.ts now includes checkHealth() and scheduleHealthCheck() methods. This system
proactively monitors player state and, if it detects an unresponsive player, will automatically attempt to
recover by restarting the track or skipping to the next. This is supported by new events like playerStale
and trackStale that give developers hooks into this recovery process.

Voice connection state management has also been completely rewritten for better robustness. The
Manager.packetUpdate() and _handleVoiceStateUpdate() functions in src/core/Manager.ts now handle complex
scenarios like channel moves, disconnects, and server changes with much greater accuracy. This update also
adds handling for the CHANNEL_DELETE event, ensuring a player is properly destroyed if its voice channel
is removed, which prevents "ghost" players.

Finally, to enhance the developer experience, the PlayerManager in src/management/PlayerManager.ts now
features a new autoJoin() method. This utility function streamlines the process of creating or getting a
player and connecting it to a voice channel, significantly reducing boilerplate code in your commands.

What's Changed

v4.60.4

06 Aug 16:14
cc7621b

Choose a tag to compare

What's Changed

Full Changelog: v4.52.2...v4.60.4

✨ New Features

  • Granular Control for Spotify Playlist/Album Loading: You can now control the number of tracks fetched per
    API request from Spotify, separate from the total number of tracks to be loaded. This is useful for
    managing API usage and initial load times.
  • Global Playlist Track Limit: A new global option, playlistLoadLimit, has been introduced to set a default
    maximum number of tracks to load from any playlist, which can be overridden on a per-call basis.

🐛 Improvements & Bug Fixes

  • Spotify URI Support: The Spotify source now correctly parses both standard URLs (e.g.,
    https://open.spotify.com/...) and Spotify URIs (e.g., spotify:track:...) for all content types.
  • Player State Synchronization:
    • Fixed an issue where a player's track position could be incorrectly reset to 0 during a playerUpdate
      event. The position is now only updated if the new position is greater than 0 or if the track has
      just started.
    • The track position is now correctly initialized from the TrackStartEvent payload, ensuring accurate
      starting points.
  • Node Management: The NodeManager has been refactored to more reliably filter and select available and
    connected nodes, improving stability in multi-node environments.
  • Deezer & Spotify Load Control: The search and load functions for both Deezer and Spotify sources now
    allow for passing a limit option to override the default limits set in the manager configuration.

🛠️ API Changes & Technical Details

  1. Manager Options (IOptionsManager)

The following properties have been added to the manager configuration interface:

  • playlistLoadLimit?: number;
    • Description: Sets a global default for the maximum number of tracks to load from a playlist across
      all sources. Defaults to undefined (no limit).
  • spotify.limitLoadPlaylistPage?: number;
    • Description: Sets the number of tracks to fetch per API request for Spotify playlists.
    • Default: 100.
  • spotify.limitLoadAlbumPage?: number;
    • Description: Sets the number of tracks to fetch per API request for Spotify albums.
    • Default: 50.
  1. Manager Class
  • Manager.search()
    The options object for the search method now accepts a limit property to override the global
    playlistLoadLimit.

    • New Signature:

1 search(options: {
2 query: string;
3 source?: TSearchSources;
4 node?: string;
5 requester?: unknown;
6 fallbackSources?: TSearchSources[];
7 limit?: number; // <-- New parameter
8 }): Promise

  1. NodeManager Class (src/management/NodeManager.ts)

New utility methods have been added to improve node handling:

  • getConnected()

    • Description: Returns an array of all Node instances that are currently connected.
    • Signature: public getConnected(): Node[]
  • hasConnected()

    • Description: Returns a boolean (true/false) indicating if there is at least one connected node.
    • Signature: public hasConnected(): boolean
  • Internal Refactor: The methods getNodeWithCapability() and sortByUsage() now use getConnected()
    internally to ensure they only operate on active nodes, making node selection more reliable.

  1. Spotify Source (src/sources/Spotify.ts)
  • load() Method:

    • The method now accepts an options object to specify a limit.
    • New Signature: public async load(rawUrl: string, options?: { limit?: number }): Promise
    • Logic: Implemented a while loop to handle pagination. It now uses limitLoadPlaylistPage or
      limitLoadAlbumPage for each API request and continues fetching pages until the options.limit or the
      global playlistLoadLimit is reached.
  • search() Method:

    • The method now accepts an options object to specify a limit.
    • New Signature: public async search(query: string, options?: { limit?: number }): Promise
  • getLinkType() Method:

    • The regular expressions have been updated to support Spotify URIs.
    • Example (Track): /(?:open\.spotify\.com\/(?:intl-[^/]+\/)?track\/|spotify:track:)(\w+)/
  1. Deezer Source (src/sources/Deezer.ts)
  • load() Method:

    • The method now accepts an options object to specify a limit.
    • New Signature: public async load(query: string, options?: { limit?: number }): Promise
  • search() Method:

    • The method now accepts an options object to specify a limit.
    • New Signature: public async search(query: string, options?: { limit?: number }): Promise

v4.52.2

16 Jul 18:21
852216b

Choose a tag to compare

📦 What's Changed

This release brings major enhancements to Moonlink.js, focusing on a more flexible database system, robust player state management, expanded lyrics integration, and advanced queue control.


🚀 New Features

  • Flexible Database System
    Introduced a fully customizable database layer with support for MongoDB (MongooseDB), LocalDB (WAL-based file storage), and MemoryDB. Users can now choose their preferred provider and storage path, enabling persistent player and queue data across restarts.
    (Contributed by @Nevercold)

  • Advanced Queue Operations
    Added powerful new async methods to the Queue for greater control:

    • moveRange: move a range of tracks
    • removeRange: remove a range of tracks
    • duplicate: duplicate a track
    • jump: jump to a specific track
      All queue operations now ensure reliable data persistence.
  • Expanded Lyrics Integration
    Reworked lyrics handling with new methods for both static and synchronized (live) lyrics. Improved plugin selection logic ensures the best available provider (LavaLyrics, Lyrics.kt, or JavaLyricsPlugin) is used automatically.

  • Node Health Monitoring
    Implemented periodic health checks in the NodeManager to detect unhealthy nodes and automatically migrate players, ensuring seamless performance and uptime.

  • Text-to-Speech (TTS) Support
    Added a new player.speak() method with support for multiple TTS providers (Flowery TTS, Google Cloud TTS, Skybot), enabling dynamic voice interactions in your bot.

  • Queue Deduplication
    Introduced removeDuplicates() in the Queue to prevent duplicate tracks, solving long-standing issues with repeated entries.
    (Contributed by 1lucas1apk)


🛠 Improvements

  • Persistent Player State
    Player and queue data are now consistently stored using the new database layer, ensuring state is retained across bot restarts.

  • Improved Player Lifecycle Management
    Enhanced player creation and node selection logic, including better handling of node capabilities per source and intelligent fallbacks for uninterrupted playback.

  • Flexible Requester Handling
    Updated Track and Player classes to support requester as either a string or an object, offering more flexibility when identifying who requested a track.
    (Contributed by @comicallybad)

  • Track Enhancements
    Improved Track structure with enhanced requester support and new origin tracking for smarter routing and source resolution.

  • Documentation Updates
    Revamped the introduction and added a detailed troubleshooting guide to help developers resolve common issues more easily.

  • Internal Refinements
    Numerous internal improvements and optimizations for better stability, performance, and maintainability.


🐛 Bug Fixes

  • Paused State Handling
    Fixed an issue where the player.paused state was being incorrectly reset by Lavalink's playerUpdate event. User-initiated pauses are now reliably preserved.

👥 Contributors

  • @Nevercold — for the new flexible database system and provider support.
  • @comicallybad — for improving requester handling in the Track and Player classes.

🔗 [Full Changelog](v4.44.4...v4.52.2)

v4.44.4

14 Jul 02:50
4c1651a

Choose a tag to compare

What's Changed

Full Changelog: v4.28.34...v4.44.4

v4.28.34

11 Jul 01:40
ef102ec

Choose a tag to compare

What's Changed

Full Changelog: v4.28.32...v4.28.34

v4.28.32

11 Jul 00:58
fc6980b

Choose a tag to compare

What's Changed

Full Changelog: v.4.6.18...v4.28.32