Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: [] Add shared query cache #1540

Merged
merged 1 commit into from
Nov 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 4 additions & 31 deletions packages/reference/src/common/EntityStore.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,7 @@
import React, { useCallback, useEffect, useMemo, useRef } from 'react';

import { BaseAppSDK } from '@contentful/app-sdk';
import {
FetchQueryOptions,
Query,
QueryCache,
QueryClient,
QueryClientProvider,
QueryKey,
useQuery,
useQueryClient,
} from '@tanstack/react-query';
import { FetchQueryOptions, Query, QueryKey } from '@tanstack/react-query';
import constate from 'constate';
import { PlainClientAPI, createClient } from 'contentful-management';
import PQueue from 'p-queue';
Expand All @@ -24,6 +15,7 @@ import {
ScheduledAction,
Space,
} from '../types';
import { SharedQueryClientProvider, useQuery, useQueryClient } from './queryClient';

export type ResourceInfo<R extends Resource = Resource> = {
resource: R;
Expand Down Expand Up @@ -462,29 +454,10 @@ export function useResource(resourceType: ResourceType, urn: string, options?: U
}

function EntityProvider({ children, ...props }: React.PropsWithChildren<EntityStoreProps>) {
const reactQueryClient = useMemo(() => {
const queryCache = new QueryCache();
const queryClient = new QueryClient({
queryCache,
defaultOptions: {
queries: {
useErrorBoundary: false,
refetchOnWindowFocus: false,
refetchOnReconnect: true,
refetchOnMount: false,
staleTime: Infinity,
retry: false,
},
},
});

return queryClient;
}, []);

return (
<QueryClientProvider client={reactQueryClient}>
<SharedQueryClientProvider>
<InternalServiceProvider {...props}>{children}</InternalServiceProvider>
</QueryClientProvider>
</SharedQueryClientProvider>
);
}

Expand Down
47 changes: 47 additions & 0 deletions packages/reference/src/common/queryClient.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import * as React from 'react';

import { QueryClient, useQuery as useRQ } from '@tanstack/react-query';

/**
* A custom client context ensures zero conflict with host apps also using
* React Query.
*/
const clientContext = React.createContext<QueryClient | undefined>(undefined);

export function useQueryClient(): QueryClient {
const client = React.useContext(clientContext);

return React.useMemo(() => {
if (client) {
return client;
}

return new QueryClient({
defaultOptions: {
queries: {
useErrorBoundary: false,
refetchOnWindowFocus: false,
refetchOnReconnect: true,
refetchOnMount: false,
staleTime: Infinity,
retry: false,
},
},
});
}, [client]);
}

// @ts-expect-error
export const useQuery: typeof useRQ = (key, fn, opt) => {
return useRQ(key, fn, { ...opt, context: clientContext });
};

/**
* Provides access to a query client either by sharing an existing client or
* creating a new one.
*/
export function SharedQueryClientProvider({ children }: React.PropsWithChildren<{}>) {
const client = useQueryClient();

return <clientContext.Provider value={client}>{children}</clientContext.Provider>;
}
1 change: 1 addition & 0 deletions packages/reference/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export type {
} from './common/customCardTypes';
export { SortableLinkList } from './common/SortableLinkList';
export { EntityProvider, useEntityLoader, useEntity, useResource } from './common/EntityStore';
export { SharedQueryClientProvider as EntityCacheProvider } from './common/queryClient';
export type { ResourceInfo } from './common/EntityStore';
export { SingleResourceReferenceEditor, MultipleResourceReferenceEditor } from './resources';
export * from './types';
Loading