@remedia/node 0.1.0-dev.0 → 0.1.0-dev.1

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/filters.js CHANGED
@@ -3,7 +3,12 @@ export class FilterControls {
3
3
  #read;
4
4
  #replace;
5
5
  #clear;
6
- /** @internal Constructed by playback session wrappers. */
6
+ /**
7
+ * @internal Constructed by playback session wrappers.
8
+ * @param read - Callback returning the currently configured raw filtergraph.
9
+ * @param replace - Callback that validates and applies a replacement raw filtergraph.
10
+ * @param clear - Callback that disables the current raw filtergraph.
11
+ */
7
12
  constructor(read, replace, clear) {
8
13
  this.#read = read;
9
14
  this.#replace = replace;
@@ -13,7 +18,11 @@ export class FilterControls {
13
18
  get graph() {
14
19
  return this.#read();
15
20
  }
16
- /** Validate and replace the graph at a safe PCM boundary. */
21
+ /**
22
+ * Validate and replace the graph at a safe PCM boundary.
23
+ * @param graph - Trusted, non-empty raw FFmpeg audio filtergraph; native validation errors reject the operation.
24
+ * @returns Resolves after configuration is applied; rejects for an empty or invalid filtergraph.
25
+ */
17
26
  set(graph) {
18
27
  if (typeof graph !== 'string')
19
28
  throw new TypeError('filtergraph must be a string');
@@ -24,11 +33,18 @@ export class FilterControls {
24
33
  return Promise.resolve();
25
34
  return this.#replace(graph);
26
35
  }
27
- /** Disable the raw filtergraph without changing master volume. */
36
+ /**
37
+ * Disable the raw filtergraph without changing master volume.
38
+ * @returns Resolves when filtering is disabled.
39
+ */
28
40
  clear() {
29
41
  return this.#clear();
30
42
  }
31
43
  }
44
+ /**
45
+ * Validate a finite linear gain in the inclusive range 0 through 2; invalid values throw RangeError.
46
+ * @param gain - Finite linear master gain from 0 through 2; 1 leaves amplitude unchanged.
47
+ */
32
48
  export function validateVolume(gain) {
33
49
  if (!Number.isFinite(gain) || gain < 0 || gain > 2) {
34
50
  throw new RangeError('volume must be a finite linear gain between 0.0 and 2.0');
package/dist/gateway.d.ts CHANGED
@@ -1,28 +1,52 @@
1
1
  /** Minimal Discord Gateway integration used by the Node.js voice adapter. */
2
2
  export interface DiscordGatewayVoicePayload {
3
+ /** Discord Gateway operation code; voice state requests use 4. */
3
4
  op: 4;
5
+ /** Gateway payload data; voice requests contain guild, channel, and self-state fields. */
4
6
  d: {
7
+ /** Discord guild snowflake to route through the bot Gateway. */
5
8
  guild_id: string;
9
+ /** Voice channel snowflake, or null to leave voice. */
6
10
  channel_id: string | null;
7
- self_mute: false;
8
- self_deaf: false;
11
+ /** Discord self-mute flag; independent of playback volume and pause. */
12
+ self_mute: boolean;
13
+ /** Discord self-deaf flag; independent of playback volume and pause. */
14
+ self_deaf: boolean;
9
15
  };
10
16
  }
11
- /** Send a Gateway payload through the application's existing Discord client or shard. */
17
+ /**
18
+ * Send a Gateway payload through the application's existing Discord client or shard.
19
+ * @param guildId - Discord guild snowflake used to route the operation.
20
+ * @param payload - Discord Gateway OP 4 payload to send through the guild shard.
21
+ */
12
22
  export type DiscordGatewaySend = (guildId: string, payload: DiscordGatewayVoicePayload) => void | Promise<void>;
13
23
  /** A raw Discord Gateway packet, such as the value emitted by a client's `raw` event. */
14
24
  export interface DiscordGatewayPacket {
25
+ /** Gateway dispatch event name, when the packet represents a dispatch. */
15
26
  t?: string;
27
+ /** Raw event-specific Gateway payload, validated only for supported voice dispatches. */
16
28
  d?: unknown;
29
+ /** Gateway operation code, when supplied by the host application. */
17
30
  op?: number;
31
+ /**
32
+ * Additional Gateway packet fields forwarded unchanged by the host application.
33
+ * @param key - Additional Gateway packet field name.
34
+ */
18
35
  [key: string]: unknown;
19
36
  }
37
+ /** Gateway dispatch names used to obtain voice transport credentials. */
20
38
  export type DiscordVoiceGatewayEvent = 'VOICE_STATE_UPDATE' | 'VOICE_SERVER_UPDATE';
39
+ /** Validated guild-scoped voice dispatch with sequence and Gateway epoch correlation. */
21
40
  export interface DiscordVoiceGatewayDispatch {
41
+ /** Gateway voice dispatch name. */
22
42
  event: DiscordVoiceGatewayEvent;
43
+ /** Event-specific structured payload. */
23
44
  data: Record<string, unknown>;
45
+ /** Discord guild snowflake as a decimal string; unique within the owning client. */
24
46
  guildId: string;
47
+ /** Host Gateway dispatch sequence used to reject stale voice credentials. */
25
48
  sequence?: number;
49
+ /** Gateway READY epoch used to distinguish independent dispatch sequence spaces. */
26
50
  epoch: number;
27
51
  }
28
52
  /**
@@ -32,14 +56,33 @@ export interface DiscordVoiceGatewayDispatch {
32
56
  */
33
57
  export declare class DiscordGatewayAdapter {
34
58
  #private;
59
+ /**
60
+ * Construct this wrapper with its owning services. Use the owning engine or client factory for application code.
61
+ * @param send - Application callback routing Gateway OP 4 through the correct guild shard.
62
+ */
35
63
  constructor(send: DiscordGatewaySend);
36
64
  /** Most recently observed Gateway dispatch sequence, when supplied by the host client. */
37
65
  get lastSequence(): number | undefined;
38
66
  /** Changes when the host Gateway starts a new READY session and resets its sequence. */
39
67
  get epoch(): number;
40
- /** Request a voice channel join or leave through Gateway OP 4. */
41
- setVoiceChannel(guildId: string, channelId: string | null): void | Promise<void>;
42
- /** Parse only relevant voice dispatches; malformed and unrelated packets are ignored. */
68
+ /**
69
+ * Request a voice channel join or leave through Gateway OP 4.
70
+ * @param guildId - Discord guild snowflake used to route the operation.
71
+ * @param channelId - Destination Discord voice channel snowflake; null requests a leave where supported.
72
+ * @param selfDeaf - Discord self-deaf flag; defaults to true.
73
+ * @param selfMute - Discord self-mute flag; defaults to false.
74
+ */
75
+ setVoiceChannel(guildId: string, channelId: string | null, selfDeaf?: boolean, selfMute?: boolean): void | Promise<void>;
76
+ /**
77
+ * Parse only relevant voice dispatches; malformed and unrelated packets are ignored.
78
+ * @param packet - Raw packet from this bot's Gateway dispatch stream.
79
+ * @returns Validated voice dispatch, or undefined for an unrelated or malformed packet.
80
+ */
43
81
  receive(packet: unknown): DiscordVoiceGatewayDispatch | undefined;
44
82
  }
83
+ /**
84
+ * Check whether a string contains a positive decimal Discord snowflake that fits u64.
85
+ * @param value - Discord snowflake string to validate.
86
+ * @returns True for a valid positive u64 snowflake string.
87
+ */
45
88
  export declare function isSnowflake(value: string): boolean;
package/dist/gateway.js CHANGED
@@ -7,6 +7,10 @@ export class DiscordGatewayAdapter {
7
7
  #send;
8
8
  #lastSequence;
9
9
  #epoch = 0;
10
+ /**
11
+ * Construct this wrapper with its owning services. Use the owning engine or client factory for application code.
12
+ * @param send - Application callback routing Gateway OP 4 through the correct guild shard.
13
+ */
10
14
  constructor(send) {
11
15
  this.#send = send;
12
16
  }
@@ -18,19 +22,29 @@ export class DiscordGatewayAdapter {
18
22
  get epoch() {
19
23
  return this.#epoch;
20
24
  }
21
- /** Request a voice channel join or leave through Gateway OP 4. */
22
- setVoiceChannel(guildId, channelId) {
25
+ /**
26
+ * Request a voice channel join or leave through Gateway OP 4.
27
+ * @param guildId - Discord guild snowflake used to route the operation.
28
+ * @param channelId - Destination Discord voice channel snowflake; null requests a leave where supported.
29
+ * @param selfDeaf - Discord self-deaf flag; defaults to true.
30
+ * @param selfMute - Discord self-mute flag; defaults to false.
31
+ */
32
+ setVoiceChannel(guildId, channelId, selfDeaf = true, selfMute = false) {
23
33
  return this.#send(guildId, {
24
34
  op: 4,
25
35
  d: {
26
36
  guild_id: guildId,
27
37
  channel_id: channelId,
28
- self_mute: false,
29
- self_deaf: false,
38
+ self_mute: selfMute,
39
+ self_deaf: selfDeaf,
30
40
  },
31
41
  });
32
42
  }
33
- /** Parse only relevant voice dispatches; malformed and unrelated packets are ignored. */
43
+ /**
44
+ * Parse only relevant voice dispatches; malformed and unrelated packets are ignored.
45
+ * @param packet - Raw packet from this bot's Gateway dispatch stream.
46
+ * @returns Validated voice dispatch, or undefined for an unrelated or malformed packet.
47
+ */
34
48
  receive(packet) {
35
49
  if (!isRecord(packet) || typeof packet.t !== 'string')
36
50
  return undefined;
@@ -65,6 +79,11 @@ export class DiscordGatewayAdapter {
65
79
  return dispatch;
66
80
  }
67
81
  }
82
+ /**
83
+ * Check whether a string contains a positive decimal Discord snowflake that fits u64.
84
+ * @param value - Discord snowflake string to validate.
85
+ * @returns True for a valid positive u64 snowflake string.
86
+ */
68
87
  export function isSnowflake(value) {
69
88
  if (!/^\d{1,20}$/.test(value))
70
89
  return false;
package/dist/input.d.ts CHANGED
@@ -1,20 +1,46 @@
1
1
  import { Buffer } from 'node:buffer';
2
2
  import type { Readable } from 'node:stream';
3
3
  import type { NativeMediaSource, NativeRemedia } from '../native.js';
4
+ /**
5
+ * Encoded media input. Files and HTTP(S) URLs work in both modes; owned bytes and caller-owned binary Readables require embedded playback.
6
+ */
4
7
  export type MediaSource = {
8
+ /** Local media file path; remote mode resolves it on the server and enforces configured file roots. */
5
9
  file: string;
6
10
  } | {
11
+ /** HTTP(S) media URL opened by the selected engine; remote nodes enforce server URL policy. */
7
12
  url: string;
8
13
  } | {
14
+ /** Owned encoded media bytes, supported by embedded nodes only. */
9
15
  buffer: Buffer | Uint8Array;
10
16
  } | {
17
+ /**
18
+ * Caller-owned binary Readable, consumed with bounded backpressure in embedded mode; Remedia does not destroy it.
19
+ */
11
20
  stream: Readable;
12
21
  };
22
+ /** Internal bounded byte-stream input and cancellation handle owned by a playback wrapper. */
13
23
  export interface ReadableInputHandle {
24
+ /** Native byte-stream source fed by the bounded input pump. */
14
25
  readonly source: NativeMediaSource;
26
+ /**
27
+ * Cancel the native byte queue and detach input-pump listeners without destroying the caller-owned stream.
28
+ * @returns Resolves after the input pump has released its resources.
29
+ */
15
30
  cancel(): Promise<void>;
16
31
  }
32
+ /**
33
+ * Convert a file, HTTP(S) URL, or owned byte input to the native media representation.
34
+ * @param source - Encoded media input; Buffer and caller-owned binary Readable inputs require embedded mode.
35
+ * @returns A native source; bytes are copied into an owned Buffer.
36
+ */
17
37
  export declare function toNativeSource(source: Exclude<MediaSource, {
18
38
  stream: Readable;
19
39
  }>): NativeMediaSource;
40
+ /**
41
+ * Start a bounded native input pump for a caller-owned binary Readable.
42
+ * @param native - Owning native engine instance; its resources must outlive this wrapper.
43
+ * @param stream - Caller-owned binary Readable to consume with bounded native backpressure.
44
+ * @returns Native stream source and an idempotent cancellation handle.
45
+ */
20
46
  export declare function createReadableInput(native: NativeRemedia, stream: Readable): ReadableInputHandle;
package/dist/input.js CHANGED
@@ -1,4 +1,9 @@
1
1
  import { Buffer } from 'node:buffer';
2
+ /**
3
+ * Convert a file, HTTP(S) URL, or owned byte input to the native media representation.
4
+ * @param source - Encoded media input; Buffer and caller-owned binary Readable inputs require embedded mode.
5
+ * @returns A native source; bytes are copied into an owned Buffer.
6
+ */
2
7
  export function toNativeSource(source) {
3
8
  if ('file' in source)
4
9
  return { kind: 'file', value: source.file };
@@ -6,6 +11,12 @@ export function toNativeSource(source) {
6
11
  return { kind: 'url', value: source.url };
7
12
  return { kind: 'buffer', bytes: Buffer.from(source.buffer) };
8
13
  }
14
+ /**
15
+ * Start a bounded native input pump for a caller-owned binary Readable.
16
+ * @param native - Owning native engine instance; its resources must outlive this wrapper.
17
+ * @param stream - Caller-owned binary Readable to consume with bounded native backpressure.
18
+ * @returns Native stream source and an idempotent cancellation handle.
19
+ */
9
20
  export function createReadableInput(native, stream) {
10
21
  const streamId = native.createByteStream();
11
22
  const cancellation = new AbortController();
@@ -2,165 +2,314 @@ import type { MediaSource } from './input.js';
2
2
  import type { AudioStreamInfo, PlaybackPosition, PlaybackState } from './types.js';
3
3
  /** Stable names for playback/session event subscriptions and emission. */
4
4
  export declare const PlaybackSessionEvents: {
5
+ /** Emitted after a source starts and its stream information is available. */
5
6
  readonly playbackStarted: "playbackStarted";
7
+ /** Emitted when a source generation reaches natural end-of-stream. */
6
8
  readonly playbackCompleted: "playbackCompleted";
9
+ /** Emitted when a source generation is explicitly stopped or cancelled. */
7
10
  readonly playbackStopped: "playbackStopped";
11
+ /** Emitted when a source generation fails to open, decode, process, or deliver output. */
8
12
  readonly playbackFailed: "playbackFailed";
13
+ /** Emitted when playback is paused without replacing its source generation. */
9
14
  readonly playbackPaused: "playbackPaused";
15
+ /** Emitted when paused playback resumes. */
10
16
  readonly playbackResumed: "playbackResumed";
17
+ /** Emitted after seeking to a source timeline position. */
11
18
  readonly playbackSeeked: "playbackSeeked";
19
+ /** Emitted when the configured session filtergraph changes. */
12
20
  readonly filterChanged: "filterChanged";
21
+ /** Emitted when the configured session linear gain changes. */
13
22
  readonly volumeChanged: "volumeChanged";
23
+ /** Emitted when a session is unregistered and its owned resources are released. */
14
24
  readonly sessionDisposed: "sessionDisposed";
15
25
  };
26
+ /** Union of the stable event names defined by PlaybackSessionEvents. */
16
27
  export type PlaybackSessionEvents = (typeof PlaybackSessionEvents)[keyof typeof PlaybackSessionEvents];
28
+ /** Stable event names for typed VoiceSessionEvents subscriptions. */
17
29
  export declare const VoiceSessionEvents: {
30
+ /** Emitted when the Discord transport lifecycle state changes. */
18
31
  readonly voiceStateChanged: "voiceStateChanged";
32
+ /** Emitted when voice connection or recovery fails. */
19
33
  readonly voiceFailed: "voiceFailed";
20
34
  };
35
+ /** Union of the stable event names defined by VoiceSessionEvents. */
21
36
  export type VoiceSessionEvents = (typeof VoiceSessionEvents)[keyof typeof VoiceSessionEvents];
37
+ /** Stable event names for typed RemediaEvents subscriptions. */
22
38
  export declare const RemediaEvents: {
39
+ /** Emitted for a structured native diagnostic event. */
23
40
  readonly debug: "debug";
41
+ /** Emitted when the Discord transport lifecycle state changes. */
24
42
  readonly voiceStateChanged: "voiceStateChanged";
43
+ /** Emitted when voice connection or recovery fails. */
25
44
  readonly voiceFailed: "voiceFailed";
45
+ /** Emitted after a source starts and its stream information is available. */
26
46
  readonly playbackStarted: "playbackStarted";
47
+ /** Emitted when a source generation reaches natural end-of-stream. */
27
48
  readonly playbackCompleted: "playbackCompleted";
49
+ /** Emitted when a source generation is explicitly stopped or cancelled. */
28
50
  readonly playbackStopped: "playbackStopped";
51
+ /** Emitted when a source generation fails to open, decode, process, or deliver output. */
29
52
  readonly playbackFailed: "playbackFailed";
53
+ /** Emitted when playback is paused without replacing its source generation. */
30
54
  readonly playbackPaused: "playbackPaused";
55
+ /** Emitted when paused playback resumes. */
31
56
  readonly playbackResumed: "playbackResumed";
57
+ /** Emitted after seeking to a source timeline position. */
32
58
  readonly playbackSeeked: "playbackSeeked";
59
+ /** Emitted when the configured session filtergraph changes. */
33
60
  readonly filterChanged: "filterChanged";
61
+ /** Emitted when the configured session linear gain changes. */
34
62
  readonly volumeChanged: "volumeChanged";
63
+ /** Emitted when a session is unregistered and its owned resources are released. */
35
64
  readonly sessionDisposed: "sessionDisposed";
36
65
  };
66
+ /** Union of the stable event names defined by RemediaEvents. */
37
67
  export type RemediaEvents = (typeof RemediaEvents)[keyof typeof RemediaEvents];
68
+ /**
69
+ * Correlation fields identifying the session and source generation that produced a playback event.
70
+ * @typeParam Metadata - Application-owned metadata attached to playback generations.
71
+ */
38
72
  export interface PlaybackEventIdentity<Metadata = unknown> {
73
+ /** Opaque Remedia session identity used to correlate events; distinct from the Discord bot user ID. */
39
74
  sessionId: string;
75
+ /** Discord guild snowflake as a decimal string; unique within the owning client. */
40
76
  guildId?: string;
77
+ /** Node identifier; embedded session events use null. */
41
78
  nodeId: string | null;
79
+ /** Source generation used to correlate playback events; independent of transport replacement generations. */
42
80
  generation: number;
81
+ /** Application-owned metadata retained locally for the source generation and attached to its events. */
43
82
  customMetadata?: Metadata;
44
83
  /** True only when a terminal event was reconstructed from an authoritative remote snapshot. */
45
84
  reconstructed?: boolean;
46
85
  }
86
+ /**
87
+ * Typed argument tuples for playback lifecycle notifications.
88
+ * @typeParam Metadata - Application-owned metadata attached to playback generations.
89
+ */
47
90
  export type PlaybackLifecycleEvents<Metadata = unknown> = {
91
+ /** Emitted after a source starts and its stream information is available. */
48
92
  [PlaybackSessionEvents.playbackStarted]: [
49
93
  PlaybackEventIdentity<Metadata> & {
94
+ /** Current playback lifecycle state. */
50
95
  state: 'playing';
96
+ /** Metadata for the audio stream that started playback. */
51
97
  info: AudioStreamInfo;
52
98
  }
53
99
  ];
100
+ /** Emitted when a source generation reaches natural end-of-stream. */
54
101
  [PlaybackSessionEvents.playbackCompleted]: [
55
102
  PlaybackEventIdentity<Metadata> & {
103
+ /** Current playback lifecycle state. */
56
104
  state: 'completed';
105
+ /** Latest source and output timeline measurements in milliseconds. */
57
106
  position: PlaybackPosition;
58
107
  }
59
108
  ];
109
+ /** Emitted when a source generation is explicitly stopped or cancelled. */
60
110
  [PlaybackSessionEvents.playbackStopped]: [
61
111
  PlaybackEventIdentity<Metadata> & {
112
+ /** Current playback lifecycle state. */
62
113
  state: 'stopped';
114
+ /** Optional explanation for cancellation or a terminal playback event. */
63
115
  reason?: string;
64
116
  }
65
117
  ];
118
+ /** Emitted when a source generation fails to open, decode, process, or deliver output. */
66
119
  [PlaybackSessionEvents.playbackFailed]: [
67
120
  PlaybackEventIdentity<Metadata> & {
121
+ /** Current playback lifecycle state. */
68
122
  state: 'failed';
123
+ /** Error object describing the operation or source failure. */
69
124
  error: Error;
70
125
  }
71
126
  ];
127
+ /** Emitted when playback is paused without replacing its source generation. */
72
128
  [PlaybackSessionEvents.playbackPaused]: [
73
129
  PlaybackEventIdentity<Metadata> & {
130
+ /** Playback or transport lifecycle state before this transition. */
74
131
  previousState: PlaybackState;
132
+ /** Current playback lifecycle state. */
75
133
  state: 'paused';
76
134
  }
77
135
  ];
136
+ /** Emitted when paused playback resumes. */
78
137
  [PlaybackSessionEvents.playbackResumed]: [
79
138
  PlaybackEventIdentity<Metadata> & {
139
+ /** Playback or transport lifecycle state before this transition. */
80
140
  previousState: PlaybackState;
141
+ /** Current playback lifecycle state. */
81
142
  state: 'playing';
82
143
  }
83
144
  ];
145
+ /** Emitted after seeking to a source timeline position. */
84
146
  [PlaybackSessionEvents.playbackSeeked]: [
85
147
  PlaybackEventIdentity<Metadata> & {
148
+ /** Requested source timeline position in milliseconds. */
86
149
  positionMs: number;
150
+ /** Source timeline position before seeking, in milliseconds, or null when unknown. */
87
151
  previousPositionMs: number | null;
88
152
  }
89
153
  ];
154
+ /** Emitted when the configured session filtergraph changes. */
90
155
  [PlaybackSessionEvents.filterChanged]: [
91
156
  PlaybackEventIdentity<Metadata> & {
157
+ /** Filtergraph active before this change, or null when filtering was disabled. */
92
158
  previousGraph: string | null;
159
+ /** Current raw FFmpeg audio filtergraph, or null when filtering is disabled. */
93
160
  graph: string | null;
94
161
  }
95
162
  ];
163
+ /** Emitted when the configured session linear gain changes. */
96
164
  [PlaybackSessionEvents.volumeChanged]: [
97
165
  PlaybackEventIdentity<Metadata> & {
166
+ /** Linear master gain before this change. */
98
167
  previousVolume: number;
168
+ /** Session master linear gain from 0 through 2, independent of filtergraph processing; defaults to 1. */
99
169
  volume: number;
100
170
  }
101
171
  ];
102
172
  };
173
+ /** Correlation fields identifying the session that produced a voice transport event. */
103
174
  export interface VoiceEventIdentity {
175
+ /** Opaque Remedia session identity used to correlate events; distinct from the Discord bot user ID. */
104
176
  sessionId: string;
177
+ /** Discord guild snowflake as a decimal string; unique within the owning client. */
105
178
  guildId: string;
179
+ /** Node identifier; embedded session events use null. */
106
180
  nodeId: string | null;
107
181
  }
182
+ /** Normalized voice lifecycle state used in events; DAVE negotiation uses negotiating_dave. */
108
183
  export type LifecycleVoiceState = 'connecting' | 'negotiating_dave' | 'connected' | 'reconnecting' | 'disconnecting' | 'disconnected' | 'failed';
184
+ /** Typed argument tuples for voice transport notifications, independent of playback generation. */
109
185
  export type VoiceLifecycleEvents = {
186
+ /** Emitted when the Discord transport lifecycle state changes. */
110
187
  [VoiceSessionEvents.voiceStateChanged]: [
111
188
  VoiceEventIdentity & {
189
+ /** Playback or transport lifecycle state before this transition. */
112
190
  previousState: LifecycleVoiceState;
191
+ /** Current playback lifecycle state. */
113
192
  state: LifecycleVoiceState;
114
193
  }
115
194
  ];
116
- [VoiceSessionEvents.voiceFailed]: [VoiceEventIdentity & {
117
- state: 'failed';
118
- error: Error;
119
- }];
195
+ /** Emitted when voice connection or recovery fails. */
196
+ [VoiceSessionEvents.voiceFailed]: [
197
+ VoiceEventIdentity & {
198
+ /** Current playback lifecycle state. */
199
+ state: 'failed';
200
+ /** Error object describing the operation or source failure. */
201
+ error: Error;
202
+ }
203
+ ];
120
204
  };
205
+ /**
206
+ * Combined playback, voice, and disposal event arguments for a session.
207
+ * @typeParam Metadata - Application-owned metadata attached to playback generations.
208
+ */
121
209
  export type SessionLifecycleEvents<Metadata = unknown> = PlaybackLifecycleEvents<Metadata> & VoiceLifecycleEvents & {
210
+ /** Emitted when a session is unregistered and its owned resources are released. */
122
211
  [PlaybackSessionEvents.sessionDisposed]: [
123
212
  {
213
+ /** Opaque Remedia session identity used to correlate events; distinct from the Discord bot user ID. */
124
214
  sessionId: string;
215
+ /** Discord guild snowflake as a decimal string; unique within the owning client. */
125
216
  guildId?: string;
217
+ /** Node identifier; embedded session events use null. */
126
218
  nodeId: string | null;
219
+ /** Source generation used to correlate playback events; independent of transport replacement generations. */
127
220
  generation: number;
128
221
  }
129
222
  ];
130
223
  };
224
+ /**
225
+ * Playback and disposal event arguments emitted by an embedded playback wrapper.
226
+ * @typeParam Metadata - Application-owned metadata attached to playback generations.
227
+ */
131
228
  export type PlaybackSessionEventMap<Metadata = unknown> = PlaybackLifecycleEvents<Metadata> & {
229
+ /** Emitted when a session is unregistered and its owned resources are released. */
132
230
  [PlaybackSessionEvents.sessionDisposed]: [
133
231
  {
232
+ /** Opaque Remedia session identity used to correlate events; distinct from the Discord bot user ID. */
134
233
  sessionId: string;
234
+ /** Discord guild snowflake as a decimal string; unique within the owning client. */
135
235
  guildId?: string;
236
+ /** Node identifier; embedded session events use null. */
136
237
  nodeId: string | null;
238
+ /** Source generation used to correlate playback events; independent of transport replacement generations. */
137
239
  generation: number;
138
240
  }
139
241
  ];
140
242
  };
243
+ /** Session lifecycle events and native diagnostic notifications forwarded by the embedded engine. */
141
244
  export interface RemediaLifecycleEvents extends SessionLifecycleEvents<unknown> {
245
+ /** Emitted for a structured native diagnostic event. */
142
246
  [RemediaEvents.debug]: [import('./types.js').DiagnosticEvent];
143
247
  }
248
+ /**
249
+ * Local metadata and cancellation options for one playback generation; session configuration persists across generations.
250
+ * @typeParam Metadata - Application-owned metadata attached to playback generations.
251
+ */
144
252
  export interface PlayOptions<Metadata = unknown> {
253
+ /** Application-owned metadata retained locally for the source generation and attached to its events. */
145
254
  customMetadata?: Metadata;
146
- /** Aborting before startup cancels hooks; aborting after startup stops this playback. */
255
+ /**
256
+ * Optional cancellation signal; cancellation before startup prevents playback, and cancellation after startup stops that generation.
257
+ */
147
258
  signal?: AbortSignal;
148
259
  }
260
+ /**
261
+ * Caller-owned media input, metadata, and cancellation signal supplied to each awaited pre-play hook.
262
+ * @typeParam Metadata - Application-owned metadata attached to playback generations.
263
+ */
149
264
  export interface BeforePlayContext<Metadata = unknown> {
265
+ /** Caller-owned encoded input that the hooks inspect before the decoder opens it. */
150
266
  readonly source: MediaSource;
267
+ /** Application-owned metadata retained locally for the source generation and attached to its events. */
151
268
  readonly customMetadata: Metadata | undefined;
152
- /** Aborted when the operation signal fires or the session is disposed. */
269
+ /** Cancellation signal for this hook invocation; check it before performing asynchronous work. */
153
270
  readonly signal: AbortSignal;
154
271
  }
272
+ /**
273
+ * Hook result: return nothing to continue, or cancel with an optional explanation to reject playback with AbortError.
274
+ */
155
275
  export type BeforePlayResult = void | {
276
+ /** Return true from a pre-play hook to reject playback before opening the source. */
156
277
  cancel: true;
278
+ /** Optional explanation for cancellation or a terminal playback event. */
157
279
  reason?: string;
158
280
  };
281
+ /**
282
+ * Awaited local callback run before a source opens; rejection or cancellation prevents that source from starting.
283
+ * @typeParam Metadata - Application-owned metadata attached to playback generations.
284
+ * @param context - Source, local metadata, and cancellation signal supplied to the awaited hooks.
285
+ * @returns Nothing to continue, or a cancellation result; a promise is awaited before source opening.
286
+ */
159
287
  export type BeforePlayHook<Metadata = unknown> = (context: BeforePlayContext<Metadata>) => BeforePlayResult | Promise<BeforePlayResult>;
160
- /** Ordered, awaited local middleware. It is not a server authorization mechanism. */
288
+ /**
289
+ * Ordered, awaited local middleware. It is not a server authorization mechanism.
290
+ * @typeParam Metadata - Application-owned metadata attached to playback generations.
291
+ */
161
292
  export declare class PlaybackHooks<Metadata = unknown> {
162
293
  #private;
294
+ /**
295
+ * Append an awaited pre-play hook. Hooks run in registration order before a source opens.
296
+ * @param hook - Local callback to await before opening each source; returning cancel rejects playback.
297
+ * @returns An idempotent function that removes this hook registration.
298
+ */
163
299
  beforePlay(hook: BeforePlayHook<Metadata>): () => void;
300
+ /**
301
+ * Run registered pre-play hooks in order and reject on cancellation or hook failure.
302
+ * @param context - Source, local metadata, and cancellation signal supplied to the awaited hooks.
303
+ * @returns Resolves when every hook permits playback; cancellation rejects with AbortError.
304
+ */
164
305
  runBeforePlay(context: BeforePlayContext<Metadata>): Promise<void>;
165
306
  }
307
+ /**
308
+ * Create playback event correlation fields for one local source generation.
309
+ * @param generation - Native source generation associated with the lifecycle notification.
310
+ * @param customMetadata - Application-owned metadata associated with this source generation.
311
+ * @returns Identity fields with metadata included only when provided.
312
+ * @typeParam Metadata - Application-owned metadata attached to playback generations.
313
+ * @param sessionId - Opaque Remedia session identity used for event correlation.
314
+ */
166
315
  export declare function lifecycleContext<Metadata>(sessionId: string, generation: number, customMetadata: Metadata | undefined): PlaybackEventIdentity<Metadata>;