magmastream
Advanced tools
Comparing version 2.7.3 to 2.7.4
@@ -5,3 +5,2 @@ "use strict"; | ||
const tslib_1 = require("tslib"); | ||
/* eslint-disable no-async-promise-executor */ | ||
const Utils_1 = require("./Utils"); | ||
@@ -95,8 +94,3 @@ const collection_1 = require("@discordjs/collection"); | ||
if (!lavaPlayer.state.connected) { | ||
try { | ||
player.connect(); | ||
} | ||
catch (error) { | ||
continue; | ||
} | ||
player.connect(); | ||
} | ||
@@ -333,69 +327,36 @@ const tracks = []; | ||
} | ||
lastSaveTimes = new Map(); | ||
eventBatchInterval = null; | ||
eventBatchDuration = 1000; | ||
latestPlayerStates = new Map(); | ||
/** | ||
* Registers the events that trigger saving player states. | ||
* @private | ||
* Handles the shutdown of the process by saving all active players' states and optionally cleaning up inactive players. | ||
* This function is called when the process is about to exit. | ||
* It iterates through all players and calls {@link savePlayerState} to save their states. | ||
* Optionally, it also calls {@link cleanupInactivePlayers} to remove any stale player state files. | ||
* After saving and cleaning up, it exits the process. | ||
*/ | ||
registerPlayerStateEvents() { | ||
// The events to listen for | ||
const events = [ | ||
// The player state has been updated | ||
ManagerEventTypes.PlayerStateUpdate, | ||
// The player has been destroyed | ||
ManagerEventTypes.PlayerDestroy, | ||
]; | ||
// Register the events | ||
for (const event of events) { | ||
// Call the collectPlayerStateEvent function when the event is emitted | ||
this.on(event, (player) => this.collectPlayerStateEvent(event, player)); | ||
async handleShutdown() { | ||
console.warn("\x1b[31m%s\x1b[0m", "MAGMASTREAM WARNING: Shutting down! Please wait, saving active players..."); | ||
// Create an array of promises for saving player states | ||
const savePromises = Array.from(this.players.keys()).map((guildId) => { | ||
return new Promise((resolve) => { | ||
try { | ||
this.savePlayerState(guildId); | ||
resolve(); // Resolve immediately after calling savePlayerState | ||
} | ||
catch (error) { | ||
console.error(`Error saving player state for guild ${guildId}:`, error); | ||
throw error; | ||
} | ||
}); | ||
}); | ||
// Wait for all save operations to complete and check for errors | ||
const results = await Promise.allSettled(savePromises); | ||
const errors = results.filter((result) => result.status === "rejected"); | ||
if (errors.length > 0) { | ||
console.error("`\x1b[31m%s\x1b[0m", `MAGMASTREAM ERROR: ${errors.length} player states failed to save.`); | ||
} | ||
// Clean up inactive players here | ||
this.cleanupInactivePlayers(); | ||
console.warn("\x1b[32m%s\x1b[0m", "MAGMASTREAM INFO: Shutting down complete, exiting..."); | ||
setTimeout(() => process.exit(errors.length > 0 ? 1 : 0), 100); | ||
} | ||
/** | ||
* Collects player state events and stores them in memory. | ||
* This function is called whenever a player state event is emitted. | ||
* It stores the latest player state for each guild in the {@link latestPlayerStates} map. | ||
* If the event is "playerDestroy", it removes the player from the map and deletes the last save time for the guild. | ||
* @param event The event that triggered this function. | ||
* @param player The player that emitted the event. | ||
*/ | ||
collectPlayerStateEvent(event, player) { | ||
if (event === "playerDestroy") { | ||
// Remove the player from the map and delete the last save time for the guild | ||
this.lastSaveTimes.delete(player.guild); | ||
this.players.delete(player.guild); | ||
this.cleanupInactivePlayers(); | ||
} | ||
else if (event === "playerStateUpdate") { | ||
// Store the latest player state for the guild | ||
this.latestPlayerStates.set(player.guild, player); | ||
} | ||
// Start the batch timer if it's not already running | ||
if (!this.eventBatchInterval) { | ||
// Set the timer to process the batch events after the specified duration | ||
this.eventBatchInterval = setTimeout(() => this.processBatchEvents(), this.eventBatchDuration); | ||
} | ||
} | ||
/** | ||
* Processes the collected player state events | ||
* This function is called when the batch timer expires and it clears the timer | ||
* It saves the latest player states for each guild in the `latestPlayerStates` map | ||
* It then clears the map after processing | ||
*/ | ||
processBatchEvents() { | ||
if (this.eventBatchInterval) { | ||
// Clear the timer so it doesn't interfere with the next batch | ||
clearTimeout(this.eventBatchInterval); | ||
this.eventBatchInterval = null; | ||
} | ||
// Save the latest player states for each guild in a single write operation | ||
this.latestPlayerStates.forEach((player, guildId) => { | ||
this.savePlayerState(guildId); | ||
}); | ||
// Clear the latest player states after processing | ||
this.latestPlayerStates.clear(); | ||
} | ||
/** | ||
* Initiates the Manager class. | ||
@@ -417,3 +378,4 @@ * @param options | ||
super(); | ||
this.registerPlayerStateEvents(); | ||
process.on("SIGINT", async () => await this.handleShutdown()); | ||
process.on("SIGTERM", async () => await this.handleShutdown()); | ||
(0, managerCheck_1.default)(options); | ||
@@ -420,0 +382,0 @@ Utils_1.Structure.get("Player").init(this); |
@@ -643,3 +643,4 @@ "use strict"; | ||
catch (error) { | ||
return false; | ||
if (error) | ||
return false; | ||
} | ||
@@ -646,0 +647,0 @@ if (response.data.error || !response.data.similartracks?.track?.length) { |
@@ -298,6 +298,10 @@ "use strict"; | ||
(function (TrackSourceTypes) { | ||
TrackSourceTypes["Spotify"] = "spotify"; | ||
TrackSourceTypes["AppleMusic"] = "applemusic"; | ||
TrackSourceTypes["Bandcamp"] = "bandcamp"; | ||
TrackSourceTypes["Deezer"] = "deezer"; | ||
TrackSourceTypes["Jiosaavn"] = "jiosaavn"; | ||
TrackSourceTypes["SoundCloud"] = "soundcloud"; | ||
TrackSourceTypes["Spotify"] = "spotify"; | ||
TrackSourceTypes["Tidal"] = "tidal"; | ||
TrackSourceTypes["YouTube"] = "youtube"; | ||
})(TrackSourceTypes || (exports.TrackSourceTypes = TrackSourceTypes = {})); |
{ | ||
"name": "magmastream", | ||
"version": "2.7.3", | ||
"version": "2.7.4", | ||
"description": "A user-friendly Lavalink client designed for NodeJS.", | ||
@@ -13,13 +13,13 @@ "main": "dist/index.js", | ||
"types": "rtb --dist dist", | ||
"lint": "eslint --ext .ts ./src", | ||
"lint": "eslint src", | ||
"ci": "run-s lint build types" | ||
}, | ||
"devDependencies": { | ||
"@favware/rollup-type-bundler": "^3.3.0", | ||
"@favware/rollup-type-bundler": "^4.0.0", | ||
"@types/lodash": "^4.17.14", | ||
"@types/node": "^20.17.12", | ||
"@types/node": "^22.10.7", | ||
"@types/ws": "^8.5.13", | ||
"@typescript-eslint/eslint-plugin": "^7.18.0", | ||
"@typescript-eslint/parser": "^7.18.0", | ||
"eslint": "^8.57.1", | ||
"@typescript-eslint/eslint-plugin": "^8.21.0", | ||
"@typescript-eslint/parser": "^8.21.0", | ||
"eslint": "^9.18.0", | ||
"npm-run-all": "^4.1.5", | ||
@@ -26,0 +26,0 @@ "typedoc": "^0.27.6", |
@@ -0,0 +0,0 @@ <p align="center"> |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
270179
5964