Skip to content

Commit 8b3311c

Browse files
committed
chore(shared,clerk-js): Set defaultOptions to queryClient
1 parent 4fae43c commit 8b3311c

File tree

7 files changed

+89
-33
lines changed

7 files changed

+89
-33
lines changed

packages/clerk-js/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@
7070
"@formkit/auto-animate": "^0.8.2",
7171
"@stripe/stripe-js": "5.6.0",
7272
"@swc/helpers": "^0.5.17",
73-
"@tanstack/query-core": "5.87.4",
73+
"@tanstack/query-core": "catalog:tanstack",
7474
"@zxcvbn-ts/core": "3.0.4",
7575
"@zxcvbn-ts/language-common": "3.0.4",
7676
"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
@@ -97,7 +97,7 @@ import type {
9797
} from '@clerk/shared/types';
9898
import { addClerkPrefix, isAbsoluteUrl, stripScheme } from '@clerk/shared/url';
9999
import { allSettled, handleValueOrFn, noop } from '@clerk/shared/utils';
100-
import type { QueryClient } from '@tanstack/query-core';
100+
import type { QueryClient, QueryClientConfig } from '@tanstack/query-core';
101101

102102
import { debugLogger, initDebugLogger } from '@/utils/debug';
103103

@@ -201,6 +201,24 @@ const defaultOptions: ClerkOptions = {
201201
newSubscriptionRedirectUrl: undefined,
202202
};
203203

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

@@ -246,23 +264,12 @@ export class Clerk implements ClerkInterface {
246264
#touchThrottledUntil = 0;
247265
#publicEventBus = createClerkEventBus();
248266

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

263270
return this.#queryClient
264271
? {
265-
__tag: 'clerk-rq-client',
272+
__tag: RQ_CLIENT_TAG,
266273
client: this.#queryClient,
267274
}
268275
: undefined;
@@ -292,6 +299,25 @@ export class Clerk implements ClerkInterface {
292299

293300
public __internal_setActiveInProgress = false;
294301

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

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: 6 additions & 2 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)