Adapter: Shuffle Strategy
IShuffleStrategy controls the permutation queueShuffle() applies to the queue. The contract is deliberately minimal.
The interface
TypeScript
interface IShuffleStrategy {
order<T extends BasePlaylistItem>(items: ReadonlyArray<T>, currentIndex: number): T[];
}
items is the current queue, read-only. currentIndex is the zero-based index of the playing item, or -1 when nothing is active. order() returns a permutation, same items, no drops, no duplicates.
Rules & restrictions
- Cursor-follow is not your responsibility. Finding the playing item’s new position after the permutation and updating the queue pointer is owned by
MediaList, so it works correctly for any implementation, a strategy author writes only the reordering logic. currentIndexis there so a strategy can pin the currently-playing item (return it first, or leave it untouched, and shuffle only the rest), but nothing forces that behavior, a strategy that ignorescurrentIndexentirely and reorders everything is equally valid.
Default implementation
FisherYatesShuffle (singleton instance: fisherYatesShuffle) is an unbiased uniform-random permutation, ignores currentIndex, the whole queue reshuffles including the playing item’s position.
How to extend it
TypeScript
import nmplayer from '@nomercy-entertainment/nomercy-video-player'; // nomercy-music-player's factory works identically
import type { IShuffleStrategy } from '@nomercy-entertainment/nomercy-player-core';
const player = nmplayer('player');
const pinCurrentFirst: IShuffleStrategy = {
order: (items, currentIndex) => {
if (currentIndex < 0) return [...items].sort(() => Math.random() - 0.5);
const current = items[currentIndex];
const rest = items.filter((_, i) => i !== currentIndex).sort(() => Math.random() - 0.5);
return [current, ...rest];
},
};
player.setup({ shuffleStrategy: pinCurrentFirst });
Next steps
- Adapter: Realtime Channel: the transport port behind
Plugin.websocket().