diff --git a/.changeset/thirty-pears-reply.md b/.changeset/thirty-pears-reply.md new file mode 100644 index 00000000000..783bd8d0c87 --- /dev/null +++ b/.changeset/thirty-pears-reply.md @@ -0,0 +1,6 @@ +--- +'@clerk/clerk-js': patch +'@clerk/shared': patch +--- + +Disable retry in queryClient. diff --git a/packages/clerk-js/package.json b/packages/clerk-js/package.json index d9dba6d50c5..d672736feb3 100644 --- a/packages/clerk-js/package.json +++ b/packages/clerk-js/package.json @@ -70,7 +70,7 @@ "@formkit/auto-animate": "^0.8.2", "@stripe/stripe-js": "5.6.0", "@swc/helpers": "^0.5.17", - "@tanstack/query-core": "5.87.4", + "@tanstack/query-core": "catalog:tanstack", "@zxcvbn-ts/core": "3.0.4", "@zxcvbn-ts/language-common": "3.0.4", "alien-signals": "2.0.6", diff --git a/packages/clerk-js/src/core/clerk.ts b/packages/clerk-js/src/core/clerk.ts index da8f4f62bb6..e023d6d9fe8 100644 --- a/packages/clerk-js/src/core/clerk.ts +++ b/packages/clerk-js/src/core/clerk.ts @@ -97,7 +97,7 @@ import type { } from '@clerk/shared/types'; import { addClerkPrefix, isAbsoluteUrl, stripScheme } from '@clerk/shared/url'; import { allSettled, handleValueOrFn, noop } from '@clerk/shared/utils'; -import type { QueryClient } from '@tanstack/query-core'; +import type { QueryClient, QueryClientConfig } from '@tanstack/query-core'; import { debugLogger, initDebugLogger } from '@/utils/debug'; @@ -201,6 +201,24 @@ const defaultOptions: ClerkOptions = { newSubscriptionRedirectUrl: undefined, }; +const RQ_CLIENT_TAG = 'clerk-rq-client' as const; + +type ClerkRQClient = { __tag: typeof RQ_CLIENT_TAG; client: QueryClient }; + +const clerkQueryClientConfig: QueryClientConfig = { + defaultOptions: { + queries: { + // use the retry logic that fapiClient uses + retry: false, + // Note: to refetch onWindowFocus, you need to call `queryClient.mount()` + refetchOnWindowFocus: false, + refetchOnReconnect: false, + // the query will refetch on mount if the data is stale + refetchOnMount: true, + }, + }, +}; + export class Clerk implements ClerkInterface { public static mountComponentRenderer?: MountComponentRenderer; @@ -246,23 +264,12 @@ export class Clerk implements ClerkInterface { #touchThrottledUntil = 0; #publicEventBus = createClerkEventBus(); - get __internal_queryClient(): { __tag: 'clerk-rq-client'; client: QueryClient } | undefined { - if (!this.#queryClient) { - void import('./query-core') - .then(module => module.QueryClient) - .then(QueryClient => { - if (this.#queryClient) { - return; - } - this.#queryClient = new QueryClient(); - // @ts-expect-error - queryClientStatus is not typed - this.#publicEventBus.emit('queryClientStatus', 'ready'); - }); - } + get __internal_queryClient(): ClerkRQClient | undefined { + this.#initQueryClient(); return this.#queryClient ? { - __tag: 'clerk-rq-client', + __tag: RQ_CLIENT_TAG, client: this.#queryClient, } : undefined; @@ -292,6 +299,25 @@ export class Clerk implements ClerkInterface { public __internal_setActiveInProgress = false; + #initQueryClient = (): void => { + if (this.#queryClient) { + return; + } + + void import('./query-core') + .then(module => module.QueryClient) + .then(QueryClientCtor => { + if (this.#queryClient) { + return; + } + + this.#queryClient = new QueryClientCtor(clerkQueryClientConfig); + + // @ts-expect-error - queryClientStatus is not typed + this.#publicEventBus.emit('queryClientStatus', 'ready'); + }); + }; + get publishableKey(): string { return this.#publishableKey; } diff --git a/packages/clerk-js/src/test/mock-helpers.ts b/packages/clerk-js/src/test/mock-helpers.ts index d76dea115bb..ea8719cbac5 100644 --- a/packages/clerk-js/src/test/mock-helpers.ts +++ b/packages/clerk-js/src/test/mock-helpers.ts @@ -55,6 +55,9 @@ export const mockClerkMethods = (clerk: LoadedClerk): DeepVitestMocked { const clerk = useClerkInstanceContext(); // @ts-expect-error - __internal_queryClient is not typed - const queryClient = clerk.__internal_queryClient as { __tag: 'clerk-rq-client'; client: QueryClient } | undefined; + const queryClient = clerk.__internal_queryClient as ClerkRQClient | undefined; const [, setQueryClientLoaded] = useState( typeof queryClient === 'object' && '__tag' in queryClient && queryClient.__tag === 'clerk-rq-client', ); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b4e64573239..c63ab4d0b00 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -28,6 +28,10 @@ catalogs: zx: specifier: 8.8.5 version: 8.8.5 + tanstack: + '@tanstack/query-core': + specifier: 5.87.4 + version: 5.87.4 overrides: jest: 29.7.0 @@ -459,7 +463,7 @@ importers: specifier: ^0.5.17 version: 0.5.17 '@tanstack/query-core': - specifier: 5.87.4 + specifier: catalog:tanstack version: 5.87.4 '@zxcvbn-ts/core': specifier: 3.0.4 @@ -939,7 +943,7 @@ importers: specifier: 5.6.0 version: 5.6.0 '@tanstack/query-core': - specifier: 5.87.4 + specifier: catalog:tanstack version: 5.87.4 '@types/glob-to-regexp': specifier: 0.4.4 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 39b6bb4fc0d..30e7ddaf868 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -18,6 +18,10 @@ catalogs: react: ^18.0.0 || ^19.0.0 || ^19.0.0-0 react-dom: ^18.0.0 || ^19.0.0 || ^19.0.0-0 + # Can be referenced through "catalog:tanstack" + tanstack: + '@tanstack/query-core': 5.87.4 + # Can be referenced through "catalog:repo" repo: tslib: 2.8.1