feat: implement P0/P1 performance and code quality optimizations
P0 Performance Optimizations: - Add debounced search (300ms) to reduce re-renders during typing - Implement single-pass filter function for O(n) complexity - Add TanStack Query cancellation before new requests P1 Code Quality Optimizations: - Add runtime type guards for filter validation - Implement two derived values (filteredFonts + sortedFilteredFonts) - Remove all 'as any[]' casts from filter bridge - Add fast-path for default sorting (skip unnecessary operations) New Utilities: - debounce utility with 4 tests (all pass) - filterUtils with 15 tests (all pass) - typeGuards with 20 tests (all pass) - Total: 39 new tests Modified Files: - unifiedFontStore.svelte.ts: Add debouncing, use filter/sort utilities - filterBridge.svelte.ts: Type-safe validation with type guards - unifiedFontStore.test.ts: Fix pre-existing bugs (missing async, duplicate imports) Code Quality: - 0 linting warnings/errors (oxlint) - FSD compliant architecture (entity lib layer) - Backward compatible store API
This commit is contained in:
115
src/features/FontManagement/lib/filterBridge.svelte.ts
Normal file
115
src/features/FontManagement/lib/filterBridge.svelte.ts
Normal file
@@ -0,0 +1,115 @@
|
||||
import {
|
||||
filterValidValues,
|
||||
isValidFontCategory,
|
||||
isValidFontProvider,
|
||||
isValidFontSubset,
|
||||
} from '$entities/Font/lib/typeGuards';
|
||||
import type { UnifiedFontStore } from '$entities/Font/model/store';
|
||||
import { filterManager } from '$features/FilterFonts';
|
||||
import type { Property } from '$shared/lib';
|
||||
|
||||
/**
|
||||
* ============================================================================
|
||||
* FILTER BRIDGE
|
||||
* ============================================================================
|
||||
*
|
||||
* Bridges the UI filter state (filterManager from FilterFonts feature) with the
|
||||
* unified font store (unifiedFontStore from Font entity).
|
||||
*
|
||||
* OPTIMIZATIONS (P1):
|
||||
* - Runtime type validation using type guards
|
||||
* - No more 'as any[]' casts - type-safe assignments
|
||||
*/
|
||||
|
||||
// ... (comments)
|
||||
|
||||
// ============================================================================
|
||||
// FILTER GROUP MAPPING
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* Get selected values from a filter manager group by ID
|
||||
*/
|
||||
function getSelectedFilterValues(groupId: string): string[] {
|
||||
const group = filterManager.getGroup(groupId);
|
||||
if (!group) return [];
|
||||
|
||||
return group.instance.selectedProperties.map((property: Property<string>) => property.value);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// SYNC LOGIC
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* Sync filter manager state to unified font store
|
||||
*
|
||||
* @param store - The unified font store instance
|
||||
*/
|
||||
export function syncFilters(store: UnifiedFontStore): void {
|
||||
const providers = getSelectedFilterValues('providers');
|
||||
const categories = getSelectedFilterValues('categories');
|
||||
const subsets = getSelectedFilterValues('subsets');
|
||||
|
||||
// Validate and filter providers
|
||||
const validProviders = filterValidValues(providers, isValidFontProvider);
|
||||
|
||||
// Validate and filter categories
|
||||
const validCategories = filterValidValues(categories, isValidFontCategory);
|
||||
|
||||
// Validate and filter subsets
|
||||
const validSubsets = filterValidValues(subsets, isValidFontSubset);
|
||||
|
||||
// Update unified store filters with validated, type-safe values
|
||||
store.filters = {
|
||||
providers: validProviders,
|
||||
categories: validCategories,
|
||||
subsets: validSubsets,
|
||||
searchQuery: store.filters.searchQuery,
|
||||
};
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// PUBLIC API
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* Apply current filters and fetch fonts from providers
|
||||
*
|
||||
* @param store - The unified font store instance
|
||||
*/
|
||||
export async function applyFilters(store: UnifiedFontStore): Promise<void> {
|
||||
await store.fetchFonts();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset all filters to their default state
|
||||
*
|
||||
* @param store - The unified font store instance
|
||||
*/
|
||||
export function resetFilters(store: UnifiedFontStore): void {
|
||||
// Reset filter manager selections
|
||||
filterManager.deselectAllGlobal();
|
||||
|
||||
// Clear unified store filters
|
||||
store.clearFilters();
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply current filter selections and fetch fonts
|
||||
*
|
||||
* @param store - The unified font store instance
|
||||
*/
|
||||
export async function applyFilterType(store: UnifiedFontStore): Promise<void> {
|
||||
syncFilters(store);
|
||||
await store.fetchFonts();
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// RE-EXPORTS FOR CONVENIENCE
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* Re-export filter manager for direct access
|
||||
*/
|
||||
export { filterManager } from '$features/FilterFonts';
|
||||
Reference in New Issue
Block a user