fix(filters): use proxy fetch function
This commit is contained in:
135
src/features/GetFonts/model/state/filters.svelte.ts
Normal file
135
src/features/GetFonts/model/state/filters.svelte.ts
Normal file
@@ -0,0 +1,135 @@
|
||||
/**
|
||||
* Filters store for dynamic filter metadata
|
||||
*
|
||||
* Fetches and caches filter metadata from /api/v1/filters endpoint.
|
||||
* Provides reactive access to filter data for providers, categories, and subsets.
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* import { filtersStore } from '$features/GetFonts';
|
||||
*
|
||||
* // Access filters (reactive)
|
||||
* $: filters = filtersStore.filters;
|
||||
* $: isLoading = filtersStore.isLoading;
|
||||
* $: error = filtersStore.error;
|
||||
* ```
|
||||
*/
|
||||
|
||||
import { fetchProxyFilters } from '$entities/Font/api/proxy/filters';
|
||||
import type {
|
||||
FilterMetadata,
|
||||
FilterOption,
|
||||
} from '$entities/Font/api/proxy/filters';
|
||||
import { queryClient } from '$shared/api/queryClient';
|
||||
import {
|
||||
type QueryKey,
|
||||
QueryObserver,
|
||||
type QueryObserverOptions,
|
||||
type QueryObserverResult,
|
||||
} from '@tanstack/query-core';
|
||||
|
||||
/**
|
||||
* Filters store wrapping TanStack Query
|
||||
*
|
||||
* Fetches and caches filter metadata using fetchProxyFilters()
|
||||
* Provides reactive access to filter data
|
||||
*/
|
||||
class FiltersStore {
|
||||
/** Cleanup function for effects */
|
||||
cleanup: () => void;
|
||||
|
||||
/** TanStack Query result state */
|
||||
protected result = $state<QueryObserverResult<FilterMetadata[], Error>>({} as any);
|
||||
|
||||
/** TanStack Query observer instance */
|
||||
protected observer: QueryObserver<FilterMetadata[], Error>;
|
||||
|
||||
/** Shared query client */
|
||||
protected qc = queryClient;
|
||||
|
||||
/**
|
||||
* Creates a new filters store
|
||||
*/
|
||||
constructor() {
|
||||
this.observer = new QueryObserver(this.qc, this.getOptions());
|
||||
|
||||
// Sync TanStack Query state -> Svelte state
|
||||
this.observer.subscribe(r => {
|
||||
this.result = r;
|
||||
});
|
||||
|
||||
// Sync Svelte state changes -> TanStack Query options
|
||||
this.cleanup = $effect.root(() => {
|
||||
$effect(() => {
|
||||
this.observer.setOptions(this.getOptions());
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Query key for TanStack Query caching
|
||||
*/
|
||||
protected getQueryKey(): QueryKey {
|
||||
return ['filters'] as const;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch function for filter metadata
|
||||
* Uses fetchProxyFilters() from proxy API
|
||||
*/
|
||||
protected async fetchFn(): Promise<FilterMetadata[]> {
|
||||
return await fetchProxyFilters();
|
||||
}
|
||||
|
||||
/**
|
||||
* TanStack Query options
|
||||
*/
|
||||
protected getOptions(): QueryObserverOptions<FilterMetadata[], Error> {
|
||||
return {
|
||||
queryKey: this.getQueryKey(),
|
||||
queryFn: () => this.fetchFn(),
|
||||
staleTime: 5 * 60 * 1000, // 5 minutes
|
||||
gcTime: 10 * 60 * 1000, // 10 minutes
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all filters
|
||||
*/
|
||||
get filters(): FilterMetadata[] {
|
||||
return this.result.data ?? [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get loading state
|
||||
*/
|
||||
get isLoading(): boolean {
|
||||
return this.result.isLoading;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get error state
|
||||
*/
|
||||
get isError(): boolean {
|
||||
return this.result.isError;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get error message
|
||||
*/
|
||||
get error(): string | null {
|
||||
return this.result.error?.message ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up effects and observers
|
||||
*/
|
||||
destroy() {
|
||||
this.cleanup();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Singleton instance
|
||||
*/
|
||||
export const filtersStore = new FiltersStore();
|
||||
Reference in New Issue
Block a user