lavalink-client 1.0.6 → 1.0.7

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
@@ -1,5 +1,26 @@
1
1
  # Lavalink Client
2
- Easy and advanced lavalink client. Use it with lavalink plugins as well as latest lavalink versions.
2
+ Easy, flexible and feature-rich lavalink@v4 Client. Both for Beginners and Proficients.
3
+
4
+ <div align="center">
5
+ <p>
6
+ <img src="https://madewithlove.now.sh/at?heart=true&template=for-the-badge" alt="Made with love in Austria">
7
+ <img alt="Made with TypeScript" src="https://img.shields.io/badge/typescript-%23007ACC.svg?style=for-the-badge&logo=typescript&logoColor=white">
8
+ </p>
9
+ <p>
10
+ <a href="https://www.npmjs.com/package/lavalink-client">
11
+ <img src="https://img.shields.io/npm/v/lavalink-client.svg?maxAge=3600&style=for-the-badge&logo=npm&logoColor=red" alt="NPM version" />
12
+ </a>
13
+ <a href="https://www.npmjs.com/package/lavalink-client">
14
+ <img src="https://img.shields.io/npm/dt/lavalink-client.svg?maxAge=3600&style=for-the-badge&logo=npm&logoColor=red" alt="NPM downloads" />
15
+ </a>
16
+ <a href="https://lc4.gitbook.io/lavalink-client/">
17
+ <img src="https://img.shields.io/badge/Documation-%230288D1.svg?style=for-the-badge&logo=gitbook&logoColor=white" alt="Get Started Now">
18
+ </a>
19
+ </p>
20
+ <p>
21
+ <a href="https://www.npmjs.com/package/lavalink-client"><img src="https://nodei.co/npm/lavalink-client.png?downloads=true&stars=true" alt="npm install lavalink-client" /></a>
22
+ </p>
23
+ </div>
3
24
 
4
25
  # Install
5
26
 
@@ -7,7 +7,7 @@ export declare class FilterManager {
7
7
  equalizerBands: EQBand[];
8
8
  filterUpdatedState: number;
9
9
  filters: PlayerFilters;
10
- data: LavalinkFilterData;
10
+ data: FilterData;
11
11
  constructor(player: Player);
12
12
  applyPlayerFilters(): Promise<void>;
13
13
  /**
@@ -215,9 +215,8 @@ export interface ReverbFilter {
215
215
  delay: number;
216
216
  decay: number;
217
217
  }
218
- export interface LavalinkFilterData {
218
+ export interface FilterData {
219
219
  volume?: number;
220
- equalizer?: EQBand[];
221
220
  karaoke?: KaraokeFilter;
222
221
  timescale?: TimescaleFilter;
223
222
  tremolo?: FreqFilter;
@@ -229,3 +228,6 @@ export interface LavalinkFilterData {
229
228
  echo: EchoFilter;
230
229
  reverb: ReverbFilter;
231
230
  }
231
+ export interface LavalinkFilterData extends FilterData {
232
+ equalizer?: EQBand[];
233
+ }
@@ -1,10 +1,10 @@
1
1
  /// <reference types="node" />
2
2
  import { EventEmitter } from "events";
3
3
  import { NodeManager } from "./NodeManager";
4
- import { QueueSaverOptions } from "./Queue";
5
- import { GuildShardPayload, LavalinkSearchPlatform, ManagerUitls, MiniMap, SearchPlatform, TrackEndEvent, TrackExceptionEvent, TrackStartEvent, TrackStuckEvent, VoicePacket, VoiceServer, VoiceState, WebSocketClosedEvent } from "./Utils";
4
+ import { ManagerQueueOptions } from "./Queue";
5
+ import { GuildShardPayload, ManagerUitls, MiniMap, SearchPlatform, TrackEndEvent, TrackExceptionEvent, TrackStartEvent, TrackStuckEvent, VoicePacket, VoiceServer, VoiceState, WebSocketClosedEvent } from "./Utils";
6
6
  import { LavalinkNodeOptions } from "./Node";
7
- import { DestroyReasonsType, Player, PlayerOptions } from "./Player";
7
+ import { DestroyReasonsType, Player, PlayerJson, PlayerOptions } from "./Player";
8
8
  import { Track, UnresolvedTrack } from "./Track";
9
9
  export interface LavalinkManager {
10
10
  nodeManager: NodeManager;
@@ -18,7 +18,7 @@ export interface BotClientOptions {
18
18
  /** So users can pass entire objects / classes */
19
19
  [x: string | number | symbol | undefined]: any;
20
20
  }
21
- export interface LavalinkPlayerOptions {
21
+ export interface ManagerPlayerOptions {
22
22
  /** If the Lavalink Volume should be decremented by x number */
23
23
  volumeDecrementer?: number;
24
24
  /** How often it should update the the player Position */
@@ -44,13 +44,18 @@ export interface LavalinkPlayerOptions {
44
44
  useUnresolvedData?: boolean;
45
45
  }
46
46
  export interface ManagerOptions {
47
+ /** The Node Options, for all Nodes! (on init) */
47
48
  nodes: LavalinkNodeOptions[];
48
- queueOptions?: QueueSaverOptions;
49
+ /** @async The Function to send the voice connection changes from Lavalink to Discord */
50
+ sendToShard: (guildId: string, payload: GuildShardPayload) => void;
51
+ /** The Bot Client's Data for Authorization */
49
52
  client?: BotClientOptions;
50
- playerOptions?: LavalinkPlayerOptions;
53
+ /** QueueOptions for all Queues */
54
+ queueOptions?: ManagerQueueOptions;
55
+ /** PlayerOptions for all Players */
56
+ playerOptions?: ManagerPlayerOptions;
57
+ /** If it should skip to the next Track on TrackEnd / TrackError etc. events */
51
58
  autoSkip?: boolean;
52
- /** @async */
53
- sendToShard: (guildId: string, payload: GuildShardPayload) => void;
54
59
  }
55
60
  interface LavalinkManagerEvents {
56
61
  /**
@@ -107,7 +112,7 @@ interface LavalinkManagerEvents {
107
112
  * Always emits when the player (on lavalink side) got updated
108
113
  * @event Manager#playerUpdate
109
114
  */
110
- "playerUpdate": (player: Player) => void;
115
+ "playerUpdate": (oldPlayerJson: PlayerJson, newPlayer: Player) => void;
111
116
  }
112
117
  export interface LavalinkManager {
113
118
  options: ManagerOptions;
@@ -115,7 +120,7 @@ export interface LavalinkManager {
115
120
  emit<U extends keyof LavalinkManagerEvents>(event: U, ...args: Parameters<LavalinkManagerEvents[U]>): boolean;
116
121
  }
117
122
  export declare class LavalinkManager extends EventEmitter {
118
- static DefaultSources: Record<SearchPlatform, LavalinkSearchPlatform>;
123
+ static DefaultSources: Record<SearchPlatform, import("./Utils").LavalinkSearchPlatform>;
119
124
  static SourceLinksRegexes: Record<import("./Utils").SourcesRegex, RegExp>;
120
125
  initiated: boolean;
121
126
  readonly players: MiniMap<string, Player>;
@@ -81,7 +81,7 @@ class LavalinkManager extends events_1.EventEmitter {
81
81
  const keys = Object.getOwnPropertyNames(Object.getPrototypeOf(options.queueOptions?.queueChangesWatcher));
82
82
  const requiredKeys = ["tracksAdd", "tracksRemoved", "shuffled"];
83
83
  if (!requiredKeys.every(v => keys.includes(v)) || !requiredKeys.every(v => typeof options.queueOptions?.queueChangesWatcher[v] === "function"))
84
- throw new SyntaxError(`The provided ManagerOption.QueueChangesWatcher, does not have all required functions: ${requiredKeys.join(", ")}`);
84
+ throw new SyntaxError(`The provided ManagerOption.DefaultQueueChangesWatcher, does not have all required functions: ${requiredKeys.join(", ")}`);
85
85
  }
86
86
  }
87
87
  constructor(options) {
@@ -358,7 +358,7 @@ class LavalinkNode {
358
358
  if (data.playerOptions.filters.volume)
359
359
  player.filterManager.data.volume = data.playerOptions.filters.volume;
360
360
  if (data.playerOptions.filters.equalizer)
361
- player.filterManager.data.equalizer = data.playerOptions.filters.equalizer;
361
+ player.filterManager.equalizerBands = data.playerOptions.filters.equalizer;
362
362
  if (data.playerOptions.filters.karaoke)
363
363
  player.filterManager.data.karaoke = data.playerOptions.filters.karaoke;
364
364
  if (data.playerOptions.filters.lowPass)
@@ -441,6 +441,7 @@ class LavalinkNode {
441
441
  const player = this.NodeManager.LavalinkManager.getPlayer(payload.guildId);
442
442
  if (!player)
443
443
  return;
444
+ const oldPlayer = player?.toJSON();
444
445
  if (player.get("internal_updateInterval"))
445
446
  clearInterval(player.get("internal_updateInterval"));
446
447
  // override the position
@@ -478,7 +479,7 @@ class LavalinkNode {
478
479
  player.filterManager.filterUpdatedState = 0;
479
480
  }
480
481
  }
481
- this.NodeManager.LavalinkManager.emit("playerUpdate", player);
482
+ this.NodeManager.LavalinkManager.emit("playerUpdate", oldPlayer, player);
482
483
  break;
483
484
  case "event":
484
485
  this.handleEvent(payload);
@@ -525,7 +526,6 @@ class LavalinkNode {
525
526
  return this.NodeManager.LavalinkManager.emit("trackStart", player, track, payload);
526
527
  }
527
528
  async trackEnd(player, track, payload) {
528
- console.log(payload.reason);
529
529
  // If there are no songs in the queue
530
530
  if (!player.queue.tracks.length && player.repeatMode === "off")
531
531
  return this.queueEnd(player, track, payload);
@@ -562,8 +562,11 @@ class LavalinkNode {
562
562
  await this.NodeManager.LavalinkManager.options?.playerOptions?.onEmptyQueue?.autoPlayFunction(player, track);
563
563
  if (player.queue.tracks.length > 0)
564
564
  await (0, Utils_1.queueTrackEnd)(player);
565
- if (player.queue.current)
565
+ if (player.queue.current) {
566
+ if (payload.type === "TrackEndEvent")
567
+ this.NodeManager.LavalinkManager.emit("trackEnd", player, track, payload);
566
568
  return player.play({ noReplace: true, paused: false });
569
+ }
567
570
  }
568
571
  player.queue.previous.unshift(track);
569
572
  if (payload?.reason !== "stopped") {
@@ -1,4 +1,4 @@
1
- import { FilterManager, LavalinkFilterData } from "./Filters";
1
+ import { EQBand, FilterData, FilterManager, LavalinkFilterData } from "./Filters";
2
2
  import { LavalinkManager } from "./LavalinkManager";
3
3
  import { LavalinkNode } from "./Node";
4
4
  import { Queue } from "./Queue";
@@ -7,6 +7,27 @@ import { LavalinkPlayerVoiceOptions, SearchPlatform, SearchResult } from "./Util
7
7
  type PlayerDestroyReasons = "QueueEmpty" | "NodeDestroy" | "NodeDeleted" | "LavalinkNoVoice" | "NodeReconnectFail" | "PlayerReconnectFail" | "Disconnected" | "ChannelDeleted";
8
8
  export type DestroyReasonsType = PlayerDestroyReasons | string;
9
9
  export declare const DestroyReasons: Record<PlayerDestroyReasons, PlayerDestroyReasons>;
10
+ export interface PlayerJson {
11
+ guildId: string;
12
+ options: PlayerOptions;
13
+ voiceChannelId: string;
14
+ textChannelId?: string;
15
+ position: number;
16
+ lastPosition: number;
17
+ volume: number;
18
+ lavalinkVolume: number;
19
+ repeatMode: RepeatMode;
20
+ paused: boolean;
21
+ playing: boolean;
22
+ createdTimeStamp?: number;
23
+ filters: FilterData;
24
+ ping: {
25
+ ws: number;
26
+ lavalink: number;
27
+ };
28
+ equalizer: EQBand[];
29
+ nodeId?: string;
30
+ }
10
31
  export type RepeatMode = "queue" | "track" | "off";
11
32
  export interface PlayerOptions {
12
33
  guildId: string;
@@ -170,22 +191,6 @@ export declare class Player {
170
191
  */
171
192
  changeNode(newNode: LavalinkNode | string): Promise<string>;
172
193
  /** Converts the Player including Queue to a Json state */
173
- toJSON(): {
174
- guildId: string;
175
- options: PlayerOptions;
176
- voiceChannelId: string;
177
- textChannelId: string;
178
- position: number;
179
- lastPosition: number;
180
- volume: number;
181
- lavalinkVolume: number;
182
- repeatMode: RepeatMode;
183
- paused: boolean;
184
- playing: boolean;
185
- createdTimeStamp: number;
186
- filters: {};
187
- equalizer: import("./Filters").EQBand[];
188
- nodeId: string;
189
- };
194
+ toJSON(): PlayerJson;
190
195
  }
191
196
  export {};
@@ -405,6 +405,7 @@ class Player {
405
405
  filters: this.filterManager?.data || {},
406
406
  equalizer: this.filterManager?.equalizerBands || [],
407
407
  nodeId: this.node?.id,
408
+ ping: this.ping,
408
409
  };
409
410
  }
410
411
  }
@@ -1,53 +1,58 @@
1
1
  import { Track, UnresolvedTrack } from "./Track";
2
+ import { MiniMap } from "./Utils";
2
3
  export interface StoredQueue {
3
4
  current: Track | null;
4
5
  previous: Track[];
5
6
  tracks: Track[];
6
7
  }
7
- export interface StoreManager extends Record<any, any> {
8
+ export interface QueueStoreManager extends Record<string, any> {
8
9
  /** @async get a Value (MUST RETURN UNPARSED!) */
9
10
  get: (guildId: unknown) => Promise<any>;
10
11
  /** @async Set a value inside a guildId (MUST BE UNPARSED) */
11
12
  set: (guildId: unknown, value: unknown) => Promise<any>;
12
13
  /** @async Delete a Database Value based of it's guildId */
13
14
  delete: (guildId: unknown) => Promise<any>;
14
- /** @async Transform the value(s) inside of the StoreManager (IF YOU DON'T NEED PARSING/STRINGIFY, then just return the value) */
15
+ /** @async Transform the value(s) inside of the QueueStoreManager (IF YOU DON'T NEED PARSING/STRINGIFY, then just return the value) */
15
16
  stringify: (value: unknown) => Promise<any>;
16
17
  /** @async Parse the saved value back to the Queue (IF YOU DON'T NEED PARSING/STRINGIFY, then just return the value) */
17
18
  parse: (value: unknown) => Promise<Partial<StoredQueue>>;
18
19
  }
19
- export interface QueueSaverOptions {
20
- maxPreviousTracks: number;
21
- queueStore?: StoreManager;
20
+ export interface ManagerQueueOptions {
21
+ maxPreviousTracks?: number;
22
+ queueStore?: QueueStoreManager;
22
23
  queueChangesWatcher?: QueueChangesWatcher;
23
24
  }
24
25
  export interface QueueSaver {
25
26
  /** @private */
26
- _: StoreManager;
27
+ _: QueueStoreManager;
27
28
  /** @private */
28
- options: QueueSaverOptions;
29
+ options: {
30
+ maxPreviousTracks: number;
31
+ };
29
32
  }
30
33
  export declare class QueueSaver {
31
- constructor(options: QueueSaverOptions);
34
+ constructor(options: ManagerQueueOptions);
32
35
  get(guildId: string): Promise<Partial<StoredQueue>>;
33
36
  delete(guildId: string): Promise<any>;
34
37
  set(guildId: string, value: any): Promise<any>;
35
38
  sync(guildId: string): Promise<Partial<StoredQueue>>;
36
39
  }
37
- export declare class DefaultQueueStore {
40
+ export declare class DefaultQueueStore implements QueueStoreManager {
38
41
  private data;
39
42
  constructor();
40
- get(guildId: any): Promise<any>;
41
- set(guildId: any, stringifiedValue: any): Promise<Map<any, any>>;
43
+ get(guildId: any): Promise<unknown>;
44
+ set(guildId: any, stringifiedValue: any): Promise<MiniMap<unknown, unknown>>;
42
45
  delete(guildId: any): Promise<boolean>;
43
46
  stringify(value: any): Promise<any>;
44
47
  parse(value: any): Promise<Partial<StoredQueue>>;
45
48
  }
46
- export declare class QueueChangesWatcher {
47
- constructor();
48
- tracksAdd(guildId: string, tracks: (Track | UnresolvedTrack)[], position: number, oldStoredQueue: StoredQueue, newStoredQueue: StoredQueue): void;
49
- tracksRemoved(guildId: string, tracks: (Track | UnresolvedTrack)[], position: number, oldStoredQueue: StoredQueue, newStoredQueue: StoredQueue): void;
50
- shuffled(guildId: string, oldStoredQueue: StoredQueue, newStoredQueue: StoredQueue): void;
49
+ export interface QueueChangesWatcher {
50
+ /** get a Value (MUST RETURN UNPARSED!) */
51
+ tracksAdd: (guildId: string, tracks: (Track | UnresolvedTrack)[], position: number, oldStoredQueue: StoredQueue, newStoredQueue: StoredQueue) => any;
52
+ /** Set a value inside a guildId (MUST BE UNPARSED) */
53
+ tracksRemoved: (guildId: string, tracks: (Track | UnresolvedTrack)[], position: number, oldStoredQueue: StoredQueue, newStoredQueue: StoredQueue) => any;
54
+ /** Set a value inside a guildId (MUST BE UNPARSED) */
55
+ shuffled: (guildId: string, oldStoredQueue: StoredQueue, newStoredQueue: StoredQueue) => any;
51
56
  }
52
57
  export declare class Queue {
53
58
  readonly tracks: (Track | UnresolvedTrack)[];
@@ -60,7 +65,7 @@ export declare class Queue {
60
65
  private readonly QueueSaver;
61
66
  private managerUtils;
62
67
  private queueChanges;
63
- constructor(guildId: string, data?: Partial<StoredQueue>, QueueSaver?: QueueSaver, queueOptions?: QueueSaverOptions);
68
+ constructor(guildId: string, data?: Partial<StoredQueue>, QueueSaver?: QueueSaver, queueOptions?: ManagerQueueOptions);
64
69
  private applyData;
65
70
  /**
66
71
  * Utils for a Queue
@@ -77,7 +82,7 @@ export declare class Queue {
77
82
  sync: (override?: boolean, dontSyncCurrent?: boolean) => Promise<void>;
78
83
  destroy: () => Promise<any>;
79
84
  /**
80
- * @returns {{current:Track|null, previous:Track[], tracks:Track[]}}The Queue, but in a raw State, which allows easier handling for the storeManager
85
+ * @returns {{current:Track|null, previous:Track[], tracks:Track[]}}The Queue, but in a raw State, which allows easier handling for the QueueStoreManager
81
86
  */
82
87
  toJSON: () => StoredQueue;
83
88
  /**
@@ -1,12 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Queue = exports.QueueChangesWatcher = exports.DefaultQueueStore = exports.QueueSaver = void 0;
3
+ exports.Queue = exports.DefaultQueueStore = exports.QueueSaver = void 0;
4
4
  const Utils_1 = require("./Utils");
5
5
  class QueueSaver {
6
6
  constructor(options) {
7
- this._ = options.queueStore || new DefaultQueueStore();
7
+ this._ = options?.queueStore || new DefaultQueueStore();
8
8
  this.options = {
9
- maxPreviousTracks: options.maxPreviousTracks
9
+ maxPreviousTracks: options?.maxPreviousTracks || 25,
10
10
  };
11
11
  }
12
12
  async get(guildId) {
@@ -24,9 +24,8 @@ class QueueSaver {
24
24
  }
25
25
  exports.QueueSaver = QueueSaver;
26
26
  class DefaultQueueStore {
27
- data = new Map();
28
- constructor() {
29
- }
27
+ data = new Utils_1.MiniMap();
28
+ constructor() { }
30
29
  async get(guildId) {
31
30
  return await this.data.get(guildId);
32
31
  }
@@ -44,20 +43,6 @@ class DefaultQueueStore {
44
43
  }
45
44
  }
46
45
  exports.DefaultQueueStore = DefaultQueueStore;
47
- class QueueChangesWatcher {
48
- constructor() {
49
- }
50
- tracksAdd(guildId, tracks, position, oldStoredQueue, newStoredQueue) {
51
- return;
52
- }
53
- tracksRemoved(guildId, tracks, position, oldStoredQueue, newStoredQueue) {
54
- return;
55
- }
56
- shuffled(guildId, oldStoredQueue, newStoredQueue) {
57
- return;
58
- }
59
- }
60
- exports.QueueChangesWatcher = QueueChangesWatcher;
61
46
  class Queue {
62
47
  tracks = [];
63
48
  previous = [];
@@ -111,7 +96,7 @@ class Queue {
111
96
  return await this.QueueSaver.delete(this.guildId);
112
97
  },
113
98
  /**
114
- * @returns {{current:Track|null, previous:Track[], tracks:Track[]}}The Queue, but in a raw State, which allows easier handling for the storeManager
99
+ * @returns {{current:Track|null, previous:Track[], tracks:Track[]}}The Queue, but in a raw State, which allows easier handling for the QueueStoreManager
115
100
  */
116
101
  toJSON: () => {
117
102
  if (this.previous.length > this.options.maxPreviousTracks)
@@ -7,8 +7,8 @@ export declare const TrackSymbol: unique symbol;
7
7
  export declare const UnresolvedTrackSymbol: unique symbol;
8
8
  export declare const QueueSymbol: unique symbol;
9
9
  export declare const NodeSymbol: unique symbol;
10
- export type LavalinkSearchPlatform = "ytsearch" | "ytmsearch" | "scsearch" | "spsearch" | "sprec" | "amsearch" | "dzsearch" | "dzisrc" | "sprec" | "ymsearch" | "speak" | "tts" | "ftts";
11
- export type ClientSearchPlatform = "youtube" | "yt" | "yt" | "youtube music" | "youtubemusic" | "ytm" | "soundcloud" | "sc" | "am" | "apple music" | "applemusic" | "apple" | "yandex music" | "sp" | "sprec" | "spsuggestion" | "spotify" | "dz" | "deezer" | "yandex" | "yandexmusic";
10
+ export type LavalinkSearchPlatform = "ytsearch" | "ytmsearch" | "scsearch" | "spsearch" | "sprec" | "amsearch" | "dzsearch" | "dzisrc" | "ymsearch" | "speak" | "tts" | "ftts";
11
+ export type ClientSearchPlatform = "youtube" | "yt" | "youtube music" | "youtubemusic" | "ytm" | "soundcloud" | "sc" | "am" | "apple music" | "applemusic" | "apple" | "sp" | "spsuggestion" | "spotify" | "dz" | "deezer" | "yandex" | "yandex music" | "yandexmusic";
12
12
  export type SearchPlatform = LavalinkSearchPlatform | ClientSearchPlatform;
13
13
  export type SourcesRegex = "YoutubeRegex" | "YoutubeMusicRegex" | "SoundCloudRegex" | "SoundCloudMobileRegex" | "DeezerTrackRegex" | "DeezerArtistRegex" | "DeezerEpisodeRegex" | "DeezerMixesRegex" | "DeezerPageLinkRegex" | "DeezerPlaylistRegex" | "DeezerAlbumRegex" | "AllDeezerRegex" | "AllDeezerRegexWithoutPageLink" | "SpotifySongRegex" | "SpotifyPlaylistRegex" | "SpotifyArtistRegex" | "SpotifyEpisodeRegex" | "SpotifyShowRegex" | "SpotifyAlbumRegex" | "AllSpotifyRegex" | "mp3Url" | "m3uUrl" | "m3u8Url" | "mp4Url" | "m4aUrl" | "wavUrl" | "aacpUrl" | "tiktok" | "mixcloud" | "musicYandex" | "radiohost" | "bandcamp" | "appleMusic" | "TwitchTv" | "vimeo";
14
14
  export interface PlaylistInfo {
@@ -7,7 +7,7 @@ export declare class FilterManager {
7
7
  equalizerBands: EQBand[];
8
8
  filterUpdatedState: number;
9
9
  filters: PlayerFilters;
10
- data: LavalinkFilterData;
10
+ data: FilterData;
11
11
  constructor(player: Player);
12
12
  applyPlayerFilters(): Promise<void>;
13
13
  /**
@@ -215,9 +215,8 @@ export interface ReverbFilter {
215
215
  delay: number;
216
216
  decay: number;
217
217
  }
218
- export interface LavalinkFilterData {
218
+ export interface FilterData {
219
219
  volume?: number;
220
- equalizer?: EQBand[];
221
220
  karaoke?: KaraokeFilter;
222
221
  timescale?: TimescaleFilter;
223
222
  tremolo?: FreqFilter;
@@ -229,3 +228,6 @@ export interface LavalinkFilterData {
229
228
  echo: EchoFilter;
230
229
  reverb: ReverbFilter;
231
230
  }
231
+ export interface LavalinkFilterData extends FilterData {
232
+ equalizer?: EQBand[];
233
+ }
@@ -1,10 +1,10 @@
1
1
  /// <reference types="node" />
2
2
  import { EventEmitter } from "events";
3
3
  import { NodeManager } from "./NodeManager";
4
- import { QueueSaverOptions } from "./Queue";
5
- import { GuildShardPayload, LavalinkSearchPlatform, ManagerUitls, MiniMap, SearchPlatform, TrackEndEvent, TrackExceptionEvent, TrackStartEvent, TrackStuckEvent, VoicePacket, VoiceServer, VoiceState, WebSocketClosedEvent } from "./Utils";
4
+ import { ManagerQueueOptions } from "./Queue";
5
+ import { GuildShardPayload, ManagerUitls, MiniMap, SearchPlatform, TrackEndEvent, TrackExceptionEvent, TrackStartEvent, TrackStuckEvent, VoicePacket, VoiceServer, VoiceState, WebSocketClosedEvent } from "./Utils";
6
6
  import { LavalinkNodeOptions } from "./Node";
7
- import { DestroyReasonsType, Player, PlayerOptions } from "./Player";
7
+ import { DestroyReasonsType, Player, PlayerJson, PlayerOptions } from "./Player";
8
8
  import { Track, UnresolvedTrack } from "./Track";
9
9
  export interface LavalinkManager {
10
10
  nodeManager: NodeManager;
@@ -18,7 +18,7 @@ export interface BotClientOptions {
18
18
  /** So users can pass entire objects / classes */
19
19
  [x: string | number | symbol | undefined]: any;
20
20
  }
21
- export interface LavalinkPlayerOptions {
21
+ export interface ManagerPlayerOptions {
22
22
  /** If the Lavalink Volume should be decremented by x number */
23
23
  volumeDecrementer?: number;
24
24
  /** How often it should update the the player Position */
@@ -44,13 +44,18 @@ export interface LavalinkPlayerOptions {
44
44
  useUnresolvedData?: boolean;
45
45
  }
46
46
  export interface ManagerOptions {
47
+ /** The Node Options, for all Nodes! (on init) */
47
48
  nodes: LavalinkNodeOptions[];
48
- queueOptions?: QueueSaverOptions;
49
+ /** @async The Function to send the voice connection changes from Lavalink to Discord */
50
+ sendToShard: (guildId: string, payload: GuildShardPayload) => void;
51
+ /** The Bot Client's Data for Authorization */
49
52
  client?: BotClientOptions;
50
- playerOptions?: LavalinkPlayerOptions;
53
+ /** QueueOptions for all Queues */
54
+ queueOptions?: ManagerQueueOptions;
55
+ /** PlayerOptions for all Players */
56
+ playerOptions?: ManagerPlayerOptions;
57
+ /** If it should skip to the next Track on TrackEnd / TrackError etc. events */
51
58
  autoSkip?: boolean;
52
- /** @async */
53
- sendToShard: (guildId: string, payload: GuildShardPayload) => void;
54
59
  }
55
60
  interface LavalinkManagerEvents {
56
61
  /**
@@ -107,7 +112,7 @@ interface LavalinkManagerEvents {
107
112
  * Always emits when the player (on lavalink side) got updated
108
113
  * @event Manager#playerUpdate
109
114
  */
110
- "playerUpdate": (player: Player) => void;
115
+ "playerUpdate": (oldPlayerJson: PlayerJson, newPlayer: Player) => void;
111
116
  }
112
117
  export interface LavalinkManager {
113
118
  options: ManagerOptions;
@@ -115,7 +120,7 @@ export interface LavalinkManager {
115
120
  emit<U extends keyof LavalinkManagerEvents>(event: U, ...args: Parameters<LavalinkManagerEvents[U]>): boolean;
116
121
  }
117
122
  export declare class LavalinkManager extends EventEmitter {
118
- static DefaultSources: Record<SearchPlatform, LavalinkSearchPlatform>;
123
+ static DefaultSources: Record<SearchPlatform, import("./Utils").LavalinkSearchPlatform>;
119
124
  static SourceLinksRegexes: Record<import("./Utils").SourcesRegex, RegExp>;
120
125
  initiated: boolean;
121
126
  readonly players: MiniMap<string, Player>;
@@ -78,7 +78,7 @@ export class LavalinkManager extends EventEmitter {
78
78
  const keys = Object.getOwnPropertyNames(Object.getPrototypeOf(options.queueOptions?.queueChangesWatcher));
79
79
  const requiredKeys = ["tracksAdd", "tracksRemoved", "shuffled"];
80
80
  if (!requiredKeys.every(v => keys.includes(v)) || !requiredKeys.every(v => typeof options.queueOptions?.queueChangesWatcher[v] === "function"))
81
- throw new SyntaxError(`The provided ManagerOption.QueueChangesWatcher, does not have all required functions: ${requiredKeys.join(", ")}`);
81
+ throw new SyntaxError(`The provided ManagerOption.DefaultQueueChangesWatcher, does not have all required functions: ${requiredKeys.join(", ")}`);
82
82
  }
83
83
  }
84
84
  constructor(options) {
@@ -354,7 +354,7 @@ export class LavalinkNode {
354
354
  if (data.playerOptions.filters.volume)
355
355
  player.filterManager.data.volume = data.playerOptions.filters.volume;
356
356
  if (data.playerOptions.filters.equalizer)
357
- player.filterManager.data.equalizer = data.playerOptions.filters.equalizer;
357
+ player.filterManager.equalizerBands = data.playerOptions.filters.equalizer;
358
358
  if (data.playerOptions.filters.karaoke)
359
359
  player.filterManager.data.karaoke = data.playerOptions.filters.karaoke;
360
360
  if (data.playerOptions.filters.lowPass)
@@ -437,6 +437,7 @@ export class LavalinkNode {
437
437
  const player = this.NodeManager.LavalinkManager.getPlayer(payload.guildId);
438
438
  if (!player)
439
439
  return;
440
+ const oldPlayer = player?.toJSON();
440
441
  if (player.get("internal_updateInterval"))
441
442
  clearInterval(player.get("internal_updateInterval"));
442
443
  // override the position
@@ -474,7 +475,7 @@ export class LavalinkNode {
474
475
  player.filterManager.filterUpdatedState = 0;
475
476
  }
476
477
  }
477
- this.NodeManager.LavalinkManager.emit("playerUpdate", player);
478
+ this.NodeManager.LavalinkManager.emit("playerUpdate", oldPlayer, player);
478
479
  break;
479
480
  case "event":
480
481
  this.handleEvent(payload);
@@ -521,7 +522,6 @@ export class LavalinkNode {
521
522
  return this.NodeManager.LavalinkManager.emit("trackStart", player, track, payload);
522
523
  }
523
524
  async trackEnd(player, track, payload) {
524
- console.log(payload.reason);
525
525
  // If there are no songs in the queue
526
526
  if (!player.queue.tracks.length && player.repeatMode === "off")
527
527
  return this.queueEnd(player, track, payload);
@@ -558,8 +558,11 @@ export class LavalinkNode {
558
558
  await this.NodeManager.LavalinkManager.options?.playerOptions?.onEmptyQueue?.autoPlayFunction(player, track);
559
559
  if (player.queue.tracks.length > 0)
560
560
  await queueTrackEnd(player);
561
- if (player.queue.current)
561
+ if (player.queue.current) {
562
+ if (payload.type === "TrackEndEvent")
563
+ this.NodeManager.LavalinkManager.emit("trackEnd", player, track, payload);
562
564
  return player.play({ noReplace: true, paused: false });
565
+ }
563
566
  }
564
567
  player.queue.previous.unshift(track);
565
568
  if (payload?.reason !== "stopped") {
@@ -1,4 +1,4 @@
1
- import { FilterManager, LavalinkFilterData } from "./Filters";
1
+ import { EQBand, FilterData, FilterManager, LavalinkFilterData } from "./Filters";
2
2
  import { LavalinkManager } from "./LavalinkManager";
3
3
  import { LavalinkNode } from "./Node";
4
4
  import { Queue } from "./Queue";
@@ -7,6 +7,27 @@ import { LavalinkPlayerVoiceOptions, SearchPlatform, SearchResult } from "./Util
7
7
  type PlayerDestroyReasons = "QueueEmpty" | "NodeDestroy" | "NodeDeleted" | "LavalinkNoVoice" | "NodeReconnectFail" | "PlayerReconnectFail" | "Disconnected" | "ChannelDeleted";
8
8
  export type DestroyReasonsType = PlayerDestroyReasons | string;
9
9
  export declare const DestroyReasons: Record<PlayerDestroyReasons, PlayerDestroyReasons>;
10
+ export interface PlayerJson {
11
+ guildId: string;
12
+ options: PlayerOptions;
13
+ voiceChannelId: string;
14
+ textChannelId?: string;
15
+ position: number;
16
+ lastPosition: number;
17
+ volume: number;
18
+ lavalinkVolume: number;
19
+ repeatMode: RepeatMode;
20
+ paused: boolean;
21
+ playing: boolean;
22
+ createdTimeStamp?: number;
23
+ filters: FilterData;
24
+ ping: {
25
+ ws: number;
26
+ lavalink: number;
27
+ };
28
+ equalizer: EQBand[];
29
+ nodeId?: string;
30
+ }
10
31
  export type RepeatMode = "queue" | "track" | "off";
11
32
  export interface PlayerOptions {
12
33
  guildId: string;
@@ -170,22 +191,6 @@ export declare class Player {
170
191
  */
171
192
  changeNode(newNode: LavalinkNode | string): Promise<string>;
172
193
  /** Converts the Player including Queue to a Json state */
173
- toJSON(): {
174
- guildId: string;
175
- options: PlayerOptions;
176
- voiceChannelId: string;
177
- textChannelId: string;
178
- position: number;
179
- lastPosition: number;
180
- volume: number;
181
- lavalinkVolume: number;
182
- repeatMode: RepeatMode;
183
- paused: boolean;
184
- playing: boolean;
185
- createdTimeStamp: number;
186
- filters: {};
187
- equalizer: import("./Filters").EQBand[];
188
- nodeId: string;
189
- };
194
+ toJSON(): PlayerJson;
190
195
  }
191
196
  export {};
@@ -402,6 +402,7 @@ export class Player {
402
402
  filters: this.filterManager?.data || {},
403
403
  equalizer: this.filterManager?.equalizerBands || [],
404
404
  nodeId: this.node?.id,
405
+ ping: this.ping,
405
406
  };
406
407
  }
407
408
  }
@@ -1,53 +1,58 @@
1
1
  import { Track, UnresolvedTrack } from "./Track";
2
+ import { MiniMap } from "./Utils";
2
3
  export interface StoredQueue {
3
4
  current: Track | null;
4
5
  previous: Track[];
5
6
  tracks: Track[];
6
7
  }
7
- export interface StoreManager extends Record<any, any> {
8
+ export interface QueueStoreManager extends Record<string, any> {
8
9
  /** @async get a Value (MUST RETURN UNPARSED!) */
9
10
  get: (guildId: unknown) => Promise<any>;
10
11
  /** @async Set a value inside a guildId (MUST BE UNPARSED) */
11
12
  set: (guildId: unknown, value: unknown) => Promise<any>;
12
13
  /** @async Delete a Database Value based of it's guildId */
13
14
  delete: (guildId: unknown) => Promise<any>;
14
- /** @async Transform the value(s) inside of the StoreManager (IF YOU DON'T NEED PARSING/STRINGIFY, then just return the value) */
15
+ /** @async Transform the value(s) inside of the QueueStoreManager (IF YOU DON'T NEED PARSING/STRINGIFY, then just return the value) */
15
16
  stringify: (value: unknown) => Promise<any>;
16
17
  /** @async Parse the saved value back to the Queue (IF YOU DON'T NEED PARSING/STRINGIFY, then just return the value) */
17
18
  parse: (value: unknown) => Promise<Partial<StoredQueue>>;
18
19
  }
19
- export interface QueueSaverOptions {
20
- maxPreviousTracks: number;
21
- queueStore?: StoreManager;
20
+ export interface ManagerQueueOptions {
21
+ maxPreviousTracks?: number;
22
+ queueStore?: QueueStoreManager;
22
23
  queueChangesWatcher?: QueueChangesWatcher;
23
24
  }
24
25
  export interface QueueSaver {
25
26
  /** @private */
26
- _: StoreManager;
27
+ _: QueueStoreManager;
27
28
  /** @private */
28
- options: QueueSaverOptions;
29
+ options: {
30
+ maxPreviousTracks: number;
31
+ };
29
32
  }
30
33
  export declare class QueueSaver {
31
- constructor(options: QueueSaverOptions);
34
+ constructor(options: ManagerQueueOptions);
32
35
  get(guildId: string): Promise<Partial<StoredQueue>>;
33
36
  delete(guildId: string): Promise<any>;
34
37
  set(guildId: string, value: any): Promise<any>;
35
38
  sync(guildId: string): Promise<Partial<StoredQueue>>;
36
39
  }
37
- export declare class DefaultQueueStore {
40
+ export declare class DefaultQueueStore implements QueueStoreManager {
38
41
  private data;
39
42
  constructor();
40
- get(guildId: any): Promise<any>;
41
- set(guildId: any, stringifiedValue: any): Promise<Map<any, any>>;
43
+ get(guildId: any): Promise<unknown>;
44
+ set(guildId: any, stringifiedValue: any): Promise<MiniMap<unknown, unknown>>;
42
45
  delete(guildId: any): Promise<boolean>;
43
46
  stringify(value: any): Promise<any>;
44
47
  parse(value: any): Promise<Partial<StoredQueue>>;
45
48
  }
46
- export declare class QueueChangesWatcher {
47
- constructor();
48
- tracksAdd(guildId: string, tracks: (Track | UnresolvedTrack)[], position: number, oldStoredQueue: StoredQueue, newStoredQueue: StoredQueue): void;
49
- tracksRemoved(guildId: string, tracks: (Track | UnresolvedTrack)[], position: number, oldStoredQueue: StoredQueue, newStoredQueue: StoredQueue): void;
50
- shuffled(guildId: string, oldStoredQueue: StoredQueue, newStoredQueue: StoredQueue): void;
49
+ export interface QueueChangesWatcher {
50
+ /** get a Value (MUST RETURN UNPARSED!) */
51
+ tracksAdd: (guildId: string, tracks: (Track | UnresolvedTrack)[], position: number, oldStoredQueue: StoredQueue, newStoredQueue: StoredQueue) => any;
52
+ /** Set a value inside a guildId (MUST BE UNPARSED) */
53
+ tracksRemoved: (guildId: string, tracks: (Track | UnresolvedTrack)[], position: number, oldStoredQueue: StoredQueue, newStoredQueue: StoredQueue) => any;
54
+ /** Set a value inside a guildId (MUST BE UNPARSED) */
55
+ shuffled: (guildId: string, oldStoredQueue: StoredQueue, newStoredQueue: StoredQueue) => any;
51
56
  }
52
57
  export declare class Queue {
53
58
  readonly tracks: (Track | UnresolvedTrack)[];
@@ -60,7 +65,7 @@ export declare class Queue {
60
65
  private readonly QueueSaver;
61
66
  private managerUtils;
62
67
  private queueChanges;
63
- constructor(guildId: string, data?: Partial<StoredQueue>, QueueSaver?: QueueSaver, queueOptions?: QueueSaverOptions);
68
+ constructor(guildId: string, data?: Partial<StoredQueue>, QueueSaver?: QueueSaver, queueOptions?: ManagerQueueOptions);
64
69
  private applyData;
65
70
  /**
66
71
  * Utils for a Queue
@@ -77,7 +82,7 @@ export declare class Queue {
77
82
  sync: (override?: boolean, dontSyncCurrent?: boolean) => Promise<void>;
78
83
  destroy: () => Promise<any>;
79
84
  /**
80
- * @returns {{current:Track|null, previous:Track[], tracks:Track[]}}The Queue, but in a raw State, which allows easier handling for the storeManager
85
+ * @returns {{current:Track|null, previous:Track[], tracks:Track[]}}The Queue, but in a raw State, which allows easier handling for the QueueStoreManager
81
86
  */
82
87
  toJSON: () => StoredQueue;
83
88
  /**
@@ -1,9 +1,9 @@
1
- import { ManagerUitls } from "./Utils";
1
+ import { ManagerUitls, MiniMap } from "./Utils";
2
2
  export class QueueSaver {
3
3
  constructor(options) {
4
- this._ = options.queueStore || new DefaultQueueStore();
4
+ this._ = options?.queueStore || new DefaultQueueStore();
5
5
  this.options = {
6
- maxPreviousTracks: options.maxPreviousTracks
6
+ maxPreviousTracks: options?.maxPreviousTracks || 25,
7
7
  };
8
8
  }
9
9
  async get(guildId) {
@@ -20,9 +20,8 @@ export class QueueSaver {
20
20
  }
21
21
  }
22
22
  export class DefaultQueueStore {
23
- data = new Map();
24
- constructor() {
25
- }
23
+ data = new MiniMap();
24
+ constructor() { }
26
25
  async get(guildId) {
27
26
  return await this.data.get(guildId);
28
27
  }
@@ -39,19 +38,6 @@ export class DefaultQueueStore {
39
38
  return value; // JSON.parse(value)
40
39
  }
41
40
  }
42
- export class QueueChangesWatcher {
43
- constructor() {
44
- }
45
- tracksAdd(guildId, tracks, position, oldStoredQueue, newStoredQueue) {
46
- return;
47
- }
48
- tracksRemoved(guildId, tracks, position, oldStoredQueue, newStoredQueue) {
49
- return;
50
- }
51
- shuffled(guildId, oldStoredQueue, newStoredQueue) {
52
- return;
53
- }
54
- }
55
41
  export class Queue {
56
42
  tracks = [];
57
43
  previous = [];
@@ -105,7 +91,7 @@ export class Queue {
105
91
  return await this.QueueSaver.delete(this.guildId);
106
92
  },
107
93
  /**
108
- * @returns {{current:Track|null, previous:Track[], tracks:Track[]}}The Queue, but in a raw State, which allows easier handling for the storeManager
94
+ * @returns {{current:Track|null, previous:Track[], tracks:Track[]}}The Queue, but in a raw State, which allows easier handling for the QueueStoreManager
109
95
  */
110
96
  toJSON: () => {
111
97
  if (this.previous.length > this.options.maxPreviousTracks)
@@ -7,8 +7,8 @@ export declare const TrackSymbol: unique symbol;
7
7
  export declare const UnresolvedTrackSymbol: unique symbol;
8
8
  export declare const QueueSymbol: unique symbol;
9
9
  export declare const NodeSymbol: unique symbol;
10
- export type LavalinkSearchPlatform = "ytsearch" | "ytmsearch" | "scsearch" | "spsearch" | "sprec" | "amsearch" | "dzsearch" | "dzisrc" | "sprec" | "ymsearch" | "speak" | "tts" | "ftts";
11
- export type ClientSearchPlatform = "youtube" | "yt" | "yt" | "youtube music" | "youtubemusic" | "ytm" | "soundcloud" | "sc" | "am" | "apple music" | "applemusic" | "apple" | "yandex music" | "sp" | "sprec" | "spsuggestion" | "spotify" | "dz" | "deezer" | "yandex" | "yandexmusic";
10
+ export type LavalinkSearchPlatform = "ytsearch" | "ytmsearch" | "scsearch" | "spsearch" | "sprec" | "amsearch" | "dzsearch" | "dzisrc" | "ymsearch" | "speak" | "tts" | "ftts";
11
+ export type ClientSearchPlatform = "youtube" | "yt" | "youtube music" | "youtubemusic" | "ytm" | "soundcloud" | "sc" | "am" | "apple music" | "applemusic" | "apple" | "sp" | "spsuggestion" | "spotify" | "dz" | "deezer" | "yandex" | "yandex music" | "yandexmusic";
12
12
  export type SearchPlatform = LavalinkSearchPlatform | ClientSearchPlatform;
13
13
  export type SourcesRegex = "YoutubeRegex" | "YoutubeMusicRegex" | "SoundCloudRegex" | "SoundCloudMobileRegex" | "DeezerTrackRegex" | "DeezerArtistRegex" | "DeezerEpisodeRegex" | "DeezerMixesRegex" | "DeezerPageLinkRegex" | "DeezerPlaylistRegex" | "DeezerAlbumRegex" | "AllDeezerRegex" | "AllDeezerRegexWithoutPageLink" | "SpotifySongRegex" | "SpotifyPlaylistRegex" | "SpotifyArtistRegex" | "SpotifyEpisodeRegex" | "SpotifyShowRegex" | "SpotifyAlbumRegex" | "AllSpotifyRegex" | "mp3Url" | "m3uUrl" | "m3u8Url" | "mp4Url" | "m4aUrl" | "wavUrl" | "aacpUrl" | "tiktok" | "mixcloud" | "musicYandex" | "radiohost" | "bandcamp" | "appleMusic" | "TwitchTv" | "vimeo";
14
14
  export interface PlaylistInfo {
@@ -1,7 +1,7 @@
1
1
  /// <reference types="node" />
2
2
  import { EventEmitter } from "node:events";
3
3
  import { NodeManager } from "./NodeManager";
4
- import { QueueSaverOptions, StoreManager } from "./Queue";
4
+ import { ManagerQueueOptions, QueueStoreManager } from "./Queue";
5
5
  import { PlayerManager } from "./PlayerManager";
6
6
  import { GuildShardPayload, ManagerUitls, SearchPlatform } from "./Utils";
7
7
  import { LavalinkNodeOptions } from "./Node";
@@ -15,7 +15,7 @@ export interface BotClientOptions {
15
15
  id: string;
16
16
  username: string;
17
17
  }
18
- export interface LavalinkPlayerOptions {
18
+ export interface ManagerPlayerOptions {
19
19
  volumeDecrementer?: number;
20
20
  clientBasedPositionUpdateInterval?: number;
21
21
  defaultSearchPlatform?: SearchPlatform;
@@ -23,10 +23,10 @@ export interface LavalinkPlayerOptions {
23
23
  }
24
24
  export interface ManagerOptions {
25
25
  nodes: LavalinkNodeOptions[];
26
- queueStore?: StoreManager;
27
- queueOptions?: QueueSaverOptions;
26
+ queueStore?: QueueStoreManager;
27
+ queueOptions?: ManagerQueueOptions;
28
28
  client?: BotClientOptions;
29
- playerOptions?: LavalinkPlayerOptions;
29
+ playerOptions?: ManagerPlayerOptions;
30
30
  autoSkip?: boolean;
31
31
  /** @async */
32
32
  sendToShard: (guildId: string, payload: GuildShardPayload) => void;
@@ -4,29 +4,29 @@ export interface StoredQueue {
4
4
  previousTracks: Track[];
5
5
  nextTracks: Track[];
6
6
  }
7
- export interface StoreManager extends Record<any, any> {
7
+ export interface QueueStoreManager extends Record<any, any> {
8
8
  /** @async get a Value */
9
9
  get: (key: unknown) => any;
10
10
  /** @async Set a value inside a key */
11
11
  set: (key: unknown, value: unknown) => any;
12
12
  /** @async Delete a Database Value based of it's key */
13
13
  delete: (key: unknown) => any;
14
- /** @async Transform the value(s) inside of the StoreManager */
14
+ /** @async Transform the value(s) inside of the QueueStoreManager */
15
15
  stringify: (value: unknown) => any;
16
16
  /** @async Parse the saved value back to the Queue */
17
17
  parse: (value: unknown) => Queue;
18
18
  }
19
- export interface QueueSaverOptions {
19
+ export interface ManagerQueueOptions {
20
20
  maxPreviousTracks: number;
21
21
  }
22
22
  export interface QueueSaver {
23
23
  /** @private */
24
- _: StoreManager;
24
+ _: QueueStoreManager;
25
25
  /** @private */
26
- options: QueueSaverOptions;
26
+ options: ManagerQueueOptions;
27
27
  }
28
28
  export declare class QueueSaver {
29
- constructor(storeManager: StoreManager, options: QueueSaverOptions);
29
+ constructor(QueueStoreManager: QueueStoreManager, options: ManagerQueueOptions);
30
30
  get(key: string): Promise<Queue>;
31
31
  delete(key: string): Promise<any>;
32
32
  set(key: string, value: any): Promise<any>;
@@ -59,7 +59,7 @@ export declare class Queue {
59
59
  /** The Size of the previous Track(s) */
60
60
  get previousSize(): number;
61
61
  /**
62
- * @returns The Queue, but in a raw State, which allows easier handling for the storeManager
62
+ * @returns The Queue, but in a raw State, which allows easier handling for the QueueStoreManager
63
63
  */
64
64
  getStored(): StoredQueue;
65
65
  /**
@@ -17,29 +17,29 @@ export interface QueueManager {
17
17
  /** @private */
18
18
  LavalinkManager: LavalinkManager;
19
19
  }
20
- export interface StoreManager extends Record<any, any> {
20
+ export interface QueueStoreManager extends Record<any, any> {
21
21
  /** @async get a Value */
22
22
  get: (key: unknown) => any;
23
23
  /** @async Set a value inside a key */
24
24
  set: (key: unknown, value: unknown) => any;
25
25
  /** @async Delete a Database Value based of it's key */
26
26
  delete: (key: unknown) => any;
27
- /** @async Transform the value(s) inside of the StoreManager */
27
+ /** @async Transform the value(s) inside of the QueueStoreManager */
28
28
  stringify: (value: unknown) => any;
29
29
  /** @async Parse the saved value back to the Queue */
30
30
  parse: (value: unknown) => Queue;
31
31
  }
32
- export interface QueueSaverOptions {
32
+ export interface ManagerQueueOptions {
33
33
  maxPreviousTracks: number;
34
34
  }
35
35
  export interface QueueSaver {
36
36
  /** @private */
37
- _: StoreManager;
37
+ _: QueueStoreManager;
38
38
  /** @private */
39
- options: QueueSaverOptions;
39
+ options: ManagerQueueOptions;
40
40
  }
41
41
  export declare class QueueSaver {
42
- constructor(storeManager: StoreManager, options: QueueSaverOptions);
42
+ constructor(QueueStoreManager: QueueStoreManager, options: ManagerQueueOptions);
43
43
  get(key: string): Promise<Queue>;
44
44
  delete(key: string): Promise<any>;
45
45
  set(key: string, value: any): Promise<any>;
@@ -7,7 +7,7 @@ export declare class FilterManager {
7
7
  equalizerBands: EQBand[];
8
8
  filterUpdatedState: number;
9
9
  filters: PlayerFilters;
10
- data: LavalinkFilterData;
10
+ data: FilterData;
11
11
  constructor(player: Player);
12
12
  applyPlayerFilters(): Promise<void>;
13
13
  /**
@@ -215,9 +215,8 @@ export interface ReverbFilter {
215
215
  delay: number;
216
216
  decay: number;
217
217
  }
218
- export interface LavalinkFilterData {
218
+ export interface FilterData {
219
219
  volume?: number;
220
- equalizer?: EQBand[];
221
220
  karaoke?: KaraokeFilter;
222
221
  timescale?: TimescaleFilter;
223
222
  tremolo?: FreqFilter;
@@ -229,3 +228,6 @@ export interface LavalinkFilterData {
229
228
  echo: EchoFilter;
230
229
  reverb: ReverbFilter;
231
230
  }
231
+ export interface LavalinkFilterData extends FilterData {
232
+ equalizer?: EQBand[];
233
+ }
@@ -1,10 +1,10 @@
1
1
  /// <reference types="node" />
2
2
  import { EventEmitter } from "events";
3
3
  import { NodeManager } from "./NodeManager";
4
- import { QueueSaverOptions } from "./Queue";
5
- import { GuildShardPayload, LavalinkSearchPlatform, ManagerUitls, MiniMap, SearchPlatform, TrackEndEvent, TrackExceptionEvent, TrackStartEvent, TrackStuckEvent, VoicePacket, VoiceServer, VoiceState, WebSocketClosedEvent } from "./Utils";
4
+ import { ManagerQueueOptions } from "./Queue";
5
+ import { GuildShardPayload, ManagerUitls, MiniMap, SearchPlatform, TrackEndEvent, TrackExceptionEvent, TrackStartEvent, TrackStuckEvent, VoicePacket, VoiceServer, VoiceState, WebSocketClosedEvent } from "./Utils";
6
6
  import { LavalinkNodeOptions } from "./Node";
7
- import { DestroyReasonsType, Player, PlayerOptions } from "./Player";
7
+ import { DestroyReasonsType, Player, PlayerJson, PlayerOptions } from "./Player";
8
8
  import { Track, UnresolvedTrack } from "./Track";
9
9
  export interface LavalinkManager {
10
10
  nodeManager: NodeManager;
@@ -18,7 +18,7 @@ export interface BotClientOptions {
18
18
  /** So users can pass entire objects / classes */
19
19
  [x: string | number | symbol | undefined]: any;
20
20
  }
21
- export interface LavalinkPlayerOptions {
21
+ export interface ManagerPlayerOptions {
22
22
  /** If the Lavalink Volume should be decremented by x number */
23
23
  volumeDecrementer?: number;
24
24
  /** How often it should update the the player Position */
@@ -44,13 +44,18 @@ export interface LavalinkPlayerOptions {
44
44
  useUnresolvedData?: boolean;
45
45
  }
46
46
  export interface ManagerOptions {
47
+ /** The Node Options, for all Nodes! (on init) */
47
48
  nodes: LavalinkNodeOptions[];
48
- queueOptions?: QueueSaverOptions;
49
+ /** @async The Function to send the voice connection changes from Lavalink to Discord */
50
+ sendToShard: (guildId: string, payload: GuildShardPayload) => void;
51
+ /** The Bot Client's Data for Authorization */
49
52
  client?: BotClientOptions;
50
- playerOptions?: LavalinkPlayerOptions;
53
+ /** QueueOptions for all Queues */
54
+ queueOptions?: ManagerQueueOptions;
55
+ /** PlayerOptions for all Players */
56
+ playerOptions?: ManagerPlayerOptions;
57
+ /** If it should skip to the next Track on TrackEnd / TrackError etc. events */
51
58
  autoSkip?: boolean;
52
- /** @async */
53
- sendToShard: (guildId: string, payload: GuildShardPayload) => void;
54
59
  }
55
60
  interface LavalinkManagerEvents {
56
61
  /**
@@ -107,7 +112,7 @@ interface LavalinkManagerEvents {
107
112
  * Always emits when the player (on lavalink side) got updated
108
113
  * @event Manager#playerUpdate
109
114
  */
110
- "playerUpdate": (player: Player) => void;
115
+ "playerUpdate": (oldPlayerJson: PlayerJson, newPlayer: Player) => void;
111
116
  }
112
117
  export interface LavalinkManager {
113
118
  options: ManagerOptions;
@@ -115,7 +120,7 @@ export interface LavalinkManager {
115
120
  emit<U extends keyof LavalinkManagerEvents>(event: U, ...args: Parameters<LavalinkManagerEvents[U]>): boolean;
116
121
  }
117
122
  export declare class LavalinkManager extends EventEmitter {
118
- static DefaultSources: Record<SearchPlatform, LavalinkSearchPlatform>;
123
+ static DefaultSources: Record<SearchPlatform, import("./Utils").LavalinkSearchPlatform>;
119
124
  static SourceLinksRegexes: Record<import("./Utils").SourcesRegex, RegExp>;
120
125
  initiated: boolean;
121
126
  readonly players: MiniMap<string, Player>;
@@ -1,4 +1,4 @@
1
- import { FilterManager, LavalinkFilterData } from "./Filters";
1
+ import { EQBand, FilterData, FilterManager, LavalinkFilterData } from "./Filters";
2
2
  import { LavalinkManager } from "./LavalinkManager";
3
3
  import { LavalinkNode } from "./Node";
4
4
  import { Queue } from "./Queue";
@@ -7,6 +7,27 @@ import { LavalinkPlayerVoiceOptions, SearchPlatform, SearchResult } from "./Util
7
7
  type PlayerDestroyReasons = "QueueEmpty" | "NodeDestroy" | "NodeDeleted" | "LavalinkNoVoice" | "NodeReconnectFail" | "PlayerReconnectFail" | "Disconnected" | "ChannelDeleted";
8
8
  export type DestroyReasonsType = PlayerDestroyReasons | string;
9
9
  export declare const DestroyReasons: Record<PlayerDestroyReasons, PlayerDestroyReasons>;
10
+ export interface PlayerJson {
11
+ guildId: string;
12
+ options: PlayerOptions;
13
+ voiceChannelId: string;
14
+ textChannelId?: string;
15
+ position: number;
16
+ lastPosition: number;
17
+ volume: number;
18
+ lavalinkVolume: number;
19
+ repeatMode: RepeatMode;
20
+ paused: boolean;
21
+ playing: boolean;
22
+ createdTimeStamp?: number;
23
+ filters: FilterData;
24
+ ping: {
25
+ ws: number;
26
+ lavalink: number;
27
+ };
28
+ equalizer: EQBand[];
29
+ nodeId?: string;
30
+ }
10
31
  export type RepeatMode = "queue" | "track" | "off";
11
32
  export interface PlayerOptions {
12
33
  guildId: string;
@@ -170,22 +191,6 @@ export declare class Player {
170
191
  */
171
192
  changeNode(newNode: LavalinkNode | string): Promise<string>;
172
193
  /** Converts the Player including Queue to a Json state */
173
- toJSON(): {
174
- guildId: string;
175
- options: PlayerOptions;
176
- voiceChannelId: string;
177
- textChannelId: string;
178
- position: number;
179
- lastPosition: number;
180
- volume: number;
181
- lavalinkVolume: number;
182
- repeatMode: RepeatMode;
183
- paused: boolean;
184
- playing: boolean;
185
- createdTimeStamp: number;
186
- filters: {};
187
- equalizer: import("./Filters").EQBand[];
188
- nodeId: string;
189
- };
194
+ toJSON(): PlayerJson;
190
195
  }
191
196
  export {};
@@ -1,53 +1,58 @@
1
1
  import { Track, UnresolvedTrack } from "./Track";
2
+ import { MiniMap } from "./Utils";
2
3
  export interface StoredQueue {
3
4
  current: Track | null;
4
5
  previous: Track[];
5
6
  tracks: Track[];
6
7
  }
7
- export interface StoreManager extends Record<any, any> {
8
+ export interface QueueStoreManager extends Record<string, any> {
8
9
  /** @async get a Value (MUST RETURN UNPARSED!) */
9
10
  get: (guildId: unknown) => Promise<any>;
10
11
  /** @async Set a value inside a guildId (MUST BE UNPARSED) */
11
12
  set: (guildId: unknown, value: unknown) => Promise<any>;
12
13
  /** @async Delete a Database Value based of it's guildId */
13
14
  delete: (guildId: unknown) => Promise<any>;
14
- /** @async Transform the value(s) inside of the StoreManager (IF YOU DON'T NEED PARSING/STRINGIFY, then just return the value) */
15
+ /** @async Transform the value(s) inside of the QueueStoreManager (IF YOU DON'T NEED PARSING/STRINGIFY, then just return the value) */
15
16
  stringify: (value: unknown) => Promise<any>;
16
17
  /** @async Parse the saved value back to the Queue (IF YOU DON'T NEED PARSING/STRINGIFY, then just return the value) */
17
18
  parse: (value: unknown) => Promise<Partial<StoredQueue>>;
18
19
  }
19
- export interface QueueSaverOptions {
20
- maxPreviousTracks: number;
21
- queueStore?: StoreManager;
20
+ export interface ManagerQueueOptions {
21
+ maxPreviousTracks?: number;
22
+ queueStore?: QueueStoreManager;
22
23
  queueChangesWatcher?: QueueChangesWatcher;
23
24
  }
24
25
  export interface QueueSaver {
25
26
  /** @private */
26
- _: StoreManager;
27
+ _: QueueStoreManager;
27
28
  /** @private */
28
- options: QueueSaverOptions;
29
+ options: {
30
+ maxPreviousTracks: number;
31
+ };
29
32
  }
30
33
  export declare class QueueSaver {
31
- constructor(options: QueueSaverOptions);
34
+ constructor(options: ManagerQueueOptions);
32
35
  get(guildId: string): Promise<Partial<StoredQueue>>;
33
36
  delete(guildId: string): Promise<any>;
34
37
  set(guildId: string, value: any): Promise<any>;
35
38
  sync(guildId: string): Promise<Partial<StoredQueue>>;
36
39
  }
37
- export declare class DefaultQueueStore {
40
+ export declare class DefaultQueueStore implements QueueStoreManager {
38
41
  private data;
39
42
  constructor();
40
- get(guildId: any): Promise<any>;
41
- set(guildId: any, stringifiedValue: any): Promise<Map<any, any>>;
43
+ get(guildId: any): Promise<unknown>;
44
+ set(guildId: any, stringifiedValue: any): Promise<MiniMap<unknown, unknown>>;
42
45
  delete(guildId: any): Promise<boolean>;
43
46
  stringify(value: any): Promise<any>;
44
47
  parse(value: any): Promise<Partial<StoredQueue>>;
45
48
  }
46
- export declare class QueueChangesWatcher {
47
- constructor();
48
- tracksAdd(guildId: string, tracks: (Track | UnresolvedTrack)[], position: number, oldStoredQueue: StoredQueue, newStoredQueue: StoredQueue): void;
49
- tracksRemoved(guildId: string, tracks: (Track | UnresolvedTrack)[], position: number, oldStoredQueue: StoredQueue, newStoredQueue: StoredQueue): void;
50
- shuffled(guildId: string, oldStoredQueue: StoredQueue, newStoredQueue: StoredQueue): void;
49
+ export interface QueueChangesWatcher {
50
+ /** get a Value (MUST RETURN UNPARSED!) */
51
+ tracksAdd: (guildId: string, tracks: (Track | UnresolvedTrack)[], position: number, oldStoredQueue: StoredQueue, newStoredQueue: StoredQueue) => any;
52
+ /** Set a value inside a guildId (MUST BE UNPARSED) */
53
+ tracksRemoved: (guildId: string, tracks: (Track | UnresolvedTrack)[], position: number, oldStoredQueue: StoredQueue, newStoredQueue: StoredQueue) => any;
54
+ /** Set a value inside a guildId (MUST BE UNPARSED) */
55
+ shuffled: (guildId: string, oldStoredQueue: StoredQueue, newStoredQueue: StoredQueue) => any;
51
56
  }
52
57
  export declare class Queue {
53
58
  readonly tracks: (Track | UnresolvedTrack)[];
@@ -60,7 +65,7 @@ export declare class Queue {
60
65
  private readonly QueueSaver;
61
66
  private managerUtils;
62
67
  private queueChanges;
63
- constructor(guildId: string, data?: Partial<StoredQueue>, QueueSaver?: QueueSaver, queueOptions?: QueueSaverOptions);
68
+ constructor(guildId: string, data?: Partial<StoredQueue>, QueueSaver?: QueueSaver, queueOptions?: ManagerQueueOptions);
64
69
  private applyData;
65
70
  /**
66
71
  * Utils for a Queue
@@ -77,7 +82,7 @@ export declare class Queue {
77
82
  sync: (override?: boolean, dontSyncCurrent?: boolean) => Promise<void>;
78
83
  destroy: () => Promise<any>;
79
84
  /**
80
- * @returns {{current:Track|null, previous:Track[], tracks:Track[]}}The Queue, but in a raw State, which allows easier handling for the storeManager
85
+ * @returns {{current:Track|null, previous:Track[], tracks:Track[]}}The Queue, but in a raw State, which allows easier handling for the QueueStoreManager
81
86
  */
82
87
  toJSON: () => StoredQueue;
83
88
  /**
@@ -7,8 +7,8 @@ export declare const TrackSymbol: unique symbol;
7
7
  export declare const UnresolvedTrackSymbol: unique symbol;
8
8
  export declare const QueueSymbol: unique symbol;
9
9
  export declare const NodeSymbol: unique symbol;
10
- export type LavalinkSearchPlatform = "ytsearch" | "ytmsearch" | "scsearch" | "spsearch" | "sprec" | "amsearch" | "dzsearch" | "dzisrc" | "sprec" | "ymsearch" | "speak" | "tts" | "ftts";
11
- export type ClientSearchPlatform = "youtube" | "yt" | "yt" | "youtube music" | "youtubemusic" | "ytm" | "soundcloud" | "sc" | "am" | "apple music" | "applemusic" | "apple" | "yandex music" | "sp" | "sprec" | "spsuggestion" | "spotify" | "dz" | "deezer" | "yandex" | "yandexmusic";
10
+ export type LavalinkSearchPlatform = "ytsearch" | "ytmsearch" | "scsearch" | "spsearch" | "sprec" | "amsearch" | "dzsearch" | "dzisrc" | "ymsearch" | "speak" | "tts" | "ftts";
11
+ export type ClientSearchPlatform = "youtube" | "yt" | "youtube music" | "youtubemusic" | "ytm" | "soundcloud" | "sc" | "am" | "apple music" | "applemusic" | "apple" | "sp" | "spsuggestion" | "spotify" | "dz" | "deezer" | "yandex" | "yandex music" | "yandexmusic";
12
12
  export type SearchPlatform = LavalinkSearchPlatform | ClientSearchPlatform;
13
13
  export type SourcesRegex = "YoutubeRegex" | "YoutubeMusicRegex" | "SoundCloudRegex" | "SoundCloudMobileRegex" | "DeezerTrackRegex" | "DeezerArtistRegex" | "DeezerEpisodeRegex" | "DeezerMixesRegex" | "DeezerPageLinkRegex" | "DeezerPlaylistRegex" | "DeezerAlbumRegex" | "AllDeezerRegex" | "AllDeezerRegexWithoutPageLink" | "SpotifySongRegex" | "SpotifyPlaylistRegex" | "SpotifyArtistRegex" | "SpotifyEpisodeRegex" | "SpotifyShowRegex" | "SpotifyAlbumRegex" | "AllSpotifyRegex" | "mp3Url" | "m3uUrl" | "m3u8Url" | "mp4Url" | "m4aUrl" | "wavUrl" | "aacpUrl" | "tiktok" | "mixcloud" | "musicYandex" | "radiohost" | "bandcamp" | "appleMusic" | "TwitchTv" | "vimeo";
14
14
  export interface PlaylistInfo {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lavalink-client",
3
- "version": "1.0.6",
3
+ "version": "1.0.7",
4
4
  "description": "Easy and advanced lavalink client. Use it with lavalink plugins as well as latest lavalink versions",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",