Files
scoreko-dev/src/dashboard/services/pack-service.ts
T
Pandipipas b32c0e4560 feat: implement replicant state synchronization for commentary, players, scoreboard, and graphics settings
- Added a new service for synchronizing state with replicants in `replicant-state-service.ts`.
- Refactored commentary store to utilize the new synchronization service.
- Created a new graphics settings store that syncs with replicants.
- Introduced a packs store for managing installed packs and their states.
- Updated players and scoreboard stores to use the new synchronization service.
- Created shared services for managing replicated state in graphics components.
- Refactored existing components to use the new shared services for replicant state.
- Added normalization and default values for commentary, graphics settings, players, and scoreboard.
- Improved type safety and organization in shared domain files for better maintainability.
2026-05-30 21:22:48 +02:00

80 lines
3.1 KiB
TypeScript

import { sendNodecgCommand, sendNodecgMessage } from '../../nodecg/browser/messages';
import { createPackBrowserReplicants } from '../../nodecg/browser/packReplicants';
import { messageNames } from '../../nodecg/messageNames';
import type {
PackDownloadState,
PackManifest,
PackRegistry,
PackUpdateInfo,
} from '../../shared/domain/packs/types';
export interface PackReplicantHandlers {
onRegistryChanged: (value: PackRegistry | null) => void;
onInstalledPacksChanged: (value: string[], previousValue: string[]) => void;
onDownloadStatesChanged: (value: Record<string, PackDownloadState>) => void;
onAvailableUpdatesChanged: (value: Record<string, PackUpdateInfo>) => void;
}
export interface PackService {
subscribe: (handlers: PackReplicantHandlers) => Promise<() => void>;
fetchRegistry: () => Promise<void>;
downloadPack: (packId: string) => Promise<void>;
uninstallPack: (packId: string) => Promise<void>;
updatePack: (packId: string) => Promise<void>;
readLocalManifest: (packId: string) => Promise<PackManifest>;
}
export const createPackService = (): PackService => {
const subscribe = async (handlers: PackReplicantHandlers): Promise<() => void> => {
const {
registryRep,
installedRep,
statesRep,
updatesRep,
waitUntilReady,
} = createPackBrowserReplicants();
await waitUntilReady();
handlers.onRegistryChanged(registryRep.value ?? null);
handlers.onInstalledPacksChanged(installedRep.value ?? [], []);
handlers.onDownloadStatesChanged(statesRep.value ?? {});
handlers.onAvailableUpdatesChanged(updatesRep.value ?? {});
const onRegistryChanged = (value: PackRegistry | null): void => {
handlers.onRegistryChanged(value ?? null);
};
const onInstalledPacksChanged = (value: string[], previousValue?: string[]): void => {
handlers.onInstalledPacksChanged(value ?? [], previousValue ?? []);
};
const onDownloadStatesChanged = (value: Record<string, PackDownloadState>): void => {
handlers.onDownloadStatesChanged(value ?? {});
};
const onAvailableUpdatesChanged = (value: Record<string, PackUpdateInfo>): void => {
handlers.onAvailableUpdatesChanged(value ?? {});
};
registryRep.on('change', onRegistryChanged);
installedRep.on('change', onInstalledPacksChanged);
statesRep.on('change', onDownloadStatesChanged);
updatesRep.on('change', onAvailableUpdatesChanged);
return () => {
registryRep.off('change', onRegistryChanged);
installedRep.off('change', onInstalledPacksChanged);
statesRep.off('change', onDownloadStatesChanged);
updatesRep.off('change', onAvailableUpdatesChanged);
};
};
return {
subscribe,
fetchRegistry: () => sendNodecgCommand(messageNames.packs.fetchRegistry),
downloadPack: (packId: string) => sendNodecgCommand(messageNames.packs.download, packId),
uninstallPack: (packId: string) => sendNodecgCommand(messageNames.packs.uninstall, packId),
updatePack: (packId: string) => sendNodecgCommand(messageNames.packs.update, packId),
readLocalManifest: (packId: string) =>
sendNodecgMessage<PackManifest>(messageNames.packs.readLocalManifest, packId),
};
};