@apollo/client 4.2.0-alpha.1 → 4.2.0-alpha.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +209 -0
- package/__cjs/core/ApolloClient.cjs +25 -12
- package/__cjs/core/ApolloClient.cjs.map +1 -1
- package/__cjs/core/ApolloClient.d.cts +305 -146
- package/__cjs/core/QueryManager.cjs.map +1 -1
- package/__cjs/core/defaultOptions.cjs +3 -0
- package/__cjs/core/defaultOptions.cjs.map +1 -0
- package/__cjs/core/defaultOptions.d.cts +90 -0
- package/__cjs/core/index.cjs.map +1 -1
- package/__cjs/core/index.d.cts +2 -1
- package/__cjs/link/ws/index.cjs +9 -1
- package/__cjs/link/ws/index.cjs.map +1 -1
- package/__cjs/link/ws/index.d.cts +1 -1
- package/__cjs/react/hooks/useBackgroundQuery.cjs +3 -3
- package/__cjs/react/hooks/useBackgroundQuery.cjs.map +1 -1
- package/__cjs/react/hooks/useBackgroundQuery.d.cts +1598 -765
- package/__cjs/react/hooks/useLazyQuery.cjs +3 -5
- package/__cjs/react/hooks/useLazyQuery.cjs.map +1 -1
- package/__cjs/react/hooks/useLazyQuery.d.cts +369 -115
- package/__cjs/react/hooks/useLoadableQuery.cjs +8 -4
- package/__cjs/react/hooks/useLoadableQuery.cjs.map +1 -1
- package/__cjs/react/hooks/useLoadableQuery.d.cts +507 -192
- package/__cjs/react/hooks/useMutation.cjs +5 -48
- package/__cjs/react/hooks/useMutation.cjs.map +1 -1
- package/__cjs/react/hooks/useMutation.d.cts +239 -130
- package/__cjs/react/hooks/useQuery.cjs +5 -5
- package/__cjs/react/hooks/useQuery.cjs.map +1 -1
- package/__cjs/react/hooks/useQuery.d.cts +636 -276
- package/__cjs/react/hooks/useSubscription.cjs +1 -1
- package/__cjs/react/hooks/useSubscription.cjs.map +1 -1
- package/__cjs/react/hooks/useSubscription.d.cts +2 -2
- package/__cjs/react/hooks/useSuspenseQuery.cjs +3 -3
- package/__cjs/react/hooks/useSuspenseQuery.cjs.map +1 -1
- package/__cjs/react/hooks/useSuspenseQuery.d.cts +799 -399
- package/__cjs/react/internal/cache/getSuspenseCache.cjs.map +1 -1
- package/__cjs/react/internal/cache/getSuspenseCache.d.cts +7 -0
- package/__cjs/utilities/internal/LazyType.cjs +3 -0
- package/__cjs/utilities/internal/LazyType.cjs.map +1 -0
- package/__cjs/utilities/internal/LazyType.d.cts +10 -0
- package/__cjs/utilities/internal/index.cjs.map +1 -1
- package/__cjs/utilities/internal/index.d.cts +3 -0
- package/__cjs/utilities/internal/types/OptionWithFallback.cjs +3 -0
- package/__cjs/utilities/internal/types/OptionWithFallback.cjs.map +1 -0
- package/__cjs/utilities/internal/types/OptionWithFallback.d.cts +5 -0
- package/__cjs/utilities/internal/types/SignatureStyle.cjs +3 -0
- package/__cjs/utilities/internal/types/SignatureStyle.cjs.map +1 -0
- package/__cjs/utilities/internal/types/SignatureStyle.d.cts +24 -0
- package/__cjs/version.cjs +1 -1
- package/core/ApolloClient.d.ts +305 -146
- package/core/ApolloClient.js +25 -12
- package/core/ApolloClient.js.map +1 -1
- package/core/QueryManager.js.map +1 -1
- package/core/defaultOptions.d.ts +90 -0
- package/core/defaultOptions.js +2 -0
- package/core/defaultOptions.js.map +1 -0
- package/core/index.d.ts +2 -1
- package/core/index.js.map +1 -1
- package/link/ws/index.d.ts +1 -1
- package/link/ws/index.js +9 -1
- package/link/ws/index.js.map +1 -1
- package/package.json +3 -7
- package/react/hooks/useBackgroundQuery.d.ts +1598 -765
- package/react/hooks/useBackgroundQuery.js +2 -2
- package/react/hooks/useBackgroundQuery.js.map +1 -1
- package/react/hooks/useLazyQuery.d.ts +369 -115
- package/react/hooks/useLazyQuery.js +2 -4
- package/react/hooks/useLazyQuery.js.map +1 -1
- package/react/hooks/useLoadableQuery.d.ts +507 -192
- package/react/hooks/useLoadableQuery.js +7 -3
- package/react/hooks/useLoadableQuery.js.map +1 -1
- package/react/hooks/useMutation.d.ts +239 -130
- package/react/hooks/useMutation.js +5 -48
- package/react/hooks/useMutation.js.map +1 -1
- package/react/hooks/useQuery.d.ts +636 -276
- package/react/hooks/useQuery.js +2 -2
- package/react/hooks/useQuery.js.map +1 -1
- package/react/hooks/useSubscription.d.ts +2 -2
- package/react/hooks/useSubscription.js +1 -1
- package/react/hooks/useSubscription.js.map +1 -1
- package/react/hooks/useSuspenseQuery.d.ts +799 -399
- package/react/hooks/useSuspenseQuery.js +2 -2
- package/react/hooks/useSuspenseQuery.js.map +1 -1
- package/react/hooks-compiled/useBackgroundQuery.d.ts +1598 -765
- package/react/hooks-compiled/useBackgroundQuery.js +2 -2
- package/react/hooks-compiled/useBackgroundQuery.js.map +1 -1
- package/react/hooks-compiled/useLazyQuery.d.ts +369 -115
- package/react/hooks-compiled/useLazyQuery.js +2 -4
- package/react/hooks-compiled/useLazyQuery.js.map +1 -1
- package/react/hooks-compiled/useLoadableQuery.d.ts +507 -192
- package/react/hooks-compiled/useLoadableQuery.js +2 -2
- package/react/hooks-compiled/useLoadableQuery.js.map +1 -1
- package/react/hooks-compiled/useMutation.d.ts +239 -130
- package/react/hooks-compiled/useMutation.js +4 -47
- package/react/hooks-compiled/useMutation.js.map +1 -1
- package/react/hooks-compiled/useQuery.d.ts +636 -276
- package/react/hooks-compiled/useQuery.js +2 -2
- package/react/hooks-compiled/useQuery.js.map +1 -1
- package/react/hooks-compiled/useSubscription.d.ts +2 -2
- package/react/hooks-compiled/useSubscription.js +1 -1
- package/react/hooks-compiled/useSubscription.js.map +1 -1
- package/react/hooks-compiled/useSuspenseQuery.d.ts +799 -399
- package/react/hooks-compiled/useSuspenseQuery.js +2 -2
- package/react/hooks-compiled/useSuspenseQuery.js.map +1 -1
- package/react/internal/cache/getSuspenseCache.d.ts +7 -0
- package/react/internal/cache/getSuspenseCache.js.map +1 -1
- package/skills/apollo-client/SKILL.md +168 -0
- package/skills/apollo-client/references/caching.md +560 -0
- package/skills/apollo-client/references/error-handling.md +350 -0
- package/skills/apollo-client/references/fragments.md +804 -0
- package/skills/apollo-client/references/integration-client.md +336 -0
- package/skills/apollo-client/references/integration-nextjs.md +325 -0
- package/skills/apollo-client/references/integration-react-router.md +256 -0
- package/skills/apollo-client/references/integration-tanstack-start.md +378 -0
- package/skills/apollo-client/references/mutations.md +549 -0
- package/skills/apollo-client/references/queries.md +416 -0
- package/skills/apollo-client/references/state-management.md +428 -0
- package/skills/apollo-client/references/suspense-hooks.md +773 -0
- package/skills/apollo-client/references/troubleshooting.md +487 -0
- package/skills/apollo-client/references/typescript-codegen.md +133 -0
- package/utilities/internal/LazyType.d.ts +10 -0
- package/utilities/internal/LazyType.js +2 -0
- package/utilities/internal/LazyType.js.map +1 -0
- package/utilities/internal/index.d.ts +3 -0
- package/utilities/internal/index.js.map +1 -1
- package/utilities/internal/types/OptionWithFallback.d.ts +5 -0
- package/utilities/internal/types/OptionWithFallback.js +2 -0
- package/utilities/internal/types/OptionWithFallback.js.map +1 -0
- package/utilities/internal/types/SignatureStyle.d.ts +24 -0
- package/utilities/internal/types/SignatureStyle.js +2 -0
- package/utilities/internal/types/SignatureStyle.js.map +1 -0
- package/version.js +1 -1
|
@@ -0,0 +1,487 @@
|
|
|
1
|
+
# Troubleshooting Reference
|
|
2
|
+
|
|
3
|
+
## Table of Contents
|
|
4
|
+
|
|
5
|
+
- [Setup Issues](#setup-issues)
|
|
6
|
+
- [Cache Issues](#cache-issues)
|
|
7
|
+
- [TypeScript Issues](#typescript-issues)
|
|
8
|
+
- [Performance Issues](#performance-issues)
|
|
9
|
+
- [DevTools Usage](#devtools-usage)
|
|
10
|
+
- [Common Error Messages](#common-error-messages)
|
|
11
|
+
|
|
12
|
+
## Setup Issues
|
|
13
|
+
|
|
14
|
+
### Provider Not Found
|
|
15
|
+
|
|
16
|
+
**Error:** `Could not find "client" in the context or passed in as an option`
|
|
17
|
+
|
|
18
|
+
**Cause:** Component is not wrapped with `ApolloProvider`.
|
|
19
|
+
|
|
20
|
+
**Solution:**
|
|
21
|
+
|
|
22
|
+
```tsx
|
|
23
|
+
// Ensure ApolloProvider wraps your app
|
|
24
|
+
import { ApolloProvider } from "@apollo/client";
|
|
25
|
+
|
|
26
|
+
function App() {
|
|
27
|
+
return (
|
|
28
|
+
<ApolloProvider client={client}>
|
|
29
|
+
<YourApp />
|
|
30
|
+
</ApolloProvider>
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Multiple Apollo Clients
|
|
36
|
+
|
|
37
|
+
**Problem:** Unintended cache isolation or conflicting states.
|
|
38
|
+
|
|
39
|
+
**Solution:** Use a single client instance or explicitly manage multiple clients:
|
|
40
|
+
|
|
41
|
+
```tsx
|
|
42
|
+
// Single client (recommended)
|
|
43
|
+
const client = new ApolloClient({
|
|
44
|
+
/* ... */
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
export function App() {
|
|
48
|
+
return (
|
|
49
|
+
<ApolloProvider client={client}>
|
|
50
|
+
<Router />
|
|
51
|
+
</ApolloProvider>
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Multiple clients (rare use case)
|
|
56
|
+
const publicClient = new ApolloClient({
|
|
57
|
+
uri: "/public/graphql",
|
|
58
|
+
cache: new InMemoryCache(),
|
|
59
|
+
});
|
|
60
|
+
const adminClient = new ApolloClient({
|
|
61
|
+
uri: "/admin/graphql",
|
|
62
|
+
cache: new InMemoryCache(),
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
function AdminSection() {
|
|
66
|
+
return (
|
|
67
|
+
<ApolloProvider client={adminClient}>
|
|
68
|
+
<AdminDashboard />
|
|
69
|
+
</ApolloProvider>
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Client Created in Component
|
|
75
|
+
|
|
76
|
+
**Problem:** New client on every render causes cache loss.
|
|
77
|
+
|
|
78
|
+
**Solution:** Create client outside component or use a ref pattern:
|
|
79
|
+
|
|
80
|
+
```tsx
|
|
81
|
+
// Bad - new client on every render
|
|
82
|
+
function App() {
|
|
83
|
+
const client = new ApolloClient({
|
|
84
|
+
/* ... */
|
|
85
|
+
}); // Don't do this!
|
|
86
|
+
return <ApolloProvider client={client}>...</ApolloProvider>;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Module-level client definition
|
|
90
|
+
// Okay if there is a 100% guarantee this application will never use SSR
|
|
91
|
+
const client = new ApolloClient({
|
|
92
|
+
/* ... */
|
|
93
|
+
});
|
|
94
|
+
function App() {
|
|
95
|
+
return <ApolloProvider client={client}>...</ApolloProvider>;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Good - store Apollo Client in a ref that is initialized once
|
|
99
|
+
function useApolloClient(makeApolloClient: () => ApolloClient): ApolloClient {
|
|
100
|
+
const storeRef = useRef<ApolloClient | null>(null);
|
|
101
|
+
if (!storeRef.current) {
|
|
102
|
+
storeRef.current = makeApolloClient();
|
|
103
|
+
}
|
|
104
|
+
return storeRef.current;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Better - singleton global in non-SSR environments to survive unmounts
|
|
108
|
+
const singleton = Symbol.for("ApolloClientSingleton");
|
|
109
|
+
declare global {
|
|
110
|
+
interface Window {
|
|
111
|
+
[singleton]?: ApolloClient;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function useApolloClient(makeApolloClient: () => ApolloClient): ApolloClient {
|
|
116
|
+
const storeRef = useRef<ApolloClient | null>(null);
|
|
117
|
+
if (!storeRef.current) {
|
|
118
|
+
if (typeof window === "undefined") {
|
|
119
|
+
storeRef.current = makeApolloClient();
|
|
120
|
+
} else {
|
|
121
|
+
window[singleton] ??= makeApolloClient();
|
|
122
|
+
storeRef.current = window[singleton];
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return storeRef.current;
|
|
126
|
+
}
|
|
127
|
+
// Note: this second option might need manual removal between tests
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## Cache Issues
|
|
131
|
+
|
|
132
|
+
### Stale Data Not Updating
|
|
133
|
+
|
|
134
|
+
**Problem:** UI doesn't reflect mutations or other updates.
|
|
135
|
+
|
|
136
|
+
**Solution 1:** Verify cache key identification:
|
|
137
|
+
|
|
138
|
+
```typescript
|
|
139
|
+
const cache = new InMemoryCache({
|
|
140
|
+
typePolicies: {
|
|
141
|
+
// Ensure proper identification
|
|
142
|
+
Product: {
|
|
143
|
+
keyFields: ["id"], // or ['sku'] if no id field
|
|
144
|
+
},
|
|
145
|
+
},
|
|
146
|
+
});
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
**Solution 2:** Update cache after mutations:
|
|
150
|
+
|
|
151
|
+
```tsx
|
|
152
|
+
const [deleteProduct] = useMutation(DELETE_PRODUCT, {
|
|
153
|
+
update: (cache, { data }) => {
|
|
154
|
+
cache.evict({ id: cache.identify(data.deleteProduct) });
|
|
155
|
+
cache.gc();
|
|
156
|
+
},
|
|
157
|
+
});
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
**Solution 3:** Use appropriate fetch policy:
|
|
161
|
+
|
|
162
|
+
```tsx
|
|
163
|
+
const { data } = useQuery(GET_PRODUCTS, {
|
|
164
|
+
fetchPolicy: "cache-and-network", // Always fetch fresh data
|
|
165
|
+
});
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### Missing Cache Updates After Mutation
|
|
169
|
+
|
|
170
|
+
**Problem:** New items don't appear in lists after creation.
|
|
171
|
+
|
|
172
|
+
**Solution:** Manually update the cache:
|
|
173
|
+
|
|
174
|
+
```tsx
|
|
175
|
+
const [createProduct] = useMutation(CREATE_PRODUCT, {
|
|
176
|
+
update: (cache, { data }) => {
|
|
177
|
+
const existing = cache.readQuery<{ products: Product[] }>({
|
|
178
|
+
query: GET_PRODUCTS,
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
cache.writeQuery({
|
|
182
|
+
query: GET_PRODUCTS,
|
|
183
|
+
data: {
|
|
184
|
+
products: [...(existing?.products ?? []), data.createProduct],
|
|
185
|
+
},
|
|
186
|
+
});
|
|
187
|
+
},
|
|
188
|
+
});
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### Pagination Cache Issues
|
|
192
|
+
|
|
193
|
+
**Problem:** Paginated data not merging correctly.
|
|
194
|
+
|
|
195
|
+
**Solution:** Configure proper type policies:
|
|
196
|
+
|
|
197
|
+
```typescript
|
|
198
|
+
const cache = new InMemoryCache({
|
|
199
|
+
typePolicies: {
|
|
200
|
+
Query: {
|
|
201
|
+
fields: {
|
|
202
|
+
products: {
|
|
203
|
+
keyArgs: ["category"], // Only category creates new cache entries
|
|
204
|
+
merge(existing = [], incoming) {
|
|
205
|
+
return [...existing, ...incoming];
|
|
206
|
+
},
|
|
207
|
+
},
|
|
208
|
+
},
|
|
209
|
+
},
|
|
210
|
+
},
|
|
211
|
+
});
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### Cache Normalization Problems
|
|
215
|
+
|
|
216
|
+
**Problem:** Objects with same ID showing different data in different queries.
|
|
217
|
+
|
|
218
|
+
**Debug:** Check cache contents:
|
|
219
|
+
|
|
220
|
+
```typescript
|
|
221
|
+
// In DevTools console or component
|
|
222
|
+
console.log(client.cache.extract());
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
**Solution:** Ensure consistent `__typename` and `id` fields:
|
|
226
|
+
|
|
227
|
+
```graphql
|
|
228
|
+
query GetUsers {
|
|
229
|
+
users {
|
|
230
|
+
id # Always include id
|
|
231
|
+
name
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
## TypeScript Issues
|
|
237
|
+
|
|
238
|
+
### Type Generation Setup
|
|
239
|
+
|
|
240
|
+
**Problem:** No type safety for GraphQL operations.
|
|
241
|
+
|
|
242
|
+
**Solution:** Set up GraphQL Code Generator with the [recommended starter configuration](https://www.apollographql.com/docs/react/development-testing/graphql-codegen#recommended-starter-configuration), as described in the [Skill](../SKILL.md).
|
|
243
|
+
|
|
244
|
+
### Using Generated Types
|
|
245
|
+
|
|
246
|
+
```tsx
|
|
247
|
+
import { useQuery } from "@apollo/client/react";
|
|
248
|
+
import { GetUsersDocument, GetUsersQuery } from "./generated/graphql";
|
|
249
|
+
|
|
250
|
+
function UserList() {
|
|
251
|
+
// Fully typed without manual type annotations
|
|
252
|
+
const { data, loading, error } = useQuery(GetUsersDocument);
|
|
253
|
+
|
|
254
|
+
// data.users is automatically typed as GetUsersQuery['users']
|
|
255
|
+
return (
|
|
256
|
+
<ul>{data?.users.map((user) => <li key={user.id}>{user.name}</li>)}</ul>
|
|
257
|
+
);
|
|
258
|
+
}
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
## Performance Issues
|
|
262
|
+
|
|
263
|
+
### Over-Fetching
|
|
264
|
+
|
|
265
|
+
**Problem:** Fetching more data than needed.
|
|
266
|
+
|
|
267
|
+
**Solution:** Select only required fields:
|
|
268
|
+
|
|
269
|
+
```graphql
|
|
270
|
+
# Bad - fetching everything
|
|
271
|
+
query GetUsers {
|
|
272
|
+
users {
|
|
273
|
+
id
|
|
274
|
+
name
|
|
275
|
+
email
|
|
276
|
+
profile { ... }
|
|
277
|
+
posts { ... }
|
|
278
|
+
friends { ... }
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
# Good - fetch what's needed
|
|
283
|
+
query GetUserNames {
|
|
284
|
+
users {
|
|
285
|
+
id
|
|
286
|
+
name
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
### N+1 Queries
|
|
292
|
+
|
|
293
|
+
**Problem:** Multiple network requests for related data.
|
|
294
|
+
|
|
295
|
+
**Solution:** Structure queries to batch requests. Best practice: use query colocation and compose queries from fragments defined on child components.
|
|
296
|
+
|
|
297
|
+
```graphql
|
|
298
|
+
# Bad - separate queries
|
|
299
|
+
query GetUser($id: ID!) {
|
|
300
|
+
user(id: $id) {
|
|
301
|
+
id
|
|
302
|
+
name
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
query GetUserPosts($userId: ID!) {
|
|
306
|
+
posts(userId: $userId) {
|
|
307
|
+
id
|
|
308
|
+
title
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
# Good - single query
|
|
313
|
+
query GetUserWithPosts($id: ID!) {
|
|
314
|
+
user(id: $id) {
|
|
315
|
+
id
|
|
316
|
+
name
|
|
317
|
+
posts {
|
|
318
|
+
id
|
|
319
|
+
title
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
### Unnecessary Re-Renders
|
|
326
|
+
|
|
327
|
+
**Problem:** Components re-render when unrelated cache data changes.
|
|
328
|
+
|
|
329
|
+
**Solution:** Use `useFragment` and data masking for selective field reading. If that is not possible, `useQuery` with `@nonreactive` directives might be an alternative.
|
|
330
|
+
|
|
331
|
+
```tsx
|
|
332
|
+
// Prefer useFragment with data masking
|
|
333
|
+
const { data } = useFragment({
|
|
334
|
+
fragment: USER_FRAGMENT,
|
|
335
|
+
from: { __typename: "User", id },
|
|
336
|
+
});
|
|
337
|
+
|
|
338
|
+
// Alternative: use @nonreactive directive
|
|
339
|
+
const GET_USER = gql`
|
|
340
|
+
query GetUser($id: ID!) {
|
|
341
|
+
user(id: $id) {
|
|
342
|
+
id
|
|
343
|
+
name
|
|
344
|
+
# This field won't trigger re-renders when it changes
|
|
345
|
+
metadata @nonreactive {
|
|
346
|
+
lastSeen
|
|
347
|
+
preferences
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
`;
|
|
352
|
+
|
|
353
|
+
const { data } = useQuery(GET_USER, {
|
|
354
|
+
variables: { id },
|
|
355
|
+
});
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
### Cache Misses
|
|
359
|
+
|
|
360
|
+
**Debug:** Use Apollo DevTools to inspect cache.
|
|
361
|
+
|
|
362
|
+
```typescript
|
|
363
|
+
const client = new ApolloClient({
|
|
364
|
+
cache: new InMemoryCache(),
|
|
365
|
+
// DevTools are enabled by default in development
|
|
366
|
+
// Only configure this when you need to enable them in production
|
|
367
|
+
devtools: {
|
|
368
|
+
enabled: true,
|
|
369
|
+
},
|
|
370
|
+
});
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
## DevTools Usage
|
|
374
|
+
|
|
375
|
+
### Installing Apollo DevTools
|
|
376
|
+
|
|
377
|
+
Install the browser extension:
|
|
378
|
+
|
|
379
|
+
- [Chrome](https://chrome.google.com/webstore/detail/apollo-client-devtools/jdkknkkbebbapilgoeccciglkfbmbnfm)
|
|
380
|
+
- [Firefox](https://addons.mozilla.org/en-US/firefox/addon/apollo-developer-tools/)
|
|
381
|
+
|
|
382
|
+
### Enabling DevTools
|
|
383
|
+
|
|
384
|
+
DevTools are enabled by default in development. Only configure this setting if you need to enable them in production:
|
|
385
|
+
|
|
386
|
+
```typescript
|
|
387
|
+
const client = new ApolloClient({
|
|
388
|
+
cache: new InMemoryCache(),
|
|
389
|
+
devtools: {
|
|
390
|
+
enabled: true, // Set to true to enable in production
|
|
391
|
+
},
|
|
392
|
+
});
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
### DevTools Features
|
|
396
|
+
|
|
397
|
+
1. **Cache Inspector**: View normalized cache contents
|
|
398
|
+
2. **Queries**: See active queries and their states
|
|
399
|
+
3. **Mutations**: Track mutation history
|
|
400
|
+
4. **Explorer**: Build and test queries against your schema
|
|
401
|
+
5. **Memoization Limits**: Monitor and track cache memoization
|
|
402
|
+
6. **Cache Writes**: Track all writes to the cache
|
|
403
|
+
|
|
404
|
+
### Debugging Cache
|
|
405
|
+
|
|
406
|
+
```typescript
|
|
407
|
+
// Log cache contents
|
|
408
|
+
console.log(JSON.stringify(client.cache.extract(), null, 2));
|
|
409
|
+
|
|
410
|
+
// Check specific object using cache.identify
|
|
411
|
+
console.log(
|
|
412
|
+
client.cache.readFragment({
|
|
413
|
+
id: cache.identify({ __typename: "User", id: 1 }),
|
|
414
|
+
fragment: gql`
|
|
415
|
+
fragment _ on User {
|
|
416
|
+
id
|
|
417
|
+
name
|
|
418
|
+
email
|
|
419
|
+
}
|
|
420
|
+
`,
|
|
421
|
+
})
|
|
422
|
+
);
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
## Common Error Messages
|
|
426
|
+
|
|
427
|
+
### "Missing field 'X' in {...}"
|
|
428
|
+
|
|
429
|
+
**Cause:** Query doesn't include required field for cache normalization.
|
|
430
|
+
|
|
431
|
+
**Solution:** Include `id` and `__typename`:
|
|
432
|
+
|
|
433
|
+
```graphql
|
|
434
|
+
query GetUsers {
|
|
435
|
+
users {
|
|
436
|
+
id # Required for caching
|
|
437
|
+
__typename # Usually added automatically
|
|
438
|
+
name
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
**Additional advice**: Read the full error message thoroughly.
|
|
444
|
+
|
|
445
|
+
### "Store reset while query was in flight"
|
|
446
|
+
|
|
447
|
+
**Cause:** `client.resetStore()` called during active queries.
|
|
448
|
+
|
|
449
|
+
**Solution:** Wait for queries to complete or use `clearStore()`:
|
|
450
|
+
|
|
451
|
+
```typescript
|
|
452
|
+
// Option 1: Clear without refetching
|
|
453
|
+
await client.clearStore();
|
|
454
|
+
|
|
455
|
+
// Option 2: Reset and refetch active queries
|
|
456
|
+
await client.resetStore();
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
### "Invariant Violation: X"
|
|
460
|
+
|
|
461
|
+
**Cause:** Various configuration or usage errors.
|
|
462
|
+
|
|
463
|
+
**Common fixes:**
|
|
464
|
+
|
|
465
|
+
- Ensure `ApolloProvider` wraps the component tree
|
|
466
|
+
- Check that `gql` tagged templates are valid GraphQL
|
|
467
|
+
- Verify cache configuration matches your schema
|
|
468
|
+
|
|
469
|
+
### "Cannot read property 'X' of undefined"
|
|
470
|
+
|
|
471
|
+
**Cause:** Accessing data before query completes.
|
|
472
|
+
|
|
473
|
+
**Solution:** Check `dataState` for proper type narrowing:
|
|
474
|
+
|
|
475
|
+
```tsx
|
|
476
|
+
const { data, dataState } = useQuery(GET_USER);
|
|
477
|
+
|
|
478
|
+
// dataState can be "complete", "partial", "streaming", or "empty"
|
|
479
|
+
// It describes the completeness of the data, not a loading state
|
|
480
|
+
if (dataState === "empty") return <Spinner />;
|
|
481
|
+
|
|
482
|
+
// Now data is guaranteed to exist
|
|
483
|
+
return <div>{data.user.name}</div>;
|
|
484
|
+
|
|
485
|
+
// Or use optional chaining
|
|
486
|
+
return <div>{data?.user?.name}</div>;
|
|
487
|
+
```
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
# TypeScript Code Generation
|
|
2
|
+
|
|
3
|
+
This guide covers setting up GraphQL Code Generator for type-safe Apollo Client usage with TypeScript.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -D @graphql-codegen/cli @graphql-codegen/typescript @graphql-codegen/typescript-operations @graphql-codegen/typed-document-node
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Configuration
|
|
12
|
+
|
|
13
|
+
Create a `codegen.ts` file in your project root:
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
// codegen.ts
|
|
17
|
+
import { CodegenConfig } from "@graphql-codegen/cli";
|
|
18
|
+
|
|
19
|
+
const config: CodegenConfig = {
|
|
20
|
+
overwrite: true,
|
|
21
|
+
schema: "<URL_OF_YOUR_GRAPHQL_API>",
|
|
22
|
+
// This assumes that all your source files are in a top-level `src/` directory - you might need to adjust this to your file structure
|
|
23
|
+
documents: ["src/**/*.{ts,tsx}"],
|
|
24
|
+
// Don't exit with non-zero status when there are no documents
|
|
25
|
+
ignoreNoDocuments: true,
|
|
26
|
+
generates: {
|
|
27
|
+
// Use a path that works the best for the structure of your application
|
|
28
|
+
"./src/types/__generated__/graphql.ts": {
|
|
29
|
+
plugins: ["typescript", "typescript-operations", "typed-document-node"],
|
|
30
|
+
config: {
|
|
31
|
+
avoidOptionals: {
|
|
32
|
+
// Use `null` for nullable fields instead of optionals
|
|
33
|
+
field: true,
|
|
34
|
+
// Allow nullable input fields to remain unspecified
|
|
35
|
+
inputValue: false,
|
|
36
|
+
},
|
|
37
|
+
// Use `unknown` instead of `any` for unconfigured scalars
|
|
38
|
+
defaultScalarType: "unknown",
|
|
39
|
+
// Apollo Client always includes `__typename` fields
|
|
40
|
+
nonOptionalTypename: true,
|
|
41
|
+
// Apollo Client doesn't add the `__typename` field to root types so
|
|
42
|
+
// don't generate a type for the `__typename` for root operation types.
|
|
43
|
+
skipTypeNameForRoot: true,
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export default config;
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Enable Data Masking
|
|
53
|
+
|
|
54
|
+
To enable data masking with GraphQL Code Generator, create a type declaration file to inform Apollo Client about the generated types:
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
// apollo-client.d.ts
|
|
58
|
+
import { GraphQLCodegenDataMasking } from "@apollo/client/masking";
|
|
59
|
+
|
|
60
|
+
declare module "@apollo/client" {
|
|
61
|
+
export interface TypeOverrides
|
|
62
|
+
extends GraphQLCodegenDataMasking.TypeOverrides {}
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Running Code Generation
|
|
67
|
+
|
|
68
|
+
Add a script to your `package.json`:
|
|
69
|
+
|
|
70
|
+
```json
|
|
71
|
+
{
|
|
72
|
+
"scripts": {
|
|
73
|
+
"codegen": "graphql-codegen"
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Run code generation:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
npm run codegen
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Usage with Apollo Client
|
|
85
|
+
|
|
86
|
+
The typed-document-node plugin generates `TypedDocumentNode` types that Apollo Client hooks automatically infer.
|
|
87
|
+
|
|
88
|
+
### Defining Operations
|
|
89
|
+
|
|
90
|
+
Define your operations inline with the `if (false)` pattern. This allows GraphQL Code Generator to detect and extract operations without executing the code at runtime (bundlers omit this dead code during minification):
|
|
91
|
+
|
|
92
|
+
```typescript
|
|
93
|
+
import { gql } from "@apollo/client";
|
|
94
|
+
|
|
95
|
+
// This query will never be consumed in runtime code, so it is wrapped in `if (false)` so the bundler can omit it when bundling.
|
|
96
|
+
if (false) {
|
|
97
|
+
gql`
|
|
98
|
+
query GetUser($id: ID!) {
|
|
99
|
+
user(id: $id) {
|
|
100
|
+
id
|
|
101
|
+
name
|
|
102
|
+
email
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
`;
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Using Generated Types
|
|
110
|
+
|
|
111
|
+
After running `npm run codegen`, import the generated `TypedDocumentNode`:
|
|
112
|
+
|
|
113
|
+
```typescript
|
|
114
|
+
import { useQuery } from "@apollo/client/react";
|
|
115
|
+
import { GetUserDocument } from "./queries.generated";
|
|
116
|
+
|
|
117
|
+
function UserProfile({ userId }: { userId: string }) {
|
|
118
|
+
// Types are automatically inferred from GetUserDocument
|
|
119
|
+
const { data } = useQuery(GetUserDocument, {
|
|
120
|
+
variables: { id: userId },
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
// ... other logic ...
|
|
124
|
+
|
|
125
|
+
return <div>{data?.user.name}</div>;
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## Important Notes
|
|
130
|
+
|
|
131
|
+
- The typed-document-node plugin might have a bundle size tradeoff but can prevent inconsistencies and is best suited for usage with LLMs, so it is recommended for most applications.
|
|
132
|
+
- See the [GraphQL Code Generator documentation](https://www.apollographql.com/docs/react/development-testing/graphql-codegen#recommended-starter-configuration) for other recommended configuration patterns if required.
|
|
133
|
+
- Apollo Client hooks automatically infer types from `TypedDocumentNode` - never use manual generics like `useQuery<QueryType, VariablesType>()`.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This circular type (that never actually gets evaluated) is needed to prevent
|
|
3
|
+
* TypeScript from eagerly inlining the `ApolloClient.QueryResultForOptions`
|
|
4
|
+
* type, which would cause problems with global types getting evaluated
|
|
5
|
+
* on build of userland wrapping libraries, and not in the final userland project.
|
|
6
|
+
*/
|
|
7
|
+
export type LazyType<T> = T & {
|
|
8
|
+
[K in "" as never]: LazyType<never>;
|
|
9
|
+
};
|
|
10
|
+
//# sourceMappingURL=LazyType.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LazyType.js","sourceRoot":"","sources":["../../../src/utilities/internal/LazyType.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * This circular type (that never actually gets evaluated) is needed to prevent\n * TypeScript from eagerly inlining the `ApolloClient.QueryResultForOptions`\n * type, which would cause problems with global types getting evaluated\n * on build of userland wrapping libraries, and not in the final userland project.\n */\nexport type LazyType<T> = T & { [K in \"\" as never]: LazyType<never> };\n"]}
|
|
@@ -14,6 +14,9 @@ export type { RemoveIndexSignature } from "./types/RemoveIndexSignature.js";
|
|
|
14
14
|
export type { StreamInfoTrie } from "./types/StreamInfoTrie.js";
|
|
15
15
|
export type { VariablesOption } from "./types/VariablesOption.js";
|
|
16
16
|
export type { DocumentationTypes } from "./types/DocumentationTypes.js";
|
|
17
|
+
export type { LazyType } from "./LazyType.js";
|
|
18
|
+
export type { ClassicSignature, SignatureStyle, } from "./types/SignatureStyle.js";
|
|
19
|
+
export type { OptionWithFallback } from "./types/OptionWithFallback.js";
|
|
17
20
|
export { argumentsObjectFromField } from "./argumentsObjectFromField.js";
|
|
18
21
|
export { canUseDOM } from "./canUseDOM.js";
|
|
19
22
|
export { checkDocument } from "./checkDocument.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/utilities/internal/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/utilities/internal/index.ts"],"names":[],"mappings":"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","sourcesContent":["export type { DecoratedPromise } from \"./types/DecoratedPromise.js\";\nexport type { DeepOmit } from \"./types/DeepOmit.js\";\nexport type { ExtensionsWithStreamInfo } from \"./types/ExtensionsWithStreamDetails.js\";\nexport type { FragmentMap } from \"./types/FragmentMap.js\";\nexport type { FragmentMapFunction } from \"./types/FragmentMapFunction.js\";\nexport type { FulfilledPromise } from \"./types/FulfilledPromise.js\";\nexport type { IsAny } from \"./types/IsAny.js\";\nexport type { NoInfer } from \"./types/NoInfer.js\";\nexport type { PendingPromise } from \"./types/PendingPromise.js\";\nexport type { Prettify } from \"./types/Prettify.js\";\nexport type { Primitive } from \"./types/Primitive.js\";\nexport type { RejectedPromise } from \"./types/RejectedPromise.js\";\nexport type { RemoveIndexSignature } from \"./types/RemoveIndexSignature.js\";\nexport type { StreamInfoTrie } from \"./types/StreamInfoTrie.js\";\nexport type { VariablesOption } from \"./types/VariablesOption.js\";\nexport type { DocumentationTypes } from \"./types/DocumentationTypes.js\";\nexport type { LazyType } from \"./LazyType.js\";\nexport type {\n ClassicSignature,\n SignatureStyle,\n} from \"./types/SignatureStyle.js\";\nexport type { OptionWithFallback } from \"./types/OptionWithFallback.js\";\n\nexport { argumentsObjectFromField } from \"./argumentsObjectFromField.js\";\nexport { canUseDOM } from \"./canUseDOM.js\";\nexport { checkDocument } from \"./checkDocument.js\";\nexport { cloneDeep } from \"./cloneDeep.js\";\nexport { combineLatestBatched } from \"./combineLatestBatched.js\";\nexport { compact } from \"./compact.js\";\nexport { createFragmentMap } from \"./createFragmentMap.js\";\nexport { createFulfilledPromise } from \"./createFulfilledPromise.js\";\nexport { createRejectedPromise } from \"./createRejectedPromise.js\";\nexport { dealias } from \"./dealias.js\";\nexport { decoratePromise } from \"./decoratePromise.js\";\nexport { DeepMerger } from \"./DeepMerger.js\";\nexport { getDefaultValues } from \"./getDefaultValues.js\";\nexport { getFragmentFromSelection } from \"./getFragmentFromSelection.js\";\nexport { getFragmentQueryDocument } from \"./getFragmentQueryDocument.js\";\nexport { getFragmentDefinition } from \"./getFragmentDefinition.js\";\nexport { getFragmentDefinitions } from \"./getFragmentDefinitions.js\";\nexport { getGraphQLErrorsFromResult } from \"./getGraphQLErrorsFromResult.js\";\nexport { getMainDefinition } from \"./getMainDefinition.js\";\nexport { getOperationDefinition } from \"./getOperationDefinition.js\";\nexport { getOperationName } from \"./getOperationName.js\";\nexport { getQueryDefinition } from \"./getQueryDefinition.js\";\nexport { getStoreKeyName } from \"./getStoreKeyName.js\";\nexport { graphQLResultHasError } from \"./graphQLResultHasError.js\";\nexport { hasDirectives } from \"./hasDirectives.js\";\nexport { hasForcedResolvers } from \"./hasForcedResolvers.js\";\nexport { isArray } from \"./isArray.js\";\nexport { isDocumentNode } from \"./isDocumentNode.js\";\nexport { isField } from \"./isField.js\";\nexport { isNonEmptyArray } from \"./isNonEmptyArray.js\";\nexport { isNonNullObject } from \"./isNonNullObject.js\";\nexport { isPlainObject } from \"./isPlainObject.js\";\nexport { makeReference } from \"./makeReference.js\";\nexport { makeUniqueId } from \"./makeUniqueId.js\";\nexport { maybeDeepFreeze } from \"./maybeDeepFreeze.js\";\nexport { mergeDeep } from \"./mergeDeep.js\";\nexport { mergeDeepArray } from \"./mergeDeepArray.js\";\nexport { mergeOptions } from \"./mergeOptions.js\";\nexport { omitDeep } from \"./omitDeep.js\";\nexport { preventUnhandledRejection } from \"./preventUnhandledRejection.js\";\nexport { removeDirectivesFromDocument } from \"./removeDirectivesFromDocument.js\";\nexport { removeMaskedFragmentSpreads } from \"./removeFragmentSpreads.js\";\nexport { resultKeyNameFromField } from \"./resultKeyNameFromField.js\";\nexport { shouldInclude } from \"./shouldInclude.js\";\nexport { storeKeyNameFromField } from \"./storeKeyNameFromField.js\";\nexport { stringifyForDisplay } from \"./stringifyForDisplay.js\";\nexport { toQueryResult } from \"./toQueryResult.js\";\nexport { filterMap } from \"./filterMap.js\";\nexport { equalByQuery } from \"./equalByQuery.js\";\nexport { canonicalStringify } from \"./canonicalStringify.js\";\nexport { mapObservableFragmentMemoized } from \"./mapObservableFragment.js\";\nexport {\n extensionsSymbol,\n streamInfoSymbol,\n variablesUnknownSymbol,\n} from \"./constants.js\";\nexport { bindCacheKey } from \"./bindCacheKey.js\";\n\nexport {\n getApolloCacheMemoryInternals,\n getApolloClientMemoryInternals,\n getInMemoryCacheMemoryInternals,\n registerGlobalCache,\n} from \"../internal/getMemoryInternals.js\";\n\nexport { AutoCleanedStrongCache, AutoCleanedWeakCache } from \"./caches.js\";\n\nexport type { ApplyHKT } from \"./types/ApplyHKT.js\";\nexport type { ApplyHKTImplementationWithDefault } from \"./types/ApplyHKTImplementationWithDefault.js\";\n"]}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { RemoveIndexSignature } from "./RemoveIndexSignature.js";
|
|
2
|
+
type ReplaceUndefinedWithDefault<Value, Default> = Value extends any ? Value extends undefined ? Default : Value : never;
|
|
3
|
+
export type OptionWithFallback<Options, DefaultOptions, Key extends keyof DefaultOptions> = Key extends keyof RemoveIndexSignature<Options> ? ReplaceUndefinedWithDefault<Options[Key], DefaultOptions[Key]> : DefaultOptions[Key];
|
|
4
|
+
export {};
|
|
5
|
+
//# sourceMappingURL=OptionWithFallback.d.ts.map
|