From 2a761b9d478ce6d51e0dbec3d3b80cd70f8eff8d Mon Sep 17 00:00:00 2001 From: Ilia Mashkov Date: Wed, 8 Apr 2026 09:54:27 +0300 Subject: [PATCH] =?UTF-8?q?feat(FontStore):=20implement=20lifecycle,=20par?= =?UTF-8?q?am=20management,=20async=20methods,=20shortcuts,=20pagination,?= =?UTF-8?q?=20category=20getters,=20singleton=20=E2=80=94=20all=20tests=20?= =?UTF-8?q?green?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../model/store/fontStore/fontStore.svelte.ts | 107 +++++++++++++----- 1 file changed, 80 insertions(+), 27 deletions(-) diff --git a/src/entities/Font/model/store/fontStore/fontStore.svelte.ts b/src/entities/Font/model/store/fontStore/fontStore.svelte.ts index 9b10bf7..a48ef54 100644 --- a/src/entities/Font/model/store/fontStore/fontStore.svelte.ts +++ b/src/entities/Font/model/store/fontStore/fontStore.svelte.ts @@ -102,54 +102,105 @@ export class FontStore { // -- Lifecycle -- - destroy(): void {} + destroy() { + this.#unsubscribe(); + this.#observer.destroy(); + } // -- Param management -- - setParams(_updates: Partial): void {} - invalidate(): void {} + setParams(updates: Partial) { + this.#params = { ...this.#params, ...updates }; + this.#observer.setOptions(this.buildOptions()); + } + invalidate() { + this.#qc.invalidateQueries({ queryKey: this.buildQueryKey(this.#params) }); + } // -- Async operations -- - async refetch(): Promise {} - async prefetch(_params: FontStoreParams): Promise {} - 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>( + this.buildQueryKey(this.#params), + ); + if (!data) return undefined; + return data.pages.flatMap(p => p.fonts); + } + + setQueryData(updater: (old: UnifiedFont[] | undefined) => UnifiedFont[]) { + this.#qc.setQueryData>( + 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 {} - prevPage(): void {} // no-op: infinite scroll only loads forward + async nextPage(): Promise { + 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 });