linkdave 0.1.6 → 0.2.0-dev.db8ab4a

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/player.js CHANGED
@@ -1,25 +1,26 @@
1
1
  import { GatewayOpcodes } from "discord-api-types/v10";
2
+ import { PlayerFilters } from "./filters.js";
2
3
  import { Queue } from "./queue.js";
3
- import { EventName, PlayerState, TrackEndReason } from "./types.js";
4
+ import { DisconnectReason, EventName, PlayerState, TrackEndReason } from "./types.js";
4
5
  import { unwrap } from "./utils.js";
5
6
  export class Player {
6
7
  static CONNECT_TIMEOUT = 10_000;
7
8
  #client;
8
9
  #guildId;
9
10
  #queue;
11
+ #filters = new PlayerFilters();
10
12
  #node;
11
13
  #voiceChannelId = null;
12
14
  #selfMute;
13
15
  #selfDeaf;
14
16
  #state = PlayerState.Idle;
15
- #position = 0;
16
- #volume = 100;
17
17
  #current = null;
18
18
  #voiceState = null;
19
19
  #pendingVoice = null;
20
- #lastServerEvent = null;
21
20
  #migrationTarget = null;
22
21
  #migrationResolve = null;
22
+ #inactivityTimeout;
23
+ #inactivityTimer = null;
23
24
  constructor(client, guildId, node, options) {
24
25
  this.#client = client;
25
26
  this.#guildId = guildId;
@@ -28,6 +29,7 @@ export class Player {
28
29
  this.#voiceChannelId = options?.voiceChannelId ?? null;
29
30
  this.#selfMute = options?.selfMute ?? false;
30
31
  this.#selfDeaf = options?.selfDeaf ?? true;
32
+ this.#inactivityTimeout = options?.inactivityTimeout ?? 0;
31
33
  }
32
34
  get guildId() {
33
35
  return this.#guildId;
@@ -38,12 +40,6 @@ export class Player {
38
40
  get state() {
39
41
  return this.#state;
40
42
  }
41
- get position() {
42
- return this.#position;
43
- }
44
- get volume() {
45
- return this.#volume;
46
- }
47
43
  get current() {
48
44
  return this.#current;
49
45
  }
@@ -62,12 +58,16 @@ export class Player {
62
58
  get connected() {
63
59
  return this.#voiceState !== null;
64
60
  }
61
+ get filters() {
62
+ return this.#filters;
63
+ }
65
64
  connect(channelId, timeoutMs = Player.CONNECT_TIMEOUT) {
66
65
  const targetChannel = channelId ?? this.#voiceChannelId;
67
66
  if (!targetChannel) {
68
67
  throw new RangeError("No voice channel ID provided");
69
68
  }
70
69
  this.#voiceChannelId = targetChannel;
70
+ this.#state = PlayerState.Connecting;
71
71
  this.#client._sendToShard(this.#guildId, {
72
72
  op: GatewayOpcodes.VoiceStateUpdate,
73
73
  d: {
@@ -79,6 +79,9 @@ export class Player {
79
79
  });
80
80
  return new Promise((resolve, reject) => {
81
81
  const cleanup = () => {
82
+ if (this.#state === PlayerState.Connecting) {
83
+ this.#state = PlayerState.Idle;
84
+ }
82
85
  this.#node.off(EventName.VoiceConnect, onConnect);
83
86
  this.#node.off(EventName.VoiceDisconnect, onDisconnect);
84
87
  clearTimeout(timer);
@@ -86,7 +89,6 @@ export class Player {
86
89
  const timer = setTimeout(() => {
87
90
  cleanup();
88
91
  this.#pendingVoice = null;
89
- this.#lastServerEvent = null;
90
92
  reject(new Error(`Voice connection timed out for guild "${this.#guildId}"`));
91
93
  }, timeoutMs);
92
94
  const onConnect = (event) => {
@@ -98,6 +100,8 @@ export class Player {
98
100
  const onDisconnect = (event) => {
99
101
  if (event.guild_id !== this.#guildId)
100
102
  return;
103
+ if (event.reason === DisconnectReason.Requested)
104
+ return;
101
105
  cleanup();
102
106
  reject(new Error(`Voice connection failed for guild "${this.#guildId}": ${event.reason ?? "unknown"}`));
103
107
  };
@@ -106,7 +110,6 @@ export class Player {
106
110
  });
107
111
  }
108
112
  disconnect() {
109
- this.#queue._deactivate();
110
113
  this.#client._sendToShard(this.#guildId, {
111
114
  op: GatewayOpcodes.VoiceStateUpdate,
112
115
  d: {
@@ -116,21 +119,13 @@ export class Player {
116
119
  self_deaf: false
117
120
  }
118
121
  });
119
- this.#voiceChannelId = null;
120
- this.#state = PlayerState.Idle;
121
- this.#current = null;
122
- this.#position = 0;
123
- this.#voiceState = null;
124
- this.#pendingVoice = null;
125
- this.#lastServerEvent = null;
122
+ this.#cleanup();
126
123
  }
127
124
  async handleVoiceStateUpdate(data) {
128
125
  if (!data.channel_id) {
129
- this.#voiceChannelId = null;
130
- this.#voiceState = null;
131
- this.#pendingVoice = null;
132
- this.#lastServerEvent = null;
133
- if (this.#node.connected) {
126
+ const hadVoiceState = this.#voiceState !== null;
127
+ this.#cleanup();
128
+ if (hadVoiceState && this.#node.connected) {
134
129
  const [, err] = await unwrap(this.#node.sendDisconnect(this.#guildId));
135
130
  if (err)
136
131
  this.#node.emit(EventName.Error, err);
@@ -140,19 +135,12 @@ export class Player {
140
135
  this.#pendingVoice ??= {};
141
136
  this.#pendingVoice.channelId = data.channel_id;
142
137
  this.#pendingVoice.sessionId = data.session_id;
143
- if (!this.#pendingVoice.serverEvent && this.#lastServerEvent && this.#voiceState?.channelId === data.channel_id) {
144
- this.#pendingVoice.serverEvent = this.#lastServerEvent;
145
- }
146
138
  this.#tryConnectLinkDave();
147
139
  }
148
140
  async handleVoiceServerUpdate(data) {
149
141
  if (!data.endpoint) {
150
142
  const hadVoiceState = this.#voiceState !== null;
151
- this.#voiceState = null;
152
- if (this.#pendingVoice) {
153
- delete this.#pendingVoice.serverEvent;
154
- }
155
- // Only send disconnect if we had an active voice state to tear down.
143
+ this.#cleanup();
156
144
  if (hadVoiceState && this.#node.connected) {
157
145
  const [, err] = await unwrap(this.#node.sendDisconnect(this.#guildId));
158
146
  if (err)
@@ -176,14 +164,12 @@ export class Player {
176
164
  if (!pending?.channelId || !pending.sessionId || !pending.serverEvent) {
177
165
  return;
178
166
  }
179
- // We have all the data, connect to LinkDave
180
167
  this.#connectToLinkDave(pending.channelId, pending.sessionId, pending.serverEvent);
181
168
  this.#pendingVoice = null;
182
169
  }
183
170
  #connectToLinkDave(channelId, sessionId, event) {
184
171
  this.#voiceChannelId = channelId;
185
172
  this.#voiceState = { channelId, sessionId, event };
186
- this.#lastServerEvent = event;
187
173
  this.#node.sendVoiceUpdate({
188
174
  client_id: this.#client.clientId,
189
175
  guild_id: this.#guildId,
@@ -198,10 +184,12 @@ export class Player {
198
184
  await this.#sendPlay(url, options);
199
185
  }
200
186
  async #sendPlay(url, options = {}) {
187
+ const filters = options.filters ?? this.#filters.toPayload();
201
188
  await this.#node.sendPlay(this.#guildId, {
202
189
  url,
203
190
  ...(options.startTime !== undefined && { start_time: options.startTime }),
204
- ...(options.volume !== undefined && { volume: options.volume })
191
+ ...(options.requesterId !== undefined && { requester_id: options.requesterId }),
192
+ ...(filters !== undefined && { filters })
205
193
  });
206
194
  }
207
195
  async pause() {
@@ -213,17 +201,12 @@ export class Player {
213
201
  async stop() {
214
202
  this.#queue._deactivate();
215
203
  await this.#node.sendStop(this.#guildId);
216
- this.#current = null;
217
204
  this.#state = PlayerState.Idle;
218
- this.#position = 0;
205
+ this.#current = null;
219
206
  }
220
207
  async seek(position) {
221
208
  await this.#node.sendSeek(this.#guildId, { position });
222
209
  }
223
- async setVolume(volume) {
224
- this.#volume = Math.max(0, Math.min(1_000, volume));
225
- await this.#node.sendVolume(this.#guildId, { volume: this.#volume });
226
- }
227
210
  async destroy() {
228
211
  this.disconnect();
229
212
  if (!this.#node.connected) {
@@ -232,9 +215,8 @@ export class Player {
232
215
  }
233
216
  const waitForVoiceDisconnect = this.#waitForNodeVoiceDisconnect(Player.CONNECT_TIMEOUT);
234
217
  await unwrap(this.#node.sendDisconnect(this.#guildId));
235
- if (!(await waitForVoiceDisconnect)) {
236
- this.#client._onPlayerDestroy(this.#guildId);
237
- }
218
+ await waitForVoiceDisconnect;
219
+ this.#client._onPlayerDestroy(this.#guildId);
238
220
  }
239
221
  #waitForNodeVoiceDisconnect(timeoutMs) {
240
222
  return new Promise((resolve) => {
@@ -267,27 +249,43 @@ export class Player {
267
249
  this.#migrationResolve = resolve;
268
250
  });
269
251
  }
270
- _updateState(data) {
252
+ _onPlayerUpdate(data) {
253
+ if (data.state === PlayerState.Playing)
254
+ this.#stopTimer();
255
+ else if (this.#state === PlayerState.Playing)
256
+ this.#startTimer();
271
257
  this.#state = data.state;
272
- this.#position = data.position;
273
- this.#volume = data.volume;
274
258
  }
275
259
  _onTrackStart(data) {
276
260
  this.#current = data.track;
261
+ this.#state = PlayerState.Playing;
262
+ this.#stopTimer();
277
263
  }
278
264
  _onTrackEnd(data) {
279
265
  if (!this.#queue.active || this.#queue.size === 0) {
280
- this.#current = null;
281
266
  this.#state = PlayerState.Idle;
267
+ this.#current = null;
268
+ this.#startTimer();
282
269
  }
283
- this.#queue._onTrackEnd(data.reason !== TrackEndReason.Stopped);
270
+ this.#queue._onTrackEnd(data.reason !== TrackEndReason.Stopped && data.reason !== TrackEndReason.Replaced);
284
271
  }
285
- _onVoiceDisconnect() {
272
+ _onVoiceConnect() {
273
+ if (this.#state !== PlayerState.Connecting)
274
+ return;
275
+ this.#state = PlayerState.Idle;
276
+ this.#startTimer();
277
+ }
278
+ #cleanup() {
279
+ this.#voiceChannelId = null;
280
+ this.#queue._deactivate();
286
281
  this.#voiceState = null;
287
282
  this.#pendingVoice = null;
288
283
  this.#state = PlayerState.Idle;
289
284
  this.#current = null;
290
- this.#position = 0;
285
+ this.#stopTimer();
286
+ }
287
+ _onVoiceDisconnect() {
288
+ this.#cleanup();
291
289
  }
292
290
  _onMigrateReady(data) {
293
291
  if (!this.#migrationTarget || data.guild_id !== this.#guildId) {
@@ -308,17 +306,16 @@ export class Player {
308
306
  });
309
307
  }
310
308
  if (data.state === PlayerState.Playing && data.url) {
311
- const playData = {
312
- url: data.url,
313
- start_time: data.position,
314
- volume: data.volume
315
- };
316
- // Wait for voice connection on the new node before playing
317
309
  const onVoiceConnect = (event) => {
318
310
  if (event.guild_id !== this.#guildId)
319
311
  return;
320
312
  this.#node.off(EventName.VoiceConnect, onVoiceConnect);
321
- void this.#node.sendPlay(this.#guildId, playData);
313
+ void this.#node.sendPlay(this.#guildId, {
314
+ url: data.url,
315
+ start_time: data.position,
316
+ ...(data.requester_id !== undefined && { requester_id: data.requester_id }),
317
+ ...(data.filters !== undefined && { filters: data.filters })
318
+ });
322
319
  };
323
320
  this.#node.on(EventName.VoiceConnect, onVoiceConnect);
324
321
  }
@@ -328,5 +325,28 @@ export class Player {
328
325
  this.#migrationResolve(null);
329
326
  this.#migrationResolve = null;
330
327
  }
328
+ #startTimer() {
329
+ if (this.#inactivityTimeout <= 0)
330
+ return;
331
+ this.#stopTimer();
332
+ this.#inactivityTimer = setTimeout(() => {
333
+ if (this.#state === PlayerState.Playing)
334
+ return;
335
+ this.disconnect();
336
+ if (this.#node.connected) {
337
+ void this.#node.sendDisconnect(this.#guildId);
338
+ }
339
+ this.#client._onPlayerDestroy(this.#guildId);
340
+ this.#client.emit(EventName.VoiceDisconnect, {
341
+ guild_id: this.#guildId,
342
+ reason: DisconnectReason.Inactivity
343
+ });
344
+ }, this.#inactivityTimeout);
345
+ }
346
+ #stopTimer() {
347
+ if (this.#inactivityTimer === null)
348
+ return;
349
+ clearTimeout(this.#inactivityTimer);
350
+ this.#inactivityTimer = null;
351
+ }
331
352
  }
332
- //# sourceMappingURL=player.js.map
package/dist/queue.d.ts CHANGED
@@ -1,16 +1,19 @@
1
- import type { Player } from "./player.js";
1
+ import type { Player, PlayOptions } from "./player.js";
2
+ export interface QueueItem {
3
+ uri: string;
4
+ options: PlayOptions;
5
+ }
2
6
  export declare class Queue {
3
7
  #private;
4
8
  constructor(player: Player);
5
- add(uri: string): this;
9
+ add(uri: string, options?: PlayOptions): this;
6
10
  start(): Promise<void>;
7
11
  skip(): Promise<void>;
8
- remove(index: number): string | undefined;
12
+ remove(index: number): QueueItem | undefined;
9
13
  clear(): void;
10
- get tracks(): readonly string[];
14
+ get tracks(): readonly QueueItem[];
11
15
  get size(): number;
12
16
  get active(): boolean;
13
17
  _onTrackEnd(finished: boolean): void;
14
18
  _deactivate(): void;
15
19
  }
16
- //# sourceMappingURL=queue.d.ts.map
package/dist/queue.js CHANGED
@@ -6,8 +6,8 @@ export class Queue {
6
6
  constructor(player) {
7
7
  this.#player = player;
8
8
  }
9
- add(uri) {
10
- this.#tracks.push(uri);
9
+ add(uri, options = {}) {
10
+ this.#tracks.push({ uri, options });
11
11
  return this;
12
12
  }
13
13
  async start() {
@@ -56,10 +56,10 @@ export class Queue {
56
56
  if (!item)
57
57
  return;
58
58
  this.#player
59
- .play(item, undefined, true)
59
+ .play(item.uri, item.options, true)
60
60
  .then(() => null, (error_) => {
61
61
  const error = error_ instanceof Error ? error_ : new Error(String(error_));
62
- const payload = { guild_id: this.#player.guildId, url: item, error };
62
+ const payload = { guild_id: this.#player.guildId, url: item.uri, error };
63
63
  this.#player.node.emit(EventName.QueueError, payload);
64
64
  this._onTrackEnd(true);
65
65
  });
@@ -71,7 +71,6 @@ export class Queue {
71
71
  const item = this.#tracks.shift();
72
72
  if (!item)
73
73
  return;
74
- await this.#player.play(item, undefined, true);
74
+ await this.#player.play(item.uri, item.options, true);
75
75
  }
76
76
  }
77
- //# sourceMappingURL=queue.js.map
package/dist/rest.d.ts CHANGED
@@ -6,4 +6,3 @@ export declare class RESTClient {
6
6
  patch(route: string, body?: unknown): Promise<void>;
7
7
  delete(route: string): Promise<void>;
8
8
  }
9
- //# sourceMappingURL=rest.d.ts.map
package/dist/rest.js CHANGED
@@ -42,4 +42,3 @@ export class RESTClient {
42
42
  }
43
43
  }
44
44
  }
45
- //# sourceMappingURL=rest.js.map
package/dist/types.d.ts CHANGED
@@ -1,21 +1,19 @@
1
1
  import type { Node } from "./node.js";
2
2
  export declare enum ClientOpCodes {
3
- Ping = 0,
4
- VoiceUpdate = 1,
5
- PlayerMigrate = 2
3
+ VoiceUpdate = 0,
4
+ PlayerMigrate = 1
6
5
  }
7
6
  export declare enum ServerOpCodes {
8
- Pong = 0,
9
- Ready = 1,
10
- VoiceConnect = 2,
11
- VoiceDisconnect = 3,
12
- PlayerUpdate = 4,
13
- TrackStart = 5,
14
- TrackEnd = 6,
15
- TrackError = 7,
16
- Stats = 8,
17
- NodeDraining = 9,
18
- MigrateReady = 10
7
+ Ready = 0,
8
+ VoiceConnect = 1,
9
+ VoiceDisconnect = 2,
10
+ PlayerUpdate = 3,
11
+ TrackStart = 4,
12
+ TrackEnd = 5,
13
+ TrackError = 6,
14
+ Stats = 7,
15
+ NodeDraining = 8,
16
+ MigrateReady = 9
19
17
  }
20
18
  export declare enum TrackEndReason {
21
19
  Finished = "finished",
@@ -26,7 +24,27 @@ export declare enum TrackEndReason {
26
24
  export declare enum PlayerState {
27
25
  Idle = "idle",
28
26
  Playing = "playing",
29
- Paused = "paused"
27
+ Paused = "paused",
28
+ Connecting = "connecting"
29
+ }
30
+ export declare enum Filter {
31
+ /** Slows and lowers pitch (speed ×0.8, pitch ×0.8). */
32
+ Vaporwave = 0,
33
+ /** Speeds up and raises pitch (speed ×1.3, pitch ×1.3). */
34
+ Nightcore = 1,
35
+ /** Rotates audio around the stereo field at 0.2 Hz. */
36
+ Rotation = 2,
37
+ /** Oscillates volume at 4 Hz with 0.6 depth. */
38
+ Tremolo = 3,
39
+ /** Oscillates pitch at 4 Hz with 0.5 depth. */
40
+ Vibrato = 4,
41
+ /** Suppresses high frequencies (smoothing factor 20). */
42
+ LowPass = 5
43
+ }
44
+ export interface FiltersPayload {
45
+ enabled?: Filter[];
46
+ pitch?: number;
47
+ speed?: number;
30
48
  }
31
49
  export type ServerMessage = {
32
50
  op: ServerOpCodes.Ready;
@@ -49,9 +67,6 @@ export type ServerMessage = {
49
67
  } | {
50
68
  op: ServerOpCodes.VoiceDisconnect;
51
69
  d: VoiceDisconnectPayload;
52
- } | {
53
- op: ServerOpCodes.Pong;
54
- d?: undefined;
55
70
  } | {
56
71
  op: ServerOpCodes.Stats;
57
72
  d: StatsPayload;
@@ -65,9 +80,6 @@ export type ServerMessage = {
65
80
  export type ClientMessage = {
66
81
  op: ClientOpCodes.VoiceUpdate;
67
82
  d: VoiceUpdatePayload;
68
- } | {
69
- op: ClientOpCodes.Ping;
70
- d?: undefined;
71
83
  } | {
72
84
  op: ClientOpCodes.PlayerMigrate;
73
85
  d: PlayerMigratePayload;
@@ -87,7 +99,8 @@ export interface VoiceUpdatePayload {
87
99
  export interface PlayPayload {
88
100
  url: string;
89
101
  start_time?: number;
90
- volume?: number;
102
+ requester_id?: string;
103
+ filters?: FiltersPayload;
91
104
  }
92
105
  export interface GuildPayload {
93
106
  guild_id: string;
@@ -95,9 +108,6 @@ export interface GuildPayload {
95
108
  export interface SeekPayload {
96
109
  position: number;
97
110
  }
98
- export interface VolumePayload {
99
- volume: number;
100
- }
101
111
  export interface ReadyPayload {
102
112
  session_id: string;
103
113
  resumed: boolean;
@@ -105,13 +115,12 @@ export interface ReadyPayload {
105
115
  export interface PlayerUpdatePayload {
106
116
  guild_id: string;
107
117
  state: PlayerState;
108
- position: number;
109
- volume: number;
110
118
  }
111
119
  export interface TrackInfo {
112
120
  url: string;
113
121
  title?: string;
114
122
  duration: number;
123
+ requester_id?: string;
115
124
  }
116
125
  export interface TrackStartPayload {
117
126
  guild_id: string;
@@ -132,20 +141,25 @@ export interface QueueErrorPayload {
132
141
  url: string;
133
142
  error: Error;
134
143
  }
144
+ export declare enum DisconnectReason {
145
+ ConnectionLost = "connection_lost",
146
+ ConnectionFailed = "connection_failed",
147
+ Requested = "requested",
148
+ Inactivity = "inactivity"
149
+ }
135
150
  export interface VoiceConnectPayload {
136
151
  guild_id: string;
137
152
  channel_id: string;
138
153
  }
139
154
  export interface VoiceDisconnectPayload {
140
155
  guild_id: string;
141
- reason?: string;
156
+ reason?: DisconnectReason;
142
157
  }
143
158
  export interface StatsPayload {
144
159
  players: number;
145
160
  playing_tracks: number;
146
161
  uptime: number;
147
162
  memory: number;
148
- draining: boolean;
149
163
  }
150
164
  export interface PlayerMigratePayload {
151
165
  guild_id: string;
@@ -158,8 +172,9 @@ export interface MigrateReadyPayload {
158
172
  guild_id: string;
159
173
  url: string;
160
174
  position: number;
161
- volume: number;
162
175
  state: PlayerState;
176
+ requester_id?: string;
177
+ filters?: FiltersPayload;
163
178
  }
164
179
  export interface ClosePayload {
165
180
  code: number;
@@ -174,7 +189,6 @@ export declare enum EventName {
174
189
  QueueError = "queueError",
175
190
  VoiceConnect = "voiceConnect",
176
191
  VoiceDisconnect = "voiceDisconnect",
177
- Pong = "pong",
178
192
  Stats = "stats",
179
193
  NodeDraining = "nodeDraining",
180
194
  MigrateReady = "migrateReady",
@@ -190,7 +204,6 @@ export interface Events {
190
204
  [EventName.QueueError]: QueueErrorPayload;
191
205
  [EventName.VoiceConnect]: VoiceConnectPayload;
192
206
  [EventName.VoiceDisconnect]: VoiceDisconnectPayload;
193
- [EventName.Pong]: undefined;
194
207
  [EventName.Stats]: StatsPayload;
195
208
  [EventName.NodeDraining]: NodeDrainingPayload;
196
209
  [EventName.MigrateReady]: MigrateReadyPayload;
@@ -224,7 +237,5 @@ export declare const Routes: {
224
237
  readonly resume: (sessionId: string, guildId: string) => `/sessions/${string}/players/${string}/resume`;
225
238
  readonly stop: (sessionId: string, guildId: string) => `/sessions/${string}/players/${string}/stop`;
226
239
  readonly seek: (sessionId: string, guildId: string) => `/sessions/${string}/players/${string}/seek`;
227
- readonly volume: (sessionId: string, guildId: string) => `/sessions/${string}/players/${string}/volume`;
228
240
  readonly disconnect: (sessionId: string, guildId: string) => `/sessions/${string}/players/${string}`;
229
241
  };
230
- //# sourceMappingURL=types.d.ts.map
package/dist/types.js CHANGED
@@ -1,22 +1,20 @@
1
1
  export var ClientOpCodes;
2
2
  (function (ClientOpCodes) {
3
- ClientOpCodes[ClientOpCodes["Ping"] = 0] = "Ping";
4
- ClientOpCodes[ClientOpCodes["VoiceUpdate"] = 1] = "VoiceUpdate";
5
- ClientOpCodes[ClientOpCodes["PlayerMigrate"] = 2] = "PlayerMigrate";
3
+ ClientOpCodes[ClientOpCodes["VoiceUpdate"] = 0] = "VoiceUpdate";
4
+ ClientOpCodes[ClientOpCodes["PlayerMigrate"] = 1] = "PlayerMigrate";
6
5
  })(ClientOpCodes || (ClientOpCodes = {}));
7
6
  export var ServerOpCodes;
8
7
  (function (ServerOpCodes) {
9
- ServerOpCodes[ServerOpCodes["Pong"] = 0] = "Pong";
10
- ServerOpCodes[ServerOpCodes["Ready"] = 1] = "Ready";
11
- ServerOpCodes[ServerOpCodes["VoiceConnect"] = 2] = "VoiceConnect";
12
- ServerOpCodes[ServerOpCodes["VoiceDisconnect"] = 3] = "VoiceDisconnect";
13
- ServerOpCodes[ServerOpCodes["PlayerUpdate"] = 4] = "PlayerUpdate";
14
- ServerOpCodes[ServerOpCodes["TrackStart"] = 5] = "TrackStart";
15
- ServerOpCodes[ServerOpCodes["TrackEnd"] = 6] = "TrackEnd";
16
- ServerOpCodes[ServerOpCodes["TrackError"] = 7] = "TrackError";
17
- ServerOpCodes[ServerOpCodes["Stats"] = 8] = "Stats";
18
- ServerOpCodes[ServerOpCodes["NodeDraining"] = 9] = "NodeDraining";
19
- ServerOpCodes[ServerOpCodes["MigrateReady"] = 10] = "MigrateReady";
8
+ ServerOpCodes[ServerOpCodes["Ready"] = 0] = "Ready";
9
+ ServerOpCodes[ServerOpCodes["VoiceConnect"] = 1] = "VoiceConnect";
10
+ ServerOpCodes[ServerOpCodes["VoiceDisconnect"] = 2] = "VoiceDisconnect";
11
+ ServerOpCodes[ServerOpCodes["PlayerUpdate"] = 3] = "PlayerUpdate";
12
+ ServerOpCodes[ServerOpCodes["TrackStart"] = 4] = "TrackStart";
13
+ ServerOpCodes[ServerOpCodes["TrackEnd"] = 5] = "TrackEnd";
14
+ ServerOpCodes[ServerOpCodes["TrackError"] = 6] = "TrackError";
15
+ ServerOpCodes[ServerOpCodes["Stats"] = 7] = "Stats";
16
+ ServerOpCodes[ServerOpCodes["NodeDraining"] = 8] = "NodeDraining";
17
+ ServerOpCodes[ServerOpCodes["MigrateReady"] = 9] = "MigrateReady";
20
18
  })(ServerOpCodes || (ServerOpCodes = {}));
21
19
  export var TrackEndReason;
22
20
  (function (TrackEndReason) {
@@ -30,7 +28,30 @@ export var PlayerState;
30
28
  PlayerState["Idle"] = "idle";
31
29
  PlayerState["Playing"] = "playing";
32
30
  PlayerState["Paused"] = "paused";
31
+ PlayerState["Connecting"] = "connecting";
33
32
  })(PlayerState || (PlayerState = {}));
33
+ export var Filter;
34
+ (function (Filter) {
35
+ /** Slows and lowers pitch (speed ×0.8, pitch ×0.8). */
36
+ Filter[Filter["Vaporwave"] = 0] = "Vaporwave";
37
+ /** Speeds up and raises pitch (speed ×1.3, pitch ×1.3). */
38
+ Filter[Filter["Nightcore"] = 1] = "Nightcore";
39
+ /** Rotates audio around the stereo field at 0.2 Hz. */
40
+ Filter[Filter["Rotation"] = 2] = "Rotation";
41
+ /** Oscillates volume at 4 Hz with 0.6 depth. */
42
+ Filter[Filter["Tremolo"] = 3] = "Tremolo";
43
+ /** Oscillates pitch at 4 Hz with 0.5 depth. */
44
+ Filter[Filter["Vibrato"] = 4] = "Vibrato";
45
+ /** Suppresses high frequencies (smoothing factor 20). */
46
+ Filter[Filter["LowPass"] = 5] = "LowPass";
47
+ })(Filter || (Filter = {}));
48
+ export var DisconnectReason;
49
+ (function (DisconnectReason) {
50
+ DisconnectReason["ConnectionLost"] = "connection_lost";
51
+ DisconnectReason["ConnectionFailed"] = "connection_failed";
52
+ DisconnectReason["Requested"] = "requested";
53
+ DisconnectReason["Inactivity"] = "inactivity";
54
+ })(DisconnectReason || (DisconnectReason = {}));
34
55
  export var EventName;
35
56
  (function (EventName) {
36
57
  EventName["Ready"] = "ready";
@@ -41,7 +62,6 @@ export var EventName;
41
62
  EventName["QueueError"] = "queueError";
42
63
  EventName["VoiceConnect"] = "voiceConnect";
43
64
  EventName["VoiceDisconnect"] = "voiceDisconnect";
44
- EventName["Pong"] = "pong";
45
65
  EventName["Stats"] = "stats";
46
66
  EventName["NodeDraining"] = "nodeDraining";
47
67
  EventName["MigrateReady"] = "migrateReady";
@@ -60,7 +80,5 @@ export const Routes = {
60
80
  resume: (sessionId, guildId) => `/sessions/${sessionId}/players/${guildId}/resume`,
61
81
  stop: (sessionId, guildId) => `/sessions/${sessionId}/players/${guildId}/stop`,
62
82
  seek: (sessionId, guildId) => `/sessions/${sessionId}/players/${guildId}/seek`,
63
- volume: (sessionId, guildId) => `/sessions/${sessionId}/players/${guildId}/volume`,
64
83
  disconnect: (sessionId, guildId) => `/sessions/${sessionId}/players/${guildId}`
65
84
  };
66
- //# sourceMappingURL=types.js.map
package/dist/utils.d.ts CHANGED
@@ -3,4 +3,3 @@ export declare const constructUri: {
3
3
  mp3: (url: `http://${string}` | `https://${string}`) => `http://${string}` | `https://${string}`;
4
4
  tts: (text: string, voice: string, translate?: boolean) => string;
5
5
  };
6
- //# sourceMappingURL=utils.d.ts.map
package/dist/utils.js CHANGED
@@ -11,4 +11,3 @@ export const constructUri = {
11
11
  mp3: (url) => url,
12
12
  tts: (text, voice, translate = false) => `tts://invoke?text=${encodeURIComponent(text)}&speaker=${encodeURIComponent(voice)}&translate=${translate ? "true" : "false"}`
13
13
  };
14
- //# sourceMappingURL=utils.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "linkdave",
3
- "version": "0.1.6",
3
+ "version": "0.2.0-dev.db8ab4a",
4
4
  "author": "Luna Seemann <luna@wamellow.com> (http://shi.gg)",
5
5
  "description": "TypeScript client library for linkdave Discord audio streaming server",
6
6
  "repository": {
@@ -31,9 +31,9 @@
31
31
  "packageManager": "bun@1.3.10",
32
32
  "devDependencies": {
33
33
  "@mwlica/eslint": "^1.2.0",
34
- "@types/node": "^25.6.0",
34
+ "@types/node": "^25.9.1",
35
35
  "typescript": "^6.0.3",
36
- "typescript-eslint": "^8.59.0"
36
+ "typescript-eslint": "^8.60.0"
37
37
  },
38
38
  "keywords": [
39
39
  "discord",
@@ -44,6 +44,6 @@
44
44
  ],
45
45
  "license": "AGPL-3.0-only",
46
46
  "dependencies": {
47
- "discord-api-types": "^0.38.47"
47
+ "discord-api-types": "^0.38.48"
48
48
  }
49
- }
49
+ }