mirror of
https://github.com/Psychotoxical/psysonic.git
synced 2026-07-22 07:15:47 +00:00
refactor(playback): move thin-state queue resolver out of utils/library into the feature
The queue-resolver family (queueTrackResolver, queueRestore, queueItemRef, queueTrackView) runtime-imports usePlayerStore / playerStoreTypes — it is the playback engine's thin-state queue subsystem, not shared library infra. It sat in utils/library only because it queries the local index. Co-locate into features/playback/store so those edges become intra-feature; its remaining deps (advancedSearchLocal, libraryReady, serverLookup, serverIndexKey, authStore) are plain core/infra (feature -> infra, no inversion). Removes 4 of the 6 store/utils -> feature runtime inversions that blocked the utils/library -> lib move. 8 files moved, 46 consumers rewritten. tsc 0, lint 0, targeted suites green.
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
import { useAuthStore } from '@/store/authStore';
|
||||
import { usePlayerStore } from '@/features/playback/store/playerStore';
|
||||
import type { QueueItemRef } from '@/features/playback/store/playerStoreTypes';
|
||||
import { canonicalQueueServerKey } from '@/utils/server/serverIndexKey';
|
||||
import { resolveBatch } from './queueTrackResolver';
|
||||
|
||||
/**
|
||||
* Full-queue restore (thin-state, decision B). The player store rehydrates the
|
||||
* whole thin `queueItems` ref list from localStorage on startup; this eagerly
|
||||
* resolves every ref into the resolver cache so the queue UI / playback paths
|
||||
* have real `Track` metadata. `resolveBatch` does the index batch
|
||||
* (`library_get_tracks_batch`, ≤100 refs/call) → `getSong` network fallback (P8)
|
||||
* internally, so the queue is never empty even with the index off (the P6
|
||||
* default — every ref still resolves via getSong).
|
||||
*
|
||||
* Clears the restore-pending sentinel (`queueItemsIndex`) once the eager resolve
|
||||
* is dispatched so it runs at most once; `queueItems` stays canonical. Legacy
|
||||
* pre-thin-state blobs that only carried `queueRefs` were normalised into
|
||||
* `queueItems` by the store's persist `merge`, so this reads `queueItems` only.
|
||||
*/
|
||||
export async function hydrateQueueFromIndex(): Promise<void> {
|
||||
const player = usePlayerStore.getState();
|
||||
|
||||
// Restore-pending sentinel: `partialize` writes `queueItemsIndex` alongside
|
||||
// the full `queueItems` on every persist, so a fresh rehydrate carries it
|
||||
// back. Normal in-memory mutations keep `queueItems` canonical but never set
|
||||
// the index, so its presence — not a non-empty `queueItems` — marks "this
|
||||
// restored queue still needs an eager resolve". Without it (steady state /
|
||||
// later server switch) there is nothing to do.
|
||||
const restorePending =
|
||||
player.queueItemsIndex !== undefined || (player.queueRefs?.length ?? 0) > 0;
|
||||
if (!restorePending) return;
|
||||
|
||||
let refs: QueueItemRef[] = player.queueItems ?? [];
|
||||
if (refs.length === 0 && player.queueRefs?.length) {
|
||||
const rawSid = player.queueServerId ?? useAuthStore.getState().activeServerId ?? '';
|
||||
const sid = canonicalQueueServerKey(rawSid);
|
||||
refs = player.queueRefs.map(trackId => ({ serverId: sid, trackId }));
|
||||
}
|
||||
|
||||
// Clear the restore-pending sentinel + any legacy refs; `queueItems` stays the
|
||||
// canonical mirror. Done up front so a later resolve never re-triggers.
|
||||
usePlayerStore.setState({
|
||||
queueItemsIndex: undefined,
|
||||
queueRefs: undefined,
|
||||
queueRefsIndex: undefined,
|
||||
});
|
||||
|
||||
if (refs.length === 0) return;
|
||||
|
||||
// Eager resolve of the whole queue into the resolver cache (best-effort —
|
||||
// index batch when ready, else getSong window fallback so the queue plays
|
||||
// even with the index off). Failures leave refs as placeholders until a row
|
||||
// scrolls into view and the resolver bridge fetches them.
|
||||
try {
|
||||
await resolveBatch(refs);
|
||||
} catch {
|
||||
/* best-effort */
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user