feat: add stable query key factory

This commit is contained in:
Ilia Mashkov
2026-04-15 12:06:32 +03:00
parent f072c5b270
commit 1cbc262af7
2 changed files with 71 additions and 0 deletions

View 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']);
});
});
});

View 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;