feature/comparison-slider #19
@@ -55,7 +55,6 @@ export type {
|
||||
FontshareFont,
|
||||
FontshareLink,
|
||||
FontsharePublisher,
|
||||
FontshareStore,
|
||||
FontshareStyle,
|
||||
FontshareStyleProperties,
|
||||
FontshareTag,
|
||||
@@ -75,21 +74,10 @@ export type {
|
||||
export {
|
||||
appliedFontsManager,
|
||||
createUnifiedFontStore,
|
||||
fetchFontshareFontsQuery,
|
||||
selectedFontsStore,
|
||||
unifiedFontStore,
|
||||
} from './model';
|
||||
|
||||
// Stores (DEPRECATED)
|
||||
export {
|
||||
createFontshareStore,
|
||||
fontshareStore,
|
||||
} from './model';
|
||||
export {
|
||||
createGoogleFontsStore,
|
||||
GoogleFontsStore,
|
||||
} from './model/services/fetchGoogleFonts.svelte';
|
||||
|
||||
// UI elements
|
||||
export {
|
||||
FontApplicator,
|
||||
|
||||
@@ -34,8 +34,6 @@ export type {
|
||||
UnifiedFontVariant,
|
||||
} from './types';
|
||||
|
||||
export { fetchFontshareFontsQuery } from './services';
|
||||
|
||||
export {
|
||||
appliedFontsManager,
|
||||
createUnifiedFontStore,
|
||||
@@ -43,10 +41,3 @@ export {
|
||||
type UnifiedFontStore,
|
||||
unifiedFontStore,
|
||||
} from './store';
|
||||
|
||||
// DEPRECATED: Fontshare store (kept for backward compatibility)
|
||||
export {
|
||||
createFontshareStore,
|
||||
type FontshareStore,
|
||||
fontshareStore,
|
||||
} from './store/fontshareStore.svelte';
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
import {
|
||||
type FontshareParams,
|
||||
fetchFontshareFonts,
|
||||
} from '../../api';
|
||||
import { normalizeFontshareFonts } from '../../lib';
|
||||
import type { UnifiedFont } from '../types';
|
||||
|
||||
/**
|
||||
* Query function for fetching fonts from Fontshare.
|
||||
*
|
||||
* @param params - The parameters for fetching fonts from Fontshare (E.g. search query, page number, etc.).
|
||||
* @returns A promise that resolves with an array of UnifiedFont objects representing the fonts found in Fontshare.
|
||||
*/
|
||||
export async function fetchFontshareFontsQuery(params: FontshareParams): Promise<UnifiedFont[]> {
|
||||
try {
|
||||
const response = await fetchFontshareFonts(params);
|
||||
return normalizeFontshareFonts(response.fonts);
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
if (error.message.includes('Failed to fetch')) {
|
||||
throw new Error(
|
||||
'Unable to connect to Fontshare. Please check your internet connection.',
|
||||
);
|
||||
}
|
||||
if (error.message.includes('404')) {
|
||||
throw new Error('Font not found in Fontshare catalog.');
|
||||
}
|
||||
}
|
||||
throw new Error('Failed to load fonts from Fontshare.');
|
||||
}
|
||||
}
|
||||
@@ -1,274 +0,0 @@
|
||||
/**
|
||||
* Service for fetching Google Fonts with Svelte 5 runes + TanStack Query
|
||||
*/
|
||||
import {
|
||||
type CreateQueryResult,
|
||||
createQuery,
|
||||
useQueryClient,
|
||||
} from '@tanstack/svelte-query';
|
||||
import {
|
||||
type GoogleFontsParams,
|
||||
fetchGoogleFonts,
|
||||
} from '../../api';
|
||||
import { normalizeGoogleFonts } from '../../lib';
|
||||
import type {
|
||||
FontCategory,
|
||||
FontSubset,
|
||||
} from '../types';
|
||||
import type { UnifiedFont } from '../types/normalize';
|
||||
|
||||
/**
|
||||
* Query key factory
|
||||
*/
|
||||
function getGoogleFontsQueryKey(params: GoogleFontsParams) {
|
||||
return ['googleFonts', params] as const;
|
||||
}
|
||||
|
||||
/**
|
||||
* Query function
|
||||
*/
|
||||
export async function fetchGoogleFontsQuery(params: GoogleFontsParams): Promise<UnifiedFont[]> {
|
||||
try {
|
||||
const response = await fetchGoogleFonts({
|
||||
category: params.category,
|
||||
subset: params.subset,
|
||||
sort: params.sort,
|
||||
});
|
||||
return normalizeGoogleFonts(response.items);
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
if (error.message.includes('Failed to fetch')) {
|
||||
throw new Error(
|
||||
'Unable to connect to Google Fonts. Please check your internet connection.',
|
||||
);
|
||||
}
|
||||
if (error.message.includes('404')) {
|
||||
throw new Error('Font not found in Google Fonts catalog.');
|
||||
}
|
||||
}
|
||||
throw new Error('Failed to load fonts from Google Fonts.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Google Fonts store wrapping TanStack Query with runes
|
||||
*/
|
||||
export class GoogleFontsStore {
|
||||
params = $state<GoogleFontsParams>({});
|
||||
private query: CreateQueryResult<UnifiedFont[], Error>;
|
||||
private queryClient = useQueryClient();
|
||||
|
||||
constructor(initialParams: GoogleFontsParams = {}) {
|
||||
this.params = initialParams;
|
||||
|
||||
// Create the query - automatically reactive
|
||||
this.query = createQuery(() => ({
|
||||
queryKey: getGoogleFontsQueryKey(this.params),
|
||||
queryFn: () => fetchGoogleFontsQuery(this.params),
|
||||
staleTime: 5 * 60 * 1000, // 5 minutes
|
||||
gcTime: 10 * 60 * 1000, // 10 minutes
|
||||
}));
|
||||
}
|
||||
|
||||
// Proxy TanStack Query's reactive state
|
||||
get fonts() {
|
||||
return this.query.data ?? [];
|
||||
}
|
||||
|
||||
get isLoading() {
|
||||
return this.query.isLoading;
|
||||
}
|
||||
|
||||
get isFetching() {
|
||||
return this.query.isFetching;
|
||||
}
|
||||
|
||||
get isRefetching() {
|
||||
return this.query.isRefetching;
|
||||
}
|
||||
|
||||
get error() {
|
||||
return this.query.error;
|
||||
}
|
||||
|
||||
get isError() {
|
||||
return this.query.isError;
|
||||
}
|
||||
|
||||
get isSuccess() {
|
||||
return this.query.isSuccess;
|
||||
}
|
||||
|
||||
get status() {
|
||||
return this.query.status;
|
||||
}
|
||||
|
||||
// Derived helpers
|
||||
get hasData() {
|
||||
return this.fonts.length > 0;
|
||||
}
|
||||
|
||||
get isEmpty() {
|
||||
return !this.isLoading && this.fonts.length === 0;
|
||||
}
|
||||
|
||||
get fontCount() {
|
||||
return this.fonts.length;
|
||||
}
|
||||
|
||||
// Filtered fonts by category (if you need additional client-side filtering)
|
||||
get sansSerifFonts() {
|
||||
return this.fonts.filter(f => f.category === 'sans-serif');
|
||||
}
|
||||
|
||||
get serifFonts() {
|
||||
return this.fonts.filter(f => f.category === 'serif');
|
||||
}
|
||||
|
||||
get displayFonts() {
|
||||
return this.fonts.filter(f => f.category === 'display');
|
||||
}
|
||||
|
||||
get handwritingFonts() {
|
||||
return this.fonts.filter(f => f.category === 'handwriting');
|
||||
}
|
||||
|
||||
get monospaceFonts() {
|
||||
return this.fonts.filter(f => f.category === 'monospace');
|
||||
}
|
||||
|
||||
/**
|
||||
* Update parameters - TanStack Query will automatically refetch
|
||||
*/
|
||||
setParams(newParams: Partial<GoogleFontsParams>) {
|
||||
this.params = { ...this.params, ...newParams };
|
||||
}
|
||||
|
||||
setCategory(category: FontCategory | undefined) {
|
||||
this.setParams({ category });
|
||||
}
|
||||
|
||||
setSubset(subset: FontSubset | undefined) {
|
||||
this.setParams({ subset });
|
||||
}
|
||||
|
||||
setSort(sort: 'popularity' | 'alpha' | 'date' | undefined) {
|
||||
this.setParams({ sort });
|
||||
}
|
||||
|
||||
setSearch(search: string) {
|
||||
this.setParams({ search });
|
||||
}
|
||||
|
||||
clearSearch() {
|
||||
this.setParams({ search: undefined });
|
||||
}
|
||||
|
||||
clearFilters() {
|
||||
this.params = {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Manually refetch
|
||||
*/
|
||||
async refetch() {
|
||||
await this.query.refetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidate cache and refetch
|
||||
*/
|
||||
invalidate() {
|
||||
this.queryClient.invalidateQueries({
|
||||
queryKey: getGoogleFontsQueryKey(this.params),
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidate all Google Fonts queries
|
||||
*/
|
||||
invalidateAll() {
|
||||
this.queryClient.invalidateQueries({
|
||||
queryKey: ['googleFonts'],
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefetch with different params (for hover states, pagination, etc.)
|
||||
*/
|
||||
async prefetch(params: GoogleFontsParams) {
|
||||
await this.queryClient.prefetchQuery({
|
||||
queryKey: getGoogleFontsQueryKey(params),
|
||||
queryFn: () => fetchGoogleFontsQuery(params),
|
||||
staleTime: 5 * 60 * 1000,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefetch next category (useful for tab switching)
|
||||
*/
|
||||
async prefetchCategory(category: FontCategory) {
|
||||
await this.prefetch({ ...this.params, category });
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancel ongoing queries
|
||||
*/
|
||||
cancel() {
|
||||
this.queryClient.cancelQueries({
|
||||
queryKey: getGoogleFontsQueryKey(this.params),
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear cache for current params
|
||||
*/
|
||||
clearCache() {
|
||||
this.queryClient.removeQueries({
|
||||
queryKey: getGoogleFontsQueryKey(this.params),
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cached data without triggering fetch
|
||||
*/
|
||||
getCachedData() {
|
||||
return this.queryClient.getQueryData<UnifiedFont[]>(
|
||||
getGoogleFontsQueryKey(this.params),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if data exists in cache
|
||||
*/
|
||||
hasCache(params?: GoogleFontsParams) {
|
||||
const key = params ? getGoogleFontsQueryKey(params) : getGoogleFontsQueryKey(this.params);
|
||||
return this.queryClient.getQueryData(key) !== undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set data manually (optimistic updates)
|
||||
*/
|
||||
setQueryData(updater: (old: UnifiedFont[] | undefined) => UnifiedFont[]) {
|
||||
this.queryClient.setQueryData(
|
||||
getGoogleFontsQueryKey(this.params),
|
||||
updater,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get query state for debugging
|
||||
*/
|
||||
getQueryState() {
|
||||
return this.queryClient.getQueryState(
|
||||
getGoogleFontsQueryKey(this.params),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory function to create Google Fonts store
|
||||
*/
|
||||
export function createGoogleFontsStore(params: GoogleFontsParams = {}) {
|
||||
return new GoogleFontsStore(params);
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
export { fetchFontshareFontsQuery } from './fetchFontshareFonts.svelte';
|
||||
export { fetchGoogleFontsQuery } from './fetchGoogleFonts.svelte';
|
||||
@@ -1,40 +0,0 @@
|
||||
import type { FontshareParams } from '../../api';
|
||||
import { fetchFontshareFontsQuery } from '../services';
|
||||
import type { UnifiedFont } from '../types';
|
||||
import { BaseFontStore } from './baseFontStore.svelte';
|
||||
|
||||
/**
|
||||
* Fontshare store wrapping TanStack Query with runes
|
||||
*/
|
||||
export class FontshareStore extends BaseFontStore<FontshareParams> {
|
||||
constructor(initialParams: FontshareParams = {}) {
|
||||
super(initialParams);
|
||||
}
|
||||
|
||||
protected getQueryKey(params: FontshareParams) {
|
||||
// Normalize params to treat empty arrays/strings as undefined
|
||||
const normalized = Object.entries(params).reduce((acc, [key, value]) => {
|
||||
if (value === '' || (Array.isArray(value) && value.length === 0)) {
|
||||
return acc;
|
||||
}
|
||||
return { ...acc, [key]: value };
|
||||
}, {});
|
||||
|
||||
return ['fontshare', normalized] as const;
|
||||
}
|
||||
|
||||
protected async fetchFn(params: FontshareParams): Promise<UnifiedFont[]> {
|
||||
return fetchFontshareFontsQuery(params);
|
||||
}
|
||||
|
||||
// Provider-specific methods (shortcuts)
|
||||
setSearch(search: string) {
|
||||
this.setParams({ q: search } as any);
|
||||
}
|
||||
}
|
||||
|
||||
export function createFontshareStore(params: FontshareParams = {}) {
|
||||
return new FontshareStore(params);
|
||||
}
|
||||
|
||||
export const fontshareStore = new FontshareStore();
|
||||
@@ -1,27 +0,0 @@
|
||||
import type { GoogleFontsParams } from '../../api';
|
||||
import { fetchGoogleFontsQuery } from '../services';
|
||||
import type { UnifiedFont } from '../types';
|
||||
import { BaseFontStore } from './baseFontStore.svelte';
|
||||
|
||||
/**
|
||||
* Google Fonts store wrapping TanStack Query with runes
|
||||
*/
|
||||
export class GoogleFontsStore extends BaseFontStore<GoogleFontsParams> {
|
||||
constructor(initialParams: GoogleFontsParams = {}) {
|
||||
super(initialParams);
|
||||
}
|
||||
|
||||
protected getQueryKey(params: GoogleFontsParams) {
|
||||
return ['googleFonts', params] as const;
|
||||
}
|
||||
|
||||
protected async fetchFn(params: GoogleFontsParams): Promise<UnifiedFont[]> {
|
||||
return fetchGoogleFontsQuery(params);
|
||||
}
|
||||
}
|
||||
|
||||
export function createGoogleFontsStore(params: GoogleFontsParams = {}) {
|
||||
return new GoogleFontsStore(params);
|
||||
}
|
||||
|
||||
export const googleFontsStore = new GoogleFontsStore();
|
||||
@@ -18,17 +18,3 @@ export { appliedFontsManager } from './appliedFontsStore/appliedFontsStore.svelt
|
||||
|
||||
// Selected fonts store (user selection - unchanged)
|
||||
export { selectedFontsStore } from './selectedFontsStore/selectedFontsStore.svelte';
|
||||
|
||||
// DEPRECATED: Fontshare store (will be removed in Phase 6)
|
||||
export {
|
||||
createFontshareStore,
|
||||
type FontshareStore,
|
||||
fontshareStore,
|
||||
} from './fontshareStore.svelte';
|
||||
|
||||
// DEPRECATED: Google Fonts store (will be removed in Phase 6)
|
||||
export {
|
||||
createGoogleFontsStore,
|
||||
type GoogleFontsStore,
|
||||
googleFontsStore,
|
||||
} from './googleFontsStore.svelte';
|
||||
|
||||
Reference in New Issue
Block a user