refactor(shared/api): lazify queryClient to remove eager-construction footgun

queryClient.ts constructed the TanStack client at module eval but was not
in the sideEffects allowlist, so Rollup treated the module as pure — safe
only while a value-importer keeps it alive (D-3).

- replace the eager `queryClient` singleton with a memoized getQueryClient()
  factory; construction is deferred to first call
- the module is now genuinely side-effect-free, so no sideEffects exception
  is needed and construction can never be legally tree-shaken away
- route all consumers through getQueryClient() (QueryProvider as first
  caller; stores via class fields/observers; tests via a local alias; the
  fontCatalogStore spec mock now overrides getQueryClient)
This commit is contained in:
Ilia Mashkov
2026-06-02 23:13:03 +03:00
parent b390efdabe
commit 60e115309c
13 changed files with 71 additions and 48 deletions
@@ -27,18 +27,21 @@ vi.mock('$shared/api/queryClient', async importOriginal => {
*/
const { QueryClient } = await import('@tanstack/query-core');
const actual = await importOriginal<typeof import('$shared/api/queryClient')>();
const mockClient = new QueryClient({
defaultOptions: { queries: { retry: 0, gcTime: 0 } },
});
return {
...actual,
queryClient: new QueryClient({
defaultOptions: { queries: { retry: 0, gcTime: 0 } },
}),
getQueryClient: () => mockClient,
};
});
vi.mock('../../../api', () => ({ fetchProxyFonts: vi.fn() }));
import { queryClient } from '$shared/api/queryClient';
import { getQueryClient } from '$shared/api/queryClient';
import { fetchProxyFonts } from '../../../api';
const queryClient = getQueryClient();
const fetch = fetchProxyFonts as ReturnType<typeof vi.fn>;
type FontPage = { fonts: UnifiedFont[]; total: number; limit: number; offset: number };
@@ -1,7 +1,7 @@
import {
DEFAULT_QUERY_GC_TIME_MS,
DEFAULT_QUERY_STALE_TIME_MS,
queryClient,
getQueryClient,
} from '$shared/api/queryClient';
import {
type InfiniteData,
@@ -46,7 +46,7 @@ export class FontCatalogStore {
readonly unknown[],
PageParam
>;
#qc = queryClient;
#qc = getQueryClient();
#unsubscribe: () => void;
constructor(params: FontStoreParams = {}) {
@@ -1,4 +1,6 @@
import { queryClient } from '$shared/api/queryClient';
import { getQueryClient } from '$shared/api/queryClient';
const queryClient = getQueryClient();
import { fontKeys } from '$shared/api/queryKeys';
import {
beforeEach,