feat(FontStore): implement lifecycle, param management, async methods, shortcuts, pagination, category getters, singleton — all tests green
This commit is contained in:
@@ -102,54 +102,105 @@ export class FontStore {
|
||||
|
||||
// -- Lifecycle --
|
||||
|
||||
destroy(): void {}
|
||||
destroy() {
|
||||
this.#unsubscribe();
|
||||
this.#observer.destroy();
|
||||
}
|
||||
|
||||
// -- Param management --
|
||||
|
||||
setParams(_updates: Partial<FontStoreParams>): void {}
|
||||
invalidate(): void {}
|
||||
setParams(updates: Partial<FontStoreParams>) {
|
||||
this.#params = { ...this.#params, ...updates };
|
||||
this.#observer.setOptions(this.buildOptions());
|
||||
}
|
||||
invalidate() {
|
||||
this.#qc.invalidateQueries({ queryKey: this.buildQueryKey(this.#params) });
|
||||
}
|
||||
|
||||
// -- Async operations --
|
||||
|
||||
async refetch(): Promise<void> {}
|
||||
async prefetch(_params: FontStoreParams): Promise<void> {}
|
||||
cancel(): void {}
|
||||
getCachedData(): UnifiedFont[] | undefined {
|
||||
return undefined;
|
||||
async refetch() {
|
||||
this.#observer.setOptions(this.buildOptions());
|
||||
await this.#observer.refetch();
|
||||
}
|
||||
|
||||
async prefetch(params: FontStoreParams) {
|
||||
await this.#qc.prefetchInfiniteQuery(this.buildOptions(params));
|
||||
}
|
||||
|
||||
cancel() {
|
||||
this.#qc.cancelQueries({ queryKey: this.buildQueryKey(this.#params) });
|
||||
}
|
||||
|
||||
getCachedData(): UnifiedFont[] | undefined {
|
||||
const data = this.#qc.getQueryData<InfiniteData<FontPage, PageParam>>(
|
||||
this.buildQueryKey(this.#params),
|
||||
);
|
||||
if (!data) return undefined;
|
||||
return data.pages.flatMap(p => p.fonts);
|
||||
}
|
||||
|
||||
setQueryData(updater: (old: UnifiedFont[] | undefined) => UnifiedFont[]) {
|
||||
this.#qc.setQueryData<InfiniteData<FontPage, PageParam>>(
|
||||
this.buildQueryKey(this.#params),
|
||||
old => {
|
||||
const flatFonts = old?.pages.flatMap(p => p.fonts);
|
||||
const newFonts = updater(flatFonts);
|
||||
const template = old?.pages[0] ?? { total: newFonts.length, limit: newFonts.length, offset: 0 };
|
||||
return {
|
||||
pages: [{ ...template, fonts: newFonts }],
|
||||
pageParams: [{ offset: 0 } as PageParam],
|
||||
};
|
||||
},
|
||||
);
|
||||
}
|
||||
setQueryData(_updater: (old: UnifiedFont[] | undefined) => UnifiedFont[]): void {}
|
||||
|
||||
// -- Filter shortcuts --
|
||||
|
||||
setProviders(_v: ProxyFontsParams['providers']): void {}
|
||||
setCategories(_v: ProxyFontsParams['categories']): void {}
|
||||
setSubsets(_v: ProxyFontsParams['subsets']): void {}
|
||||
setSearch(_v: string): void {}
|
||||
setSort(_v: ProxyFontsParams['sort']): void {}
|
||||
setProviders(v: ProxyFontsParams['providers']) {
|
||||
this.setParams({ providers: v });
|
||||
}
|
||||
setCategories(v: ProxyFontsParams['categories']) {
|
||||
this.setParams({ categories: v });
|
||||
}
|
||||
setSubsets(v: ProxyFontsParams['subsets']) {
|
||||
this.setParams({ subsets: v });
|
||||
}
|
||||
setSearch(v: string) {
|
||||
this.setParams({ q: v || undefined });
|
||||
}
|
||||
setSort(v: ProxyFontsParams['sort']) {
|
||||
this.setParams({ sort: v });
|
||||
}
|
||||
|
||||
// -- Pagination navigation --
|
||||
|
||||
async nextPage(): Promise<void> {}
|
||||
prevPage(): void {} // no-op: infinite scroll only loads forward
|
||||
async nextPage(): Promise<void> {
|
||||
await this.#observer.fetchNextPage();
|
||||
}
|
||||
prevPage(): void {} // no-op: infinite scroll accumulates forward only; method kept for API compatibility
|
||||
goToPage(_page: number): void {} // no-op
|
||||
setLimit(_limit: number): void {}
|
||||
|
||||
setLimit(limit: number) {
|
||||
this.setParams({ limit });
|
||||
}
|
||||
|
||||
// -- Category views --
|
||||
|
||||
get sansSerifFonts(): UnifiedFont[] {
|
||||
return [];
|
||||
get sansSerifFonts() {
|
||||
return this.fonts.filter(f => f.category === 'sans-serif');
|
||||
}
|
||||
get serifFonts(): UnifiedFont[] {
|
||||
return [];
|
||||
get serifFonts() {
|
||||
return this.fonts.filter(f => f.category === 'serif');
|
||||
}
|
||||
get displayFonts(): UnifiedFont[] {
|
||||
return [];
|
||||
get displayFonts() {
|
||||
return this.fonts.filter(f => f.category === 'display');
|
||||
}
|
||||
get handwritingFonts(): UnifiedFont[] {
|
||||
return [];
|
||||
get handwritingFonts() {
|
||||
return this.fonts.filter(f => f.category === 'handwriting');
|
||||
}
|
||||
get monospaceFonts(): UnifiedFont[] {
|
||||
return [];
|
||||
get monospaceFonts() {
|
||||
return this.fonts.filter(f => f.category === 'monospace');
|
||||
}
|
||||
|
||||
// -- Private helpers (TypeScript-private so tests can spy via `as any`) --
|
||||
@@ -207,3 +258,5 @@ export class FontStore {
|
||||
export function createFontStore(params: FontStoreParams = {}): FontStore {
|
||||
return new FontStore(params);
|
||||
}
|
||||
|
||||
export const fontStore = new FontStore({ limit: 50 });
|
||||
|
||||
Reference in New Issue
Block a user