fix(api): don't cache direct queries

This also adds a global `window.allTidal` flag to force all queries to go through the API, which is useful for testing.
This commit is contained in:
Daniel 2026-03-20 11:26:49 -05:00
parent 44ec9ed6d9
commit b48ee588aa

View file

@ -21,7 +21,7 @@ import { isCustomFormat } from './ffmpegFormats.ts';
import { DownloadProgress } from './progressEvents.js'; import { DownloadProgress } from './progressEvents.js';
import { resolveDownloadTotalBytes } from './downloadProgressUtils.js'; import { resolveDownloadTotalBytes } from './downloadProgressUtils.js';
import { readableStreamIterator } from './readableStreamIterator.js'; import { readableStreamIterator } from './readableStreamIterator.js';
import { HiFiClient } from './HiFi.ts'; import { HiFiClient, TidalResponse } from './HiFi.ts';
export const DASH_MANIFEST_UNAVAILABLE_CODE = 'DASH_MANIFEST_UNAVAILABLE'; export const DASH_MANIFEST_UNAVAILABLE_CODE = 'DASH_MANIFEST_UNAVAILABLE';
export { resolveDownloadTotalBytes }; export { resolveDownloadTotalBytes };
@ -58,7 +58,7 @@ export class LosslessAPI {
const type = options.type || 'api'; const type = options.type || 'api';
const instanceRoutes = ['/track', '/album/similar', '/artist/similar', '/video']; const instanceRoutes = ['/track', '/album/similar', '/artist/similar', '/video'];
if (!instanceRoutes.some((route) => relativePath.startsWith(route))) { if (window.allTidal == true || !instanceRoutes.some((route) => relativePath.startsWith(route))) {
try { try {
console.log(relativePath); console.log(relativePath);
return await client.queryResponse(relativePath); return await client.queryResponse(relativePath);
@ -435,7 +435,9 @@ export class LosslessAPI {
items: preparedTracks, items: preparedTracks,
}; };
await this.cache.set('search_tracks', query, result); if (!(response instanceof TidalResponse)) {
await this.cache.set('search_tracks', query, result);
}
return result; return result;
} catch (error) { } catch (error) {
if (error.name === 'AbortError') throw error; if (error.name === 'AbortError') throw error;
@ -457,7 +459,9 @@ export class LosslessAPI {
items: normalized.items.map((a) => this.prepareArtist(a)), items: normalized.items.map((a) => this.prepareArtist(a)),
}; };
await this.cache.set('search_artists', query, result); if (!(response instanceof TidalResponse)) {
await this.cache.set('search_artists', query, result);
}
return result; return result;
} catch (error) { } catch (error) {
if (error.name === 'AbortError') throw error; if (error.name === 'AbortError') throw error;
@ -480,7 +484,9 @@ export class LosslessAPI {
items: this.deduplicateAlbums(preparedItems), items: this.deduplicateAlbums(preparedItems),
}; };
await this.cache.set('search_albums', query, result); if (!(response instanceof TidalResponse)) {
await this.cache.set('search_albums', query, result);
}
return result; return result;
} catch (error) { } catch (error) {
if (error.name === 'AbortError') throw error; if (error.name === 'AbortError') throw error;
@ -502,7 +508,9 @@ export class LosslessAPI {
items: normalized.items.map((p) => this.preparePlaylist(p)), items: normalized.items.map((p) => this.preparePlaylist(p)),
}; };
await this.cache.set('search_playlists', query, result); if (!(response instanceof TidalResponse)) {
await this.cache.set('search_playlists', query, result);
}
return result; return result;
} catch (error) { } catch (error) {
if (error.name === 'AbortError') throw error; if (error.name === 'AbortError') throw error;
@ -527,7 +535,9 @@ export class LosslessAPI {
items: normalized.items.map((v) => this.prepareVideo(v)), items: normalized.items.map((v) => this.prepareVideo(v)),
}; };
await this.cache.set('search_videos', query, result); if (!(response instanceof TidalResponse)) {
await this.cache.set('search_videos', query, result);
}
return result; return result;
} catch (error) { } catch (error) {
if (error.name === 'AbortError') throw error; if (error.name === 'AbortError') throw error;
@ -554,7 +564,9 @@ export class LosslessAPI {
originalTrackUrl: data.OriginalTrackUrl || null, originalTrackUrl: data.OriginalTrackUrl || null,
}; };
await this.cache.set('video', id, result); if (!(response instanceof TidalResponse)) {
await this.cache.set('video', id, result);
}
return result; return result;
} }
@ -683,7 +695,9 @@ export class LosslessAPI {
const result = { album, tracks }; const result = { album, tracks };
await this.cache.set('album', id, result); if (!(response instanceof TidalResponse)) {
await this.cache.set('album', id, result);
}
return result; return result;
} }
@ -793,7 +807,9 @@ export class LosslessAPI {
const result = { playlist, tracks }; const result = { playlist, tracks };
await this.cache.set('playlist', id, result); if (!(response instanceof TidalResponse)) {
await this.cache.set('playlist', id, result);
}
return result; return result;
} }
@ -827,7 +843,9 @@ export class LosslessAPI {
}; };
const result = { mix, tracks }; const result = { mix, tracks };
await this.cache.set('mix', id, result); if (!(response instanceof TidalResponse)) {
await this.cache.set('mix', id, result);
}
return result; return result;
} }
@ -984,7 +1002,9 @@ export class LosslessAPI {
const result = { ...artist, albums, eps, tracks, videos }; const result = { ...artist, albums, eps, tracks, videos };
await this.cache.set('artist', cacheKey, result); if (!(primaryResponse instanceof TidalResponse) && !(contentResponse instanceof TidalResponse)) {
await this.cache.set('artist', cacheKey, result);
}
return result; return result;
} }
@ -1004,7 +1024,9 @@ export class LosslessAPI {
const result = items.map((artist) => this.prepareArtist(artist)); const result = items.map((artist) => this.prepareArtist(artist));
await this.cache.set('similar_artists', artistId, result); if (!(response instanceof TidalResponse)) {
await this.cache.set('similar_artists', artistId, result);
}
return result; return result;
} catch (e) { } catch (e) {
console.warn('Failed to fetch similar artists:', e); console.warn('Failed to fetch similar artists:', e);
@ -1032,7 +1054,9 @@ export class LosslessAPI {
text: data.text, text: data.text,
source: data.source || 'Tidal', source: data.source || 'Tidal',
}; };
await this.cache.set('artist', cacheKey, bio); if (!(response instanceof TidalResponse)) {
await this.cache.set('artist', cacheKey, bio);
}
return bio; return bio;
} }
} }
@ -1057,7 +1081,9 @@ export class LosslessAPI {
const result = items.map((album) => this.prepareAlbum(album)); const result = items.map((album) => this.prepareAlbum(album));
await this.cache.set('similar_albums', albumId, result); if (!(response instanceof TidalResponse)) {
await this.cache.set('similar_albums', albumId, result);
}
return result; return result;
} catch (e) { } catch (e) {
console.warn('Failed to fetch similar albums:', e); console.warn('Failed to fetch similar albums:', e);
@ -1197,7 +1223,9 @@ export class LosslessAPI {
if (found) { if (found) {
track = this.prepareTrack(found.item || found); track = this.prepareTrack(found.item || found);
await this.cache.set('track', cacheKey, track); if (!(response instanceof TidalResponse)) {
await this.cache.set('track', cacheKey, track);
}
return track; return track;
} }
@ -1219,7 +1247,9 @@ export class LosslessAPI {
const items = data.items || []; const items = data.items || [];
const tracks = items.map((item) => this.prepareTrack(item.track || item)); const tracks = items.map((item) => this.prepareTrack(item.track || item));
await this.cache.set('recommendations', id, tracks); if (!(response instanceof TidalResponse)) {
await this.cache.set('recommendations', id, tracks);
}
return tracks; return tracks;
} catch (error) { } catch (error) {
console.error('Failed to fetch recommendations:', error); console.error('Failed to fetch recommendations:', error);
@ -1236,7 +1266,9 @@ export class LosslessAPI {
const jsonResponse = await response.json(); const jsonResponse = await response.json();
const result = this.parseTrackLookup(this.normalizeTrackResponse(jsonResponse)); const result = this.parseTrackLookup(this.normalizeTrackResponse(jsonResponse));
await this.cache.set('track', cacheKey, result); if (!(response instanceof TidalResponse)) {
await this.cache.set('track', cacheKey, result);
}
return result; return result;
} }
@ -1259,7 +1291,9 @@ export class LosslessAPI {
} }
} }
this.streamCache.set(cacheKey, streamUrl); if (!(lookup instanceof TidalResponse)) {
this.streamCache.set(cacheKey, streamUrl);
}
return streamUrl; return streamUrl;
} }
@ -1304,7 +1338,9 @@ export class LosslessAPI {
throw new Error(`Could not resolve video stream URL for ID: ${id}`); throw new Error(`Could not resolve video stream URL for ID: ${id}`);
} }
this.streamCache.set(cacheKey, streamUrl); if (!(lookup instanceof TidalResponse)) {
this.streamCache.set(cacheKey, streamUrl);
}
return streamUrl; return streamUrl;
} }