Skip to content

GroupListeningPlugin

GroupListeningPlugin is where NoMercy Connect watch-party parity lands for the music player. The idea is server-coordinated lockstep transport: every client in a session plays the same track at the same position, drift gets corrected automatically, and one client holds the DJ role to issue control actions.

This plugin is roadmapped for v2.1. The class is exported now so consumers can register it, hold the import path stable, and react to the failure event before the implementation ships.

When the player initializes, use() throws NotImplementedError internally. The core catches that error inside _registerPlugin, logs it, calls dispose(), and emits plugin:failed and plugin:group-listening:failed. The error never surfaces to your code. Do not register this plugin in production code yet.

TypeScript
import { GroupListeningPlugin } from '@nomercy-entertainment/nomercy-music-player/plugins';
import type { GroupListeningOptions, GroupListeningEvents } from '@nomercy-entertainment/nomercy-music-player/plugins';

Plugin id: 'group-listening'

Options

The GroupListeningOptions interface is defined in source and will drive the v2.1 implementation. The fields below reflect the real interface, not speculative design.

OptionTypeDefaultDescription
wsUrlstringrequiredWebSocket endpoint for room and session sync.
sessionIdstringundefinedRoom or session id this client joins. Omit to create a new session.
driftThresholdMsnumber80Acceptable playback drift in milliseconds before a correction is applied.
maxRateAdjustnumber0.05Maximum playback-rate adjustment factor used during drift correction, equivalent to plus or minus 5 percent.
canControlbooleantrueWhether this client may issue control actions (that is, hold the DJ role).

Events

The GroupListeningEvents interface exists in source and reserves the event names for v2.1. No events fire in v2.0 because use() throws before any wiring takes place. The table below is a reference for what the interface declares; do not subscribe to these events until the implementation ships.

EventPayloadDescription
session:joined{ sessionId: string; participants: number }Reserved: this client successfully joined a session.
session:leftvoidReserved: this client left the session.
sync:applied{ source: 'remote'; action: 'play' | 'pause' | 'seek' | 'next' | 'previous'; from: string }Reserved: a remote sync action was applied to this client.
sync:broadcast{ action: string; payload: unknown }Reserved: a control action was broadcast to the session by this client.
sync:drift{ deltaMs: number }Reserved: clock drift was detected and a correction is being applied.
sync:participants{ count: number }Reserved: the participant count in the session changed.
role:dj-acquired{ id: string }Reserved: this client acquired the DJ role.
role:dj-lostvoidReserved: this client lost the DJ role.
unsupported{ reason: string }Reserved: the server protocol or environment is unsupported.

Methods

use()

TypeScript
use(): void

Stub implementation. Always throws NotImplementedError with message 'GroupListeningPlugin: roadmapped for v2.1. Not available in v2.0.' The core catches this internally; the exception does not reach your code.

dispose()

TypeScript
dispose(): void

No-op in the stub — there is nothing to tear down.

Registration

Register the plugin and listen to plugin:failed to react when the core disables it. Do not wrap addPlugin or setup in a try/catch expecting NotImplementedError — the core swallows that error internally and it never reaches your code.

TypeScript
import nmMPlayer from '@nomercy-entertainment/nomercy-music-player';
import { GroupListeningPlugin } from '@nomercy-entertainment/nomercy-music-player/plugins';

const player = nmMPlayer('main')
.addPlugin(GroupListeningPlugin, {
wsUrl: 'wss://your-server.example.com/sync',
sessionId: 'room-abc',
driftThresholdMs: 80,
canControl: true,
})
.setup({
baseUrl: 'https://raw.githubusercontent.com/NoMercy-Entertainment/nomercy-media/master/Music',
playlist: [
{
id: 'kjc-01',
name: 'Thaw You Out',
url: '/D/Derek%20Clegg/%5B2010%5D%20KJC/01%20Thaw%20You%20Out.mp3',
artist: 'Derek Clegg',
},
],
});

// The core emits plugin:failed when use() throws internally.
// Use this event to detect that GroupListeningPlugin is not yet active.
player.on('plugin:group-listening:failed', ({ id, error }) => {
console.warn(`${id} is not available in v2.0:`, error.message);
});

See also