chore: follow the general comments style

This commit is contained in:
Ilia Mashkov
2026-04-17 12:14:55 +03:00
parent 0ebf75b24e
commit cfaff46d59
56 changed files with 1600 additions and 499 deletions
+311 -39
View File
@@ -1,8 +1,4 @@
/**
* ============================================================================
* MOCK FONT STORE HELPERS
* ============================================================================
*
* Factory functions and preset mock data for TanStack Query stores and state management.
* Used in Storybook stories for components that use reactive stores.
*
@@ -35,27 +31,73 @@ import {
generateMockFonts,
} from './fonts.mock';
// TANSTACK QUERY MOCK TYPES
/**
* Mock TanStack Query state
*/
export interface MockQueryState<TData = unknown, TError = Error> {
/**
* Primary query status (pending, success, error)
*/
status: QueryStatus;
/**
* Payload data (present on success)
*/
data?: TData;
/**
* Caught error object (present on error)
*/
error?: TError;
/**
* True if initial load is in progress
*/
isLoading?: boolean;
/**
* True if background fetch is in progress
*/
isFetching?: boolean;
/**
* True if query resolved successfully
*/
isSuccess?: boolean;
/**
* True if query failed
*/
isError?: boolean;
/**
* True if query is waiting to be executed
*/
isPending?: boolean;
/**
* Timestamp of last successful data retrieval
*/
dataUpdatedAt?: number;
/**
* Timestamp of last recorded error
*/
errorUpdatedAt?: number;
/**
* Total number of consecutive failures
*/
failureCount?: number;
/**
* Detailed reason for the last failure
*/
failureReason?: TError;
/**
* Number of times an error has been caught
*/
errorUpdateCount?: number;
/**
* True if currently refetching in background
*/
isRefetching?: boolean;
/**
* True if refetch attempt failed
*/
isRefetchError?: boolean;
/**
* True if query is paused (e.g. offline)
*/
isPaused?: boolean;
}
@@ -63,26 +105,72 @@ export interface MockQueryState<TData = unknown, TError = Error> {
* Mock TanStack Query observer result
*/
export interface MockQueryObserverResult<TData = unknown, TError = Error> {
/**
* Current observer status
*/
status?: QueryStatus;
/**
* Cached or active data payload
*/
data?: TData;
/**
* Caught error from the observer
*/
error?: TError;
/**
* Loading flag for the observer
*/
isLoading?: boolean;
/**
* Fetching flag for the observer
*/
isFetching?: boolean;
/**
* Success flag for the observer
*/
isSuccess?: boolean;
/**
* Error flag for the observer
*/
isError?: boolean;
/**
* Pending flag for the observer
*/
isPending?: boolean;
/**
* Last update time for data
*/
dataUpdatedAt?: number;
/**
* Last update time for error
*/
errorUpdatedAt?: number;
/**
* Consecutive failure count
*/
failureCount?: number;
/**
* Failure reason object
*/
failureReason?: TError;
/**
* Error count for the observer
*/
errorUpdateCount?: number;
/**
* Refetching flag
*/
isRefetching?: boolean;
/**
* Refetch error flag
*/
isRefetchError?: boolean;
/**
* Paused flag
*/
isPaused?: boolean;
}
// TANSTACK QUERY MOCK FACTORIES
/**
* Create a mock query state for TanStack Query
*/
@@ -138,33 +226,53 @@ export function createSuccessState<TData>(data: TData): MockQueryObserverResult<
return createMockQueryState<TData>({ status: 'success', data, error: undefined });
}
// FONT STORE MOCKS
/**
* Mock UnifiedFontStore state
*/
export interface MockFontStoreState {
/** All cached fonts */
/**
* Map of mock fonts indexed by ID
*/
fonts: Record<string, UnifiedFont>;
/** Current page */
/**
* Currently active page number
*/
page: number;
/** Total pages available */
/**
* Total number of pages calculated from limit
*/
totalPages: number;
/** Items per page */
/**
* Number of items per page
*/
limit: number;
/** Total font count */
/**
* Total number of available fonts
*/
total: number;
/** Loading state */
/**
* Store-level loading status
*/
isLoading: boolean;
/** Error state */
/**
* Caught error object
*/
error: Error | null;
/** Search query */
/**
* Mock search filter string
*/
searchQuery: string;
/** Selected provider */
/**
* Mock provider filter selection
*/
provider: 'google' | 'fontshare' | 'all';
/** Selected category */
/**
* Mock category filter selection
*/
category: string | null;
/** Selected subset */
/**
* Mock subset filter selection
*/
subset: string | null;
}
@@ -210,10 +318,12 @@ export function createMockFontStoreState(
}
/**
* Preset font store states
* Preset font store states for UI testing
*/
export const MOCK_FONT_STORE_STATES = {
/** Initial loading state */
/**
* Initial loading state with no data
*/
loading: createMockFontStoreState({
isLoading: true,
fonts: {},
@@ -221,7 +331,9 @@ export const MOCK_FONT_STORE_STATES = {
page: 1,
}),
/** Empty state (no fonts found) */
/**
* State with no fonts matching filters
*/
empty: createMockFontStoreState({
fonts: {},
total: 0,
@@ -229,7 +341,9 @@ export const MOCK_FONT_STORE_STATES = {
isLoading: false,
}),
/** First page with fonts */
/**
* First page of results (10 items)
*/
firstPage: createMockFontStoreState({
fonts: Object.fromEntries(
Object.values(UNIFIED_FONTS).slice(0, 10).map(font => [font.id, font]),
@@ -241,7 +355,9 @@ export const MOCK_FONT_STORE_STATES = {
isLoading: false,
}),
/** Second page with fonts */
/**
* Second page of results (10 items)
*/
secondPage: createMockFontStoreState({
fonts: Object.fromEntries(
Object.values(UNIFIED_FONTS).slice(10, 20).map(font => [font.id, font]),
@@ -253,7 +369,9 @@ export const MOCK_FONT_STORE_STATES = {
isLoading: false,
}),
/** Last page with fonts */
/**
* Final page of results (5 items)
*/
lastPage: createMockFontStoreState({
fonts: Object.fromEntries(
Object.values(UNIFIED_FONTS).slice(0, 5).map(font => [font.id, font]),
@@ -265,7 +383,9 @@ export const MOCK_FONT_STORE_STATES = {
isLoading: false,
}),
/** Error state */
/**
* Terminal failure state
*/
error: createMockFontStoreState({
fonts: {},
error: new Error('Failed to load fonts'),
@@ -274,7 +394,9 @@ export const MOCK_FONT_STORE_STATES = {
isLoading: false,
}),
/** With search query */
/**
* State with active search query
*/
withSearch: createMockFontStoreState({
fonts: Object.fromEntries(
Object.values(UNIFIED_FONTS).slice(0, 3).map(font => [font.id, font]),
@@ -285,7 +407,9 @@ export const MOCK_FONT_STORE_STATES = {
searchQuery: 'Roboto',
}),
/** Filtered by category */
/**
* State with active category filter
*/
filteredByCategory: createMockFontStoreState({
fonts: Object.fromEntries(
Object.values(UNIFIED_FONTS)
@@ -299,7 +423,9 @@ export const MOCK_FONT_STORE_STATES = {
category: 'serif',
}),
/** Filtered by provider */
/**
* State with active provider filter
*/
filteredByProvider: createMockFontStoreState({
fonts: Object.fromEntries(
Object.values(UNIFIED_FONTS)
@@ -313,7 +439,9 @@ export const MOCK_FONT_STORE_STATES = {
provider: 'google',
}),
/** Large dataset */
/**
* Large collection for performance testing (50 items)
*/
largeDataset: createMockFontStoreState({
fonts: Object.fromEntries(
generateMockFonts(50).map(font => [font.id, font]),
@@ -326,17 +454,30 @@ export const MOCK_FONT_STORE_STATES = {
}),
};
// MOCK STORE OBJECT
/**
* Create a mock store object that mimics TanStack Query behavior
* Useful for components that subscribe to store properties
*/
export function createMockStore<T>(config: {
/**
* Reactive data payload
*/
data?: T;
/**
* Loading status flag
*/
isLoading?: boolean;
/**
* Error status flag
*/
isError?: boolean;
/**
* Catch-all error object
*/
error?: Error;
/**
* Background fetching flag
*/
isFetching?: boolean;
}) {
const {
@@ -348,24 +489,45 @@ export function createMockStore<T>(config: {
} = config;
return {
/**
* Returns the active data payload
*/
get data() {
return data;
},
/**
* True if initially loading
*/
get isLoading() {
return isLoading;
},
/**
* True if last request failed
*/
get isError() {
return isError;
},
/**
* Returns the caught error object
*/
get error() {
return error;
},
/**
* True if fetching in background
*/
get isFetching() {
return isFetching;
},
/**
* True if query is stable and has data
*/
get isSuccess() {
return !isLoading && !isError && data !== undefined;
},
/**
* Returns semantic status string
*/
get status() {
if (isLoading) return 'pending';
if (isError) return 'error';
@@ -375,23 +537,29 @@ export function createMockStore<T>(config: {
}
/**
* Preset mock stores
* Preset mock stores for common UI states
*/
export const MOCK_STORES = {
/** Font store in loading state */
/**
* Initial loading state
*/
loadingFontStore: createMockStore<UnifiedFont[]>({
isLoading: true,
data: undefined,
}),
/** Font store with fonts loaded */
/**
* Successful data load state
*/
successFontStore: createMockStore<UnifiedFont[]>({
data: Object.values(UNIFIED_FONTS),
isLoading: false,
isError: false,
}),
/** Font store with error */
/**
* API error state
*/
errorFontStore: createMockStore<UnifiedFont[]>({
data: undefined,
isLoading: false,
@@ -399,7 +567,9 @@ export const MOCK_STORES = {
error: new Error('Failed to load fonts'),
}),
/** Font store with empty results */
/**
* Empty result set state
*/
emptyFontStore: createMockStore<UnifiedFont[]>({
data: [],
isLoading: false,
@@ -414,36 +584,69 @@ export const MOCK_STORES = {
const mockState = createMockFontStoreState(state);
return {
// State properties
/**
* Collection of mock fonts
*/
get fonts() {
return mockState.fonts;
},
/**
* Current mock page
*/
get page() {
return mockState.page;
},
/**
* Total mock pages
*/
get totalPages() {
return mockState.totalPages;
},
/**
* Mock items per page
*/
get limit() {
return mockState.limit;
},
/**
* Total mock items
*/
get total() {
return mockState.total;
},
/**
* Mock loading status
*/
get isLoading() {
return mockState.isLoading;
},
/**
* Mock error status
*/
get error() {
return mockState.error;
},
/**
* Mock search string
*/
get searchQuery() {
return mockState.searchQuery;
},
/**
* Mock provider filter
*/
get provider() {
return mockState.provider;
},
/**
* Mock category filter
*/
get category() {
return mockState.category;
},
/**
* Mock subset filter
*/
get subset() {
return mockState.subset;
},
@@ -464,15 +667,45 @@ export const MOCK_STORES = {
* Matches FontStore's public API for Storybook use
*/
fontStore: (config: {
/**
* Preset font list
*/
fonts?: UnifiedFont[];
/**
* Total item count
*/
total?: number;
/**
* Items per page
*/
limit?: number;
/**
* Pagination offset
*/
offset?: number;
/**
* Loading flag
*/
isLoading?: boolean;
/**
* Fetching flag
*/
isFetching?: boolean;
/**
* Error flag
*/
isError?: boolean;
/**
* Catch-all error object
*/
error?: Error | null;
/**
* Has more pages flag
*/
hasMore?: boolean;
/**
* Current page number
*/
page?: number;
} = {}) => {
const {
@@ -495,27 +728,51 @@ export const MOCK_STORES = {
return {
// State getters
/**
* Current mock parameters
*/
get params() {
return state.params;
},
/**
* Mock font list
*/
get fonts() {
return mockFonts;
},
/**
* Mock loading state
*/
get isLoading() {
return isLoading;
},
/**
* Mock fetching state
*/
get isFetching() {
return isFetching;
},
/**
* Mock error state
*/
get isError() {
return isError;
},
/**
* Mock error object
*/
get error() {
return error;
},
/**
* Mock empty state check
*/
get isEmpty() {
return !isLoading && !isFetching && mockFonts.length === 0;
},
/**
* Mock pagination metadata
*/
get pagination() {
return {
total: mockTotal,
@@ -527,18 +784,33 @@ export const MOCK_STORES = {
};
},
// Category getters
/**
* Derived sans-serif filter
*/
get sansSerifFonts() {
return mockFonts.filter(f => f.category === 'sans-serif');
},
/**
* Derived serif filter
*/
get serifFonts() {
return mockFonts.filter(f => f.category === 'serif');
},
/**
* Derived display filter
*/
get displayFonts() {
return mockFonts.filter(f => f.category === 'display');
},
/**
* Derived handwriting filter
*/
get handwritingFonts() {
return mockFonts.filter(f => f.category === 'handwriting');
},
/**
* Derived monospace filter
*/
get monospaceFonts() {
return mockFonts.filter(f => f.category === 'monospace');
},