magmastream 2.9.3-dev.23 → 2.9.3-dev.24

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.d.ts CHANGED
@@ -915,6 +915,10 @@ interface ManagerOptions {
915
915
  * @default UseNodeOptions.LeastPlayers
916
916
  */
917
917
  useNode?: UseNodeOptions.LeastLoad | UseNodeOptions.LeastPlayers;
918
+ /** Whether the manager should listen to SIGINT and SIGTERM events.
919
+ * @default true
920
+ */
921
+ listenToSIGEvents?: boolean;
918
922
  /**
919
923
  * Function to send data to the websocket.
920
924
  * @param id The ID of the node to send the data to.
@@ -3151,6 +3155,7 @@ declare class Manager extends EventEmitter {
3151
3155
  private get priorityNode();
3152
3156
  protected send(packet: GatewayVoiceStateUpdate): unknown;
3153
3157
  protected getUserFromCache(id: string): AnyUser | undefined;
3158
+ protected getGuildFromCache(id: string): AnyGuild | undefined;
3154
3159
  sendPacket(packet: GatewayVoiceStateUpdate): unknown;
3155
3160
  /**
3156
3161
  * Resolves a PortableUser or ID to a real user object.
@@ -3703,6 +3708,7 @@ declare class DiscordenoManager extends Manager {
3703
3708
  * Uses user-provided cache getter if available, otherwise falls back to minimal info.
3704
3709
  */
3705
3710
  resolveUser(user: AnyUser | string): Promise<User$2 | AnyUser>;
3711
+ resolveGuild(guildId: string): AnyGuild;
3706
3712
  }
3707
3713
 
3708
3714
  /**
@@ -95,6 +95,7 @@ class Manager extends events_1.EventEmitter {
95
95
  deleteDestroyedPlayers: options.stateStorage?.deleteDestroyedPlayers ?? true,
96
96
  },
97
97
  autoPlaySearchPlatforms: options.autoPlaySearchPlatforms ?? [Enums_1.AutoPlayPlatform.YouTube],
98
+ listenToSIGEvents: options.listenToSIGEvents ?? true,
98
99
  send: this._send,
99
100
  };
100
101
  Utils_1.AutoPlayUtils.init(this);
@@ -102,49 +103,51 @@ class Manager extends events_1.EventEmitter {
102
103
  for (const nodeOptions of this.options.nodes)
103
104
  new Node_1.Node(this, nodeOptions);
104
105
  }
105
- process.on("SIGINT", async () => {
106
- console.warn("\x1b[33mSIGINT received! Graceful shutdown initiated...\x1b[0m");
107
- try {
108
- await this.handleShutdown();
109
- console.warn("\x1b[32mShutdown complete. Waiting for Node.js event loop to empty...\x1b[0m");
110
- // Prevent forced exit by Windows
111
- setTimeout(() => {
106
+ if (this.options.listenToSIGEvents) {
107
+ process.on("SIGINT", async () => {
108
+ console.warn("\x1b[33mSIGINT received! Graceful shutdown initiated...\x1b[0m");
109
+ try {
110
+ await this.handleShutdown();
111
+ console.warn("\x1b[32mShutdown complete. Waiting for Node.js event loop to empty...\x1b[0m");
112
+ // Prevent forced exit by Windows
113
+ setTimeout(() => {
114
+ process.exit(0);
115
+ }, 2000);
116
+ }
117
+ catch (err) {
118
+ const error = err instanceof MagmastreamError_1.MagmaStreamError
119
+ ? err
120
+ : new MagmastreamError_1.MagmaStreamError({
121
+ code: Enums_1.MagmaStreamErrorCode.MANAGER_SHUTDOWN_FAILED,
122
+ message: "An unknown error occurred.",
123
+ cause: err,
124
+ context: { stage: "SIGINT" },
125
+ });
126
+ console.error(error);
127
+ process.exit(1);
128
+ }
129
+ });
130
+ process.on("SIGTERM", async () => {
131
+ console.warn("\x1b[33mSIGTERM received! Graceful shutdown initiated...\x1b[0m");
132
+ try {
133
+ await this.handleShutdown();
134
+ console.warn("\x1b[32mShutdown complete. Exiting now...\x1b[0m");
112
135
  process.exit(0);
113
- }, 2000);
114
- }
115
- catch (err) {
116
- const error = err instanceof MagmastreamError_1.MagmaStreamError
117
- ? err
118
- : new MagmastreamError_1.MagmaStreamError({
119
- code: Enums_1.MagmaStreamErrorCode.MANAGER_SHUTDOWN_FAILED,
120
- message: "An unknown error occurred.",
121
- cause: err,
122
- context: { stage: "SIGINT" },
123
- });
124
- console.error(error);
125
- process.exit(1);
126
- }
127
- });
128
- process.on("SIGTERM", async () => {
129
- console.warn("\x1b[33mSIGTERM received! Graceful shutdown initiated...\x1b[0m");
130
- try {
131
- await this.handleShutdown();
132
- console.warn("\x1b[32mShutdown complete. Exiting now...\x1b[0m");
133
- process.exit(0);
134
- }
135
- catch (err) {
136
- const error = err instanceof MagmastreamError_1.MagmaStreamError
137
- ? err
138
- : new MagmastreamError_1.MagmaStreamError({
139
- code: Enums_1.MagmaStreamErrorCode.MANAGER_SHUTDOWN_FAILED,
140
- message: "An unknown error occurred.",
141
- cause: err,
142
- context: { stage: "SIGTERM" },
143
- });
144
- console.error(error);
145
- process.exit(1);
146
- }
147
- });
136
+ }
137
+ catch (err) {
138
+ const error = err instanceof MagmastreamError_1.MagmaStreamError
139
+ ? err
140
+ : new MagmastreamError_1.MagmaStreamError({
141
+ code: Enums_1.MagmaStreamErrorCode.MANAGER_SHUTDOWN_FAILED,
142
+ message: "An unknown error occurred.",
143
+ cause: err,
144
+ context: { stage: "SIGTERM" },
145
+ });
146
+ console.error(error);
147
+ process.exit(1);
148
+ }
149
+ });
150
+ }
148
151
  }
149
152
  /**
150
153
  * Initiates the Manager.
@@ -527,10 +530,10 @@ class Manager extends events_1.EventEmitter {
527
530
  });
528
531
  // Read guild directories inside players base dir
529
532
  const guildDirs = await promises_1.default.readdir(playersBaseDir, { withFileTypes: true });
530
- for (const dirent of guildDirs) {
531
- if (!dirent.isDirectory())
533
+ for (const file of guildDirs) {
534
+ if (!file.isDirectory())
532
535
  continue;
533
- const guildId = dirent.name;
536
+ const guildId = file.name;
534
537
  const stateFilePath = Utils_1.PlayerUtils.getPlayerStatePath(guildId);
535
538
  try {
536
539
  await promises_1.default.access(stateFilePath);
@@ -556,23 +559,9 @@ class Manager extends events_1.EventEmitter {
556
559
  applyVolumeAsFilter: state.options.applyVolumeAsFilter,
557
560
  pauseOnDisconnect: state.options.pauseOnDisconnect,
558
561
  };
559
- this.emit(Enums_1.ManagerEventTypes.Debug, `[MANAGER] Recreating player: ${state.guildId} from saved file: ${Utils_1.JSONUtils.safe(state.options, 2)}`);
560
562
  const player = this.create(playerOptions);
563
+ this.emit(Enums_1.ManagerEventTypes.Debug, `[MANAGER] Recreating player: ${state.guildId} from saved file: ${Utils_1.JSONUtils.safe(state.options, 2)}`);
561
564
  player.connect();
562
- await player.node.rest.updatePlayer({
563
- guildId: state.options.guildId,
564
- data: {
565
- voice: {
566
- token: state.voiceState.event.token,
567
- endpoint: state.voiceState.event.endpoint,
568
- sessionId: state.voiceState.sessionId,
569
- channelId: state.voiceState.channelId,
570
- },
571
- },
572
- });
573
- const tracks = [];
574
- const currentTrack = state.queue.current;
575
- const queueTracks = state.queue.tracks;
576
565
  if (state.isAutoplay) {
577
566
  const savedUser = state.data.clientUser;
578
567
  if (savedUser) {
@@ -584,6 +573,9 @@ class Manager extends events_1.EventEmitter {
584
573
  if (savedNowPlayingMessage) {
585
574
  player.setNowPlayingMessage(savedNowPlayingMessage);
586
575
  }
576
+ const tracks = [];
577
+ const currentTrack = state.queue.current;
578
+ const queueTracks = state.queue.tracks;
587
579
  if (lavaPlayer.track) {
588
580
  await player.queue.clear();
589
581
  if (currentTrack) {
@@ -732,9 +724,8 @@ class Manager extends events_1.EventEmitter {
732
724
  if (!hasGuild)
733
725
  continue;
734
726
  const lavaPlayer = await node.rest.getPlayer(state.guildId);
735
- if (!lavaPlayer) {
727
+ if (!lavaPlayer)
736
728
  await this.destroy(guildId);
737
- }
738
729
  const playerOptions = {
739
730
  guildId: state.options.guildId,
740
731
  textChannelId: state.options.textChannelId,
@@ -745,24 +736,9 @@ class Manager extends events_1.EventEmitter {
745
736
  applyVolumeAsFilter: state.options.applyVolumeAsFilter,
746
737
  pauseOnDisconnect: state.options.pauseOnDisconnect,
747
738
  };
748
- this.emit(Enums_1.ManagerEventTypes.Debug, `[MANAGER] Recreating player: ${guildId} from Redis`);
749
739
  const player = this.create(playerOptions);
740
+ this.emit(Enums_1.ManagerEventTypes.Debug, `[MANAGER] Recreating player: ${guildId} from Redis`);
750
741
  player.connect();
751
- await player.node.rest.updatePlayer({
752
- guildId: state.options.guildId,
753
- data: {
754
- voice: {
755
- token: state.voiceState.event.token,
756
- endpoint: state.voiceState.event.endpoint,
757
- sessionId: state.voiceState.sessionId,
758
- channelId: state.voiceState.channelId,
759
- },
760
- },
761
- });
762
- // Rest of the player state restoration code (tracks, filters, etc.)
763
- const tracks = [];
764
- const currentTrack = state.queue.current;
765
- const queueTracks = state.queue.tracks;
766
742
  if (state.isAutoplay) {
767
743
  const savedUser = state.data.clientUser;
768
744
  if (savedUser) {
@@ -774,6 +750,10 @@ class Manager extends events_1.EventEmitter {
774
750
  if (savedNowPlayingMessage) {
775
751
  player.setNowPlayingMessage(savedNowPlayingMessage);
776
752
  }
753
+ // Rest of the player state restoration code (tracks, filters, etc.)
754
+ const tracks = [];
755
+ const currentTrack = state.queue.current;
756
+ const queueTracks = state.queue.tracks;
777
757
  if (lavaPlayer.track) {
778
758
  await player.queue.clear();
779
759
  if (currentTrack) {
@@ -1352,6 +1332,9 @@ class Manager extends events_1.EventEmitter {
1352
1332
  getUserFromCache(id) {
1353
1333
  return this._getUser?.(id);
1354
1334
  }
1335
+ getGuildFromCache(id) {
1336
+ return this._getGuild?.(id);
1337
+ }
1355
1338
  sendPacket(packet) {
1356
1339
  return this.send(packet);
1357
1340
  }
@@ -127,7 +127,8 @@ class Node {
127
127
  }
128
128
  getNodeSessionPath() {
129
129
  const safeId = String(this.options.identifier).replace(/[^a-zA-Z0-9._-]/g, "_");
130
- return path_1.default.join(this.getNodeSessionsDir(), `${safeId}.txt`);
130
+ const clusterId = String(this.manager.options.clusterId ?? 0);
131
+ return path_1.default.join(this.getNodeSessionsDir(), `${safeId}__${clusterId}.txt`);
131
132
  }
132
133
  /**
133
134
  * Loads session IDs from the sessionIds.json file if it exists.
@@ -69,5 +69,9 @@ class DiscordenoManager extends Manager_1.Manager {
69
69
  username: typeof user === "string" ? undefined : user.username,
70
70
  };
71
71
  }
72
+ resolveGuild(guildId) {
73
+ // Try user-provided cache getter
74
+ return this.getGuildFromCache(guildId);
75
+ }
72
76
  }
73
77
  exports.DiscordenoManager = DiscordenoManager;
package/package.json CHANGED
@@ -1,107 +1,107 @@
1
1
  {
2
- "name": "magmastream",
3
- "version": "2.9.3-dev.23",
4
- "description": "A user-friendly Lavalink client designed for NodeJS.",
5
- "main": "dist/index.js",
6
- "types": "dist/index.d.ts",
7
- "files": [
8
- "dist"
9
- ],
10
- "scripts": {
11
- "build": "tsc",
12
- "types": "rtb --dist dist",
13
- "format": "prettier --write .",
14
- "format:check": "prettier --check .",
15
- "lint": "eslint \"src/**/*.{ts,js}\"",
16
- "lint:fix": "eslint --fix \"src/**/*.{ts,js}\"",
17
- "ci": "run-s format:check lint build types",
18
- "release:dev": "npm run format && npm run lint:fix && npm run ci && npm version prerelease --preid=dev && git push && npm publish --tag dev"
19
- },
20
- "devDependencies": {
21
- "@favware/rollup-type-bundler": "^4.0.0",
22
- "@types/jsdom": "^27.0.0",
23
- "@types/lodash": "^4.17.24",
24
- "@types/node": "^25.3.0",
25
- "@types/ws": "^8.18.1",
26
- "@typescript-eslint/eslint-plugin": "^8.56.0",
27
- "@typescript-eslint/parser": "^8.56.0",
28
- "eslint": "^10.0.1",
29
- "npm-run-all": "^4.1.5",
30
- "prettier": "^3.8.1",
31
- "typedoc": "^0.28.17",
32
- "typedoc-plugin-no-inherit": "^1.6.1",
33
- "typescript": "^5.9.3"
34
- },
35
- "dependencies": {
36
- "@discordjs/collection": "^2.1.1",
37
- "axios": "^1.13.5",
38
- "events": "^3.3.0",
39
- "ioredis": "^5.9.3",
40
- "jsdom": "^28.1.0",
41
- "lodash": "^4.17.23",
42
- "safe-stable-stringify": "^2.5.0",
43
- "tslib": "^2.8.1",
44
- "ws": "^8.19.0"
45
- },
46
- "optionalDependencies": {
47
- "discord.js": "14.x",
48
- "discordeno": "21.x",
49
- "eris": "0.18.x",
50
- "oceanic.js": "^1.13.0",
51
- "seyfert": "4.x"
52
- },
53
- "overrides": {
54
- "undici": "^6.23.0"
55
- },
56
- "engines": {
57
- "node": ">=20.19.0"
58
- },
59
- "eslintConfig": {
60
- "root": true,
61
- "parser": "@typescript-eslint/parser",
62
- "plugins": [
63
- "@typescript-eslint"
64
- ],
65
- "rules": {
66
- "object-curly-spacing": [
67
- "error",
68
- "always"
69
- ]
70
- },
71
- "extends": [
72
- "eslint:recommended",
73
- "plugin:@typescript-eslint/recommended"
74
- ]
75
- },
76
- "keywords": [
77
- "lavalink client",
78
- "wrapper",
79
- "typescript",
80
- "discord.js",
81
- "node.js",
82
- "java",
83
- "javascript",
84
- "audio streaming",
85
- "music bot",
86
- "voice chat",
87
- "discord integration",
88
- "high performance",
89
- "scalable",
90
- "easy-to-use",
91
- "feature-rich",
92
- "cross-platform",
93
- "seamless integration",
94
- "community support",
95
- "documentation",
96
- "open-source",
97
- "lavalink",
98
- "magmastream"
99
- ],
100
- "repository": {
101
- "type": "git",
102
- "url": "git+https://gitryx.com/MagmaStream/magmastream.git#main"
103
- },
104
- "homepage": "https://docs.magmastream.com",
105
- "author": "Abel Purnwasy",
106
- "license": "Apache-2.0"
2
+ "name": "magmastream",
3
+ "version": "2.9.3-dev.24",
4
+ "description": "A user-friendly Lavalink client designed for NodeJS.",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "files": [
8
+ "dist"
9
+ ],
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "types": "rtb --dist dist",
13
+ "format": "prettier --write .",
14
+ "format:check": "prettier --check .",
15
+ "lint": "eslint \"src/**/*.{ts,js}\"",
16
+ "lint:fix": "eslint --fix \"src/**/*.{ts,js}\"",
17
+ "ci": "run-s format:check lint build types",
18
+ "release:dev": "npm run format && npm run lint:fix && npm run ci && npm version prerelease --preid=dev && git push && npm publish --tag dev"
19
+ },
20
+ "devDependencies": {
21
+ "@favware/rollup-type-bundler": "^4.0.0",
22
+ "@types/jsdom": "^28.0.0",
23
+ "@types/lodash": "^4.17.24",
24
+ "@types/node": "^25.3.0",
25
+ "@types/ws": "^8.18.1",
26
+ "@typescript-eslint/eslint-plugin": "^8.56.0",
27
+ "@typescript-eslint/parser": "^8.56.0",
28
+ "eslint": "^10.0.2",
29
+ "npm-run-all": "^4.1.5",
30
+ "prettier": "^3.8.1",
31
+ "typedoc": "^0.28.17",
32
+ "typedoc-plugin-no-inherit": "^1.6.1",
33
+ "typescript": "^5.9.3"
34
+ },
35
+ "dependencies": {
36
+ "@discordjs/collection": "^2.1.1",
37
+ "axios": "^1.13.6",
38
+ "events": "^3.3.0",
39
+ "ioredis": "^5.10.0",
40
+ "jsdom": "^28.1.0",
41
+ "lodash": "^4.17.23",
42
+ "safe-stable-stringify": "^2.5.0",
43
+ "tslib": "^2.8.1",
44
+ "ws": "^8.19.0"
45
+ },
46
+ "optionalDependencies": {
47
+ "discord.js": "14.x",
48
+ "discordeno": "21.x",
49
+ "eris": "0.18.x",
50
+ "oceanic.js": "1.13.x",
51
+ "seyfert": "4.x"
52
+ },
53
+ "overrides": {
54
+ "undici": "^7.0.0"
55
+ },
56
+ "engines": {
57
+ "node": ">=20.19.0"
58
+ },
59
+ "eslintConfig": {
60
+ "root": true,
61
+ "parser": "@typescript-eslint/parser",
62
+ "plugins": [
63
+ "@typescript-eslint"
64
+ ],
65
+ "rules": {
66
+ "object-curly-spacing": [
67
+ "error",
68
+ "always"
69
+ ]
70
+ },
71
+ "extends": [
72
+ "eslint:recommended",
73
+ "plugin:@typescript-eslint/recommended"
74
+ ]
75
+ },
76
+ "keywords": [
77
+ "lavalink client",
78
+ "wrapper",
79
+ "typescript",
80
+ "discord.js",
81
+ "node.js",
82
+ "java",
83
+ "javascript",
84
+ "audio streaming",
85
+ "music bot",
86
+ "voice chat",
87
+ "discord integration",
88
+ "high performance",
89
+ "scalable",
90
+ "easy-to-use",
91
+ "feature-rich",
92
+ "cross-platform",
93
+ "seamless integration",
94
+ "community support",
95
+ "documentation",
96
+ "open-source",
97
+ "lavalink",
98
+ "magmastream"
99
+ ],
100
+ "repository": {
101
+ "type": "git",
102
+ "url": "git+https://gitryx.com/MagmaStream/magmastream.git#main"
103
+ },
104
+ "homepage": "https://docs.magmastream.com",
105
+ "author": "Abel Purnwasy",
106
+ "license": "Apache-2.0"
107
107
  }