feat(web): add TanStack Query helpers for library endpoints
qk.{artists,artist,album} key generators and create*Query wrappers
with shared page size, sort-aware keys, and infinite-query plumbing
for /api/artists.
This commit is contained in:
@@ -0,0 +1,17 @@
|
||||
import { describe, expect, test } from 'vitest';
|
||||
import { qk } from './queries';
|
||||
|
||||
describe('qk key generators', () => {
|
||||
test('artists key includes sort discriminator', () => {
|
||||
expect(qk.artists('alpha')).toEqual(['artists', { sort: 'alpha' }]);
|
||||
expect(qk.artists('newest')).toEqual(['artists', { sort: 'newest' }]);
|
||||
});
|
||||
|
||||
test('artist key tuple', () => {
|
||||
expect(qk.artist('abc')).toEqual(['artist', 'abc']);
|
||||
});
|
||||
|
||||
test('album key tuple', () => {
|
||||
expect(qk.album('xyz')).toEqual(['album', 'xyz']);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,41 @@
|
||||
import { createQuery, createInfiniteQuery } from '@tanstack/svelte-query';
|
||||
import { api } from './client';
|
||||
import type { ArtistRef, ArtistDetail, AlbumDetail, Page } from './types';
|
||||
|
||||
export type ArtistSort = 'alpha' | 'newest';
|
||||
export const ARTIST_PAGE_SIZE = 50;
|
||||
|
||||
export const qk = {
|
||||
artists: (sort: ArtistSort) => ['artists', { sort }] as const,
|
||||
artist: (id: string) => ['artist', id] as const,
|
||||
album: (id: string) => ['album', id] as const,
|
||||
};
|
||||
|
||||
export function createArtistsQuery(sort: ArtistSort) {
|
||||
return createInfiniteQuery({
|
||||
queryKey: qk.artists(sort),
|
||||
queryFn: ({ pageParam = 0 }) =>
|
||||
api.get<Page<ArtistRef>>(
|
||||
`/api/artists?sort=${sort}&limit=${ARTIST_PAGE_SIZE}&offset=${pageParam}`
|
||||
),
|
||||
initialPageParam: 0,
|
||||
getNextPageParam: (last) => {
|
||||
const loaded = last.offset + last.items.length;
|
||||
return loaded >= last.total ? undefined : loaded;
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export function createArtistQuery(id: string) {
|
||||
return createQuery({
|
||||
queryKey: qk.artist(id),
|
||||
queryFn: () => api.get<ArtistDetail>(`/api/artists/${id}`),
|
||||
});
|
||||
}
|
||||
|
||||
export function createAlbumQuery(id: string) {
|
||||
return createQuery({
|
||||
queryKey: qk.album(id),
|
||||
queryFn: () => api.get<AlbumDetail>(`/api/albums/${id}`),
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user