Skip to content

Commit fa78a9b

Browse files
committed
chore(playground): add support for React Compiler
1 parent a14be45 commit fa78a9b

2 files changed

Lines changed: 47 additions & 78 deletions

File tree

playground/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"lint": "eslint .",
1010
"preview": "vite preview",
1111
"typecheck": "tsc --noEmit",
12-
"codegen": "openapi-qraft --plugin tanstack-query-react --plugin openapi-typescript https://raw.githubusercontent.com/swagger-api/swagger-petstore/7767363b841961221a38c0be9c6b1066a5120051/src/main/resources/openapi.yaml --clean -o src/api --openapi-types-import-path '../schema.d.ts' --openapi-types-file-name schema.d.ts",
12+
"codegen": "openapi-qraft --plugin tanstack-query-react --plugin openapi-typescript https://raw.githubusercontent.com/swagger-api/swagger-petstore/7767363b841961221a38c0be9c6b1066a5120051/src/main/resources/openapi.yaml --clean -o src/api --openapi-types-import-path '../schema.d.ts' --openapi-types-file-name schema.d.ts --create-api-client-fn createPlaygroundAPIClient filename:create-playground-api-client context:PlaygroundAPIClientContext",
1313
"generate:mocks": "msw init && msw-auto-mock https://raw.githubusercontent.com/swagger-api/swagger-petstore/7767363b841961221a38c0be9c6b1066a5120051/src/main/resources/openapi.yaml -o src/mocks --max-array-length 10 --typescript --base-url 'https://petstore3.swagger.io/api/v3'",
1414
"e2e:pre-build": "npm run codegen",
1515
"e2e:post-build": "echo 'No post-build command'",

playground/src/App.tsx

Lines changed: 46 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,19 @@
1-
import {
2-
OperationSchema,
3-
QraftClientOptions,
4-
requestFn,
5-
RequestFnPayload,
6-
RequestFnResponse,
7-
} from '@openapi-qraft/react';
1+
import { requestFn } from '@openapi-qraft/react';
82
import { QraftSecureRequestFn } from '@openapi-qraft/react/Unstable_QraftSecureRequestFn';
9-
import {
10-
QueryClient,
11-
QueryClientProvider,
12-
useQueryClient,
13-
} from '@tanstack/react-query';
3+
import { QueryClient } from '@tanstack/react-query';
144
import {
155
ComponentProps,
16-
createContext,
176
ReactNode,
187
useContext,
8+
useEffect,
199
useState,
2010
} from 'react';
21-
import { components, createAPIClient, Services } from './api';
11+
import {
12+
components,
13+
createPlaygroundAPIClient,
14+
PlaygroundAPIClientContext,
15+
Services,
16+
} from './api';
2217

2318
function AppComponent() {
2419
const [petIdToEdit, setPetIdToEditToEdit] = useState<number | null>(null);
@@ -98,14 +93,15 @@ function PetListFilter({
9893
);
9994
}
10095

96+
const qraft = createPlaygroundAPIClient();
97+
10198
function PetList({
10299
petsFilter,
103100
onEdit,
104101
}: {
105102
petsFilter: PetsFilter;
106103
onEdit: (petId: number) => void;
107104
}) {
108-
const qraft = useCreateAPIClient();
109105
const { data, error, isPending } = qraft.pet.findPetsByStatus.useQuery({
110106
query: { status: petsFilter.status },
111107
});
@@ -188,7 +184,7 @@ function PetUpdateForm({
188184
onUpdate: () => void;
189185
onReset: () => void;
190186
}) {
191-
const qraft = useCreateAPIClient();
187+
const qraftContext = usePlaygroundAPIClientContext();
192188

193189
const petParameters: typeof qraft.pet.getPetById.types.parameters = {
194190
path: { petId },
@@ -202,11 +198,14 @@ function PetUpdateForm({
202198

203199
const { isPending, mutate } = qraft.pet.updatePet.useMutation(undefined, {
204200
async onMutate(variables) {
205-
await qraft.pet.getPetById.cancelQueries({ parameters: petParameters });
201+
const miniQraft = createPlaygroundAPIClient(qraftContext);
202+
await miniQraft.pet.getPetById.cancelQueries({
203+
parameters: petParameters,
204+
});
206205

207-
const prevPet = qraft.pet.getPetById.getQueryData(petParameters);
206+
const prevPet = miniQraft.pet.getPetById.getQueryData(petParameters);
208207

209-
qraft.pet.getPetById.setQueryData(petParameters, (oldData) => ({
208+
miniQraft.pet.getPetById.setQueryData(petParameters, (oldData) => ({
210209
...oldData,
211210
...variables.body,
212211
}));
@@ -215,12 +214,16 @@ function PetUpdateForm({
215214
},
216215
async onError(_error, _variables, context) {
217216
if (context?.prevPet) {
218-
qraft.pet.getPetById.setQueryData(petParameters, context.prevPet);
217+
createPlaygroundAPIClient(qraftContext).pet.getPetById.setQueryData(
218+
petParameters,
219+
context.prevPet
220+
);
219221
}
220222
},
221223
async onSuccess(updatedPet) {
222-
qraft.pet.getPetById.setQueryData(petParameters, updatedPet);
223-
await qraft.pet.findPetsByStatus.invalidateQueries();
224+
const miniQraft = createPlaygroundAPIClient(qraftContext);
225+
miniQraft.pet.getPetById.setQueryData(petParameters, updatedPet);
226+
await miniQraft.pet.findPetsByStatus.invalidateQueries();
224227
onUpdate();
225228
},
226229
});
@@ -292,11 +295,13 @@ function PetCreateForm({
292295
onCreate: (pet: components['schemas']['Pet']) => void;
293296
onReset: () => void;
294297
}) {
295-
const qraft = useCreateAPIClient();
298+
const qraftContext = usePlaygroundAPIClientContext();
296299

297300
const { isPending, mutate, error } = qraft.pet.addPet.useMutation(undefined, {
298301
async onSuccess(createdPet) {
299-
await qraft.pet.findPetsByStatus.invalidateQueries();
302+
await createPlaygroundAPIClient(
303+
qraftContext
304+
).pet.findPetsByStatus.invalidateQueries();
300305
if (!createdPet)
301306
throw new Error('createdPet not found in addPet.onSuccess');
302307
onCreate(createdPet);
@@ -414,6 +419,12 @@ function getErrorMessage(error: unknown) {
414419
const QraftProviders = ({ children }: { children: ReactNode }) => {
415420
const [queryClient] = useState(() => new QueryClient());
416421

422+
useEffect(() => {
423+
queryClient.mount();
424+
425+
return queryClient.unmount();
426+
}, [queryClient]);
427+
417428
return (
418429
<QraftSecureRequestFn
419430
requestFn={requestFn}
@@ -429,68 +440,26 @@ const QraftProviders = ({ children }: { children: ReactNode }) => {
429440
}}
430441
>
431442
{(secureRequestFn) => (
432-
<QueryClientProvider client={queryClient}>
433-
<APIContext.Provider
434-
value={{
435-
baseUrl: 'https://petstore3.swagger.io/api/v3',
436-
requestFn: secureRequestFn,
437-
}}
438-
>
439-
{children}
440-
</APIContext.Provider>
441-
</QueryClientProvider>
443+
<PlaygroundAPIClientContext.Provider
444+
value={{
445+
baseUrl: 'https://petstore3.swagger.io/api/v3',
446+
requestFn: secureRequestFn,
447+
queryClient,
448+
}}
449+
>
450+
{children}
451+
</PlaygroundAPIClientContext.Provider>
442452
)}
443453
</QraftSecureRequestFn>
444454
);
445455
};
446456

447-
function useCreateAPIClient(options?: Partial<QraftClientOptions>) {
448-
const apiContextValue = useContext(APIContext);
449-
450-
const requestFn =
451-
(options && 'requestFn' in options && options?.requestFn) ??
452-
apiContextValue?.requestFn;
453-
const baseUrl =
454-
(options && 'baseUrl' in options && options?.baseUrl) ??
455-
apiContextValue?.baseUrl;
456-
const queryClient = useQueryClient(
457-
options && 'queryClient' in options ? options?.queryClient : undefined
458-
);
459-
460-
if (!requestFn)
461-
throw new Error('requestFn not found in APIContext or options');
462-
if (!baseUrl) throw new Error('baseUrl not found in APIContext or options');
463-
464-
return createAPIClient({
465-
requestFn,
466-
baseUrl,
467-
queryClient,
468-
});
457+
function usePlaygroundAPIClientContext() {
458+
return useContext(PlaygroundAPIClientContext)!;
469459
}
470460

471461
type PetStatus = NonNullable<components['schemas']['Pet']['status']>;
472462

473-
interface APIContextValue {
474-
/**
475-
* Base URL to use for the request
476-
* @example 'https://api.example.com'
477-
*/
478-
baseUrl?: string;
479-
480-
/**
481-
* The `requestFn` will be invoked with every request.
482-
*/
483-
requestFn<TData, TError>(
484-
requestSchema: OperationSchema,
485-
requestInfo: RequestFnPayload
486-
): Promise<RequestFnResponse<TData, TError>>;
487-
488-
/** The QueryClient to use in Hooks */
489-
queryClient?: QueryClient;
490-
}
491-
492-
const APIContext = createContext<APIContextValue | undefined>(undefined);
493-
494463
function assertPetStatus(
495464
petStatusToCreate: unknown
496465
): asserts petStatusToCreate is PetStatus {

0 commit comments

Comments
 (0)