import { fontKeys } from '$shared/api/queryKeys'; import { BaseQueryStore } from '$shared/lib/helpers/BaseQueryStore.svelte'; import { fetchFontsByIds, seedFontCache, } from '../../api/proxy/proxyFonts'; import { FontNetworkError, FontResponseError, } from '../../lib/errors/errors'; import type { UnifiedFont } from '../../model/types'; /** * Internal fetcher that seeds the cache and handles error wrapping. * Standalone function to avoid 'this' issues during construction. */ async function fetchAndSeed(ids: string[]): Promise { if (ids.length === 0) return []; let response: UnifiedFont[]; try { response = await fetchFontsByIds(ids); } catch (cause) { throw new FontNetworkError(cause); } if (!response || !Array.isArray(response)) { throw new FontResponseError('batchResponse', response); } seedFontCache(response); return response; } /** * Reactive store for fetching and caching batches of fonts by ID. * Integrates with TanStack Query via BaseQueryStore and handles * normalized cache seeding. */ export class BatchFontStore extends BaseQueryStore { constructor(initialIds: string[] = []) { super({ queryKey: fontKeys.batch(initialIds), queryFn: () => fetchAndSeed(initialIds), enabled: initialIds.length > 0, retry: false, }); } /** * Updates the IDs to fetch. Triggers a new query. * * @param ids - Array of font IDs */ setIds(ids: string[]): void { this.updateOptions({ queryKey: fontKeys.batch(ids), queryFn: () => fetchAndSeed(ids), enabled: ids.length > 0, retry: false, }); } /** * Array of fetched fonts */ get fonts(): UnifiedFont[] { return this.result.data ?? []; } /** * Whether the query is currently loading */ get isLoading(): boolean { return this.result.isLoading; } /** * Whether the query encountered an error */ get isError(): boolean { return this.result.isError; } /** * The error object if the query failed */ get error(): Error | null { return (this.result.error as Error) ?? null; } }