import { findLocalPlaybackUrl } from '../utils/offline/offlineLibraryHelpers'; import { resolvePlaybackUrl, type PlaybackSourceKind } from '../utils/playback/resolvePlaybackUrl'; import { resolveServerIdForIndexKey } from '../utils/server/serverLookup'; import { sameQueueTrackId } from '../utils/playback/queueIdentity'; /** * Helpers that classify the URL `audio_play` was last invoked with, so the * runtime can rebind playback onto a freshly-promoted hot-cache entry the * next time the same track plays. * * `lastOpenedWithHttpTrackId` remembers the most recent track id we asked * the engine to fetch over HTTP (anything that isn't the `psysonic-local://` * scheme). When the hot-cache later promotes that track to a local URL we * compare against this id to decide whether a transparent rebind is worth * triggering. */ let lastOpenedWithHttpTrackId: string | null = null; export function recordEnginePlayUrl(trackId: string, url: string): void { lastOpenedWithHttpTrackId = url.startsWith('psysonic-local://') ? null : trackId; } /** Matches `playTrack` / PlayerBar: stream vs hot-cache vs offline file from resolved `audio_play` URL. */ export function playbackSourceHintForResolvedUrl(trackId: string, serverId: string, url: string): PlaybackSourceKind { if (!url.startsWith('psysonic-local://')) return 'stream'; const profileId = resolveServerIdForIndexKey(serverId) || serverId; return findLocalPlaybackUrl(trackId, profileId, 'library') ? 'offline' : 'hot'; } export function shouldRebindPlaybackToHotCache(trackId: string, serverId: string): boolean { if (!serverId) return false; if (!lastOpenedWithHttpTrackId || !sameQueueTrackId(lastOpenedWithHttpTrackId, trackId)) { return false; } return resolvePlaybackUrl(trackId, serverId).startsWith('psysonic-local://'); } /** Test-only: clear the module-scoped track id so each test starts clean. */ export function _resetPlaybackUrlRoutingForTest(): void { lastOpenedWithHttpTrackId = null; }