import { api } from '../index'; import { toTrack, type RawTrack } from '../mappers'; import type { RadioResult } from '../types'; // Radio + similarity (ยง6.5). Stateless: the client passes the seed + already- // queued ids and pulls more as the queue drains. interface RawRadioTrack { track: RawTrack; reason: string; } interface RawRadio { source: string; tracks: RawRadioTrack[]; } interface RawSimilar { source: string; tracks: RawTrack[]; } export interface RadioArgs { seedTrackId?: string; fromLikes?: boolean; exploration?: number; count?: number; excludeIds?: string[]; } const toBody = (a: RadioArgs) => ({ seed_track_id: a.seedTrackId ?? null, from_likes: a.fromLikes ?? false, exploration: a.exploration ?? 0.25, count: a.count ?? 20, exclude_ids: a.excludeIds ?? [], }); const toRadio = (r: RawRadio): RadioResult => ({ source: r.source, picks: r.tracks.map((x) => ({ track: toTrack(x.track), reason: x.reason })), }); export const radioApi = api.injectEndpoints({ endpoints: (build) => ({ startRadio: build.mutation({ query: (a) => ({ url: '/radio', method: 'POST', body: toBody(a) }), transformResponse: (r: RawRadio) => toRadio(r), }), radioNext: build.mutation({ query: (a) => ({ url: '/radio/next', method: 'POST', body: toBody(a) }), transformResponse: (r: RawRadio) => toRadio(r), }), getSimilarTracks: build.query({ query: (trackId) => `/tracks/${trackId}/similar`, transformResponse: (r: RawSimilar) => ({ source: r.source, picks: r.tracks.map((t) => ({ track: toTrack(t), reason: 'similar' })), }), }), }), overrideExisting: false, }); export const { useStartRadioMutation, useRadioNextMutation, useGetSimilarTracksQuery, } = radioApi;