Skip to content

Commit 1d4e7a7

Browse files
authored
chore(shared): Improve cache key creation (#7217)
1 parent bdbb0d9 commit 1d4e7a7

14 files changed

+448
-348
lines changed

.changeset/lemon-facts-stare.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@clerk/shared': patch
3+
---
4+
5+
Update how cache keys are created in SWR/RQ hooks.

packages/clerk-js/bundlewatch.config.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
{ "path": "./dist/clerk.legacy.browser.js", "maxSize": "123KB" },
77
{ "path": "./dist/clerk.headless*.js", "maxSize": "63.2KB" },
88
{ "path": "./dist/ui-common*.js", "maxSize": "117.1KB" },
9-
{ "path": "./dist/ui-common*.legacy.*.js", "maxSize": "120KB" },
9+
{ "path": "./dist/ui-common*.legacy.*.js", "maxSize": "120.1KB" },
1010
{ "path": "./dist/vendors*.js", "maxSize": "47KB" },
1111
{ "path": "./dist/coinbase*.js", "maxSize": "38KB" },
1212
{ "path": "./dist/stripe-vendors*.js", "maxSize": "1KB" },

packages/shared/src/react/hooks/__tests__/usePagesOrInfinite.spec.ts

Lines changed: 130 additions & 148 deletions
Large diffs are not rendered by default.

packages/shared/src/react/hooks/createBillingPaginatedHook.tsx

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
useUserContext,
88
} from '../contexts';
99
import type { PagesOrInfiniteOptions, PaginatedHookConfig, PaginatedResources } from '../types';
10+
import { createCacheKeys } from './createCacheKeys';
1011
import { usePagesOrInfinite, useWithSafeValues } from './usePagesOrInfinite';
1112

1213
/**
@@ -35,6 +36,16 @@ export interface HookParams
3536
* @default true
3637
*/
3738
enabled?: boolean;
39+
/**
40+
* On `cache` mode, no request will be triggered when the hook is mounted and the data will be fetched from the cache.
41+
*
42+
* @default undefined
43+
*
44+
* @hidden
45+
*
46+
* @experimental
47+
*/
48+
__experimental_mode?: 'cache';
3849
}
3950
> {
4051
/**
@@ -110,28 +121,31 @@ export function createBillingPaginatedHook<TResource extends ClerkResource, TPar
110121

111122
const isEnabled = !!hookParams && clerk.loaded && !!billingEnabled && (externalEnabled ?? true);
112123

113-
const result = usePagesOrInfinite<TParams, ClerkPaginatedResponse<TResource>>(
114-
(hookParams || {}) as TParams,
115-
fetchFn,
116-
{
117-
...({
118-
keepPreviousData: safeValues.keepPreviousData,
119-
infinite: safeValues.infinite,
120-
} as PaginatedHookConfig<unknown>),
124+
const result = usePagesOrInfinite({
125+
fetcher: fetchFn,
126+
config: {
127+
keepPreviousData: safeValues.keepPreviousData,
128+
infinite: safeValues.infinite,
121129
enabled: isEnabled,
122130
...(options?.unauthenticated ? {} : { isSignedIn: Boolean(user) }),
123131
__experimental_mode: safeValues.__experimental_mode,
132+
initialPage: safeValues.initialPage,
133+
pageSize: safeValues.pageSize,
124134
},
125-
{
126-
type: resourceType,
127-
...(options?.unauthenticated
128-
? { for: safeFor }
129-
: {
135+
keys: createCacheKeys({
136+
stablePrefix: resourceType,
137+
authenticated: !options?.unauthenticated,
138+
tracked: options?.unauthenticated
139+
? ({ for: safeFor } as const)
140+
: ({
130141
userId: user?.id,
131-
...(isForOrganization ? { orgId: organization?.id } : {}),
132-
}),
133-
},
134-
);
142+
...(isForOrganization ? { [__CLERK_USE_RQ__ ? 'orgId' : '_orgId']: organization?.id } : {}),
143+
} as const),
144+
untracked: {
145+
args: hookParams as TParams,
146+
},
147+
}),
148+
});
135149

136150
return result;
137151
};
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/**
2+
* @internal
3+
*/
4+
export function createCacheKeys<
5+
Params,
6+
StableKey extends string,
7+
T extends Record<string, unknown> = Record<string, unknown>,
8+
U extends Record<string, unknown> | undefined = undefined,
9+
>(params: {
10+
stablePrefix: StableKey;
11+
authenticated: boolean;
12+
tracked: T;
13+
untracked: U extends { args: Params } ? U : never;
14+
}) {
15+
return {
16+
queryKey: [params.stablePrefix, params.authenticated, params.tracked, params.untracked] as const,
17+
invalidationKey: [params.stablePrefix, params.authenticated, params.tracked] as const,
18+
stableKey: params.stablePrefix,
19+
authenticated: params.authenticated,
20+
};
21+
}

packages/shared/src/react/hooks/useAPIKeys.ts

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
'use client';
22

33
import { eventMethodCalled } from '../../telemetry/events/method-called';
4-
import type { APIKeyResource, ClerkPaginatedResponse, GetAPIKeysParams } from '../../types';
4+
import type { APIKeyResource, GetAPIKeysParams } from '../../types';
55
import { useAssertWrappedByClerkProvider, useClerkInstanceContext } from '../contexts';
66
import type { PaginatedHookConfig, PaginatedResources } from '../types';
7+
import { createCacheKeys } from './createCacheKeys';
78
import { usePagesOrInfinite, useWithSafeValues } from './usePagesOrInfinite';
89

910
/**
@@ -92,17 +93,25 @@ export function useAPIKeys<T extends UseAPIKeysParams>(params?: T): UseAPIKeysRe
9293

9394
const isEnabled = (safeValues.enabled ?? true) && clerk.loaded;
9495

95-
return usePagesOrInfinite<GetAPIKeysParams, ClerkPaginatedResponse<APIKeyResource>>(
96-
hookParams,
97-
clerk.apiKeys?.getAll ? (params: GetAPIKeysParams) => clerk.apiKeys.getAll(params) : undefined,
98-
{
96+
return usePagesOrInfinite({
97+
fetcher: clerk.apiKeys?.getAll ? (params: GetAPIKeysParams) => clerk.apiKeys.getAll(params) : undefined,
98+
config: {
9999
keepPreviousData: safeValues.keepPreviousData,
100100
infinite: safeValues.infinite,
101101
enabled: isEnabled,
102+
isSignedIn: Boolean(clerk.user),
103+
initialPage: safeValues.initialPage,
104+
pageSize: safeValues.pageSize,
102105
},
103-
{
104-
type: 'apiKeys',
105-
subject: safeValues.subject || '',
106-
},
107-
) as UseAPIKeysReturn<T>;
106+
keys: createCacheKeys({
107+
stablePrefix: 'apiKeys',
108+
authenticated: Boolean(clerk.user),
109+
tracked: {
110+
subject: safeValues.subject,
111+
},
112+
untracked: {
113+
args: hookParams,
114+
},
115+
}),
116+
}) as UseAPIKeysReturn<T>;
108117
}

packages/shared/src/react/hooks/useOrganization.tsx

Lines changed: 69 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { getCurrentOrganizationMembership } from '../../organization';
22
import { eventMethodCalled } from '../../telemetry/events/method-called';
33
import type {
4-
ClerkPaginatedResponse,
54
GetDomainsParams,
65
GetInvitationsParams,
76
GetMembershipRequestParams,
@@ -19,6 +18,7 @@ import {
1918
useSessionContext,
2019
} from '../contexts';
2120
import type { PaginatedHookConfig, PaginatedResources, PaginatedResourcesWithDefault } from '../types';
21+
import { createCacheKeys } from './createCacheKeys';
2222
import { usePagesOrInfinite, useWithSafeValues } from './usePagesOrInfinite';
2323

2424
/**
@@ -357,70 +357,93 @@ export function useOrganization<T extends UseOrganizationParams>(params?: T): Us
357357
status: invitationsSafeValues.status,
358358
};
359359

360-
const domains = usePagesOrInfinite<GetDomainsParams, ClerkPaginatedResponse<OrganizationDomainResource>>(
361-
{
362-
...domainParams,
363-
},
364-
organization?.getDomains,
365-
{
360+
const domains = usePagesOrInfinite({
361+
fetcher: organization?.getDomains,
362+
config: {
366363
keepPreviousData: domainSafeValues.keepPreviousData,
367364
infinite: domainSafeValues.infinite,
368365
enabled: !!domainParams,
366+
isSignedIn: Boolean(organization),
367+
initialPage: domainSafeValues.initialPage,
368+
pageSize: domainSafeValues.pageSize,
369369
},
370-
{
371-
type: 'domains',
372-
organizationId: organization?.id,
373-
},
374-
);
370+
keys: createCacheKeys({
371+
stablePrefix: 'domains',
372+
authenticated: Boolean(organization),
373+
tracked: {
374+
organizationId: organization?.id,
375+
},
376+
untracked: {
377+
args: domainParams,
378+
},
379+
}),
380+
});
375381

376-
const membershipRequests = usePagesOrInfinite<
377-
GetMembershipRequestParams,
378-
ClerkPaginatedResponse<OrganizationMembershipRequestResource>
379-
>(
380-
{
381-
...membershipRequestParams,
382-
},
383-
organization?.getMembershipRequests,
384-
{
382+
const membershipRequests = usePagesOrInfinite({
383+
fetcher: organization?.getMembershipRequests,
384+
config: {
385385
keepPreviousData: membershipRequestSafeValues.keepPreviousData,
386386
infinite: membershipRequestSafeValues.infinite,
387387
enabled: !!membershipRequestParams,
388+
isSignedIn: Boolean(organization),
389+
initialPage: membershipRequestSafeValues.initialPage,
390+
pageSize: membershipRequestSafeValues.pageSize,
388391
},
389-
{
390-
type: 'membershipRequests',
391-
organizationId: organization?.id,
392-
},
393-
);
392+
keys: createCacheKeys({
393+
stablePrefix: 'membershipRequests',
394+
authenticated: Boolean(organization),
395+
tracked: {
396+
organizationId: organization?.id,
397+
},
398+
untracked: {
399+
args: membershipRequestParams,
400+
},
401+
}),
402+
});
394403

395-
const memberships = usePagesOrInfinite<GetMembersParams, ClerkPaginatedResponse<OrganizationMembershipResource>>(
396-
membersParams || {},
397-
organization?.getMemberships,
398-
{
404+
const memberships = usePagesOrInfinite({
405+
fetcher: organization?.getMemberships,
406+
config: {
399407
keepPreviousData: membersSafeValues.keepPreviousData,
400408
infinite: membersSafeValues.infinite,
401409
enabled: !!membersParams,
410+
isSignedIn: Boolean(organization),
411+
initialPage: membersSafeValues.initialPage,
412+
pageSize: membersSafeValues.pageSize,
402413
},
403-
{
404-
type: 'members',
405-
organizationId: organization?.id,
406-
},
407-
);
414+
keys: createCacheKeys({
415+
stablePrefix: 'members',
416+
authenticated: Boolean(organization),
417+
tracked: {
418+
organizationId: organization?.id,
419+
},
420+
untracked: {
421+
args: membersParams,
422+
},
423+
}),
424+
});
408425

409-
const invitations = usePagesOrInfinite<GetInvitationsParams, ClerkPaginatedResponse<OrganizationInvitationResource>>(
410-
{
411-
...invitationsParams,
412-
},
413-
organization?.getInvitations,
414-
{
426+
const invitations = usePagesOrInfinite({
427+
fetcher: organization?.getInvitations,
428+
config: {
415429
keepPreviousData: invitationsSafeValues.keepPreviousData,
416430
infinite: invitationsSafeValues.infinite,
417431
enabled: !!invitationsParams,
432+
isSignedIn: Boolean(organization),
433+
initialPage: invitationsSafeValues.initialPage,
434+
pageSize: invitationsSafeValues.pageSize,
418435
},
419-
{
420-
type: 'invitations',
421-
organizationId: organization?.id,
422-
},
423-
);
436+
keys: createCacheKeys({
437+
stablePrefix: 'invitations',
438+
authenticated: Boolean(organization),
439+
tracked: {
440+
organizationId: organization?.id,
441+
},
442+
untracked: {
443+
args: invitationsParams,
444+
},
445+
}),
446+
});
424447

425448
if (organization === undefined) {
426449
return {

0 commit comments

Comments
 (0)