diff --git a/src/entities/Font/model/stores/fontCollectionStore.ts b/src/entities/Font/model/stores/fontCollectionStore.ts deleted file mode 100644 index 83835d5..0000000 --- a/src/entities/Font/model/stores/fontCollectionStore.ts +++ /dev/null @@ -1,263 +0,0 @@ -/** - * Font collection store - * - * Main font collection cache using Svelte stores. - * Integrates with TanStack Query for advanced caching and deduplication. - * - * Provides derived stores for filtered/sorted fonts. - */ - -import type { - FontCategory, - FontCollectionFilters, - FontCollectionSort, - FontCollectionState, - FontCollectionStore, - FontProvider, - FontSubset, - UnifiedFont, -} from '$entities/Font/model/types'; -import { createCollectionCache } from '$shared/lib/fetch/collectionCache'; -import type { Writable } from 'svelte/store'; -import { - derived, - get, - writable, -} from 'svelte/store'; - -/** - * Create font collection store - * - * @param initialState - Initial state for collection - * @returns Font collection store instance - * - * @example - * ```ts - * const fontCollection = createFontCollectionStore({ - * fonts: {}, - * filters: {}, - * sort: { field: 'name', direction: 'asc' } - * }); - * - * // Add fonts to collection - * fontCollection.addFonts([font1, font2]); - * - * // Use in component - * $fontCollection.filteredFonts - * ``` - */ -export function createFontCollectionStore( - initialState?: Partial, -): FontCollectionStore { - const cache = createCollectionCache({ - defaultTTL: 5 * 60 * 1000, // 5 minutes - maxSize: 1000, - }); - - const defaultState: FontCollectionState = { - fonts: {}, - filters: {}, - sort: { field: 'name', direction: 'asc' }, - }; - - const state: Writable = writable({ - ...defaultState, - ...initialState, - }); - - const isLoading = writable(false); - const error = writable(); - - // Derived store for fonts as array - const fonts = derived(state, $state => { - return Object.values($state.fonts); - }); - - // Derived store for filtered fonts - const filteredFonts = derived([state, fonts], ([$state, $fonts]) => { - let filtered = [...$fonts]; - - // Apply search filter - if ($state.filters.searchQuery) { - const query = $state.filters.searchQuery.toLowerCase(); - filtered = filtered.filter(font => font.name.toLowerCase().includes(query)); - } - - // Apply provider filter - if ($state.filters.provider) { - filtered = filtered.filter( - font => font.provider === $state.filters.provider, - ); - } - - // Apply category filter - if ($state.filters.category) { - filtered = filtered.filter( - font => font.category === $state.filters.category, - ); - } - - // Apply subset filter - if ($state.filters.subsets?.length) { - filtered = filtered.filter(font => - $state.filters.subsets!.some(subset => font.subsets.includes(subset as FontSubset)) - ); - } - - // Apply sort - const { field, direction } = $state.sort; - const multiplier = direction === 'asc' ? 1 : -1; - - filtered.sort((a, b) => { - let comparison = 0; - - if (field === 'name') { - comparison = a.name.localeCompare(b.name); - } else if (field === 'popularity') { - const aPop = a.metadata.popularity ?? 0; - const bPop = b.metadata.popularity ?? 0; - comparison = aPop - bPop; - } else if (field === 'category') { - comparison = a.category.localeCompare(b.category); - } - - return comparison * multiplier; - }); - - return filtered; - }); - - // Derived store for count - const count = derived(fonts, $fonts => $fonts.length); - - return { - // Expose main state - state, - - // Expose derived stores - fonts, - filteredFonts, - count, - isLoading, - error, - - /** - * Add multiple fonts to collection - */ - addFonts: (newFonts: UnifiedFont[]) => { - state.update($state => { - const fontsMap = { ...$state.fonts }; - - for (const font of newFonts) { - fontsMap[font.id] = font; - cache.set(font.id, font); - } - - return { - ...$state, - fonts: fontsMap, - }; - }); - }, - - /** - * Add single font to collection - */ - addFont: (font: UnifiedFont) => { - state.update($state => ({ - ...$state, - fonts: { - ...$state.fonts, - [font.id]: font, - }, - })); - cache.set(font.id, font); - }, - - /** - * Remove font from collection - */ - removeFont: (fontId: string) => { - state.update($state => { - const { [fontId]: _, ...rest } = $state.fonts; - return { - ...$state, - fonts: rest, - }; - }); - cache.remove(fontId); - }, - - /** - * Clear all fonts - */ - clear: () => { - state.set({ - ...get(state), - fonts: {}, - }); - cache.clear(); - }, - - /** - * Update filters - */ - setFilters: (filters: Partial) => { - state.update($state => ({ - ...$state, - filters: { - ...$state.filters, - ...filters, - }, - })); - }, - - /** - * Clear filters - */ - clearFilters: () => { - state.update($state => ({ - ...$state, - filters: {}, - })); - }, - - /** - * Update sort configuration - */ - setSort: (sort: FontCollectionSort) => { - state.update($state => ({ - ...$state, - sort, - })); - }, - - /** - * Get font by ID - */ - getFont: (fontId: string) => { - const currentState = get(state); - return currentState.fonts[fontId]; - }, - - /** - * Get fonts by provider - */ - getFontsByProvider: (provider: FontProvider) => { - const currentState = get(state); - return Object.values(currentState.fonts).filter( - font => font.provider === provider, - ); - }, - - /** - * Get fonts by category - */ - getFontsByCategory: (category: FontCategory) => { - const currentState = get(state); - return Object.values(currentState.fonts).filter( - font => font.category === category, - ); - }, - }; -} diff --git a/src/entities/Font/model/stores/index.ts b/src/entities/Font/model/stores/index.ts deleted file mode 100644 index e260461..0000000 --- a/src/entities/Font/model/stores/index.ts +++ /dev/null @@ -1,13 +0,0 @@ -/** - * Font collection store exports - * - * Exports font collection store types and factory function - */ - -export type { - FontCollectionFilters, - FontCollectionSort, - FontCollectionState, - FontCollectionStore, -} from '../types'; -export { createFontCollectionStore } from './fontCollectionStore';