feat: add stable query key factory
This commit is contained in:
48
src/shared/api/queryKeys.test.ts
Normal file
48
src/shared/api/queryKeys.test.ts
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
import {
|
||||||
|
describe,
|
||||||
|
expect,
|
||||||
|
it,
|
||||||
|
} from 'vitest';
|
||||||
|
import { fontKeys } from './queryKeys';
|
||||||
|
|
||||||
|
describe('fontKeys', () => {
|
||||||
|
describe('Hierarchy', () => {
|
||||||
|
it('should generate base keys', () => {
|
||||||
|
expect(fontKeys.all).toEqual(['fonts']);
|
||||||
|
expect(fontKeys.lists()).toEqual(['fonts', 'list']);
|
||||||
|
expect(fontKeys.batches()).toEqual(['fonts', 'batch']);
|
||||||
|
expect(fontKeys.details()).toEqual(['fonts', 'detail']);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Batch Keys (Stability & Sorting)', () => {
|
||||||
|
it('should sort IDs for stable serialization', () => {
|
||||||
|
const key1 = fontKeys.batch(['b', 'a', 'c']);
|
||||||
|
const key2 = fontKeys.batch(['c', 'b', 'a']);
|
||||||
|
const expected = ['fonts', 'batch', ['a', 'b', 'c']];
|
||||||
|
expect(key1).toEqual(expected);
|
||||||
|
expect(key2).toEqual(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle empty ID arrays', () => {
|
||||||
|
expect(fontKeys.batch([])).toEqual(['fonts', 'batch', []]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('List Keys (Parameters)', () => {
|
||||||
|
it('should include parameters in list keys', () => {
|
||||||
|
const params = { provider: 'google' };
|
||||||
|
expect(fontKeys.list(params)).toEqual(['fonts', 'list', params]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle empty parameters', () => {
|
||||||
|
expect(fontKeys.list({})).toEqual(['fonts', 'list', {}]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Detail Keys', () => {
|
||||||
|
it('should generate unique detail keys per ID', () => {
|
||||||
|
expect(fontKeys.detail('roboto')).toEqual(['fonts', 'detail', 'roboto']);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
23
src/shared/api/queryKeys.ts
Normal file
23
src/shared/api/queryKeys.ts
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
/**
|
||||||
|
* Stable query key factory for font-related queries.
|
||||||
|
* Ensures consistent serialization for batch requests by sorting IDs.
|
||||||
|
*/
|
||||||
|
export const fontKeys = {
|
||||||
|
/** Base key for all font queries */
|
||||||
|
all: ['fonts'] as const,
|
||||||
|
|
||||||
|
/** Keys for font list queries */
|
||||||
|
lists: () => [...fontKeys.all, 'list'] as const,
|
||||||
|
/** Specific font list key with filter parameters */
|
||||||
|
list: (params: object) => [...fontKeys.lists(), params] as const,
|
||||||
|
|
||||||
|
/** Keys for font batch queries */
|
||||||
|
batches: () => [...fontKeys.all, 'batch'] as const,
|
||||||
|
/** Specific batch key, sorted for stability */
|
||||||
|
batch: (ids: string[]) => [...fontKeys.batches(), [...ids].sort()] as const,
|
||||||
|
|
||||||
|
/** Keys for font detail queries */
|
||||||
|
details: () => [...fontKeys.all, 'detail'] as const,
|
||||||
|
/** Specific font detail key by ID */
|
||||||
|
detail: (id: string) => [...fontKeys.details(), id] as const,
|
||||||
|
} as const;
|
||||||
Reference in New Issue
Block a user