Skip to content

Commit 26f11d9

Browse files
committed
chore(shared,clerk-js): Set defaultOptions to queryClient
1 parent 69833fe commit 26f11d9

File tree

7 files changed

+90
-34
lines changed

7 files changed

+90
-34
lines changed

packages/clerk-js/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@
7171
"@formkit/auto-animate": "^0.8.2",
7272
"@stripe/stripe-js": "5.6.0",
7373
"@swc/helpers": "^0.5.17",
74-
"@tanstack/query-core": "5.87.4",
74+
"@tanstack/query-core": "catalog:tanstack",
7575
"@zxcvbn-ts/core": "3.0.4",
7676
"@zxcvbn-ts/language-common": "3.0.4",
7777
"alien-signals": "2.0.6",

packages/clerk-js/src/core/clerk.ts

Lines changed: 41 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ import type {
9494
} from '@clerk/shared/types';
9595
import { addClerkPrefix, isAbsoluteUrl, stripScheme } from '@clerk/shared/url';
9696
import { allSettled, handleValueOrFn, noop } from '@clerk/shared/utils';
97-
import type { QueryClient } from '@tanstack/query-core';
97+
import type { QueryClient, QueryClientConfig } from '@tanstack/query-core';
9898

9999
import { debugLogger, initDebugLogger } from '@/utils/debug';
100100

@@ -198,6 +198,24 @@ const defaultOptions: ClerkOptions = {
198198
newSubscriptionRedirectUrl: undefined,
199199
};
200200

201+
const RQ_CLIENT_TAG = 'clerk-rq-client' as const;
202+
203+
type ClerkRQClient = { __tag: typeof RQ_CLIENT_TAG; client: QueryClient };
204+
205+
const clerkQueryClientConfig: QueryClientConfig = {
206+
defaultOptions: {
207+
queries: {
208+
// use the retry logic that fapiClient uses
209+
retry: false,
210+
// Note: to refetch onWindowFocus, you need to call `queryClient.mount()`
211+
refetchOnWindowFocus: false,
212+
refetchOnReconnect: false,
213+
// the query will refetch on mount if the data is stale
214+
refetchOnMount: true,
215+
},
216+
},
217+
};
218+
201219
export class Clerk implements ClerkInterface {
202220
public static mountComponentRenderer?: MountComponentRenderer;
203221

@@ -243,23 +261,12 @@ export class Clerk implements ClerkInterface {
243261
#touchThrottledUntil = 0;
244262
#publicEventBus = createClerkEventBus();
245263

246-
get __internal_queryClient(): { __tag: 'clerk-rq-client'; client: QueryClient } | undefined {
247-
if (!this.#queryClient) {
248-
void import('./query-core')
249-
.then(module => module.QueryClient)
250-
.then(QueryClient => {
251-
if (this.#queryClient) {
252-
return;
253-
}
254-
this.#queryClient = new QueryClient();
255-
// @ts-expect-error - queryClientStatus is not typed
256-
this.#publicEventBus.emit('queryClientStatus', 'ready');
257-
});
258-
}
264+
get __internal_queryClient(): ClerkRQClient | undefined {
265+
this.#initQueryClient();
259266

260267
return this.#queryClient
261268
? {
262-
__tag: 'clerk-rq-client',
269+
__tag: RQ_CLIENT_TAG,
263270
client: this.#queryClient,
264271
}
265272
: undefined;
@@ -289,6 +296,25 @@ export class Clerk implements ClerkInterface {
289296

290297
public __internal_setActiveInProgress = false;
291298

299+
#initQueryClient = (): void => {
300+
if (this.#queryClient) {
301+
return;
302+
}
303+
304+
void import('./query-core')
305+
.then(module => module.QueryClient)
306+
.then(QueryClientCtor => {
307+
if (this.#queryClient) {
308+
return;
309+
}
310+
311+
this.#queryClient = new QueryClientCtor(clerkQueryClientConfig);
312+
313+
// @ts-expect-error - queryClientStatus is not typed
314+
this.#publicEventBus.emit('queryClientStatus', 'ready');
315+
});
316+
};
317+
292318
get publishableKey(): string {
293319
return this.#publishableKey;
294320
}

packages/clerk-js/src/test/mock-helpers.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ export const mockClerkMethods = (clerk: LoadedClerk): DeepVitestMocked<LoadedCle
5555
// Setting staleTime to Infinity will not cause issues between tests as long as each test
5656
// case has its own wrapper that initializes a Clerk instance with a new QueryClient.
5757
staleTime: Infinity,
58+
refetchOnWindowFocus: false,
59+
refetchOnReconnect: false,
60+
refetchOnMount: false,
5861
},
5962
},
6063
}),

packages/shared/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@
163163
"devDependencies": {
164164
"@stripe/react-stripe-js": "3.1.1",
165165
"@stripe/stripe-js": "5.6.0",
166-
"@tanstack/query-core": "5.87.4",
166+
"@tanstack/query-core": "catalog:tanstack",
167167
"@types/glob-to-regexp": "0.4.4",
168168
"@types/js-cookie": "3.0.6",
169169
"cross-fetch": "^4.1.0",

packages/shared/src/react/clerk-rq/use-clerk-query-client.ts

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -57,28 +57,47 @@ function createRecursiveProxy(label: string): RecursiveMock {
5757

5858
const mockQueryClient = createRecursiveProxy('ClerkMockQueryClient') as unknown as QueryClient;
5959

60+
type ClerkRQClient = { __tag: 'clerk-rq-client'; client: QueryClient };
61+
62+
const isTaggedRQClient = (value: unknown): value is ClerkRQClient => {
63+
return (
64+
typeof value === 'object' &&
65+
value !== null &&
66+
'__tag' in (value as Record<string, unknown>) &&
67+
(value as Record<string, unknown>).__tag === 'clerk-rq-client'
68+
);
69+
};
70+
71+
const getQueryClientState = (clerk: unknown): { client: QueryClient; isLoaded: boolean } => {
72+
const internal = (clerk as { __internal_queryClient?: ClerkRQClient | undefined }).__internal_queryClient;
73+
74+
if (isTaggedRQClient(internal)) {
75+
return { client: internal.client, isLoaded: true };
76+
}
77+
78+
return { client: mockQueryClient, isLoaded: false };
79+
};
80+
6081
const useClerkQueryClient = (): [QueryClient, boolean] => {
6182
const clerk = useClerkInstanceContext();
6283

63-
// @ts-expect-error - __internal_queryClient is not typed
64-
const queryClient = clerk.__internal_queryClient as { __tag: 'clerk-rq-client'; client: QueryClient } | undefined;
65-
const [, setQueryClientLoaded] = useState(
66-
typeof queryClient === 'object' && '__tag' in queryClient && queryClient.__tag === 'clerk-rq-client',
67-
);
84+
const [state, setState] = useState<{ client: QueryClient; isLoaded: boolean }>(() => getQueryClientState(clerk));
6885

6986
useEffect(() => {
70-
const _setQueryClientLoaded = () => setQueryClientLoaded(true);
71-
// @ts-expect-error - queryClientStatus is not typed
72-
clerk.on('queryClientStatus', _setQueryClientLoaded);
73-
return () => {
74-
// @ts-expect-error - queryClientStatus is not typed
75-
clerk.off('queryClientStatus', _setQueryClientLoaded);
87+
const handleStatusChange = () => {
88+
setState(getQueryClientState(clerk));
7689
};
77-
}, [clerk, setQueryClientLoaded]);
7890

79-
const isLoaded = typeof queryClient === 'object' && '__tag' in queryClient && queryClient.__tag === 'clerk-rq-client';
91+
// @ts-expect-error - queryClientStatus is not typed on Clerk
92+
clerk.on('queryClientStatus', handleStatusChange);
93+
94+
return () => {
95+
// @ts-expect-error - queryClientStatus is not typed on Clerk
96+
clerk.off('queryClientStatus', handleStatusChange);
97+
};
98+
}, [clerk]);
8099

81-
return [queryClient?.client || mockQueryClient, isLoaded];
100+
return [state.client, state.isLoaded];
82101
};
83102

84103
export { useClerkQueryClient };

pnpm-lock.yaml

Lines changed: 7 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pnpm-workspace.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ catalogs:
1818
react: ^18.0.0 || ^19.0.0 || ^19.0.0-0
1919
react-dom: ^18.0.0 || ^19.0.0 || ^19.0.0-0
2020

21+
# Can be referenced through "catalog:tanstack"
22+
tanstack:
23+
'@tanstack/query-core': 5.87.4
24+
2125
# Can be referenced through "catalog:repo"
2226
repo:
2327
tslib: 2.8.1

0 commit comments

Comments
 (0)