team-4/backend/routes/get-track.ts
2025-08-02 13:28:10 +02:00

87 lines
2.4 KiB
TypeScript

import { SpotifyTrack } from "../types/spotify.ts";
import { getSpotifyAccessToken } from "../spotify-api.ts";
import { assert } from "jsr:@std/assert/assert";
// Simple in-memory cache for track objects by ID
const trackCache = new Map<string, SpotifyTrack>();
/**
* Inner function that performs the actual API call without retries.
*/
async function fetchSpotifyTrackById(trackId: string): Promise<SpotifyTrack> {
const accessToken = await getSpotifyAccessToken();
const url = `https://api.spotify.com/v1/tracks/${trackId}?market=US`;
const response = await fetch(url, {
headers: {
"Authorization": `Bearer ${accessToken}`,
},
});
if (!response.ok) {
throw new Error(
`Failed to fetch track: ${response.status} ${await response.text()}`,
);
}
const track: SpotifyTrack = await response.json();
// Cache the result
trackCache.set(trackId, track);
return track;
}
/**
* Fetches a Spotify track by its ID, with caching.
* Returns the full SpotifyTrack object.
*/
export async function getSpotifyTrackById(
trackId: string,
): Promise<SpotifyTrack> {
// Check cache first
if (trackCache.has(trackId)) {
return trackCache.get(trackId)!;
}
const maxRetries = 10;
let lastError: Error;
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
return await fetchSpotifyTrackById(trackId);
} catch (error) {
lastError = error as Error;
if (attempt === maxRetries) {
throw Error(`Attempt ${attempt}: ${lastError}`);
}
// Optional: add delay between retries
await new Promise((resolve) => setTimeout(resolve, 1000 * attempt));
}
}
throw lastError!;
}
Deno.test("getSpotifyTrackById basic", async () => {
// Example: Blinding Lights by The Weeknd
const trackId = "2EqlS6tkEnglzr7tkKAAYD";
// First call (should fetch from API)
const track1 = await getSpotifyTrackById(trackId);
assert(track1.id === trackId);
assert(typeof track1.name === "string");
assert(Array.isArray(track1.artists));
// Second call (should hit cache)
const start = performance.now();
const track2 = await getSpotifyTrackById(trackId);
const elapsed = performance.now() - start;
console.log(track2);
console.log("Second call elapsed:", elapsed, "ms");
assert(track2.id === trackId);
assert(typeof track2.name === "string");
assert(Array.isArray(track2.artists));
assert(elapsed < 10, `Second call took too long: ${elapsed}ms`);
});