magmastream 2.10.2-alpha.4 → 2.10.2-alpha.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.
@@ -143,13 +143,13 @@ export declare class Manager extends EventEmitter {
143
143
  */
144
144
  get useableNode(): Node;
145
145
  /**
146
- * Handles the shutdown of the process by saving all active players' states and optionally cleaning up inactive players.
146
+ * Handles the shutdown of the process by saving all active players' states.
147
147
  * This function is called when the process is about to exit.
148
148
  * It iterates through all players and calls {@link savePlayerState} to save their states.
149
- * Optionally, it also calls {@link cleanupInactivePlayers} to remove any stale player state files.
150
- * After saving and cleaning up, it exits the process.
149
+ * After saving, it exits the process.
150
+ * @param stopProcess - A function to stop the process.
151
151
  */
152
- handleShutdown(): Promise<void>;
152
+ handleShutdown(stopProcess?: () => Promise<void>): Promise<void>;
153
153
  /**
154
154
  * Parses a YouTube title into a clean title and author.
155
155
  * @param title - The original title of the YouTube video.
@@ -736,13 +736,13 @@ class Manager extends events_1.EventEmitter {
736
736
  return this.options.enablePriorityMode ? this.priorityNode : this.options.useNode === Enums_1.UseNodeOptions.LeastLoad ? this.leastLoadNode.first() : this.leastPlayersNode.first();
737
737
  }
738
738
  /**
739
- * Handles the shutdown of the process by saving all active players' states and optionally cleaning up inactive players.
739
+ * Handles the shutdown of the process by saving all active players' states.
740
740
  * This function is called when the process is about to exit.
741
741
  * It iterates through all players and calls {@link savePlayerState} to save their states.
742
- * Optionally, it also calls {@link cleanupInactivePlayers} to remove any stale player state files.
743
- * After saving and cleaning up, it exits the process.
742
+ * After saving, it exits the process.
743
+ * @param stopProcess - A function to stop the process.
744
744
  */
745
- async handleShutdown() {
745
+ async handleShutdown(stopProcess) {
746
746
  this.unloadPlugins();
747
747
  console.warn("\x1b[31m%s\x1b[0m", "MAGMASTREAM WARNING: Shutting down! Please wait, saving active players...");
748
748
  try {
@@ -763,9 +763,12 @@ class Manager extends events_1.EventEmitter {
763
763
  }
764
764
  });
765
765
  await Promise.allSettled(savePromises);
766
- setTimeout(() => {
766
+ setTimeout(async () => {
767
767
  console.warn("\x1b[32m%s\x1b[0m", "MAGMASTREAM INFO: Shutting down complete, exiting...");
768
- process.exit(0);
768
+ if (stopProcess)
769
+ await stopProcess();
770
+ else
771
+ process.exit(0);
769
772
  }, 500);
770
773
  }
771
774
  catch (err) {
@@ -5,8 +5,6 @@ import { LavalinkSession, LavaPlayer, RestPlayOptions } from "./Types";
5
5
  export declare class Rest {
6
6
  /** The Node that this Rest instance is connected to. */
7
7
  private node;
8
- /** The ID of the current session. */
9
- private sessionId;
10
8
  /** The password for the Node. */
11
9
  private readonly password;
12
10
  /** The URL of the Node. */
@@ -16,6 +14,11 @@ export declare class Rest {
16
14
  /** Whether the node is a NodeLink. */
17
15
  isNodeLink: boolean;
18
16
  constructor(node: Node, manager: Manager);
17
+ /**
18
+ * Gets the session ID.
19
+ * @returns {string} Returns the session ID.
20
+ */
21
+ private get sessionId();
19
22
  /**
20
23
  * Sets the session ID.
21
24
  * This method is used to set the session ID after a resume operation is done.
@@ -10,8 +10,6 @@ const MagmastreamError_1 = require("./MagmastreamError");
10
10
  class Rest {
11
11
  /** The Node that this Rest instance is connected to. */
12
12
  node;
13
- /** The ID of the current session. */
14
- sessionId;
15
13
  /** The password for the Node. */
16
14
  password;
17
15
  /** The URL of the Node. */
@@ -23,11 +21,17 @@ class Rest {
23
21
  constructor(node, manager) {
24
22
  this.node = node;
25
23
  this.url = `http${node.options.useSSL ? "s" : ""}://${node.options.host}:${node.options.port}`;
26
- this.sessionId = node.sessionId;
27
24
  this.password = node.options.password;
28
25
  this.manager = manager;
29
26
  this.isNodeLink = node.isNodeLink;
30
27
  }
28
+ /**
29
+ * Gets the session ID.
30
+ * @returns {string} Returns the session ID.
31
+ */
32
+ get sessionId() {
33
+ return this.node.sessionId;
34
+ }
31
35
  /**
32
36
  * Sets the session ID.
33
37
  * This method is used to set the session ID after a resume operation is done.
@@ -35,8 +39,8 @@ class Rest {
35
39
  * @returns {string} Returns the set session ID.
36
40
  */
37
41
  setSessionId(sessionId) {
38
- this.sessionId = sessionId;
39
- return this.sessionId;
42
+ this.node.sessionId = sessionId;
43
+ return this.node.sessionId;
40
44
  }
41
45
  /**
42
46
  * Retrieves the player that is currently running on the node.
@@ -44,6 +48,10 @@ class Rest {
44
48
  * @returns {Promise<LavaPlayer>} Returns the player.
45
49
  */
46
50
  async getPlayer(guildId) {
51
+ if (!this.sessionId) {
52
+ this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[REST] Skipping getPlayer for ${guildId} - no session ID on node ${this.node.options.identifier}`);
53
+ return null;
54
+ }
47
55
  const result = await this.get(`/v4/sessions/${this.sessionId}/players/${guildId}`);
48
56
  this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[REST] Getting player on node: ${this.node.options.identifier} : ${Utils_1.JSONUtils.safe(result, 2)}`);
49
57
  return result;
@@ -54,6 +62,10 @@ class Rest {
54
62
  * @returns {Promise<LavaPlayer>} Returns the updated player.
55
63
  */
56
64
  async updatePlayer(options) {
65
+ if (!this.sessionId) {
66
+ this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[REST] Skipping updatePlayer for guildId: ${options.guildId} - no session ID on node ${this.node.options.identifier}`);
67
+ return null;
68
+ }
57
69
  this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[REST] Updating player: ${options.guildId}: ${Utils_1.JSONUtils.safe(options, 2)}`);
58
70
  return await this.patch(`/v4/sessions/${this.sessionId}/players/${options.guildId}?noReplace=${options.noReplace ?? false}`, options.data);
59
71
  }
@@ -63,6 +75,10 @@ class Rest {
63
75
  * @returns {Promise<void>} Returns void (204 No Content).
64
76
  */
65
77
  async destroyPlayer(guildId) {
78
+ if (!this.sessionId) {
79
+ this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[REST] Skipping destroyPlayer for guildId: ${guildId} - no session ID on node ${this.node.options.identifier}`);
80
+ return;
81
+ }
66
82
  this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[REST] Destroying player: ${guildId}`);
67
83
  return await this.delete(`/v4/sessions/${this.sessionId}/players/${guildId}`);
68
84
  }
@@ -73,6 +89,10 @@ class Rest {
73
89
  * @returns {Promise<LavalinkSession>} The updated session.
74
90
  */
75
91
  async updateSession(resuming, timeout) {
92
+ if (!this.sessionId) {
93
+ this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[REST] Skipping updateSession for resuming: ${resuming} timeout: ${timeout} - no session ID on node ${this.node.options.identifier}`);
94
+ return null;
95
+ }
76
96
  this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[REST] Updating session: ${this.sessionId}`);
77
97
  return await this.patch(`/v4/sessions/${this.sessionId}`, { resuming, timeout });
78
98
  }
@@ -115,9 +135,16 @@ class Rest {
115
135
  if (status >= 200 && status < 300) {
116
136
  return data;
117
137
  }
118
- // Lavalink sometimes returns "Guild not found" for inactive players
119
- if (status === 404 && data?.message === "Guild not found") {
120
- return [];
138
+ if (status === 404) {
139
+ if (data?.message === "Guild not found") {
140
+ // Lavalink sometimes returns "Guild not found" for inactive players
141
+ return [];
142
+ }
143
+ if (data?.message === "Session not found") {
144
+ // Session expired — trigger reconnection instead of crashing
145
+ this.manager.emit(Enums_1.ManagerEventTypes.NodeError, this.node, new MagmastreamError_1.MagmaStreamError({ code: Enums_1.MagmaStreamErrorCode.REST_REQUEST_FAILED, message: "Session not found" }));
146
+ return [];
147
+ }
121
148
  }
122
149
  const message = typeof data === "string"
123
150
  ? data
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "magmastream",
3
- "version": "2.10.2-alpha.4",
3
+ "version": "2.10.2-alpha.6",
4
4
  "description": "A user-friendly Lavalink client designed for NodeJS.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -16,8 +16,8 @@
16
16
  "lint": "eslint \"src/**/*.{ts,js}\"",
17
17
  "lint:fix": "eslint --fix \"src/**/*.{ts,js}\"",
18
18
  "ci": "run-s format:check lint build types",
19
- "release:alpha": "npm run format && npm run lint:fix && npm run ci && npm version prerelease --preid=alpha && npm publish --tag alpha && git push && git push --tags",
20
- "release:dev": "npm run format && npm run lint:fix && npm run ci && npm version prerelease --preid=dev && npm publish --tag dev && git push && git push --tags"
19
+ "release:alpha": "npm run format && npm run lint:fix && npm run ci && npm version prerelease --preid=alpha && npm publish --tag alpha && git push && git push --follow-tags",
20
+ "release:dev": "npm run format && npm run lint:fix && npm run ci && npm version prerelease --preid=dev && npm publish --tag dev && git push && git push --follow-tags"
21
21
  },
22
22
  "devDependencies": {
23
23
  "@favware/rollup-type-bundler": "^4.0.0",