@beignet/react-query 0.0.55 → 0.0.56
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 +6 -0
- package/README.md +40 -36
- package/package.json +1 -1
- package/skills/client/SKILL.md +22 -27
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
|
@@ -71,53 +71,57 @@ export function Providers({ children }: { children: ReactNode }) {
|
|
|
71
71
|
}
|
|
72
72
|
```
|
|
73
73
|
|
|
74
|
-
### 3.
|
|
74
|
+
### 3. Use contracts in components
|
|
75
75
|
|
|
76
|
-
|
|
77
|
-
options
|
|
78
|
-
|
|
76
|
+
Import the app's shared `rq` adapter and browser-safe feature contracts. Pass
|
|
77
|
+
options directly to TanStack Query; `invalidates` selects the queries to refresh
|
|
78
|
+
after a successful mutation:
|
|
79
79
|
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
|
|
80
|
+
```tsx
|
|
81
|
+
"use client";
|
|
82
|
+
|
|
83
|
+
import { useMutation, useQuery } from "@tanstack/react-query";
|
|
83
84
|
import { rq } from "@/client";
|
|
84
85
|
import { createTodo, listTodos } from "@/features/todos/contracts";
|
|
85
86
|
|
|
86
|
-
export function
|
|
87
|
-
|
|
88
|
-
|
|
87
|
+
export function TodoList() {
|
|
88
|
+
const todos = useQuery(rq(listTodos).queryOptions());
|
|
89
|
+
const create = useMutation(
|
|
90
|
+
rq(createTodo).mutationOptions({
|
|
91
|
+
invalidates: () => [rq(listTodos).contractFilter()],
|
|
92
|
+
}),
|
|
93
|
+
);
|
|
89
94
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
}
|
|
95
|
+
if (todos.isPending) return <p>Loading todos…</p>;
|
|
96
|
+
if (todos.isError) return <p role="alert">{todos.error.message}</p>;
|
|
93
97
|
|
|
94
|
-
|
|
95
|
-
|
|
98
|
+
return (
|
|
99
|
+
<div>
|
|
100
|
+
<button
|
|
101
|
+
type="button"
|
|
102
|
+
disabled={create.isPending}
|
|
103
|
+
onClick={() => create.mutate({ body: { title: "New todo" } })}
|
|
104
|
+
>
|
|
105
|
+
Add todo
|
|
106
|
+
</button>
|
|
107
|
+
{create.isError && <p role="alert">{create.error.message}</p>}
|
|
108
|
+
<ul>
|
|
109
|
+
{todos.data.items.map((todo) => <li key={todo.id}>{todo.title}</li>)}
|
|
110
|
+
</ul>
|
|
111
|
+
</div>
|
|
112
|
+
);
|
|
96
113
|
}
|
|
97
114
|
```
|
|
98
115
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
|
104
|
-
import {
|
|
105
|
-
createTodoMutationOptions,
|
|
106
|
-
invalidateTodos,
|
|
107
|
-
listTodosQueryOptions,
|
|
108
|
-
} from "@/features/todos/client/queries";
|
|
109
|
-
|
|
110
|
-
function TodoList() {
|
|
111
|
-
const queryClient = useQueryClient();
|
|
112
|
-
const todosQuery = useQuery(listTodosQueryOptions());
|
|
113
|
-
const createTodoMutation = useMutation({
|
|
114
|
-
...createTodoMutationOptions(),
|
|
115
|
-
onSuccess: () => invalidateTodos(queryClient),
|
|
116
|
-
});
|
|
116
|
+
Pass lifecycle callbacks inside `mutationOptions({ ... })`. Beignet awaits
|
|
117
|
+
`onSuccess`, then the selected invalidations before the mutation settles.
|
|
118
|
+
Declarative invalidation requires TanStack React Query 5.102.0 or newer in v5.
|
|
119
|
+
See [Declarative mutation invalidation](#declarative-mutation-invalidation).
|
|
117
120
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
+
Keep adapter setup in root `client/`. Extract
|
|
122
|
+
[feature client helpers](https://beignetjs.com/react-query#feature-client-helpers)
|
|
123
|
+
for shared query defaults, pagination, optimistic updates, or cache filters used
|
|
124
|
+
by mutations and broadcasts.
|
|
121
125
|
|
|
122
126
|
## Usage
|
|
123
127
|
|
package/package.json
CHANGED
package/skills/client/SKILL.md
CHANGED
|
@@ -34,39 +34,34 @@ export function makeQueryClient() {
|
|
|
34
34
|
Reuse the app's existing helper names and client options. Do not introduce a
|
|
35
35
|
parallel Beignet client unless the app already has a multi-client convention.
|
|
36
36
|
|
|
37
|
-
##
|
|
37
|
+
## Direct Options And Shared Behavior
|
|
38
38
|
|
|
39
|
-
|
|
40
|
-
|
|
39
|
+
Import contracts, the root `rq` adapter, and TanStack hooks in the component.
|
|
40
|
+
Inside its body, pass options directly to the hooks:
|
|
41
41
|
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
features/todos/client.ts
|
|
42
|
+
```ts
|
|
43
|
+
const todos = useQuery(rq(listTodos).queryOptions());
|
|
44
|
+
const create = useMutation(
|
|
45
|
+
rq(createTodo).mutationOptions({
|
|
46
|
+
invalidates: () => [rq(listTodos).contractFilter()],
|
|
47
|
+
}),
|
|
48
|
+
);
|
|
50
49
|
```
|
|
51
50
|
|
|
52
|
-
|
|
53
|
-
|
|
51
|
+
Extract feature client modules only when they own reusable behavior: shared
|
|
52
|
+
query defaults, pagination, optimistic updates and rollback, or filters used by
|
|
53
|
+
mutations and broadcasts. Prefer `features/<feature>/client/queries.ts` for
|
|
54
|
+
extracted options. Existing apps may use `features/<feature>/client.ts`; follow
|
|
55
|
+
their style without creating both forms. Keep component callbacks inside
|
|
56
|
+
`mutationOptions({ ... })` so they compose with declarative invalidation.
|
|
54
57
|
|
|
55
58
|
```ts
|
|
56
|
-
|
|
59
|
+
// features/todos/client/queries.ts: a shared freshness default
|
|
57
60
|
import { rq } from "@/client";
|
|
58
|
-
import {
|
|
61
|
+
import { listTodos } from "@/features/todos/contracts";
|
|
59
62
|
|
|
60
63
|
export function listTodosQueryOptions() {
|
|
61
|
-
return rq(listTodos).queryOptions({
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
export function createTodoMutationOptions() {
|
|
65
|
-
return rq(createTodo).mutationOptions();
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
export function invalidateTodos(queryClient: QueryClient) {
|
|
69
|
-
return rq(listTodos).invalidate(queryClient);
|
|
64
|
+
return rq(listTodos).queryOptions({ staleTime: 30_000 });
|
|
70
65
|
}
|
|
71
66
|
```
|
|
72
67
|
|
|
@@ -160,9 +155,9 @@ If `beignet lint` says a client component reaches a use-case module:
|
|
|
160
155
|
|
|
161
156
|
1. Move shared DTOs and validation to `features/<feature>/schemas.ts`.
|
|
162
157
|
2. Remove imports from use cases, routes, infra, providers, or `server/`.
|
|
163
|
-
3.
|
|
164
|
-
|
|
165
|
-
|
|
158
|
+
3. Import browser-safe contracts and the root `rq` adapter in the component.
|
|
159
|
+
4. Pass `rq(contract).queryOptions()` or `.mutationOptions()` to TanStack Query;
|
|
160
|
+
extract a feature client helper only for shared behavior.
|
|
166
161
|
|
|
167
162
|
Then run:
|
|
168
163
|
|