@beignet/react-query 0.0.3 → 0.0.4
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 +33 -0
- package/README.md +175 -37
- package/dist/index.d.ts +108 -15
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +140 -9
- package/dist/index.js.map +1 -1
- package/package.json +4 -5
- package/src/index.ts +293 -44
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,38 @@
|
|
|
1
1
|
# @beignet/react-query
|
|
2
2
|
|
|
3
|
+
## 0.0.4
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 8bcb31f: Mark package READMEs with Beignet's experimental alpha status and 0.0.x stability expectations.
|
|
8
|
+
- df4673f: Add TanStack Query filter helpers for Beignet contract cache invalidation and update generated UI examples to use them.
|
|
9
|
+
- 8fd9cb3: Document React Query key scopes, invalidation recipes, pagination, filters, and optimistic update patterns.
|
|
10
|
+
- d137044: Declare `@beignet/core` as a peer dependency with a lockstep version range in
|
|
11
|
+
every integration and provider package instead of a regular `"*"` dependency.
|
|
12
|
+
Installs now always resolve a single shared copy of core, so `instanceof`
|
|
13
|
+
checks such as `isContractError` and upload error identity keep working, and
|
|
14
|
+
mixed Beignet versions fail loudly at install time instead of at runtime.
|
|
15
|
+
|
|
16
|
+
If your package manager does not install peer dependencies automatically, add
|
|
17
|
+
`@beignet/core` to your app alongside these packages. `@beignet/nuqs` now also
|
|
18
|
+
declares `@beignet/react-query` as a peer dependency, and
|
|
19
|
+
`@beignet/provider-storage-s3` now expects you to install
|
|
20
|
+
`@aws-sdk/client-s3` and `@aws-sdk/s3-request-presigner` yourself, matching
|
|
21
|
+
how other providers treat their SDKs.
|
|
22
|
+
|
|
23
|
+
- 1a79090: Emit Node-compatible ESM: all relative imports in published packages now carry explicit .js extensions, fixing ERR_MODULE_NOT_FOUND when running the CLI or importing package dist files under plain Node.
|
|
24
|
+
- 493d23b: Accept observer-level TanStack Query options (`enabled`, `staleTime`, `select`, `refetchInterval`, `placeholderData`, `throwOnError`) in `queryOptions(...)` and `mutationOptions(...)`. The options were already passed through at runtime but were rejected at the type level. `@beignet/nuqs` `toQueryOptions(...)` inherits the same fix.
|
|
25
|
+
- d6ad8bb: Standardize generated client helpers around `client/index.ts`, add a typed
|
|
26
|
+
React Query invalidation helper, and align package docs with the canonical app
|
|
27
|
+
client entrypoint.
|
|
28
|
+
- 8063d38: Rename the contract front door to `defineContract`/`defineContractGroup`, rename operational commands to tasks (`@beignet/core/tasks`, `defineTasks`, `runTask`, `beignet task run`, `beignet make task`, `server/tasks.ts`, `features/<feature>/tasks/`, `paths.tasks`), and standardize context binding: context-free declarations stay top-level (`defineEvent`), while context-bound definitions come from per-capability factories (`createListeners`, `createJobs`, `createSchedules`, `createNotifications`, `createTasks`) called once in `lib/`. Top-level context-generic `defineListener`, `defineJob`, `defineSchedule`, and `defineNotification` are removed.
|
|
29
|
+
- 192c6ad: Typed clients now attach idempotency keys automatically from contract metadata (override with `idempotencyKey`), React Query mutations keep the key stable across retry attempts, and the shared client error helpers `contractErrorMessage` and `rootFormError` are now exported by @beignet/core/client and @beignet/react-hook-form.
|
|
30
|
+
- 89390fe: Add a contract route segment to generated query keys, an adapter-level `keyHeaders` opt-in, and body pagination for infinite queries.
|
|
31
|
+
|
|
32
|
+
- Query keys now include the contract route after the local name: `["beignet", namespace | null, localName, "GET /v1/todos", params?]`. Two un-namespaced contract groups with different prefixes but the same derived local name (for example `GET /v1/todos` and `GET /v2/todos`) no longer share a cache key. This changes every generated query key, so persisted caches and any hand-written keys that mirrored the old `["beignet", namespace, localName, params?]` shape are invalidated after upgrading.
|
|
33
|
+
- `createReactQuery(client, { keyHeaders })` opts specific header names into generated query keys as a normalized lowercased `headers` key component. Headers stay excluded from keys by default so persisted caches never store credentials such as `Authorization` tokens.
|
|
34
|
+
- `infiniteQueryOptions(...)` accepts a static `body` merged with `page(...).body` per page, includes the static body in the derived key, and sends the merged body on each page request, so body-paginated POST search/list contracts work without a custom `key`/`params` escape hatch.
|
|
35
|
+
|
|
3
36
|
## 0.0.3
|
|
4
37
|
|
|
5
38
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
> TanStack Query integration for Beignet
|
|
4
4
|
|
|
5
|
+
> [!CAUTION]
|
|
6
|
+
> Beignet is experimental alpha software. The `0.0.x` package line is for early
|
|
7
|
+
> evaluation, and APIs may change between releases while the framework settles.
|
|
8
|
+
|
|
5
9
|
This package provides **options-first** TanStack Query integration that's automatically typed based on your contracts. Generate `queryOptions`, `mutationOptions`, and `infiniteQueryOptions` that work with all TanStack Query primitives (`useQuery`, `useMutation`, `useInfiniteQuery`, `prefetchQuery`, `fetchQuery`, etc.) with full type inference.
|
|
6
10
|
|
|
7
11
|
## Installation
|
|
@@ -17,11 +21,12 @@ This package requires TypeScript 5.0 or higher for proper type inference.
|
|
|
17
21
|
|
|
18
22
|
## Setup
|
|
19
23
|
|
|
20
|
-
### 1. Create your client
|
|
24
|
+
### 1. Create your app client helpers
|
|
21
25
|
|
|
22
26
|
```ts
|
|
23
|
-
// lib/api-client.ts
|
|
24
27
|
import { createClient } from "@beignet/core/client";
|
|
28
|
+
import { createReactQuery } from "@beignet/react-query";
|
|
29
|
+
import { QueryClient } from "@tanstack/react-query";
|
|
25
30
|
|
|
26
31
|
export const apiClient = createClient({
|
|
27
32
|
baseUrl: "https://api.example.com",
|
|
@@ -29,27 +34,25 @@ export const apiClient = createClient({
|
|
|
29
34
|
Authorization: `Bearer ${getToken()}`,
|
|
30
35
|
}),
|
|
31
36
|
});
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
### 2. Create the React Query adapter
|
|
35
|
-
|
|
36
|
-
```ts
|
|
37
|
-
// lib/rq.ts
|
|
38
|
-
import { createReactQuery } from "@beignet/react-query";
|
|
39
|
-
import { apiClient } from "./api-client";
|
|
40
37
|
|
|
41
38
|
export const rq = createReactQuery(apiClient);
|
|
39
|
+
|
|
40
|
+
export function makeQueryClient() {
|
|
41
|
+
return new QueryClient();
|
|
42
|
+
}
|
|
42
43
|
```
|
|
43
44
|
|
|
44
|
-
###
|
|
45
|
+
### 2. Set up QueryClientProvider
|
|
45
46
|
|
|
46
47
|
```tsx
|
|
47
48
|
// app/providers.tsx
|
|
48
|
-
import {
|
|
49
|
+
import { QueryClientProvider } from "@tanstack/react-query";
|
|
50
|
+
import { type ReactNode, useState } from "react";
|
|
51
|
+
import { makeQueryClient } from "@/client";
|
|
49
52
|
|
|
50
|
-
|
|
53
|
+
export function Providers({ children }: { children: ReactNode }) {
|
|
54
|
+
const [queryClient] = useState(() => makeQueryClient());
|
|
51
55
|
|
|
52
|
-
export function Providers({ children }) {
|
|
53
56
|
return (
|
|
54
57
|
<QueryClientProvider client={queryClient}>
|
|
55
58
|
{children}
|
|
@@ -68,7 +71,7 @@ The options-first API generates options objects that can be used with any TanSta
|
|
|
68
71
|
|
|
69
72
|
```tsx
|
|
70
73
|
import { useQuery } from "@tanstack/react-query";
|
|
71
|
-
import { rq } from "@/client
|
|
74
|
+
import { rq } from "@/client";
|
|
72
75
|
import { getTodo } from "@/features/todos/contracts";
|
|
73
76
|
|
|
74
77
|
function TodoDetail({ id }: { id: string }) {
|
|
@@ -97,7 +100,7 @@ function TodoDetail({ id }: { id: string }) {
|
|
|
97
100
|
|
|
98
101
|
```tsx
|
|
99
102
|
import { useQueryClient } from "@tanstack/react-query";
|
|
100
|
-
import { rq } from "@/client
|
|
103
|
+
import { rq } from "@/client";
|
|
101
104
|
import { getTodo } from "@/features/todos/contracts";
|
|
102
105
|
|
|
103
106
|
function TodoList() {
|
|
@@ -119,12 +122,12 @@ function TodoList() {
|
|
|
119
122
|
#### Server-side data fetching
|
|
120
123
|
|
|
121
124
|
```tsx
|
|
122
|
-
import {
|
|
123
|
-
import { rq } from "@/client
|
|
125
|
+
import { dehydrate, HydrationBoundary } from "@tanstack/react-query";
|
|
126
|
+
import { makeQueryClient, rq } from "@/client";
|
|
124
127
|
import { getTodo } from "@/features/todos/contracts";
|
|
125
128
|
|
|
126
129
|
export async function TodoPage({ params }: { params: { id: string } }) {
|
|
127
|
-
const queryClient =
|
|
130
|
+
const queryClient = makeQueryClient();
|
|
128
131
|
|
|
129
132
|
// Fetch on the server
|
|
130
133
|
const todoQuery = rq(getTodo).queryOptions({
|
|
@@ -145,7 +148,7 @@ export async function TodoPage({ params }: { params: { id: string } }) {
|
|
|
145
148
|
|
|
146
149
|
```tsx
|
|
147
150
|
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
|
148
|
-
import { rq } from "@/client
|
|
151
|
+
import { rq } from "@/client";
|
|
149
152
|
import { createTodo, listTodos } from "@/features/todos/contracts";
|
|
150
153
|
|
|
151
154
|
function CreateTodoForm() {
|
|
@@ -154,8 +157,8 @@ function CreateTodoForm() {
|
|
|
154
157
|
// Generate mutation options
|
|
155
158
|
const createTodoMutation = rq(createTodo).mutationOptions({
|
|
156
159
|
onSuccess: (data, vars, onMutateResult, context) => {
|
|
157
|
-
// Invalidate
|
|
158
|
-
|
|
160
|
+
// Invalidate every cached listTodos call.
|
|
161
|
+
rq(listTodos).invalidate(queryClient);
|
|
159
162
|
},
|
|
160
163
|
});
|
|
161
164
|
|
|
@@ -180,7 +183,7 @@ function CreateTodoForm() {
|
|
|
180
183
|
|
|
181
184
|
```tsx
|
|
182
185
|
import { useInfiniteQuery } from "@tanstack/react-query";
|
|
183
|
-
import { rq } from "@/client
|
|
186
|
+
import { rq } from "@/client";
|
|
184
187
|
import { listTodos } from "@/features/todos/contracts";
|
|
185
188
|
|
|
186
189
|
function InfiniteTodoList() {
|
|
@@ -215,7 +218,7 @@ function InfiniteTodoList() {
|
|
|
215
218
|
|
|
216
219
|
## API reference
|
|
217
220
|
|
|
218
|
-
### `createReactQuery(client)`
|
|
221
|
+
### `createReactQuery(client, options?)`
|
|
219
222
|
|
|
220
223
|
Creates a React Query adapter factory.
|
|
221
224
|
|
|
@@ -223,6 +226,28 @@ Creates a React Query adapter factory.
|
|
|
223
226
|
const rq = createReactQuery(apiClient);
|
|
224
227
|
```
|
|
225
228
|
|
|
229
|
+
Headers are **excluded from generated query keys by default** because persisted
|
|
230
|
+
caches would otherwise store credentials such as `Authorization` tokens. When a
|
|
231
|
+
header changes response data — a tenant or workspace header, for example — opt
|
|
232
|
+
that specific header into keys with `keyHeaders`:
|
|
233
|
+
|
|
234
|
+
```ts
|
|
235
|
+
const rq = createReactQuery(apiClient, {
|
|
236
|
+
keyHeaders: ["X-Tenant-Id"],
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
rq(listTodos).queryOptions({
|
|
240
|
+
headers: { "X-Tenant-Id": "tenant-1", Authorization: "Bearer ..." },
|
|
241
|
+
});
|
|
242
|
+
// queryKey: ["beignet", "todos", "listTodos", "GET /todos",
|
|
243
|
+
// { headers: { "x-tenant-id": "tenant-1" } }]
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
Only whitelisted header names are included. Names are matched
|
|
247
|
+
case-insensitively and stored lowercased in the key. Never whitelist
|
|
248
|
+
credential headers; pass a per-call `key` when you need a fully custom key
|
|
249
|
+
instead.
|
|
250
|
+
|
|
226
251
|
### `rq(contract)`
|
|
227
252
|
|
|
228
253
|
Creates a contract helper with query/mutation options methods.
|
|
@@ -240,6 +265,7 @@ const queryOpts = helper.queryOptions({
|
|
|
240
265
|
path: { ... }, // Required when the contract has required path params
|
|
241
266
|
query?: { ... }, // Required when the contract has required query params
|
|
242
267
|
body?: { ... }, // Required when the contract has a required body
|
|
268
|
+
headers?: { ... }, // Sent with the request; keyed only via keyHeaders
|
|
243
269
|
key?: readonly unknown[], // Custom query key
|
|
244
270
|
// ...any other TanStack Query options (staleTime, enabled, etc.)
|
|
245
271
|
});
|
|
@@ -263,6 +289,21 @@ const mutationOpts = helper.mutationOptions({
|
|
|
263
289
|
useMutation(mutationOpts);
|
|
264
290
|
```
|
|
265
291
|
|
|
292
|
+
For contracts with idempotency metadata, the generated `mutationFn` derives
|
|
293
|
+
one idempotency key per `mutate(...)` invocation and keeps it stable across
|
|
294
|
+
TanStack retry attempts, so retried requests replay instead of re-executing.
|
|
295
|
+
Separate `mutate(...)` calls get distinct keys — retry stability does not
|
|
296
|
+
deduplicate double-clicks. Pass `idempotencyKey` in the mutation variables for
|
|
297
|
+
retry-with-same-key flows:
|
|
298
|
+
|
|
299
|
+
```ts
|
|
300
|
+
mutation.mutate({ body: { title: "New todo" }, idempotencyKey: key });
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
Caveat: calling `mutate()` with no variables skips per-invocation key
|
|
304
|
+
derivation and the client generates a fresh key per attempt. Pass a variables
|
|
305
|
+
object when an idempotent mutation should keep its key across retries.
|
|
306
|
+
|
|
266
307
|
### `helper.infiniteQueryOptions(options)`
|
|
267
308
|
|
|
268
309
|
**[Recommended]** Generate infinite query options for pagination.
|
|
@@ -271,9 +312,11 @@ useMutation(mutationOpts);
|
|
|
271
312
|
const infiniteOpts = helper.infiniteQueryOptions({
|
|
272
313
|
path?: { ... }, // Static path params included in the cache key
|
|
273
314
|
query?: { ... }, // Static query params included in the cache key
|
|
315
|
+
body?: { ... }, // Static body fields included in the cache key
|
|
274
316
|
page?: (ctx: { pageParam }) => ({
|
|
275
317
|
path?: { ... }, // Page-specific path params
|
|
276
318
|
query?: { ... }, // Page-specific query params (cursor, offset, etc.)
|
|
319
|
+
body?: { ... }, // Page-specific body fields (cursor, offset, etc.)
|
|
277
320
|
}),
|
|
278
321
|
initialPageParam: ...,
|
|
279
322
|
getNextPageParam: (lastPage) => ...,
|
|
@@ -285,6 +328,21 @@ const infiniteOpts = helper.infiniteQueryOptions({
|
|
|
285
328
|
useInfiniteQuery(infiniteOpts);
|
|
286
329
|
```
|
|
287
330
|
|
|
331
|
+
For body-paginated contracts, such as a POST search endpoint, keep the stable
|
|
332
|
+
filters in the static `body` and put the cursor in `page(...).body`. The static
|
|
333
|
+
body is part of the cache key, and each page request sends the merged body:
|
|
334
|
+
|
|
335
|
+
```ts
|
|
336
|
+
const searchOpts = rq(searchTodos).infiniteQueryOptions({
|
|
337
|
+
body: { term: "beignet" },
|
|
338
|
+
page: ({ pageParam }) => ({
|
|
339
|
+
body: { cursor: pageParam ?? null },
|
|
340
|
+
}),
|
|
341
|
+
initialPageParam: null as string | null,
|
|
342
|
+
getNextPageParam: (lastPage) => lastPage.nextCursor ?? undefined,
|
|
343
|
+
});
|
|
344
|
+
```
|
|
345
|
+
|
|
288
346
|
If you need fully dynamic params, pass a custom `key` and use `params(...)` instead:
|
|
289
347
|
|
|
290
348
|
```ts
|
|
@@ -301,7 +359,7 @@ const infiniteOpts = helper.infiniteQueryOptions({
|
|
|
301
359
|
### `helper.namespaceKey()`
|
|
302
360
|
|
|
303
361
|
Generate a namespace-level key for broad cache operations. Contracts created
|
|
304
|
-
from `
|
|
362
|
+
from `defineContractGroup().namespace("todos")` use that namespace.
|
|
305
363
|
Non-namespaced contracts use `null` so they cannot collide with a real
|
|
306
364
|
namespace string.
|
|
307
365
|
|
|
@@ -311,35 +369,115 @@ helper.namespaceKey(); // ["beignet", "todos"]
|
|
|
311
369
|
|
|
312
370
|
### `helper.contractKey()`
|
|
313
371
|
|
|
314
|
-
Generate a contract-level key without path, query, or body params.
|
|
372
|
+
Generate a contract-level key without path, query, or body params. The key
|
|
373
|
+
includes the contract route (`"GET /todos/:id"`), so two contracts with the
|
|
374
|
+
same derived local name but different routes — for example `/v1/todos` and
|
|
375
|
+
`/v2/todos` list contracts — never share a cache key.
|
|
315
376
|
|
|
316
377
|
```ts
|
|
317
|
-
helper.contractKey(); // ["beignet", "todos", "getTodo"]
|
|
378
|
+
helper.contractKey(); // ["beignet", "todos", "getTodo", "GET /todos/:id"]
|
|
318
379
|
```
|
|
319
380
|
|
|
381
|
+
The route segment is also exposed as `helper.route` (`"GET /todos/:id"`).
|
|
382
|
+
|
|
320
383
|
### `helper.key(params?)`
|
|
321
384
|
|
|
322
385
|
Generate a stable query key for cache operations.
|
|
323
386
|
|
|
324
387
|
```ts
|
|
325
|
-
helper.key();
|
|
326
|
-
|
|
388
|
+
helper.key();
|
|
389
|
+
// ["beignet", "todos", "getTodo", "GET /todos/:id"]
|
|
390
|
+
helper.key({ path: { id: "1" } });
|
|
391
|
+
// ["beignet", "todos", "getTodo", "GET /todos/:id", { path: { id: "1" } }]
|
|
327
392
|
```
|
|
328
393
|
|
|
329
394
|
`key(...)` normalizes params the same way the client serializes them: `null`
|
|
330
395
|
and `undefined` object entries are omitted, while meaningful values like `0`,
|
|
331
396
|
`false`, and empty strings are preserved. Request bodies are included in query
|
|
332
|
-
keys when passed to `queryOptions(...)`.
|
|
397
|
+
keys when passed to `queryOptions(...)`. Headers are excluded unless the
|
|
398
|
+
adapter opted in with `createReactQuery(client, { keyHeaders })`.
|
|
399
|
+
|
|
400
|
+
### `helper.namespaceFilter(options?)`
|
|
333
401
|
|
|
334
|
-
|
|
335
|
-
|
|
402
|
+
Generate TanStack Query filters for every contract in the helper's Beignet
|
|
403
|
+
namespace.
|
|
336
404
|
|
|
337
405
|
```ts
|
|
338
|
-
queryClient.invalidateQueries(
|
|
339
|
-
queryClient.invalidateQueries({
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
406
|
+
queryClient.invalidateQueries(helper.namespaceFilter());
|
|
407
|
+
queryClient.invalidateQueries(helper.namespaceFilter({ stale: true }));
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
### `helper.contractFilter(options?)`
|
|
411
|
+
|
|
412
|
+
Generate TanStack Query filters for every cached call to this contract.
|
|
413
|
+
|
|
414
|
+
```ts
|
|
415
|
+
queryClient.invalidateQueries(helper.contractFilter());
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
### `helper.filter(params?, options?)`
|
|
419
|
+
|
|
420
|
+
Generate TanStack Query filters for one contract call or parameter prefix.
|
|
421
|
+
|
|
422
|
+
```ts
|
|
423
|
+
queryClient.invalidateQueries(
|
|
424
|
+
helper.filter({ path: { id: "1" } }, { exact: true }),
|
|
425
|
+
);
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
These filters wrap plain TanStack Query keys, so prefix invalidation works as
|
|
429
|
+
expected while TanStack Query still owns cache behavior:
|
|
430
|
+
|
|
431
|
+
```ts
|
|
432
|
+
queryClient.invalidateQueries(rq(getTodo).namespaceFilter());
|
|
433
|
+
rq(getTodo).invalidate(queryClient);
|
|
434
|
+
rq(getTodo).invalidate(queryClient, { path: { id: "1" } });
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
Use the smallest filter that matches the data you want to refresh:
|
|
438
|
+
|
|
439
|
+
| Helper | Scope |
|
|
440
|
+
| --- | --- |
|
|
441
|
+
| `namespaceFilter()` | Every contract in one Beignet namespace. |
|
|
442
|
+
| `contractFilter()` | Every cached call for one contract. |
|
|
443
|
+
| `filter({ path, query, body })` | One parameter-scoped contract key. |
|
|
444
|
+
|
|
445
|
+
### `helper.invalidate(queryClient, params?, options?)`
|
|
446
|
+
|
|
447
|
+
Invalidate cached data for one contract using the helper's generated filters.
|
|
448
|
+
With no params it invalidates every cached call to the contract. Pass params to
|
|
449
|
+
target a detail key or parameter prefix.
|
|
450
|
+
|
|
451
|
+
```ts
|
|
452
|
+
await rq(listTodos).invalidate(queryClient);
|
|
453
|
+
await rq(getTodo).invalidate(queryClient, { path: { id: "1" } });
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
For list writes, invalidate the contract key so every filtered or paginated list
|
|
457
|
+
result refreshes:
|
|
458
|
+
|
|
459
|
+
```ts
|
|
460
|
+
const createTodoMutation = useMutation(
|
|
461
|
+
rq(createTodo).mutationOptions({
|
|
462
|
+
onSuccess: () => {
|
|
463
|
+
rq(listTodos).invalidate(queryClient);
|
|
464
|
+
},
|
|
465
|
+
}),
|
|
466
|
+
);
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
For detail writes, update or invalidate the exact detail key and then invalidate
|
|
470
|
+
affected list contracts:
|
|
471
|
+
|
|
472
|
+
```ts
|
|
473
|
+
const updateTodoMutation = useMutation(
|
|
474
|
+
rq(updateTodo).mutationOptions({
|
|
475
|
+
onSuccess: (_todo, vars) => {
|
|
476
|
+
rq(getTodo).invalidate(queryClient, { path: vars.path });
|
|
477
|
+
rq(listTodos).invalidate(queryClient);
|
|
478
|
+
},
|
|
479
|
+
}),
|
|
480
|
+
);
|
|
343
481
|
```
|
|
344
482
|
|
|
345
483
|
### `helper.endpoint`
|
package/dist/index.d.ts
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
|
-
import type { Client, Endpoint, EndpointCallArgs, InferEndpointContractError, InferSuccessResponse } from "@beignet/core/client";
|
|
1
|
+
import type { Client, Endpoint, EndpointCallArgs, InferBody, InferEndpointContractError, InferPathParams, InferQuery, InferSuccessResponse } from "@beignet/core/client";
|
|
2
2
|
import { type ContractLike, type HttpContractConfig, type ResolveContract } from "@beignet/core/contracts";
|
|
3
|
-
import type { InfiniteQueryObserverOptions,
|
|
4
|
-
type
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
type
|
|
8
|
-
type ContractQueryOptionsBase<TContract extends HttpContractConfig> = Omit<
|
|
3
|
+
import type { InfiniteQueryObserverOptions, InvalidateQueryFilters, QueryClient, QueryFunction, QueryKey, UseMutationOptions, UseQueryOptions } from "@tanstack/react-query";
|
|
4
|
+
type EndpointQueryArgs<TContract extends HttpContractConfig, TProvidedHeaders extends string> = Omit<EndpointCallArgs<TContract, TProvidedHeaders>, "rawBody" | "signal" | "idempotencyKey">;
|
|
5
|
+
type EndpointArgValue<TArgs, TKey extends "path" | "query" | "body" | "headers"> = TKey extends keyof TArgs ? TArgs[TKey] : undefined;
|
|
6
|
+
type IsRequiredValue<T> = undefined extends T ? false : true;
|
|
7
|
+
type RequiresQueryOptionsArgs<TContract extends HttpContractConfig, TProvidedHeaders extends string> = IsRequiredValue<InferPathParams<TContract>> extends true ? true : IsRequiredValue<InferQuery<TContract>> extends true ? true : IsRequiredValue<InferBody<TContract>> extends true ? true : IsRequiredValue<EndpointArgValue<EndpointCallArgs<TContract, TProvidedHeaders>, "headers">> extends true ? true : false;
|
|
8
|
+
type ContractQueryOptionsBase<TContract extends HttpContractConfig> = Omit<UseQueryOptions<InferSuccessResponse<TContract>, InferEndpointContractError<TContract>, InferSuccessResponse<TContract>, QueryKey>, "queryKey" | "queryFn">;
|
|
9
|
+
type ContractQueryOptionsResult<TContract extends HttpContractConfig> = ContractQueryOptionsBase<TContract> & {
|
|
10
|
+
queryKey: QueryKey;
|
|
11
|
+
queryFn: QueryFunction<InferSuccessResponse<TContract>, QueryKey>;
|
|
12
|
+
};
|
|
9
13
|
/**
|
|
10
14
|
* Options accepted by `ReactQueryContractHelper.queryOptions(...)`.
|
|
11
15
|
*
|
|
@@ -16,22 +20,39 @@ type ContractQueryOptionsBase<TContract extends HttpContractConfig> = Omit<Query
|
|
|
16
20
|
export type ContractUseQueryOptions<TContract extends HttpContractConfig, TProvidedHeaders extends string = never> = EndpointQueryArgs<TContract, TProvidedHeaders> & {
|
|
17
21
|
key?: readonly unknown[];
|
|
18
22
|
} & ContractQueryOptionsBase<TContract>;
|
|
19
|
-
type ContractQueryOptionsCallArgs<TContract extends HttpContractConfig, TProvidedHeaders extends string> =
|
|
23
|
+
type ContractQueryOptionsCallArgs<TContract extends HttpContractConfig, TProvidedHeaders extends string> = RequiresQueryOptionsArgs<TContract, TProvidedHeaders> extends true ? [args: ContractUseQueryOptions<TContract, TProvidedHeaders>] : [args?: ContractUseQueryOptions<TContract, TProvidedHeaders>];
|
|
24
|
+
export type ContractQueryKeyParams<TContract extends HttpContractConfig, TProvidedHeaders extends string = never> = {
|
|
25
|
+
path?: EndpointArgValue<EndpointQueryArgs<TContract, TProvidedHeaders>, "path">;
|
|
26
|
+
query?: EndpointArgValue<EndpointQueryArgs<TContract, TProvidedHeaders>, "query">;
|
|
27
|
+
body?: EndpointArgValue<EndpointQueryArgs<TContract, TProvidedHeaders>, "body">;
|
|
28
|
+
headers?: EndpointArgValue<EndpointQueryArgs<TContract, TProvidedHeaders>, "headers">;
|
|
29
|
+
};
|
|
20
30
|
/**
|
|
21
31
|
* Options accepted by `ReactQueryContractHelper.mutationOptions(...)`.
|
|
22
32
|
*
|
|
23
33
|
* TanStack `mutationFn` is generated from the contract endpoint, so callers pass
|
|
24
34
|
* the normal TanStack mutation lifecycle options.
|
|
25
35
|
*/
|
|
26
|
-
export type ContractUseMutationOptions<TContract extends HttpContractConfig, TProvidedHeaders extends string = never> = Omit<
|
|
36
|
+
export type ContractUseMutationOptions<TContract extends HttpContractConfig, TProvidedHeaders extends string = never> = Omit<UseMutationOptions<InferSuccessResponse<TContract>, InferEndpointContractError<TContract>, EndpointCallArgs<TContract, TProvidedHeaders>, unknown>, "mutationFn">;
|
|
37
|
+
/**
|
|
38
|
+
* Body input for infinite queries.
|
|
39
|
+
*
|
|
40
|
+
* Object bodies are shallow-partial because the full request body is the
|
|
41
|
+
* merge of the static `body` and each `page(...).body`, so neither side has
|
|
42
|
+
* to satisfy required body fields alone. The merged body is still validated
|
|
43
|
+
* by the endpoint call.
|
|
44
|
+
*/
|
|
45
|
+
type InfiniteQueryBody<TContract extends HttpContractConfig> = InferBody<TContract> extends Record<string, unknown> ? Partial<InferBody<TContract>> : EndpointCallArgs<TContract>["body"];
|
|
27
46
|
type InfiniteQueryResolvedParams<TContract extends HttpContractConfig, TProvidedHeaders extends string = never> = {
|
|
28
47
|
path?: EndpointCallArgs<TContract>["path"];
|
|
29
48
|
query?: EndpointCallArgs<TContract>["query"];
|
|
49
|
+
body?: InfiniteQueryBody<TContract>;
|
|
30
50
|
headers?: EndpointCallArgs<TContract, TProvidedHeaders>["headers"];
|
|
31
51
|
};
|
|
32
52
|
type SafeInfiniteQueryArgs<TContract extends HttpContractConfig, TPageParam, TProvidedHeaders extends string> = {
|
|
33
53
|
path?: EndpointCallArgs<TContract>["path"];
|
|
34
54
|
query?: EndpointCallArgs<TContract>["query"];
|
|
55
|
+
body?: InfiniteQueryBody<TContract>;
|
|
35
56
|
headers?: EndpointCallArgs<TContract, TProvidedHeaders>["headers"];
|
|
36
57
|
page?: (ctx: {
|
|
37
58
|
pageParam: TPageParam;
|
|
@@ -46,6 +67,7 @@ type DynamicInfiniteQueryArgs<TContract extends HttpContractConfig, TPageParam,
|
|
|
46
67
|
key: readonly unknown[];
|
|
47
68
|
path?: never;
|
|
48
69
|
query?: never;
|
|
70
|
+
body?: never;
|
|
49
71
|
page?: never;
|
|
50
72
|
};
|
|
51
73
|
type ContractInfiniteQueryOptions<TContract extends HttpContractConfig, TPageParam, TProvidedHeaders extends string> = (SafeInfiniteQueryArgs<TContract, TPageParam, TProvidedHeaders> | DynamicInfiniteQueryArgs<TContract, TPageParam, TProvidedHeaders>) & Omit<InfiniteQueryObserverOptions<InferSuccessResponse<TContract>, InferEndpointContractError<TContract>, InferSuccessResponse<TContract>, QueryKey, TPageParam>, "queryKey" | "queryFn">;
|
|
@@ -59,10 +81,14 @@ export type ContractQueryNamespaceKey = readonly [
|
|
|
59
81
|
];
|
|
60
82
|
/**
|
|
61
83
|
* Query key for one contract without path/query/body params.
|
|
84
|
+
*
|
|
85
|
+
* The fourth element is the contract route (`"GET /todos"`), so contracts
|
|
86
|
+
* with the same derived local name but different routes never share a key.
|
|
62
87
|
*/
|
|
63
88
|
export type ContractQueryContractKey = readonly [
|
|
64
89
|
typeof BEIGNET_QUERY_KEY_SCOPE,
|
|
65
90
|
string | null,
|
|
91
|
+
string,
|
|
66
92
|
string
|
|
67
93
|
];
|
|
68
94
|
/**
|
|
@@ -72,8 +98,28 @@ export type ContractQueryKey = readonly [
|
|
|
72
98
|
typeof BEIGNET_QUERY_KEY_SCOPE,
|
|
73
99
|
string | null,
|
|
74
100
|
string,
|
|
101
|
+
string,
|
|
75
102
|
unknown?
|
|
76
103
|
];
|
|
104
|
+
export type ContractQueryFilterOptions = Omit<InvalidateQueryFilters<QueryKey>, "queryKey">;
|
|
105
|
+
export type ContractQueryFilter<TKey extends QueryKey> = ContractQueryFilterOptions & {
|
|
106
|
+
queryKey: TKey;
|
|
107
|
+
};
|
|
108
|
+
/**
|
|
109
|
+
* Options accepted by `createReactQuery(client, options?)`.
|
|
110
|
+
*/
|
|
111
|
+
export type CreateReactQueryOptions = {
|
|
112
|
+
/**
|
|
113
|
+
* Header names to include in generated query keys.
|
|
114
|
+
*
|
|
115
|
+
* Headers are excluded from query keys by default because persisted caches
|
|
116
|
+
* would otherwise store credentials such as `Authorization` tokens. Opt in
|
|
117
|
+
* per adapter with the specific identity headers that change response data,
|
|
118
|
+
* such as a tenant header. Names are matched case-insensitively and stored
|
|
119
|
+
* lowercased in the key.
|
|
120
|
+
*/
|
|
121
|
+
keyHeaders?: readonly string[];
|
|
122
|
+
};
|
|
77
123
|
/**
|
|
78
124
|
* TanStack Query helper bound to one Beignet contract.
|
|
79
125
|
*
|
|
@@ -84,11 +130,17 @@ export type ContractQueryKey = readonly [
|
|
|
84
130
|
export declare class ReactQueryContractHelper<TContract extends HttpContractConfig, TProvidedHeaders extends string = never> {
|
|
85
131
|
private contract;
|
|
86
132
|
private _endpoint;
|
|
87
|
-
|
|
133
|
+
private options;
|
|
134
|
+
constructor(contract: TContract, _endpoint: Endpoint<TContract, TProvidedHeaders>, options?: CreateReactQueryOptions);
|
|
88
135
|
/**
|
|
89
136
|
* Fully qualified contract name.
|
|
90
137
|
*/
|
|
91
138
|
get name(): string;
|
|
139
|
+
/**
|
|
140
|
+
* Contract route used as the key segment that disambiguates contracts with
|
|
141
|
+
* the same local name, such as `/v1/todos` and `/v2/todos` list contracts.
|
|
142
|
+
*/
|
|
143
|
+
get route(): string;
|
|
92
144
|
/**
|
|
93
145
|
* Resource namespace used for query-key grouping.
|
|
94
146
|
*/
|
|
@@ -105,6 +157,22 @@ export declare class ReactQueryContractHelper<TContract extends HttpContractConf
|
|
|
105
157
|
* Build a contract-level query key without path/query params.
|
|
106
158
|
*/
|
|
107
159
|
contractKey(): ContractQueryContractKey;
|
|
160
|
+
/**
|
|
161
|
+
* Build TanStack Query filters for all contracts in this namespace.
|
|
162
|
+
*/
|
|
163
|
+
namespaceFilter(options?: ContractQueryFilterOptions): ContractQueryFilter<ContractQueryNamespaceKey>;
|
|
164
|
+
/**
|
|
165
|
+
* Build TanStack Query filters for every cached call to this contract.
|
|
166
|
+
*/
|
|
167
|
+
contractFilter(options?: ContractQueryFilterOptions): ContractQueryFilter<ContractQueryContractKey>;
|
|
168
|
+
/**
|
|
169
|
+
* Pick the adapter-whitelisted `keyHeaders` out of call headers.
|
|
170
|
+
*
|
|
171
|
+
* Returns `undefined` unless the adapter opted in with `keyHeaders` and the
|
|
172
|
+
* call provides at least one whitelisted header. Header names are matched
|
|
173
|
+
* case-insensitively and lowercased in the key component.
|
|
174
|
+
*/
|
|
175
|
+
private pickKeyHeaders;
|
|
108
176
|
/**
|
|
109
177
|
* Build a stable query key for this contract
|
|
110
178
|
*
|
|
@@ -112,28 +180,49 @@ export declare class ReactQueryContractHelper<TContract extends HttpContractConf
|
|
|
112
180
|
* This ensures consistent serialization between server (dehydrate) and
|
|
113
181
|
* client (hydrate), since undefined object values may serialize
|
|
114
182
|
* differently across React's RSC boundary vs JSON.stringify.
|
|
183
|
+
*
|
|
184
|
+
* Headers are never included unless the adapter opted in with
|
|
185
|
+
* `createReactQuery(client, { keyHeaders })`, and then only the whitelisted
|
|
186
|
+
* header names are included.
|
|
115
187
|
*/
|
|
116
188
|
key(params?: {
|
|
117
189
|
path?: unknown;
|
|
118
190
|
query?: unknown;
|
|
119
191
|
body?: unknown;
|
|
192
|
+
headers?: unknown;
|
|
120
193
|
}): ContractQueryKey;
|
|
194
|
+
/**
|
|
195
|
+
* Build TanStack Query filters for one contract call or parameter prefix.
|
|
196
|
+
*/
|
|
197
|
+
filter(params?: ContractQueryKeyParams<TContract, TProvidedHeaders>, options?: ContractQueryFilterOptions): ContractQueryFilter<ContractQueryKey>;
|
|
198
|
+
/**
|
|
199
|
+
* Invalidate cached data for this contract.
|
|
200
|
+
*
|
|
201
|
+
* With no params this invalidates every cached call to the contract. Pass
|
|
202
|
+
* path/query/body params to target a single call or parameter prefix.
|
|
203
|
+
*/
|
|
204
|
+
invalidate(queryClient: QueryClient, params?: ContractQueryKeyParams<TContract, TProvidedHeaders>, options?: ContractQueryFilterOptions): Promise<void>;
|
|
121
205
|
/**
|
|
122
206
|
* Create query options for TanStack Query.
|
|
123
207
|
*
|
|
124
208
|
* Pass the result to `useQuery`, `prefetchQuery`, `fetchQuery`, or any API
|
|
125
209
|
* that accepts query options.
|
|
126
210
|
*/
|
|
127
|
-
queryOptions(...callArgs: ContractQueryOptionsCallArgs<TContract, TProvidedHeaders>):
|
|
128
|
-
queryKey: QueryKey;
|
|
129
|
-
};
|
|
211
|
+
queryOptions(...callArgs: ContractQueryOptionsCallArgs<TContract, TProvidedHeaders>): ContractQueryOptionsResult<TContract>;
|
|
130
212
|
/**
|
|
131
213
|
* Create mutation options for TanStack Query.
|
|
132
214
|
*
|
|
133
215
|
* The generated `mutationFn` accepts the same variables shape as the
|
|
134
216
|
* underlying contract endpoint call.
|
|
217
|
+
*
|
|
218
|
+
* For contracts with idempotency metadata, the generated `mutationFn`
|
|
219
|
+
* derives one idempotency key per `mutate(...)` invocation and keeps it
|
|
220
|
+
* stable across TanStack retry attempts, which re-invoke `mutationFn` with
|
|
221
|
+
* the same variables object. Pass `idempotencyKey` in the variables to
|
|
222
|
+
* control the key explicitly. Calling `mutate()` with no variables falls
|
|
223
|
+
* back to per-attempt key generation in the client.
|
|
135
224
|
*/
|
|
136
|
-
mutationOptions(args?:
|
|
225
|
+
mutationOptions(args?: ContractUseMutationOptions<TContract, TProvidedHeaders>): UseMutationOptions<InferSuccessResponse<TContract>, InferEndpointContractError<TContract>, EndpointCallArgs<TContract, TProvidedHeaders>, unknown>;
|
|
137
226
|
/**
|
|
138
227
|
* Create infinite query options for TanStack Query.
|
|
139
228
|
*
|
|
@@ -152,7 +241,11 @@ export declare class ReactQueryContractHelper<TContract extends HttpContractConf
|
|
|
152
241
|
*
|
|
153
242
|
* Create this once near client setup, then bind contracts with the returned
|
|
154
243
|
* `rq(contract)` function.
|
|
244
|
+
*
|
|
245
|
+
* Pass `keyHeaders` to include specific identity headers, such as a tenant
|
|
246
|
+
* header, in generated query keys. Headers are excluded by default so
|
|
247
|
+
* persisted caches never store credentials.
|
|
155
248
|
*/
|
|
156
|
-
export declare function createReactQuery<TProvidedHeaders extends string = never>(client: Client<TProvidedHeaders
|
|
249
|
+
export declare function createReactQuery<TProvidedHeaders extends string = never>(client: Client<TProvidedHeaders>, options?: CreateReactQueryOptions): <TContractLike extends ContractLike>(contract: TContractLike) => ReactQueryContractHelper<ResolveContract<TContractLike>, TProvidedHeaders>;
|
|
157
250
|
export {};
|
|
158
251
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,MAAM,EACN,QAAQ,EACR,gBAAgB,EAChB,0BAA0B,EAC1B,oBAAoB,EACrB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,kBAAkB,EACvB,KAAK,eAAe,EAErB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,KAAK,EACV,4BAA4B,EAC5B,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|