From 28a8e4991586daa54671b5361faac1b29930b03b Mon Sep 17 00:00:00 2001 From: Ilia Mashkov Date: Mon, 1 Jun 2026 11:49:53 +0300 Subject: [PATCH] refactor(font): keep @tanstack out of the entity public API barrel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extract NonRetryableError into its own tanstack-free module and drop the ./api re-export from the Font slice barrel. Importing $entities/Font no longer transitively loads @tanstack/query-core or constructs the QueryClient singleton via the ./api and ./lib (errors) chains — light consumers (domain, types, consts) and unit specs stop paying for TanStack. Note: ./ui still pulls the stores; addressed separately. --- src/entities/Font/index.ts | 11 ++++++++++- src/entities/Font/lib/errors/errors.ts | 2 +- .../FilterAndSortFonts/api/filters/filters.ts | 2 +- src/shared/api/nonRetryableError.ts | 14 ++++++++++++++ src/shared/api/queryClient.ts | 11 +---------- 5 files changed, 27 insertions(+), 13 deletions(-) create mode 100644 src/shared/api/nonRetryableError.ts 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