diff --git a/src/entities/Font/index.ts b/src/entities/Font/index.ts index 938ecb0..d25188a 100644 --- a/src/entities/Font/index.ts +++ b/src/entities/Font/index.ts @@ -1,4 +1,3 @@ -export * from './api'; export * from './domain'; export * from './lib'; export * from './ui'; @@ -8,6 +7,16 @@ export * from './ui'; export * from './model/const/const'; export * from './model/types'; +/* + * `./api` (proxy clients: `fetchProxyFonts`, `seedFontCache`, …) is intentionally + * NOT re-exported here. Those clients import `$shared/api/queryClient`, whose + * module eval runs `new QueryClient()` and loads `@tanstack/query-core`. Funneling + * them through this barrel made every consumer of `$entities/Font` — including + * pure-domain and type-only importers — eager-load TanStack and construct the + * client (notably in unit specs). Import API clients via the segment: + * import { fetchProxyFonts } from '$entities/Font/api'; + */ + /* * Stores (`fontCatalogStore`, `fontLifecycleManager`, `FontsByIdsStore`) are * intentionally NOT re-exported here. They instantiate module-level singletons diff --git a/src/entities/Font/lib/errors/errors.ts b/src/entities/Font/lib/errors/errors.ts index 4702c8a..0f057c2 100644 --- a/src/entities/Font/lib/errors/errors.ts +++ b/src/entities/Font/lib/errors/errors.ts @@ -1,4 +1,4 @@ -import { NonRetryableError } from '$shared/api/queryClient'; +import { NonRetryableError } from '$shared/api/nonRetryableError'; /** * Thrown when the network request to the proxy API fails. diff --git a/src/features/FilterAndSortFonts/api/filters/filters.ts b/src/features/FilterAndSortFonts/api/filters/filters.ts index ef38be4..8e0e51e 100644 --- a/src/features/FilterAndSortFonts/api/filters/filters.ts +++ b/src/features/FilterAndSortFonts/api/filters/filters.ts @@ -9,7 +9,7 @@ import { api } from '$shared/api/api'; import { API_ENDPOINTS } from '$shared/api/endpoints'; -import { NonRetryableError } from '$shared/api/queryClient'; +import { NonRetryableError } from '$shared/api/nonRetryableError'; const PROXY_API_URL = API_ENDPOINTS.filters; diff --git a/src/shared/api/nonRetryableError.ts b/src/shared/api/nonRetryableError.ts new file mode 100644 index 0000000..7ce5a3e --- /dev/null +++ b/src/shared/api/nonRetryableError.ts @@ -0,0 +1,14 @@ +/** + * Marker base class for errors that retrying will never fix — schema-validation + * failures, unauthorized responses, contract violations, etc. + * + * The queryClient retry handler short-circuits when it sees this; without it, + * a non-transient backend bug pins the UI through the full retry budget + * (default 3× exponential backoff ≈ 7s). + * + * Lives in its own module — free of `@tanstack/query-core` — so error types that + * extend it (e.g. `FontResponseError`) can be imported without dragging the + * TanStack client and its eager `new QueryClient()` instantiation into the + * importer's module graph. See the barrel-coupling notes in the FSD audit. + */ +export class NonRetryableError extends Error {} diff --git a/src/shared/api/queryClient.ts b/src/shared/api/queryClient.ts index 8e18293..1e921e5 100644 --- a/src/shared/api/queryClient.ts +++ b/src/shared/api/queryClient.ts @@ -1,14 +1,5 @@ import { QueryClient } from '@tanstack/query-core'; - -/** - * Marker base class for errors that retrying will never fix — schema-validation - * failures, unauthorized responses, contract violations, etc. - * - * The queryClient retry handler short-circuits when it sees this; without it, - * a non-transient backend bug pins the UI through the full retry budget - * (default 3× exponential backoff ≈ 7s). - */ -export class NonRetryableError extends Error {} +import { NonRetryableError } from './nonRetryableError'; /** * Data remains fresh for this long after fetch. Stores that override