- Rename fontCache.ts to collectionCache.ts
- Rename FontCacheManager interface to CollectionCacheManager
- Make implementation fully generic (already was, just renamed interface)
- Update exports in shared/fetch/index.ts
- Fix getStats() to return derived store value for accurate statistics
- Add comprehensive test coverage for collection cache manager
- 41 test cases covering all functionality
- Tests for caching, deduplication, state tracking
- Tests for statistics, reactivity, and edge cases
Closes task-1 of Phase 1 refactoring
- Add type-safe buildQueryString function to /utils
- Support primitives, arrays, and optional values
- Proper URL encoding for special characters
- Add comprehensive tests (25 test cases, all passing)
- Update Google Fonts API client to use shared utility
- Update Fontshare API client to use shared utility
- Export utility from /utils/index.ts
Benefits:
- DRY - Single source of truth for query string logic
- Type-safe - Proper TypeScript support with QueryParams type
- Tested - Comprehensive test coverage
- Maintainable - One place to fix bugs
- Created unified model/types.ts with all type definitions
- Consolidated domain types (FontCategory, FontProvider, FontSubset)
- Consolidated Google Fonts API types (FontItem, GoogleFontsApiModel, etc.)
- Consolidated Fontshare API types (FontshareFont, FontshareStyle, etc.)
- Consolidated normalization types (UnifiedFont, FontStyleUrls, etc.)
- Consolidated store types (FontCollectionStore, FontCollectionFilters, etc.)
- Removed duplicate type files (font.ts, google_fonts.ts, fontshare_fonts.ts)
- Updated all imports to use consolidated types
- Updated normalize module to import from /Font
- Updated API clients to re-export types for backward compatibility
- Updated store to use centralized types
- Updated Font index.ts to export all types
Benefits:
- Centralized type definitions in single location
- Cleaner imports (single import from /Font)
- Better code organization with clear sections
- Follows FSD principles (types in model layer)
- No duplicate type definitions
- Added GoogleFontItem type alias for backward compatibility
- Updated normalize.ts to properly type Record<string, string> values
- Fixed import paths in Font index.ts (added subdirectory paths)
- Removed unused Readable import from store
- Removed type exports from normalize and API index files
- Updated stores index.ts to import types from parent types.ts
- All tests passing (129 tests)
All imports now use centralized types from model/types.ts:
- API clients re-export types for backward compatibility
- Normalize module imports types and exports functions
- Store module imports types and exports factory
- Main index.ts exports all types from model/types.ts
- Moved unifiedFontStore creation from Page.svelte to Layout.svelte
- Layout now creates store instance and provides it via setContext()
- Page.svelte now receives store via getContext() instead of creating it
- Fixes context accessibility issue where FiltersSidebar and FontSearch
(siblings of Page) could not access the store
- All child components now share the same store instance at Layout level
This resolves the architectural issue where context only flows downward,
not sideways. All components (FiltersSidebar, FontSearch, Page) are now
children of Layout and can access the unifiedFontStore context.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Store Pattern Migration: - Created createVirtualizerStore using Svelte stores (writable/derived) - Replaced useVirtualList hook with createVirtualizerStore - Matches existing store patterns (createFilterStore, createControlStore) - More Svelte-idiomatic than React-inspired hook pattern Component Refactoring: - Renamed FontVirtualList.svelte → VirtualList.svelte - Moved component from shared/virtual/ → shared/ui/ - Updated to use store pattern instead of hook - Removed pixel values from style tags (uses Tailwind CSS) - Height now configurable via Tailwind classes (e.g., 'h-96', 'h-[500px]') - Props changed from shorthand {fonts} to explicit items prop File Changes: - Deleted: useVirtualList.ts (replaced by store pattern) - Deleted: FontVirtualList.svelte (renamed and moved) - Deleted: useVirtualList.test.ts (updated to test store pattern) - Updated: README.md with store pattern usage examples - Updated: index.ts with migration guide - Created: createVirtualizerStore.ts in shared/store/ - Created: VirtualList.svelte in shared/ui/ - Created: createVirtualizerStore.test.ts - Created: barrel exports (shared/store/index.ts, shared/ui/index.ts) Styling Improvements: - All pixel values removed from <style> tags - Uses Tailwind CSS for all styling - Responsive height via Tailwind classes or props - Only inline styles for dynamic positioning (required for virtualization) TypeScript & Testing: - Full TypeScript support with generics - All 33 tests passing - Type checking passes - Linting passes (minor warnings only) Breaking Changes: - Component name: FontVirtualList → VirtualList - Component location: $shared/virtual → $shared/ui - Hook removed: useVirtualList → createVirtualizerStore - Props change: {fonts} shorthand → items prop - Import changes: $shared/virtual → $shared/ui and $shared/store Documentation: - Updated README.md with store pattern examples - Added migration guide in virtual/index.ts - Documented breaking changes and migration stepsStore Pattern Migration: - Created createVirtualizerStore using Svelte stores (writable/derived) - Replaced useVirtualList hook with createVirtualizerStore - Matches existing store patterns (createFilterStore, createControlStore) - More Svelte-idiomatic than React-inspired hook pattern Component Refactoring: - Renamed FontVirtualList.svelte → VirtualList.svelte - Moved component from shared/virtual/ → shared/ui/ - Updated to use store pattern instead of hook - Removed pixel values from style tags (uses Tailwind CSS) - Height now configurable via Tailwind classes (e.g., 'h-96', 'h-[500px]') - Props changed from shorthand {fonts} to explicit items prop File Changes: - Deleted: useVirtualList.ts (replaced by store pattern) - Deleted: FontVirtualList.svelte (renamed and moved) - Deleted: useVirtualList.test.ts (updated to test store pattern) - Updated: README.md with store pattern usage examples - Updated: index.ts with migration guide - Created: createVirtualizerStore.ts in shared/store/ - Created: VirtualList.svelte in shared/ui/ - Created: createVirtualizerStore.test.ts - Created: barrel exports (shared/store/index.ts, shared/ui/index.ts) Styling Improvements: - All pixel values removed from <style> tags - Uses Tailwind CSS for all styling - Responsive height via Tailwind classes or props - Only inline styles for dynamic positioning (required for virtualization) TypeScript & Testing: - Full TypeScript support with generics - All 33 tests passing - Type checking passes - Linting passes (minor warnings only) Breaking Changes: - Component name: FontVirtualList → VirtualList - Component location: $shared/virtual → $shared/ui - Hook removed: useVirtualList → createVirtualizerStore - Props change: {fonts} shorthand → items prop - Import changes: $shared/virtual → $shared/ui and $shared/store Documentation: - Updated README.md with store pattern examples - Added migration guide in virtual/index.ts - Documented breaking changes and migration steps