@hitch42/applet 0.1.1-beta.7 → 0.1.1-beta.9

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.
Files changed (177) hide show
  1. package/dist/_internal/client.js +120 -11
  2. package/dist/_internal/log-context.d.ts +34 -0
  3. package/dist/_internal/log-context.js +2 -0
  4. package/dist/_internal/server.d.ts +14 -1
  5. package/dist/_internal/server.js +122 -118
  6. package/dist/applet.js +22 -11
  7. package/dist/build-Bh_S5BUv.js +2 -0
  8. package/dist/{build-DauirTcY.js → build-CEfFoIZZ.js} +1 -1
  9. package/dist/{ci-gPrwo6C0.js → ci-BKw14X2h.js} +14 -13
  10. package/dist/client.d.ts +3 -3
  11. package/dist/{contract-DB9QQhD9.d.ts → contract-CsUpTBe0.d.ts} +1 -1
  12. package/dist/{deploy-CqrtNJ1x.js → deploy-wGYjwXrx.js} +139 -88
  13. package/dist/email-DBTVhNB_.js +62 -0
  14. package/dist/{generate-BIifT6PK.js → generate-BEIYs17x.js} +70 -32
  15. package/dist/generate-Dox-OYt6.js +2 -0
  16. package/dist/headers-DkNr9MLJ.js +17 -0
  17. package/dist/index.d.ts +122 -10
  18. package/dist/index.js +142 -26
  19. package/dist/{init-Wu6XmyVc.js → init-6oGPM46R.js} +15 -17
  20. package/dist/{load-config-BknBkdRs.js → load-config-xEdTXs0y.js} +2 -2
  21. package/dist/log-context-zu8U9Sjm.js +73 -0
  22. package/dist/{login-iT9MRuaw.js → login-CUx3TmFQ.js} +1 -1
  23. package/dist/{logs-B-qZGXSK.js → logs-DSjuEN0Q.js} +20 -22
  24. package/dist/{manifest-C489nYUy.d.ts → manifest-C6_F4bL8.d.ts} +7 -0
  25. package/dist/{manifest-Bd04cWhu.js → manifest-CJSL9GuC.js} +22 -3
  26. package/dist/me-BW7Paary.js +32 -0
  27. package/dist/{project-C_rtpjp8.js → project-BRZGd6xq.js} +202 -20
  28. package/dist/prompt-ChS-grYO.js +29 -0
  29. package/dist/query-cache-CXmAyLv3.js +82 -0
  30. package/dist/react.d.ts +3 -2
  31. package/dist/react.js +98 -80
  32. package/dist/schedules-C8_Svr4h.js +42 -0
  33. package/dist/server.d.ts +9 -4
  34. package/dist/server.js +29 -8
  35. package/dist/telephony-protocol-D-nf3Gca.d.ts +76 -0
  36. package/dist/telephony.d.ts +97 -0
  37. package/dist/telephony.js +726 -0
  38. package/dist/{upload-YbRKEqR6.d.ts → upload-DKZzz5kW.d.ts} +6 -6
  39. package/dist/{variables-DcwMeIau.js → variables-DT5RyHdH.js} +14 -39
  40. package/dist/vite.d.ts +3 -60
  41. package/dist/vite.js +497 -27
  42. package/dist/workflow-engine-BOTzURKM.js +111 -0
  43. package/dist/{workspace-B6lenAS5.js → workspace-D0dnnlxL.js} +37 -39
  44. package/package.json +18 -5
  45. package/scaffold/.agents/skills/hitch-applets/SKILL.md +50 -18
  46. package/scaffold/.agents/skills/hitch-applets/references/email-tracking.md +49 -0
  47. package/scaffold/.agents/skills/hitch-applets/references/files.md +3 -3
  48. package/scaffold/.agents/skills/hitch-applets/references/manifest.md +12 -2
  49. package/scaffold/.agents/skills/hitch-applets/references/markdown.md +2 -0
  50. package/scaffold/.agents/skills/hitch-applets/references/performance.md +1 -1
  51. package/scaffold/.agents/skills/hitch-applets/references/records.md +27 -4
  52. package/scaffold/.agents/skills/hitch-applets/references/schedules.md +7 -2
  53. package/scaffold/.agents/skills/hitch-applets/references/server.md +0 -3
  54. package/scaffold/.agents/skills/hitch-applets/references/workflows.md +11 -3
  55. package/scaffold/.agents/skills/hitch-cli/SKILL.md +20 -20
  56. package/scaffold/.agents/skills/hitch-data/SKILL.md +3 -2
  57. package/scaffold/.agents/skills/hitch-data/references/attributes.md +7 -1
  58. package/scaffold/.agents/skills/hitch-data/references/limits.md +23 -23
  59. package/scaffold/.agents/skills/hitch-theory/SKILL.md +151 -0
  60. package/scaffold/.agents/skills/react-best-practices/SKILL.md +127 -0
  61. package/scaffold/.agents/skills/react-best-practices/rules/advanced-effect-event-deps.md +50 -0
  62. package/scaffold/.agents/skills/react-best-practices/rules/advanced-event-handler-refs.md +55 -0
  63. package/scaffold/.agents/skills/react-best-practices/rules/advanced-init-once.md +42 -0
  64. package/scaffold/.agents/skills/react-best-practices/rules/advanced-use-latest.md +39 -0
  65. package/scaffold/.agents/skills/react-best-practices/rules/async-cheap-condition-before-await.md +37 -0
  66. package/scaffold/.agents/skills/react-best-practices/rules/async-defer-await.md +82 -0
  67. package/scaffold/.agents/skills/react-best-practices/rules/async-dependencies.md +48 -0
  68. package/scaffold/.agents/skills/react-best-practices/rules/async-parallel.md +24 -0
  69. package/scaffold/.agents/skills/react-best-practices/rules/bundle-analyzable-paths.md +42 -0
  70. package/scaffold/.agents/skills/react-best-practices/rules/bundle-barrel-imports.md +39 -0
  71. package/scaffold/.agents/skills/react-best-practices/rules/bundle-conditional.md +35 -0
  72. package/scaffold/.agents/skills/react-best-practices/rules/bundle-defer-third-party.md +46 -0
  73. package/scaffold/.agents/skills/react-best-practices/rules/bundle-dynamic-imports.md +38 -0
  74. package/scaffold/.agents/skills/react-best-practices/rules/bundle-preload.md +40 -0
  75. package/scaffold/.agents/skills/react-best-practices/rules/client-event-listeners.md +78 -0
  76. package/scaffold/.agents/skills/react-best-practices/rules/client-localstorage-schema.md +74 -0
  77. package/scaffold/.agents/skills/react-best-practices/rules/client-passive-event-listeners.md +48 -0
  78. package/scaffold/.agents/skills/react-best-practices/rules/js-batch-dom-css.md +110 -0
  79. package/scaffold/.agents/skills/react-best-practices/rules/js-cache-function-results.md +58 -0
  80. package/scaffold/.agents/skills/react-best-practices/rules/js-cache-property-access.md +28 -0
  81. package/scaffold/.agents/skills/react-best-practices/rules/js-cache-storage.md +56 -0
  82. package/scaffold/.agents/skills/react-best-practices/rules/js-combine-iterations.md +32 -0
  83. package/scaffold/.agents/skills/react-best-practices/rules/js-early-exit.md +50 -0
  84. package/scaffold/.agents/skills/react-best-practices/rules/js-flatmap-filter.md +51 -0
  85. package/scaffold/.agents/skills/react-best-practices/rules/js-hoist-regexp.md +45 -0
  86. package/scaffold/.agents/skills/react-best-practices/rules/js-index-maps.md +37 -0
  87. package/scaffold/.agents/skills/react-best-practices/rules/js-length-check-first.md +50 -0
  88. package/scaffold/.agents/skills/react-best-practices/rules/js-min-max-loop.md +82 -0
  89. package/scaffold/.agents/skills/react-best-practices/rules/js-request-idle-callback.md +104 -0
  90. package/scaffold/.agents/skills/react-best-practices/rules/js-set-map-lookups.md +24 -0
  91. package/scaffold/.agents/skills/react-best-practices/rules/js-tosorted-immutable.md +57 -0
  92. package/scaffold/.agents/skills/react-best-practices/rules/rendering-activity.md +26 -0
  93. package/scaffold/.agents/skills/react-best-practices/rules/rendering-animate-svg-wrapper.md +38 -0
  94. package/scaffold/.agents/skills/react-best-practices/rules/rendering-conditional-render.md +32 -0
  95. package/scaffold/.agents/skills/react-best-practices/rules/rendering-content-visibility.md +38 -0
  96. package/scaffold/.agents/skills/react-best-practices/rules/rendering-hoist-jsx.md +36 -0
  97. package/scaffold/.agents/skills/react-best-practices/rules/rendering-resource-hints.md +81 -0
  98. package/scaffold/.agents/skills/react-best-practices/rules/rendering-script-defer-async.md +36 -0
  99. package/scaffold/.agents/skills/react-best-practices/rules/rendering-svg-precision.md +28 -0
  100. package/scaffold/.agents/skills/react-best-practices/rules/rendering-usetransition-loading.md +43 -0
  101. package/scaffold/.agents/skills/react-best-practices/rules/rerender-defer-reads.md +39 -0
  102. package/scaffold/.agents/skills/react-best-practices/rules/rerender-dependencies.md +45 -0
  103. package/scaffold/.agents/skills/react-best-practices/rules/rerender-derived-state-no-effect.md +40 -0
  104. package/scaffold/.agents/skills/react-best-practices/rules/rerender-derived-state.md +29 -0
  105. package/scaffold/.agents/skills/react-best-practices/rules/rerender-functional-setstate.md +77 -0
  106. package/scaffold/.agents/skills/react-best-practices/rules/rerender-lazy-state-init.md +56 -0
  107. package/scaffold/.agents/skills/react-best-practices/rules/rerender-memo-with-default-value.md +36 -0
  108. package/scaffold/.agents/skills/react-best-practices/rules/rerender-memo.md +44 -0
  109. package/scaffold/.agents/skills/react-best-practices/rules/rerender-move-effect-to-event.md +45 -0
  110. package/scaffold/.agents/skills/react-best-practices/rules/rerender-no-inline-components.md +75 -0
  111. package/scaffold/.agents/skills/react-best-practices/rules/rerender-simple-expression-in-memo.md +35 -0
  112. package/scaffold/.agents/skills/react-best-practices/rules/rerender-split-combined-hooks.md +64 -0
  113. package/scaffold/.agents/skills/react-best-practices/rules/rerender-transitions.md +40 -0
  114. package/scaffold/.agents/skills/react-best-practices/rules/rerender-use-deferred-value.md +59 -0
  115. package/scaffold/.agents/skills/react-best-practices/rules/rerender-use-ref-transient-values.md +73 -0
  116. package/scaffold/.agents/skills/tanstack-query/SKILL.md +136 -0
  117. package/scaffold/.agents/skills/tanstack-query/references/compositions/automatic-invalidation-after-mutations.md +124 -0
  118. package/scaffold/.agents/skills/tanstack-query/references/compositions/broadcast-realtime-and-multi-tab-synchronization.md +150 -0
  119. package/scaffold/.agents/skills/tanstack-query/references/compositions/compose-query-with-tanstack-router-and-start.md +248 -0
  120. package/scaffold/.agents/skills/tanstack-query/references/compositions/enforce-query-best-practices-with-eslint.md +167 -0
  121. package/scaffold/.agents/skills/tanstack-query/references/compositions/persist-offline-and-restore-caches.md +181 -0
  122. package/scaffold/.agents/skills/tanstack-query/references/compositions/query-data-and-forms.md +156 -0
  123. package/scaffold/.agents/skills/tanstack-query/references/core/build-query-abstractions.md +130 -0
  124. package/scaffold/.agents/skills/tanstack-query/references/core/cancel-queries-and-consume-abort-signals.md +176 -0
  125. package/scaffold/.agents/skills/tanstack-query/references/core/concurrent-optimistic-updates.md +135 -0
  126. package/scaffold/.agents/skills/tanstack-query/references/core/coordinate-query-execution.md +188 -0
  127. package/scaffold/.agents/skills/tanstack-query/references/core/design-query-keys-and-options.md +182 -0
  128. package/scaffold/.agents/skills/tanstack-query/references/core/fetch-and-observe-queries.md +193 -0
  129. package/scaffold/.agents/skills/tanstack-query/references/core/implement-optimistic-updates-and-cache-writes.md +168 -0
  130. package/scaffold/.agents/skills/tanstack-query/references/core/paginate-and-build-infinite-queries.md +188 -0
  131. package/scaffold/.agents/skills/tanstack-query/references/core/seed-placeholder-select-and-transform-data.md +188 -0
  132. package/scaffold/.agents/skills/tanstack-query/references/core/selectors-and-derived-state.md +145 -0
  133. package/scaffold/.agents/skills/tanstack-query/references/core/tune-defaults-freshness-retries-and-refetching.md +172 -0
  134. package/scaffold/.agents/skills/tanstack-query/references/core/understand-query-internals-and-observers.md +104 -0
  135. package/scaffold/.agents/skills/tanstack-query/references/core/write-mutations-and-invalidate-related-queries.md +183 -0
  136. package/scaffold/.agents/skills/tanstack-query/references/framework/debug-with-devtools.md +169 -0
  137. package/scaffold/.agents/skills/tanstack-query/references/framework/handle-status-and-errors.md +119 -0
  138. package/scaffold/.agents/skills/tanstack-query/references/framework/shape-data-and-render-efficiently.md +184 -0
  139. package/scaffold/.agents/skills/tanstack-query/references/framework/use-framework-adapter-reactivity.md +185 -0
  140. package/scaffold/.agents/skills/tanstack-query/references/framework/use-suspense-and-error-boundaries.md +208 -0
  141. package/scaffold/.agents/skills/tanstack-query/references/lifecycle/migrate-major-versions-and-codemods.md +169 -0
  142. package/scaffold/.agents/skills/tanstack-query/references/lifecycle/prefetch-and-remove-request-waterfalls.md +228 -0
  143. package/scaffold/.agents/skills/tanstack-query/references/lifecycle/setup-query-client-and-providers.md +161 -0
  144. package/scaffold/.agents/skills/tanstack-query/references/lifecycle/ssr-hydration-and-streaming.md +209 -0
  145. package/scaffold/.agents/skills/tanstack-query/references/lifecycle/test-query-code.md +160 -0
  146. package/scaffold/.agents/skills/tanstack-router/SKILL.md +134 -0
  147. package/scaffold/.agents/skills/tanstack-router/references/compositions/router-query.md +412 -0
  148. package/scaffold/.agents/skills/tanstack-router/references/react-router.md +495 -0
  149. package/scaffold/.agents/skills/tanstack-router/references/router-core/auth-and-guards.md +495 -0
  150. package/scaffold/.agents/skills/tanstack-router/references/router-core/code-splitting.md +318 -0
  151. package/scaffold/.agents/skills/tanstack-router/references/router-core/data-loading.md +490 -0
  152. package/scaffold/.agents/skills/tanstack-router/references/router-core/index.md +158 -0
  153. package/scaffold/.agents/skills/tanstack-router/references/router-core/navigation.md +433 -0
  154. package/scaffold/.agents/skills/tanstack-router/references/router-core/not-found-and-errors.md +436 -0
  155. package/scaffold/.agents/skills/tanstack-router/references/router-core/path-params.md +383 -0
  156. package/scaffold/.agents/skills/tanstack-router/references/router-core/search-params.md +343 -0
  157. package/scaffold/.agents/skills/tanstack-router/references/router-core/ssr.md +462 -0
  158. package/scaffold/.agents/skills/tanstack-router/references/router-core/type-safety.md +493 -0
  159. package/scaffold/.agents/skills/tanstack-router/references/router-plugin.md +250 -0
  160. package/scaffold/.agents/skills/tanstack-router/references/virtual-file-routes.md +215 -0
  161. package/scaffold/.agents/skills/web-design-guidelines/SKILL.md +184 -0
  162. package/scaffold/.github/workflows/hitch.yml +1 -1
  163. package/scaffold/AGENTS.md +2 -2
  164. package/scaffold/applet/src/client/components/ui/alert.tsx +1 -1
  165. package/scaffold/applet/src/client/components/ui/button.tsx +1 -1
  166. package/scaffold/applet/src/client/components/ui/checkbox.tsx +1 -1
  167. package/scaffold/applet/src/client/components/ui/dialog.tsx +2 -2
  168. package/scaffold/applet/src/client/components/ui/dropdown-menu.tsx +2 -2
  169. package/scaffold/applet/src/client/components/ui/input-group.tsx +2 -2
  170. package/scaffold/applet/src/client/components/ui/select.tsx +2 -2
  171. package/scaffold/applet/src/client/components/ui/sheet.tsx +2 -2
  172. package/scaffold/applet/src/client/components/ui/spinner.tsx +2 -1
  173. package/scaffold/applet/src/client/components/ui/tabs.tsx +1 -1
  174. package/scaffold/applet/src/client/lib/utils.ts +1 -6
  175. package/scaffold/applet/src/client/styles/globals.css +2 -0
  176. package/dist/build-DhNDp7ji.js +0 -2
  177. package/dist/generate-DSk8ihsC.js +0 -2
@@ -0,0 +1,168 @@
1
+ ---
2
+ name: core/implement-optimistic-updates-and-cache-writes
3
+ description: >
4
+ Use this when implementing optimistic updates, onMutate rollback context,
5
+ cancelQueries before writes, setQueryData, setQueriesData, immutable cache writes,
6
+ mutation rollback, and offline-aware optimistic state.
7
+ type: core
8
+ library: TanStack Query
9
+ library_version: "5.101.0"
10
+ requires:
11
+ - core/write-mutations-and-invalidate-related-queries
12
+ - core/cancel-queries-and-consume-abort-signals
13
+ sources:
14
+ - TanStack/query:docs/framework/react/guides/optimistic-updates.md
15
+ - TanStack/query:docs/framework/react/guides/updates-from-mutation-responses.md
16
+ - TanStack/query:docs/framework/react/guides/query-cancellation.md
17
+ - TanStack/query:docs/framework/react/plugins/persistQueryClient.md
18
+ ---
19
+
20
+ ## Setup
21
+
22
+ ```ts
23
+ import { useMutation, useQueryClient } from "@tanstack/react-query";
24
+
25
+ type Todo = { id: number; title: string };
26
+
27
+ export function useOptimisticAddTodo() {
28
+ const queryClient = useQueryClient();
29
+ return useMutation({
30
+ mutationFn: async (title: string) => ({ id: Date.now(), title }),
31
+ onMutate: async (title) => {
32
+ await queryClient.cancelQueries({ queryKey: ["todos"] });
33
+ const previous = queryClient.getQueryData<Array<Todo>>(["todos"]);
34
+ queryClient.setQueryData<Array<Todo>>(["todos"], (old = []) => [...old, { id: -1, title }]);
35
+ return { previous };
36
+ },
37
+ onError: (_error, _title, context) => {
38
+ queryClient.setQueryData(["todos"], context?.previous);
39
+ },
40
+ onSettled: async () => {
41
+ await queryClient.invalidateQueries({ queryKey: ["todos"] });
42
+ },
43
+ });
44
+ }
45
+ ```
46
+
47
+ ## Core Patterns
48
+
49
+ ### Write mutation response into detail cache
50
+
51
+ ```ts
52
+ import { useMutation, useQueryClient } from "@tanstack/react-query";
53
+
54
+ export function useUpdateTodo() {
55
+ const queryClient = useQueryClient();
56
+ return useMutation({
57
+ mutationFn: async (todo: { id: number; title: string }) => todo,
58
+ onSuccess: (todo) => queryClient.setQueryData(["todo", todo.id], todo),
59
+ });
60
+ }
61
+ ```
62
+
63
+ ### Update lists immutably
64
+
65
+ ```ts
66
+ import { QueryClient } from "@tanstack/react-query";
67
+
68
+ const queryClient = new QueryClient();
69
+
70
+ queryClient.setQueryData<Array<{ id: number; title: string }>>(["todos"], (old = []) =>
71
+ old.map((todo) => (todo.id === 1 ? { ...todo, title: "Done" } : todo)),
72
+ );
73
+ ```
74
+
75
+ ### Roll back with context
76
+
77
+ ```ts
78
+ import { QueryClient } from "@tanstack/react-query";
79
+
80
+ const queryClient = new QueryClient();
81
+ const previous = queryClient.getQueryData(["todos"]);
82
+ queryClient.setQueryData(["todos"], [{ id: 1, title: "Optimistic" }]);
83
+ queryClient.setQueryData(["todos"], previous);
84
+ ```
85
+
86
+ ## Common Mistakes
87
+
88
+ ### CRITICAL Optimistic write without cancellation
89
+
90
+ Wrong:
91
+
92
+ ```ts
93
+ import { QueryClient } from "@tanstack/react-query";
94
+
95
+ const queryClient = new QueryClient();
96
+ queryClient.setQueryData(["todos"], [{ id: 1, title: "Optimistic" }]);
97
+ ```
98
+
99
+ Correct:
100
+
101
+ ```ts
102
+ import { QueryClient } from "@tanstack/react-query";
103
+
104
+ const queryClient = new QueryClient();
105
+ await queryClient.cancelQueries({ queryKey: ["todos"] });
106
+ queryClient.setQueryData(["todos"], [{ id: 1, title: "Optimistic" }]);
107
+ ```
108
+
109
+ An in-flight refetch can overwrite an optimistic write unless it is cancelled first.
110
+
111
+ Source: TanStack/query:docs/framework/react/guides/optimistic-updates.md
112
+
113
+ ### CRITICAL In-place mutation
114
+
115
+ Wrong:
116
+
117
+ ```ts
118
+ import { QueryClient } from "@tanstack/react-query";
119
+
120
+ const queryClient = new QueryClient();
121
+ queryClient.setQueryData<Array<{ id: number; done: boolean }>>(["todos"], (old = []) => {
122
+ old[0].done = true;
123
+ return old;
124
+ });
125
+ ```
126
+
127
+ Correct:
128
+
129
+ ```ts
130
+ import { QueryClient } from "@tanstack/react-query";
131
+
132
+ const queryClient = new QueryClient();
133
+ queryClient.setQueryData<Array<{ id: number; done: boolean }>>(["todos"], (old = []) =>
134
+ old.map((todo) => (todo.id === 1 ? { ...todo, done: true } : todo)),
135
+ );
136
+ ```
137
+
138
+ Cache updates must be immutable so observers can detect and share changes correctly.
139
+
140
+ Source: TanStack/query:docs/framework/react/guides/updates-from-mutation-responses.md
141
+
142
+ ### HIGH Persisted persister loses optimistic mutation
143
+
144
+ Wrong:
145
+
146
+ ```ts
147
+ import { QueryClient } from "@tanstack/react-query";
148
+
149
+ export const queryClient = new QueryClient();
150
+ queryClient.setMutationDefaults(["updateTodo"], {});
151
+ ```
152
+
153
+ Correct:
154
+
155
+ ```ts
156
+ import { QueryClient } from "@tanstack/react-query";
157
+
158
+ export const queryClient = new QueryClient();
159
+ queryClient.setMutationDefaults(["updateTodo"], {
160
+ mutationFn: async (todo: { id: number; title: string }) => todo,
161
+ });
162
+ ```
163
+
164
+ Paused persisted mutations need a default mutationFn after hydration because functions cannot be serialized.
165
+
166
+ Source: TanStack/query:docs/framework/react/plugins/persistQueryClient.md
167
+
168
+ See also: `core/cancel-queries-and-consume-abort-signals` before optimistic writes.
@@ -0,0 +1,188 @@
1
+ ---
2
+ name: core/paginate-and-build-infinite-queries
3
+ description: >
4
+ Use this when implementing pagination, lagged queries, placeholderData,
5
+ keepPreviousData migration, useInfiniteQuery, initialPageParam,
6
+ getNextPageParam, getPreviousPageParam, maxPages, pages, or pageParams.
7
+ type: core
8
+ library: TanStack Query
9
+ library_version: "5.101.0"
10
+ requires:
11
+ - core/design-query-keys-and-options
12
+ - core/fetch-and-observe-queries
13
+ sources:
14
+ - TanStack/query:docs/framework/react/guides/paginated-queries.md
15
+ - TanStack/query:docs/framework/react/guides/infinite-queries.md
16
+ - TanStack/query:docs/framework/react/reference/useInfiniteQuery.md
17
+ - TanStack/query:docs/reference/InfiniteQueryObserver.md
18
+ - TanStack/query:docs/eslint/infinite-query-property-order.md
19
+ ---
20
+
21
+ ## Setup
22
+
23
+ ```ts
24
+ import { keepPreviousData, useQuery } from "@tanstack/react-query";
25
+
26
+ export function useProjects(page: number) {
27
+ return useQuery({
28
+ queryKey: ["projects", page],
29
+ queryFn: async () => ({ page, projects: [{ id: page }] }),
30
+ placeholderData: keepPreviousData,
31
+ });
32
+ }
33
+ ```
34
+
35
+ ## Core Patterns
36
+
37
+ ### Build an infinite query
38
+
39
+ ```ts
40
+ import { useInfiniteQuery } from "@tanstack/react-query";
41
+
42
+ export function useFeed() {
43
+ return useInfiniteQuery({
44
+ queryKey: ["feed"],
45
+ queryFn: async ({ pageParam }) => ({
46
+ nextCursor: pageParam + 1,
47
+ items: [{ id: pageParam }],
48
+ }),
49
+ initialPageParam: 0,
50
+ getNextPageParam: (lastPage) => lastPage.nextCursor,
51
+ });
52
+ }
53
+ ```
54
+
55
+ ### Bound memory with maxPages
56
+
57
+ ```ts
58
+ import { useInfiniteQuery } from "@tanstack/react-query";
59
+
60
+ export function useBoundedFeed() {
61
+ return useInfiniteQuery({
62
+ queryKey: ["feed"],
63
+ queryFn: async ({ pageParam }) => ({
64
+ nextCursor: pageParam + 1,
65
+ items: [{ id: pageParam }],
66
+ }),
67
+ initialPageParam: 0,
68
+ getNextPageParam: (lastPage) => lastPage.nextCursor,
69
+ maxPages: 5,
70
+ });
71
+ }
72
+ ```
73
+
74
+ ### Preserve infinite data shape
75
+
76
+ ```ts
77
+ import { QueryClient } from "@tanstack/react-query";
78
+
79
+ const queryClient = new QueryClient();
80
+
81
+ queryClient.setQueryData(["feed"], {
82
+ pages: [{ items: [{ id: 1 }], nextCursor: 2 }],
83
+ pageParams: [1],
84
+ });
85
+ ```
86
+
87
+ ## Common Mistakes
88
+
89
+ ### CRITICAL Missing initialPageParam
90
+
91
+ Wrong:
92
+
93
+ ```ts
94
+ import { useInfiniteQuery } from "@tanstack/react-query";
95
+
96
+ export function useFeed() {
97
+ return useInfiniteQuery({
98
+ queryKey: ["feed"],
99
+ queryFn: async () => ({ items: [] }),
100
+ getNextPageParam: () => 1,
101
+ });
102
+ }
103
+ ```
104
+
105
+ Correct:
106
+
107
+ ```ts
108
+ import { useInfiniteQuery } from "@tanstack/react-query";
109
+
110
+ export function useFeed() {
111
+ return useInfiniteQuery({
112
+ queryKey: ["feed"],
113
+ queryFn: async ({ pageParam }) => ({ items: [pageParam] }),
114
+ initialPageParam: 0,
115
+ getNextPageParam: () => 1,
116
+ });
117
+ }
118
+ ```
119
+
120
+ v5 requires an explicit initial page param so pageParams can be serialized and inferred.
121
+
122
+ Source: TanStack/query:docs/framework/react/guides/infinite-queries.md
123
+
124
+ ### HIGH Overlapping infinite fetches
125
+
126
+ Wrong:
127
+
128
+ ```tsx
129
+ import { useInfiniteQuery } from "@tanstack/react-query";
130
+
131
+ export function Feed() {
132
+ const query = useInfiniteQuery({
133
+ queryKey: ["feed"],
134
+ queryFn: async ({ pageParam }) => ({ nextCursor: pageParam + 1 }),
135
+ initialPageParam: 0,
136
+ getNextPageParam: (page) => page.nextCursor,
137
+ });
138
+ return <button onClick={() => query.fetchNextPage()}>More</button>;
139
+ }
140
+ ```
141
+
142
+ Correct:
143
+
144
+ ```tsx
145
+ import { useInfiniteQuery } from "@tanstack/react-query";
146
+
147
+ export function Feed() {
148
+ const query = useInfiniteQuery({
149
+ queryKey: ["feed"],
150
+ queryFn: async ({ pageParam }) => ({ nextCursor: pageParam + 1 }),
151
+ initialPageParam: 0,
152
+ getNextPageParam: (page) => page.nextCursor,
153
+ });
154
+ return (
155
+ <button disabled={query.isFetchingNextPage} onClick={() => query.fetchNextPage()}>
156
+ More
157
+ </button>
158
+ );
159
+ }
160
+ ```
161
+
162
+ Only one ongoing fetch should update an infinite query cache at a time unless explicitly overridden.
163
+
164
+ Source: TanStack/query:docs/framework/react/guides/infinite-queries.md
165
+
166
+ ### HIGH Broken pages shape
167
+
168
+ Wrong:
169
+
170
+ ```ts
171
+ import { QueryClient } from "@tanstack/react-query";
172
+
173
+ const queryClient = new QueryClient();
174
+ queryClient.setQueryData(["feed"], [{ id: 1 }]);
175
+ ```
176
+
177
+ Correct:
178
+
179
+ ```ts
180
+ import { QueryClient } from "@tanstack/react-query";
181
+
182
+ const queryClient = new QueryClient();
183
+ queryClient.setQueryData(["feed"], { pages: [[{ id: 1 }]], pageParams: [0] });
184
+ ```
185
+
186
+ Infinite query data must keep `pages` and `pageParams`; refetches expect that shape.
187
+
188
+ Source: TanStack/query:docs/framework/react/guides/infinite-queries.md
@@ -0,0 +1,188 @@
1
+ ---
2
+ name: core/seed-placeholder-select-and-transform-data
3
+ description: >
4
+ Use this when choosing initialData, initialDataUpdatedAt, placeholderData,
5
+ keepPreviousData, select, data transformation, cache seeding, detail-from-list
6
+ seeding, or derived query data.
7
+ type: core
8
+ library: TanStack Query
9
+ library_version: "5.101.0"
10
+ requires:
11
+ - core/design-query-keys-and-options
12
+ - core/fetch-and-observe-queries
13
+ sources:
14
+ - TanStack/query:docs/framework/react/guides/initial-query-data.md
15
+ - TanStack/query:docs/framework/react/guides/placeholder-query-data.md
16
+ - TanStack/query:docs/framework/react/guides/render-optimizations.md
17
+ - TanStack/query:docs/framework/react/reference/queryOptions.md
18
+ ---
19
+
20
+ ## Setup
21
+
22
+ ```ts
23
+ import { keepPreviousData, useQuery } from "@tanstack/react-query";
24
+
25
+ export function useProjects(page: number) {
26
+ return useQuery({
27
+ queryKey: ["projects", page],
28
+ queryFn: async () => ({ page, items: [{ id: page }] }),
29
+ placeholderData: keepPreviousData,
30
+ });
31
+ }
32
+ ```
33
+
34
+ ## Core Patterns
35
+
36
+ ### Seed detail data from a list
37
+
38
+ ```ts
39
+ import { QueryClient, useQuery } from "@tanstack/react-query";
40
+
41
+ const queryClient = new QueryClient();
42
+
43
+ export function useTodo(todoId: number) {
44
+ return useQuery({
45
+ queryKey: ["todo", todoId],
46
+ queryFn: async () => ({ id: todoId, title: "Fresh" }),
47
+ initialData: () =>
48
+ queryClient
49
+ .getQueryData<Array<{ id: number; title: string }>>(["todos"])
50
+ ?.find((todo) => todo.id === todoId),
51
+ });
52
+ }
53
+ ```
54
+
55
+ ### Select the smallest shape
56
+
57
+ ```ts
58
+ import { useQuery } from "@tanstack/react-query";
59
+
60
+ export function useTodoCount() {
61
+ return useQuery({
62
+ queryKey: ["todos"],
63
+ queryFn: async () => [{ id: 1 }, { id: 2 }],
64
+ select: (todos) => todos.length,
65
+ });
66
+ }
67
+ ```
68
+
69
+ ### Transform in the query function for cache-wide shape
70
+
71
+ ```ts
72
+ import { queryOptions } from "@tanstack/react-query";
73
+
74
+ export const todosOptions = queryOptions({
75
+ queryKey: ["todos"],
76
+ queryFn: async () =>
77
+ [{ id: 1, title: "ship" }].map((todo) => ({
78
+ ...todo,
79
+ title: todo.title.toUpperCase(),
80
+ })),
81
+ });
82
+ ```
83
+
84
+ ## Common Mistakes
85
+
86
+ ### HIGH initialData overwrite assumption
87
+
88
+ Wrong:
89
+
90
+ ```ts
91
+ import { useQuery } from "@tanstack/react-query";
92
+
93
+ export function useTodo() {
94
+ return useQuery({
95
+ queryKey: ["todo", 1],
96
+ queryFn: async () => ({ id: 1, title: "Server" }),
97
+ initialData: { id: 1, title: "Always" },
98
+ });
99
+ }
100
+ ```
101
+
102
+ Correct:
103
+
104
+ ```ts
105
+ import { useQuery } from "@tanstack/react-query";
106
+
107
+ export function useTodo() {
108
+ return useQuery({
109
+ queryKey: ["todo", 1],
110
+ queryFn: async () => ({ id: 1, title: "Server" }),
111
+ placeholderData: { id: 1, title: "Temporary" },
112
+ });
113
+ }
114
+ ```
115
+
116
+ `initialData` is persisted to cache as real data; placeholder data is observer-local.
117
+
118
+ Source: TanStack/query:docs/framework/react/guides/initial-query-data.md
119
+
120
+ ### HIGH v4 keepPreviousData option
121
+
122
+ Wrong:
123
+
124
+ ```ts
125
+ import { useQuery } from "@tanstack/react-query";
126
+
127
+ export function usePage(page: number) {
128
+ return useQuery({
129
+ queryKey: ["page", page],
130
+ queryFn: async () => ({ page }),
131
+ keepPreviousData: true,
132
+ });
133
+ }
134
+ ```
135
+
136
+ Correct:
137
+
138
+ ```ts
139
+ import { keepPreviousData, useQuery } from "@tanstack/react-query";
140
+
141
+ export function usePage(page: number) {
142
+ return useQuery({
143
+ queryKey: ["page", page],
144
+ queryFn: async () => ({ page }),
145
+ placeholderData: keepPreviousData,
146
+ });
147
+ }
148
+ ```
149
+
150
+ v5 replaced the `keepPreviousData` option with `placeholderData: keepPreviousData`.
151
+
152
+ Source: TanStack/query:docs/framework/react/guides/migrating-to-v5.md
153
+
154
+ ### MEDIUM Throwing in select
155
+
156
+ Wrong:
157
+
158
+ ```ts
159
+ import { useQuery } from "@tanstack/react-query";
160
+
161
+ export function useFirstTodo() {
162
+ return useQuery({
163
+ queryKey: ["todos"],
164
+ queryFn: async () => [] as Array<{ id: number }>,
165
+ select: (todos) => todos[0].id,
166
+ });
167
+ }
168
+ ```
169
+
170
+ Correct:
171
+
172
+ ```ts
173
+ import { useQuery } from "@tanstack/react-query";
174
+
175
+ export function useFirstTodo() {
176
+ return useQuery({
177
+ queryKey: ["todos"],
178
+ queryFn: async () => [] as Array<{ id: number }>,
179
+ select: (todos) => todos[0]?.id ?? null,
180
+ });
181
+ }
182
+ ```
183
+
184
+ `select` transforms successful data; it is not the right place to model fetch errors.
185
+
186
+ Source: TanStack/query:docs/framework/react/guides/render-optimizations.md
187
+
188
+ See also: `lifecycle/ssr-hydration-and-streaming` for SSR tradeoffs compared to hydration.
@@ -0,0 +1,145 @@
1
+ ---
2
+ name: core/selectors-and-derived-state
3
+ description: >
4
+ Use this when selecting, transforming, or deriving data from TanStack Query:
5
+ select functions, selector memoization, fine-grained subscriptions, structural
6
+ sharing, queryOptions composition with select, and deriving client state from
7
+ server state instead of syncing it through effects.
8
+ type: core
9
+ library: TanStack Query
10
+ library_version: "5.101.0"
11
+ requires:
12
+ - core/seed-placeholder-select-and-transform-data
13
+ - framework/shape-data-and-render-efficiently
14
+ sources:
15
+ - TanStack/query:docs/framework/react/guides/render-optimizations.md
16
+ - TanStack/query:docs/framework/react/reference/queryOptions.md
17
+ ---
18
+
19
+ ## Core Patterns
20
+
21
+ Use `select` to subscribe a component to the data shape it actually needs while keeping the full response in the cache.
22
+
23
+ ### Select a stable slice
24
+
25
+ ```tsx
26
+ import { queryOptions, useSuspenseQuery } from "@tanstack/react-query";
27
+
28
+ const productOptions = (id: string) =>
29
+ queryOptions({
30
+ queryKey: ["product", id],
31
+ queryFn: () => fetchProduct(id),
32
+ });
33
+
34
+ function ProductTitle({ id }: { id: string }) {
35
+ const title = useSuspenseQuery({
36
+ ...productOptions(id),
37
+ select: (product) => product.title,
38
+ });
39
+
40
+ return <h1>{title.data}</h1>;
41
+ }
42
+ ```
43
+
44
+ ### Stabilize expensive selectors
45
+
46
+ ```tsx
47
+ const selectAverageRating = (products: Array<Product>) => expensiveAverage(products);
48
+
49
+ function ProductSummary({ filters }: { filters: ProductFilters }) {
50
+ return useSuspenseQuery({
51
+ ...productsOptions(filters),
52
+ select: selectAverageRating,
53
+ });
54
+ }
55
+ ```
56
+
57
+ Use `React.useCallback` when the selector closes over component props. Move it outside the component when it has no dependencies.
58
+
59
+ ### Derive client state instead of syncing it
60
+
61
+ ```tsx
62
+ const selectedUser = usersQuery.data?.find((user) => user.id === selectedUserId);
63
+ const visibleSelectedUserId = selectedUser ? selectedUserId : null;
64
+ ```
65
+
66
+ When server data changes, derived values update naturally during render.
67
+
68
+ ## Common Mistakes
69
+
70
+ ### HIGH Syncing derived state through an effect
71
+
72
+ Wrong:
73
+
74
+ ```tsx
75
+ React.useEffect(() => {
76
+ if (!users?.some((user) => user.id === selectedUserId)) {
77
+ setSelectedUserId(null);
78
+ }
79
+ }, [users, selectedUserId]);
80
+ ```
81
+
82
+ Correct:
83
+
84
+ ```tsx
85
+ const selectedUser = users?.find((user) => user.id === selectedUserId);
86
+ const visibleSelectedUserId = selectedUser ? selectedUserId : null;
87
+ ```
88
+
89
+ Prefer deriving client state from server state during render when no side effect is required.
90
+
91
+ ### MEDIUM Inline expensive select reruns on unrelated renders
92
+
93
+ Wrong:
94
+
95
+ ```tsx
96
+ useSuspenseQuery({
97
+ ...productsOptions(filters),
98
+ select: (data) => expensiveSuperTransformation(data),
99
+ });
100
+ ```
101
+
102
+ Correct:
103
+
104
+ ```tsx
105
+ const selectProducts = (data: Array<Product>) => expensiveSuperTransformation(data);
106
+
107
+ useSuspenseQuery({
108
+ ...productsOptions(filters),
109
+ select: selectProducts,
110
+ });
111
+ ```
112
+
113
+ TanStack Query reruns `select` when data changes or the selector function identity changes.
114
+
115
+ ### MEDIUM Using select to throw domain errors
116
+
117
+ Wrong:
118
+
119
+ ```tsx
120
+ useQuery({
121
+ queryKey: ["todos"],
122
+ queryFn: fetchTodos,
123
+ select: (todos) => {
124
+ if (!todos.length) throw new Error("No todos");
125
+ return todos;
126
+ },
127
+ });
128
+ ```
129
+
130
+ Correct:
131
+
132
+ ```tsx
133
+ useQuery({
134
+ queryKey: ["todos"],
135
+ queryFn: async () => {
136
+ const todos = await fetchTodos();
137
+ if (!todos.length) throw new Error("No todos");
138
+ return todos;
139
+ },
140
+ });
141
+ ```
142
+
143
+ `select` transforms successful data. Query errors belong in the query function.
144
+
145
+ Source: TanStack/query:docs/framework/react/guides/render-optimizations.md