ryanlink 1.0.2 → 2.0.0

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.
Files changed (62) hide show
  1. package/LICENSE +201 -37
  2. package/README.md +97 -370
  3. package/dist/index.cjs +4833 -0
  4. package/dist/index.d.cts +1703 -0
  5. package/dist/index.d.ts +1528 -1160
  6. package/dist/index.js +4262 -4197
  7. package/dist/index.mjs +4261 -4106
  8. package/package.json +87 -79
  9. package/dist/index.d.mts +0 -1335
  10. package/dist/index.js.map +0 -1
  11. package/dist/index.mjs.map +0 -1
  12. package/src/audio/AudioFilters.ts +0 -316
  13. package/src/audio/AudioQueue.ts +0 -782
  14. package/src/audio/AudioTrack.ts +0 -242
  15. package/src/audio/QueueController.ts +0 -252
  16. package/src/audio/TrackCollection.ts +0 -138
  17. package/src/audio/index.ts +0 -9
  18. package/src/config/defaults.ts +0 -223
  19. package/src/config/endpoints.ts +0 -99
  20. package/src/config/index.ts +0 -9
  21. package/src/config/patterns.ts +0 -55
  22. package/src/config/presets.ts +0 -400
  23. package/src/config/symbols.ts +0 -31
  24. package/src/core/PluginSystem.ts +0 -50
  25. package/src/core/RyanlinkPlayer.ts +0 -403
  26. package/src/core/index.ts +0 -6
  27. package/src/extensions/AutoplayExtension.ts +0 -283
  28. package/src/extensions/FairPlayExtension.ts +0 -154
  29. package/src/extensions/LyricsExtension.ts +0 -187
  30. package/src/extensions/PersistenceExtension.ts +0 -182
  31. package/src/extensions/SponsorBlockExtension.ts +0 -81
  32. package/src/extensions/index.ts +0 -9
  33. package/src/index.ts +0 -19
  34. package/src/lavalink/ConnectionPool.ts +0 -326
  35. package/src/lavalink/HttpClient.ts +0 -316
  36. package/src/lavalink/LavalinkConnection.ts +0 -409
  37. package/src/lavalink/index.ts +0 -7
  38. package/src/metadata.ts +0 -88
  39. package/src/types/api/Rest.ts +0 -949
  40. package/src/types/api/Websocket.ts +0 -463
  41. package/src/types/api/index.ts +0 -6
  42. package/src/types/audio/FilterManager.ts +0 -29
  43. package/src/types/audio/Queue.ts +0 -4
  44. package/src/types/audio/QueueManager.ts +0 -30
  45. package/src/types/audio/index.ts +0 -7
  46. package/src/types/common.ts +0 -63
  47. package/src/types/core/Player.ts +0 -322
  48. package/src/types/core/index.ts +0 -5
  49. package/src/types/index.ts +0 -6
  50. package/src/types/lavalink/Node.ts +0 -173
  51. package/src/types/lavalink/NodeManager.ts +0 -34
  52. package/src/types/lavalink/REST.ts +0 -144
  53. package/src/types/lavalink/index.ts +0 -32
  54. package/src/types/voice/VoiceManager.ts +0 -176
  55. package/src/types/voice/index.ts +0 -5
  56. package/src/utils/helpers.ts +0 -169
  57. package/src/utils/index.ts +0 -6
  58. package/src/utils/validators.ts +0 -184
  59. package/src/voice/RegionSelector.ts +0 -184
  60. package/src/voice/VoiceConnection.ts +0 -458
  61. package/src/voice/VoiceSession.ts +0 -297
  62. package/src/voice/index.ts +0 -7
package/README.md CHANGED
@@ -1,19 +1,18 @@
1
1
  <div align="center">
2
- <img alt="Ryanlink" src="assets/ryanlink.jpeg" width="120" />
2
+ <img alt="ryanlink" src="assets/ryanlink.png" width="120" />
3
3
 
4
4
  # Ryanlink
5
5
 
6
- A modern, feature-rich Lavalink client for Node.js with TypeScript support
6
+ A modern, high-performance audio client for Node.js, Bun, and Deno.
7
7
 
8
8
  <br/>
9
9
 
10
10
  [![NPM Version](https://img.shields.io/npm/v/ryanlink?style=flat&logo=npm)](https://www.npmjs.com/package/ryanlink)
11
11
  [![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)
12
12
  [![Node Version](https://img.shields.io/node/v/ryanlink)](https://nodejs.org)
13
- [![TypeScript](https://img.shields.io/badge/TypeScript-5.3+-blue.svg?logo=typescript)](https://www.typescriptlang.org/)
14
- [![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/ryanwtf7/ryanlink/coverage.yml?branch=master&label=tests)](https://github.com/ryanwtf7/ryanlink/actions)
13
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.4+-blue.svg?logo=typescript)](https://www.typescriptlang.org/)
15
14
 
16
- [Documentation](https://ryanwtf7.github.io/ryanlink) • [NPM Package](https://www.npmjs.com/package/ryanlink) • [GitHub](https://github.com/ryanwtf7/ryanlink)
15
+ [Documentation](https://ryanwtf7.github.io/ryanlink/) • [NPM Package](https://www.npmjs.com/package/ryanlink) • [GitHub](https://github.com/ryanwtf7/ryanlink)
17
16
 
18
17
  </div>
19
18
 
@@ -21,36 +20,20 @@
21
20
 
22
21
  ## Overview
23
22
 
24
- Ryanlink is a powerful Lavalink client library designed to simplify music bot development for Discord. Built with modern TypeScript and featuring a unique architecture, it provides an intuitive interface for managing audio playback, queues, and advanced audio processing.
23
+ **Ryanlink** is a premium, feature-rich lavalink-v4 wrapper designed for speed, flexibility, and developer experience. It provides a robust architecture for Discord music bots with first-class TypeScript support and cross-runtime compatibility.
25
24
 
26
25
  ### Key Features
27
26
 
28
- - **Modern Lavalink v4 Support** - Full compatibility with the latest Lavalink API
29
- - **Cross-Runtime Compatibility** - Works seamlessly with Node.js, Bun, and Deno
30
- - **Professional Audio Processing** - 17 built-in EQ presets for instant audio enhancement
31
- - **Advanced Queue Management** - Sort, filter, search, and manipulate tracks with ease
32
- - **Powerful Extensions System** - Autoplay, Lyrics, SponsorBlock, FairPlay, and Persistence
33
- - **Type-Safe** - Complete TypeScript definitions with full IntelliSense support
34
- - **Production Ready** - Comprehensive error handling, automatic reconnection, and session management
35
- - **Flexible Architecture** - Feature-based organization for better maintainability
27
+ - **Lavalink v4 Protocol** - Full support for the latest lavalink features and filters.
28
+ - **Cross-Runtime Ready** - Optimized for **Node.js**, **Bun**, and **Deno**.
29
+ - **Flexible Queue Stores** - Use the default in-memory store or bring your own (Redis, databases, etc.).
30
+ - **High-Performance Audio** - Native fetch, efficient memory management, and parallel track loading.
31
+ - **Professional Filters** - Built-in EQ presets and custom DSP filters (Bassboost, Nightcore, etc.).
32
+ - **Smart Automation** - Optional auto-pause on mute and instant filter application via `instaFixFilter`.
33
+ - **Strictly Type-Safe** - 100% TypeScript with advanced module augmentation support.
34
+ - **Dynamic Metadata** - Real-time access to library version and package information.
36
35
 
37
- ### Supported Platforms
38
-
39
- Ryanlink supports audio from 20+ streaming platforms through LavaSrc integration:
40
-
41
- <div align="center">
42
-
43
- | Platform | Support | Platform | Support | Platform | Support |
44
- | ------------ | ------- | --------- | ------- | ------------ | ------- |
45
- | YouTube | ✓ | Spotify | ✓ | Apple Music | ✓ |
46
- | SoundCloud | ✓ | Deezer | ✓ | Tidal | ✓ |
47
- | Bandcamp | ✓ | Twitch | ✓ | Amazon Music | ✓ |
48
- | Yandex Music | ✓ | JioSaavn | ✓ | Pandora | ✓ |
49
- | Qobuz | ✓ | Audiomack | ✓ | Mixcloud | ✓ |
50
- | Anghami | ✓ | Audius | ✓ | Gaana | ✓ |
51
- | Instagram | ✓ | Shazam | ✓ | Direct URLs | ✓ |
52
-
53
- </div>
36
+ ---
54
37
 
55
38
  ## Installation
56
39
 
@@ -58,398 +41,142 @@ Ryanlink supports audio from 20+ streaming platforms through LavaSrc integration
58
41
  # npm
59
42
  npm install ryanlink
60
43
 
61
- # yarn
62
- yarn add ryanlink
44
+ # bun
45
+ bun add ryanlink
63
46
 
64
47
  # pnpm
65
48
  pnpm add ryanlink
66
-
67
- # bun
68
- bun add ryanlink
69
49
  ```
70
50
 
71
- ### Deno
72
-
73
- ```typescript
74
- import { RyanlinkPlayer } from "npm:ryanlink@latest";
75
- ```
51
+ ---
76
52
 
77
53
  ## Quick Start
78
54
 
79
55
  ```typescript
80
- import { Client } from "discord.js";
81
- import { RyanlinkPlayer } from "ryanlink";
82
-
83
- const client = new Client({ intents: ["Guilds", "GuildVoiceStates"] });
84
-
85
- const player = new RyanlinkPlayer({
86
- nodes: [
87
- {
88
- name: "main",
89
- host: "localhost",
90
- port: 2333,
91
- password: "youshallnotpass",
92
- secure: false,
93
- },
94
- ],
95
- forwardVoiceUpdate: async (guildId, payload) => {
96
- const guild = client.guilds.cache.get(guildId);
97
- if (guild) guild.shard.send(payload);
56
+ import { Client, GatewayIntentBits } from 'discord.js'
57
+ import { RyanlinkManager } from 'ryanlink'
58
+
59
+ const client = new Client({
60
+ intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildVoiceStates],
61
+ })
62
+
63
+ client.ryanlink = new RyanlinkManager({
64
+ nodes: [
65
+ {
66
+ name: 'main',
67
+ host: 'localhost',
68
+ port: 2333,
69
+ authorization: 'youshallnotpass',
70
+ secure: false,
98
71
  },
99
- });
72
+ ],
73
+ sendToShard: (guildId, payload) => {
74
+ client.guilds.cache.get(guildId)?.shard.send(payload)
75
+ },
76
+ client: {
77
+ id: process.env.CLIENT_ID,
78
+ username: 'RyanlinkBot',
79
+ },
80
+ })
100
81
 
101
- client.on("ready", async () => {
102
- await player.init(client.user.id);
103
- console.log(`${client.user.tag} is ready!`);
104
- });
82
+ client.on('ready', () => {
83
+ client.ryanlink.init({ ...client.user })
84
+ console.log(`${client.user.tag} is online and connected to ryanlink`)
85
+ })
105
86
 
106
- client.on("raw", (packet) => {
107
- player.voices.handleDispatch(packet);
108
- });
87
+ client.on('raw', (packet) => {
88
+ client.ryanlink.provideVoiceUpdate(packet)
89
+ })
109
90
 
110
- client.login("YOUR_BOT_TOKEN");
91
+ client.login('YOUR_BOT_TOKEN')
111
92
  ```
112
93
 
113
- ## Core Concepts
114
-
115
- ### Playing Music
94
+ ---
116
95
 
117
- ```typescript
118
- // Play from URL or search query
119
- const queue = await player.play("Never Gonna Give You Up", {
120
- guildId: interaction.guildId,
121
- voiceId: interaction.member.voice.channelId,
122
- textId: interaction.channelId,
123
- });
124
-
125
- // Play from direct URL
126
- await player.play("https://open.spotify.com/track/...", {
127
- guildId: interaction.guildId,
128
- voiceId: interaction.member.voice.channelId,
129
- });
130
-
131
- // Search with specific source
132
- const results = await player.search("ytsearch:Rick Astley");
133
- ```
96
+ ## Core Usage
134
97
 
135
- ### Queue Management
98
+ ### Playing Audio
136
99
 
137
100
  ```typescript
138
- const queue = player.getQueue(guildId);
139
-
140
- // Basic controls
141
- await queue.pause();
142
- await queue.resume();
143
- await queue.stop();
144
- await queue.skip();
145
- await queue.previous();
101
+ const player = client.ryanlink.createPlayer({
102
+ guildId: interaction.guildId,
103
+ voiceChannelId: interaction.member.voice.channelId,
104
+ textChannelId: interaction.channelId,
105
+ })
146
106
 
147
- // Volume control
148
- await queue.setVolume(0.5); // 50%
107
+ const res = await player.search('Never Gonna Give You Up', interaction.user)
108
+ player.queue.add(res.tracks[0])
149
109
 
150
- // Repeat modes
151
- await queue.setRepeatMode("track"); // Repeat current track
152
- await queue.setRepeatMode("queue"); // Repeat entire queue
153
- await queue.setRepeatMode("off"); // No repeat
110
+ if (!player.playing) await player.play()
154
111
 
155
- // Shuffle
156
- await queue.shuffle();
157
- await queue.shuffle(true); // Include previous tracks
158
-
159
- // Seek
160
- await queue.seek(60000); // Seek to 1 minute
112
+ console.log(`Added: ${res.tracks[0].info.title}`)
161
113
  ```
162
114
 
163
- ### Advanced Queue Operations
115
+ ### Queue Controls
164
116
 
165
117
  ```typescript
166
- // Sort tracks
167
- await queue.sortBy("duration", "desc");
168
- await queue.sortBy("title", "asc");
169
- await queue.sortBy((a, b) => a.duration - b.duration);
170
-
171
- // Filter tracks
172
- const longTracks = queue.filterTracks({
173
- duration: { min: 180000 }, // 3+ minutes
174
- });
175
-
176
- const rockTracks = queue.filterTracks({
177
- title: "rock",
178
- });
179
-
180
- // Find specific track
181
- const track = queue.findTrack({ title: "Never Gonna" });
182
-
183
- // Move tracks
184
- await queue.move(5, 0); // Move track at index 5 to front
185
-
186
- // Remove tracks
187
- await queue.remove(3); // Remove track at index 3
118
+ const player = client.ryanlink.players.get(guildId)
188
119
 
189
- // Get track range
190
- const nextTen = queue.getTracks(0, 10);
120
+ await player.pause()
121
+ await player.resume()
122
+ await player.skip()
123
+ await player.setVolume(50) // 0 - 100
124
+ player.setRepeatMode('queue') // "off" | "track" | "queue"
191
125
  ```
192
126
 
193
127
  ### Audio Filters
194
128
 
195
129
  ```typescript
196
- // Apply EQ preset
197
- await queue.filters.setEQPreset("BassboostHigh");
198
- await queue.filters.setEQPreset("Rock");
199
- await queue.filters.setEQPreset("Nightcore");
200
-
201
- // Get available presets
202
- const presets = queue.filters.getEQPresetNames();
203
- // ["BassboostEarrape", "BassboostHigh", "BassboostMedium", "BassboostLow",
204
- // "Rock", "Classic", "Pop", "Electronic", "Gaming", "Nightcore",
205
- // "Vaporwave", "TrebleBass", "HighQuality", "BetterMusic", "FullSound",
206
- // "Soft", "TV", "Radio", "Normalization"]
207
-
208
- // Custom filters
209
- await queue.filters.apply({
210
- equalizer: [
211
- { band: 0, gain: 0.2 },
212
- { band: 1, gain: 0.15 },
213
- ],
214
- timescale: { speed: 1.5, pitch: 1.2 },
215
- volume: 1.0,
216
- });
217
-
218
- // Individual filter control
219
- await queue.filters.set("timescale", { speed: 1.5 });
220
- await queue.filters.delete("timescale");
221
- await queue.filters.clear();
222
- ```
223
-
224
- ## Extensions
225
-
226
- ### Autoplay Extension
227
-
228
- Automatically plays related tracks when the queue ends.
229
-
230
- ```typescript
231
- import { AutoplayExtension } from "ryanlink";
232
-
233
- const player = new RyanlinkPlayer({
234
- plugins: [
235
- new AutoplayExtension({
236
- enabled: true,
237
- maxHistory: 50,
238
- sources: {
239
- spotify: true,
240
- youtube: true,
241
- youtubemusic: true,
242
- soundcloud: false,
243
- },
244
- }),
245
- ],
246
- });
247
- ```
248
-
249
- ### Lyrics Extension
250
-
251
- Fetch synchronized lyrics from multiple sources.
252
-
253
- ```typescript
254
- import { LyricsExtension } from "ryanlink";
255
-
256
- const player = new RyanlinkPlayer({
257
- plugins: [
258
- new LyricsExtension({
259
- sources: ["lrclib", "genius", "musixmatch"],
260
- cache: true,
261
- }),
262
- ],
263
- });
264
-
265
- // Get lyrics
266
- const lyrics = await queue.getLyrics();
267
- ```
268
-
269
- ### SponsorBlock Extension
270
-
271
- Skip sponsored segments in YouTube videos.
272
-
273
- ```typescript
274
- import { SponsorBlockExtension } from "ryanlink";
275
-
276
- const player = new RyanlinkPlayer({
277
- plugins: [
278
- new SponsorBlockExtension({
279
- categories: ["sponsor", "intro", "outro", "selfpromo"],
280
- autoSkip: true,
281
- }),
282
- ],
283
- });
284
- ```
285
-
286
- ### FairPlay Extension
130
+ // Apply professional EQ presets
131
+ await player.filterManager.setEQ([
132
+ { band: 0, gain: 0.25 },
133
+ { band: 1, gain: 0.25 },
134
+ ])
287
135
 
288
- Limit tracks per user for fair queue distribution.
289
-
290
- ```typescript
291
- import { FairPlayExtension } from "ryanlink";
292
-
293
- const player = new RyanlinkPlayer({
294
- plugins: [
295
- new FairPlayExtension({
296
- maxPerUser: 3,
297
- enforceLimit: true,
298
- }),
299
- ],
300
- });
136
+ // Custom Timescale via filterManager
137
+ await player.filterManager.setFilters({
138
+ timescale: { speed: 1.2, pitch: 1.1 },
139
+ })
301
140
  ```
302
141
 
303
- ### Persistence Extension
142
+ ---
304
143
 
305
- Save and restore queues across bot restarts.
144
+ ## Diagnostic Metadata
306
145
 
307
- ```typescript
308
- import { PersistenceExtension } from "ryanlink";
309
-
310
- const player = new RyanlinkPlayer({
311
- plugins: [
312
- new PersistenceExtension({
313
- autoSave: true,
314
- saveInterval: 60000, // 1 minute
315
- }),
316
- ],
317
- });
318
- ```
319
-
320
- ## Events
146
+ Access library information dynamically:
321
147
 
322
148
  ```typescript
323
- // Track events
324
- player.on("trackStart", (queue, track) => {
325
- console.log(`Now playing: ${track.title}`);
326
- });
327
-
328
- player.on("trackFinish", (queue, track, reason) => {
329
- console.log(`Finished: ${track.title} (${reason})`);
330
- });
331
-
332
- player.on("trackError", (queue, track, error) => {
333
- console.error(`Error: ${error.message}`);
334
- });
335
-
336
- player.on("trackStuck", (queue, track, threshold) => {
337
- console.warn(`Track stuck: ${track.title}`);
338
- });
339
-
340
- // Queue events
341
- player.on("queueCreate", (queue) => {
342
- console.log(`Queue created for guild ${queue.guildId}`);
343
- });
344
-
345
- player.on("queueFinish", (queue) => {
346
- console.log("Queue finished!");
347
- });
348
-
349
- player.on("queueDestroy", (queue, reason) => {
350
- console.log(`Queue destroyed: ${reason}`);
351
- });
352
-
353
- // Node events
354
- player.on("nodeConnect", (node, reconnects) => {
355
- console.log(`Node ${node.name} connected`);
356
- });
357
-
358
- player.on("nodeReady", (node, resumed, sessionId) => {
359
- console.log(`Node ${node.name} ready`);
360
- });
361
-
362
- player.on("nodeDisconnect", (node, code, reason) => {
363
- console.log(`Node ${node.name} disconnected`);
364
- });
365
-
366
- player.on("nodeError", (node, error) => {
367
- console.error(`Node error: ${error.message}`);
368
- });
369
- ```
370
-
371
- ## TypeScript Support
372
-
373
- Ryanlink is built with TypeScript and provides complete type definitions.
149
+ import { version } from 'ryanlink'
374
150
 
375
- ### Module Augmentation
376
-
377
- Extend types for custom data:
378
-
379
- ```typescript
380
- declare module "ryanlink" {
381
- interface QueueContext {
382
- textChannelId: string;
383
- requesterId: string;
384
- }
385
-
386
- interface CommonUserData {
387
- id: string;
388
- username: string;
389
- requestedAt: number;
390
- }
391
-
392
- interface CommonPluginInfo {
393
- customField?: string;
394
- }
395
- }
151
+ console.log(`Ryanlink v${version}`)
396
152
  ```
397
153
 
398
- ## Requirements
399
-
400
- - **Node.js**: 18.0.0 or higher
401
- - **Bun**: 1.0.0 or higher
402
- - **Deno**: 1.30.0 or higher
403
- - **Lavalink**: 4.0.0 or higher
154
+ ---
404
155
 
405
156
  ## Architecture
406
157
 
407
- Ryanlink uses a feature-based architecture for better organization:
158
+ Ryanlink is organized into modular features for maximum maintainability:
408
159
 
409
- ```
410
- src/
411
- ├── core/ # Player and plugin system
412
- ├── lavalink/ # Lavalink connection and HTTP client
413
- ├── audio/ # Queue, tracks, and filters
414
- ├── voice/ # Voice connection management
415
- ├── extensions/ # Built-in extensions
416
- ├── config/ # Configuration and constants
417
- ├── utils/ # Utility functions
418
- └── types/ # TypeScript definitions
419
- ```
160
+ - `src/` - Core library source files including:
161
+ - `core/Manager.ts` - Main entry point
162
+ - `node/Node.ts` - Connection and REST interfaces
163
+ - `audio/Player.ts` - Audio playback and queue controller
164
+ - `audio/Queue.ts` - Advanced track management
420
165
 
421
- ## Performance
166
+ ---
422
167
 
423
- - **Efficient Memory Usage** - Optimized data structures and caching
424
- - **Fast Track Loading** - Parallel track resolution
425
- - **Minimal Overhead** - Native fetch API, no unnecessary dependencies
426
- - **Smart Reconnection** - Automatic recovery with exponential backoff
168
+ ## Requirements
427
169
 
428
- ## Contributing
170
+ - **Lavalink**: 4.0.0+
171
+ - **Node.js**: 18.0.0+ (Support for Bun/Deno)
172
+ - **TypeScript**: 5.4+ (Standardized)
429
173
 
430
- Contributions are welcome! Please read our [Contributing Guide](CONTRIBUTING.md) for details on our code of conduct and the process for submitting pull requests.
174
+ ---
431
175
 
432
176
  ## License
433
177
 
434
- This project is licensed under the Apache License 2.0 - see the [LICENSE](LICENSE) file for details.
435
-
436
- ## Acknowledgements
437
-
438
- Ryanlink was inspired by and builds upon concepts from:
439
-
440
- - [distube](https://github.com/skick1234/DisTube) - Player-queue design patterns
441
- - [discord.js](https://github.com/discordjs/discord.js) - Manager-cache architecture
442
- - [Hoshimi](https://github.com/Ganyu-Studios/Hoshimi) - Module augmentation patterns
443
- - [discolink](https://github.com/execaman/discolink) - Modern Lavalink client design
444
-
445
- ## Support
446
-
447
- - [Documentation](https://ryanwtf7.github.io/ryanlink)
448
- - [GitHub Issues](https://github.com/ryanwtf7/ryanlink/issues)
449
- - [GitHub Discussions](https://github.com/ryanwtf7/ryanlink/discussions)
450
-
451
- ---
178
+ Licensed under the **Apache License 2.0**. See the [LICENSE](LICENSE) file for more information.
452
179
 
453
180
  <div align="center">
454
- Made with ❤️ by RY4N
181
+ Made with care by RY4N
455
182
  </div>