audio-channel-queue 1.9.0 → 1.11.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.
package/dist/index.d.ts CHANGED
@@ -3,12 +3,13 @@
3
3
  * Exports all public functions and types for audio queue management, pause/resume controls,
4
4
  * volume management with ducking, progress tracking, and comprehensive event system
5
5
  */
6
- export { queueAudio, queueAudioPriority, stopCurrentAudioInChannel, stopAllAudioInChannel, stopAllAudio, playAudioQueue } from './core';
6
+ export { queueAudio, queueAudioPriority, stopCurrentAudioInChannel, stopAllAudioInChannel, stopAllAudio, playAudioQueue, destroyChannel, destroyAllChannels, setQueueConfig, getQueueConfig, setChannelQueueLimit } from './core';
7
+ export { clearQueueAfterCurrent, getQueueItemInfo, getQueueLength, removeQueuedItem, reorderQueue, swapQueueItems } from './queue-manipulation';
7
8
  export { getErrorRecovery, getRetryConfig, offAudioError, onAudioError, retryFailedAudio, setErrorRecovery, setRetryConfig } from './errors';
8
9
  export { getAllChannelsPauseState, isChannelPaused, pauseAllChannels, pauseAllWithFade, pauseChannel, pauseWithFade, resumeAllChannels, resumeAllWithFade, resumeChannel, resumeWithFade, togglePauseAllChannels, togglePauseAllWithFade, togglePauseChannel, togglePauseWithFade } from './pause';
9
- export { clearVolumeDucking, fadeVolume, getAllChannelsVolume, getChannelVolume, getFadeConfig, setAllChannelsVolume, setChannelVolume, setVolumeDucking, transitionVolume } from './volume';
10
- export { getAllChannelsInfo, getCurrentAudioInfo, getQueueSnapshot, offAudioPause, offAudioProgress, offAudioResume, offQueueChange, onAudioComplete, onAudioPause, onAudioProgress, onAudioResume, onAudioStart, onQueueChange } from './info';
10
+ export { clearVolumeDucking, fadeVolume, getAllChannelsVolume, getChannelVolume, getFadeConfig, setAllChannelsVolume, setChannelVolume, setVolumeDucking, transitionVolume, cancelVolumeTransition, cancelAllVolumeTransitions } from './volume';
11
+ export { getAllChannelsInfo, getCurrentAudioInfo, getQueueSnapshot, offAudioComplete, offAudioPause, offAudioProgress, offAudioResume, offAudioStart, offQueueChange, onAudioComplete, onAudioPause, onAudioProgress, onAudioResume, onAudioStart, onQueueChange } from './info';
11
12
  export { audioChannels } from './info';
12
- export { cleanWebpackFilename, createQueueSnapshot, extractFileName, getAudioInfoFromElement } from './utils';
13
- export type { AudioCompleteCallback, AudioCompleteInfo, AudioErrorCallback, AudioErrorInfo, AudioInfo, AudioPauseCallback, AudioQueueOptions, AudioResumeCallback, AudioStartCallback, AudioStartInfo, ChannelFadeState, ErrorRecoveryOptions, ExtendedAudioQueueChannel, FadeConfig, ProgressCallback, QueueChangeCallback, QueueItem, QueueSnapshot, RetryConfig, VolumeConfig } from './types';
14
- export { EasingType, FadeType, GLOBAL_PROGRESS_KEY } from './types';
13
+ export { cleanWebpackFilename, createQueueSnapshot, extractFileName, getAudioInfoFromElement, sanitizeForDisplay, validateAudioUrl } from './utils';
14
+ export type { AudioCompleteCallback, AudioCompleteInfo, AudioErrorCallback, AudioErrorInfo, AudioInfo, AudioPauseCallback, AudioQueueOptions, AudioResumeCallback, AudioStartCallback, AudioStartInfo, ChannelFadeState, ErrorRecoveryOptions, ExtendedAudioQueueChannel, FadeConfig, ProgressCallback, QueueChangeCallback, QueueItem, QueueManipulationResult, QueueSnapshot, RetryConfig, VolumeConfig, QueueConfig } from './types';
15
+ export { EasingType, FadeType, MAX_CHANNELS, TimerType, GLOBAL_PROGRESS_KEY } from './types';
package/dist/index.js CHANGED
@@ -5,8 +5,8 @@
5
5
  * volume management with ducking, progress tracking, and comprehensive event system
6
6
  */
7
7
  Object.defineProperty(exports, "__esModule", { value: true });
8
- exports.audioChannels = exports.onQueueChange = exports.onAudioStart = exports.onAudioResume = exports.onAudioProgress = exports.onAudioPause = exports.onAudioComplete = exports.offQueueChange = exports.offAudioResume = exports.offAudioProgress = exports.offAudioPause = exports.getQueueSnapshot = exports.getCurrentAudioInfo = exports.getAllChannelsInfo = exports.transitionVolume = exports.setVolumeDucking = exports.setChannelVolume = exports.setAllChannelsVolume = exports.getFadeConfig = exports.getChannelVolume = exports.getAllChannelsVolume = exports.fadeVolume = exports.clearVolumeDucking = exports.togglePauseWithFade = exports.togglePauseChannel = exports.togglePauseAllWithFade = exports.togglePauseAllChannels = exports.resumeWithFade = exports.resumeChannel = exports.resumeAllWithFade = exports.resumeAllChannels = exports.pauseWithFade = exports.pauseChannel = exports.pauseAllWithFade = exports.pauseAllChannels = exports.isChannelPaused = exports.getAllChannelsPauseState = exports.setRetryConfig = exports.setErrorRecovery = exports.retryFailedAudio = exports.onAudioError = exports.offAudioError = exports.getRetryConfig = exports.getErrorRecovery = exports.playAudioQueue = exports.stopAllAudio = exports.stopAllAudioInChannel = exports.stopCurrentAudioInChannel = exports.queueAudioPriority = exports.queueAudio = void 0;
9
- exports.GLOBAL_PROGRESS_KEY = exports.FadeType = exports.EasingType = exports.getAudioInfoFromElement = exports.extractFileName = exports.createQueueSnapshot = exports.cleanWebpackFilename = void 0;
8
+ exports.getAllChannelsInfo = exports.cancelAllVolumeTransitions = exports.cancelVolumeTransition = exports.transitionVolume = exports.setVolumeDucking = exports.setChannelVolume = exports.setAllChannelsVolume = exports.getFadeConfig = exports.getChannelVolume = exports.getAllChannelsVolume = exports.fadeVolume = exports.clearVolumeDucking = exports.togglePauseWithFade = exports.togglePauseChannel = exports.togglePauseAllWithFade = exports.togglePauseAllChannels = exports.resumeWithFade = exports.resumeChannel = exports.resumeAllWithFade = exports.resumeAllChannels = exports.pauseWithFade = exports.pauseChannel = exports.pauseAllWithFade = exports.pauseAllChannels = exports.isChannelPaused = exports.getAllChannelsPauseState = exports.setRetryConfig = exports.setErrorRecovery = exports.retryFailedAudio = exports.onAudioError = exports.offAudioError = exports.getRetryConfig = exports.getErrorRecovery = exports.swapQueueItems = exports.reorderQueue = exports.removeQueuedItem = exports.getQueueLength = exports.getQueueItemInfo = exports.clearQueueAfterCurrent = exports.setChannelQueueLimit = exports.getQueueConfig = exports.setQueueConfig = exports.destroyAllChannels = exports.destroyChannel = exports.playAudioQueue = exports.stopAllAudio = exports.stopAllAudioInChannel = exports.stopCurrentAudioInChannel = exports.queueAudioPriority = exports.queueAudio = void 0;
9
+ exports.GLOBAL_PROGRESS_KEY = exports.TimerType = exports.MAX_CHANNELS = exports.FadeType = exports.EasingType = exports.validateAudioUrl = exports.sanitizeForDisplay = exports.getAudioInfoFromElement = exports.extractFileName = exports.createQueueSnapshot = exports.cleanWebpackFilename = exports.audioChannels = exports.onQueueChange = exports.onAudioStart = exports.onAudioResume = exports.onAudioProgress = exports.onAudioPause = exports.onAudioComplete = exports.offQueueChange = exports.offAudioStart = exports.offAudioResume = exports.offAudioProgress = exports.offAudioPause = exports.offAudioComplete = exports.getQueueSnapshot = exports.getCurrentAudioInfo = void 0;
10
10
  // Core queue management functions
11
11
  var core_1 = require("./core");
12
12
  Object.defineProperty(exports, "queueAudio", { enumerable: true, get: function () { return core_1.queueAudio; } });
@@ -15,6 +15,19 @@ Object.defineProperty(exports, "stopCurrentAudioInChannel", { enumerable: true,
15
15
  Object.defineProperty(exports, "stopAllAudioInChannel", { enumerable: true, get: function () { return core_1.stopAllAudioInChannel; } });
16
16
  Object.defineProperty(exports, "stopAllAudio", { enumerable: true, get: function () { return core_1.stopAllAudio; } });
17
17
  Object.defineProperty(exports, "playAudioQueue", { enumerable: true, get: function () { return core_1.playAudioQueue; } });
18
+ Object.defineProperty(exports, "destroyChannel", { enumerable: true, get: function () { return core_1.destroyChannel; } });
19
+ Object.defineProperty(exports, "destroyAllChannels", { enumerable: true, get: function () { return core_1.destroyAllChannels; } });
20
+ Object.defineProperty(exports, "setQueueConfig", { enumerable: true, get: function () { return core_1.setQueueConfig; } });
21
+ Object.defineProperty(exports, "getQueueConfig", { enumerable: true, get: function () { return core_1.getQueueConfig; } });
22
+ Object.defineProperty(exports, "setChannelQueueLimit", { enumerable: true, get: function () { return core_1.setChannelQueueLimit; } });
23
+ // Queue manipulation functions
24
+ var queue_manipulation_1 = require("./queue-manipulation");
25
+ Object.defineProperty(exports, "clearQueueAfterCurrent", { enumerable: true, get: function () { return queue_manipulation_1.clearQueueAfterCurrent; } });
26
+ Object.defineProperty(exports, "getQueueItemInfo", { enumerable: true, get: function () { return queue_manipulation_1.getQueueItemInfo; } });
27
+ Object.defineProperty(exports, "getQueueLength", { enumerable: true, get: function () { return queue_manipulation_1.getQueueLength; } });
28
+ Object.defineProperty(exports, "removeQueuedItem", { enumerable: true, get: function () { return queue_manipulation_1.removeQueuedItem; } });
29
+ Object.defineProperty(exports, "reorderQueue", { enumerable: true, get: function () { return queue_manipulation_1.reorderQueue; } });
30
+ Object.defineProperty(exports, "swapQueueItems", { enumerable: true, get: function () { return queue_manipulation_1.swapQueueItems; } });
18
31
  // Error handling and recovery functions
19
32
  var errors_1 = require("./errors");
20
33
  Object.defineProperty(exports, "getErrorRecovery", { enumerable: true, get: function () { return errors_1.getErrorRecovery; } });
@@ -51,14 +64,18 @@ Object.defineProperty(exports, "setAllChannelsVolume", { enumerable: true, get:
51
64
  Object.defineProperty(exports, "setChannelVolume", { enumerable: true, get: function () { return volume_1.setChannelVolume; } });
52
65
  Object.defineProperty(exports, "setVolumeDucking", { enumerable: true, get: function () { return volume_1.setVolumeDucking; } });
53
66
  Object.defineProperty(exports, "transitionVolume", { enumerable: true, get: function () { return volume_1.transitionVolume; } });
67
+ Object.defineProperty(exports, "cancelVolumeTransition", { enumerable: true, get: function () { return volume_1.cancelVolumeTransition; } });
68
+ Object.defineProperty(exports, "cancelAllVolumeTransitions", { enumerable: true, get: function () { return volume_1.cancelAllVolumeTransitions; } });
54
69
  // Audio information and progress tracking functions
55
70
  var info_1 = require("./info");
56
71
  Object.defineProperty(exports, "getAllChannelsInfo", { enumerable: true, get: function () { return info_1.getAllChannelsInfo; } });
57
72
  Object.defineProperty(exports, "getCurrentAudioInfo", { enumerable: true, get: function () { return info_1.getCurrentAudioInfo; } });
58
73
  Object.defineProperty(exports, "getQueueSnapshot", { enumerable: true, get: function () { return info_1.getQueueSnapshot; } });
74
+ Object.defineProperty(exports, "offAudioComplete", { enumerable: true, get: function () { return info_1.offAudioComplete; } });
59
75
  Object.defineProperty(exports, "offAudioPause", { enumerable: true, get: function () { return info_1.offAudioPause; } });
60
76
  Object.defineProperty(exports, "offAudioProgress", { enumerable: true, get: function () { return info_1.offAudioProgress; } });
61
77
  Object.defineProperty(exports, "offAudioResume", { enumerable: true, get: function () { return info_1.offAudioResume; } });
78
+ Object.defineProperty(exports, "offAudioStart", { enumerable: true, get: function () { return info_1.offAudioStart; } });
62
79
  Object.defineProperty(exports, "offQueueChange", { enumerable: true, get: function () { return info_1.offQueueChange; } });
63
80
  Object.defineProperty(exports, "onAudioComplete", { enumerable: true, get: function () { return info_1.onAudioComplete; } });
64
81
  Object.defineProperty(exports, "onAudioPause", { enumerable: true, get: function () { return info_1.onAudioPause; } });
@@ -75,8 +92,12 @@ Object.defineProperty(exports, "cleanWebpackFilename", { enumerable: true, get:
75
92
  Object.defineProperty(exports, "createQueueSnapshot", { enumerable: true, get: function () { return utils_1.createQueueSnapshot; } });
76
93
  Object.defineProperty(exports, "extractFileName", { enumerable: true, get: function () { return utils_1.extractFileName; } });
77
94
  Object.defineProperty(exports, "getAudioInfoFromElement", { enumerable: true, get: function () { return utils_1.getAudioInfoFromElement; } });
95
+ Object.defineProperty(exports, "sanitizeForDisplay", { enumerable: true, get: function () { return utils_1.sanitizeForDisplay; } });
96
+ Object.defineProperty(exports, "validateAudioUrl", { enumerable: true, get: function () { return utils_1.validateAudioUrl; } });
78
97
  // Enums and constants
79
98
  var types_1 = require("./types");
80
99
  Object.defineProperty(exports, "EasingType", { enumerable: true, get: function () { return types_1.EasingType; } });
81
100
  Object.defineProperty(exports, "FadeType", { enumerable: true, get: function () { return types_1.FadeType; } });
101
+ Object.defineProperty(exports, "MAX_CHANNELS", { enumerable: true, get: function () { return types_1.MAX_CHANNELS; } });
102
+ Object.defineProperty(exports, "TimerType", { enumerable: true, get: function () { return types_1.TimerType; } });
82
103
  Object.defineProperty(exports, "GLOBAL_PROGRESS_KEY", { enumerable: true, get: function () { return types_1.GLOBAL_PROGRESS_KEY; } });
package/dist/info.d.ts CHANGED
@@ -2,9 +2,35 @@
2
2
  * @fileoverview Audio information and progress tracking functions for the audio-channel-queue package
3
3
  */
4
4
  import { AudioInfo, QueueSnapshot, ProgressCallback, QueueChangeCallback, AudioStartCallback, AudioCompleteCallback, AudioPauseCallback, AudioResumeCallback, ExtendedAudioQueueChannel } from './types';
5
+ /**
6
+ * Gets the current list of whitelisted channel properties
7
+ * This is automatically derived from the ExtendedAudioQueueChannel interface
8
+ * @returns Array of whitelisted property names
9
+ * @internal
10
+ */
11
+ export declare const getWhitelistedChannelProperties: () => string[];
12
+ /**
13
+ * Returns the list of non-whitelisted properties found on a specific channel
14
+ * These are properties that will trigger warnings when modified directly
15
+ * @param channelNumber - The channel number to inspect (defaults to 0)
16
+ * @returns Array of property names that are not in the whitelist, or empty array if channel doesn't exist
17
+ * @example
18
+ * ```typescript
19
+ * // Add some custom property to a channel
20
+ * (audioChannels[0] as any).customProperty = 'test';
21
+ *
22
+ * const nonWhitelisted = getNonWhitelistedChannelProperties(0);
23
+ * console.log(nonWhitelisted); // ['customProperty']
24
+ * ```
25
+ * @internal
26
+ */
27
+ export declare const getNonWhitelistedChannelProperties: (channelNumber?: number) => string[];
5
28
  /**
6
29
  * Global array to store audio channels with their queues and callback management
7
30
  * Each channel maintains its own audio queue and event callback sets
31
+ *
32
+ * Note: While you can inspect this array for debugging, direct modification is discouraged.
33
+ * Use the provided API functions for safe channel management.
8
34
  */
9
35
  export declare const audioChannels: ExtendedAudioQueueChannel[];
10
36
  /**
@@ -37,22 +63,24 @@ export declare const getCurrentAudioInfo: (channelNumber?: number) => AudioInfo
37
63
  export declare const getAllChannelsInfo: () => (AudioInfo | null)[];
38
64
  /**
39
65
  * Gets a complete snapshot of the queue state for a specific channel
40
- * @param channelNumber - The channel number
66
+ * @param channelNumber - The channel number (defaults to 0)
41
67
  * @returns QueueSnapshot object or null if channel doesn't exist
42
68
  * @example
43
69
  * ```typescript
44
- * const snapshot = getQueueSnapshot(0);
70
+ * const snapshot = getQueueSnapshot();
45
71
  * if (snapshot) {
46
72
  * console.log(`Queue has ${snapshot.totalItems} items`);
47
73
  * console.log(`Currently playing: ${snapshot.items[0]?.fileName}`);
48
74
  * }
75
+ * const channelSnapshot = getQueueSnapshot(2);
49
76
  * ```
50
77
  */
51
- export declare const getQueueSnapshot: (channelNumber: number) => QueueSnapshot | null;
78
+ export declare const getQueueSnapshot: (channelNumber?: number) => QueueSnapshot | null;
52
79
  /**
53
80
  * Subscribes to real-time progress updates for a specific channel
54
81
  * @param channelNumber - The channel number
55
82
  * @param callback - Function to call with audio info updates
83
+ * @throws Error if the channel number exceeds the maximum allowed channels
56
84
  * @example
57
85
  * ```typescript
58
86
  * onAudioProgress(0, (info) => {
@@ -64,17 +92,19 @@ export declare const getQueueSnapshot: (channelNumber: number) => QueueSnapshot
64
92
  export declare const onAudioProgress: (channelNumber: number, callback: ProgressCallback) => void;
65
93
  /**
66
94
  * Removes progress listeners for a specific channel
67
- * @param channelNumber - The channel number
95
+ * @param channelNumber - The channel number (defaults to 0)
68
96
  * @example
69
97
  * ```typescript
70
- * offAudioProgress(0); // Stop receiving progress updates for channel 0
98
+ * offAudioProgress();
99
+ * offAudioProgress(1); // Stop receiving progress updates for channel 1
71
100
  * ```
72
101
  */
73
- export declare const offAudioProgress: (channelNumber: number) => void;
102
+ export declare function offAudioProgress(channelNumber?: number): void;
74
103
  /**
75
104
  * Subscribes to queue change events for a specific channel
76
105
  * @param channelNumber - The channel number to monitor
77
106
  * @param callback - Function to call when queue changes
107
+ * @throws Error if the channel number exceeds the maximum allowed channels
78
108
  * @example
79
109
  * ```typescript
80
110
  * onQueueChange(0, (snapshot) => {
@@ -97,6 +127,7 @@ export declare const offQueueChange: (channelNumber: number) => void;
97
127
  * Subscribes to audio start events for a specific channel
98
128
  * @param channelNumber - The channel number to monitor
99
129
  * @param callback - Function to call when audio starts playing
130
+ * @throws Error if the channel number exceeds the maximum allowed channels
100
131
  * @example
101
132
  * ```typescript
102
133
  * onAudioStart(0, (info) => {
@@ -110,6 +141,7 @@ export declare const onAudioStart: (channelNumber: number, callback: AudioStartC
110
141
  * Subscribes to audio complete events for a specific channel
111
142
  * @param channelNumber - The channel number to monitor
112
143
  * @param callback - Function to call when audio completes
144
+ * @throws Error if the channel number exceeds the maximum allowed channels
113
145
  * @example
114
146
  * ```typescript
115
147
  * onAudioComplete(0, (info) => {
@@ -125,6 +157,7 @@ export declare const onAudioComplete: (channelNumber: number, callback: AudioCom
125
157
  * Subscribes to audio pause events for a specific channel
126
158
  * @param channelNumber - The channel number to monitor
127
159
  * @param callback - Function to call when audio is paused
160
+ * @throws Error if the channel number exceeds the maximum allowed channels
128
161
  * @example
129
162
  * ```typescript
130
163
  * onAudioPause(0, (channelNumber, info) => {
@@ -138,6 +171,7 @@ export declare const onAudioPause: (channelNumber: number, callback: AudioPauseC
138
171
  * Subscribes to audio resume events for a specific channel
139
172
  * @param channelNumber - The channel number to monitor
140
173
  * @param callback - Function to call when audio is resumed
174
+ * @throws Error if the channel number exceeds the maximum allowed channels
141
175
  * @example
142
176
  * ```typescript
143
177
  * onAudioResume(0, (channelNumber, info) => {
@@ -165,3 +199,21 @@ export declare const offAudioPause: (channelNumber: number) => void;
165
199
  * ```
166
200
  */
167
201
  export declare const offAudioResume: (channelNumber: number) => void;
202
+ /**
203
+ * Removes audio start event listeners for a specific channel
204
+ * @param channelNumber - The channel number
205
+ * @example
206
+ * ```typescript
207
+ * offAudioStart(0); // Stop receiving start notifications for channel 0
208
+ * ```
209
+ */
210
+ export declare const offAudioStart: (channelNumber: number) => void;
211
+ /**
212
+ * Removes audio complete event listeners for a specific channel
213
+ * @param channelNumber - The channel number
214
+ * @example
215
+ * ```typescript
216
+ * offAudioComplete(0); // Stop receiving completion notifications for channel 0
217
+ * ```
218
+ */
219
+ export declare const offAudioComplete: (channelNumber: number) => void;
package/dist/info.js CHANGED
@@ -3,15 +3,134 @@
3
3
  * @fileoverview Audio information and progress tracking functions for the audio-channel-queue package
4
4
  */
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.offAudioResume = exports.offAudioPause = exports.onAudioResume = exports.onAudioPause = exports.onAudioComplete = exports.onAudioStart = exports.offQueueChange = exports.onQueueChange = exports.offAudioProgress = exports.onAudioProgress = exports.getQueueSnapshot = exports.getAllChannelsInfo = exports.getCurrentAudioInfo = exports.audioChannels = void 0;
6
+ exports.offAudioComplete = exports.offAudioStart = exports.offAudioResume = exports.offAudioPause = exports.onAudioResume = exports.onAudioPause = exports.onAudioComplete = exports.onAudioStart = exports.offQueueChange = exports.onQueueChange = exports.onAudioProgress = exports.getQueueSnapshot = exports.getAllChannelsInfo = exports.getCurrentAudioInfo = exports.audioChannels = exports.getNonWhitelistedChannelProperties = exports.getWhitelistedChannelProperties = void 0;
7
+ exports.offAudioProgress = offAudioProgress;
7
8
  const types_1 = require("./types");
8
9
  const utils_1 = require("./utils");
9
10
  const events_1 = require("./events");
11
+ /**
12
+ * Gets the current list of whitelisted channel properties
13
+ * This is automatically derived from the ExtendedAudioQueueChannel interface
14
+ * @returns Array of whitelisted property names
15
+ * @internal
16
+ */
17
+ const getWhitelistedChannelProperties = () => {
18
+ // Create a sample channel object to extract property names
19
+ const sampleChannel = {
20
+ audioCompleteCallbacks: new Set(),
21
+ audioErrorCallbacks: new Set(),
22
+ audioPauseCallbacks: new Set(),
23
+ audioResumeCallbacks: new Set(),
24
+ audioStartCallbacks: new Set(),
25
+ isPaused: false,
26
+ progressCallbacks: new Map(),
27
+ queue: [],
28
+ queueChangeCallbacks: new Set(),
29
+ volume: 1.0
30
+ };
31
+ // Get all property names from the interface (including optional ones)
32
+ const propertyNames = [
33
+ ...Object.getOwnPropertyNames(sampleChannel),
34
+ // Add optional properties that might not be present on the sample
35
+ 'fadeState',
36
+ 'isLocked',
37
+ 'maxQueueSize',
38
+ 'retryConfig',
39
+ 'volumeConfig' // Legacy property that might still be used
40
+ ];
41
+ return [...new Set(propertyNames)]; // Remove duplicates
42
+ };
43
+ exports.getWhitelistedChannelProperties = getWhitelistedChannelProperties;
44
+ /**
45
+ * Returns the list of non-whitelisted properties found on a specific channel
46
+ * These are properties that will trigger warnings when modified directly
47
+ * @param channelNumber - The channel number to inspect (defaults to 0)
48
+ * @returns Array of property names that are not in the whitelist, or empty array if channel doesn't exist
49
+ * @example
50
+ * ```typescript
51
+ * // Add some custom property to a channel
52
+ * (audioChannels[0] as any).customProperty = 'test';
53
+ *
54
+ * const nonWhitelisted = getNonWhitelistedChannelProperties(0);
55
+ * console.log(nonWhitelisted); // ['customProperty']
56
+ * ```
57
+ * @internal
58
+ */
59
+ const getNonWhitelistedChannelProperties = (channelNumber = 0) => {
60
+ const channel = exports.audioChannels[channelNumber];
61
+ if (!channel) {
62
+ return [];
63
+ }
64
+ const whitelistedProperties = (0, exports.getWhitelistedChannelProperties)();
65
+ const allChannelProperties = Object.getOwnPropertyNames(channel);
66
+ // Filter out properties that are in the whitelist
67
+ const nonWhitelistedProperties = allChannelProperties.filter((property) => !whitelistedProperties.includes(property));
68
+ return nonWhitelistedProperties;
69
+ };
70
+ exports.getNonWhitelistedChannelProperties = getNonWhitelistedChannelProperties;
10
71
  /**
11
72
  * Global array to store audio channels with their queues and callback management
12
73
  * Each channel maintains its own audio queue and event callback sets
74
+ *
75
+ * Note: While you can inspect this array for debugging, direct modification is discouraged.
76
+ * Use the provided API functions for safe channel management.
13
77
  */
14
- exports.audioChannels = [];
78
+ exports.audioChannels = new Proxy([], {
79
+ deleteProperty(target, prop) {
80
+ if (typeof prop === 'string' && !isNaN(Number(prop))) {
81
+ // eslint-disable-next-line no-console
82
+ console.warn('Warning: Direct deletion from audioChannels detected. ' +
83
+ 'Consider using stopAllAudioInChannel() for proper cleanup.');
84
+ }
85
+ delete target[prop];
86
+ return true;
87
+ },
88
+ get(target, prop) {
89
+ const value = target[prop];
90
+ // Return channel objects with warnings on modification attempts
91
+ if (typeof value === 'object' &&
92
+ value !== null &&
93
+ typeof prop === 'string' &&
94
+ !isNaN(Number(prop))) {
95
+ return new Proxy(value, {
96
+ set(channelTarget, channelProp, channelValue) {
97
+ // Allow internal modifications but warn about direct property changes
98
+ // Use the automatically-derived whitelist from the interface
99
+ const whitelistedProperties = (0, exports.getWhitelistedChannelProperties)();
100
+ if (typeof channelProp === 'string' && !whitelistedProperties.includes(channelProp)) {
101
+ // eslint-disable-next-line no-console
102
+ console.warn(`Warning: Direct modification of channel.${channelProp} detected. ` +
103
+ 'Use API functions for safer channel management.');
104
+ }
105
+ const key = typeof channelProp === 'symbol' ? channelProp.toString() : channelProp;
106
+ channelTarget[key] = channelValue;
107
+ return true;
108
+ }
109
+ });
110
+ }
111
+ return value;
112
+ },
113
+ set(target, prop, value) {
114
+ // Allow normal array operations
115
+ const key = typeof prop === 'symbol' ? prop.toString() : prop;
116
+ target[key] = value;
117
+ return true;
118
+ }
119
+ });
120
+ /**
121
+ * Validates a channel number against MAX_CHANNELS limit
122
+ * @param channelNumber - The channel number to validate
123
+ * @throws Error if the channel number is invalid
124
+ * @internal
125
+ */
126
+ const validateChannelNumber = (channelNumber) => {
127
+ if (channelNumber < 0) {
128
+ throw new Error('Channel number must be non-negative');
129
+ }
130
+ if (channelNumber >= types_1.MAX_CHANNELS) {
131
+ throw new Error(`Channel number ${channelNumber} exceeds maximum allowed channels (${types_1.MAX_CHANNELS})`);
132
+ }
133
+ };
15
134
  /**
16
135
  * Gets current audio information for a specific channel
17
136
  * @param channelNumber - The channel number (defaults to 0)
@@ -57,18 +176,19 @@ const getAllChannelsInfo = () => {
57
176
  exports.getAllChannelsInfo = getAllChannelsInfo;
58
177
  /**
59
178
  * Gets a complete snapshot of the queue state for a specific channel
60
- * @param channelNumber - The channel number
179
+ * @param channelNumber - The channel number (defaults to 0)
61
180
  * @returns QueueSnapshot object or null if channel doesn't exist
62
181
  * @example
63
182
  * ```typescript
64
- * const snapshot = getQueueSnapshot(0);
183
+ * const snapshot = getQueueSnapshot();
65
184
  * if (snapshot) {
66
185
  * console.log(`Queue has ${snapshot.totalItems} items`);
67
186
  * console.log(`Currently playing: ${snapshot.items[0]?.fileName}`);
68
187
  * }
188
+ * const channelSnapshot = getQueueSnapshot(2);
69
189
  * ```
70
190
  */
71
- const getQueueSnapshot = (channelNumber) => {
191
+ const getQueueSnapshot = (channelNumber = 0) => {
72
192
  return (0, utils_1.createQueueSnapshot)(channelNumber, exports.audioChannels);
73
193
  };
74
194
  exports.getQueueSnapshot = getQueueSnapshot;
@@ -76,6 +196,7 @@ exports.getQueueSnapshot = getQueueSnapshot;
76
196
  * Subscribes to real-time progress updates for a specific channel
77
197
  * @param channelNumber - The channel number
78
198
  * @param callback - Function to call with audio info updates
199
+ * @throws Error if the channel number exceeds the maximum allowed channels
79
200
  * @example
80
201
  * ```typescript
81
202
  * onAudioProgress(0, (info) => {
@@ -85,6 +206,7 @@ exports.getQueueSnapshot = getQueueSnapshot;
85
206
  * ```
86
207
  */
87
208
  const onAudioProgress = (channelNumber, callback) => {
209
+ validateChannelNumber(channelNumber);
88
210
  if (!exports.audioChannels[channelNumber]) {
89
211
  exports.audioChannels[channelNumber] = {
90
212
  audioCompleteCallbacks: new Set(),
@@ -122,13 +244,14 @@ const onAudioProgress = (channelNumber, callback) => {
122
244
  exports.onAudioProgress = onAudioProgress;
123
245
  /**
124
246
  * Removes progress listeners for a specific channel
125
- * @param channelNumber - The channel number
247
+ * @param channelNumber - The channel number (defaults to 0)
126
248
  * @example
127
249
  * ```typescript
128
- * offAudioProgress(0); // Stop receiving progress updates for channel 0
250
+ * offAudioProgress();
251
+ * offAudioProgress(1); // Stop receiving progress updates for channel 1
129
252
  * ```
130
253
  */
131
- const offAudioProgress = (channelNumber) => {
254
+ function offAudioProgress(channelNumber = 0) {
132
255
  const channel = exports.audioChannels[channelNumber];
133
256
  if (!(channel === null || channel === void 0 ? void 0 : channel.progressCallbacks))
134
257
  return;
@@ -139,12 +262,12 @@ const offAudioProgress = (channelNumber) => {
139
262
  }
140
263
  // Clear all callbacks for this channel
141
264
  channel.progressCallbacks.clear();
142
- };
143
- exports.offAudioProgress = offAudioProgress;
265
+ }
144
266
  /**
145
267
  * Subscribes to queue change events for a specific channel
146
268
  * @param channelNumber - The channel number to monitor
147
269
  * @param callback - Function to call when queue changes
270
+ * @throws Error if the channel number exceeds the maximum allowed channels
148
271
  * @example
149
272
  * ```typescript
150
273
  * onQueueChange(0, (snapshot) => {
@@ -154,6 +277,7 @@ exports.offAudioProgress = offAudioProgress;
154
277
  * ```
155
278
  */
156
279
  const onQueueChange = (channelNumber, callback) => {
280
+ validateChannelNumber(channelNumber);
157
281
  if (!exports.audioChannels[channelNumber]) {
158
282
  exports.audioChannels[channelNumber] = {
159
283
  audioCompleteCallbacks: new Set(),
@@ -194,6 +318,7 @@ exports.offQueueChange = offQueueChange;
194
318
  * Subscribes to audio start events for a specific channel
195
319
  * @param channelNumber - The channel number to monitor
196
320
  * @param callback - Function to call when audio starts playing
321
+ * @throws Error if the channel number exceeds the maximum allowed channels
197
322
  * @example
198
323
  * ```typescript
199
324
  * onAudioStart(0, (info) => {
@@ -203,6 +328,7 @@ exports.offQueueChange = offQueueChange;
203
328
  * ```
204
329
  */
205
330
  const onAudioStart = (channelNumber, callback) => {
331
+ validateChannelNumber(channelNumber);
206
332
  if (!exports.audioChannels[channelNumber]) {
207
333
  exports.audioChannels[channelNumber] = {
208
334
  audioCompleteCallbacks: new Set(),
@@ -228,6 +354,7 @@ exports.onAudioStart = onAudioStart;
228
354
  * Subscribes to audio complete events for a specific channel
229
355
  * @param channelNumber - The channel number to monitor
230
356
  * @param callback - Function to call when audio completes
357
+ * @throws Error if the channel number exceeds the maximum allowed channels
231
358
  * @example
232
359
  * ```typescript
233
360
  * onAudioComplete(0, (info) => {
@@ -239,6 +366,7 @@ exports.onAudioStart = onAudioStart;
239
366
  * ```
240
367
  */
241
368
  const onAudioComplete = (channelNumber, callback) => {
369
+ validateChannelNumber(channelNumber);
242
370
  if (!exports.audioChannels[channelNumber]) {
243
371
  exports.audioChannels[channelNumber] = {
244
372
  audioCompleteCallbacks: new Set(),
@@ -264,6 +392,7 @@ exports.onAudioComplete = onAudioComplete;
264
392
  * Subscribes to audio pause events for a specific channel
265
393
  * @param channelNumber - The channel number to monitor
266
394
  * @param callback - Function to call when audio is paused
395
+ * @throws Error if the channel number exceeds the maximum allowed channels
267
396
  * @example
268
397
  * ```typescript
269
398
  * onAudioPause(0, (channelNumber, info) => {
@@ -273,6 +402,7 @@ exports.onAudioComplete = onAudioComplete;
273
402
  * ```
274
403
  */
275
404
  const onAudioPause = (channelNumber, callback) => {
405
+ validateChannelNumber(channelNumber);
276
406
  if (!exports.audioChannels[channelNumber]) {
277
407
  exports.audioChannels[channelNumber] = {
278
408
  audioCompleteCallbacks: new Set(),
@@ -298,6 +428,7 @@ exports.onAudioPause = onAudioPause;
298
428
  * Subscribes to audio resume events for a specific channel
299
429
  * @param channelNumber - The channel number to monitor
300
430
  * @param callback - Function to call when audio is resumed
431
+ * @throws Error if the channel number exceeds the maximum allowed channels
301
432
  * @example
302
433
  * ```typescript
303
434
  * onAudioResume(0, (channelNumber, info) => {
@@ -307,6 +438,7 @@ exports.onAudioPause = onAudioPause;
307
438
  * ```
308
439
  */
309
440
  const onAudioResume = (channelNumber, callback) => {
441
+ validateChannelNumber(channelNumber);
310
442
  if (!exports.audioChannels[channelNumber]) {
311
443
  exports.audioChannels[channelNumber] = {
312
444
  audioCompleteCallbacks: new Set(),
@@ -358,3 +490,33 @@ const offAudioResume = (channelNumber) => {
358
490
  channel.audioResumeCallbacks.clear();
359
491
  };
360
492
  exports.offAudioResume = offAudioResume;
493
+ /**
494
+ * Removes audio start event listeners for a specific channel
495
+ * @param channelNumber - The channel number
496
+ * @example
497
+ * ```typescript
498
+ * offAudioStart(0); // Stop receiving start notifications for channel 0
499
+ * ```
500
+ */
501
+ const offAudioStart = (channelNumber) => {
502
+ const channel = exports.audioChannels[channelNumber];
503
+ if (!(channel === null || channel === void 0 ? void 0 : channel.audioStartCallbacks))
504
+ return;
505
+ channel.audioStartCallbacks.clear();
506
+ };
507
+ exports.offAudioStart = offAudioStart;
508
+ /**
509
+ * Removes audio complete event listeners for a specific channel
510
+ * @param channelNumber - The channel number
511
+ * @example
512
+ * ```typescript
513
+ * offAudioComplete(0); // Stop receiving completion notifications for channel 0
514
+ * ```
515
+ */
516
+ const offAudioComplete = (channelNumber) => {
517
+ const channel = exports.audioChannels[channelNumber];
518
+ if (!(channel === null || channel === void 0 ? void 0 : channel.audioCompleteCallbacks))
519
+ return;
520
+ channel.audioCompleteCallbacks.clear();
521
+ };
522
+ exports.offAudioComplete = offAudioComplete;
package/dist/pause.js CHANGED
@@ -77,7 +77,7 @@ const pauseWithFade = (...args_1) => __awaiter(void 0, [...args_1], void 0, func
77
77
  // First fade or no transition in progress, capture current volume
78
78
  // But ensure we don't capture a volume of 0 during a transition
79
79
  const currentVolume = getChannelVolumeSync(channelNumber);
80
- originalVolume = currentVolume > 0 ? currentVolume : (_c = (_b = channel.fadeState) === null || _b === void 0 ? void 0 : _b.originalVolume) !== null && _c !== void 0 ? _c : 1.0;
80
+ originalVolume = currentVolume > 0 ? currentVolume : ((_c = (_b = channel.fadeState) === null || _b === void 0 ? void 0 : _b.originalVolume) !== null && _c !== void 0 ? _c : 1.0);
81
81
  }
82
82
  // Store fade state for resumeWithFade to use (including custom duration)
83
83
  channel.fadeState = {
@@ -0,0 +1,104 @@
1
+ /**
2
+ * @fileoverview Queue manipulation functions for the audio-channel-queue package
3
+ * Provides advanced queue management including item removal, reordering, and clearing
4
+ */
5
+ import { QueueManipulationResult, QueueItem } from './types';
6
+ /**
7
+ * Removes a specific item from the queue by its slot number (0-based index)
8
+ * Cannot remove the currently playing item (index 0) - use stopCurrentAudioInChannel instead
9
+ * @param queuedSlotNumber - Zero-based index of the item to remove (must be > 0)
10
+ * @param channelNumber - The channel number (defaults to 0)
11
+ * @returns Promise resolving to operation result with success status and updated queue
12
+ * @throws Error if trying to remove currently playing item or invalid slot number
13
+ * @example
14
+ * ```typescript
15
+ * // Remove the second item in queue (index 1)
16
+ * const result = await removeQueuedItem(1, 0);
17
+ * if (result.success) {
18
+ * console.log(`Removed item, queue now has ${result.updatedQueue.totalItems} items`);
19
+ * }
20
+ *
21
+ * // Remove the third item from channel 1
22
+ * await removeQueuedItem(2, 1);
23
+ * ```
24
+ */
25
+ export declare const removeQueuedItem: (queuedSlotNumber: number, channelNumber?: number) => Promise<QueueManipulationResult>;
26
+ /**
27
+ * Reorders a queue item by moving it from one position to another
28
+ * Cannot reorder the currently playing item (index 0)
29
+ * @param currentQueuedSlotNumber - Current zero-based index of the item to move (must be > 0)
30
+ * @param newQueuedSlotNumber - New zero-based index where the item should be placed (must be > 0)
31
+ * @param channelNumber - The channel number (defaults to 0)
32
+ * @returns Promise resolving to operation result with success status and updated queue
33
+ * @throws Error if trying to reorder currently playing item or invalid slot numbers
34
+ * @example
35
+ * ```typescript
36
+ * // Move item from position 2 to position 1 (make it play next)
37
+ * const result = await reorderQueue(2, 1, 0);
38
+ * if (result.success) {
39
+ * console.log('Item moved successfully');
40
+ * }
41
+ *
42
+ * // Move item from position 1 to end of queue
43
+ * await reorderQueue(1, 4, 0); // Assuming queue has 5+ items
44
+ * ```
45
+ */
46
+ export declare const reorderQueue: (currentQueuedSlotNumber: number, newQueuedSlotNumber: number, channelNumber?: number) => Promise<QueueManipulationResult>;
47
+ /**
48
+ * Clears all queued audio items after the currently playing item
49
+ * The current audio will continue playing but nothing will follow it
50
+ * @param channelNumber - The channel number (defaults to 0)
51
+ * @returns Promise resolving to operation result with success status and updated queue
52
+ * @example
53
+ * ```typescript
54
+ * // Let current song finish but clear everything after it
55
+ * const result = await clearQueueAfterCurrent(0);
56
+ * if (result.success) {
57
+ * console.log(`Cleared queue, current audio will be the last to play`);
58
+ * }
59
+ * ```
60
+ */
61
+ export declare const clearQueueAfterCurrent: (channelNumber?: number) => Promise<QueueManipulationResult>;
62
+ /**
63
+ * Gets information about a specific queue item by its slot number
64
+ * @param queueSlotNumber - Zero-based index of the queue item
65
+ * @param channelNumber - The channel number (defaults to 0)
66
+ * @returns QueueItem information or null if slot doesn't exist
67
+ * @example
68
+ * ```typescript
69
+ * const itemInfo = getQueueItemInfo(1, 0);
70
+ * if (itemInfo) {
71
+ * console.log(`Next to play: ${itemInfo.fileName}`);
72
+ * console.log(`Duration: ${itemInfo.duration}ms`);
73
+ * }
74
+ * ```
75
+ */
76
+ export declare const getQueueItemInfo: (queueSlotNumber: number, channelNumber?: number) => QueueItem | null;
77
+ /**
78
+ * Gets the current queue length for a specific channel
79
+ * @param channelNumber - The channel number (defaults to 0)
80
+ * @returns Number of items in the queue, or 0 if channel doesn't exist
81
+ * @example
82
+ * ```typescript
83
+ * const queueSize = getQueueLength(0);
84
+ * console.log(`Channel 0 has ${queueSize} items in queue`);
85
+ * ```
86
+ */
87
+ export declare const getQueueLength: (channelNumber?: number) => number;
88
+ /**
89
+ * Swaps the positions of two queue items
90
+ * Cannot swap with the currently playing item (index 0)
91
+ * @param slotA - Zero-based index of first item to swap (must be > 0)
92
+ * @param slotB - Zero-based index of second item to swap (must be > 0)
93
+ * @param channelNumber - The channel number (defaults to 0)
94
+ * @returns Promise resolving to operation result with success status and updated queue
95
+ * @example
96
+ * ```typescript
97
+ * // Swap the second and third items in queue
98
+ * const result = await swapQueueItems(1, 2, 0);
99
+ * if (result.success) {
100
+ * console.log('Items swapped successfully');
101
+ * }
102
+ * ```
103
+ */
104
+ export declare const swapQueueItems: (slotA: number, slotB: number, channelNumber?: number) => Promise<QueueManipulationResult>;