hoshimi 0.3.3 → 0.3.6

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/dist/index.js CHANGED
@@ -21,45 +21,56 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
23
  AudioOutput: () => AudioOutput,
24
+ AudioOutputData: () => AudioOutputData,
24
25
  DSPXPluginFilter: () => DSPXPluginFilter,
25
26
  DebugLevels: () => DebugLevels,
27
+ DefaultFilterPreset: () => DefaultFilterPreset,
28
+ DefaultPlayerFilters: () => DefaultPlayerFilters,
26
29
  DestroyReasons: () => DestroyReasons,
27
- Events: () => Events,
30
+ EventNames: () => EventNames,
28
31
  FilterManager: () => FilterManager,
29
32
  FilterType: () => FilterType,
30
33
  Hoshimi: () => Hoshimi,
34
+ HoshimiAgent: () => HoshimiAgent,
31
35
  HttpMethods: () => HttpMethods,
32
36
  HttpStatusCodes: () => HttpStatusCodes,
33
37
  LavalinkPluginFilter: () => LavalinkPluginFilter,
34
38
  LoadType: () => LoadType,
35
39
  LoopMode: () => LoopMode,
36
40
  ManagerError: () => ManagerError,
37
- MemoryAdapter: () => MemoryAdapter,
38
41
  Node: () => Node,
39
42
  NodeDestroyReasons: () => NodeDestroyReasons,
40
43
  NodeError: () => NodeError,
44
+ NodeManagerError: () => NodeManagerError,
41
45
  NodeSortTypes: () => NodeSortTypes,
42
46
  OpCodes: () => OpCodes,
43
47
  OptionError: () => OptionError,
44
48
  Player: () => Player,
45
49
  PlayerError: () => PlayerError,
46
50
  PlayerEventType: () => PlayerEventType,
51
+ PlayerMemoryStorage: () => PlayerMemoryStorage,
52
+ PlayerStorageAdapter: () => PlayerStorageAdapter,
47
53
  PluginInfoType: () => PluginInfoType,
48
54
  PluginNames: () => PluginNames,
49
55
  Queue: () => Queue,
56
+ QueueMemoryStorage: () => QueueMemoryStorage,
57
+ QueueStorageAdapter: () => QueueStorageAdapter,
50
58
  ResolveError: () => ResolveError,
51
59
  Rest: () => Rest,
52
60
  RestPathType: () => RestPathType,
61
+ RestRoutes: () => RestRoutes,
53
62
  SearchEngines: () => SearchEngines,
54
63
  Severity: () => Severity,
55
64
  SourceNames: () => SourceNames,
56
65
  State: () => State,
57
- StorageAdapter: () => StorageAdapter,
58
66
  StorageError: () => StorageError,
59
67
  Structures: () => Structures,
60
68
  Track: () => Track,
61
69
  TrackEndReason: () => TrackEndReason,
62
70
  UnresolvedTrack: () => UnresolvedTrack,
71
+ UrlRegex: () => UrlRegex,
72
+ ValidEngines: () => ValidEngines,
73
+ ValidSources: () => ValidSources,
63
74
  WebsocketCloseCodes: () => WebsocketCloseCodes,
64
75
  createHoshimi: () => createHoshimi
65
76
  });
@@ -96,6 +107,12 @@ var StorageError = class extends Error {
96
107
  this.name = "Hoshimi [StorageError]";
97
108
  }
98
109
  };
110
+ var NodeManagerError = class extends Error {
111
+ constructor(message) {
112
+ super(message);
113
+ this.name = "Hoshimi [NodeManagerError]";
114
+ }
115
+ };
99
116
  var ResolveError = class extends Error {
100
117
  constructor(message) {
101
118
  super(message);
@@ -140,6 +157,7 @@ var SearchEngines = /* @__PURE__ */ ((SearchEngines2) => {
140
157
  SearchEngines2["Local"] = "local";
141
158
  SearchEngines2["PornHub"] = "phsearch";
142
159
  SearchEngines2["TextToSpeech"] = "speak";
160
+ SearchEngines2["HTTP"] = "http";
143
161
  return SearchEngines2;
144
162
  })(SearchEngines || {});
145
163
  var DebugLevels = /* @__PURE__ */ ((DebugLevels2) => {
@@ -151,32 +169,33 @@ var DebugLevels = /* @__PURE__ */ ((DebugLevels2) => {
151
169
  DebugLevels2[DebugLevels2["Test"] = 6] = "Test";
152
170
  return DebugLevels2;
153
171
  })(DebugLevels || {});
154
- var Events = /* @__PURE__ */ ((Events2) => {
155
- Events2["Debug"] = "debug";
156
- Events2["Error"] = "error";
157
- Events2["NodeRaw"] = "nodeRaw";
158
- Events2["NodeError"] = "nodeError";
159
- Events2["NodeReady"] = "nodeReady";
160
- Events2["NodeDisconnect"] = "nodeDisconnect";
161
- Events2["NodeReconnecting"] = "nodeReconnecting";
162
- Events2["NodeDestroy"] = "nodeDestroy";
163
- Events2["NodeResumed"] = "nodeResumed";
164
- Events2["NodeCreate"] = "nodeCreate";
165
- Events2["PlayerCreate"] = "playerCreate";
166
- Events2["PlayerUpdate"] = "playerUpdate";
167
- Events2["PlayerDestroy"] = "playerDestroy";
168
- Events2["TrackStart"] = "trackStart";
169
- Events2["TrackEnd"] = "trackEnd";
170
- Events2["TrackStuck"] = "trackStuck";
171
- Events2["TrackError"] = "trackError";
172
- Events2["LyricsFound"] = "lyricsFound";
173
- Events2["LyricsNotFound"] = "lyricsNotFound";
174
- Events2["LyricsLine"] = "lyricsLine";
175
- Events2["QueueEnd"] = "queueEnd";
176
- Events2["QueueUpdate"] = "queueUpdate";
177
- Events2["WebSocketClosed"] = "socketClosed";
178
- return Events2;
179
- })(Events || {});
172
+ var EventNames = /* @__PURE__ */ ((EventNames2) => {
173
+ EventNames2["Debug"] = "debug";
174
+ EventNames2["Error"] = "error";
175
+ EventNames2["NodeRaw"] = "nodeRaw";
176
+ EventNames2["NodeError"] = "nodeError";
177
+ EventNames2["NodeReady"] = "nodeReady";
178
+ EventNames2["NodeDisconnect"] = "nodeDisconnect";
179
+ EventNames2["NodeReconnecting"] = "nodeReconnecting";
180
+ EventNames2["NodeDestroy"] = "nodeDestroy";
181
+ EventNames2["NodeResumed"] = "nodeResumed";
182
+ EventNames2["NodeCreate"] = "nodeCreate";
183
+ EventNames2["PlayerCreate"] = "playerCreate";
184
+ EventNames2["PlayerUpdate"] = "playerUpdate";
185
+ EventNames2["PlayerDestroy"] = "playerDestroy";
186
+ EventNames2["PlayerError"] = "playerError";
187
+ EventNames2["TrackStart"] = "trackStart";
188
+ EventNames2["TrackEnd"] = "trackEnd";
189
+ EventNames2["TrackStuck"] = "trackStuck";
190
+ EventNames2["TrackError"] = "trackError";
191
+ EventNames2["LyricsFound"] = "lyricsFound";
192
+ EventNames2["LyricsNotFound"] = "lyricsNotFound";
193
+ EventNames2["LyricsLine"] = "lyricsLine";
194
+ EventNames2["QueueEnd"] = "queueEnd";
195
+ EventNames2["QueueUpdate"] = "queueUpdate";
196
+ EventNames2["WebSocketClosed"] = "socketClosed";
197
+ return EventNames2;
198
+ })(EventNames || {});
180
199
  var DestroyReasons = /* @__PURE__ */ ((DestroyReasons2) => {
181
200
  DestroyReasons2["Stop"] = "Player-Stop";
182
201
  DestroyReasons2["Requested"] = "Player-Requested";
@@ -184,6 +203,8 @@ var DestroyReasons = /* @__PURE__ */ ((DestroyReasons2) => {
184
203
  DestroyReasons2["NodeDisconnected"] = "Player-NodeDisconnected";
185
204
  DestroyReasons2["NodeDestroy"] = "Player-NodeDestroy";
186
205
  DestroyReasons2["VoiceChannelDeleted"] = "Player-VoiceChannelDeleted";
206
+ DestroyReasons2["VoiceChannelLeft"] = "Player-VoiceChannelLeft";
207
+ DestroyReasons2["ReconnectFailed"] = "Player-ReconnectFailed";
187
208
  return DestroyReasons2;
188
209
  })(DestroyReasons || {});
189
210
 
@@ -346,9 +367,120 @@ var HttpStatusCodes = /* @__PURE__ */ ((HttpStatusCodes2) => {
346
367
  HttpStatusCodes2[HttpStatusCodes2["GatewayTimeout"] = 504] = "GatewayTimeout";
347
368
  return HttpStatusCodes2;
348
369
  })(HttpStatusCodes || {});
370
+ var RestRoutes = {
371
+ /**
372
+ *
373
+ * Get the updated player endpoint.
374
+ * @param {string} sessionId The session id of the node.
375
+ * @param {string} guildId The guild id of the player.
376
+ * @returns {RestEndpoint} The endpoint for updating the player.
377
+ */
378
+ UpdatePlayer(sessionId, guildId) {
379
+ return `/sessions/${sessionId}/players/${guildId}`;
380
+ },
381
+ /**
382
+ *
383
+ * Get the update session endpoint.
384
+ * @param {string} sessionId The session id of the node.
385
+ * @returns {RestEndpoint} The endpoint for updating the session.
386
+ */
387
+ UpdateSession(sessionId) {
388
+ return `/sessions/${sessionId}`;
389
+ },
390
+ /**
391
+ *
392
+ * Get the get players endpoint.
393
+ * @param {string} sessionId The session id of the node.
394
+ * @returns {RestEndpoint} The endpoint for getting the players.
395
+ */
396
+ GetPlayers(sessionId) {
397
+ return `/sessions/${sessionId}/players`;
398
+ },
399
+ /**
400
+ *
401
+ * Get the current lyrics endpoint.
402
+ * @param {string} sessionId The session id of the node.
403
+ * @param {string} guildId The guild id of the player.
404
+ * @returns {RestEndpoint} The endpoint for getting the current lyrics.
405
+ */
406
+ CurrentLyrics(sessionId, guildId) {
407
+ return `/sessions/${sessionId}/players/${guildId}/track/lyrics`;
408
+ },
409
+ /**
410
+ *
411
+ * Subscribe to lyrics endpoint.
412
+ * @param {string} sessionId The session id of the node.
413
+ * @param {string} guildId The guild id of the player.
414
+ * @returns {RestEndpoint} The endpoint for subscribing to lyrics.
415
+ */
416
+ SubscribeLyrics(sessionId, guildId) {
417
+ return `/sessions/${sessionId}/players/${guildId}/lyrics/subscribe`;
418
+ },
419
+ /**
420
+ * Get the lyrics endpoint.
421
+ * @type {RestEndpoint}
422
+ */
423
+ GetLyrics: "/lyrics",
424
+ /**
425
+ * Get the decode track endpoint.
426
+ * @type {RestEndpoint}
427
+ */
428
+ DecodeTrack: "/decodetrack",
429
+ /**
430
+ * Get the decode tracks endpoint.
431
+ * @type {RestEndpoint}
432
+ */
433
+ DecodeTracks: "/decodetracks",
434
+ /**
435
+ * Get the load tracks endpoint.
436
+ * @type {RestEndpoint}
437
+ */
438
+ LoadTracks: "/loadtracks",
439
+ /**
440
+ * Get the node info endpoint.
441
+ * @type {RestEndpoint}
442
+ */
443
+ NodeInfo: "/info",
444
+ /**
445
+ * Get the load lyrics endpoint.
446
+ * @type {RestEndpoint}
447
+ * @description Used in NodelinkLyricsManager, only for nodelink nodes.
448
+ */
449
+ LoadLyrics: "/loadlyrics",
450
+ /**
451
+ * Get the connection endpoint.
452
+ * @type {RestEndpoint}
453
+ * @description Used for checking the connection status of the node, only for nodelink nodes.
454
+ */
455
+ Connection: "/connection"
456
+ };
457
+
458
+ // src/classes/storage/adapters/PlayerAdapter.ts
459
+ var PlayerStorageAdapter = class {
460
+ /**
461
+ * The namespace of the storage.
462
+ * @type {string}
463
+ * @default "hoshimiplayer"
464
+ * @example
465
+ * ```ts
466
+ * console.log(storage.namespace); // "hoshimiplayer"
467
+ * ```
468
+ */
469
+ namespace = "hoshimiplayer";
470
+ };
349
471
 
350
- // src/classes/queue/adapters/adapter.ts
351
- var StorageAdapter = class {
472
+ // src/classes/storage/adapters/QueueAdapter.ts
473
+ var QueueStorageAdapter = class {
474
+ /**
475
+ * The namespace of the storage.
476
+ * @type {string}
477
+ * @default "hoshimiqueue"
478
+ * @example
479
+ * ```ts
480
+ * console.log(storage.namespace); // "hoshimiqueue"
481
+ * ```
482
+ */
483
+ namespace = "hoshimiqueue";
352
484
  };
353
485
 
354
486
  // src/classes/Track.ts
@@ -371,7 +503,7 @@ var Track = class {
371
503
  pluginInfo;
372
504
  /**
373
505
  * The track user data.
374
- * @type {Record<string, unknown>}
506
+ * @type {TrackUserData}
375
507
  */
376
508
  userData;
377
509
  /**
@@ -441,7 +573,7 @@ var UnresolvedTrack = class {
441
573
  pluginInfo;
442
574
  /**
443
575
  * The track user data.
444
- * @type {Record<string, unknown> | undefined}
576
+ * @type {TrackUserData | undefined}
445
577
  */
446
578
  userData;
447
579
  /**
@@ -469,7 +601,7 @@ var UnresolvedTrack = class {
469
601
  constructor(track, requester) {
470
602
  this.info = track.info;
471
603
  this.encoded = track.encoded;
472
- this.requester = requester;
604
+ this.requester = requester ?? {};
473
605
  this.pluginInfo = track.pluginInfo;
474
606
  this.userData = track.userData ?? {};
475
607
  }
@@ -491,10 +623,14 @@ var UnresolvedTrack = class {
491
623
  if (this.info.uri) {
492
624
  const track = await player.search({ query: this.info.uri, requester: this.requester }).then((result) => result.tracks[0]);
493
625
  if (!track) throw new ResolveError("Track could not be resolved from URI.");
494
- player.manager.emit("debug" /* Debug */, 3 /* Player */, `[Unresolved] -> [Track] Resolved the track from URI: ${this.info.uri}`);
626
+ player.manager.emit(
627
+ "debug" /* Debug */,
628
+ 3 /* Player */,
629
+ `[Unresolved] -> [Track] Resolved the track from URI: ${this.info.uri}`
630
+ );
495
631
  return track;
496
632
  }
497
- const query = [this.info.title, this.info.uri].filter(Boolean).join(" by ");
633
+ const query = [this.info.title, this.info.author].filter(Boolean).join(" by ");
498
634
  const excluded = ["twitch" /* Twitch */, "flowery-tts" /* FloweryTTS */, "mixer" /* Mixer */, "vimeo" /* Vimeo */];
499
635
  const engine = this.info.sourceName && !excluded.includes(this.info.sourceName) ? validateEngine(this.info.sourceName) : player.manager.options.defaultSearchEngine;
500
636
  player.manager.emit(
@@ -531,12 +667,20 @@ var UnresolvedTrack = class {
531
667
  // package.json
532
668
  var package_default = {
533
669
  name: "hoshimi",
534
- version: "0.3.3",
670
+ version: "0.3.6",
535
671
  description: "A lavalink@v4 client easy to use, up-to-date and all ears.",
536
672
  main: "./dist/index.js",
537
673
  module: "./dist/index.mjs",
538
674
  types: "./dist/index.d.ts",
539
- packageManager: "pnpm@10.25.0+sha512.5e82639027af37cf832061bcc6d639c219634488e0f2baebe785028a793de7b525ffcd3f7ff574f5e9860654e098fe852ba8ac5dd5cefe1767d23a020a92f501",
675
+ packageManager: "pnpm@10.29.3+sha512.498e1fb4cca5aa06c1dcf2611e6fafc50972ffe7189998c409e90de74566444298ffe43e6cd2acdc775ba1aa7cc5e092a8b7054c811ba8c5770f84693d33d2dc",
676
+ exports: {
677
+ ".": {
678
+ types: "./dist/index.d.ts",
679
+ require: "./dist/index.js",
680
+ import: "./dist/index.mjs",
681
+ default: "./dist/index.js"
682
+ }
683
+ },
540
684
  files: [
541
685
  "dist"
542
686
  ],
@@ -572,8 +716,8 @@ var package_default = {
572
716
  author: "Ganyu Studios",
573
717
  license: "MIT",
574
718
  devDependencies: {
575
- "@biomejs/biome": "^2.3.8",
576
- "@types/node": "^25.0.1",
719
+ "@biomejs/biome": "^2.3.15",
720
+ "@types/node": "^25.2.3",
577
721
  "@types/ws": "^8.18.1",
578
722
  husky: "^9.1.7",
579
723
  "lint-staged": "^16.2.7",
@@ -582,7 +726,7 @@ var package_default = {
582
726
  typescript: "^5.9.3"
583
727
  },
584
728
  dependencies: {
585
- ws: "^8.18.3"
729
+ ws: "^8.19.0"
586
730
  },
587
731
  pnpm: {
588
732
  onlyBuiltDependencies: [
@@ -761,20 +905,53 @@ function validateManagerOptions(options) {
761
905
  throw new OptionError("The manager option 'options.nodes' must be a valid array of nodes and atleast one valid node.");
762
906
  if (typeof options.sendPayload !== "function")
763
907
  throw new OptionError("The manager option 'options.sendPayload' must be a vaid function.");
764
- if (typeof options.queueOptions !== "undefined" && typeof options.queueOptions.maxPreviousTracks !== "number")
765
- throw new OptionError("The manager option 'options.queueOptions.maxPreviousTracks' must be a number.");
766
- if (typeof options.queueOptions !== "undefined" && typeof options.queueOptions.autoplayFn !== "function")
767
- throw new OptionError("The manager option 'options.queueOptions.autoplayFn' must be a function.");
768
- if (typeof options.queueOptions?.storage !== "undefined" && !(options.queueOptions.storage instanceof StorageAdapter))
769
- throw new OptionError("The manager option 'options.queueOptions.storage' must be a valid storage manager.");
770
908
  if (typeof options.defaultSearchEngine !== "undefined" && !ValidEngines.includes(options.defaultSearchEngine))
771
909
  throw new OptionError("The manager option 'options.defaultSearchEngine' Must be a valid search engine.");
772
- if (typeof options.client !== "undefined" && typeof options.client !== "object")
773
- throw new OptionError("The manager option 'options.client' Must be a valid object.");
774
- if (typeof options.client !== "undefined" && typeof options.client.id !== "undefined" && typeof options.client.id !== "string")
775
- throw new OptionError("The manager option 'options.client.id' Must be a valid string.");
776
- if (typeof options.client !== "undefined" && typeof options.client.id !== "undefined" && typeof options.client.username !== "string")
777
- throw new OptionError("The manager option 'options.client.username' must be a valid string.");
910
+ if (typeof options.queueOptions !== "undefined") {
911
+ if (typeof options.queueOptions.maxHistory !== "number")
912
+ throw new OptionError("The manager option 'options.queueOptions.maxPreviousTracks' must be a number.");
913
+ if (typeof options.queueOptions.autoplayFn !== "function")
914
+ throw new OptionError("The manager option 'options.queueOptions.autoplayFn' must be a function.");
915
+ if (typeof options.queueOptions.storage !== "undefined" && !(options.queueOptions.storage instanceof QueueStorageAdapter))
916
+ throw new OptionError("The manager option 'options.queueOptions.storage' must be a valid storage manager.");
917
+ if (typeof options.queueOptions.autoPlay !== "undefined" && typeof options.queueOptions.autoPlay !== "boolean")
918
+ throw new OptionError("The manager option 'options.queueOptions.autoPlay' must be a boolean.");
919
+ }
920
+ if (typeof options.playerOptions !== "undefined") {
921
+ if (!(options.playerOptions.storage instanceof PlayerStorageAdapter))
922
+ throw new OptionError("The manager option 'options.playerOptions.storage' must be a valid storage manager.");
923
+ if (typeof options.playerOptions.requesterFn !== "function")
924
+ throw new OptionError("The manager option 'options.playerOptions.requesterFn' must be a valid function.");
925
+ if (typeof options.playerOptions.onError !== "undefined") {
926
+ if (typeof options.playerOptions.onError.autoDestroy !== "boolean")
927
+ throw new OptionError("The manager option 'options.playerOptions.onError.autoDestroy' must be a boolean.");
928
+ if (typeof options.playerOptions.onError.autoSkip !== "boolean")
929
+ throw new OptionError("The manager option 'options.playerOptions.onError.autoSkip' must be a boolean.");
930
+ if (typeof options.playerOptions.onError.autoStop !== "boolean")
931
+ throw new OptionError("The manager option 'options.playerOptions.onError.autoStop' must be a boolean.");
932
+ }
933
+ }
934
+ if (typeof options.client !== "undefined") {
935
+ if (typeof options.client !== "object") throw new OptionError("The manager option 'options.client' Must be a valid object.");
936
+ if (typeof options.client.id !== "undefined" && typeof options.client.id !== "string")
937
+ throw new OptionError("The manager option 'options.client.id' Must be a valid string.");
938
+ if (typeof options.client.username !== "undefined" && typeof options.client.username !== "string")
939
+ throw new OptionError("The manager option 'options.client.username' must be a valid string.");
940
+ }
941
+ if (typeof options.nodeOptions !== "undefined") {
942
+ if (typeof options.nodeOptions.resumable !== "undefined" && typeof options.nodeOptions.resumable !== "boolean")
943
+ throw new OptionError("The manager option 'options.nodeOptions.resumable' must be a boolean.");
944
+ if (typeof options.nodeOptions.resumeTimeout !== "undefined" && typeof options.nodeOptions.resumeTimeout !== "number")
945
+ throw new OptionError("The manager option 'options.nodeOptions.resumeTimeout' must be a number.");
946
+ if (typeof options.nodeOptions.resumeByLibrary !== "undefined" && typeof options.nodeOptions.resumeByLibrary !== "boolean")
947
+ throw new OptionError("The manager option 'options.nodeOptions.resumeByLibrary' must be a boolean.");
948
+ if (typeof options.nodeOptions.userAgent !== "undefined" && typeof options.nodeOptions.userAgent !== "string")
949
+ throw new OptionError("The manager option 'options.nodeOptions.userAgent' must be a string.");
950
+ }
951
+ if (typeof options.restOptions !== "undefined") {
952
+ if (typeof options.restOptions.resumeTimeout !== "undefined" && typeof options.restOptions.resumeTimeout !== "number")
953
+ throw new OptionError("The manager option 'options.restOptions.resumeTimeout' must be a number.");
954
+ }
778
955
  }
779
956
  function validateQuery(search) {
780
957
  if (typeof search !== "object") throw new OptionError("The 'query' must be a valid object.");
@@ -822,6 +999,11 @@ function validatePlayerData(data) {
822
999
  player.lastPosition = data.playerOptions.position;
823
1000
  player.lastPositionUpdate = Date.now();
824
1001
  }
1002
+ if (typeof data.playerOptions.filters === "object") {
1003
+ const timescale = Object.freeze({ ...player.filterManager.data.timescale });
1004
+ Object.assign(player.filterManager.data, data.playerOptions.filters);
1005
+ player.filterManager.check(timescale);
1006
+ }
825
1007
  }
826
1008
  }
827
1009
  function validateNodePlugins(node, plugins) {
@@ -846,9 +1028,11 @@ function validateEngine(type) {
846
1028
  }
847
1029
  function validateTrack(player, track) {
848
1030
  if (!track) return Promise.resolve(null);
849
- if (isTrack(track)) return Promise.resolve(new Track(track, track.requester));
1031
+ const requesterFn2 = player.manager.options.playerOptions.requesterFn;
1032
+ if (isTrack(track)) return Promise.resolve(new Track(track, requesterFn2(track.requester)));
850
1033
  if (!isUnresolvedTrack(track)) throw new ResolveError("The track is not a valid unresolved track.");
851
- if (!track.resolve || typeof track.resolve !== "function") return new UnresolvedTrack(track, track.requester).resolve(player);
1034
+ if (!track.resolve || typeof track.resolve !== "function")
1035
+ return new UnresolvedTrack(track, requesterFn2(track.requester)).resolve(player);
852
1036
  return track.resolve(player);
853
1037
  }
854
1038
  var isTrack = (track) => {
@@ -880,6 +1064,9 @@ function stringify(value, space) {
880
1064
  space
881
1065
  );
882
1066
  }
1067
+ function requesterFn(requester) {
1068
+ return requester;
1069
+ }
883
1070
  function isNode(options) {
884
1071
  return typeof options.host === "string" && typeof options.port === "number" && typeof options.password === "string" && (typeof options.id === "string" || typeof options.id === "undefined") && (typeof options.secure === "boolean" || typeof options.secure === "undefined") && (typeof options.sessionId === "string" || typeof options.sessionId === "undefined") && (typeof options.retryAmount === "number" || typeof options.retryAmount === "undefined") && (typeof options.retryDelay === "number" || typeof options.retryDelay === "undefined");
885
1072
  }
@@ -919,7 +1106,7 @@ var LyricsManager = class {
919
1106
  if (!this.node.sessionId) return null;
920
1107
  validateNodePlugins(this.node, ["lavalyrics-plugin" /* LavaLyrics */, "java-lyrics-plugin" /* JavaLyrics */, "lavasrc-plugin" /* LavaSrc */]);
921
1108
  return this.node.rest.request({
922
- endpoint: `/sessions/${this.node.sessionId}/players/${guildId}/track/lyrics`,
1109
+ endpoint: RestRoutes.CurrentLyrics(this.node.sessionId, guildId),
923
1110
  params: {
924
1111
  skipTrackSource: `${skipSource}`
925
1112
  }
@@ -941,7 +1128,7 @@ var LyricsManager = class {
941
1128
  if (!this.node.sessionId) return null;
942
1129
  validateNodePlugins(this.node, ["lavalyrics-plugin" /* LavaLyrics */, "java-lyrics-plugin" /* JavaLyrics */, "lavasrc-plugin" /* LavaSrc */]);
943
1130
  return this.node.rest.request({
944
- endpoint: "/lyrics",
1131
+ endpoint: RestRoutes.GetLyrics,
945
1132
  params: {
946
1133
  track: track.encoded,
947
1134
  skipTrackSource: `${skipSource}`
@@ -964,7 +1151,7 @@ var LyricsManager = class {
964
1151
  if (!this.node.sessionId) return;
965
1152
  validateNodePlugins(this.node, ["lavalyrics-plugin" /* LavaLyrics */, "java-lyrics-plugin" /* JavaLyrics */, "lavasrc-plugin" /* LavaSrc */]);
966
1153
  await this.node.rest.request({
967
- endpoint: `/sessions/${this.node.sessionId}/players/${guildId}/lyrics/subscribe`,
1154
+ endpoint: RestRoutes.SubscribeLyrics(this.node.sessionId, guildId),
968
1155
  method: "POST" /* Post */,
969
1156
  params: {
970
1157
  skipTrackSource: `${skipSource}`
@@ -986,7 +1173,7 @@ var LyricsManager = class {
986
1173
  if (!this.node.sessionId) return;
987
1174
  validateNodePlugins(this.node, ["lavalyrics-plugin" /* LavaLyrics */, "java-lyrics-plugin" /* JavaLyrics */, "lavasrc-plugin" /* LavaSrc */]);
988
1175
  await this.node.rest.request({
989
- endpoint: `/sessions/${this.node.sessionId}/players/${guildId}/lyrics/subscribe`,
1176
+ endpoint: RestRoutes.SubscribeLyrics(this.node.sessionId, guildId),
990
1177
  method: "DELETE" /* Delete */
991
1178
  });
992
1179
  }
@@ -1253,7 +1440,7 @@ var NodeManager = class {
1253
1440
  */
1254
1441
  getLeastUsed(sortType = "penalties" /* Penalties */) {
1255
1442
  const nodes = this.nodes.filter((node) => node.state === 2 /* Connected */);
1256
- if (!nodes.length) throw new Error("No connected nodes available.");
1443
+ if (!nodes.length) throw new NodeManagerError("No connected nodes available.");
1257
1444
  switch (sortType) {
1258
1445
  case "players" /* Players */:
1259
1446
  return nodes.reduce((a, b) => (a.stats?.players ?? 0) < (b.stats?.players ?? 0) ? a : b);
@@ -1378,8 +1565,8 @@ async function onEnd() {
1378
1565
  (x) => x.info.identifier === this.queue.current.info.identifier && x.info.title === this.queue.current.info.title
1379
1566
  )) {
1380
1567
  this.queue.history.unshift(this.queue.current);
1381
- if (this.queue.history.length > this.manager.options.queueOptions.maxPreviousTracks)
1382
- this.queue.history.splice(this.manager.options.queueOptions.maxPreviousTracks, this.queue.history.length);
1568
+ if (this.queue.history.length > this.manager.options.queueOptions.maxHistory)
1569
+ this.queue.history.splice(this.manager.options.queueOptions.maxHistory, this.queue.history.length);
1383
1570
  await this.queue.utils.save();
1384
1571
  this.manager.emit(
1385
1572
  "debug" /* Debug */,
@@ -1389,7 +1576,7 @@ async function onEnd() {
1389
1576
  }
1390
1577
  if (this.loop === 1 /* Track */ && this.queue.current) this.queue.unshift(this.queue.current);
1391
1578
  if (this.loop === 2 /* Queue */ && this.queue.current) this.queue.add(this.queue.current);
1392
- if (!this.queue.current) this.queue.current = await validateTrack(this, this.queue.shift());
1579
+ if (!this.queue.current) this.queue.current = await validateTrack(this, await this.queue.shift());
1393
1580
  await this.queue.utils.save();
1394
1581
  return;
1395
1582
  }
@@ -1536,6 +1723,43 @@ async function socketClosed(payload) {
1536
1723
  `[Player] -> [Socket] The socket has closed: ${this.guildId} | Payload: ${stringify(payload)}`
1537
1724
  );
1538
1725
  }
1726
+ async function resumeByLibrary(players) {
1727
+ this.nodeManager.manager.emit("debug" /* Debug */, 2 /* Node */, `[Socket] -> [${this.id}]: Resuming session by library...`);
1728
+ for (const player of players) {
1729
+ try {
1730
+ if (!player.playing && !player.paused && !player.queue.totalSize) {
1731
+ this.nodeManager.manager.emit(
1732
+ "debug" /* Debug */,
1733
+ 2 /* Node */,
1734
+ `[Player] -> [Resume] Destroyed player for guild ${player.guildId} due to empty queue.`
1735
+ );
1736
+ await player.destroy();
1737
+ return;
1738
+ }
1739
+ const track = player.queue.current;
1740
+ await player.node.updatePlayer({
1741
+ guildId: player.guildId,
1742
+ playerOptions: { voice: player.voice }
1743
+ });
1744
+ await player.connect();
1745
+ await player.queue.utils.sync(false, true);
1746
+ if (track)
1747
+ await player.play({
1748
+ track,
1749
+ noReplace: false,
1750
+ position: player.lastPosition,
1751
+ paused: player.paused
1752
+ });
1753
+ } catch (error) {
1754
+ this.nodeManager.manager.emit("nodeError" /* NodeError */, this, error);
1755
+ }
1756
+ this.nodeManager.manager.emit(
1757
+ "debug" /* Debug */,
1758
+ 2 /* Node */,
1759
+ `[Player] -> [Resume] Resumed player for guild ${player.guildId} using the library.`
1760
+ );
1761
+ }
1762
+ }
1539
1763
 
1540
1764
  // src/util/events/websocket.ts
1541
1765
  function onOpen(res) {
@@ -1608,34 +1832,36 @@ async function onMessage(message) {
1608
1832
  this.sessionId = payload.sessionId;
1609
1833
  this.session.resuming = payload.resumed;
1610
1834
  if (payload.resumed) {
1611
- const players = await this.rest.request({
1612
- endpoint: `/sessions/${payload.sessionId}/players`
1613
- }) ?? [];
1835
+ const players2 = await this.rest.getPlayers();
1614
1836
  const timeout = this.nodeManager.manager.options.nodeOptions.resumeTimeout;
1615
- this.nodeManager.manager.emit("nodeResumed" /* NodeResumed */, this, players, payload);
1837
+ this.nodeManager.manager.emit("nodeResumed" /* NodeResumed */, this, players2, payload);
1616
1838
  this.nodeManager.manager.emit(
1617
1839
  "debug" /* Debug */,
1618
1840
  2 /* Node */,
1619
- `[Socket] <- [${this.id}]: Resumed session. | Session id: ${payload.sessionId} | Players: ${players.length} | Resumed: ${payload.resumed} | Timeout: ${timeout}ms`
1841
+ `[Socket] <- [${this.id}]: Resumed session. | Session id: ${payload.sessionId} | Players: ${players2.length} | Resumed: ${payload.resumed} | Timeout: ${timeout}ms`
1620
1842
  );
1621
1843
  }
1622
- this.info = await this.rest.request({ endpoint: "/info" });
1623
- this.nodeManager.manager.emit(
1624
- "debug" /* Debug */,
1625
- 2 /* Node */,
1626
- `[Socket] <- [${this.id}]: Received ready event. | Session id: ${payload.sessionId} | Resumed: ${payload.resumed}`
1627
- );
1628
- this.nodeManager.manager.emit("nodeReady" /* NodeReady */, this, this.retryAmount, payload);
1629
- const isResumable = this.nodeManager.manager.options.nodeOptions.resumable;
1630
- if (isResumable) {
1844
+ const players = this.nodeManager.manager.players.filter((p) => p.node.id === this.id);
1845
+ const isLibrary = this.nodeManager.manager.options.nodeOptions.resumeByLibrary;
1846
+ if (!payload.resumed && isLibrary && players.length) await resumeByLibrary.call(this, players);
1847
+ this.info = await this.rest.request({ endpoint: RestRoutes.NodeInfo });
1848
+ if (this.info) this.info.isNodelink = !!this.info.isNodelink;
1849
+ const resuming = this.nodeManager.manager.options.nodeOptions.resumable;
1850
+ if (resuming) {
1631
1851
  const timeout = this.nodeManager.manager.options.nodeOptions.resumeTimeout;
1632
1852
  this.nodeManager.manager.emit(
1633
1853
  "debug" /* Debug */,
1634
1854
  2 /* Node */,
1635
- `[Socket] -> [${this.id}]: Resuming session... | Timeout: ${timeout}ms`
1855
+ `[Socket] -> [${this.id}]: Setting timeout to resume session. | Timeout: ${timeout}ms`
1636
1856
  );
1637
- await this.updateSession(isResumable, timeout);
1857
+ await this.updateSession({ resuming, timeout });
1638
1858
  }
1859
+ this.nodeManager.manager.emit(
1860
+ "debug" /* Debug */,
1861
+ 2 /* Node */,
1862
+ `[Socket] <- [${this.id}]: Received ready event. | Session id: ${payload.sessionId} | Resumed: ${payload.resumed}`
1863
+ );
1864
+ this.nodeManager.manager.emit("nodeReady" /* NodeReady */, this, this.retryAmount, payload);
1639
1865
  }
1640
1866
  break;
1641
1867
  case "event" /* Event */: {
@@ -1683,7 +1909,11 @@ async function onMessage(message) {
1683
1909
  break;
1684
1910
  }
1685
1911
  }
1686
- this.nodeManager.manager.emit("debug" /* Debug */, 2 /* Node */, `[Socket] -> [${this.id}]: Received payload: ${stringify(payload)}`);
1912
+ this.nodeManager.manager.emit(
1913
+ "debug" /* Debug */,
1914
+ 2 /* Node */,
1915
+ `[Socket] -> [${this.id}]: Received payload: ${stringify(payload)}`
1916
+ );
1687
1917
  } catch (error) {
1688
1918
  this.nodeManager.manager.emit("nodeError" /* NodeError */, this, error);
1689
1919
  }
@@ -1708,7 +1938,7 @@ var Node = class {
1708
1938
  nodeManager;
1709
1939
  /**
1710
1940
  * The lyrics manager for the node.
1711
- * @type {LyricsManager}
1941
+ * @type {LyricsManagerStructure}
1712
1942
  */
1713
1943
  lyricsManager;
1714
1944
  /**
@@ -1809,14 +2039,14 @@ var Node = class {
1809
2039
  decode = {
1810
2040
  single: async (track, requester) => {
1811
2041
  const raw = await this.rest.request({
1812
- endpoint: "/decodetrack",
2042
+ endpoint: RestRoutes.DecodeTrack,
1813
2043
  params: { encodedTrack: track }
1814
2044
  });
1815
2045
  return new Track(raw, requester);
1816
2046
  },
1817
2047
  multiple: async (tracks, requester) => {
1818
2048
  const raw = await this.rest.request({
1819
- endpoint: "/decodetracks",
2049
+ endpoint: RestRoutes.DecodeTracks,
1820
2050
  method: "POST" /* Post */,
1821
2051
  body: stringify(tracks)
1822
2052
  }) ?? [];
@@ -1838,6 +2068,25 @@ var Node = class {
1838
2068
  get id() {
1839
2069
  return this.options.id;
1840
2070
  }
2071
+ /**
2072
+ *
2073
+ * Check if the node is a Nodelink node.
2074
+ * @returns {boolean} True if the node is a Nodelink node, false otherwise.
2075
+ * @example
2076
+ * ```ts
2077
+ * const node = manager.nodeManager.get("node1");
2078
+ * if (node) {
2079
+ * if (node.isNodelink()) {
2080
+ * console.log("The node is a Nodelink node");
2081
+ * } else {
2082
+ * console.log("The node is a Lavalink node");
2083
+ * }
2084
+ * }
2085
+ * ```
2086
+ */
2087
+ isNodelink() {
2088
+ return this.info?.isNodelink ?? false;
2089
+ }
1841
2090
  /**
1842
2091
  * The socket address to connect the node.
1843
2092
  * @type {string}
@@ -1897,7 +2146,7 @@ var Node = class {
1897
2146
  search.engine ??= this.nodeManager.manager.options.defaultSearchEngine;
1898
2147
  const identifier = validateQuery(search);
1899
2148
  return this.rest.request({
1900
- endpoint: "/loadtracks",
2149
+ endpoint: RestRoutes.LoadTracks,
1901
2150
  params: {
1902
2151
  identifier,
1903
2152
  ...search.params
@@ -2061,21 +2310,20 @@ var Node = class {
2061
2310
  /**
2062
2311
  *
2063
2312
  * Update the session for the node
2064
- * @param {boolean} resuming Enable resuming for the session.
2065
- * @param {number | null} timeout The timeout for the session.
2313
+ * @param {SessionResumingOptions} options The session resuming options.
2066
2314
  * @returns {Promise<LavalinkSession | null>}
2067
2315
  * @example
2068
2316
  * ```ts
2069
2317
  * const node = manager.nodeManager.get("node1");
2070
2318
  * if (node) {
2071
- * const session = await node.updateSession(true, 60);
2319
+ * const session = await node.updateSession({ resuming: true, timeout: 30000 });
2072
2320
  * console.log(session); // the lavalink session
2073
2321
  * }
2074
2322
  * ```
2075
2323
  */
2076
- async updateSession(resuming, timeout = null) {
2324
+ async updateSession(options) {
2077
2325
  if (!this.sessionId) return null;
2078
- const session = await this.rest.updateSession(resuming, timeout);
2326
+ const session = await this.rest.updateSession(options);
2079
2327
  if (session) this.session = session;
2080
2328
  return session;
2081
2329
  }
@@ -2331,7 +2579,7 @@ var Rest = class {
2331
2579
  validatePlayerData.call(this.node, data);
2332
2580
  return this.request({
2333
2581
  method: "PATCH" /* Patch */,
2334
- endpoint: `/sessions/${this.sessionId}/players/${data.guildId}`,
2582
+ endpoint: RestRoutes.UpdatePlayer(this.sessionId, data.guildId),
2335
2583
  body: { ...data.playerOptions },
2336
2584
  params: { noReplace: `${data.noReplace ?? false}` }
2337
2585
  });
@@ -2382,23 +2630,23 @@ var Rest = class {
2382
2630
  );
2383
2631
  await this.request({
2384
2632
  method: "DELETE" /* Delete */,
2385
- endpoint: `/sessions/${this.sessionId}/players/${guildId}`
2633
+ endpoint: RestRoutes.UpdatePlayer(this.sessionId, guildId)
2386
2634
  });
2387
2635
  }
2388
2636
  /**
2389
2637
  *
2390
2638
  * Update the session for the node
2391
- * @param {boolean} resuming Enable resuming for the session.
2392
- * @param {number | null} timeout The timeout for the session.
2639
+ * @param {SessionResumingOptions} options The session resuming options.
2393
2640
  * @returns {Promise<LavalinkSession | null>} The updated session data.
2394
2641
  * @example
2395
2642
  * ```ts
2396
- * const session = await node.rest.updateSession(true, 10000);
2643
+ * const session = await node.rest.updateSession({ resuming: true, timeout: 30000 });
2397
2644
  * if (session) console.log(session); // The lavalink session data
2398
2645
  * ```
2399
2646
  */
2400
- updateSession(resuming, timeout = null) {
2647
+ updateSession(options) {
2401
2648
  if (!this.sessionId) return Promise.resolve(null);
2649
+ const { resuming, timeout } = options;
2402
2650
  this.node.nodeManager.manager.emit(
2403
2651
  "debug" /* Debug */,
2404
2652
  4 /* Rest */,
@@ -2406,10 +2654,40 @@ var Rest = class {
2406
2654
  );
2407
2655
  return this.request({
2408
2656
  method: "PATCH" /* Patch */,
2409
- endpoint: `/sessions/${this.sessionId}`,
2657
+ endpoint: RestRoutes.UpdateSession(this.sessionId),
2410
2658
  body: { resuming, timeout }
2411
2659
  });
2412
2660
  }
2661
+ /**
2662
+ *
2663
+ * Get all players for the current session.
2664
+ * @returns {Promise<LavalinkPlayer[]>} The players for the current session.
2665
+ * @example
2666
+ * ```ts
2667
+ * const players = await node.rest.getPlayers();
2668
+ * console.log(players); // The lavalink players for the current session
2669
+ * ```
2670
+ */
2671
+ async getPlayers() {
2672
+ if (!this.sessionId) return [];
2673
+ this.node.nodeManager.manager.emit(
2674
+ "debug" /* Debug */,
2675
+ 4 /* Rest */,
2676
+ `[Rest] -> [${this.node.id}]: Fetching all players for session id: ${this.sessionId}`
2677
+ );
2678
+ const players = await this.request({
2679
+ endpoint: RestRoutes.GetPlayers(this.sessionId)
2680
+ }) ?? [];
2681
+ if (!players.length) {
2682
+ this.node.nodeManager.manager.emit(
2683
+ "debug" /* Debug */,
2684
+ 4 /* Rest */,
2685
+ `[Rest] <- [${this.node.id}]: No players found for session id: ${this.sessionId}`
2686
+ );
2687
+ return [];
2688
+ }
2689
+ return players;
2690
+ }
2413
2691
  };
2414
2692
 
2415
2693
  // src/classes/player/filters/DSPXPlugin.ts
@@ -2432,6 +2710,14 @@ var DSPXPluginFilter = class {
2432
2710
  * Set the low-pass filter with the given settings.
2433
2711
  * @param {FilterPluginPassSettings} [settings=DefaultFilter.DSPXLowPass] The settings for the low-pass filter.
2434
2712
  * @returns {Promise<this>} The instance of the filter manager.
2713
+ * @throws {PlayerError} If the node does not have the required plugin or filter enabled.
2714
+ * @example
2715
+ * ```ts
2716
+ * // Set the low-pass filter with custom settings
2717
+ * await player.filterManager.dspxPlugin.setLowPass({ cutoffFrequency: 500, boostFactor: 1.5 });
2718
+ * // Disable the low-pass filter
2719
+ * await player.filterManager.dspxPlugin.setLowPass();
2720
+ * ```
2435
2721
  */
2436
2722
  async setLowPass(settings = DefaultFilterPreset.DSPXLowPass) {
2437
2723
  validateNodePlugins(this.manager.player.node, ["lavadspx-plugin" /* LavaDspx */]);
@@ -2454,6 +2740,14 @@ var DSPXPluginFilter = class {
2454
2740
  * Set the high-pass filter with the given settings.
2455
2741
  * @param {FilterPluginPassSettings} [settings=DefaultFilter.DSPXHighPass] The settings for the high-pass filter.
2456
2742
  * @returns {Promise<this>} The instance of the filter manager.
2743
+ * @throws {PlayerError} If the node does not have the required plugin or filter enabled.
2744
+ * @example
2745
+ * ```ts
2746
+ * // Set the high-pass filter with custom settings
2747
+ * await player.filterManager.dspxPlugin.setHighPass({ cutoffFrequency: 2000, boostFactor: 0.8 });
2748
+ * // Disable the high-pass filter
2749
+ * await player.filterManager.dspxPlugin.setHighPass();
2750
+ * ```
2457
2751
  */
2458
2752
  async setHighPass(settings = DefaultFilterPreset.DSPXHighPass) {
2459
2753
  validateNodePlugins(this.manager.player.node, ["lavadspx-plugin" /* LavaDspx */]);
@@ -2476,6 +2770,14 @@ var DSPXPluginFilter = class {
2476
2770
  * Set the normalization filter with the given settings.
2477
2771
  * @param {NormalizationSettings} [settings=DefaultFilter.DSPXNormalization] The settings for the normalization filter.
2478
2772
  * @returns {Promise<this>} The instance of the filter manager.
2773
+ * @throws {PlayerError} If the node does not have the required plugin or filter enabled.
2774
+ * @example
2775
+ * ```ts
2776
+ * // Set the normalization filter with custom settings
2777
+ * await player.filterManager.dspxPlugin.setNormalization({ maxAmplitude: 0.9, adaptive: true });
2778
+ * // Disable the normalization filter
2779
+ * await player.filterManager.dspxPlugin.setNormalization();
2780
+ * ```
2479
2781
  */
2480
2782
  async setNormalization(settings = DefaultFilterPreset.DSPXNormalization) {
2481
2783
  validateNodePlugins(this.manager.player.node, ["lavadspx-plugin" /* LavaDspx */]);
@@ -2498,6 +2800,14 @@ var DSPXPluginFilter = class {
2498
2800
  * Set the echo filter with the given settings.
2499
2801
  * @param {EchoSettings} [settings=DefaultFilter.DSPXEcho] The settings for the echo filter.
2500
2802
  * @returns {Promise<this>} The instance of the filter manager.
2803
+ * @throws {PlayerError} If the node does not have the required plugin or filter enabled.
2804
+ * @example
2805
+ * ```ts
2806
+ * // Set the echo filter with custom settings
2807
+ * await player.filterManager.dspxPlugin.setEcho({ echoLength: 500, decay: 0.5, delay: 200 });
2808
+ * // Disable the echo filter
2809
+ * await player.filterManager.dspxPlugin.setEcho();
2810
+ * ```
2501
2811
  */
2502
2812
  async setEcho(settings = DefaultFilterPreset.DSPXEcho) {
2503
2813
  validateNodePlugins(this.manager.player.node, ["lavadspx-plugin" /* LavaDspx */]);
@@ -2538,6 +2848,14 @@ var LavalinkPluginFilter = class {
2538
2848
  * Set the echo filter with the given settings.
2539
2849
  * @param {Omit<EchoSettings, "echoLength">} [settings=DefaultFilter.PluginEcho] The settings for the echo filter.
2540
2850
  * @returns {Promise<this>} The instance of the filter manager.
2851
+ * @throws {PlayerError} If the node does not have the required plugin or filter enabled.
2852
+ * @example
2853
+ * ```ts
2854
+ * // Set the echo filter with custom settings
2855
+ * await player.filterManager.lavalinkPlugin.setEcho({ decay: 0.5, delay: 200 });
2856
+ * // Disable the echo filter
2857
+ * await player.filterManager.lavalinkPlugin.setEcho();
2858
+ * ```
2541
2859
  */
2542
2860
  async setEcho(settings = DefaultFilterPreset.PluginEcho) {
2543
2861
  validateNodePlugins(this.manager.player.node, ["lavalink-filter-plugin" /* FilterPlugin */]);
@@ -2560,6 +2878,14 @@ var LavalinkPluginFilter = class {
2560
2878
  * Set the reverb filter with the given settings.
2561
2879
  * @param {Partial<LavalinkFilterPluginReverbSettings>} [settings=DefaultFilter.PluginReverb] The settings for the reverb filter.
2562
2880
  * @returns {Promise<this>} The instance of the filter manager.
2881
+ * @throws {PlayerError} If the node does not have the required plugin or filter enabled.
2882
+ * @example
2883
+ * ```ts
2884
+ * // Set the reverb filter with custom settings
2885
+ * await player.filterManager.lavalinkPlugin.setReverb({ delays: [50, 100, 150], gains: [0.5, 0.3, 0.2] });
2886
+ * // Disable the reverb filter
2887
+ * await player.filterManager.lavalinkPlugin.setReverb();
2888
+ * ```
2563
2889
  */
2564
2890
  async setReverb(settings = DefaultFilterPreset.PluginReverb) {
2565
2891
  validateNodePlugins(this.manager.player.node, ["lavalink-filter-plugin" /* FilterPlugin */]);
@@ -2653,6 +2979,11 @@ var FilterManager = class {
2653
2979
  /**
2654
2980
  * Resets all filters to their default values.
2655
2981
  * @returns {Promise<this>} A promise that resolves to the instance of the filter manager.
2982
+ * @example
2983
+ * ```ts
2984
+ * // Reset all filters
2985
+ * await player.filterManager.reset();
2986
+ * ```
2656
2987
  */
2657
2988
  async reset() {
2658
2989
  this.filters = {
@@ -2686,6 +3017,11 @@ var FilterManager = class {
2686
3017
  *
2687
3018
  * Applies the current filters to the player.
2688
3019
  * @returns {Promise<this>} A promise that resolves to the instance of the filter manager.
3020
+ * @example
3021
+ * ```ts
3022
+ * // Apply the current filters
3023
+ * await player.filterManager.apply();
3024
+ * ```
2689
3025
  */
2690
3026
  async apply() {
2691
3027
  if (!this.player.node.sessionId) return this;
@@ -2722,6 +3058,11 @@ var FilterManager = class {
2722
3058
  * Checks if the current filters are active.
2723
3059
  * @param {TimescaleSettings} timescale The timescale settings to check against.
2724
3060
  * @returns {void} Nothing!
3061
+ * @example
3062
+ * ```ts
3063
+ * // Check the current filters
3064
+ * player.filterManager.check();
3065
+ * ```
2725
3066
  */
2726
3067
  check(timescale) {
2727
3068
  this.filters.rotation = this.data.rotation?.rotationHz !== 0;
@@ -2752,6 +3093,12 @@ var FilterManager = class {
2752
3093
  * Checks if a specific filter is active.
2753
3094
  * @param {FilterType} filter The filter type to check.
2754
3095
  * @returns {boolean} True if the filter is active, false otherwise.
3096
+ * @example
3097
+ * ```ts
3098
+ * // Check if the nightcore filter is active
3099
+ * const isNightcoreActive = player.filterManager.has(FilterType.Nightcore);
3100
+ * console.log(isNightcoreActive); // true or false
3101
+ * ```
2755
3102
  */
2756
3103
  has(filter) {
2757
3104
  const dspx = this.filters.lavalinkLavaDspxPlugin[filter];
@@ -2768,6 +3115,12 @@ var FilterManager = class {
2768
3115
  * Sets the volume for the player.
2769
3116
  * @param {number} volume The volume level to set (between 0 and 5).
2770
3117
  * @returns {Promise<this>} A promise that resolves to the player instance.
3118
+ * @throws {PlayerError} If the volume is not a number between 0 and 5.
3119
+ * @example
3120
+ * ```ts
3121
+ * // Set the volume to 2.5
3122
+ * await player.filterManager.setVolume(2.5);
3123
+ * ```
2771
3124
  */
2772
3125
  async setVolume(volume) {
2773
3126
  if (typeof volume !== "number" || Number.isNaN(volume) || volume < 0 || volume > 5)
@@ -2780,6 +3133,12 @@ var FilterManager = class {
2780
3133
  * Sets the audio output for the player.
2781
3134
  * @param {AudioOutput} output The audio output to set.
2782
3135
  * @returns {Promise<this>} A promise that resolves to the player instance.
3136
+ * @throws {PlayerError} If the output is not a valid AudioOutput value.
3137
+ * @example
3138
+ * ```ts
3139
+ * // Set the audio output to mono
3140
+ * await player.filterManager.setAudioOutput(AudioOutput.Mono);
3141
+ * ```
2783
3142
  */
2784
3143
  async setAudioOutput(output) {
2785
3144
  const outputs = Object.values(AudioOutput);
@@ -2793,6 +3152,12 @@ var FilterManager = class {
2793
3152
  * Sets the speed for the player.
2794
3153
  * @param {number} speed The speed to set (default is 1).
2795
3154
  * @returns {Promise<this>} A promise that resolves to the player instance.
3155
+ * @throws {PlayerError} If the node does not support the timescale filter.
3156
+ * @example
3157
+ * ```ts
3158
+ * // Set the speed to 1.5
3159
+ * await player.filterManager.setSpeed(1.5);
3160
+ * ```
2796
3161
  */
2797
3162
  async setSpeed(speed = 1) {
2798
3163
  if (!this.player.node.info?.filters?.includes("timescale" /* Timescale */))
@@ -2814,6 +3179,12 @@ var FilterManager = class {
2814
3179
  * Sets the rate for the player.
2815
3180
  * @param {number} rate The rate to set (default is 1).
2816
3181
  * @returns {Promise<this>} A promise that resolves to the player instance.
3182
+ * @throws {PlayerError} If the node does not support the timescale filter.
3183
+ * @example
3184
+ * ```ts
3185
+ * // Set the rate to 1.2
3186
+ * await player.filterManager.setRate(1.2);
3187
+ * ```
2817
3188
  */
2818
3189
  async setRate(rate = 1) {
2819
3190
  if (!this.player.node.info?.filters?.includes("timescale" /* Timescale */))
@@ -2835,6 +3206,12 @@ var FilterManager = class {
2835
3206
  * Sets the pitch for the player.
2836
3207
  * @param {number} pitch The pitch
2837
3208
  * @returns {Promise<this>} A promise that resolves to the player instance.
3209
+ * @throws {PlayerError} If the node does not support the timescale filter.
3210
+ * @example
3211
+ * ```ts
3212
+ * // Set the pitch to 0.8
3213
+ * await player.filterManager.setPitch(0.8);
3214
+ * ```
2838
3215
  */
2839
3216
  async setPitch(pitch = 1) {
2840
3217
  if (!this.player.node.info?.filters?.includes("timescale" /* Timescale */))
@@ -2856,6 +3233,15 @@ var FilterManager = class {
2856
3233
  * Sets the EQ bands for the player.
2857
3234
  * @param {RestOrArray<EQBandSettings>} bands The EQ band settings to set.
2858
3235
  * @returns {Promise<this>} A promise that resolves to the instance of the manager.
3236
+ * @throws {PlayerError} If the bands array is empty or contains invalid band settings.
3237
+ * @example
3238
+ * ```ts
3239
+ * // Set multiple EQ bands
3240
+ * await player.filterManager.setEQBand(
3241
+ * { band: 0, gain: 0.5 },
3242
+ * { band: 1, gain: -0.3 },
3243
+ * );
3244
+ * ```
2859
3245
  */
2860
3246
  async setEQBand(...bands) {
2861
3247
  bands = bands.flat();
@@ -2868,6 +3254,11 @@ var FilterManager = class {
2868
3254
  *
2869
3255
  * Clears all EQ bands for the player.
2870
3256
  * @returns {Promise<this>} A promise that resolves to the instance of the manager.
3257
+ * @example
3258
+ * ```ts
3259
+ * // Clear all EQ bands
3260
+ * await player.filterManager.clearEQBands();
3261
+ * ```
2871
3262
  */
2872
3263
  async clearEQBands() {
2873
3264
  return this.setEQBand(Array.from({ length: 15 }, (_, i) => ({ band: i, gain: 0 })));
@@ -2877,6 +3268,12 @@ var FilterManager = class {
2877
3268
  * Set the vibrato filter with the given settings.
2878
3269
  * @param {TremoloSettings} [settings=DefaultFilterPreset.Vibrato] The settings for the vibrato filter.
2879
3270
  * @returns {Promise<this>} The instance of the filter manager.
3271
+ * @throws {PlayerError} If the node does not support the vibrato filter.
3272
+ * @example
3273
+ * ```ts
3274
+ * // Set the vibrato filter
3275
+ * await player.filterManager.setVibrato({ frequency: 4.0, depth: 0.5 });
3276
+ * ```
2880
3277
  */
2881
3278
  async setVibrato(settings = DefaultFilterPreset.Vibrato) {
2882
3279
  if (!this.player.node.info?.filters?.includes("vibrato" /* Vibrato */))
@@ -2893,6 +3290,12 @@ var FilterManager = class {
2893
3290
  * Set the tremolo filter with the given settings.
2894
3291
  * @param {TremoloSettings} [settings=DefaultFilterPreset.Tremolo] The settings for the tremolo filter.
2895
3292
  * @returns {Promise<this>} The instance of the filter manager.
3293
+ * @throws {PlayerError} If the node does not support the tremolo filter.
3294
+ * @example
3295
+ * ```ts
3296
+ * // Set the tremolo filter
3297
+ * await player.filterManager.setTremolo({ frequency: 4.0, depth: 0.5 });
3298
+ * ```
2896
3299
  */
2897
3300
  async setTremolo(settings = DefaultFilterPreset.Tremolo) {
2898
3301
  if (!this.player.node.info?.filters?.includes("tremolo" /* Tremolo */))
@@ -2909,6 +3312,12 @@ var FilterManager = class {
2909
3312
  * Set the low-pass filter with the given settings.
2910
3313
  * @param {LowPassSettings} [settings=DefaultFilterPreset.Lowpass] The settings for the low-pass filter.
2911
3314
  * @returns {Promise<this>} The instance of the filter manager.
3315
+ * @throws {PlayerError} If the node does not support the low-pass filter.
3316
+ * @example
3317
+ * ```ts
3318
+ * // Set the low-pass filter
3319
+ * await player.filterManager.setLowPass({ smoothing: 20.0 });
3320
+ * ```
2912
3321
  */
2913
3322
  async setLowPass(settings = DefaultFilterPreset.Lowpass) {
2914
3323
  if (!this.player.node.info?.filters?.includes("lowPass" /* LowPass */))
@@ -2921,6 +3330,12 @@ var FilterManager = class {
2921
3330
  * Set the nightcore filter with the given settings.
2922
3331
  * @param {Partial<TimescaleSettings>} [settings=DefaultFilterPreset.Nightcore] The settings for the nightcore filter.
2923
3332
  * @returns {Promise<this>} The instance of the filter manager.
3333
+ * @throws {PlayerError} If the node does not support the timescale filter.
3334
+ * @example
3335
+ * ```ts
3336
+ * // Set the nightcore filter
3337
+ * await player.filterManager.setNightcore();
3338
+ * ```
2924
3339
  */
2925
3340
  async setNightcore(settings = DefaultFilterPreset.Nightcore) {
2926
3341
  if (!this.player.node.info?.filters?.includes("timescale" /* Timescale */))
@@ -2940,6 +3355,12 @@ var FilterManager = class {
2940
3355
  * Set the vaporwave filter with the given settings.
2941
3356
  * @param {Partial<TimescaleSettings>} [settings=DefaultFilterPreset.Vaporwave] The settings for the vaporwave filter.
2942
3357
  * @returns {Promise<this>} The instance of the filter manager.
3358
+ * @throws {PlayerError} If the node does not support the timescale filter.
3359
+ * @example
3360
+ * ```ts
3361
+ * // Set the vaporwave filter
3362
+ * await player.filterManager.setVaporwave();
3363
+ * ```
2943
3364
  */
2944
3365
  async setVaporwave(settings = DefaultFilterPreset.Vaporwave) {
2945
3366
  if (!this.player.node.info?.filters?.includes("timescale" /* Timescale */))
@@ -2959,6 +3380,12 @@ var FilterManager = class {
2959
3380
  * Set the karaoke filter with the given settings.
2960
3381
  * @param {KaraokeSettings} [settings=DefaultFilterPreset.Karaoke] The settings for the karaoke filter.
2961
3382
  * @returns {Promise<this>} The instance of the filter manager.
3383
+ * @throws {PlayerError} If the node does not support the karaoke filter.
3384
+ * @example
3385
+ * ```ts
3386
+ * // Set the karaoke filter
3387
+ * await player.filterManager.setKaraoke({ level: -15.0, monoLevel: -20.0, filterBand: 220.0, filterWidth: 100.0 });
3388
+ * ```
2962
3389
  */
2963
3390
  async setKaraoke(settings = DefaultFilterPreset.Karaoke) {
2964
3391
  if (!this.player.node.info?.filters?.includes("karaoke" /* Karaoke */))
@@ -2977,6 +3404,12 @@ var FilterManager = class {
2977
3404
  * Set the distortion filter with the given settings.
2978
3405
  * @param {Partial<DistortionSettings>} [settings=DefaultFilterPreset.Distortion] The settings for the distortion filter.
2979
3406
  * @returns {Promise<this>} The instance of the filter manager.
3407
+ * @throws {PlayerError} If the node does not support the distortion filter.
3408
+ * @example
3409
+ * ```ts
3410
+ * // Set the distortion filter
3411
+ * await player.filterManager.setDistortion({ sinOffset: 0.5, sinScale: 2.0 });
3412
+ * ```
2980
3413
  */
2981
3414
  async setDistortion(settings = DefaultFilterPreset.Distortion) {
2982
3415
  if (!this.player.node.info?.filters?.includes("distortion" /* Distortion */))
@@ -2997,6 +3430,12 @@ var FilterManager = class {
2997
3430
  * Set the timescale filter with the given settings.
2998
3431
  * @param {Partial<TimescaleSettings>} settings The timescale settings to set.
2999
3432
  * @returns {Promise<this>} The instance of the filter manager.
3433
+ * @throws {PlayerError} If the node does not support the timescale filter.
3434
+ * @example
3435
+ * ```ts
3436
+ * // Set the timescale filter
3437
+ * await player.filterManager.setTimescale({ speed: 1.2, pitch: 0.8, rate: 1.0 });
3438
+ * ```
3000
3439
  */
3001
3440
  async setTimescale(settings) {
3002
3441
  if (!this.player.node.info?.filters?.includes("timescale" /* Timescale */))
@@ -3012,107 +3451,26 @@ var FilterManager = class {
3012
3451
  /**
3013
3452
  * Convert the filter settings to a JSON object.
3014
3453
  * @returns {FilterSettings} The filter settings as a JSON object.
3454
+ * @example
3455
+ * ```ts
3456
+ * // Convert filter settings to JSON
3457
+ * const filterSettingsJSON = player.filterManager.toJSON();
3458
+ * console.log(filterSettingsJSON); // { volume: 1, equalizer: [...], ... }
3459
+ * ```
3015
3460
  */
3016
3461
  toJSON() {
3017
3462
  return { ...this.data };
3018
3463
  }
3019
3464
  };
3020
3465
 
3021
- // src/classes/player/Storage.ts
3022
- var PlayerStorage = class {
3023
- /**
3024
- * The internal storage.
3025
- * @type {Map<K, V>}
3026
- * @private
3027
- * @readonly
3028
- * @internal
3029
- */
3030
- internal = /* @__PURE__ */ new Map();
3031
- /**
3032
- *
3033
- * Get the value for a key in the storage.
3034
- * @param {K} key The key to get the value for.
3035
- * @returns {V | undefined} The value for the key, or undefined if it doesn't exist.
3036
- */
3037
- get(key) {
3038
- return this.internal.get(key);
3039
- }
3040
- /**
3041
- * Set the value for a key in the storage.
3042
- * @param {K} key The key to set the value for.
3043
- * @param {V} value The value to set for the key.
3044
- */
3045
- set(key, value) {
3046
- this.internal.set(key, value);
3047
- }
3048
- /**
3049
- * Check if the storage has a key.
3050
- * @param {K} key The key to check for.
3051
- * @returns {boolean} True if the storage has the key, false otherwise.
3052
- */
3053
- has(key) {
3054
- return this.internal.has(key);
3055
- }
3056
- /**
3057
- * Delete a key from the storage.
3058
- * @param {K} key The key to delete.
3059
- * @returns {boolean} True if the key was deleted, false otherwise.
3060
- */
3061
- delete(key) {
3062
- return this.internal.delete(key);
3063
- }
3064
- /**
3065
- * Get all keys in the storage.
3066
- * @returns {K[]} The keys in the storage.
3067
- */
3068
- keys() {
3069
- return [...this.internal.keys()];
3070
- }
3071
- /**
3072
- * Get all values in the storage.
3073
- * @returns {V[]} The values in the storage.
3074
- */
3075
- values() {
3076
- return [...this.internal.values()];
3077
- }
3078
- /**
3079
- * Get all entries in the storage.
3080
- * @returns {[K, V][]} The entries in the storage.
3081
- */
3082
- entries() {
3083
- return [...this.internal.entries()];
3084
- }
3085
- /**
3086
- *
3087
- * Get all key-value pairs in the storage.
3088
- * @returns {Record<K[number], V>} An object containing all key-value pairs in the storage, excluding internal keys.
3089
- */
3090
- all() {
3091
- return Object.fromEntries([...this.internal.entries()].filter(([key]) => !key.startsWith("internal_")));
3092
- }
3093
- /**
3094
- * Clear the storage.
3095
- */
3096
- clear() {
3097
- this.internal.clear();
3098
- }
3099
- /**
3100
- * Get the size of the storage.
3101
- * @returns {number} The number of entries in the storage.
3102
- */
3103
- get size() {
3104
- return this.internal.size;
3105
- }
3106
- };
3107
-
3108
3466
  // src/classes/player/Player.ts
3109
3467
  var Player = class {
3110
3468
  /**
3111
3469
  * The data for the player.
3112
- * @type {PlayerStorage}
3470
+ * @type {PlayerStorageAdapter}
3113
3471
  * @readonly
3114
3472
  */
3115
- data = new PlayerStorage();
3473
+ data;
3116
3474
  /**
3117
3475
  * The options for the player.
3118
3476
  * @type {PlayerOptions}
@@ -3264,6 +3622,7 @@ var Player = class {
3264
3622
  this.volume = options.volume ?? 100;
3265
3623
  this.textId = options.textId;
3266
3624
  this.node = (typeof this.options.node === "string" ? this.manager.nodeManager.get(this.options.node) : this.options.node) ?? this.manager.nodeManager.getLeastUsed();
3625
+ this.data = this.manager.options.playerOptions.storage;
3267
3626
  validatePlayerOptions(this.options);
3268
3627
  this.queue = Structures.Queue(this);
3269
3628
  this.filterManager = Structures.FilterManager(this);
@@ -3279,6 +3638,14 @@ var Player = class {
3279
3638
  current: (skipSource) => this.node.lyricsManager.current(this.guildId, skipSource),
3280
3639
  get: (track, skipSource) => this.node.lyricsManager.get(track, skipSource)
3281
3640
  };
3641
+ /**
3642
+ *
3643
+ * Check if the player is currently playing a track.
3644
+ * @returns {boolean} Whether the player is currently playing a track.
3645
+ */
3646
+ isPlaying() {
3647
+ return this.playing && !this.paused;
3648
+ }
3282
3649
  /**
3283
3650
  *
3284
3651
  * Search for a track or playlist.
@@ -3362,15 +3729,8 @@ var Player = class {
3362
3729
  */
3363
3730
  async disconnect() {
3364
3731
  if (!this.voiceId) return this;
3365
- await this.manager.options.sendPayload(this.guildId, {
3366
- op: 4,
3367
- d: {
3368
- guild_id: this.guildId,
3369
- channel_id: null,
3370
- self_deaf: this.selfDeaf,
3371
- self_mute: this.selfMute
3372
- }
3373
- });
3732
+ this.voiceId = void 0;
3733
+ await this.setVoice({ voiceId: void 0 });
3374
3734
  this.manager.emit("debug" /* Debug */, 3 /* Player */, `[Player] -> [Disconnect] Player disconnected for guild: ${this.guildId}`);
3375
3735
  this.connected = false;
3376
3736
  return this;
@@ -3416,11 +3776,15 @@ var Player = class {
3416
3776
  async play(options = {}) {
3417
3777
  if (typeof options !== "object") throw new PlayerError("The play options must be an object.");
3418
3778
  if (options.track) this.queue.current = await validateTrack(this, options.track);
3419
- else if (!this.queue.current) this.queue.current = await validateTrack(this, this.queue.shift());
3779
+ else if (!this.queue.current) this.queue.current = await validateTrack(this, await this.queue.shift());
3420
3780
  if (!this.queue.current) throw new PlayerError("No track to play.");
3421
3781
  if (!isTrack(this.queue.current) && !isUnresolvedTrack(this.queue.current))
3422
3782
  throw new PlayerError("The track must be a valid Track or UnresolvedTrack instance.");
3423
- this.manager.emit("debug" /* Debug */, 3 /* Player */, `[Player] -> [Play] A new track is playing: ${this.queue.current.info.title}`);
3783
+ this.manager.emit(
3784
+ "debug" /* Debug */,
3785
+ 3 /* Player */,
3786
+ `[Player] -> [Play] A new track is playing: ${this.queue.current.info.title}`
3787
+ );
3424
3788
  const position = options.position ?? 0;
3425
3789
  this.lastPosition = position;
3426
3790
  this.lastPositionUpdate = Date.now();
@@ -3449,15 +3813,7 @@ var Player = class {
3449
3813
  */
3450
3814
  async connect() {
3451
3815
  if (!this.voiceId) return this;
3452
- await this.manager.options.sendPayload(this.guildId, {
3453
- op: 4,
3454
- d: {
3455
- guild_id: this.guildId,
3456
- channel_id: this.voiceId,
3457
- self_deaf: this.selfDeaf,
3458
- self_mute: this.selfMute
3459
- }
3460
- });
3816
+ await this.setVoice();
3461
3817
  this.manager.emit("debug" /* Debug */, 3 /* Player */, `[Player] -> [Connect] Player connected for guild: ${this.guildId}`);
3462
3818
  this.connected = true;
3463
3819
  return this;
@@ -3556,7 +3912,7 @@ var Player = class {
3556
3912
  }
3557
3913
  /**
3558
3914
  * Set the voice of the player.
3559
- * @param {Partial<VoiceChannelUpdate>} voice The voice state to set.
3915
+ * @param {NullableVoiceChannelUpdate} options The voice state to set.
3560
3916
  * @returns {Promise<void>}
3561
3917
  * @example
3562
3918
  * ```ts
@@ -3564,27 +3920,17 @@ var Player = class {
3564
3920
  * player.setVoice({ voiceId: "newVoiceId" });
3565
3921
  * ```
3566
3922
  */
3567
- async setVoice(voice) {
3568
- if (voice.voiceId === this.voiceId) return;
3569
- if (voice.voiceId) {
3570
- this.voiceId = voice.voiceId;
3571
- this.options.voiceId = voice.voiceId;
3572
- }
3573
- if (voice.selfDeaf) {
3574
- this.selfDeaf = voice.selfDeaf;
3575
- this.options.selfDeaf = voice.selfDeaf;
3576
- }
3577
- if (voice.selfMute) {
3578
- this.selfMute = voice.selfMute;
3579
- this.options.selfMute = voice.selfMute;
3580
- }
3923
+ async setVoice(options = {}) {
3924
+ options.voiceId ??= this.voiceId;
3925
+ options.selfDeaf ??= this.selfDeaf;
3926
+ options.selfMute ??= this.selfMute;
3581
3927
  await this.manager.options.sendPayload(this.guildId, {
3582
3928
  op: 4,
3583
3929
  d: {
3584
3930
  guild_id: this.guildId,
3585
- self_deaf: this.selfDeaf,
3586
- self_mute: this.selfMute,
3587
- channel_id: this.voiceId ?? null
3931
+ self_deaf: options.selfDeaf,
3932
+ self_mute: options.selfMute,
3933
+ channel_id: options.voiceId ?? null
3588
3934
  }
3589
3935
  });
3590
3936
  this.manager.emit(
@@ -3643,6 +3989,12 @@ var Player = class {
3643
3989
  * Update the player with new data.
3644
3990
  * @param {NonGuildUpdatePlayerInfo} data The data to update the player with.
3645
3991
  * @returns {Promise<LavalinkPlayer | null>} The updated player data.
3992
+ * @example
3993
+ * ```ts
3994
+ * const player = manager.getPlayer("guildId");
3995
+ * const updatedPlayer = await player.updatePlayer({ volume: 50 });
3996
+ * console.log(updatedPlayer); // the updated player data
3997
+ * ```
3646
3998
  */
3647
3999
  async updatePlayer(data) {
3648
4000
  return this.node.updatePlayer({
@@ -3690,7 +4042,7 @@ var Player = class {
3690
4042
  var QueueStore = class {
3691
4043
  /**
3692
4044
  * Storage manager instance.
3693
- * @type {StorageAdapter}
4045
+ * @type {QueueStorageAdapter}
3694
4046
  * @private
3695
4047
  * @readonly
3696
4048
  * @internal
@@ -3699,7 +4051,7 @@ var QueueStore = class {
3699
4051
  /**
3700
4052
  *
3701
4053
  * Constructor of the queue store.
3702
- * @param {StorageAdapter} storage Storage manager instance.
4054
+ * @param {QueueStorageAdapter} storage Storage manager instance.
3703
4055
  * @example
3704
4056
  * ```ts
3705
4057
  * const storage = new CustomStorage();
@@ -3801,16 +4153,15 @@ var QueueUtils = class {
3801
4153
  * ```
3802
4154
  */
3803
4155
  save() {
3804
- const max = this.options.maxPreviousTracks;
4156
+ const max = this.options.maxHistory;
3805
4157
  const length = this.queue.tracks.length;
3806
- const json = this.queue.toJSON();
3807
4158
  if (length > max) this.queue.history.splice(0, length - max);
3808
4159
  this.queue.player.manager.emit(
3809
4160
  "debug" /* Debug */,
3810
4161
  5 /* Queue */,
3811
- `[Queue] -> [Adapter] Saving queue for ${this.queue.player.guildId} | Object: ${stringify(json)}`
4162
+ `[Queue] -> [Adapter] Saving queue for ${this.queue.player.guildId} | Object: ${stringify(this.queue.toJSON())}`
3812
4163
  );
3813
- return this.store.set(this.queue.player.guildId, json);
4164
+ return this.store.set(this.queue.player.guildId, this.queue.toJSON());
3814
4165
  }
3815
4166
  /**
3816
4167
  *
@@ -3832,6 +4183,8 @@ var QueueUtils = class {
3832
4183
  /**
3833
4184
  *
3834
4185
  * Sync the queue.
4186
+ * @param {boolean} [override=true] Whether to override the current queue or not.
4187
+ * @param {boolean} [syncCurrent=false] Whether to sync the current track or not.
3835
4188
  * @returns {Awaitable<void>}
3836
4189
  * @example
3837
4190
  * ```ts
@@ -3976,25 +4329,50 @@ var Queue = class {
3976
4329
  isEmpty() {
3977
4330
  return this.size === 0;
3978
4331
  }
4332
+ /**
4333
+ *
4334
+ * Build a track from a Lavalink track or unresolved Lavalink track.
4335
+ * @param {LavalinkTrack | UnresolvedLavalinkTrack} track The track to build.
4336
+ * @param {TrackRequester} requester The requester of the track.
4337
+ * @returns {Promise<Track>} The built track.
4338
+ * @example
4339
+ * ```ts
4340
+ * const queue = player.queue;
4341
+ * const lavalinkTrack = {...} // some lavalink track
4342
+ * const track = await queue.build(lavalinkTrack, author);
4343
+ *
4344
+ * console.log(track.info.title); // The title of the track
4345
+ * ```
4346
+ */
4347
+ async build(track, requester) {
4348
+ const requesterFn2 = this.player.manager.options.playerOptions.requesterFn;
4349
+ if (isUnresolvedTrack(track)) return new UnresolvedTrack(track, requesterFn2(requester)).resolve(this.player);
4350
+ if (isTrack(track)) return new Track(track, requesterFn2(requester));
4351
+ return track;
4352
+ }
3979
4353
  /**
3980
4354
  *
3981
4355
  * Get the previous track of the queue.
3982
4356
  * @param {boolean} [remove=false] Whether to remove the track from the previous queue.
3983
- * @returns {Track | null} The previous track of the queue.
4357
+ * @returns {Promise<Track | null>} The previous track of the queue.
3984
4358
  * @example
3985
4359
  * ```ts
3986
4360
  * const queue = player.queue;
3987
4361
  *
3988
- * console.log(queue.previous()); // null
4362
+ * console.log(await queue.previous()); // null
3989
4363
  * queue.add(track);
3990
4364
  * queue.add(track2);
3991
4365
  *
3992
- * console.log(queue.previous()); // track
3993
- * console.log(queue.previous(true)); // track and remove it from the previous tracks
4366
+ * console.log(await queue.previous()); // track
4367
+ * console.log(await queue.previous(true)); // track and remove it from the previous tracks
3994
4368
  * ```
3995
4369
  */
3996
- previous(remove = false) {
3997
- if (remove) return this.history.shift() ?? null;
4370
+ async previous(remove = false) {
4371
+ if (remove) {
4372
+ const track = this.history.shift() ?? null;
4373
+ if (track) await this.utils.save();
4374
+ return track;
4375
+ }
3998
4376
  return this.history[0] ?? null;
3999
4377
  }
4000
4378
  /**
@@ -4002,94 +4380,102 @@ var Queue = class {
4002
4380
  * Add a track or tracks to the queue.
4003
4381
  * @param {Track | Track[]} track The track or tracks to add.
4004
4382
  * @param {number} [position] The position to add the track or tracks.
4005
- * @returns {this} The queue instance.
4383
+ * @returns {Promise<this>} The queue instance.
4006
4384
  * @example
4007
4385
  * ```ts
4008
4386
  * const queue = player.queue;
4009
4387
  *
4010
4388
  * console.log(queue.size); // 0
4011
4389
  *
4012
- * queue.add(track);
4390
+ * await queue.add(track);
4013
4391
  * console.log(queue.size); // 1
4014
4392
  *
4015
- * queue.add([track1, track2]);
4393
+ * await queue.add([track1, track2]);
4016
4394
  * console.log(queue.size); // 3
4017
4395
  *
4018
- * queue.add(track3, 1);
4396
+ * await queue.add(track3, 1);
4019
4397
  * console.log(queue.size); // 4
4020
4398
  * console.log(queue.tracks); // [track1, track3, track2, track]
4021
4399
  * ```
4022
4400
  */
4023
- add(track, position) {
4401
+ async add(track, position) {
4024
4402
  const tracks = Array.isArray(track) ? track : [track];
4025
4403
  if (typeof position === "number" && position >= 0 && position < this.tracks.length) return this.splice(position, 0, ...tracks);
4026
4404
  this.tracks.push(...tracks);
4027
4405
  this.player.manager.emit("queueUpdate" /* QueueUpdate */, this.player, this);
4028
4406
  this.player.manager.emit("debug" /* Debug */, 5 /* Queue */, `[Queue] -> [Add] Added ${this.tracks.length} tracks to the queue.`);
4407
+ await this.utils.save();
4029
4408
  return this;
4030
4409
  }
4031
4410
  /**
4032
4411
  *
4033
4412
  * Get the first track of the queue.
4034
- * @returns {HoshimiTrack | null} The first track of the queue.
4413
+ * @returns {Promise<HoshimiTrack | null>} The first track of the queue.
4035
4414
  * @example
4036
4415
  * ```ts
4037
4416
  * const queue = player.queue;
4038
4417
  *
4039
- * console.log(queue.shift()); // null
4040
- * queue.add(track);
4418
+ * console.log(await queue.shift()); // null
4419
+ * await queue.add(track);
4041
4420
  *
4042
- * console.log(queue.shift()); // track
4043
- * queue.add(track2);
4421
+ * console.log(await queue.shift()); // track
4422
+ * await queue.add(track2);
4044
4423
  * ```
4045
4424
  */
4046
- shift() {
4047
- return this.tracks.shift() ?? null;
4425
+ async shift() {
4426
+ const track = this.tracks.shift() ?? null;
4427
+ if (track) await this.utils.save();
4428
+ return track;
4048
4429
  }
4049
4430
  /**
4050
4431
  *
4051
4432
  * Add tracks to the beginning of the queue.
4052
4433
  * @param {Track[]} tracks The tracks to add.
4053
- * @returns {this} The queue instance.
4434
+ * @returns {Promise<this>} The queue instance.
4054
4435
  * @example
4055
4436
  * ```ts
4056
4437
  * const queue = player.queue;
4057
4438
  *
4058
4439
  * console.log(queue.size); // 0
4059
- * queue.unshift(track);
4440
+ * await queue.unshift(track);
4060
4441
  *
4061
4442
  * console.log(queue.size); // 1
4062
- * queue.unshift([track1, track2]);
4443
+ * await queue.unshift(track1, track2);
4063
4444
  *
4064
4445
  * console.log(queue.size); // 3
4065
4446
  * console.log(queue.tracks); // [track1, track2, track]
4066
4447
  * ```
4067
4448
  */
4068
- unshift(...tracks) {
4449
+ async unshift(...tracks) {
4069
4450
  this.tracks.unshift(...tracks);
4070
- this.player.manager.emit("debug" /* Debug */, 5 /* Queue */, `[Queue] -> [Unshift] Added ${this.tracks.length} tracks to the queue.`);
4451
+ this.player.manager.emit(
4452
+ "debug" /* Debug */,
4453
+ 5 /* Queue */,
4454
+ `[Queue] -> [Unshift] Added ${this.tracks.length} tracks to the queue.`
4455
+ );
4456
+ await this.utils.save();
4071
4457
  return this;
4072
4458
  }
4073
4459
  /**
4074
4460
  *
4075
4461
  * Shuffle the queue.
4076
- * @returns {this} The queue instance.
4462
+ * @returns {Promise<this>} The queue instance.
4077
4463
  * @example
4078
4464
  * ```ts
4079
4465
  * const queue = player.queue;
4080
4466
  *
4081
4467
  * console.log(queue.size); // 0
4082
- * queue.add(track);
4083
- * queue.add([track1, track2]);
4468
+ * await queue.add(track);
4469
+ * await queue.add(track1, track2);
4084
4470
  *
4085
4471
  * console.log(queue.size); // 3
4086
4472
  * console.log(queue.tracks); // [track, track1, track2]
4087
4473
  *
4088
- * queue.shuffle();
4474
+ * await queue.shuffle();
4089
4475
  * console.log(queue.tracks); // [track2, track, track1]
4090
4476
  * ```
4091
4477
  */
4092
- shuffle() {
4478
+ async shuffle() {
4093
4479
  if (this.size <= 1) return this;
4094
4480
  if (this.size === 2) [this.tracks[0], this.tracks[1]] = [this.tracks[1], this.tracks[0]];
4095
4481
  else {
@@ -4100,31 +4486,33 @@ var Queue = class {
4100
4486
  }
4101
4487
  this.player.manager.emit("queueUpdate" /* QueueUpdate */, this.player, this);
4102
4488
  this.player.manager.emit("debug" /* Debug */, 5 /* Queue */, "[Queue] -> [Shuffle] Shuffled the queue.");
4489
+ await this.utils.save();
4103
4490
  return this;
4104
4491
  }
4105
4492
  /**
4106
4493
  *
4107
4494
  * Clear the queue.
4108
- * @returns {this} The queue instance.
4495
+ * @returns {Promise<this>} The queue instance.
4109
4496
  * @example
4110
4497
  * ```ts
4111
4498
  * const queue = player.queue;
4112
4499
  *
4113
4500
  * console.log(queue.size); // 0
4114
- * queue.add(track);
4115
- * queue.add([track1, track2]);
4501
+ * await queue.add(track);
4502
+ * await queue.add(track1, track2);
4116
4503
  *
4117
4504
  * console.log(queue.size); // 3
4118
- * queue.clear();
4505
+ * await queue.clear();
4119
4506
  * console.log(queue.size); // 0
4120
4507
  * ```
4121
4508
  */
4122
- clear() {
4509
+ async clear() {
4123
4510
  this.tracks = [];
4124
4511
  this.history = [];
4125
4512
  this.current = null;
4126
4513
  this.player.manager.emit("queueUpdate" /* QueueUpdate */, this.player, this);
4127
4514
  this.player.manager.emit("debug" /* Debug */, 5 /* Queue */, "[Queue] -> [Clear] Cleared the queue.");
4515
+ await this.utils.save();
4128
4516
  return this;
4129
4517
  }
4130
4518
  /**
@@ -4132,15 +4520,31 @@ var Queue = class {
4132
4520
  * Move a track to a specific position in the queue.
4133
4521
  * @param {Track} track The track to move.
4134
4522
  * @param {number} to The position to move.
4135
- * @returns {this} The queue instance.
4523
+ * @returns {Promise<this>} The queue instance.
4524
+ * @example
4525
+ * ```ts
4526
+ * const queue = player.queue;
4527
+ * await queue.add(track);
4528
+ * await queue.add(track1);
4529
+ * await queue.add(track2);
4530
+ *
4531
+ * console.log(queue.tracks); // [track, track1, track2]
4532
+ * await queue.move(track1, 0);
4533
+ * console.log(queue.tracks); // [track1, track, track2]
4534
+ * ```
4136
4535
  */
4137
- move(track, to) {
4536
+ async move(track, to) {
4138
4537
  const index = this.tracks.indexOf(track);
4139
4538
  if (index === -1) return this;
4140
- this.splice(index, 1);
4141
- this.add(track, to - 1);
4539
+ await this.splice(index, 1);
4540
+ await this.add(track, to - 1);
4142
4541
  this.player.manager.emit("queueUpdate" /* QueueUpdate */, this.player, this);
4143
- this.player.manager.emit("debug" /* Debug */, 5 /* Queue */, `[Queue] -> [Move] Moved track ${track.info.title} to position ${to}.`);
4542
+ this.player.manager.emit(
4543
+ "debug" /* Debug */,
4544
+ 5 /* Queue */,
4545
+ `[Queue] -> [Move] Moved track ${track.info.title} to position ${to}.`
4546
+ );
4547
+ await this.utils.save();
4144
4548
  return this;
4145
4549
  }
4146
4550
  /**
@@ -4149,23 +4553,42 @@ var Queue = class {
4149
4553
  * @param {number} start The start index.
4150
4554
  * @param {number} deleteCount The number of tracks to delete.
4151
4555
  * @param {Track | Track[]} [tracks] The tracks to add.
4152
- * @returns {this} The queue instance.
4556
+ * @returns {Promise<this>} The queue instance.
4557
+ * @example
4558
+ * ```ts
4559
+ * const queue = player.queue;
4560
+ * await queue.add(track);
4561
+ * await queue.add(track1);
4562
+ * await queue.add(track2);
4563
+ *
4564
+ * console.log(queue.tracks); // [track, track1, track2]
4565
+ * await queue.splice(1, 1);
4566
+ * console.log(queue.tracks); // [track, track2]
4567
+ * ```
4153
4568
  */
4154
- splice(start, deleteCount, tracks) {
4155
- if (!this.size && tracks) this.add(tracks);
4569
+ async splice(start, deleteCount, tracks) {
4570
+ if (!this.size && tracks) await this.add(tracks);
4156
4571
  if (tracks) this.tracks.splice(start, deleteCount, ...Array.isArray(tracks) ? tracks : [tracks]);
4157
4572
  else this.tracks.splice(start, deleteCount);
4158
4573
  this.player.manager.emit("queueUpdate" /* QueueUpdate */, this.player, this);
4159
4574
  this.player.manager.emit("debug" /* Debug */, 5 /* Queue */, `[Queue] -> [Splice] Removed ${deleteCount} tracks from the queue.`);
4575
+ await this.utils.save();
4160
4576
  return this;
4161
4577
  }
4162
4578
  /**
4163
4579
  *
4164
4580
  * Convert the queue to a JSON object.
4165
4581
  * @returns {QueueJson} The queue JSON object.
4582
+ * @example
4583
+ * ```ts
4584
+ * const queue = player.queue;
4585
+ * await queue.add(track);
4586
+ *
4587
+ * console.log(queue.toJSON()); // { tracks: [track], history: [], current: null }
4588
+ * ```
4166
4589
  */
4167
4590
  toJSON() {
4168
- const max = this.player.manager.options.queueOptions.maxPreviousTracks;
4591
+ const max = this.player.manager.options.queueOptions.maxHistory;
4169
4592
  if (this.history.length > max) this.history.splice(max, this.history.length);
4170
4593
  return {
4171
4594
  tracks: this.tracks,
@@ -4204,7 +4627,7 @@ var Structures = {
4204
4627
  var maxTracks = 10;
4205
4628
  async function autoplayFn(player, lastTrack) {
4206
4629
  if (!lastTrack) return;
4207
- const isEnabled = !!player.data.get("enabledAutoplay") || player.manager.options.queueOptions.autoPlay;
4630
+ const isEnabled = !!await player.data.get("enabledAutoplay") || player.manager.options.queueOptions.autoPlay;
4208
4631
  if (!isEnabled) return;
4209
4632
  const filter = (tracks) => tracks.filter(
4210
4633
  (track) => !(player.queue.history.some((t) => t.info.identifier === track.info.identifier) || lastTrack.info.identifier === track.info.identifier)
@@ -4245,8 +4668,54 @@ async function autoplayFn(player, lastTrack) {
4245
4668
  }
4246
4669
  }
4247
4670
 
4248
- // src/classes/queue/adapters/memory.ts
4249
- var MemoryAdapter = class extends StorageAdapter {
4671
+ // src/classes/storage/PlayerMemory.ts
4672
+ var PlayerMemoryStorage = class extends PlayerStorageAdapter {
4673
+ /**
4674
+ * The internal storage.
4675
+ * @type {Map<K, V>}
4676
+ * @private
4677
+ * @readonly
4678
+ * @internal
4679
+ */
4680
+ internal = /* @__PURE__ */ new Map();
4681
+ get(key) {
4682
+ return this.internal.get(this.buildKey(this.namespace, key));
4683
+ }
4684
+ set(key, value) {
4685
+ this.internal.set(this.buildKey(this.namespace, key), value);
4686
+ }
4687
+ has(key) {
4688
+ return this.internal.has(this.buildKey(this.namespace, key));
4689
+ }
4690
+ delete(key) {
4691
+ return this.internal.delete(this.buildKey(this.namespace, key));
4692
+ }
4693
+ keys() {
4694
+ return [...this.internal.keys()];
4695
+ }
4696
+ values() {
4697
+ return [...this.internal.values()];
4698
+ }
4699
+ entries() {
4700
+ return [...this.internal.entries()];
4701
+ }
4702
+ all() {
4703
+ return Object.fromEntries([...this.internal.entries()].filter(([key]) => !key.startsWith("internal_")));
4704
+ }
4705
+ clear() {
4706
+ this.internal.clear();
4707
+ }
4708
+ size() {
4709
+ return this.internal.size;
4710
+ }
4711
+ buildKey(...parts) {
4712
+ const flattern = parts.flat();
4713
+ return flattern.join(":");
4714
+ }
4715
+ };
4716
+
4717
+ // src/classes/storage/QueueMemory.ts
4718
+ var QueueMemoryStorage = class extends QueueStorageAdapter {
4250
4719
  /**
4251
4720
  * Memory storage.
4252
4721
  * @type {Map<string, QueueJson>}
@@ -4259,16 +4728,16 @@ var MemoryAdapter = class extends StorageAdapter {
4259
4728
  return this.parse(this.storage.get(key));
4260
4729
  }
4261
4730
  set(key, value) {
4262
- this.storage.set(key, this.stringify(value));
4731
+ this.storage.set(this.buildKey(this.namespace, key), this.stringify(value));
4263
4732
  }
4264
4733
  delete(key) {
4265
- return this.storage.delete(key);
4734
+ return this.storage.delete(this.buildKey(this.namespace, key));
4266
4735
  }
4267
4736
  clear() {
4268
4737
  this.storage.clear();
4269
4738
  }
4270
4739
  has(key) {
4271
- return this.storage.has(key);
4740
+ return this.storage.has(this.buildKey(this.namespace, key));
4272
4741
  }
4273
4742
  parse(value) {
4274
4743
  return value;
@@ -4276,6 +4745,10 @@ var MemoryAdapter = class extends StorageAdapter {
4276
4745
  stringify(value) {
4277
4746
  return value;
4278
4747
  }
4748
+ buildKey(...parts) {
4749
+ const flattern = parts.flat();
4750
+ return flattern.join(":");
4751
+ }
4279
4752
  };
4280
4753
 
4281
4754
  // src/classes/Hoshimi.ts
@@ -4306,6 +4779,7 @@ var Hoshimi = class extends import_node_events.EventEmitter {
4306
4779
  * The constructor for the manager.
4307
4780
  * @param {HoshimiOptions} options The options for the manager.
4308
4781
  * @throws {ManagerError} If the options are not provided.
4782
+ * @throws {OptionError} If the options are invalid.
4309
4783
  * @example
4310
4784
  * ```ts
4311
4785
  * const manager = new Hoshimi({
@@ -4331,10 +4805,24 @@ var Hoshimi = class extends import_node_events.EventEmitter {
4331
4805
  * resumeByLibrary: false,
4332
4806
  * },
4333
4807
  * queueOptions: {
4334
- * maxPreviousTracks: 25,
4335
- * autoplayFn: autoplayFn,
4336
- * autoPlay: false,
4808
+ * maxHistory: 25,
4809
+ * autoplayFn: autoplayFn,
4810
+ * autoPlay: false,
4811
+ * storage: new MemoryAdapter(),
4812
+ * requesterFn: defaultRequesterFn,
4337
4813
  * },
4814
+ * playerOptions: {
4815
+ * onDisconnect: {
4816
+ * autoDestroy: false,
4817
+ * autoReconnect: false,
4818
+ * autoQueue: false,
4819
+ * },
4820
+ * onError: {
4821
+ * autoDestroy: false,
4822
+ * autoSkip: false,
4823
+ * autoStop: false,
4824
+ * },
4825
+ * },
4338
4826
  * });
4339
4827
  *
4340
4828
  * console.log(manager); // The manager instance
@@ -4356,10 +4844,24 @@ var Hoshimi = class extends import_node_events.EventEmitter {
4356
4844
  resumeTimeout: options.nodeOptions?.resumeTimeout ?? 1e4
4357
4845
  },
4358
4846
  queueOptions: {
4359
- maxPreviousTracks: options.queueOptions?.maxPreviousTracks ?? 25,
4847
+ maxHistory: options.queueOptions?.maxHistory ?? 25,
4360
4848
  autoplayFn: options.queueOptions?.autoplayFn ?? autoplayFn,
4361
4849
  autoPlay: options.queueOptions?.autoPlay ?? false,
4362
- storage: options.queueOptions?.storage ?? new MemoryAdapter()
4850
+ storage: options.queueOptions?.storage ?? new QueueMemoryStorage()
4851
+ },
4852
+ playerOptions: {
4853
+ requesterFn: options.playerOptions?.requesterFn ?? requesterFn,
4854
+ storage: options.playerOptions?.storage ?? new PlayerMemoryStorage(),
4855
+ onDisconnect: {
4856
+ autoDestroy: options.playerOptions?.onDisconnect?.autoDestroy ?? false,
4857
+ autoReconnect: options.playerOptions?.onDisconnect?.autoReconnect ?? false,
4858
+ autoQueue: options.playerOptions?.onDisconnect?.autoQueue ?? false
4859
+ },
4860
+ onError: {
4861
+ autoDestroy: options.playerOptions?.onError?.autoDestroy ?? false,
4862
+ autoSkip: options.playerOptions?.onError?.autoSkip ?? false,
4863
+ autoStop: options.playerOptions?.onError?.autoStop ?? false
4864
+ }
4363
4865
  },
4364
4866
  client: {
4365
4867
  id: options.client?.id ?? "",
@@ -4471,37 +4973,98 @@ var Hoshimi = class extends import_node_events.EventEmitter {
4471
4973
  this.emit("debug" /* Debug */, 3 /* Player */, "[Player] -> [Voice] The guild id is missing.");
4472
4974
  return;
4473
4975
  }
4474
- if ("user_id" in data && data.user_id !== this.options.client?.id) {
4475
- this.emit("debug" /* Debug */, 3 /* Player */, "[Player] -> [Voice] The user id does not match the client id.");
4476
- return;
4477
- }
4478
4976
  const player = this.getPlayer(data.guild_id);
4479
4977
  if (!player) {
4480
4978
  this.emit("debug" /* Debug */, 3 /* Player */, "[Player] -> [Voice] The player is not found.");
4481
4979
  return;
4482
4980
  }
4483
4981
  if ("session_id" in data) player.voice.sessionId = data.session_id;
4484
- if ("token" in data) player.voice.token = data.token;
4485
- if ("endpoint" in data) player.voice.endpoint = data.endpoint;
4486
- if (player.voice.sessionId && player.voice.token && player.voice.endpoint) {
4487
- await player.node.updatePlayer({
4488
- guildId: data.guild_id,
4982
+ if ("token" in data && "endpoint" in data) {
4983
+ if (!player.voice.sessionId) {
4984
+ this.emit(
4985
+ "debug" /* Debug */,
4986
+ 3 /* Player */,
4987
+ `[Player] -> [Voice] The session id is missing for: ${data.guild_id}`
4988
+ );
4989
+ return;
4990
+ }
4991
+ await player.updatePlayer({
4489
4992
  playerOptions: {
4490
- voice: player.voice
4993
+ voice: {
4994
+ sessionId: player.voice.sessionId,
4995
+ token: data.token,
4996
+ endpoint: data.endpoint
4997
+ }
4491
4998
  }
4492
4999
  });
4493
5000
  this.emit(
4494
5001
  "debug" /* Debug */,
4495
5002
  3 /* Player */,
4496
- `[Player] -> [Voice] Updated the player voice for: ${data.guild_id} | Session: ${player.voice.sessionId} | Token: ${player.voice.token} | Endpoint: ${player.voice.endpoint}`
5003
+ `[Player] -> [Voice] Updated the player voice for: ${data.guild_id} | Session: ${player.voice.sessionId} | Token: ${data.token} | Endpoint: ${data.endpoint}`
4497
5004
  );
4498
5005
  return;
4499
5006
  }
4500
- this.emit("debug" /* Debug */, 3 /* Player */, `[Player] -> [Voice] The player voice is missing for: ${data.guild_id}`);
5007
+ if (data.user_id !== this.options.client.id) {
5008
+ this.emit("debug" /* Debug */, 3 /* Player */, "[Player] -> [Voice] The user id does not match the client id.");
5009
+ return;
5010
+ }
5011
+ if (data.channel_id !== null) {
5012
+ const voiceId = player.voiceId ?? player.options.voiceId;
5013
+ if (data.channel_id !== voiceId) {
5014
+ this.emit(
5015
+ "debug" /* Debug */,
5016
+ 3 /* Player */,
5017
+ `[Player] -> [Voice] Updating the voice channel for: ${data.guild_id} | Old: ${voiceId} | New: ${data.channel_id}`
5018
+ );
5019
+ player.voice.sessionId = data.session_id ?? player.voice.sessionId;
5020
+ player.voiceId = data.channel_id;
5021
+ player.options.voiceId = data.channel_id;
5022
+ if (!player.connected) await player.connect();
5023
+ return;
5024
+ }
5025
+ } else {
5026
+ this.emit(
5027
+ "debug" /* Debug */,
5028
+ 3 /* Player */,
5029
+ `[Player] -> [Voice] The channel id is missing for: ${data.guild_id}`
5030
+ );
5031
+ const { autoDestroy, autoReconnect, autoQueue } = this.options.playerOptions.onDisconnect;
5032
+ if (autoDestroy) {
5033
+ await player.destroy("Player-VoiceChannelLeft" /* VoiceChannelLeft */);
5034
+ return;
5035
+ }
5036
+ if (autoReconnect) {
5037
+ try {
5038
+ const position = player.position;
5039
+ const paused = player.paused;
5040
+ this.emit(
5041
+ "debug" /* Debug */,
5042
+ 3 /* Player */,
5043
+ `[Player] -> [Voice] Attempting to reconnect the player for: ${data.guild_id}`
5044
+ );
5045
+ if (autoQueue && player.queue.current && !player.queue.isEmpty()) await player.connect();
5046
+ if (player.queue.current) return player.play({ track: player.queue.current, paused, position });
5047
+ if (!player.queue.isEmpty()) return player.play({ paused });
5048
+ this.emit(
5049
+ "debug" /* Debug */,
5050
+ 3 /* Player */,
5051
+ `[Player] -> [Voice] No tracks to play after reconnect for: ${data.guild_id}`
5052
+ );
5053
+ } catch (error) {
5054
+ this.emit("playerError" /* PlayerError */, player, error);
5055
+ await player.destroy("Player-ReconnectFailed" /* ReconnectFailed */);
5056
+ }
5057
+ }
5058
+ player.voiceId = void 0;
5059
+ player.voice = {
5060
+ endpoint: null,
5061
+ sessionId: null,
5062
+ token: null
5063
+ };
5064
+ return;
5065
+ }
4501
5066
  }
4502
5067
  break;
4503
- default:
4504
- break;
4505
5068
  }
4506
5069
  }
4507
5070
  /**
@@ -4606,6 +5169,7 @@ var Hoshimi = class extends import_node_events.EventEmitter {
4606
5169
  1 /* Manager */,
4607
5170
  `[Manager] -> [Search] Searching for: ${options.query} (${options.engine ?? "unknown"}) | Result: ${stringify(res)}`
4608
5171
  );
5172
+ const requesterFn2 = this.options.playerOptions.requesterFn;
4609
5173
  switch (res.loadType) {
4610
5174
  case "empty" /* Empty */: {
4611
5175
  return {
@@ -4631,7 +5195,7 @@ var Hoshimi = class extends import_node_events.EventEmitter {
4631
5195
  exception: null,
4632
5196
  playlist: res.data,
4633
5197
  pluginInfo: res.data.pluginInfo,
4634
- tracks: res.data.tracks.map((t) => new Track(t, options.requester))
5198
+ tracks: res.data.tracks.map((t) => new Track(t, requesterFn2(options.requester)))
4635
5199
  };
4636
5200
  }
4637
5201
  case "search" /* Search */: {
@@ -4640,7 +5204,7 @@ var Hoshimi = class extends import_node_events.EventEmitter {
4640
5204
  exception: null,
4641
5205
  playlist: null,
4642
5206
  pluginInfo: null,
4643
- tracks: res.data.map((t) => new Track(t, options.requester))
5207
+ tracks: res.data.map((t) => new Track(t, requesterFn2(options.requester)))
4644
5208
  };
4645
5209
  }
4646
5210
  case "track" /* Track */: {
@@ -4649,7 +5213,7 @@ var Hoshimi = class extends import_node_events.EventEmitter {
4649
5213
  exception: null,
4650
5214
  playlist: null,
4651
5215
  pluginInfo: res.data.pluginInfo,
4652
- tracks: [new Track(res.data, options.requester)]
5216
+ tracks: [new Track(res.data, requesterFn2(options.requester))]
4653
5217
  };
4654
5218
  }
4655
5219
  }
@@ -4661,45 +5225,56 @@ function createHoshimi(...args) {
4661
5225
  // Annotate the CommonJS export names for ESM import in node:
4662
5226
  0 && (module.exports = {
4663
5227
  AudioOutput,
5228
+ AudioOutputData,
4664
5229
  DSPXPluginFilter,
4665
5230
  DebugLevels,
5231
+ DefaultFilterPreset,
5232
+ DefaultPlayerFilters,
4666
5233
  DestroyReasons,
4667
- Events,
5234
+ EventNames,
4668
5235
  FilterManager,
4669
5236
  FilterType,
4670
5237
  Hoshimi,
5238
+ HoshimiAgent,
4671
5239
  HttpMethods,
4672
5240
  HttpStatusCodes,
4673
5241
  LavalinkPluginFilter,
4674
5242
  LoadType,
4675
5243
  LoopMode,
4676
5244
  ManagerError,
4677
- MemoryAdapter,
4678
5245
  Node,
4679
5246
  NodeDestroyReasons,
4680
5247
  NodeError,
5248
+ NodeManagerError,
4681
5249
  NodeSortTypes,
4682
5250
  OpCodes,
4683
5251
  OptionError,
4684
5252
  Player,
4685
5253
  PlayerError,
4686
5254
  PlayerEventType,
5255
+ PlayerMemoryStorage,
5256
+ PlayerStorageAdapter,
4687
5257
  PluginInfoType,
4688
5258
  PluginNames,
4689
5259
  Queue,
5260
+ QueueMemoryStorage,
5261
+ QueueStorageAdapter,
4690
5262
  ResolveError,
4691
5263
  Rest,
4692
5264
  RestPathType,
5265
+ RestRoutes,
4693
5266
  SearchEngines,
4694
5267
  Severity,
4695
5268
  SourceNames,
4696
5269
  State,
4697
- StorageAdapter,
4698
5270
  StorageError,
4699
5271
  Structures,
4700
5272
  Track,
4701
5273
  TrackEndReason,
4702
5274
  UnresolvedTrack,
5275
+ UrlRegex,
5276
+ ValidEngines,
5277
+ ValidSources,
4703
5278
  WebsocketCloseCodes,
4704
5279
  createHoshimi
4705
5280
  });