feat(web/m7-352): kind-aware createPlaylistsQuery + system-playlists-status helper
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
||||
import { getSystemPlaylistsStatus } from './me';
|
||||
|
||||
vi.mock('./client', () => ({
|
||||
api: { get: vi.fn() }
|
||||
}));
|
||||
|
||||
import { api } from './client';
|
||||
|
||||
describe('me API', () => {
|
||||
beforeEach(() => vi.clearAllMocks());
|
||||
|
||||
it('getSystemPlaylistsStatus GETs the correct path', async () => {
|
||||
(api.get as unknown as ReturnType<typeof vi.fn>).mockResolvedValueOnce({
|
||||
in_flight: false, last_run_at: null, last_error: null
|
||||
});
|
||||
const got = await getSystemPlaylistsStatus();
|
||||
expect(api.get).toHaveBeenCalledWith('/api/me/system-playlists-status');
|
||||
expect(got.in_flight).toBe(false);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,24 @@
|
||||
import { createQuery } from '@tanstack/svelte-query';
|
||||
import { api } from './client';
|
||||
import { qk } from './queries';
|
||||
|
||||
export type SystemPlaylistsStatus = {
|
||||
in_flight: boolean;
|
||||
last_run_at: string | null;
|
||||
last_error: string | null;
|
||||
};
|
||||
|
||||
export async function getSystemPlaylistsStatus(): Promise<SystemPlaylistsStatus> {
|
||||
return api.get<SystemPlaylistsStatus>('/api/me/system-playlists-status');
|
||||
}
|
||||
|
||||
// Refresh aggressively while a build is in_flight so the building → built
|
||||
// transition appears live on the home page. Stale-time is short; manual
|
||||
// invalidations on the server's POST endpoints are out of scope.
|
||||
export function createSystemPlaylistsStatusQuery() {
|
||||
return createQuery({
|
||||
queryKey: qk.systemPlaylistsStatus(),
|
||||
queryFn: getSystemPlaylistsStatus,
|
||||
staleTime: 10_000
|
||||
});
|
||||
}
|
||||
@@ -3,13 +3,16 @@ import { apiFetch } from './client';
|
||||
import { qk } from './queries';
|
||||
import type { Playlist, PlaylistDetail } from './types';
|
||||
|
||||
export type PlaylistKind = 'user' | 'system' | 'all';
|
||||
|
||||
export type ListPlaylistsResponse = {
|
||||
owned: Playlist[];
|
||||
public: Playlist[];
|
||||
};
|
||||
|
||||
export async function listPlaylists(): Promise<ListPlaylistsResponse> {
|
||||
return (await apiFetch('/api/playlists', { method: 'GET' })) as ListPlaylistsResponse;
|
||||
export async function listPlaylists(kind?: PlaylistKind): Promise<ListPlaylistsResponse> {
|
||||
const k = kind ?? 'user';
|
||||
return (await apiFetch(`/api/playlists?kind=${k}`, { method: 'GET' })) as ListPlaylistsResponse;
|
||||
}
|
||||
|
||||
export async function getPlaylist(id: string): Promise<PlaylistDetail> {
|
||||
@@ -73,10 +76,10 @@ export async function reorderPlaylist(playlistID: string, orderedPositions: numb
|
||||
})) as PlaylistDetail;
|
||||
}
|
||||
|
||||
export function createPlaylistsQuery() {
|
||||
export function createPlaylistsQuery(kind?: PlaylistKind) {
|
||||
return createQuery({
|
||||
queryKey: qk.playlists(),
|
||||
queryFn: listPlaylists,
|
||||
queryKey: qk.playlists(kind),
|
||||
queryFn: () => listPlaylists(kind),
|
||||
staleTime: 30_000
|
||||
});
|
||||
}
|
||||
|
||||
@@ -39,8 +39,10 @@ export const qk = {
|
||||
home: () => ['home'] as const,
|
||||
albumsAlpha: () => ['albumsAlpha'] as const,
|
||||
artistTracks: (artistId: string) => ['artistTracks', artistId] as const,
|
||||
playlists: () => ['playlists'] as const,
|
||||
playlist: (id: string) => ['playlist', id] as const,
|
||||
playlists: (kind?: 'user' | 'system' | 'all') =>
|
||||
['playlists', { kind: kind ?? 'user' }] as const,
|
||||
playlist: (id: string) => ['playlist', id] as const,
|
||||
systemPlaylistsStatus: () => ['systemPlaylistsStatus'] as const,
|
||||
};
|
||||
|
||||
export function createArtistsQuery(sort: ArtistSort) {
|
||||
|
||||
Reference in New Issue
Block a user